Fix button roundtrip in editor, alignment persistence, and test email rendering
This commit is contained in:
@@ -36,13 +36,15 @@ export default function AppearanceGeneral() {
|
||||
friendly: { name: 'Friendly', fonts: 'Poppins + Open Sans' },
|
||||
elegant: { name: 'Elegant', fonts: 'Cormorant + Lato' },
|
||||
};
|
||||
|
||||
|
||||
const [colors, setColors] = useState({
|
||||
primary: '#1a1a1a',
|
||||
secondary: '#6b7280',
|
||||
accent: '#3b82f6',
|
||||
text: '#111827',
|
||||
background: '#ffffff',
|
||||
gradientStart: '#9333ea', // purple-600 defaults
|
||||
gradientEnd: '#3b82f6', // blue-500 defaults
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
@@ -51,7 +53,7 @@ export default function AppearanceGeneral() {
|
||||
// Load appearance settings
|
||||
const response = await api.get('/appearance/settings');
|
||||
const general = response.data?.general;
|
||||
|
||||
|
||||
if (general) {
|
||||
if (general.spa_mode) setSpaMode(general.spa_mode);
|
||||
if (general.spa_page) setSpaPage(general.spa_page || 0);
|
||||
@@ -70,10 +72,12 @@ export default function AppearanceGeneral() {
|
||||
accent: general.colors.accent || '#3b82f6',
|
||||
text: general.colors.text || '#111827',
|
||||
background: general.colors.background || '#ffffff',
|
||||
gradientStart: general.colors.gradientStart || '#9333ea',
|
||||
gradientEnd: general.colors.gradientEnd || '#3b82f6',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Load available pages
|
||||
const pagesResponse = await api.get('/pages/list');
|
||||
console.log('Pages API response:', pagesResponse);
|
||||
@@ -90,7 +94,7 @@ export default function AppearanceGeneral() {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
loadSettings();
|
||||
}, []);
|
||||
|
||||
@@ -108,7 +112,7 @@ export default function AppearanceGeneral() {
|
||||
},
|
||||
colors,
|
||||
});
|
||||
|
||||
|
||||
toast.success('General settings saved successfully');
|
||||
} catch (error) {
|
||||
console.error('Save error:', error);
|
||||
@@ -139,7 +143,7 @@ export default function AppearanceGeneral() {
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div className="flex items-start space-x-3">
|
||||
<RadioGroupItem value="checkout_only" id="spa-checkout" />
|
||||
<div className="space-y-1">
|
||||
@@ -151,7 +155,7 @@ export default function AppearanceGeneral() {
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div className="flex items-start space-x-3">
|
||||
<RadioGroupItem value="full" id="spa-full" />
|
||||
<div className="space-y-1">
|
||||
@@ -175,14 +179,14 @@ export default function AppearanceGeneral() {
|
||||
<Alert>
|
||||
<AlertCircle className="h-4 w-4" />
|
||||
<AlertDescription>
|
||||
This page will render the full SPA to the body element with no theme interference.
|
||||
This page will render the full SPA to the body element with no theme interference.
|
||||
The SPA Mode above determines the initial route (shop or cart). React Router handles navigation via /#/ routing.
|
||||
</AlertDescription>
|
||||
</Alert>
|
||||
|
||||
|
||||
<SettingsSection label="SPA Entry Page" htmlFor="spa-page">
|
||||
<Select
|
||||
value={spaPage.toString()}
|
||||
<Select
|
||||
value={spaPage.toString()}
|
||||
onValueChange={(value) => setSpaPage(parseInt(value))}
|
||||
>
|
||||
<SelectTrigger id="spa-page">
|
||||
@@ -246,7 +250,7 @@ export default function AppearanceGeneral() {
|
||||
<p className="text-sm text-muted-foreground mb-3">
|
||||
Self-hosted fonts, no external requests
|
||||
</p>
|
||||
|
||||
|
||||
{typographyMode === 'predefined' && (
|
||||
<Select value={predefinedPair} onValueChange={setPredefinedPair}>
|
||||
<SelectTrigger className="w-full min-w-[300px] [&>span]:line-clamp-none [&>span]:whitespace-normal">
|
||||
@@ -284,7 +288,7 @@ export default function AppearanceGeneral() {
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div className="flex items-start space-x-3">
|
||||
<RadioGroupItem value="custom_google" id="typo-custom" />
|
||||
<div className="space-y-1 flex-1">
|
||||
@@ -297,7 +301,7 @@ export default function AppearanceGeneral() {
|
||||
Using Google Fonts may not be GDPR compliant
|
||||
</AlertDescription>
|
||||
</Alert>
|
||||
|
||||
|
||||
{typographyMode === 'custom_google' && (
|
||||
<div className="space-y-3 mt-3">
|
||||
<SettingsSection label="Heading Font" htmlFor="heading-font">
|
||||
@@ -321,7 +325,7 @@ export default function AppearanceGeneral() {
|
||||
</div>
|
||||
</div>
|
||||
</RadioGroup>
|
||||
|
||||
|
||||
<div className="space-y-3 pt-4 border-t">
|
||||
<Label>Font Scale: {fontScale[0].toFixed(1)}x</Label>
|
||||
<Slider
|
||||
@@ -345,18 +349,18 @@ export default function AppearanceGeneral() {
|
||||
>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
{Object.entries(colors).map(([key, value]) => (
|
||||
<SettingsSection key={key} label={key.charAt(0).toUpperCase() + key.slice(1)} htmlFor={`color-${key}`}>
|
||||
<SettingsSection key={key} label={key.charAt(0).toUpperCase() + key.slice(1).replace(/([A-Z])/g, ' $1')} htmlFor={`color-${key}`}>
|
||||
<div className="flex gap-2">
|
||||
<Input
|
||||
id={`color-${key}`}
|
||||
type="color"
|
||||
value={value}
|
||||
value={value as string}
|
||||
onChange={(e) => setColors({ ...colors, [key]: e.target.value })}
|
||||
className="w-20 h-10 cursor-pointer"
|
||||
/>
|
||||
<Input
|
||||
type="text"
|
||||
value={value}
|
||||
value={value as string}
|
||||
onChange={(e) => setColors({ ...colors, [key]: e.target.value })}
|
||||
className="flex-1 font-mono"
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user