update: flow BG

main
marszayn 2026-04-23 13:46:50 +07:00
parent e728c4995b
commit 5d47f0e3a2
4 changed files with 174 additions and 50 deletions

View File

@ -22,18 +22,24 @@ namespace eSPJ.Controllers.SpjDriverUpstController
_env = env; _env = env;
} }
[HttpGet("")] [HttpGet("muatan")]
public IActionResult Index() public IActionResult Index()
{ {
return View("~/Views/Admin/Transport/SpjDriverUpst/Submit/Index.cshtml"); return View("~/Views/Admin/Transport/SpjDriverUpst/Submit/Index.cshtml");
} }
[HttpGet("struk")] [HttpGet("struk-rdf")]
public IActionResult Struk() public IActionResult StrukRDF()
{ {
return View("~/Views/Admin/Transport/SpjDriverUpst/Submit/Struk.cshtml"); return View("~/Views/Admin/Transport/SpjDriverUpst/Submit/Struk.cshtml");
} }
[HttpGet("struk-index")]
public IActionResult StrukIndex()
{
return View("~/Views/Admin/Transport/SpjDriverUpst/Submit/Struk_Index.cshtml");
}
[HttpPost("ocr-struk")] [HttpPost("ocr-struk")]
[IgnoreAntiforgeryToken] [IgnoreAntiforgeryToken]
public async Task<IActionResult> OcrStruk(IFormFile? Foto) public async Task<IActionResult> OcrStruk(IFormFile? Foto)
@ -44,9 +50,9 @@ namespace eSPJ.Controllers.SpjDriverUpstController
if (Foto.Length > 10 * 1024 * 1024) if (Foto.Length > 10 * 1024 * 1024)
return BadRequest(new { success = false, message = "Ukuran foto terlalu besar. Maksimal 10MB." }); return BadRequest(new { success = false, message = "Ukuran foto terlalu besar. Maksimal 10MB." });
var apiKey = _configuration["OpenRouter:OCRkey"]; var apiKey = _configuration["9Router:OCRkey"];
if (string.IsNullOrWhiteSpace(apiKey)) if (string.IsNullOrWhiteSpace(apiKey))
return StatusCode(500, new { success = false, message = "OpenRouter API key belum diset." }); return StatusCode(500, new { success = false, message = "9Router API key belum diset." });
byte[] fileBytes; byte[] fileBytes;
await using (var ms = new MemoryStream()) await using (var ms = new MemoryStream())
@ -61,7 +67,7 @@ namespace eSPJ.Controllers.SpjDriverUpstController
var payload = new var payload = new
{ {
model = "google/gemini-2.5-flash-image", model = "image-combo",
messages = new object[] messages = new object[]
{ {
new new
@ -102,7 +108,7 @@ namespace eSPJ.Controllers.SpjDriverUpstController
}; };
var json = JsonSerializer.Serialize(payload); var json = JsonSerializer.Serialize(payload);
var request = new HttpRequestMessage(HttpMethod.Post, "https://openrouter.ai/api/v1/chat/completions"); var request = new HttpRequestMessage(HttpMethod.Post, "http://10.50.50.61:20128/v1/chat/completions");
request.Headers.TryAddWithoutValidation("Authorization", $"Bearer {apiKey}"); request.Headers.TryAddWithoutValidation("Authorization", $"Bearer {apiKey}");
request.Headers.TryAddWithoutValidation("Accept", "application/json"); request.Headers.TryAddWithoutValidation("Accept", "application/json");
request.Headers.TryAddWithoutValidation("HTTP-Referer", "https://pesapakawan.dinaslhdki.id"); request.Headers.TryAddWithoutValidation("HTTP-Referer", "https://pesapakawan.dinaslhdki.id");

View File

@ -169,26 +169,6 @@
<p class="text-sm text-gray-500 text-center">Periksa dan lengkapi data struk sebelum submit.</p> <p class="text-sm text-gray-500 text-center">Periksa dan lengkapi data struk sebelum submit.</p>
</div> </div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">Timbang</label>
<div id="timbang-options" class="grid grid-cols-2 gap-3">
<label class="timbang-opt flex items-center gap-2 p-3 border-2 rounded-lg cursor-pointer transition-all border-upst bg-upst/5" data-value="TPA">
<input type="radio" name="Timbang" value="TPA" checked class="hidden">
<div class="w-4 h-4 rounded-full border-2 border-upst flex items-center justify-center shrink-0">
<div class="w-2 h-2 rounded-full bg-upst timbang-dot"></div>
</div>
<span class="text-sm font-medium text-gray-700">Timbangan TPA</span>
</label>
<label class="timbang-opt flex items-center gap-2 p-3 border-2 rounded-lg cursor-pointer transition-all border-gray-200" data-value="RDF">
<input type="radio" name="Timbang" value="RDF" class="hidden">
<div class="w-4 h-4 rounded-full border-2 border-gray-300 flex items-center justify-center shrink-0">
<div class="w-2 h-2 rounded-full bg-transparent timbang-dot"></div>
</div>
<span class="text-sm font-medium text-gray-700">Timbangan RDF</span>
</label>
</div>
</div>
<div class="grid grid-cols-1 gap-4"> <div class="grid grid-cols-1 gap-4">
<div> <div>
<label for="NomorStruk" class="block text-sm font-medium text-gray-700 mb-1">Nomor Struk <span class="text-red-500">*</span></label> <label for="NomorStruk" class="block text-sm font-medium text-gray-700 mb-1">Nomor Struk <span class="text-red-500">*</span></label>

View File

@ -0,0 +1,86 @@
@{
Layout = "~/Views/Admin/Transport/SpjDriver/Shared/_Layout.cshtml";
ViewData["Title"] = "Submit Struk";
}
@section Styles {
<link rel="stylesheet" href="@Url.Content("~/driver/css/scanner.css")" asp-append-version="true" />
}
<div class="max-w-sm mx-auto container bg-white min-h-screen">
<div class="bg-upst text-white px-6 pt-10 pb-16 rounded-b-[40px] shadow-lg relative overflow-hidden">
<div class="absolute top-0 right-0 w-32 h-32 bg-white/5 rounded-full -mr-16 -mt-16"></div>
<div class="flex items-center justify-between relative z-10">
<a href="@Url.Action("Index", "Home")" class="w-10 h-10 flex items-center justify-center bg-white/20 hover:bg-white/30 rounded-xl transition-colors">
<i class="w-5 h-5" data-lucide="arrow-left"></i>
</a>
<div class="text-center">
<h1 class="text-lg font-bold tracking-wide uppercase">Submit Struk</h1>
<p class="text-[10px] text-white/70 font-medium">Upload Struk SPJ</p>
</div>
<img src="@Url.Content("~/driver/upst_white.svg")" alt="UPST Logo" class="absolute top-6 left-8 w-20 h-auto opacity-20">
<div class="w-10"></div>
</div>
</div>
<div class="px-6 py-6">
<div class="mb-6">
<h2 class="text-xl font-semibold text-slate-900">Pilih Tempat Pembuangan</h2>
<p class="mt-1 text-sm text-slate-500">Lanjutkan ke halaman upload sesuai tempat pembuangan</p>
</div>
<div class="grid grid-cols-1 gap-4">
@* ini arahin ke halaman upload struk titik buang via api ya mas ebik *@
<a asp-controller="Submit" asp-action="TPA"
class="group relative overflow-hidden rounded-2xl border border-slate-200 bg-white p-5 transition-all duration-200 hover:-translate-y-0.5 hover:border-blue-300 hover:shadow-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2">
<div class="flex items-start justify-between gap-4">
<div class="flex items-start gap-4">
<div class="flex h-12 w-12 shrink-0 items-center justify-center rounded-xl bg-upst text-white ring-1 ring-blue-100">
<i class="h-5 w-5" data-lucide="building-2"></i>
</div>
<div>
<div class="mb-2 inline-flex items-center rounded-full bg-slate-100 px-2.5 py-1 text-xs font-medium text-slate-600">
Input Struk
</div>
<h3 class="text-base font-semibold text-slate-900">Titik Buang</h3>
</div>
</div>
<div class="mt-1 text-slate-300 transition-transform duration-200 group-hover:translate-x-1 group-hover:text-blue-500">
<i class="h-5 w-5" data-lucide="arrow-right"></i>
</div>
</div>
</a>
<a asp-controller="Submit" asp-action="StrukRDF"
class="group relative overflow-hidden rounded-2xl border border-slate-200 bg-white p-5 transition-all duration-200 hover:-translate-y-0.5 hover:border-emerald-300 hover:shadow-md focus:outline-none focus:ring-2 focus:ring-emerald-500 focus:ring-offset-2">
<div class="flex items-start justify-between gap-4">
<div class="flex items-start gap-4">
<div class="flex h-12 w-12 shrink-0 items-center justify-center rounded-xl bg-upst text-white ring-1 ring-emerald-100">
<i class="h-5 w-5" data-lucide="receipt-text"></i>
</div>
<div>
<div class="mb-2 inline-flex items-center rounded-full bg-slate-100 px-2.5 py-1 text-xs font-medium text-slate-600">
Input Struk
</div>
<h3 class="text-base font-semibold text-slate-900">RDF</h3>
</div>
</div>
<div class="mt-1 text-slate-300 transition-transform duration-200 group-hover:translate-x-1 group-hover:text-emerald-500">
<i class="h-5 w-5" data-lucide="arrow-right"></i>
</div>
</div>
</a>
</div>
</div>
<partial name="~/Views/Admin/Transport/SpjDriverUpst/Shared/Components/_Navigation.cshtml" />
</div>
</div>

View File

@ -1,4 +1,4 @@
/*! tailwindcss v4.2.4 | MIT License | https://tailwindcss.com */ /*! tailwindcss v4.1.18 | MIT License | https://tailwindcss.com */
@layer properties; @layer properties;
@layer theme, base, components, utilities; @layer theme, base, components, utilities;
@layer theme { @layer theme {
@ -51,6 +51,8 @@
--color-green-700: oklch(52.7% 0.154 150.069); --color-green-700: oklch(52.7% 0.154 150.069);
--color-green-800: oklch(44.8% 0.119 151.328); --color-green-800: oklch(44.8% 0.119 151.328);
--color-emerald-50: oklch(97.9% 0.021 166.113); --color-emerald-50: oklch(97.9% 0.021 166.113);
--color-emerald-100: oklch(95% 0.052 163.051);
--color-emerald-300: oklch(84.5% 0.143 164.978);
--color-emerald-400: oklch(76.5% 0.177 163.223); --color-emerald-400: oklch(76.5% 0.177 163.223);
--color-emerald-500: oklch(69.6% 0.17 162.48); --color-emerald-500: oklch(69.6% 0.17 162.48);
--color-emerald-600: oklch(59.6% 0.145 163.225); --color-emerald-600: oklch(59.6% 0.145 163.225);
@ -61,16 +63,20 @@
--color-blue-50: oklch(97% 0.014 254.604); --color-blue-50: oklch(97% 0.014 254.604);
--color-blue-100: oklch(93.2% 0.032 255.585); --color-blue-100: oklch(93.2% 0.032 255.585);
--color-blue-200: oklch(88.2% 0.059 254.128); --color-blue-200: oklch(88.2% 0.059 254.128);
--color-blue-300: oklch(80.9% 0.105 251.813);
--color-blue-400: oklch(70.7% 0.165 254.624); --color-blue-400: oklch(70.7% 0.165 254.624);
--color-blue-500: oklch(62.3% 0.214 259.815); --color-blue-500: oklch(62.3% 0.214 259.815);
--color-blue-600: oklch(54.6% 0.245 262.881); --color-blue-600: oklch(54.6% 0.245 262.881);
--color-blue-700: oklch(48.8% 0.243 264.376); --color-blue-700: oklch(48.8% 0.243 264.376);
--color-blue-800: oklch(42.4% 0.199 265.638); --color-blue-800: oklch(42.4% 0.199 265.638);
--color-blue-950: oklch(28.2% 0.091 267.935);
--color-indigo-50: oklch(96.2% 0.018 272.314); --color-indigo-50: oklch(96.2% 0.018 272.314);
--color-indigo-100: oklch(93% 0.034 272.788); --color-indigo-100: oklch(93% 0.034 272.788);
--color-indigo-300: oklch(78.5% 0.115 274.713); --color-indigo-300: oklch(78.5% 0.115 274.713);
--color-purple-50: oklch(97.7% 0.014 308.299); --color-purple-50: oklch(97.7% 0.014 308.299);
--color-purple-100: oklch(94.6% 0.033 307.174);
--color-purple-300: oklch(82.7% 0.119 306.383);
--color-purple-500: oklch(62.7% 0.265 303.9);
--color-purple-600: oklch(55.8% 0.288 302.321);
--color-pink-50: oklch(97.1% 0.014 343.198); --color-pink-50: oklch(97.1% 0.014 343.198);
--color-rose-50: oklch(96.9% 0.015 12.422); --color-rose-50: oklch(96.9% 0.015 12.422);
--color-rose-500: oklch(64.5% 0.246 16.439); --color-rose-500: oklch(64.5% 0.246 16.439);
@ -336,15 +342,6 @@
.inset-x-4 { .inset-x-4 {
inset-inline: calc(var(--spacing) * 4); inset-inline: calc(var(--spacing) * 4);
} }
.\!start {
inset-inline-start: var(--spacing) !important;
}
.-start {
inset-inline-start: calc(var(--spacing) * -1);
}
.start {
inset-inline-start: var(--spacing);
}
.start-0 { .start-0 {
inset-inline-start: calc(var(--spacing) * 0); inset-inline-start: calc(var(--spacing) * 0);
} }
@ -354,12 +351,6 @@
.start-100 { .start-100 {
inset-inline-start: calc(var(--spacing) * 100); inset-inline-start: calc(var(--spacing) * 100);
} }
.-end {
inset-inline-end: calc(var(--spacing) * -1);
}
.end {
inset-inline-end: var(--spacing);
}
.end-0 { .end-0 {
inset-inline-end: calc(var(--spacing) * 0); inset-inline-end: calc(var(--spacing) * 0);
} }
@ -2679,6 +2670,9 @@
.text-slate-50 { .text-slate-50 {
color: var(--color-slate-50); color: var(--color-slate-50);
} }
.text-slate-300 {
color: var(--color-slate-300);
}
.text-slate-400 { .text-slate-400 {
color: var(--color-slate-400); color: var(--color-slate-400);
} }
@ -2841,6 +2835,12 @@
--tw-ring-color: color-mix(in oklab, var(--color-black) 5%, transparent); --tw-ring-color: color-mix(in oklab, var(--color-black) 5%, transparent);
} }
} }
.ring-blue-100 {
--tw-ring-color: var(--color-blue-100);
}
.ring-emerald-100 {
--tw-ring-color: var(--color-emerald-100);
}
.ring-gray-200 { .ring-gray-200 {
--tw-ring-color: var(--color-gray-200); --tw-ring-color: var(--color-gray-200);
} }
@ -2993,6 +2993,14 @@
} }
} }
} }
.group-hover\:translate-x-1 {
&:is(:where(.group):hover *) {
@media (hover: hover) {
--tw-translate-x: calc(var(--spacing) * 1);
translate: var(--tw-translate-x) var(--tw-translate-y);
}
}
}
.group-hover\:-translate-y-1 { .group-hover\:-translate-y-1 {
&:is(:where(.group):hover *) { &:is(:where(.group):hover *) {
@media (hover: hover) { @media (hover: hover) {
@ -3018,6 +3026,20 @@
} }
} }
} }
.group-hover\:text-blue-500 {
&:is(:where(.group):hover *) {
@media (hover: hover) {
color: var(--color-blue-500);
}
}
}
.group-hover\:text-emerald-500 {
&:is(:where(.group):hover *) {
@media (hover: hover) {
color: var(--color-emerald-500);
}
}
}
.group-hover\:text-gray-500 { .group-hover\:text-gray-500 {
&:is(:where(.group):hover *) { &:is(:where(.group):hover *) {
@media (hover: hover) { @media (hover: hover) {
@ -3170,6 +3192,20 @@
} }
} }
} }
.hover\:border-blue-300 {
&:hover {
@media (hover: hover) {
border-color: var(--color-blue-300);
}
}
}
.hover\:border-emerald-300 {
&:hover {
@media (hover: hover) {
border-color: var(--color-emerald-300);
}
}
}
.hover\:border-green-400 { .hover\:border-green-400 {
&:hover { &:hover {
@media (hover: hover) { @media (hover: hover) {
@ -3462,6 +3498,16 @@
box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow); box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
} }
} }
.focus\:ring-blue-500 {
&:focus {
--tw-ring-color: var(--color-blue-500);
}
}
.focus\:ring-emerald-500 {
&:focus {
--tw-ring-color: var(--color-emerald-500);
}
}
.focus\:ring-gray-200 { .focus\:ring-gray-200 {
&:focus { &:focus {
--tw-ring-color: var(--color-gray-200); --tw-ring-color: var(--color-gray-200);
@ -3487,6 +3533,12 @@
--tw-ring-color: var(--color-red-200); --tw-ring-color: var(--color-red-200);
} }
} }
.focus\:ring-offset-2 {
&:focus {
--tw-ring-offset-width: 2px;
--tw-ring-offset-shadow: var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
}
}
.focus\:outline-none { .focus\:outline-none {
&:focus { &:focus {
--tw-outline-style: none; --tw-outline-style: none;