update : struk dan perapihan folder admin

main
marszayn 2025-08-05 13:35:42 +07:00
parent a4b5c45312
commit 9962a58df0
17 changed files with 1752 additions and 576 deletions

View File

@ -0,0 +1,28 @@
using System.Diagnostics;
using Microsoft.AspNetCore.Mvc;
using eSPJ.Models;
namespace eSPJ.Controllers.SpjAdminController;
[Route("admin")]
public class AdminController : Controller
{
[HttpGet("")]
public IActionResult Index()
{
return View("~/Views/Admin/Transport/SpjAdmin/Home/Index.cshtml");
}
[HttpGet("scan")]
public IActionResult Scan()
{
return View("~/Views/Admin/Transport/SpjAdmin/Scan/Index.cshtml");
}
[HttpGet("history")]
public IActionResult History()
{
return View("~/Views/Admin/Transport/SpjAdmin/History/Index.cshtml");
}
}

View File

@ -1,98 +0,0 @@
using Microsoft.AspNetCore.Mvc;
namespace eSPJ.Controllers.SpjDriverController
{
[Route("scan")]
public class ScanController : Controller
{
[HttpGet("")]
public IActionResult Index()
{
return View("~/Views/Admin/Transport/SpjDriver/Scan/Index.cshtml");
}
[HttpGet("detail")]
public IActionResult Detail()
{
return View("~/Views/Admin/Transport/SpjDriver/Scan/Detail.cshtml");
}
[HttpGet("create")]
public IActionResult Create()
{
return View("~/Views/Admin/Transport/SpjDriver/Scan/Create.cshtml");
}
[HttpPost]
public async Task<IActionResult> ProcessScan(string barcode)
{
try
{
if (string.IsNullOrEmpty(barcode))
{
TempData["Error"] = "Kode barcode tidak boleh kosong.";
return RedirectToAction("Index");
}
if (barcode.Length < 5)
{
TempData["Error"] = "Format kode SPJ tidak valid. Minimal 5 karakter.";
return RedirectToAction("Index");
}
barcode = barcode.Trim();
var spjData = await ValidateSpjCode(barcode);
if (spjData == null)
{
TempData["Error"] = $"SPJ dengan kode '{barcode}' tidak ditemukan.";
return RedirectToAction("Index");
}
TempData["Success"] = $"SPJ '{barcode}' berhasil ditemukan!";
return RedirectToAction("Index", "Detail", new { spjCode = barcode });
}
catch (Exception)
{
TempData["Error"] = "Terjadi kesalahan saat memproses scan. Silakan coba lagi.";
return RedirectToAction("Index");
}
}
private async Task<SpjData?> ValidateSpjCode(string barcode)
{
try
{
await Task.Delay(100);
if (barcode.ToUpper().StartsWith("SPJ"))
{
return new SpjData
{
Code = barcode,
Status = "Active",
Driver = "Sample Driver",
Vehicle = "Sample Vehicle"
};
}
return null;
}
catch
{
return null;
}
}
public class SpjData
{
public string Code { get; set; } = string.Empty;
public string Status { get; set; } = string.Empty;
public string Driver { get; set; } = string.Empty;
public string Vehicle { get; set; } = string.Empty;
}
}
}

View File

