From d803e2e524ba61754e5dc5e377d9081fdcd4b7ff Mon Sep 17 00:00:00 2001 From: AJ Frio Date: Thu, 19 Feb 2026 11:15:40 -0700 Subject: [PATCH] Add collapsible panel to store settings editor --- src/components/admin/StoreSettingsEditor.jsx | 530 +++++++++---------- 1 file changed, 258 insertions(+), 272 deletions(-) diff --git a/src/components/admin/StoreSettingsEditor.jsx b/src/components/admin/StoreSettingsEditor.jsx index f4b70b7..1829c01 100644 --- a/src/components/admin/StoreSettingsEditor.jsx +++ b/src/components/admin/StoreSettingsEditor.jsx @@ -1,5 +1,4 @@ import { useState, useEffect, useMemo } from 'react' -import { Card, CardContent, CardHeader, CardTitle } from '../ui/card' import { Input } from '../ui/input' import { Button } from '../ui/button' import { Select } from '../ui/select' @@ -21,8 +20,9 @@ import { import { Navbar } from '../../components/storefront/Navbar' import { Hero } from '../../components/storefront/Hero' import { ProductCard } from '../../components/storefront/ProductCard' +import { Carousel } from '../../components/storefront/Carousel' import { Footer } from '../../components/storefront/Footer' -import { Paintbrush, Type, Layout, Image as ImageIcon, Info, MapPin, Mail } from 'lucide-react' +import { Paintbrush, Type, Layout, Image as ImageIcon, Info, MapPin, PanelLeftClose, PanelLeftOpen } from 'lucide-react' const MOCK_PRODUCTS = [ { @@ -57,6 +57,12 @@ const MOCK_PRODUCTS = [ } ] +const MOCK_COLLECTIONS = [ + { id: 'featured', name: 'Featured' }, + { id: 'workspace', name: 'Workspace' }, + { id: 'audio', name: 'Audio' }, +] + const COLOR_GROUPS = [ { title: 'Brand Colors', @@ -129,6 +135,8 @@ function sanitizeHexInput(value) { export function StoreSettingsEditor() { const [activeSection, setActiveSection] = useState('theme') + const [previewPage, setPreviewPage] = useState('home') + const [editorCollapsed, setEditorCollapsed] = useState(false) const [settings, setSettings] = useState({ logoType: 'text', logoText: 'OpenShop', @@ -151,7 +159,6 @@ export function StoreSettingsEditor() { businessPostalCode: '', businessCountry: '' }) - const [loading, setLoading] = useState(false) const [saving, setSaving] = useState(false) const [modalImage, setModalImage] = useState(null) const [savedOpen, setSavedOpen] = useState(false) @@ -209,7 +216,6 @@ export function StoreSettingsEditor() { const fetchSettings = async () => { try { - setLoading(true) const response = await fetch('/api/store-settings') if (response.ok) { const data = await response.json() @@ -225,8 +231,6 @@ export function StoreSettingsEditor() { } } catch (error) { console.error('Error fetching store settings:', error) - } finally { - setLoading(false) } } @@ -425,53 +429,71 @@ export function StoreSettingsEditor() { ] return ( -
- {/* Sidebar Controls */} -
-
-

Store Editor

-

Real-time preview

+
+
+
+
+

Store settings

+

Edit content on the left and compare with a storefront-accurate preview.

+
+
+
+ + +
+ +
+
- {/* Navigation Tabs */} -
- {menuItems.map(item => { - const Icon = item.icon - return ( - - ) - })} -
+
+ {!editorCollapsed && ( +
+
+ {menuItems.map((item) => { + const Icon = item.icon + return ( + + ) + })} +
- {/* Form Area */} -
- {activeSection === 'theme' && ( -
-
-

Theme

- -
+
- {COLOR_GROUPS.map((group) => ( + {COLOR_GROUPS.map((group) => (

{group.title}

@@ -504,26 +526,18 @@ export function StoreSettingsEditor() {
- handleThemeFontChange(event.target.value)}> {FONT_OPTIONS.map((font) => ( - + ))} +

Active font: {selectedFontOption.label}

- +
@@ -540,242 +554,214 @@ export function StoreSettingsEditor() {
-
- )} +
+ )} - {activeSection === 'identity' && ( -
-

Brand Identity

-
- - + {activeSection === 'identity' && ( +
+

Brand Identity

+
+ + +
+ + {settings.logoType === 'text' ? ( +
+ + +
+ ) : ( +
+ + setSettings((prev) => ({ ...prev, logoImageUrl: val }))} + placeholder="https://example.com/logo.png" + onPreview={(src) => setModalImage(src)} + hideInput + /> + {driveNotice &&

{driveNotice}

} +

Recommended size: 200x50px

+
+ )}
+ )} - {settings.logoType === 'text' ? ( + {activeSection === 'info' && ( +
+

Store Info

- - + +
- ) : ( -
- +
+ + +
+
+ )} + + {activeSection === 'hero' && ( +
+

Homepage Hero

+
+ setSettings(prev => ({ ...prev, logoImageUrl: val }))} - placeholder="https://example.com/logo.png" + value={settings.heroImageUrl} + onChange={(val) => setSettings((prev) => ({ ...prev, heroImageUrl: val }))} + placeholder="https://example.com/hero.jpg" onPreview={(src) => setModalImage(src)} hideInput /> - {driveNotice && ( -

{driveNotice}

- )} -

Recommended size: 200x50px

- )} -
- )} - - {activeSection === 'info' && ( -
-

Store Info

-
- - -
- -
- - +
+ + +
+
+ + +
-
- )} + )} - {activeSection === 'hero' && ( -
-

Homepage Hero

-
- - setSettings(prev => ({ ...prev, heroImageUrl: val }))} - placeholder="https://example.com/hero.jpg" - onPreview={(src) => setModalImage(src)} - hideInput - /> -
-
- - -
-
- - -
-
- )} - - {activeSection === 'about' && ( -
-

About Page

-
- - setSettings(prev => ({ ...prev, aboutHeroImageUrl: val }))} - placeholder="https://example.com/about-hero.jpg" - onPreview={(src) => setModalImage(src)} - hideInput - /> -
-
- - -
-
- - -
-
- -