feat(cms): implement multi-language support across frontend and admin UI

This commit is contained in:
Your Name committed 2026-06-14 09:00:57 -04:00
1 parent 730e2a7b48
commit eac45dd4a7
62 files changed
+1377 -5116

No files matched your search

-186
View File
@@ -1,186 +0,0 @@
import { Elysia, t } from "elysia";
import prisma from "../lib/prisma";
export const couponsRoute = new Elysia({ prefix: "/coupons" })
// Get all coupons (Admin)
.get("/", async () => {
return await prisma.coupon.findMany({
orderBy: { createdAt: 'desc' }
});
})
// Get active coupons (Storefront)
.get("/active", async () => {
const now = new Date();
return await prisma.coupon.findMany({
where: {
isActive: true,
OR: [
{ expiresAt: null },
{ expiresAt: { gt: now } }
]
},
orderBy: { createdAt: 'desc' }
});
})
// Create new coupon (Admin)
.post("/", async ({ body, set }) => {
try {
const data = body;
// Check if code already exists
const existing = await prisma.coupon.findUnique({
where: { code: data.code.toUpperCase() }
});
if (existing) {
set.status = 400;
return { error: "Coupon code already exists" };
}
const coupon = await prisma.coupon.create({
data: {
code: data.code.toUpperCase(),
type: data.type,
value: data.value,
minPurchase: data.minPurchase || 0,
maxDiscount: data.maxDiscount || null,
usageLimit: data.usageLimit || null,
expiresAt: data.expiresAt ? new Date(data.expiresAt) : null,
isActive: data.isActive !== undefined ? data.isActive : true
}
});
return coupon;
}
catch (err) {
console.error("[Coupons] Create Error:", err);
set.status = 500;
return { error: "Failed to create coupon" };
}
}, {
body: t.Object({
code: t.String(),
type: t.String(),
value: t.Number(),
minPurchase: t.Optional(t.Number()),
maxDiscount: t.Optional(t.Nullable(t.Number())),
usageLimit: t.Optional(t.Nullable(t.Number())),
expiresAt: t.Optional(t.Nullable(t.String())),
isActive: t.Optional(t.Boolean())
})
})
// Update coupon (Admin)
.patch("/:id", async ({ params: { id }, body, set }) => {
try {
const data = body;
const coupon = await prisma.coupon.update({
where: { id: Number(id) },
data: {
...(data.code && { code: data.code.toUpperCase() }),
...(data.type && { type: data.type }),
...(data.value !== undefined && { value: data.value }),
...(data.minPurchase !== undefined && { minPurchase: data.minPurchase }),
...(data.maxDiscount !== undefined && { maxDiscount: data.maxDiscount }),
...(data.usageLimit !== undefined && { usageLimit: data.usageLimit }),
...(data.expiresAt !== undefined && { expiresAt: data.expiresAt ? new Date(data.expiresAt) : null }),
...(data.isActive !== undefined && { isActive: data.isActive })
}
});
return coupon;
}
catch (err) {
console.error("[Coupons] Update Error:", err);
set.status = 500;
return { error: "Failed to update coupon" };
}
}, {
body: t.Object({
code: t.Optional(t.String()),
type: t.Optional(t.String()),
value: t.Optional(t.Number()),
minPurchase: t.Optional(t.Number()),
maxDiscount: t.Optional(t.Nullable(t.Number())),
usageLimit: t.Optional(t.Nullable(t.Number())),
expiresAt: t.Optional(t.Nullable(t.String())),
isActive: t.Optional(t.Boolean())
})
})
// Delete coupon (Admin)
.delete("/:id", async ({ params: { id }, set }) => {
try {
await prisma.coupon.delete({
where: { id: Number(id) }
});
return { success: true };
}
catch (err) {
set.status = 500;
return { error: "Failed to delete coupon" };
}
})
// Validate coupon (Storefront)
.post("/validate", async ({ body, set }) => {
try {
const { code, cartTotal } = body;
const upperCode = code.toUpperCase();
const coupon = await prisma.coupon.findUnique({
where: { code: upperCode }
});
if (!coupon) {
set.status = 404;
return { valid: false, error: "Coupon not found" };
}
if (!coupon.isActive) {
set.status = 400;
return { valid: false, error: "Coupon is no longer active" };
}
if (coupon.expiresAt && new Date() > coupon.expiresAt) {
set.status = 400;
return { valid: false, error: "Coupon has expired" };
}
if (coupon.usageLimit && coupon.usedCount >= coupon.usageLimit) {
set.status = 400;
return { valid: false, error: "Coupon usage limit reached" };
}
if (cartTotal < coupon.minPurchase) {
set.status = 400;
return { valid: false, error: `Minimum purchase of ฿${coupon.minPurchase} required` };
}
// Calculate discount amount
let discountAmount = 0;
if (coupon.type === "PERCENTAGE") {
discountAmount = cartTotal * (coupon.value / 100);
if (coupon.maxDiscount && discountAmount > coupon.maxDiscount) {
discountAmount = coupon.maxDiscount;
}
}
else if (coupon.type === "FIXED_AMOUNT") {
discountAmount = coupon.value;
}
else if (coupon.type === "FREE_SHIPPING") {
// We handle free shipping separately, returning discountAmount = 0 but a flag
return {
valid: true,
coupon,
discountAmount: 0,
isFreeShipping: true
};
}
// Ensure discount doesn't exceed cart total
if (discountAmount > cartTotal) {
discountAmount = cartTotal;
}
return {
valid: true,
coupon,
discountAmount,
isFreeShipping: false
};
}
catch (err) {
console.error("[Coupons] Validate Error:", err);
set.status = 500;
return { error: "Failed to validate coupon" };
}
}, {
body: t.Object({
code: t.String(),
cartTotal: t.Number()
})
});
//# sourceMappingURL=coupons.js.map