This commit is contained in:
Your Name committed 2026-06-20 21:25:31 -04:00
1 parent 1d55e979da
commit cff34ac8aa
6 files changed
+28 -2

No files matched your search

@@ -8,6 +8,7 @@ export default function SystemSettingsPage() {
// Form State // Form State
const [brandName, setBrandName] = useState('') const [brandName, setBrandName] = useState('')
const [logoUrl, setLogoUrl] = useState('')
const [shippingFee, setShippingFee] = useState<string>('') const [shippingFee, setShippingFee] = useState<string>('')
const [bankName, setBankName] = useState('') const [bankName, setBankName] = useState('')
const [bankAccountName, setBankAccountName] = useState('') const [bankAccountName, setBankAccountName] = useState('')
@@ -31,6 +32,7 @@ export default function SystemSettingsPage() {
.then(r => r.json()) .then(r => r.json())
.then((data: StoreSettings) => { .then((data: StoreSettings) => {
setBrandName(data.brandName || 'HomAroma') setBrandName(data.brandName || 'HomAroma')
setLogoUrl(data.logoUrl || '')
setShippingFee(data.shippingFee.toString()) setShippingFee(data.shippingFee.toString())
setBankName(data.bankName || '') setBankName(data.bankName || '')
setBankAccountName(data.bankAccountName || '') setBankAccountName(data.bankAccountName || '')
@@ -61,6 +63,7 @@ export default function SystemSettingsPage() {
headers: { 'Content-Type': 'application/json' }, headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ body: JSON.stringify({
brandName, brandName,
logoUrl,
shippingFee: parseFloat(shippingFee) || 0, shippingFee: parseFloat(shippingFee) || 0,
bankName, bankName,
bankAccountName, bankAccountName,
@@ -224,6 +227,23 @@ export default function SystemSettingsPage() {
<p className="text-[10px] text-slate-500">This name is used by the website and spa header/footer as the brand display name.</p> <p className="text-[10px] text-slate-500">This name is used by the website and spa header/footer as the brand display name.</p>
</div> </div>
<div className="space-y-2">
<label className="text-xs uppercase font-bold tracking-widest text-slate-500">Logo URL</label>
<input
type="url"
value={logoUrl}
onChange={e => setLogoUrl(e.target.value)}
className="admin-input w-full max-w-sm"
placeholder="https://example.com/logo.png"
/>
<p className="text-[10px] text-slate-500">If provided, this image will be displayed instead of the text brand name in headers.</p>
{logoUrl && (
<div className="mt-2 p-2 bg-black/20 rounded-md inline-block">
<img src={logoUrl} alt="Logo Preview" className="h-8 object-contain" />
</div>
)}
</div>
<div className="space-y-2"> <div className="space-y-2">
<label className="text-xs uppercase font-bold tracking-widest text-slate-500">Footer Description</label> <label className="text-xs uppercase font-bold tracking-widest text-slate-500">Footer Description</label>
<textarea <textarea
@@ -0,0 +1,2 @@
-- AlterTable
ALTER TABLE "StoreSettings" ADD COLUMN "logoUrl" TEXT;
+1
View File
@@ -208,6 +208,7 @@ model Promotion {
model StoreSettings { model StoreSettings {
id Int @id @default(1) id Int @id @default(1)
brandName String @default("HomAroma") brandName String @default("HomAroma")
logoUrl String?
shippingFee Float @default(35) shippingFee Float @default(35)
bankName String @default("KASIKORNBANK (KBANK)") bankName String @default("KASIKORNBANK (KBANK)")
bankAccountName String @default("HomAroma Co., Ltd.") bankAccountName String @default("HomAroma Co., Ltd.")
+1
View File
@@ -45,6 +45,7 @@ export const settingsRoute = new Elysia({ prefix: "/settings" })
bankAccountName: t.String(), bankAccountName: t.String(),
bankAccountNumber: t.String(), bankAccountNumber: t.String(),
pointsEarnRate: t.Number(), pointsEarnRate: t.Number(),
logoUrl: t.Optional(t.String()),
facebookUrl: t.Optional(t.String()), facebookUrl: t.Optional(t.String()),
instagramUrl: t.Optional(t.String()), instagramUrl: t.Optional(t.String()),
tiktokUrl: t.Optional(t.String()), tiktokUrl: t.Optional(t.String()),
+1 -1
View File
@@ -65,7 +65,7 @@ export default function Footer({ categories = [] }: FooterProps) {
<div className="max-w-7xl mx-auto grid grid-cols-1 md:grid-cols-4 gap-12"> <div className="max-w-7xl mx-auto grid grid-cols-1 md:grid-cols-4 gap-12">
<div className="space-y-6"> <div className="space-y-6">
<div className="text-2xl font-bold tracking-widest"> <div className="text-2xl font-bold tracking-widest">
{brandName} {settings?.logoUrl ? <img src={settings.logoUrl} alt={brandName} className="h-8 md:h-10 object-contain" /> : brandName}
</div> </div>
<p className="text-slate-500 text-sm leading-relaxed"> <p className="text-slate-500 text-sm leading-relaxed">
{settings?.footerDescription || t('footer.catchphrase')} {settings?.footerDescription || t('footer.catchphrase')}
+3 -1
View File
@@ -146,6 +146,8 @@ export default function Navbar({ topOffsetClassName = 'top-0' }: NavbarProps) {
const finalTopClassName = scrolled ? 'top-0' : computedOffset const finalTopClassName = scrolled ? 'top-0' : computedOffset
const brandName = settings?.brandName || '' const brandName = settings?.brandName || ''
const logoUrl = settings?.logoUrl || ''
return ( return (
<> <>
<nav <nav
@@ -160,7 +162,7 @@ export default function Navbar({ topOffsetClassName = 'top-0' }: NavbarProps) {
{/* Left: Logo */} {/* Left: Logo */}
<div className="flex items-center shrink-0"> <div className="flex items-center shrink-0">
<Link to="/" onClick={() => setMobileOpen(false)} className="text-xl md:text-2xl font-bold tracking-widest text-spa-forest uppercase italic shrink-0"> <Link to="/" onClick={() => setMobileOpen(false)} className="text-xl md:text-2xl font-bold tracking-widest text-spa-forest uppercase italic shrink-0">
{brandName} {logoUrl ? <img src={logoUrl} alt={brandName} className="h-8 md:h-10 object-contain" /> : brandName}
</Link> </Link>
</div> </div>