diff --git a/HANDOFF.md b/HANDOFF.md index 908b472..52e1e73 100644 --- a/HANDOFF.md +++ b/HANDOFF.md @@ -22,6 +22,41 @@ npx tsc --noEmit ## Latest Codex Changes After `76fb4f3` +### Product create preorder and warranty submit rules + +Files: +- `src/app/(dashboard)/products/new/details/page.tsx` +- `src/app/(dashboard)/products/new/specifications/page.tsx` +- `src/app/(dashboard)/products/new/review/page.tsx` +- `src/lib/product-draft.tsx` +- `src/lib/use-product-submit.ts` +- `src/lib/product-request-validation.ts` + +Behavior: +- Pre-order day placeholder is now `0`, not `14`, so an empty/unfilled value is visually obvious. +- If pre-order is checked, the Details step blocks Next unless `preOrderDay` is a valid number greater than or equal to 1. +- Warranty now has an On/Off switch in the Specifications step. +- When warranty is On: + - warranty type is required + - warranty duration must be greater than or equal to 1 + - the review page shows warranty information + - submit payload sends the filled `warrantyInformation` object +- When warranty is Off: + - warranty inputs are disabled and dimmed + - the review page hides warranty information + - submit payload still sends `warrantyInformation` as an object required by the backend, with: + +```json +{ + "type": null, + "duration": null, + "durationType": "MONTH" +} +``` + +- Frontend payload validation treats the above null-valued warranty object as warranty Off, so it does not block submit with warranty type/duration errors. +- Local test server was rebuilt and restarted against `https://api-dev.inatrading.co.id` in `.env.local`; `.env.local` is not committed. + ### AddProductRequest validation Files: diff --git a/src/app/(dashboard)/products/new/details/page.tsx b/src/app/(dashboard)/products/new/details/page.tsx index 82f3345..1f58fe8 100644 --- a/src/app/(dashboard)/products/new/details/page.tsx +++ b/src/app/(dashboard)/products/new/details/page.tsx @@ -171,6 +171,7 @@ export default function ProductDetailsPage() { const { submit, submitting } = useProductSubmit(); const { t } = useLanguage(); const d = t.dashboard.productNew.details; + const [preOrderError, setPreOrderError] = useState(""); const [keywordInput, setKeywordInput] = useState(""); const keywordLimitReached = draft.keywords.filter(Boolean).length >= MAX_KEYWORDS; const featureLimitReached = draft.features.length >= MAX_FEATURES; @@ -249,6 +250,17 @@ export default function ProductDetailsPage() { })); } + function goToPricing() { + const preOrderDay = Number(draft.preOrderDay); + if (draft.isPreOrder && (!Number.isFinite(preOrderDay) || preOrderDay < 1)) { + setPreOrderError("Hari pre-order wajib diisi minimal 1 hari."); + return; + } + + setPreOrderError(""); + router.push("/products/new/pricing"); + } + return (
- Minimal 1 hari jika pre-order aktif. +
+ {preOrderError || "Minimal 1 hari jika pre-order aktif."}