1- import { useState , useCallback , useEffect , lazy , Suspense } from "react" ;
1+ import { lazy , Suspense , useEffect } from "react" ;
22import { Toaster } from "@/components/ui/toaster" ;
33import { Toaster as Sonner } from "@/components/ui/sonner" ;
44import { TooltipProvider } from "@/components/ui/tooltip" ;
55import { QueryClient , QueryClientProvider } from "@tanstack/react-query" ;
6- import { BrowserRouter , Routes , Route , useLocation } from "react-router-dom" ;
7- import { useCartSync } from "@/hooks/useCartSync" ;
6+ import { BrowserRouter , Navigate , Route , Routes } from "react-router-dom" ;
87import { LanguageProvider } from "@/contexts/LanguageContext" ;
9- import SplashScreen from "@/components/SplashScreen" ;
10- import { useIncognitoStore } from "./stores/incognitoStore" ;
11- import AIConcierge from "./components/AIConcierge" ;
8+ import { useCartSync } from "@/hooks/useCartSync" ;
9+ import { verifyBrandDNA } from "@/lib/verifyBrandDNA" ;
1210
13- // Lazy-load route pages to reduce initial bundle & main-thread work
14- const Index = lazy ( ( ) => import ( "./pages/Index" ) ) ;
15- const Products = lazy ( ( ) => import ( "./pages/Products" ) ) ;
16- const ProductDetail = lazy ( ( ) => import ( "./pages/ProductDetail" ) ) ;
17- const NotFound = lazy ( ( ) => import ( "./pages/NotFound" ) ) ;
18- const Auth = lazy ( ( ) => import ( "./pages/Auth" ) ) ;
19- const BrandShowcase = lazy ( ( ) => import ( "./pages/BrandShowcase" ) ) ;
20- const LabTools = lazy ( ( ) => import ( "./pages/LabTools" ) ) ;
21- const Intelligence = lazy ( ( ) => import ( "./pages/Intelligence" ) ) ;
22- const AdminEnrichment = lazy ( ( ) => import ( "./pages/AdminEnrichment" ) ) ;
23- const Checkout = lazy ( ( ) => import ( "./pages/Checkout" ) ) ;
24- const Profile = lazy ( ( ) => import ( "./pages/Profile" ) ) ;
25- const Contact = lazy ( ( ) => import ( "./pages/Contact" ) ) ;
26- const Shop = lazy ( ( ) => import ( "./pages/Shop" ) ) ;
27- const Health = lazy ( ( ) => import ( "./pages/Health" ) ) ;
28- const MomBaby = lazy ( ( ) => import ( "./pages/MomBaby" ) ) ;
11+ import Index from "./pages/Index" ;
12+ import ProductDetail from "./pages/ProductDetail" ;
13+ import Collections from "./pages/Collections" ;
14+ import CollectionDetail from "./pages/CollectionDetail" ;
15+ import Brands from "./pages/Brands" ;
16+ import BrandVichy from "./pages/BrandVichy" ;
17+ import BestSellers from "./pages/BestSellers" ;
18+ import Offers from "./pages/Offers" ;
19+ import Contact from "./pages/Contact" ;
20+ import SkinConcerns from "./pages/SkinConcerns" ;
21+ import ConcernCollection from "./pages/ConcernCollection" ;
22+ import Wishlist from "./pages/Wishlist" ;
23+ import NotFound from "./pages/NotFound" ;
24+ import Auth from "./pages/Auth" ;
25+ import Account from "./pages/Account" ;
26+ import Philosophy from "./pages/Philosophy" ;
27+ import BulkUpload from "./pages/BulkUpload" ;
28+ import AdminOrders from "./pages/AdminOrders" ;
29+ import TrackOrder from "./pages/TrackOrder" ;
30+ import ManageProducts from "./pages/ManageProducts" ;
31+ import Shop from "./pages/Shop" ;
32+ import ShopAllOrganized from "./components/ShopAllOrganized" ;
33+ import DriverDashboard from "./pages/DriverDashboard" ;
34+ import AdminAuditLogs from "./pages/AdminAuditLogs" ;
35+ import AsperIntelligence from "./pages/AsperIntelligence" ;
36+ import BrandIntelligenceDashboard from "./pages/BrandIntelligenceDashboard" ;
37+ import Health from "./pages/Health" ;
38+ import { RequireAdmin } from "./components/RequireAdmin" ;
39+
40+ const BeautyAssistant = lazy ( ( ) =>
41+ import ( "@/components/BeautyAssistant" ) . then ( ( m ) => ( { default : m . BeautyAssistant } ) ) ,
42+ ) ;
2943
3044const queryClient = new QueryClient ( ) ;
3145
32- /** Scroll restoration: save/restore scroll position per route */
33- function ScrollRestoration ( ) {
34- const location = useLocation ( ) ;
35- useEffect ( ( ) => {
36- // Restore saved position for this path
37- const saved = sessionStorage . getItem ( `scroll-${ location . pathname } ` ) ;
38- if ( saved ) {
39- requestAnimationFrame ( ( ) => window . scrollTo ( 0 , parseInt ( saved , 10 ) ) ) ;
40- } else {
41- window . scrollTo ( 0 , 0 ) ;
42- }
43- // Save position on leave
44- return ( ) => {
45- sessionStorage . setItem ( `scroll-${ location . pathname } ` , String ( window . scrollY ) ) ;
46- } ;
47- } , [ location . pathname ] ) ;
48- return null ;
46+ // Cart sync wrapper component
47+ function CartSyncProvider ( { children } : { children : React . ReactNode } ) {
48+ useCartSync ( ) ;
49+ return < > { children } </ > ;
4950}
5051
51- function AppContent ( ) {
52- useCartSync ( ) ;
53- const incognito = useIncognitoStore ( ( s ) => s . enabled ) ;
54-
52+ // Clinical DNA verification: runs once on load to ensure brand tokens are active (see docs/LAUNCH_DAY_PROTOCOL.md)
53+ function useBrandDNAGuard ( ) {
5554 useEffect ( ( ) => {
56- document . body . classList . toggle ( "incognito-mode" , incognito ) ;
57- } , [ incognito ] ) ;
58-
59- return (
60- < >
61- < ScrollRestoration />
62- < Suspense fallback = { < div className = "min-h-screen bg-background" /> } >
63- < Routes >
64- < Route path = "/" element = { < Index /> } />
65- < Route path = "/products" element = { < Products /> } />
66- < Route path = "/shop" element = { < Shop /> } />
67- < Route path = "/product/:handle" element = { < ProductDetail /> } />
68- < Route path = "/brand" element = { < BrandShowcase /> } />
69- < Route path = "/auth" element = { < Auth /> } />
70- < Route path = "/intelligence" element = { < Intelligence /> } />
71- < Route path = "/lab" element = { < LabTools /> } />
72- < Route path = "/checkout" element = { < Checkout /> } />
73- < Route path = "/profile" element = { < Profile /> } />
74- < Route path = "/contact" element = { < Contact /> } />
75- < Route path = "/admin/enrichment" element = { < AdminEnrichment /> } />
76- < Route path = "/health" element = { < Health /> } />
77- < Route path = "/mom-baby" element = { < MomBaby /> } />
78- < Route path = "*" element = { < NotFound /> } />
79- </ Routes >
80- </ Suspense >
81- < AIConcierge />
82- </ >
83- ) ;
55+ const t = setTimeout ( verifyBrandDNA , 100 ) ;
56+ return ( ) => clearTimeout ( t ) ;
57+ } , [ ] ) ;
8458}
8559
8660const App = ( ) => {
87- const [ showSplash , setShowSplash ] = useState ( ( ) => {
88- // Only show splash once per session
89- if ( sessionStorage . getItem ( "asper-splash-seen" ) ) return false ;
90- return true ;
91- } ) ;
92-
93- const handleSplashComplete = useCallback ( ( ) => {
94- sessionStorage . setItem ( "asper-splash-seen" , "true" ) ;
95- setShowSplash ( false ) ;
96- } , [ ] ) ;
97-
61+ useBrandDNAGuard ( ) ;
9862 return (
9963 < QueryClientProvider client = { queryClient } >
100- < TooltipProvider >
101- < LanguageProvider >
102- < Toaster />
103- < Sonner />
104- { showSplash && < SplashScreen onComplete = { handleSplashComplete } /> }
105- < BrowserRouter >
106- < AppContent />
107- </ BrowserRouter >
108- </ LanguageProvider >
109- </ TooltipProvider >
64+ < LanguageProvider >
65+ < CartSyncProvider >
66+ < TooltipProvider >
67+ < Toaster />
68+ < Sonner position = "top-center" />
69+ < BrowserRouter >
70+ < Suspense fallback = { null } >
71+ < BeautyAssistant />
72+ </ Suspense >
73+ < Routes >
74+ < Route path = "/" element = { < Index /> } />
75+ < Route path = "/chat" element = { < Index /> } />
76+ < Route path = "/shop" element = { < Shop /> } />
77+ < Route path = "/products" element = { < Shop /> } />
78+ < Route path = "/shop/organized" element = { < ShopAllOrganized /> } />
79+ < Route path = "/product/:handle" element = { < ProductDetail /> } />
80+ < Route path = "/collections" element = { < Collections /> } />
81+ < Route
82+ path = "/collections/:slug"
83+ element = { < CollectionDetail /> }
84+ />
85+ < Route path = "/brands" element = { < Brands /> } />
86+ < Route path = "/brands/vichy" element = { < BrandVichy /> } />
87+ < Route path = "/best-sellers" element = { < BestSellers /> } />
88+ < Route path = "/offers" element = { < Offers /> } />
89+ < Route path = "/contact" element = { < Contact /> } />
90+ < Route path = "/skin-concerns" element = { < SkinConcerns /> } />
91+ < Route
92+ path = "/concerns/:concernSlug"
93+ element = { < ConcernCollection /> }
94+ />
95+ < Route path = "/wishlist" element = { < Wishlist /> } />
96+ < Route path = "/auth" element = { < Auth /> } />
97+ < Route path = "/account" element = { < Account /> } />
98+ < Route path = "/philosophy" element = { < Philosophy /> } />
99+ < Route path = "/intelligence" element = { < AsperIntelligence /> } />
100+ < Route path = "/health" element = { < Health /> } />
101+ < Route path = "/admin/bulk-upload" element = { < BulkUpload /> } />
102+ < Route path = "/admin/orders" element = { < AdminOrders /> } />
103+ < Route path = "/admin/products" element = { < ManageProducts /> } />
104+ < Route path = "/track-order" element = { < TrackOrder /> } />
105+ < Route path = "/tracking" element = { < Navigate to = "/track-order" replace /> } />
106+ < Route path = "/shipping" element = { < Navigate to = "/contact" replace /> } />
107+ < Route path = "/returns" element = { < Navigate to = "/contact" replace /> } />
108+ < Route path = "/consultation" element = { < Navigate to = "/skin-concerns" replace /> } />
109+ < Route path = "/driver" element = { < DriverDashboard /> } />
110+ < Route path = "/admin/audit-logs" element = { < AdminAuditLogs /> } />
111+ < Route
112+ path = "/brand-intelligence"
113+ element = {
114+ < RequireAdmin >
115+ < BrandIntelligenceDashboard />
116+ </ RequireAdmin >
117+ }
118+ />
119+ < Route path = "*" element = { < NotFound /> } />
120+ </ Routes >
121+ </ BrowserRouter >
122+ </ TooltipProvider >
123+ </ CartSyncProvider >
124+ </ LanguageProvider >
110125 </ QueryClientProvider >
111126 ) ;
112127} ;
113128
114- export default App ;
129+ export default App ;
0 commit comments