feat: implement user profile, order history, and address book with checkout integration

This commit is contained in:
Your Name committed 2026-06-07 18:48:56 +07:00
1 parent bae945b9d4
commit 0c3c450e1f
9 files changed
+1109 -32

No files matched your search

+162
View File
@@ -0,0 +1,162 @@
import { Elysia, t } from "elysia";
import prisma from "../lib/prisma";
export const profileRoute = new Elysia({ prefix: "/profile" })
.get("/:customerId", async ({ params: { customerId }, set }) => {
const customer = await prisma.customer.findUnique({
where: { id: Number(customerId) },
include: { addresses: true }
});
if (!customer) {
set.status = 404;
return { error: "Customer not found" };
}
return customer;
})
.put("/:customerId", async ({ params: { customerId }, body, set }) => {
try {
const { email, phone } = body as any;
const customer = await prisma.customer.update({
where: { id: Number(customerId) },
data: {
email: email || null,
phone: phone || null
}
});
return customer;
} catch (err: any) {
set.status = 500;
return { error: err.message || "Failed to update customer profile" };
}
}, {
body: t.Object({
email: t.Optional(t.Nullable(t.String())),
phone: t.Optional(t.Nullable(t.String()))
})
})
.get("/:customerId/addresses", async ({ params: { customerId } }) => {
return await prisma.customerAddress.findMany({
where: { customerId: Number(customerId) },
orderBy: { isDefault: 'desc' }
});
})
.post("/:customerId/addresses", async ({ params: { customerId }, body, set }) => {
try {
const { recipientName, phone, addressLine, subdistrict, district, province, zipcode, isDefault } = body as any;
const cId = Number(customerId);
// If isDefault is true, unset other defaults first
if (isDefault) {
await prisma.customerAddress.updateMany({
where: { customerId: cId },
data: { isDefault: false }
});
}
const address = await prisma.customerAddress.create({
data: {
customerId: cId,
recipientName,
phone,
addressLine,
subdistrict,
district,
province,
zipcode,
isDefault: !!isDefault
}
});
return address;
} catch (err: any) {
set.status = 500;
return { error: err.message || "Failed to create address" };
}
}, {
body: t.Object({
recipientName: t.String(),
phone: t.String(),
addressLine: t.String(),
subdistrict: t.String(),
district: t.String(),
province: t.String(),
zipcode: t.String(),
isDefault: t.Boolean()
})
})
.put("/:customerId/addresses/:addressId", async ({ params: { customerId, addressId }, body, set }) => {
try {
const { recipientName, phone, addressLine, subdistrict, district, province, zipcode, isDefault } = body as any;
const cId = Number(customerId);
const aId = Number(addressId);
// If setting as default, unset other defaults first
if (isDefault) {
await prisma.customerAddress.updateMany({
where: { customerId: cId },
data: { isDefault: false }
});
}
const address = await prisma.customerAddress.update({
where: { id: aId },
data: {
recipientName,
phone,
addressLine,
subdistrict,
district,
province,
zipcode,
isDefault: !!isDefault
}
});
return address;
} catch (err: any) {
set.status = 500;
return { error: err.message || "Failed to update address" };
}
}, {
body: t.Object({
recipientName: t.String(),
phone: t.String(),
addressLine: t.String(),
subdistrict: t.String(),
district: t.String(),
province: t.String(),
zipcode: t.String(),
isDefault: t.Boolean()
})
})
.delete("/:customerId/addresses/:addressId", async ({ params: { addressId }, set }) => {
try {
await prisma.customerAddress.delete({
where: { id: Number(addressId) }
});
return { success: true };
} catch (err: any) {
set.status = 500;
return { error: err.message || "Failed to delete address" };
}
})
.patch("/:customerId/addresses/:addressId/default", async ({ params: { customerId, addressId }, set }) => {
try {
const cId = Number(customerId);
const aId = Number(addressId);
// Unset other defaults
await prisma.customerAddress.updateMany({
where: { customerId: cId },
data: { isDefault: false }
});
// Set this one as default
const address = await prisma.customerAddress.update({
where: { id: aId },
data: { isDefault: true }
});
return address;
} catch (err: any) {
set.status = 500;
return { error: err.message || "Failed to set default address" };
}
});