@ -20,33 +20,60 @@ namespace eSPJ.Controllers.SpjDriverController
}
[HttpPost("struk")]
public IActionResult ProcessStruk(string NomorStruk, string BeratMuatan)
public IActionResult ProcessStruk(string NomorStruk, string NomorPolisi, string Penugasan,
string WaktuMasuk, string WaktuKeluar, int? BeratMasuk, int? BeratKeluar, int BeratNett)
{
try
{
// Validate inputs
if (string.IsNullOrEmpty(NomorStruk) || string.IsNullOrEmpty(BeratMuatan))
// Validate required inputs
if (string.IsNullOrEmpty(NomorStruk) || BeratNett <= 0)
{
TempData["Error"] = "Nomor struk dan berat muatan harus diisi.";
TempData["Error"] = "Nomor struk dan berat nett harus diisi.";
return RedirectToAction("Struk");
}
if (NomorStruk.Length < 6)
// Validate receipt number format (numbers only, 7+ digits)
if (!System.Text.RegularExpressions.Regex.IsMatch(NomorStruk, @"^\d{7,}$"))
{
TempData["Error"] = "Nomor struk minimal 6 digit.";
TempData["Error"] = "Format nomor struk tidak valid. Harus berupa angka minimal 7 digit.";
return RedirectToAction("Struk");
}
if (!decimal.TryParse(BeratMuatan, out decimal berat) || berat <= 0)
// Validate weight range
if (BeratNett < 100 || BeratNett > 50000)
{
TempData["Error"] = "Berat muatan harus berupa angka yang valid.";
TempData["Error"] = "Berat nett harus antara 100 kg - 50,000 kg.";
return RedirectToAction("Struk");
}
// Validate optional weights
if (BeratMasuk.HasValue && (BeratMasuk < 0 || BeratMasuk > 100000))
{
TempData["Error"] = "Berat masuk tidak valid.";
return RedirectToAction("Struk");
}
if (BeratKeluar.HasValue && (BeratKeluar < 0 || BeratKeluar > 100000))
{
TempData["Error"] = "Berat keluar tidak valid.";
return RedirectToAction("Struk");
}
// Here you would normally save to database
// For now, just simulate success
// For now, just simulate success with all data
var submitData = new
{
NomorStruk,
NomorPolisi = NomorPolisi ?? "N/A",
Penugasan = Penugasan ?? "N/A",
WaktuMasuk = WaktuMasuk ?? "N/A",
WaktuKeluar = WaktuKeluar ?? "N/A",
BeratMasuk = BeratMasuk?.ToString() ?? "N/A",
BeratKeluar = BeratKeluar?.ToString() ?? "N/A",
BeratNett
};
TempData["Success"] = $"Struk berhasil disubmit! No: {NomorStruk}, Berat: {BeratMuatan} kg";
TempData["Success"] = $"Struk berhasil disubmit! No: {NomorStruk}, Nett: {BeratNett} kg";
return RedirectToAction("Index", "Home");
}

View File

@ -0,0 +1,163 @@
@{
Layout = "~/Views/Admin/Transport/SpjAdmin/Shared/_Layout.cshtml";
ViewData["Title"] = "Detail Perjalanan - DLH";
}
<div class="max-w-sm mx-auto bg-gray-50 min-h-screen">
<!-- Header -->
<div class="bg-gradient-to-r from-orange-500 to-orange-600 text-white px-4 py-4 sticky top-0 z-10 shadow-lg">
<div class="flex items-center justify-between">
<a href="@Url.Action("Index", "History")" class="p-2 hover:bg-white/10 rounded-full transition-all duration-200">
<i class="w-5 h-5" data-lucide="chevron-left"></i>
</a>
<h1 class="text-lg font-bold">Detail Perjalanan</h1>
<div class="w-9"></div>
</div>
</div>
<div class="px-4 py-4 space-y-4">
<!-- SPJ Information Card -->
<div class="bg-white rounded-2xl p-5 shadow-sm border border-gray-100">
<div class="flex items-center gap-3 mb-4">
<div class="w-10 h-10 bg-orange-100 rounded-full flex items-center justify-center">
<i class="w-5 h-5 text-orange-600" data-lucide="file-text"></i>
</div>
<div>
<h2 class="text-lg font-bold text-gray-900">Data SPJ</h2>
<p class="text-xs text-gray-500">Surat Perintah Jalan</p>
</div>
</div>
<div class="space-y-3">
<div class="flex justify-between items-center py-2 border-b border-gray-50">
<span class="text-sm text-gray-600">No. SPJ</span>
<span class="font-semibold text-gray-900 text-sm">SPJ/07-2025/PKM/000476</span>
</div>
<div class="flex justify-between items-center py-2 border-b border-gray-50">
<span class="text-sm text-gray-600">Plat Nomor</span>
<span class="bg-orange-50 text-orange-700 px-3 py-1 rounded-full text-sm font-medium">B 9632 TOR</span>
</div>
<div class="flex justify-between items-center py-2 border-b border-gray-50">
<span class="text-sm text-gray-600">Nomer Pintu</span>
<span class="font-mono text-sm text-gray-700">JRC 005</span>
</div>
<div class="flex justify-between items-center py-2">
<span class="text-sm text-gray-600">Tujuan Pembuangan</span>
<span class="font-semibold text-gray-900 text-sm">Taman Barito</span>
</div>
</div>
</div>
<!-- Summary Card -->
<div class="bg-white rounded-2xl p-5 shadow-sm border border-gray-100">
<div class="flex items-center gap-3 mb-4">
<div class="w-10 h-10 bg-orange-100 rounded-full flex items-center justify-center">
<i class="w-5 h-5 text-orange-600" data-lucide="bar-chart-3"></i>
</div>
<div>
<h2 class="text-lg font-bold text-gray-900">Ringkasan</h2>
<p class="text-xs text-gray-500">Informasi perjalanan</p>
</div>
</div>
<div class="grid grid-cols-4 gap-3">
<div class="text-center p-3 bg-gray-50 rounded-xl">
<div class="text-xl font-bold text-gray-900">3</div>
<div class="text-xs text-gray-600">Total</div>
</div>
<div class="text-center p-3 bg-green-50 rounded-xl">
<div class="text-xl font-bold text-green-600">1</div>
<div class="text-xs text-gray-600">Selesai</div>
</div>
<div class="text-center p-3 bg-yellow-50 rounded-xl">
<div class="text-xl font-bold text-yellow-600">1</div>
<div class="text-xs text-gray-600">Proses</div>
</div>
<div class="text-center p-3 bg-red-50 rounded-xl">
<div class="text-xl font-bold text-red-600">1</div>
<div class="text-xs text-gray-600">Batal</div>
</div>
</div>
</div>
<!-- Pickup Locations -->
<div class="bg-white rounded-2xl p-5 shadow-sm border border-gray-100">
<div class="flex items-center gap-3 mb-4">
<div class="w-10 h-10 bg-orange-100 rounded-full flex items-center justify-center">
<i class="w-5 h-5 text-orange-600" data-lucide="map-pin"></i>
</div>
<div>
<h2 class="text-lg font-bold text-gray-900">Lokasi Pengangkutan</h2>
<p class="text-xs text-gray-500">Daftar lokasi yang dikunjungi</p>
</div>
</div>
<div class="space-y-4">
<!-- Location 1 - In Progress -->
<div class="border border-yellow-200 bg-yellow-50 rounded-xl p-4">
<div class="flex items-start gap-3">
<div class="w-8 h-8 bg-yellow-500 rounded-full flex items-center justify-center flex-shrink-0 mt-1">
<i class="w-4 h-4 text-white" data-lucide="clock"></i>
</div>
<div class="flex-1">
<div class="flex items-center gap-2 mb-2">
<span class="bg-yellow-400 text-white text-xs font-semibold px-2 py-1 rounded-full">Pengangkutan</span>
<span class="text-xs text-gray-500">Lokasi 1</span>
</div>
<h4 class="font-bold text-gray-900 mb-1">CV Tri Mitra Utama</h4>
<p class="text-sm text-gray-600 mb-1">Shell Radio Dalam</p>
<p class="text-sm text-gray-600 mb-2">Alamat:</p>
<p class="text-sm text-gray-700 leading-relaxed">
Jl. Radio Dalam Raya No.6C Gandaria Utara, Kecamatan Kebayoran Baru, Kota Jakarta Selatan 12140
</p>
</div>
</div>
</div>
<!-- Location 2 - Completed -->
<div class="border border-green-200 bg-green-100 rounded-xl p-4">
<div class="flex items-start gap-3">
<div class="w-8 h-8 bg-green-500 rounded-full flex items-center justify-center flex-shrink-0 mt-1">
<i class="w-4 h-4 text-white" data-lucide="check"></i>
</div>
<div class="flex-1">
<div class="flex items-center gap-2 mb-2">
<span class="bg-green-500 text-white text-xs font-semibold px-2 py-1 rounded-full">Sudah Diangkut</span>
<span class="text-xs text-gray-500">Lokasi 2</span>
</div>
<h4 class="font-bold text-gray-900 mb-1">CV Tri Berkah Sejahtera</h4>
<p class="text-sm text-gray-600 mb-2">Alamat:</p>
<p class="text-sm text-gray-700 leading-relaxed">
Kp. Pertanian II Rt.004 Rw.001 Kel. Klender Kec, Duren Sawit, Kota Adm. Jakarta Timur 13470
</p>
</div>
</div>
</div>
<!-- Location 3 - Cancelled -->
<div class="border border-red-200 bg-red-100 rounded-xl p-4">
<div class="flex items-start gap-3">
<div class="w-8 h-8 bg-red-500 rounded-full flex items-center justify-center flex-shrink-0 mt-1">
<i class="w-4 h-4 text-white" data-lucide="x"></i>
</div>
<div class="flex-1">
<div class="flex items-center gap-2 mb-2">
<span class="bg-red-500 text-white text-xs font-semibold px-2 py-1 rounded-full">Batal Angkut</span>
<span class="text-xs text-gray-500">Lokasi 3</span>
</div>
<h4 class="font-bold text-gray-900 mb-1">CV Tri Berkah Sejahtera</h4>
<p class="text-sm text-gray-600 mb-2">Alamat:</p>
<p class="text-sm text-gray-700 leading-relaxed">
Kp. Pertanian II Rt.004 Rw.001 Kel. Klender Kec, Duren Sawit, Kota Adm. Jakarta Timur 13470
</p>
</div>
</div>
</div>
</div>
</div>
</div>
<partial name="~/Views/Admin/Transport/SpjAdmin/Shared/Components/_Navigation.cshtml" />
</div>

View File

@ -0,0 +1,154 @@
@{
Layout = "~/Views/Admin/Transport/SpjAdmin/Shared/_Layout.cshtml";
ViewData["Title"] = "History - DLH";
}
<div class="max-w-sm mx-auto bg-gray-50 min-h-screen">
<div class="bg-gradient-to-r from-orange-500 to-orange-600 text-white px-4 py-4 sticky top-0 z-10 shadow-lg">
<div class="flex items-center justify-between">
<a href="@Url.Action("Index", "Home")" class="p-2 hover:bg-white/10 rounded-full transition-all duration-200">
<i class="w-5 h-5" data-lucide="chevron-left"></i>
</a>
<h1 class="text-lg font-bold">Riwayat Perjalanan</h1>
<div class="w-9"></div>
</div>
</div>
@{
var spjList = new[]
{
new {
Id = 1,
NoSpj = "SPJ/07-2025/PKM/000478",
Plat = "B 5678 ABC",
Kode = "JRC 007",
Tujuan = "Bantar Gebang",
Status = "In Progress",
Tanggal = "28 Jul 2025",
Waktu = "16:45"
},
new {
Id = 2,
NoSpj = "SPJ/07-2025/PKM/000476",
Plat = "B 9632 TOR",
Kode = "JRC 005",
Tujuan = "RDF Rorotan",
Status = "Completed",
Tanggal = "27 Jul 2025",
Waktu = "14:30"
},
new {
Id = 3,
NoSpj = "SPJ/07-2025/PKM/000477",
Plat = "B 1234 XYZ",
Kode = "JRC 006",
Tujuan = "RDF Pesanggarahan",
Status = "Completed",
Tanggal = "26 Jul 2025",
Waktu = "09:15"
},
new {
Id = 4,
NoSpj = "SPJ/07-2025/PKM/000479",
Plat = "B 9876 DEF",
Kode = "JRC 008",
Tujuan = "RDF Sunter",
Status = "Completed",
Tanggal = "25 Jul 2025",
Waktu = "11:20"
},
new {
Id = 5,
NoSpj = "SPJ/07-2025/PKM/000480",
Plat = "B 4321 GHI",
Kode = "JRC 009",
Tujuan = "Bantar Gebang",
Status = "Completed",
Tanggal = "24 Jul 2025",
Waktu = "08:45"
}
};
}
<div class="px-4 py-4 space-y-3">
@foreach (var spj in spjList)
{
<a href="@Url.Action("Details", "History", new { id = spj.Id })" class="block">
<div class="bg-white rounded-2xl p-4 shadow-sm border border-gray-100 hover:shadow-lg hover:border-orange-200 transition-all duration-300 relative overflow-hidden">
<div class="absolute top-0 left-0 w-full h-1 bg-gradient-to-r from-orange-400 to-orange-500"></div>
<div class="flex items-start justify-between mb-3">
<div class="flex-1 min-w-0">
<div class="flex items-center gap-2 mb-1">
<div class="w-2 h-2 bg-orange-400 rounded-full"></div>
<span class="text-xs font-medium text-gray-500 uppercase tracking-wider">No. SPJ</span>
</div>
<div class="font-bold text-gray-900 text-sm">@spj.NoSpj</div>
</div>
<div class="flex flex-col items-end gap-1">
@if (spj.Status == "Completed")
{
<span class="bg-green-100 text-green-700 px-2 py-1 rounded-full text-xs font-semibold flex items-center gap-1">
<div class="w-2 h-2 bg-green-500 rounded-full"></div>
Selesai
</span>
}
else
{
<span class="bg-blue-100 text-blue-700 px-2 py-1 rounded-full text-xs font-semibold flex items-center gap-1">
<div class="w-2 h-2 bg-blue-500 rounded-full animate-pulse"></div>
Berlangsung
</span>
}
</div>
</div>
<div class="bg-gray-50 rounded-xl p-3 mb-3">
<div class="flex items-center justify-between">
<div class="flex items-center gap-3">
<div class="w-10 h-10 bg-orange-100 rounded-lg flex items-center justify-center">
<i class="w-5 h-5 text-orange-600" data-lucide="car"></i>
</div>
<div>
<div class="font-bold text-gray-900 text-sm">@spj.Plat</div>
<div class="text-xs text-gray-500">@spj.Kode</div>
</div>
</div>
<div class="text-right">
<div class="text-xs text-gray-500">@spj.Tanggal</div>
<div class="text-xs font-medium text-gray-700">@spj.Waktu</div>
</div>
</div>
</div>
<div class="flex items-center gap-3 pt-2 border-t border-gray-100">
<div class="w-8 h-8 bg-green-100 rounded-full flex items-center justify-center flex-shrink-0">
<i class="w-4 h-4 text-green-600" data-lucide="map-pin"></i>
</div>
<div class="flex-1 min-w-0">
<div class="text-xs text-gray-500 mb-1">Tujuan</div>
<div class="font-semibold text-gray-900 text-sm">@spj.Tujuan</div>
</div>
<div class="p-2 hover:bg-gray-100 rounded-full transition-colors">
<i class="w-4 h-4 text-gray-400" data-lucide="chevron-right"></i>
</div>
</div>
</div>
</a>
}
</div>
<partial name="~/Views/Admin/Transport/SpjAdmin/Shared/Components/_Navigation.cshtml" />
<!-- Kalau butuh tampilan kosong (jika tidak ada data) -->
@* <div class="flex flex-col items-center justify-center py-16 px-4">
<div class="w-24 h-24 bg-gray-100 rounded-full flex items-center justify-center mb-4">
<i class="w-12 h-12 text-gray-400" data-lucide="clock"></i>
</div>
<h3 class="text-lg font-semibold text-gray-900 mb-2">Belum Ada Riwayat</h3>
<p class="text-gray-500 text-center text-sm">Riwayat perjalanan Anda akan muncul di sini setelah melakukan perjalanan pertama.</p>
</div> *@
</div>

View File

@ -1,5 +1,5 @@
@{
Layout = "~/Views/Admin/Transport/SpjDriver/Shared/_Layout.cshtml";
Layout = "~/Views/Admin/Transport/SpjAdmin/Shared/_Layout.cshtml";
ViewData["Title"] = "Home Page";
}
@ -82,7 +82,7 @@
</div>
</div>
<partial name="~/Views/Admin/Transport/SpjDriver/Shared/Components/_NavigationAdmin.cshtml" />
<partial name="~/Views/Admin/Transport/SpjAdmin/Shared/Components/_Navigation.cshtml" />
</div>

View File

@ -1,5 +1,5 @@
@{
Layout = "~/Views/Admin/Transport/SpjDriver/Shared/_Layout.cshtml";
Layout = "~/Views/Admin/Transport/SpjAdmin/Shared/_Layout.cshtml";
ViewData["Title"] = "Buat Barcode SPJ";
}

View File

@ -1,5 +1,5 @@
@{
Layout = "~/Views/Admin/Transport/SpjDriver/Shared/_Layout.cshtml";
Layout = "~/Views/Admin/Transport/SpjAdmin/Shared/_Layout.cshtml";
ViewData["Title"] = "Detail SPJ";
}
@ -114,5 +114,5 @@
</div>
</div>
<partial name="~/Views/Admin/Transport/SpjDriver/Shared/Components/_Navigation.cshtml" />
<partial name="~/Views/Admin/Transport/SpjAdmin/Shared/Components/_Navigation.cshtml" />
</div>

View File

@ -1,5 +1,5 @@
@{
Layout = "~/Views/Admin/Transport/SpjDriver/Shared/_Layout.cshtml";
Layout = "~/Views/Admin/Transport/SpjAdmin/Shared/_Layout.cshtml";
ViewData["Title"] = "Scan SPJ";
}
@ -149,7 +149,7 @@
</div>
</div>
</div>
<partial name="~/Views/Admin/Transport/SpjDriver/Shared/Components/_NavigationAdmin.cshtml" />
<partial name="~/Views/Admin/Transport/SpjAdmin/Shared/Components/_Navigation.cshtml" />
</div>
<register-block dynamic-section="scripts" key="jsScan">

View File

@ -0,0 +1,48 @@
<div class="fixed bottom-0 left-1/2 transform -translate-x-1/2 w-full max-w-sm z-99">
<div class="relative backdrop-blur-lg border border-gray-200/50 rounded-t-3xl shadow-xl overflow-hidden">
<div class="absolute -top-0 left-1/2 transform -translate-x-1/2 w-20 h-10">
<div class="w-full h-full bg-transparent relative">
<div class="absolute left-0 top-0 w-10 h-10 backdrop-blur-lg rounded-br-full"></div>
<div class="absolute right-0 top-0 w-10 h-10 backdrop-blur-lg rounded-bl-full"></div>
</div>
</div>
<!-- Navigation Content -->
<div class="flex justify-between items-center px-8 relative pt-6">
<!-- Home Button -->
<a href="@Url.Action("Index", "Admin")" class="flex flex-col items-center gap-1 px-4 py-2 transition-all duration-300 hover:scale-105 group">
<div class="relative">
<i class="w-6 h-6 text-gray-400 group-hover:text-orange-500 transition-colors duration-300" data-lucide="home"></i>
<div class="absolute -bottom-0.5 left-1/2 transform -translate-x-1/2 w-0 h-0.5 bg-orange-500 group-hover:w-full transition-all duration-300"></div>
</div>
<span class="text-xs text-gray-600 group-hover:text-orange-500 font-medium transition-colors duration-300">Home</span>
</a>
<div class="w-12"></div>
<!-- Profile Button -->
<a href="@Url.Action("History", "Admin")" class="flex flex-col items-center gap-1 px-4 py-2 transition-all duration-300 hover:scale-105 group">
<div class="relative">
<i class="w-6 h-6 text-gray-400 group-hover:text-orange-500 transition-colors duration-300" data-lucide="clipboard-check"></i>
<div class="absolute -bottom-0.5 left-1/2 transform -translate-x-1/2 w-0 h-0.5 bg-orange-500 group-hover:w-full transition-all duration-300"></div>
</div>
<span class="text-xs text-gray-600 group-hover:text-orange-500 font-medium transition-colors duration-300">History</span>
</a>
</div>
</div>
<!-- Center Submit -->
<div class="absolute -top-4 left-1/2 transform -translate-x-1/2">
<a href="@Url.Action("Scan", "Admin")" id="odoBtn" class="hover:cursor-pointer w-14 h-14 bg-gradient-to-br from-orange-500 via-orange-400 to-orange-600 rounded-full shadow-xl flex items-center justify-center transition-all duration-300 hover:scale-110 hover:rotate-6 border-4 border-white ring-2 ring-orange-200">
<i class="w-6 h-6 text-white" data-lucide="camera"></i>
</a>
</div>
</div>
<div class="h-30"></div>
<register-block dynamic-section="scripts" key="jsNav">
</register-block>

View File

@ -0,0 +1,25 @@
@model ErrorViewModel
@{
ViewData["Title"] = "Error";
}
<h1 class="text-danger">Error.</h1>
<h2 class="text-danger">An error occurred while processing your request.</h2>
@if (Model.ShowRequestId)
{
<p>
<strong>Request ID:</strong> <code>@Model.RequestId</code>
</p>
}
<h3>Development Mode</h3>
<p>
Swapping to <strong>Development</strong> environment will display more detailed information about the error that occurred.
</p>
<p>
<strong>The Development environment shouldn't be enabled for deployed applications.</strong>
It can result in displaying sensitive information from exceptions to end users.
For local debugging, enable the <strong>Development</strong> environment by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong>
and restarting the app.
</p>

View File

@ -0,0 +1,55 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>@ViewData["Title"] - eSPJ</title>
<script type="importmap"></script>
<!-- Theme Colors -->
<meta name="theme-color" content="#f97316">
<meta name="msapplication-navbutton-color" content="#f97316">
<meta name="apple-mobile-web-app-status-bar-style" content="default">
<!-- Mobile Optimization -->
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
<meta name="mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-title" content="SPJ Angkut">
<!-- iOS Icons -->
<link rel="apple-touch-icon" href="~/icons/icon-152x152.png">
<link rel="apple-touch-icon" sizes="180x180" href="~/icons/icon-180x180.png">
<!-- Windows Tiles -->
<meta name="msapplication-TileImage" content="/icons/icon-144x144.png">
<meta name="msapplication-TileColor" content="#f97316">
<link rel="manifest" href="@Url.Content("~/driver/manifest.json")" />
@* <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" /> *@
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter+Tight:ital,wght@0,100..900;1,100..900&display=swap" rel="stylesheet">
<link rel="stylesheet" href="@Url.Content("~/driver/css/watch.css")" asp-append-version="true" />
<link rel="stylesheet" href="@Url.Content("~/driver/css/website.css")" asp-append-version="true" />
<link rel="stylesheet" href="@Url.Content("~/driver/eSPJ.styles.css")" asp-append-version="true" />
@await RenderSectionAsync("Styles", required: false)
</head>
<body class="bg-gray-100">
@RenderBody()
<script src="@Url.Content("~/driver/lib/jquery/dist/jquery.min.js")"></script>
<script src="@Url.Content("~/driver/lib/bootstrap/dist/js/bootstrap.bundle.min.js")"></script>
<script src="@Url.Content("~/driver/js/site.js")">" asp-append-version="true"></script>
<script src="https://unpkg.com/lucide@latest"></script>
<script>
document.addEventListener('DOMContentLoaded', function () {
lucide.createIcons();
});
</script>
@await RenderSectionAsync("Scripts", required: false)
<dynamic-section name="scripts" />
</body>
</html>

View File

@ -0,0 +1,48 @@
/* Please see documentation at https://learn.microsoft.com/aspnet/core/client-side/bundling-and-minification
for details on configuring this project to bundle and minify static web assets. */
a.navbar-brand {
white-space: normal;
text-align: center;
word-break: break-all;
}
a {
color: #0077cc;
}
.btn-primary {
color: #fff;
background-color: #1b6ec2;
border-color: #1861ac;
}
.nav-pills .nav-link.active, .nav-pills .show > .nav-link {
color: #fff;
background-color: #1b6ec2;
border-color: #1861ac;
}
.border-top {
border-top: 1px solid #e5e5e5;
}
.border-bottom {
border-bottom: 1px solid #e5e5e5;
}
.box-shadow {
box-shadow: 0 .25rem .75rem rgba(0, 0, 0, .05);
}
button.accept-policy {
font-size: 1rem;
line-height: inherit;
}
.footer {
position: absolute;
bottom: 0;
width: 100%;
white-space: nowrap;
line-height: 60px;
}

View File

@ -0,0 +1,2 @@
<script src="~/lib/jquery-validation/dist/jquery.validate.min.js"></script>
<script src="~/lib/jquery-validation-unobtrusive/dist/jquery.validate.unobtrusive.min.js"></script>

File diff suppressed because it is too large Load Diff

View File

@ -242,3 +242,66 @@
box-shadow: 0 0 0 0 rgba(34, 197, 94, 0);
}
}
/* Upload functionality styling */
.upload-label {
transition: all 0.3s ease;
}
.upload-label:hover {
transform: translateY(-1px);
box-shadow: 0 4px 8px rgba(59, 130, 246, 0.3);
}
.upload-label:active {
transform: translateY(0);
}
/* Uploaded image display */
#scanner-container img {
border: 2px dashed rgba(245, 158, 11, 0.3);
background-color: #f9fafb;
}
/* Receipt format hints */
.receipt-format-hint {
background: linear-gradient(
135deg,
rgba(245, 158, 11, 0.1),
rgba(245, 158, 11, 0.05)
);
border-left: 4px solid #f59e0b;
}
/* Enhanced OCR feedback */
.ocr-success {
animation: successPulse 0.6s ease-out;
}
@keyframes successPulse {
0% {
transform: scale(1);
box-shadow: 0 0 0 0 rgba(34, 197, 94, 0.4);
}
50% {
transform: scale(1.02);
box-shadow: 0 0 0 10px rgba(34, 197, 94, 0);
}
100% {
transform: scale(1);
box-shadow: 0 0 0 0 rgba(34, 197, 94, 0);
}
}
/* Better mobile responsiveness for file upload */
@media (max-width: 640px) {
.upload-label {
padding: 12px 16px;
font-size: 14px;
}
.upload-label i {
width: 16px;
height: 16px;
}
}

