This commit is contained in:
Your Name committed 2026-06-21 01:52:57 -04:00
1 parent c449de2482
commit 7e4e89e33c
50 files changed
+306 -140

No files matched your search

+1 -1
View File
@@ -44,7 +44,7 @@ export default function CartDrawer() {
<div key={item.cartItemId} className="group relative flex gap-4 rounded-2xl border border-line-primary/20 bg-surface-page/60 p-4">
<div className="relative h-24 w-20 flex-shrink-0 overflow-hidden rounded-lg bg-surface-card">
<Image
src={item.productImage || '/images/oil_ozone.png'}
src={item.productImage || '/images/fallback-product.svg'}
alt={item.productName}
fill
unoptimized
@@ -105,12 +105,12 @@ function toOrderItem(item: CartItem) {
function saveLocalOrder(orderId: number) {
try {
const existingValue = window.localStorage.getItem('homaroma_local_orders')
const existingValue = window.localStorage.getItem('app_local_orders')
const existing = existingValue ? JSON.parse(existingValue) : []
const orderIds = Array.isArray(existing) ? existing.filter((id) => typeof id === 'number') : []
if (!orderIds.includes(orderId)) {
window.localStorage.setItem('homaroma_local_orders', JSON.stringify([orderId, ...orderIds]))
window.localStorage.setItem('app_local_orders', JSON.stringify([orderId, ...orderIds]))
}
} catch (error) {
console.warn('[website-checkout] Failed to persist local order history', error)
@@ -193,7 +193,7 @@ export default function CheckoutClient() {
useEffect(() => {
queueMicrotask(() => {
const savedCoupon = window.localStorage.getItem('homaroma_active_coupon')
const savedCoupon = window.localStorage.getItem('app_active_coupon')
if (savedCoupon) setCouponCode(savedCoupon)
})
}, [])
@@ -242,7 +242,7 @@ export default function CheckoutClient() {
useEffect(() => {
if (!couponCode || appliedCoupon || subtotalAfterL2 <= 0) return
const savedCoupon = window.localStorage.getItem('homaroma_active_coupon')
const savedCoupon = window.localStorage.getItem('app_active_coupon')
if (!savedCoupon || savedCoupon !== couponCode) return
const applySavedCoupon = async () => {
@@ -258,10 +258,10 @@ export default function CheckoutClient() {
setDiscountAmount(data.discountAmount ?? 0)
setIsFreeShipping(Boolean(data.isFreeShipping))
} else {
window.localStorage.removeItem('homaroma_active_coupon')
window.localStorage.removeItem('app_active_coupon')
}
} catch {
window.localStorage.removeItem('homaroma_active_coupon')
window.localStorage.removeItem('app_active_coupon')
}
}
@@ -289,7 +289,7 @@ export default function CheckoutClient() {
setAppliedCoupon(data.coupon.code)
setDiscountAmount(data.discountAmount ?? 0)
setIsFreeShipping(Boolean(data.isFreeShipping))
window.localStorage.setItem('homaroma_active_coupon', data.coupon.code)
window.localStorage.setItem('app_active_coupon', data.coupon.code)
} catch (error) {
setAppliedCoupon(null)
setDiscountAmount(0)
@@ -306,7 +306,7 @@ export default function CheckoutClient() {
setDiscountAmount(0)
setIsFreeShipping(false)
setCouponError(null)
window.localStorage.removeItem('homaroma_active_coupon')
window.localStorage.removeItem('app_active_coupon')
}
const selectAddress = (address: CustomerAddress | 'new') => {
@@ -611,7 +611,7 @@ export default function CheckoutClient() {
<div key={item.cartItemId} className="flex gap-3">
<div className="relative h-16 w-14 shrink-0 overflow-hidden rounded-xl bg-surface-page">
<Image
src={item.productImage || '/images/oil_ozone.png'}
src={item.productImage || '/images/fallback-product.svg'}
alt={item.productName}
fill
unoptimized
+2 -2
View File
@@ -35,7 +35,7 @@ const LANGUAGES = [
function setLanguageCookie(code: string) {
if (typeof document !== 'undefined') {
document.cookie = `homaroma_lang=${code}; path=/; max-age=31536000`
document.cookie = `app_lang=${code}; path=/; max-age=31536000`
}
}
@@ -96,7 +96,7 @@ export default function Navbar({ categories = [], initialMenu = [], settings = n
const changeLanguage = (code: string) => {
i18n.changeLanguage(code)
localStorage.setItem('homaroma_lang', code)
localStorage.setItem('app_lang', code)
setLanguageCookie(code)
const currentPathWithoutLang = getPathWithoutLocale(pathname)
@@ -327,7 +327,7 @@ export default function ProfileClient() {
<div className="flex min-w-0 items-center gap-4">
<div className="ui-avatar-shell-sm relative shrink-0">
<Image
src={displayCustomer.pictureUrl || `https://ui-avatars.com/api/?name=${encodeURIComponent(displayCustomer.displayName || 'HomAroma')}`}
src={displayCustomer.pictureUrl || `https://ui-avatars.com/api/?name=${encodeURIComponent(displayCustomer.displayName || 'Member')}`}
alt={displayCustomer.displayName || 'LINE Profile'}
fill
unoptimized
@@ -335,7 +335,7 @@ export default function ProfileClient() {
/>
</div>
<div className="min-w-0">
<h1 className="truncate text-2xl font-semibold text-text-main">{displayCustomer.displayName || 'HomAroma Member'}</h1>
<h1 className="truncate text-2xl font-semibold text-text-main">{displayCustomer.displayName || 'Member'}</h1>
<div className="mt-2 flex flex-wrap gap-x-4 gap-y-1 text-xs font-semibold text-muted-text">
{displayCustomer.phone && <span className="inline-flex items-center gap-1"><Phone className="h-3 w-3" />{displayCustomer.phone}</span>}
{displayCustomer.email && <span className="inline-flex items-center gap-1"><Mail className="h-3 w-3" />{displayCustomer.email}</span>}
@@ -379,7 +379,7 @@ export default function ProfileClient() {
{activeTab === 'orders' && (
<div className="space-y-5">
{orders.length === 0 ? (
<EmptyPanel icon={Package} title="ไม่มีประวัติการสั่งซื้อ" description="คุณยังไม่ได้ทำการสั่งซื้อสินค้าใด ๆ กับ HomAroma" actionHref="/shop" actionText="ไปหน้าช้อปปิ้ง" />
<EmptyPanel icon={Package} title="ไม่มีประวัติการสั่งซื้อ" description="คุณยังไม่ได้ทำการสั่งซื้อสินค้าใด ๆ " actionHref="/shop" actionText="ไปหน้าช้อปปิ้ง" />
) : (
orders.map((order) => (
<article key={order.id} className="ui-panel p-6">
@@ -404,7 +404,7 @@ export default function ProfileClient() {
{order.items.map((item) => (
<div key={item.id} className="flex items-center gap-3 text-sm">
<div className="relative h-11 w-11 shrink-0 overflow-hidden rounded-xl bg-surface-page">
<Image src={item.productImage || '/images/oil_ozone.png'} alt={item.productName} fill unoptimized className="h-full w-full object-cover" />
<Image src={item.productImage || '/images/fallback-product.svg'} alt={item.productName} fill unoptimized className="h-full w-full object-cover" />
</div>
<div className="min-w-0 flex-1">
<p className="truncate font-semibold text-text-main">{item.productName}</p>
@@ -16,7 +16,7 @@ export default function ShopCouponBridge({ coupon }: ShopCouponBridgeProps) {
useEffect(() => {
if (!coupon) return
localStorage.setItem('homaroma_active_coupon', coupon)
localStorage.setItem('app_active_coupon', coupon)
router.replace(getPathWithLocale('/shop', lang), { scroll: false })
}, [coupon, router, lang])
@@ -41,14 +41,14 @@ export default function TrackOrderClient() {
const [error, setError] = useState<string | null>(null)
useEffect(() => {
const storedOrders = parseStoredOrders(localStorage.getItem('homaroma_local_orders'))
const storedOrders = parseStoredOrders(localStorage.getItem('app_local_orders'))
queueMicrotask(() => setLocalOrders(storedOrders))
}, [])
const saveLocalOrder = (id: number) => {
setLocalOrders((current) => {
const next = [id, ...current.filter((item) => item !== id)].slice(0, 12)
localStorage.setItem('homaroma_local_orders', JSON.stringify(next))
localStorage.setItem('app_local_orders', JSON.stringify(next))
return next
})
}
@@ -115,7 +115,7 @@ function HeroSection({ payload, lang }: { payload: Record<string, unknown>, lang
<section className="ui-hero-shell">
<Image
src={imageUrl}
alt={title || 'HomAroma'}
alt={title || ''}
fill
unoptimized
className="absolute inset-0 h-full w-full scale-[1.02] object-cover"
@@ -130,7 +130,7 @@ function HeroSection({ payload, lang }: { payload: Record<string, unknown>, lang
</p>
)}
<h1 className="ui-hero-title">
{renderAccentTitle(title || 'HomAroma')}
{renderAccentTitle(title || '')}
</h1>
{description && (
<p className="ui-hero-copy">