fix: Refine Store Details UX and currency display

## Changes

### 1. Split Store Identity and Brand Cards 

**Before:** Single tall "Store Identity" card
**After:** Two focused cards

**Store Identity Card:**
- Store name
- Store tagline
- Contact email
- Customer support email
- Store phone

**Brand Card:**
- Store logo
- Store icon
- Brand colors (Primary, Accent, Error)
- Reset to default button

**Result:** Better organization, easier to scan

---

### 2. Fix Currency Symbol Fallback 

**Issue:** When currency has no symbol (like AUD), showed € instead
**Screenshot:** Preview showed "€1.234.568" for Australian dollar

**Fix:**
```typescript
// Get currency symbol from currencies data, fallback to currency code
const currencyInfo = currencies.find((c: any) => c.code === settings.currency);
let symbol = settings.currency; // Default to currency code

if (currencyInfo?.symbol && !currencyInfo.symbol.includes('&#')) {
  // Use symbol only if it exists and doesn't contain HTML entities
  symbol = currencyInfo.symbol;
}
```

**Result:**
- AUD → Shows "AUD1234" instead of "€1234"
- IDR → Shows "Rp1234" (has symbol)
- USD → Shows "$1234" (has symbol)
- Currencies without symbols → Show currency code

---

### 3. Move Overview Card to First Position 

**Before:** Overview card at the bottom
**After:** Overview card at the top

**Rationale:**
- Quick glance at store location, currency, timezone
- Sets context for the rest of the settings
- Industry standard (Shopify shows overview first)

**Card Content:**
```
📍 Store Location: Australia
Currency: Australian dollar • Timezone: Australia/Sydney
```

---

## Final Card Order

1. **Store Overview** (new position)
2. **Store Identity** (name, tagline, contacts)
3. **Brand** (logo, icon, colors)
4. **Store Address**
5. **Currency & Formatting**
6. **Standards & Formats**

**Result:** Logical flow, better UX, professional layout
This commit is contained in:
dwindown
2025-11-10 22:23:35 +07:00
parent 66a194155c
commit fa2ae6951b

View File

@@ -200,7 +200,14 @@ export default function StoreDetailsPage() {
.replace('.', settings.decimalSep)
.replace(/\B(?=(\d{3})+(?!\d))/g, settings.thousandSep);
const symbol = settings.currency === 'IDR' ? 'Rp' : settings.currency === 'USD' ? '$' : '€';
// Get currency symbol from currencies data, fallback to currency code
const currencyInfo = currencies.find((c: any) => c.code === settings.currency);
let symbol = settings.currency; // Default to currency code
if (currencyInfo?.symbol && !currencyInfo.symbol.includes('&#')) {
// Use symbol only if it exists and doesn't contain HTML entities
symbol = currencyInfo.symbol;
}
switch (settings.currencyPosition) {
case 'left':
@@ -223,6 +230,26 @@ export default function StoreDetailsPage() {
onSave={handleSave}
isLoading={isLoading}
>
{/* Store Overview */}
<div className="bg-primary/10 border border-primary/20 rounded-lg p-4">
{(() => {
const currencyFlag = flagsData.find((f: any) => f.code === settings.currency);
const currencyInfo = currencies.find((c: any) => c.code === settings.currency);
const countryName = currencyFlag?.country || settings.country;
return (
<>
<p className="text-sm font-medium">
📍 Store Location: {countryName}
</p>
<p className="text-sm text-muted-foreground mt-1">
Currency: {currencyInfo?.name || settings.currency} Timezone: {settings.timezone}
</p>
</>
);
})()}
</div>
{/* Store Identity */}
<SettingsCard
title="Store Identity"
@@ -237,6 +264,19 @@ export default function StoreDetailsPage() {
/>
</SettingsSection>
<SettingsSection
label="Store tagline"
description="A short tagline or slogan for your store"
htmlFor="storeTagline"
>
<Input
id="storeTagline"
value={settings.storeTagline}
onChange={(e) => updateSetting('storeTagline', e.target.value)}
placeholder="Quality products, delivered fast"
/>
</SettingsSection>
<SettingsSection
label="Contact email"
description="Customers will use this email to contact you"
@@ -278,20 +318,13 @@ export default function StoreDetailsPage() {
placeholder="+62 812 3456 7890"
/>
</SettingsSection>
</SettingsCard>
<SettingsSection
label="Store tagline"
description="A short tagline or slogan for your store"
htmlFor="storeTagline"
{/* Brand */}
<SettingsCard
title="Brand"
description="Logo, icon, and colors for your store"
>
<Input
id="storeTagline"
value={settings.storeTagline}
onChange={(e) => updateSetting('storeTagline', e.target.value)}
placeholder="Quality products, delivered fast"
/>
</SettingsSection>
<SettingsSection label="Store logo" description="Recommended: 200x60px PNG with transparent background">
<ImageUpload
value={settings.storeLogo}
@@ -309,13 +342,9 @@ export default function StoreDetailsPage() {
maxSize={1}
/>
</SettingsSection>
</SettingsCard>
{/* Brand Colors */}
<SettingsCard
title="Brand Colors"
description="Customize your admin interface colors"
>
<div className="pt-4 border-t">
<h4 className="text-sm font-medium mb-4">Brand Colors</h4>
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
<ColorPicker
label="Primary Color"
@@ -339,7 +368,7 @@ export default function StoreDetailsPage() {
/>
</div>
<div className="flex items-center gap-2 mt-4 pt-4 border-t">
<div className="flex items-center gap-2 mt-4">
<Button
type="button"
variant="outline"
@@ -357,6 +386,7 @@ export default function StoreDetailsPage() {
Changes apply after saving
</p>
</div>
</div>
</SettingsCard>
{/* Store Address */}
@@ -562,26 +592,6 @@ export default function StoreDetailsPage() {
</SettingsSection>
</div>
</SettingsCard>
{/* Summary Card - Professional, No Flag */}
<div className="bg-primary/10 border border-primary/20 rounded-lg p-4">
{(() => {
const currencyFlag = flagsData.find((f: any) => f.code === settings.currency);
const currencyInfo = currencies.find((c: any) => c.code === settings.currency);
const countryName = currencyFlag?.country || settings.country;
return (
<>
<p className="text-sm font-medium">
📍 Store Location: {countryName}
</p>
<p className="text-sm text-muted-foreground mt-1">
Currency: {currencyInfo?.name || settings.currency} Timezone: {settings.timezone}
</p>
</>
);
})()}
</div>
</SettingsLayout>
);
}