View File

@ -66,6 +66,7 @@
--color-purple-50: oklch(97.7% 0.014 308.299);
--color-purple-100: oklch(94.6% 0.033 307.174);
--color-purple-400: oklch(71.4% 0.203 305.504);
--color-purple-500: oklch(62.7% 0.265 303.9);
--color-purple-600: oklch(55.8% 0.288 302.321);
--color-rose-50: oklch(96.9% 0.015 12.422);
--color-slate-50: oklch(98.4% 0.003 247.858);
@ -336,9 +337,6 @@
.top-0 {
top: calc(var(--spacing) * 0);
}
.top-1 {
top: calc(var(--spacing) * 1);
}
.top-1\/2 {
top: calc(1/2 * 100%);
}
@ -372,9 +370,6 @@
.right-full {
right: 100%;
}
.-bottom-0 {
bottom: calc(var(--spacing) * -0);
}
.-bottom-0\.5 {
bottom: calc(var(--spacing) * -0.5);
}
@ -402,9 +397,6 @@
.left-0 {
left: calc(var(--spacing) * 0);
}
.left-1 {
left: calc(var(--spacing) * 1);
}
.left-1\/2 {
left: calc(1/2 * 100%);
}
@ -648,9 +640,6 @@
.-mt-6 {
margin-top: calc(var(--spacing) * -6);
}
.-mt-8 {
margin-top: calc(var(--spacing) * -8);
}
.-mt-10 {
margin-top: calc(var(--spacing) * -10);
}
@ -687,9 +676,6 @@
.mt-8 {
margin-top: calc(var(--spacing) * 8);
}
.mt-10 {
margin-top: calc(var(--spacing) * 10);
}
.mt-40 {
margin-top: calc(var(--spacing) * 40);
}
@ -723,9 +709,6 @@
.mb-6 {
margin-bottom: calc(var(--spacing) * 6);
}
.mb-8 {
margin-bottom: calc(var(--spacing) * 8);
}
.mb-auto {
margin-bottom: auto;
}
@ -777,18 +760,12 @@
.table-row {
display: table-row;
}
.h-0 {
height: calc(var(--spacing) * 0);
}
.h-0\.5 {
height: calc(var(--spacing) * 0.5);
}
.h-1 {
height: calc(var(--spacing) * 1);
}
.h-1\.5 {
height: calc(var(--spacing) * 1.5);
}
.h-2 {
height: calc(var(--spacing) * 2);
}
@ -819,9 +796,6 @@
.h-14 {
height: calc(var(--spacing) * 14);
}
.h-16 {
height: calc(var(--spacing) * 16);
}
.h-20 {
height: calc(var(--spacing) * 20);
}
@ -831,9 +805,6 @@
.h-25 {
height: calc(var(--spacing) * 25);
}
.h-28 {
height: calc(var(--spacing) * 28);
}
.h-30 {
height: calc(var(--spacing) * 30);
}
@ -867,9 +838,6 @@
.w-1 {
width: calc(var(--spacing) * 1);
}
.w-1\.5 {
width: calc(var(--spacing) * 1.5);
}
.w-2 {
width: calc(var(--spacing) * 2);
}
@ -903,9 +871,6 @@
.w-14 {
width: calc(var(--spacing) * 14);
}
.w-16 {
width: calc(var(--spacing) * 16);
}
.w-20 {
width: calc(var(--spacing) * 20);
}
@ -915,9 +880,6 @@
.w-25 {
width: calc(var(--spacing) * 25);
}
.w-28 {
width: calc(var(--spacing) * 28);
}
.w-32 {
width: calc(var(--spacing) * 32);
}
@ -945,9 +907,6 @@
.max-w-sm {
max-width: var(--container-sm);
}
.max-w-xs {
max-width: var(--container-xs);
}
.min-w-0 {
min-width: calc(var(--spacing) * 0);
}
@ -984,10 +943,6 @@
.border-collapse {
border-collapse: collapse;
}
.-translate-x-1 {
--tw-translate-x: calc(var(--spacing) * -1);
translate: var(--tw-translate-x) var(--tw-translate-y);
}
.-translate-x-1\/2 {
--tw-translate-x: calc(calc(1/2 * 100%) * -1);
translate: var(--tw-translate-x) var(--tw-translate-y);
@ -996,26 +951,14 @@
--tw-translate-x: calc(var(--spacing) * -12);
translate: var(--tw-translate-x) var(--tw-translate-y);
}
.translate-x-10 {
--tw-translate-x: calc(var(--spacing) * 10);
translate: var(--tw-translate-x) var(--tw-translate-y);
}
.translate-x-16 {
--tw-translate-x: calc(var(--spacing) * 16);
translate: var(--tw-translate-x) var(--tw-translate-y);
}
.-translate-y-1 {
--tw-translate-y: calc(var(--spacing) * -1);
translate: var(--tw-translate-x) var(--tw-translate-y);
}
.-translate-y-1\/2 {
--tw-translate-y: calc(calc(1/2 * 100%) * -1);
translate: var(--tw-translate-x) var(--tw-translate-y);
}
.-translate-y-10 {
--tw-translate-y: calc(var(--spacing) * -10);
translate: var(--tw-translate-x) var(--tw-translate-y);
}
.-translate-y-16 {
--tw-translate-y: calc(var(--spacing) * -16);
translate: var(--tw-translate-x) var(--tw-translate-y);
@ -1066,6 +1009,9 @@
.list-disc {
list-style-type: disc;
}
.grid-cols-1 {
grid-template-columns: repeat(1, minmax(0, 1fr));
}
.grid-cols-2 {
grid-template-columns: repeat(2, minmax(0, 1fr));
}
@ -1165,9 +1111,6 @@
margin-block-end: calc(calc(var(--spacing) * 6) * calc(1 - var(--tw-space-y-reverse)));
}
}
.self-start {
align-self: flex-start;
}
.truncate {
overflow: hidden;
text-overflow: ellipsis;
@ -1238,10 +1181,6 @@
border-top-right-radius: var(--radius-lg);
border-bottom-right-radius: var(--radius-lg);
}
.rounded-r-xl {
border-top-right-radius: var(--radius-xl);
border-bottom-right-radius: var(--radius-xl);
}
.rounded-b-2xl {
border-bottom-right-radius: var(--radius-2xl);
border-bottom-left-radius: var(--radius-2xl);
@ -1315,9 +1254,6 @@
.border-blue-200 {
border-color: var(--color-blue-200);
}
.border-emerald-200 {
border-color: var(--color-emerald-200);
}
.border-emerald-400 {
border-color: var(--color-emerald-400);
}
@ -1342,9 +1278,6 @@
.border-green-200 {
border-color: var(--color-green-200);
}
.border-green-300 {
border-color: var(--color-green-300);
}
.border-green-400 {
border-color: var(--color-green-400);
}
@ -1384,9 +1317,6 @@
.border-yellow-200 {
border-color: var(--color-yellow-200);
}
.border-yellow-400 {
border-color: var(--color-yellow-400);
}
.border-t-transparent {
border-top-color: transparent;
}
@ -1462,6 +1392,9 @@
.bg-orange-500 {
background-color: var(--color-orange-500);
}
.bg-purple-500 {
background-color: var(--color-purple-500);
}
.bg-red-50 {
background-color: var(--color-red-50);
}
@ -1507,9 +1440,6 @@
.bg-yellow-50 {
background-color: var(--color-yellow-50);
}
.bg-yellow-100 {
background-color: var(--color-yellow-100);
}
.bg-yellow-400 {
background-color: var(--color-yellow-400);
}
@ -1528,30 +1458,14 @@
--tw-gradient-from: var(--color-amber-50);
--tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));
}
.from-blue-50 {
--tw-gradient-from: var(--color-blue-50);
--tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));
}
.from-blue-100 {
--tw-gradient-from: var(--color-blue-100);
--tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));
}
.from-blue-500 {
--tw-gradient-from: var(--color-blue-500);
--tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));
}
.from-blue-600 {
--tw-gradient-from: var(--color-blue-600);
--tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));
}
.from-emerald-50 {
--tw-gradient-from: var(--color-emerald-50);
--tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));
}
.from-emerald-400 {
--tw-gradient-from: var(--color-emerald-400);
--tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));
}
.from-green-500 {
--tw-gradient-from: var(--color-green-500);
--tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));
@ -1576,10 +1490,6 @@
--tw-gradient-from: var(--color-orange-500);
--tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));
}
.from-purple-400 {
--tw-gradient-from: var(--color-purple-400);
--tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));
}
.from-red-50 {
--tw-gradient-from: var(--color-red-50);
--tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));
@ -1588,10 +1498,6 @@
--tw-gradient-from: var(--color-slate-50);
--tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));
}
.from-slate-100 {
--tw-gradient-from: var(--color-slate-100);
--tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));
}
.from-slate-700 {
--tw-gradient-from: var(--color-slate-700);
--tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));
@ -1615,14 +1521,6 @@
--tw-gradient-to: var(--color-blue-200);
--tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));
}
.to-blue-600 {
--tw-gradient-to: var(--color-blue-600);
--tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));
}
.to-emerald-600 {
--tw-gradient-to: var(--color-emerald-600);
--tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));
}
.to-green-50 {
--tw-gradient-to: var(--color-green-50);
--tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));
@ -1631,10 +1529,6 @@
--tw-gradient-to: var(--color-green-400);
--tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));
}
.to-indigo-50 {
--tw-gradient-to: var(--color-indigo-50);
--tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));
}
.to-indigo-100 {
--tw-gradient-to: var(--color-indigo-100);
--tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));
@ -1663,14 +1557,6 @@
--tw-gradient-to: var(--color-purple-50);
--tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));
}
.to-purple-100 {
--tw-gradient-to: var(--color-purple-100);
--tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));
}
.to-purple-600 {
--tw-gradient-to: var(--color-purple-600);
--tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));
}
.to-red-50 {
--tw-gradient-to: var(--color-red-50);
--tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));
@ -1687,26 +1573,10 @@
--tw-gradient-to: var(--color-rose-50);
--tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));
}
.to-slate-50 {
--tw-gradient-to: var(--color-slate-50);
--tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));
}
.to-slate-100 {
--tw-gradient-to: var(--color-slate-100);
--tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));
}
.to-slate-200 {
--tw-gradient-to: var(--color-slate-200);
--tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));
}
.to-slate-900 {
--tw-gradient-to: var(--color-slate-900);
--tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));
}
.to-teal-50 {
--tw-gradient-to: var(--color-teal-50);
--tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));
}
.to-yellow-50 {
--tw-gradient-to: var(--color-yellow-50);
--tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));
@ -1786,9 +1656,6 @@
.py-6 {
padding-block: calc(var(--spacing) * 6);
}
.py-8 {
padding-block: calc(var(--spacing) * 8);
}
.py-12 {
padding-block: calc(var(--spacing) * 12);
}
@ -1873,9 +1740,6 @@
.pb-6 {
padding-bottom: calc(var(--spacing) * 6);
}
.pb-8 {
padding-bottom: calc(var(--spacing) * 8);
}
.pb-12 {
padding-bottom: calc(var(--spacing) * 12);
}
@ -1915,10 +1779,6 @@
.font-mono {
font-family: var(--font-mono);
}
.text-2xl {
font-size: var(--text-2xl);
line-height: var(--tw-leading, var(--text-2xl--line-height));
}
.text-base {
font-size: var(--text-base);
line-height: var(--tw-leading, var(--text-base--line-height));
@ -2002,15 +1862,9 @@
.text-blue-800 {
color: var(--color-blue-800);
}
.text-emerald-600 {
color: var(--color-emerald-600);
}
.text-emerald-700 {
color: var(--color-emerald-700);
}
.text-gray-300 {
color: var(--color-gray-300);
}
.text-gray-400 {
color: var(--color-gray-400);
}
@ -2068,9 +1922,6 @@
.text-slate-400 {
color: var(--color-slate-400);
}
.text-slate-500 {
color: var(--color-slate-500);
}
.text-slate-600 {
color: var(--color-slate-600);
}
@ -2168,18 +2019,10 @@
--tw-shadow: 0 20px 25px -5px var(--tw-shadow-color, rgb(0 0 0 / 0.1)), 0 8px 10px -6px var(--tw-shadow-color, rgb(0 0 0 / 0.1));
box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
}
.ring {
--tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor);
box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
}
.ring-2 {
--tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor);
box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
}
.ring-4 {
--tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(4px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor);
box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
}
.ring-orange-200 {
--tw-ring-color: var(--color-orange-200);
}
@ -2248,16 +2091,6 @@
transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));
transition-duration: var(--tw-duration, var(--default-transition-duration));
}
.transition-shadow {
transition-property: box-shadow;
transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));
transition-duration: var(--tw-duration, var(--default-transition-duration));
}
.transition-transform {
transition-property: transform, translate, scale, rotate;
transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));
transition-duration: var(--tw-duration, var(--default-transition-duration));
}
.duration-150 {
--tw-duration: 150ms;
transition-duration: 150ms;
@ -2270,10 +2103,6 @@
--tw-duration: 300ms;
transition-duration: 300ms;
}
.duration-500 {
--tw-duration: 500ms;
transition-duration: 500ms;
}
.ease-in-out {
--tw-ease: var(--ease-in-out);
transition-timing-function: var(--ease-in-out);
@ -2297,59 +2126,6 @@
}
}
}
.group-hover\:rotate-180 {
&:is(:where(.group):hover *) {
@media (hover: hover) {
rotate: 180deg;
}
}
}
.group-hover\:from-blue-100 {
&:is(:where(.group):hover *) {
@media (hover: hover) {
--tw-gradient-from: var(--color-blue-100);
--tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));
}
}
}
.group-hover\:from-orange-100 {
&:is(:where(.group):hover *) {
@media (hover: hover) {
--tw-gradient-from: var(--color-orange-100);
--tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));
}
}
}
.group-hover\:to-indigo-200 {
&:is(:where(.group):hover *) {
@media (hover: hover) {
--tw-gradient-to: var(--color-indigo-200);
--tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));
}
}
}
.group-hover\:to-orange-200 {
&:is(:where(.group):hover *) {
@media (hover: hover) {
--tw-gradient-to: var(--color-orange-200);
--tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));
}
}
}
.group-hover\:text-blue-600 {
&:is(:where(.group):hover *) {
@media (hover: hover) {
color: var(--color-blue-600);
}
}
}
.group-hover\:text-blue-700 {
&:is(:where(.group):hover *) {
@media (hover: hover) {
color: var(--color-blue-700);
}
}
}
.group-hover\:text-orange-500 {
&:is(:where(.group):hover *) {
@media (hover: hover) {
@ -2357,20 +2133,6 @@
}
}
}
.group-hover\:text-orange-600 {
&:is(:where(.group):hover *) {
@media (hover: hover) {
color: var(--color-orange-600);
}
}
}
.group-hover\:text-orange-700 {
&:is(:where(.group):hover *) {
@media (hover: hover) {
color: var(--color-orange-700);
}
}
}
.group-hover\:opacity-100 {
&:is(:where(.group):hover *) {
@media (hover: hover) {
@ -2412,13 +2174,6 @@
}
}
}
.hover\:border-blue-200 {
&:hover {
@media (hover: hover) {
border-color: var(--color-blue-200);
}
}
}
.hover\:border-orange-200 {
&:hover {
@media (hover: hover) {
@ -2489,6 +2244,13 @@
}
}
}
.hover\:bg-purple-600 {
&:hover {
@media (hover: hover) {
background-color: var(--color-purple-600);
}
}
}
.hover\:bg-red-50 {
&:hover {
@media (hover: hover) {
@ -2503,13 +2265,6 @@
}
}
}
.hover\:bg-slate-50 {
&:hover {
@media (hover: hover) {
background-color: var(--color-slate-50);
}
}
}
.hover\:bg-white\/10 {
&:hover {
@media (hover: hover) {
@ -2530,30 +2285,6 @@
}
}
}
.hover\:bg-gradient-to-br {
&:hover {
@media (hover: hover) {
--tw-gradient-position: to bottom right in oklab;
background-image: linear-gradient(var(--tw-gradient-stops));
}
}
}
.hover\:from-blue-50 {
&:hover {
@media (hover: hover) {
--tw-gradient-from: var(--color-blue-50);
--tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));
}
}
}
.hover\:from-orange-50 {
&:hover {
@media (hover: hover) {
--tw-gradient-from: var(--color-orange-50);
--tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));
}
}
}
.hover\:from-orange-600 {
&:hover {
@media (hover: hover) {
@ -2562,22 +2293,6 @@
}
}
}
.hover\:to-indigo-100 {
&:hover {
@media (hover: hover) {
--tw-gradient-to: var(--color-indigo-100);
--tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));
}
}
}
.hover\:to-orange-100 {
&:hover {
@media (hover: hover) {
--tw-gradient-to: var(--color-orange-100);
--tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));
}
}
}
.hover\:to-orange-500 {
&:hover {
@media (hover: hover) {
@ -2608,13 +2323,6 @@
}
}
}
.hover\:text-orange-700 {
&:hover {
@media (hover: hover) {
color: var(--color-orange-700);
}
}
}
.hover\:text-orange-800 {
&:hover {
@media (hover: hover) {
@ -2622,13 +2330,6 @@
}
}
}
.hover\:no-underline {
&:hover {
@media (hover: hover) {
text-decoration-line: none;
}
}
}
.hover\:shadow-lg {
&:hover {
@media (hover: hover) {
@ -2637,14 +2338,6 @@
}
}
}
.hover\:shadow-md {
&:hover {
@media (hover: hover) {
--tw-shadow: 0 4px 6px -1px var(--tw-shadow-color, rgb(0 0 0 / 0.1)), 0 2px 4px -2px var(--tw-shadow-color, rgb(0 0 0 / 0.1));
box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
}
}
}
.hover\:shadow-xl {
&:hover {
@media (hover: hover) {