diff --git a/src/components/storefront/HydrationOverlay.jsx b/src/components/storefront/HydrationOverlay.jsx
new file mode 100644
index 0000000..048bf68
--- /dev/null
+++ b/src/components/storefront/HydrationOverlay.jsx
@@ -0,0 +1,67 @@
+const shimmer = 'animate-pulse bg-gradient-to-r from-gray-200 via-gray-100 to-gray-200'
+
+export function HydrationOverlay() {
+ return (
+
+
+
+
+
+ {[1, 2, 3].map((item) => (
+
+ ))}
+
+
+
+
+
+
+
+
+
+
+
+ {Array.from({ length: 8 }).map((_, index) => (
+
+ ))}
+
+
+
+
+
+
+ )
+}
diff --git a/src/components/storefront/Navbar.jsx b/src/components/storefront/Navbar.jsx
index a24cea1..0a9d2c0 100644
--- a/src/components/storefront/Navbar.jsx
+++ b/src/components/storefront/Navbar.jsx
@@ -1,26 +1,92 @@
-import { useState, useEffect } from 'react'
+import { useState, useEffect, useCallback } from 'react'
import { normalizeImageUrl } from '../../lib/utils'
-import { Link } from 'react-router-dom'
+import { Link, useNavigate } from 'react-router-dom'
import { Button } from '../ui/button'
import { useCart } from '../../contexts/CartContext'
import { ShoppingCart } from 'lucide-react'
-export function Navbar() {
- const [collections, setCollections] = useState([])
+const defaultStoreSettings = {
+ logoType: 'text',
+ logoText: 'OpenShop',
+ logoImageUrl: ''
+}
+
+export function Navbar({
+ initialCollections = [],
+ initialProducts = [],
+ initialStoreSettings = null
+}) {
+ const [collections, setCollections] = useState(initialCollections)
+ const [products, setProducts] = useState(initialProducts)
const [collectionsWithProducts, setCollectionsWithProducts] = useState([])
const [storeSettings, setStoreSettings] = useState({
- logoType: 'text',
- logoText: 'OpenShop',
- logoImageUrl: ''
+ ...defaultStoreSettings,
+ ...(initialStoreSettings || {})
})
const [mobileMenuOpen, setMobileMenuOpen] = useState(false)
const { itemCount, toggleCart } = useCart()
+ const navigate = useNavigate()
+ const hasInitialCollections = initialCollections.length > 0
+ const hasInitialProducts = initialProducts.length > 0
+ const hasInitialSettings = Boolean(initialStoreSettings)
+
+ const handleLogoClick = useCallback((event) => {
+ if (
+ event.defaultPrevented ||
+ event.button !== 0 ||
+ event.metaKey ||
+ event.altKey ||
+ event.ctrlKey ||
+ event.shiftKey
+ ) {
+ return
+ }
+
+ event.preventDefault()
+ setMobileMenuOpen(false)
+ navigate('/')
+
+ if (typeof window !== 'undefined') {
+ window.scrollTo({ top: 0, behavior: 'auto' })
+ }
+ }, [navigate])
useEffect(() => {
- // Fetch collections, products, and store settings for navigation
- fetchCollectionsAndProducts()
- fetchStoreSettings()
- }, [])
+ setCollections(initialCollections)
+ }, [initialCollections])
+
+ useEffect(() => {
+ setProducts(initialProducts)
+ }, [initialProducts])
+
+ useEffect(() => {
+ if (initialStoreSettings) {
+ setStoreSettings(prev => ({
+ ...prev,
+ ...initialStoreSettings
+ }))
+ }
+ }, [initialStoreSettings])
+
+ useEffect(() => {
+ if (!hasInitialCollections || !hasInitialProducts) {
+ fetchCollectionsAndProducts()
+ }
+ }, [hasInitialCollections, hasInitialProducts])
+
+ useEffect(() => {
+ if (!hasInitialSettings) {
+ fetchStoreSettings()
+ }
+ }, [hasInitialSettings])
+
+ useEffect(() => {
+ const grouped = collections.map(collection => ({
+ ...collection,
+ products: products.filter(product => product.collectionId === collection.id)
+ }))
+ setCollectionsWithProducts(grouped)
+ }, [collections, products])
const fetchCollectionsAndProducts = async () => {
try {
@@ -34,14 +100,7 @@ export function Navbar() {
const productsData = await productsResponse.json()
setCollections(collectionsData)
-
- // Group products by collection
- const collectionsWithProducts = collectionsData.map(collection => ({
- ...collection,
- products: productsData.filter(product => product.collectionId === collection.id)
- }))
-
- setCollectionsWithProducts(collectionsWithProducts)
+ setProducts(productsData)
}
} catch (error) {
console.error('Error fetching collections and products:', error)
@@ -53,7 +112,10 @@ export function Navbar() {
const response = await fetch('/api/store-settings')
if (response.ok) {
const data = await response.json()
- setStoreSettings(data)
+ setStoreSettings(prev => ({
+ ...prev,
+ ...data
+ }))
}
} catch (error) {
console.error('Error fetching store settings:', error)
@@ -65,7 +127,7 @@ export function Navbar() {
{/* Logo */}
-
+
{storeSettings.logoType === 'image' && storeSettings.logoImageUrl ? (
Home
@@ -203,7 +266,7 @@ export function Navbar() {
{/* Mobile menu button */}
-