1- import { useState , useMemo } from 'react'
1+ import { useState , useMemo , useEffect } from 'react'
22import Header from './components/Header'
33import Sidebar from './components/Sidebar'
44import ProductGrid from './components/ProductGrid'
@@ -11,6 +11,7 @@ import Checkout from './components/Checkout'
1111import AccountModal from './components/AccountModal'
1212
1313function App ( ) {
14+ const [ showSplash , setShowSplash ] = useState ( true ) ;
1415 const [ selectedCategories , setSelectedCategories ] = useState ( [ ] ) ;
1516 const [ selectedThemes , setSelectedThemes ] = useState ( [ ] ) ;
1617 const [ selectedProduct , setSelectedProduct ] = useState ( null ) ;
@@ -41,6 +42,13 @@ function App() {
4142 } catch { return [ ] ; }
4243 } ) ;
4344
45+ useEffect ( ( ) => {
46+ const timer = setTimeout ( ( ) => {
47+ setShowSplash ( false ) ;
48+ } , 2500 ) ;
49+ return ( ) => clearTimeout ( timer ) ;
50+ } , [ ] ) ;
51+
4452 const userOrdersKey = ( user ) => `zappify_orders_${ user ?. email } ` ;
4553
4654 const handleLogin = ( user ) => {
@@ -119,130 +127,173 @@ function App() {
119127 const isEmbed = new URLSearchParams ( window . location . search ) . get ( 'embed' ) === '1' ;
120128
121129 return (
122- < div className = "zappify-app" >
123- { ! isEmbed && < Header
124- onOpenOverlay = { setActiveOverlay }
125- onNavigate = { handleNavigate }
126- cartCount = { cartItems . reduce ( ( sum , i ) => sum + i . qty , 0 ) }
127- wishlistCount = { wishlistItems . length }
128- activeNav = { activeNav }
129- loggedInUser = { loggedInUser }
130- onOpenAccount = { ( ) => setShowAccount ( true ) }
131- searchQuery = { searchQuery }
132- onSearch = { setSearchQuery }
133- /> }
134-
135- < main className = "app-main" >
136- < div className = "container-broad main-layout" >
137- < AnimatePresence mode = "wait" >
138- { ! selectedProduct ? (
139- < motion . div
140- key = "grid"
141- className = "grid-view"
142- initial = { { opacity : 0 , x : - 20 } }
143- animate = { { opacity : 1 , x : 0 } }
144- exit = { { opacity : 0 , x : - 20 } }
145- transition = { { duration : 0.3 } }
146- >
147- < div className = "layout-split" >
148- < Sidebar
149- selectedCategories = { selectedCategories }
150- selectedThemes = { selectedThemes }
151- onToggleFilter = { toggleFilter }
152- />
153- < ProductGrid
154- products = { filteredProducts }
155- onProductClick = { ( product ) => { setSelectedProduct ( product ) ; window . scrollTo ( { top : 0 , behavior : 'smooth' } ) ; } }
156- onToggleWishlist = { toggleWishlist }
157- isWishlisted = { isWishlisted }
158- />
159- </ div >
160- </ motion . div >
161- ) : (
162- < motion . div
163- key = "detail"
164- className = "detail-view"
165- initial = { { opacity : 0 , y : 20 } }
166- animate = { { opacity : 1 , y : 0 } }
167- exit = { { opacity : 0 , y : - 20 } }
168- transition = { { duration : 0.4 } }
169- >
170- < ProductDetail
171- product = { selectedProduct }
172- onBack = { ( ) => setSelectedProduct ( null ) }
173- onAddToCart = { addToCart }
174- onToggleWishlist = { toggleWishlist }
175- isWishlisted = { isWishlisted ( selectedProduct . id ) }
176- />
177- </ motion . div >
130+ < AnimatePresence mode = "wait" >
131+ { showSplash ? (
132+ < SplashScreen key = "splash" />
133+ ) : (
134+ < motion . div
135+ key = "app-content"
136+ className = "zappify-app"
137+ initial = { { opacity : 0 } }
138+ animate = { { opacity : 1 } }
139+ transition = { { duration : 0.8 } }
140+ >
141+ { ! isEmbed && < Header
142+ onOpenOverlay = { setActiveOverlay }
143+ onNavigate = { handleNavigate }
144+ cartCount = { cartItems . reduce ( ( sum , i ) => sum + i . qty , 0 ) }
145+ wishlistCount = { wishlistItems . length }
146+ activeNav = { activeNav }
147+ loggedInUser = { loggedInUser }
148+ onOpenAccount = { ( ) => setShowAccount ( true ) }
149+ searchQuery = { searchQuery }
150+ onSearch = { setSearchQuery }
151+ /> }
152+
153+ < main className = "app-main" >
154+ < div className = "container-broad main-layout" >
155+ < AnimatePresence mode = "wait" >
156+ { ! selectedProduct ? (
157+ < motion . div
158+ key = "grid"
159+ className = "grid-view"
160+ initial = { { opacity : 0 , x : - 20 } }
161+ animate = { { opacity : 1 , x : 0 } }
162+ exit = { { opacity : 0 , x : - 20 } }
163+ transition = { { duration : 0.3 } }
164+ >
165+ < div className = "layout-split" >
166+ < Sidebar
167+ selectedCategories = { selectedCategories }
168+ selectedThemes = { selectedThemes }
169+ onToggleFilter = { toggleFilter }
170+ />
171+ < ProductGrid
172+ products = { filteredProducts }
173+ onProductClick = { ( product ) => { setSelectedProduct ( product ) ; window . scrollTo ( { top : 0 , behavior : 'smooth' } ) ; } }
174+ onToggleWishlist = { toggleWishlist }
175+ isWishlisted = { isWishlisted }
176+ />
177+ </ div >
178+ </ motion . div >
179+ ) : (
180+ < motion . div
181+ key = "detail"
182+ className = "detail-view"
183+ initial = { { opacity : 0 , y : 20 } }
184+ animate = { { opacity : 1 , y : 0 } }
185+ exit = { { opacity : 0 , y : - 20 } }
186+ transition = { { duration : 0.4 } }
187+ >
188+ < ProductDetail
189+ product = { selectedProduct }
190+ onBack = { ( ) => setSelectedProduct ( null ) }
191+ onAddToCart = { addToCart }
192+ onToggleWishlist = { toggleWishlist }
193+ isWishlisted = { isWishlisted ( selectedProduct . id ) }
194+ />
195+ </ motion . div >
196+ ) }
197+ </ AnimatePresence >
198+ </ div >
199+ </ main >
200+
201+ < footer className = "zappify-footer" >
202+ < div className = "container-broad" >
203+ < div className = "footer-bottom" >
204+ < p > © 2026 Zappify Shoe Store. All rights reserved.</ p >
205+ </ div >
206+ </ div >
207+ </ footer >
208+
209+ < AnimatePresence >
210+ { activeOverlay && (
211+ < Overlay
212+ type = { activeOverlay }
213+ onClose = { ( ) => setActiveOverlay ( null ) }
214+ cartItems = { cartItems }
215+ wishlistItems = { wishlistItems }
216+ onRemoveFromCart = { removeFromCart }
217+ onToggleWishlist = { toggleWishlist }
218+ onLoginSuccess = { handleLogin }
219+ onCheckout = { ( ) => { setActiveOverlay ( null ) ; setShowCheckout ( true ) ; } }
220+ loggedInUser = { loggedInUser }
221+ onSwitchOverlay = { setActiveOverlay }
222+ />
178223 ) }
179224 </ AnimatePresence >
180- </ div >
181- </ main >
182225
183- < footer className = "zappify-footer" >
184- < div className = "container-broad" >
185- < div className = "footer-bottom" >
186- < p > © 2026 Zappify Shoe Store. All rights reserved.</ p >
187- </ div >
188- </ div >
189- </ footer >
190-
191- < AnimatePresence >
192- { activeOverlay && (
193- < Overlay
194- type = { activeOverlay }
195- onClose = { ( ) => setActiveOverlay ( null ) }
196- cartItems = { cartItems }
197- wishlistItems = { wishlistItems }
198- onRemoveFromCart = { removeFromCart }
199- onToggleWishlist = { toggleWishlist }
200- onLoginSuccess = { handleLogin }
201- onCheckout = { ( ) => { setActiveOverlay ( null ) ; setShowCheckout ( true ) ; } }
202- loggedInUser = { loggedInUser }
203- onSwitchOverlay = { setActiveOverlay }
204- />
205- ) }
206- </ AnimatePresence >
207-
208- { showCheckout && (
209- < Checkout
210- cartItems = { cartItems }
211- onClose = { ( ) => setShowCheckout ( false ) }
212- onRemoveFromCart = { removeFromCart }
213- onOrderPlaced = { ( items ) => {
214- const newOrders = items . map ( item => ( {
215- ...item ,
216- orderId : Math . floor ( 10000000 + Math . random ( ) * 90000000 ) . toString ( ) ,
217- placedAt : new Date ( ) . toISOString ( ) ,
218- status : 'Placed' ,
219- } ) ) ;
220- const updated = [ ...placedOrders , ...newOrders ] ;
221- setPlacedOrders ( updated ) ;
222- localStorage . setItem ( userOrdersKey ( loggedInUser ) , JSON . stringify ( updated ) ) ;
223- setCartItems ( [ ] ) ;
224- localStorage . removeItem ( 'zappify_cart' ) ;
225- } }
226- />
227- ) }
226+ { showCheckout && (
227+ < Checkout
228+ cartItems = { cartItems }
229+ onClose = { ( ) => setShowCheckout ( false ) }
230+ onRemoveFromCart = { removeFromCart }
231+ onOrderPlaced = { ( items ) => {
232+ const newOrders = items . map ( item => ( {
233+ ...item ,
234+ orderId : Math . floor ( 10000000 + Math . random ( ) * 90000000 ) . toString ( ) ,
235+ placedAt : new Date ( ) . toISOString ( ) ,
236+ status : 'Placed' ,
237+ } ) ) ;
238+ const updated = [ ...placedOrders , ...newOrders ] ;
239+ setPlacedOrders ( updated ) ;
240+ localStorage . setItem ( userOrdersKey ( loggedInUser ) , JSON . stringify ( updated ) ) ;
241+ setCartItems ( [ ] ) ;
242+ localStorage . removeItem ( 'zappify_cart' ) ;
243+ } }
244+ />
245+ ) }
228246
229- { showAccount && loggedInUser && (
230- < AccountModal
231- user = { loggedInUser }
232- orders = { placedOrders }
233- onClose = { ( ) => setShowAccount ( false ) }
234- onLogout = { ( ) => { handleLogout ( ) ; setShowAccount ( false ) ; } }
235- onCancelOrder = { ( orderId ) => {
236- const updated = placedOrders . map ( o => o . orderId === orderId ? { ...o , status : 'Cancelled' } : o ) ;
237- setPlacedOrders ( updated ) ;
238- localStorage . setItem ( userOrdersKey ( loggedInUser ) , JSON . stringify ( updated ) ) ;
239- } }
240- />
247+ { showAccount && loggedInUser && (
248+ < AccountModal
249+ user = { loggedInUser }
250+ orders = { placedOrders }
251+ onClose = { ( ) => setShowAccount ( false ) }
252+ onLogout = { ( ) => { handleLogout ( ) ; setShowAccount ( false ) ; } }
253+ onCancelOrder = { ( orderId ) => {
254+ const updated = placedOrders . map ( o => o . orderId === orderId ? { ...o , status : 'Cancelled' } : o ) ;
255+ setPlacedOrders ( updated ) ;
256+ localStorage . setItem ( userOrdersKey ( loggedInUser ) , JSON . stringify ( updated ) ) ;
257+ } }
258+ />
259+ ) }
260+ </ motion . div >
241261 ) }
242- </ div >
262+ </ AnimatePresence >
243263 ) ;
244264}
245265
266+ const SplashScreen = ( ) => (
267+ < motion . div
268+ className = "splash-container"
269+ initial = { { opacity : 1 } }
270+ exit = { { opacity : 0 } }
271+ transition = { { duration : 0.8 , ease : "easeInOut" } }
272+ >
273+ < motion . div
274+ className = "splash-content"
275+ initial = { { scale : 0.85 , opacity : 0 , y : 10 } }
276+ animate = { { scale : 1 , opacity : 1 , y : 0 } }
277+ transition = { {
278+ duration : 1 ,
279+ ease : [ 0.22 , 1 , 0.36 , 1 ] ,
280+ opacity : { duration : 0.6 }
281+ } }
282+ >
283+ < div className = "splash-logo" >
284+ < span > Z</ span > appify
285+ </ div >
286+ < div className = "splash-subtitle" > Premium Shoe Store</ div >
287+ < motion . div
288+ className = "splash-loader"
289+ initial = { { opacity : 0 } }
290+ animate = { { opacity : 1 } }
291+ transition = { { delay : 0.8 } }
292+ />
293+ </ motion . div >
294+ </ motion . div >
295+ ) ;
296+
246297const Overlay = ( { type, onClose, cartItems, wishlistItems, onRemoveFromCart, onToggleWishlist, onLoginSuccess, onCheckout, loggedInUser, onSwitchOverlay } ) => {
247298 const [ isSignUp , setIsSignUp ] = useState ( false ) ;
248299 const [ formData , setFormData ] = useState ( { name : '' , email : '' , password : '' , confirm : '' } ) ;
0 commit comments