diff --git a/src/app/(dashboard)/products/page.tsx b/src/app/(dashboard)/products/page.tsx index 614612d..c8c22d4 100644 --- a/src/app/(dashboard)/products/page.tsx +++ b/src/app/(dashboard)/products/page.tsx @@ -30,6 +30,8 @@ interface ProductRow { totalStock: number; } +type ProductState = "UNPUBLISHED" | "DELETED_BY_SELLER" | "DELETED_BY_ADMIN" | string; + function getToken() { if (typeof window === "undefined") { return ""; @@ -184,6 +186,8 @@ function ProductsPageInner() { const [unpublishTarget, setUnpublishTarget] = useState(null); const [deleting, setDeleting] = useState(false); const [unpublishing, setUnpublishing] = useState(false); + const [publishingId, setPublishingId] = useState(null); + const [restoringId, setRestoringId] = useState(null); // Reset to page 1 when tab changes useEffect(() => { @@ -263,6 +267,7 @@ function ProductsPageInner() { } async function handleRestore(productId: string) { + setRestoringId(productId); try { const res = await fetch(`/api/products/${productId}?action=restore`, { method: "PUT", @@ -277,9 +282,37 @@ function ProductsPageInner() { window.location.reload(); } catch (err) { alert(err instanceof Error ? err.message : p.restoreError); + } finally { + setRestoringId(null); } } + async function handlePublish(productId: string) { + setPublishingId(productId); + try { + const res = await fetch(`/api/products/${productId}?action=publish`, { + method: "PUT", + headers: { "x-auth-token": getToken() }, + }); + const result = await res.json().catch(() => ({})); + + if (!res.ok) { + throw new Error(result?.responseDesc || p.publishError); + } + + window.location.reload(); + } catch (err) { + alert(err instanceof Error ? err.message : p.publishError); + } + finally { + setPublishingId(null); + } + } + + function getProductState(product: ProductRow): ProductState { + return (product.state || product.status || product.reviewStatus || "").toUpperCase(); + } + const internationalCount = rows.filter( (row) => row.market === "International" ).length; @@ -411,6 +444,12 @@ function ProductsPageInner() { ) : ( rows.map((product) => { + const productState = getProductState(product); + const isInactiveInAllTab = + activeTab === "All Product" && + (productState === "UNPUBLISHED" || + productState === "DELETED_BY_SELLER" || + productState === "DELETED_BY_ADMIN"); const stockTone = product.totalStock === 0 ? "red" @@ -441,7 +480,7 @@ function ProductsPageInner() { fill sizes="44px" className={`object-cover ${ - stockTone === "red" ? "grayscale" : "" + stockTone === "red" || isInactiveInAllTab ? "grayscale" : "" }`} /> ) : ( @@ -453,7 +492,7 @@ function ProductsPageInner() {

{product.market}

- {!isInReviewTab ? ( - !isDeletedTab ? ( - - {p.edit} - - ) : null - ) : null} - - {p.detail} - {isDeletedTab ? ( + productState === "DELETED_BY_ADMIN" ? ( + + {p.deletedByAdmin} + + ) : ( + + ) + ) : productState === "UNPUBLISHED" ? ( + + ) : productState === "DELETED_BY_SELLER" ? ( ) : ( <> + {!isInReviewTab ? ( + !isDeletedTab ? ( + + {p.edit} + + ) : null + ) : null} + + {p.detail} + {canUnpublish ? ( - ) : ( + ) : productState === "UNPUBLISHED" ? ( + ) : productState === "DELETED_BY_SELLER" ? ( + + ) : ( + <> + + Detail + + + )}
- ))} + )})}
diff --git a/src/app/api/products/[productId]/route.ts b/src/app/api/products/[productId]/route.ts index f835618..572e65e 100644 --- a/src/app/api/products/[productId]/route.ts +++ b/src/app/api/products/[productId]/route.ts @@ -41,11 +41,13 @@ export async function PUT( const isDraft = req.nextUrl.searchParams.get("draft") === "1"; const action = req.nextUrl.searchParams.get("action"); - if (action === "unpublish" || action === "restore") { + if (action === "unpublish" || action === "restore" || action === "publish") { const endpoint = action === "unpublish" ? `${API_URL}/api/v1.0/seller/product/${productId}/unpublish` - : `${API_URL}/api/v1.0/seller/product/${productId}/restore`; + : action === "restore" + ? `${API_URL}/api/v1.0/seller/product/${productId}/restore` + : `${API_URL}/api/v1.0/seller/product/${productId}/publish`; const res = await fetch(endpoint, { method: "PUT", diff --git a/src/app/layout.tsx b/src/app/layout.tsx index a930506..284b497 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -56,7 +56,7 @@ export default function RootLayout({ {/* eslint-disable-next-line @next/next/no-page-custom-font */} diff --git a/src/lib/translations/en.ts b/src/lib/translations/en.ts index 0e67a0f..5abd866 100644 --- a/src/lib/translations/en.ts +++ b/src/lib/translations/en.ts @@ -358,8 +358,10 @@ export const en = { empty: "No products found.", edit: "Edit", detail: "Detail", + publish: "Publish", restore: "Restore", unpublish: "Unpublish", + deletedByAdmin: "Deleted by admin", table: { product: "Product", price: "Price", @@ -389,6 +391,7 @@ export const en = { errorGeneric: "Failed to unpublish product", }, restoreError: "Failed to restore product", + publishError: "Failed to publish product", tabs: { allProduct: "All Product", draft: "Draft", diff --git a/src/lib/translations/id.ts b/src/lib/translations/id.ts index 2814d74..94778d8 100644 --- a/src/lib/translations/id.ts +++ b/src/lib/translations/id.ts @@ -359,8 +359,10 @@ export const id = { empty: "Tidak ada produk ditemukan.", edit: "Edit", detail: "Detail", + publish: "Publish", restore: "Restore", unpublish: "Unpublish", + deletedByAdmin: "Dihapus oleh admin", table: { product: "Produk", price: "Harga", @@ -390,6 +392,7 @@ export const id = { errorGeneric: "Gagal unpublish produk", }, restoreError: "Gagal restore produk", + publishError: "Gagal publish produk", tabs: { allProduct: "Semua Produk", draft: "Draft",