x
This commit is contained in:
1 parent
c449de2482
commit
7e4e89e33c
50 files changed
+306
-140
No files matched your search
@@ -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
|
||||
|
||||
@@ -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">
|
||||
|
||||
Reference in new issue
Block a user