summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiqdad <ahmadmiqdad27@gmail.com>2025-09-30 16:20:05 +0700
committerMiqdad <ahmadmiqdad27@gmail.com>2025-09-30 16:20:05 +0700
commit352000c186a2765416cd2fab6693e68bb62e9e53 (patch)
treef979f04cb39a7afc3cad6f7ea5d0035cea31240f
parent117be0f4b29ef8eb5622f7bf300fec570677cc23 (diff)
<Miqdad> done
-rw-r--r--app/login/page.tsx2
-rw-r--r--app/page.tsx150
2 files changed, 133 insertions, 19 deletions
diff --git a/app/login/page.tsx b/app/login/page.tsx
index 3ccefa4..c0d7ab8 100644
--- a/app/login/page.tsx
+++ b/app/login/page.tsx
@@ -154,7 +154,7 @@ const Login = () => {
<div className="bg-[#fafeff] h-screen overflow-auto">
<Header />
<div className="py-4 px-4 sm:px-96 pt-20">
- <div className="bg-white py-6 px-4 sm:px-96 shadow-md rounded-sm">
+ <div className="py-6 px-4 sm:px-96 shadow-md rounded-sm text-black">
<Typography
component="h1"
variant="h4"
diff --git a/app/page.tsx b/app/page.tsx
index 4841c09..add141f 100644
--- a/app/page.tsx
+++ b/app/page.tsx
@@ -6,7 +6,7 @@ import SjCamera from "./lib/camera/component/sjCamera";
import DispatchCamera from "./lib/camera/component/dispatchCamera";
import useCameraStore from "./lib/camera/hooks/useCameraStore";
import Header from "./lib/camera/component/hedear";
-import { Button } from "@mui/material";
+import { Button, FormControl, InputLabel, MenuItem, Select, FormHelperText } from "@mui/material";
import { SaveAsOutlined } from "@mui/icons-material";
import axios from "axios";
import odooApi from "./lib/api/odooApi";
@@ -16,11 +16,15 @@ import { getAuth } from "./lib/api/auth";
import { getCookie } from "cookies-next";
type Role = "driver" | "dispatch";
+type ShipMethod = "" | "self_pickup" | "indoteknik_delivery" | "ekspedisi";
export default function Home() {
const [isLogin, setIsLogin] = useState<boolean>(true);
const [isDriver, setIsDriver] = useState<boolean>(false);
const [isDispatch, setIsDispatch] = useState<boolean>(false);
+ const [shippingMethod, setShippingMethod] = useState<ShipMethod>("");
+ const [shipTouched, setShipTouched] = useState(false);
+
const {
barcode,
@@ -42,7 +46,6 @@ export default function Home() {
router.push("/login");
return;
}
- // baca role dari cookie yang diset saat login
const roleCookie = (getCookie("web_role") as string | undefined)?.toLowerCase() as Role | undefined;
const role: Role | null = roleCookie === "driver" || roleCookie === "dispatch" ? roleCookie : null;
@@ -61,16 +64,25 @@ export default function Home() {
return;
}
- // Validasi sesuai role yang dipilih di login
+ // Dispatch: shipping method wajib
+ if (isDispatch) setShipTouched(true);
+ if (isDispatch && !shippingMethod) {
+ alert("Shipping Method wajib dipilih.");
+ setIsLoading(false);
+ return;
+ }
+
+
+ // Validasi foto sesuai role & shipping method
if (isDispatch) {
- // Dispatch: dispatch wajib, SJ opsional
if (!imageDispatch) {
alert("Foto Dispatch Wajib Diisi");
setIsLoading(false);
return;
}
+ // SJ opsional untuk self_pickup & ekspedisi → tidak divalidasi
} else {
- // Driver (atau non-dispatch): SJ & Penerima wajib
+ // Driver: SJ & Penerima wajib
if (!imageSj || !imagePackage) {
alert("Barcode, Foto SJ, dan Foto Penerima harus tersedia.");
setIsLoading(false);
@@ -79,7 +91,6 @@ export default function Home() {
}
try {
- // siapkan base64 tanpa prefix, kalau kosong biarkan undefined
const newSjImage = imageSj ? imageSj.replace(/^.*?,/, "") : undefined;
const newPackageImage = imagePackage ? imagePackage.replace(/^.*?,/, "") : undefined;
const newDispatchImage =
@@ -87,15 +98,17 @@ export default function Home() {
? imageDispatch.replace(/^.*?,/, "")
: imageDispatch || undefined;
- // hanya kirim field yang ada
+ // Kirim hanya yang ada
const submittedSj = !!newSjImage;
const submittedPackage = !!newPackageImage;
- const submittedDispatch = !!newDispatchImage && !isDriver; // dispatch hanya untuk non-driver
+ const submittedDispatch = !!newDispatchImage && !isDriver;
const data: Record<string, string> = {};
if (submittedSj) data.sj_document = newSjImage!;
if (submittedPackage) data.paket_document = newPackageImage!;
if (submittedDispatch) data.dispatch_document = newDispatchImage!;
+ // (opsional) kirim shippingMethod jika backend mau simpan
+ if (isDispatch && shippingMethod) data.shipping_method = shippingMethod;
const response = (await odooApi(
"PUT",
@@ -106,7 +119,7 @@ export default function Home() {
if (response?.status?.code === 200) {
alert("Berhasil Submit Data");
setBarcode("");
-
+ // Bersihkan HANYA yang dikirim
if (submittedSj) setImageSj("");
if (submittedPackage) setImagePackage("");
if (submittedDispatch) setImageDispatch("");
@@ -128,6 +141,19 @@ export default function Home() {
}
};
+ // dispatch: SJ hanya utk self_pickup & ekspedisi
+ const showSjForDispatch =
+ isDispatch && (shippingMethod === "self_pickup" || shippingMethod === "ekspedisi");
+
+ // dispatch: kamera dispatch tampil utk semua method (asal sudah dipilih)
+ const showDispatchForDispatch = isDispatch && shippingMethod !== "";
+
+ // preview SJ: sembunyikan kalau dispatch belum pilih method
+ const showSjPreview = !!imageSj && (!isDispatch || showSjForDispatch);
+
+ // preview Dispatch: sembunyikan kalau dispatch belum pilih method
+ const showDispatchPreview = !!imageDispatch && (!isDispatch || showDispatchForDispatch);
+
return (
<div className="bg-white h-screen overflow-auto">
<Header />
@@ -138,27 +164,95 @@ export default function Home() {
<BarcodeScanner />
</div>
+ {/* Shipping Method (khusus dispatch) */}
+ {isDispatch && (
+ <div className="mt-4">
+ <FormControl fullWidth size="small" required error={shipTouched && !shippingMethod}>
+ {/* shrink = kunci agar label tidak tumpuk dengan placeholder */}
+ <InputLabel id="shipping-label" shrink>Shipping Method</InputLabel>
+ <Select
+ labelId="shipping-label"
+ id="shipping"
+ label="Shipping Method"
+ value={shippingMethod}
+ displayEmpty
+ onChange={(e) => setShippingMethod(e.target.value as ShipMethod)}
+ onBlur={() => setShipTouched(true)}
+ renderValue={(selected) => {
+ if (!selected) return <span style={{ opacity: 0.6 }}>Pilih Shipping Method</span>;
+ const map: Record<string, string> = {
+ self_pickup: "Self Pickup",
+ indoteknik_delivery: "Indoteknik Delivery",
+ ekspedisi: "Ekspedisi",
+ };
+ return map[selected as string] ?? "";
+ }}
+ >
+ <MenuItem value="">
+ <em>Pilih Shipping Method</em>
+ </MenuItem>
+ <MenuItem value="self_pickup">Self Pickup</MenuItem>
+ <MenuItem value="indoteknik_delivery">Indoteknik Delivery</MenuItem>
+ <MenuItem value="ekspedisi">Ekspedisi</MenuItem>
+ </Select>
+ {shipTouched && !shippingMethod && (
+ <FormHelperText>Wajib pilih shipping method.</FormHelperText>
+ )}
+ </FormControl>
+ </div>
+ )}
+
+
<div className="h-4" />
<div className="flex justify-between">
- {/* SJ: driver wajib, dispatch opsional → tampil untuk semua */}
- <SjCamera />
- {/* Penerima: tidak diperlukan dispatch → sembunyikan saat dispatch */}
- {!isDispatch && <PackageCamera />}
- {/* Dispatch: wajib untuk dispatch; non-driver boleh tampil */}
- {!isDriver && <DispatchCamera />}
+ {isDispatch ? (
+ <>
+ {showSjForDispatch && <SjCamera />}
+ {showDispatchForDispatch && <DispatchCamera />}
+ {/* dispatch TIDAK perlu kamera penerima */}
+ </>
+ ) : (
+ <>
+ {/* driver / non-dispatch */}
+ <SjCamera />
+ <PackageCamera />
+ {/* driver tidak menampilkan kamera dispatch */}
+ </>
+ )}
</div>
+
<div className="h-2" />
- {imageSj && (
+ {/* Preview SJ */}
+ {showSjPreview && (
<>
<label className="block mt-2 text-sm font-medium text-gray-700 text-center">
Gambar Foto Surat Jalan
</label>
<div className="relative w-full h-[300px] border-2 border-gray-200 p-2 rounded-sm">
<Image
- src={imageSj}
+ src={imageSj!}
+ alt="Captured"
+ fill
+ unoptimized
+ className="p-2"
+ style={{ objectFit: "cover" }}
+ />
+ </div>
+ </>
+ )}
+
+ {/* Preview Penerima (hanya non-dispatch) */}
+ {!isDispatch && imagePackage && (
+ <>
+ <label className="block mt-2 text-sm font-medium text-gray-700 text-center">
+ Gambar Foto Penerima
+ </label>
+ <div className="relative w-full h-[300px] border-2 border-gray-200 p-2 rounded-sm">
+ <Image
+ src={imagePackage}
alt="Captured"
fill
unoptimized
@@ -169,9 +263,29 @@ export default function Home() {
</>
)}
+ {/* Preview Dispatch */}
+ {showDispatchPreview && (
+ <>
+ <label className="block mt-2 text-sm font-medium text-gray-700 text-center">
+ Gambar Foto Dispatch
+ </label>
+ <div className="relative w-full h-[300px] border-2 border-gray-200 p-2 rounded-sm">
+ <Image
+ src={imageDispatch}
+ alt="Captured"
+ fill
+ unoptimized
+ className="p-2"
+ style={{ objectFit: "cover" }}
+ />
+ </div>
+ </>
+ )}
+
+
<div className="h-2" />
- {imagePackage && (
+ {!isDispatch && imagePackage && (
<>
<label className="block mt-2 text-sm font-medium text-gray-700 text-center">
Gambar Foto Penerima