Skip to content

Commit 6b61a2c

Browse files
committed
Ini bug cik
1 parent 623ef07 commit 6b61a2c

5 files changed

Lines changed: 243 additions & 8 deletions

File tree

app/(dashboard)/admin/products/new/page.tsx

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ const AddNewProduct = () => {
3333
const [merchants, setMerchants] = useState<Merchant[]>([]);
3434
const addProduct = async () => {
3535
if (
36+
!product.merchantId ||
3637
product.title === "" ||
3738
product.manufacturer === "" ||
3839
product.description == "" ||
@@ -59,6 +60,7 @@ const AddNewProduct = () => {
5960
.then((data) => {
6061
toast.success("Product added successfully");
6162
setProduct({
63+
merchantId: "",
6264
title: "",
6365
price: 0,
6466
manufacturer: "",
@@ -74,6 +76,20 @@ const AddNewProduct = () => {
7476
});
7577
};
7678

79+
const fetchMerchants = async () => {
80+
try {
81+
const res = await apiClient.get("/api/merchants");
82+
const data: Merchant[] = await res.json();
83+
setMerchants(data || []);
84+
setProduct((prev) => ({
85+
...prev,
86+
merchantId: prev.merchantId || data?.[0]?.id || "",
87+
}));
88+
} catch (e) {
89+
toast.error("Failed to load merchants");
90+
}
91+
};
92+
7793
const uploadFile = async (file: any) => {
7894
const formData = new FormData();
7995
formData.append("uploadedFile", file);
@@ -102,6 +118,7 @@ const AddNewProduct = () => {
102118
.then((data) => {
103119
setCategories(data);
104120
setProduct({
121+
merchantId: product.merchantId || "",
105122
title: "",
106123
price: 0,
107124
manufacturer: "",
@@ -116,6 +133,7 @@ const AddNewProduct = () => {
116133

117134
useEffect(() => {
118135
fetchCategories();
136+
fetchMerchants();
119137
}, []);
120138

121139
return (
@@ -128,14 +146,24 @@ const AddNewProduct = () => {
128146
<div className="label">
129147
<span className="label-text">Merchant Info:</span>
130148
</div>
131-
<input
132-
type="text"
133-
className="input input-bordered w-full max-w-xs"
134-
value={product?.title}
149+
<select
150+
className="select select-bordered"
151+
value={product?.merchantId}
135152
onChange={(e) =>
136-
setProduct({ ...product, title: e.target.value })
153+
setProduct({ ...product, merchantId: e.target.value })
137154
}
138-
/>
155+
>
156+
{merchants.map((merchant) => (
157+
<option key={merchant.id} value={merchant.id}>
158+
{merchant.name}
159+
</option>
160+
))}
161+
</select>
162+
{merchants.length === 0 && (
163+
<span className="text-xs text-red-500 mt-1">
164+
Please create a merchant first.
165+
</span>
166+
)}
139167
</label>
140168
</div>
141169

prisma/schema.prisma

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ model Product {
2727
category Category @relation(fields: [categoryId], references: [id], onDelete: Cascade)
2828
customerOrders customer_order_product[]
2929
Wishlist Wishlist[]
30+
31+
merchantId String
32+
merchant Merchant @relation(fields: [merchantId], references: [id])
3033
}
3134

3235
model Image {
@@ -84,3 +87,18 @@ model Wishlist {
8487
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
8588
userId String
8689
}
90+
91+
model Merchant {
92+
id String @id @default(uuid())
93+
name String
94+
description String?
95+
email String?
96+
phone String?
97+
address String?
98+
status String @default("ACTIVE")
99+
createdAt DateTime @default(now())
100+
updatedAt DateTime @updatedAt
101+
102+
// relasi
103+
products Product[]
104+
}

server/controllers/products.js

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,7 @@ const getAllProductsOld = asyncHandler(async (request, response) => {
261261

262262
const createProduct = asyncHandler(async (request, response) => {
263263
const {
264+
merchantId,
264265
slug,
265266
title,
266267
mainImage,
@@ -271,13 +272,30 @@ const createProduct = asyncHandler(async (request, response) => {
271272
inStock,
272273
} = request.body;
273274

275+
if (!title) {
276+
throw new AppError("Missing required field: title", 400);
277+
}
278+
274279
// Basic validation
275-
if (!title || !slug || !price || !categoryId) {
276-
throw new AppError("Missing required fields: title, slug, price, and categoryId are required", 400);
280+
if (!merchantId) {
281+
throw new AppError("Missing required field: merchantId", 400);
282+
}
283+
284+
if (!slug) {
285+
throw new AppError("Missing required field: slug", 400);
286+
}
287+
288+
if (!price) {
289+
throw new AppError("Missing required field: price", 400);
290+
}
291+
292+
if (!categoryId) {
293+
throw new AppError("Missing required field: categoryId", 400);
277294
}
278295

279296
const product = await prisma.product.create({
280297
data: {
298+
merchantId,
281299
slug,
282300
title,
283301
mainImage,
@@ -296,6 +314,7 @@ const createProduct = asyncHandler(async (request, response) => {
296314
const updateProduct = asyncHandler(async (request, response) => {
297315
const { id } = request.params;
298316
const {
317+
merchantId,
299318
slug,
300319
title,
301320
mainImage,
@@ -329,6 +348,7 @@ const updateProduct = asyncHandler(async (request, response) => {
329348
id,
330349
},
331350
data: {
351+
merchantId: merchantId,
332352
title: title,
333353
mainImage: mainImage,
334354
slug: slug,

0 commit comments

Comments
 (0)