diff --git a/src/app/page.tsx b/src/app/page.tsx index 9b67a56..c0d1f08 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -9,9 +9,30 @@ import MetricCardOne from "@/components/sections/metrics/MetricCardOne"; import FaqDouble from "@/components/sections/faq/FaqDouble"; import ContactFaq from "@/components/sections/contact/ContactFaq"; import FooterBaseReveal from "@/components/sections/footer/FooterBaseReveal"; +import VirtualTryOnUpload from "@/components/virtualTryOn/VirtualTryOnUpload"; +import VirtualTryOnPreview from "@/components/virtualTryOn/VirtualTryOnPreview"; import { Clock, Package, Sparkles, Target, Zap } from "lucide-react"; +import { useState } from "react"; export default function LandingPage() { + const [userPhoto, setUserPhoto] = useState(null); + const [clothesPhoto, setClothesPhoto] = useState(null); + const [showPreview, setShowPreview] = useState(false); + + const handleUserPhotoUpload = (photo: string) => { + setUserPhoto(photo); + }; + + const handleClothesPhotoUpload = (photo: string) => { + setClothesPhoto(photo); + }; + + const handleStartTryOn = () => { + if (userPhoto && clothesPhoto) { + setShowPreview(true); + } + }; + return ( @@ -43,8 +65,8 @@ export default function LandingPage() { logoText="VIRTUAL TRY ON" description="Upload your photo and clothes to instantly see how outfits look on you. No more guessing – visualize your style in seconds with AI-powered virtual fitting." buttons={[ - { text: "Start Try-On", href: "#features" }, - { text: "Learn More", href: "#about" }, + { text: "Start Try-On", href: "tryon" }, + { text: "Learn More", href: "about" }, ]} slides={[ { @@ -100,12 +122,41 @@ export default function LandingPage() { title="Revolutionary AI-Powered Virtual Fitting Technology. Say goodbye to sizing anxiety and hello to confident shopping." useInvertedBackground={true} buttons={[ - { text: "Get Started Free", href: "#contact" }, - { text: "View Demo", href: "#features" }, + { text: "Get Started Free", href: "tryon" }, + { text: "View Demo", href: "features" }, ]} /> +
+
+
+ {!showPreview ? ( +
+ + +
+ ) : ( + setShowPreview(false)} + /> + )} +
+
+
+
); -} +} \ No newline at end of file diff --git a/src/components/virtualTryOn/VirtualTryOnPreview.tsx b/src/components/virtualTryOn/VirtualTryOnPreview.tsx new file mode 100644 index 0000000..212e115 --- /dev/null +++ b/src/components/virtualTryOn/VirtualTryOnPreview.tsx @@ -0,0 +1,193 @@ +"use client"; + +import { useState, useEffect } from "react"; +import { ArrowLeft, Download, Share2, RotateCcw } from "lucide-react"; + +interface VirtualTryOnPreviewProps { + userPhoto: string | null; + clothesPhoto: string | null; + onBack: () => void; +} + +export default function VirtualTryOnPreview({ + userPhoto, + clothesPhoto, + onBack, +}: VirtualTryOnPreviewProps) { + const [previewImage, setPreviewImage] = useState(null); + const [isProcessing, setIsProcessing] = useState(true); + const [selectedFit, setSelectedFit] = useState<"tight" | "normal" | "loose">("normal"); + + useEffect(() => { + // Simulate AI processing time + const timer = setTimeout(() => { + setIsProcessing(false); + // Create a simple composite preview + if (userPhoto && clothesPhoto) { + // In a real implementation, this would use server-side image processing + setPreviewImage(userPhoto); + } + }, 2000); + + return () => clearTimeout(timer); + }, [userPhoto, clothesPhoto]); + + const handleDownload = () => { + if (previewImage) { + const link = document.createElement("a"); + link.href = previewImage; + link.download = "virtual-tryon-result.png"; + link.click(); + } + }; + + const handleShare = () => { + if (navigator.share && previewImage) { + navigator.share({ + title: "My Virtual Try-On", text: "Check out how I look in these clothes!"}); + } else { + // Fallback: copy to clipboard + const url = window.location.href; + navigator.clipboard.writeText(url); + alert("Link copied to clipboard!"); + } + }; + + const handleFitChange = (fit: "tight" | "normal" | "loose") => { + setSelectedFit(fit); + setIsProcessing(true); + setTimeout(() => setIsProcessing(false), 1500); + }; + + return ( +
+ {/* Header */} +
+

Your Virtual Try-On

+ +
+ + {/* Main Preview Container */} +
+ {/* Preview Image */} +
+
+ {isProcessing ? ( +
+
+

+ Processing your virtual try-on with AI technology... +

+
+ ) : previewImage ? ( + <> + Virtual try-on preview +
+ + ) : null} +
+ + {/* Details Below Preview */} +
+
+

Your Photo

+
+ {userPhoto && ( + Your photo + )} +
+
+
+

Clothes

+
+ {clothesPhoto && ( + Clothes photo + )} +
+
+
+
+ + {/* Controls Panel */} +
+ {/* Fit Selector */} +
+

+ Fit Preference +

+
+ {(["tight", "normal", "loose"] as const).map((fit) => ( + + ))} +
+
+ + {/* Action Buttons */} +
+ + + +
+ + {/* Info Box */} +
+

+ Accuracy: + This preview is powered by advanced AI. The actual fit may vary based on fabric properties and your exact measurements. +

+
+
+
+
+ ); +} \ No newline at end of file diff --git a/src/components/virtualTryOn/VirtualTryOnUpload.tsx b/src/components/virtualTryOn/VirtualTryOnUpload.tsx new file mode 100644 index 0000000..68b01cf --- /dev/null +++ b/src/components/virtualTryOn/VirtualTryOnUpload.tsx @@ -0,0 +1,136 @@ +"use client"; + +import { useState, useRef } from "react"; +import { Upload, X } from "lucide-react"; + +interface VirtualTryOnUploadProps { + title: string; + description: string; + onPhotoUpload: (photo: string) => void; + uploadType: "user" | "clothes"; +} + +export default function VirtualTryOnUpload({ + title, + description, + onPhotoUpload, + uploadType, +}: VirtualTryOnUploadProps) { + const [preview, setPreview] = useState(null); + const [isDragging, setIsDragging] = useState(false); + const fileInputRef = useRef(null); + + const handleFileSelect = (file: File) => { + if (file && file.type.startsWith("image/")) { + const reader = new FileReader(); + reader.onload = (e) => { + const result = e.target?.result as string; + setPreview(result); + onPhotoUpload(result); + }; + reader.readAsDataURL(file); + } + }; + + const handleDragOver = (e: React.DragEvent) => { + e.preventDefault(); + setIsDragging(true); + }; + + const handleDragLeave = () => { + setIsDragging(false); + }; + + const handleDrop = (e: React.DragEvent) => { + e.preventDefault(); + setIsDragging(false); + const files = e.dataTransfer.files; + if (files && files[0]) { + handleFileSelect(files[0]); + } + }; + + const handleFileInputChange = (e: React.ChangeEvent) => { + const files = e.target.files; + if (files && files[0]) { + handleFileSelect(files[0]); + } + }; + + const handleRemovePhoto = () => { + setPreview(null); + }; + + const handleClick = () => { + fileInputRef.current?.click(); + }; + + return ( +
+
+

+ {title} +

+

{description}

+
+ + {!preview ? ( +
+ +
+ +

+ {isDragging ? "Drop your photo here" : "Drag & drop or click to upload"} +

+

PNG, JPG, GIF up to 10MB

+
+
+ ) : ( +
+ {`${uploadType} + +
+
+
+
+ Processing... +
+
+ )} + +
+

+ Pro tip: For best results, ensure good + lighting, wear fitted clothes, and stand in a neutral pose. +

+
+
+ ); +} \ No newline at end of file