11import { Link } from "react-router-dom" ;
22import { Button } from "@/components/ui/button" ;
3- import { ArrowRight , Shield , Leaf , Sparkles , Sun , Moon , CloudSun , FlaskConical , Droplets } from "lucide-react" ;
3+ import { ArrowRight , Shield , Leaf , Sparkles , Sun , Moon , CloudSun , FlaskConical , Droplets , Package } from "lucide-react" ;
44import { useLanguage } from "@/contexts/LanguageContext" ;
55import { useTimeContext } from "@/hooks/useTimeContext" ;
66import { cn } from "@/lib/utils" ;
77import { motion } from "framer-motion" ;
8+ import { useQuery } from "@tanstack/react-query" ;
9+ import { supabase } from "@/integrations/supabase/client" ;
810
911const timeIcons = { morning : Sun , afternoon : CloudSun , evening : Moon } ;
1012
11- /* Floating product cards for the "Digital Tray" */
12- const trayProducts = [
13- { title : "Retinol Night Treatment" , brand : "Asper Beauty" , price : "68.00" , step : "Treatment" , icon : FlaskConical } ,
14- { title : "Vitamin C Brightening Cream" , brand : "Asper Beauty" , price : "52.00" , step : "Protection" , icon : Sparkles } ,
15- { title : "Nourishing Hair Oil" , brand : "Kérastase" , price : "32.00" , step : "Nourish" , icon : Droplets } ,
13+ const stepIcon = ( step : string ) => {
14+ if ( step . includes ( "1" ) ) return FlaskConical ;
15+ if ( step . includes ( "2" ) ) return Sparkles ;
16+ if ( step . includes ( "3" ) ) return Droplets ;
17+ return Package ;
18+ } ;
19+
20+ const stepLabel = ( step : string ) => {
21+ if ( step . includes ( "1" ) ) return "Cleanser" ;
22+ if ( step . includes ( "2" ) ) return "Treatment" ;
23+ if ( step . includes ( "3" ) ) return "Protection" ;
24+ return "Essentials" ;
25+ } ;
26+
27+ const fallbackProducts = [
28+ { title : "Retinol Night Treatment" , brand : "Asper Beauty" , price : 68 , step : "Treatment" , icon : FlaskConical } ,
29+ { title : "Vitamin C Brightening Cream" , brand : "Asper Beauty" , price : 52 , step : "Protection" , icon : Sparkles } ,
30+ { title : "Nourishing Hair Oil" , brand : "Kérastase" , price : 32 , step : "Nourish" , icon : Droplets } ,
1631] ;
1732
1833export default function Hero ( ) {
@@ -21,6 +36,30 @@ export default function Hero() {
2136 const TimeIcon = timeIcons [ timeOfDay ] ;
2237 const isAr = locale === "ar" ;
2338
39+ const { data : dbProducts } = useQuery ( {
40+ queryKey : [ "hero-tray-products" ] ,
41+ queryFn : async ( ) => {
42+ const { data } = await supabase
43+ . from ( "products" )
44+ . select ( "title, brand, price, regimen_step, image_url" )
45+ . eq ( "is_hero" , true )
46+ . order ( "bestseller_rank" , { ascending : true , nullsFirst : false } )
47+ . limit ( 3 ) ;
48+ return data ;
49+ } ,
50+ staleTime : 5 * 60 * 1000 ,
51+ } ) ;
52+
53+ const trayProducts = dbProducts && dbProducts . length > 0
54+ ? dbProducts . map ( ( p ) => ( {
55+ title : p . title ,
56+ brand : p . brand || "Asper Beauty" ,
57+ price : p . price ?? 0 ,
58+ step : stepLabel ( p . regimen_step ) ,
59+ icon : stepIcon ( p . regimen_step ) ,
60+ } ) )
61+ : fallbackProducts ;
62+
2463 return (
2564 < section className = "relative min-h-[85vh] lg:min-h-[90vh] overflow-hidden bg-background" >
2665 { /* Subtle background pattern */ }
@@ -144,7 +183,7 @@ export default function Hero() {
144183 < p className = "text-sm font-heading font-semibold text-foreground truncate" > { product . title } </ p >
145184 </ div >
146185 < div className = "text-right flex-shrink-0" >
147- < p className = "text-sm font-semibold text-foreground" > { product . price } < span className = "text-xs text-muted-foreground" > JOD</ span > </ p >
186+ < p className = "text-sm font-semibold text-foreground" > { Number ( product . price ) . toFixed ( 2 ) } < span className = "text-xs text-muted-foreground" > JOD</ span > </ p >
148187 < span className = "text-[10px] font-body uppercase tracking-wider text-accent" > { product . step } </ span >
149188 </ div >
150189 </ div >
0 commit comments