diff --git a/frontend/package.json b/frontend/package.json index 72b917d9..ae1d4fd2 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -11,7 +11,8 @@ "dependencies": { "react": "^19.0.0", "react-dom": "^19.0.0", - "next": "15.2.4" + "next": "15.2.4", + "gsap": "^3.12.5" }, "devDependencies": { "typescript": "^5", diff --git a/frontend/public/images/clean-phone.jpg b/frontend/public/images/clean-phone.jpg new file mode 100644 index 00000000..0943177b Binary files /dev/null and b/frontend/public/images/clean-phone.jpg differ diff --git a/frontend/public/images/clean-phone.png b/frontend/public/images/clean-phone.png new file mode 100644 index 00000000..6a5d5fe7 Binary files /dev/null and b/frontend/public/images/clean-phone.png differ diff --git a/frontend/public/images/foodpanda.png b/frontend/public/images/foodpanda.png new file mode 100644 index 00000000..798d677e Binary files /dev/null and b/frontend/public/images/foodpanda.png differ diff --git a/frontend/public/images/gift-card.png b/frontend/public/images/gift-card.png new file mode 100644 index 00000000..fe0b0206 Binary files /dev/null and b/frontend/public/images/gift-card.png differ diff --git a/frontend/public/images/gift-card.webp b/frontend/public/images/gift-card.webp new file mode 100644 index 00000000..5da909b3 Binary files /dev/null and b/frontend/public/images/gift-card.webp differ diff --git a/frontend/public/images/grab.png b/frontend/public/images/grab.png new file mode 100644 index 00000000..fb4357ef Binary files /dev/null and b/frontend/public/images/grab.png differ diff --git a/frontend/public/images/hero-phone.png b/frontend/public/images/hero-phone.png new file mode 100644 index 00000000..664b83ad Binary files /dev/null and b/frontend/public/images/hero-phone.png differ diff --git a/frontend/public/images/lazada.png b/frontend/public/images/lazada.png new file mode 100644 index 00000000..5943e975 Binary files /dev/null and b/frontend/public/images/lazada.png differ diff --git a/frontend/public/images/netflix.png b/frontend/public/images/netflix.png new file mode 100644 index 00000000..67ada37b Binary files /dev/null and b/frontend/public/images/netflix.png differ diff --git a/frontend/public/images/nike.jpg b/frontend/public/images/nike.jpg new file mode 100644 index 00000000..7e76c05f Binary files /dev/null and b/frontend/public/images/nike.jpg differ diff --git a/frontend/public/images/shopee.png b/frontend/public/images/shopee.png new file mode 100644 index 00000000..59770f36 Binary files /dev/null and b/frontend/public/images/shopee.png differ diff --git a/frontend/public/images/spotify.png b/frontend/public/images/spotify.png new file mode 100644 index 00000000..977702cf Binary files /dev/null and b/frontend/public/images/spotify.png differ diff --git a/frontend/public/images/starbucks.jpg b/frontend/public/images/starbucks.jpg new file mode 100644 index 00000000..41ceb22b Binary files /dev/null and b/frontend/public/images/starbucks.jpg differ diff --git a/frontend/public/images/steam.png b/frontend/public/images/steam.png new file mode 100644 index 00000000..c051a731 Binary files /dev/null and b/frontend/public/images/steam.png differ diff --git a/frontend/src/app/globals.css b/frontend/src/app/globals.css index a2dc41ec..5cd6e851 100644 --- a/frontend/src/app/globals.css +++ b/frontend/src/app/globals.css @@ -22,5 +22,42 @@ body { background: var(--background); color: var(--foreground); - font-family: Arial, Helvetica, sans-serif; + font-family: var(--font-geist-sans), Arial, Helvetica, sans-serif; + scroll-behavior: smooth; +} + +html { + scroll-behavior: smooth; +} + +/* Custom modern scrollbar */ +::-webkit-scrollbar { + width: 8px; +} +::-webkit-scrollbar-track { + background: #08070b; +} +::-webkit-scrollbar-thumb { + background: #1e1b2b; + border-radius: 9999px; + border: 2px solid #08070b; +} +::-webkit-scrollbar-thumb:hover { + background: #2e2a47; +} + +/* Custom simple keyframes for page interactions */ +@keyframes fadeIn { + from { + opacity: 0; + transform: translateY(10px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +.animate-fade-in { + animation: fadeIn 0.4s ease-out forwards; } diff --git a/frontend/src/app/layout.tsx b/frontend/src/app/layout.tsx index f7fa87eb..e9454a25 100644 --- a/frontend/src/app/layout.tsx +++ b/frontend/src/app/layout.tsx @@ -23,7 +23,7 @@ export default function RootLayout({ children: React.ReactNode; }>) { return ( - + diff --git a/frontend/src/app/page.tsx b/frontend/src/app/page.tsx index e68abe6b..d1003b71 100644 --- a/frontend/src/app/page.tsx +++ b/frontend/src/app/page.tsx @@ -1,103 +1,675 @@ -import Image from "next/image"; +"use client"; + +import React, { useState, useEffect, useRef } from "react"; +import gsap from "gsap"; +import { ScrollTrigger } from "gsap/ScrollTrigger"; export default function Home() { + const heroRef = useRef(null); + const cardsRef = useRef(null); + const howItWorksRef = useRef(null); + const calculatorRef = useRef(null); + const comparisonRef = useRef(null); + const securityRef = useRef(null); + const faqRef = useRef(null); + + // States + const [activeCategory, setActiveCategory] = useState("all"); + const [monthlySpend, setMonthlySpend] = useState(25000); + const [openFaq, setOpenFaq] = useState(null); + const [email, setEmail] = useState(""); + const [isSubmitted, setIsSubmitted] = useState(false); + const [errorMsg, setErrorMsg] = useState(""); + + const annualSavings = Math.round(monthlySpend * 12 * 0.08); // 8% average cash back + + useEffect(() => { + if (typeof window !== "undefined") { + gsap.registerPlugin(ScrollTrigger); + + const heroCtx = gsap.context(() => { + gsap.fromTo( + ".hero-fade", + { opacity: 0, y: 30 }, + { opacity: 1, y: 0, duration: 1, stagger: 0.2, ease: "power3.out" } + ); + gsap.fromTo( + ".hero-image", + { opacity: 0, scale: 0.95 }, + { opacity: 1, scale: 1, duration: 1.2, delay: 0.4, ease: "power3.out" } + ); + + // Interactive mouse-tilt 3D effect + const phone = document.querySelector(".phone-3d") as HTMLElement; + const hero = heroRef.current; + if (hero && phone) { + const handleMouseMove = (e: MouseEvent) => { + const rect = hero.getBoundingClientRect(); + const x = e.clientX - rect.left - rect.width / 2; + const y = e.clientY - rect.top - rect.height / 2; + + const tiltX = (y / (rect.height / 2)) * -12; // tilt angle Y axis limit + const tiltY = (x / (rect.width / 2)) * 18; // tilt angle X axis limit + + gsap.to(phone, { + rotateX: tiltX, + rotateY: tiltY, + ease: "power2.out", + duration: 0.4 + }); + }; + + const handleMouseLeave = () => { + gsap.to(phone, { + rotateX: 8, + rotateY: -12, + rotateZ: -2, + ease: "power3.out", + duration: 0.8 + }); + }; + + hero.addEventListener("mousemove", handleMouseMove); + hero.addEventListener("mouseleave", handleMouseLeave); + + // Set initial elegant 3D tilt + gsap.set(phone, { rotateX: 8, rotateY: -12, rotateZ: -2 }); + } + }, heroRef); + + const cardsCtx = gsap.context(() => { + gsap.fromTo( + ".card-item", + { opacity: 0, y: 30 }, + { + opacity: 1, + y: 0, + duration: 0.8, + stagger: 0.1, + ease: "power2.out", + scrollTrigger: { + trigger: cardsRef.current, + start: "top 85%", + toggleActions: "play none none none" + } + } + ); + }, cardsRef); + + const howCtx = gsap.context(() => { + gsap.fromTo( + ".step-item", + { opacity: 0, y: 20 }, + { + opacity: 1, + y: 0, + duration: 0.8, + stagger: 0.15, + ease: "power2.out", + scrollTrigger: { + trigger: howItWorksRef.current, + start: "top 85%", + toggleActions: "play none none none" + } + } + ); + }, howItWorksRef); + + // Scroll trigger animations for Calculator + const calcCtx = gsap.context(() => { + gsap.fromTo( + ".calc-animate", + { opacity: 0, y: 30 }, + { + opacity: 1, + y: 0, + duration: 1, + ease: "power3.out", + scrollTrigger: { + trigger: calculatorRef.current, + start: "top 85%", + toggleActions: "play none none none" + } + } + ); + }, calculatorRef); + + // Scroll trigger animations for Comparison + const compCtx = gsap.context(() => { + gsap.fromTo( + ".overflow-x-auto", + { opacity: 0, y: 30 }, + { + opacity: 1, + y: 0, + duration: 1, + ease: "power3.out", + scrollTrigger: { + trigger: comparisonRef.current, + start: "top 85%", + toggleActions: "play none none none" + } + } + ); + }, comparisonRef); + + // Scroll trigger animations for Security + const secCtx = gsap.context(() => { + gsap.fromTo( + ".sec-box", + { opacity: 0, scale: 0.98 }, + { + opacity: 1, + scale: 1, + duration: 1, + ease: "power3.out", + scrollTrigger: { + trigger: securityRef.current, + start: "top 85%", + toggleActions: "play none none none" + } + } + ); + }, securityRef); + + return () => { + heroCtx.revert(); + cardsCtx.revert(); + howCtx.revert(); + calcCtx.revert(); + compCtx.revert(); + secCtx.revert(); + }; + } + }, []); + + const handleSubmit = (e: React.FormEvent) => { + e.preventDefault(); + if (!email) { + setErrorMsg("Please enter your email."); + return; + } + const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; + if (!emailRegex.test(email)) { + setErrorMsg("Please enter a valid email."); + return; + } + setErrorMsg(""); + setIsSubmitted(true); + setEmail(""); + }; + + const giftCards = [ + { name: "Starbucks", cashback: "7.0%", category: "dining", logo: "/images/starbucks.jpg" }, + { name: "Grab", cashback: "5.5%", category: "travel", logo: "/images/grab.png" }, + { name: "Lazada", cashback: "8.0%", category: "shopping", logo: "/images/lazada.png" }, + { name: "Shopee", cashback: "8.5%", category: "shopping", logo: "/images/shopee.png" }, + { name: "Steam", cashback: "6.0%", category: "gaming", logo: "/images/steam.png" }, + { name: "Spotify", cashback: "10.0%", category: "gaming", logo: "/images/spotify.png" }, + { name: "Netflix", cashback: "9.0%", category: "gaming", logo: "/images/netflix.png" }, + { name: "Nike", cashback: "7.5%", category: "shopping", logo: "/images/nike.jpg" }, + { name: "Foodpanda", cashback: "6.5%", category: "dining", logo: "/images/foodpanda.png" } + ]; + + const filteredCards = activeCategory === "all" + ? giftCards + : giftCards.filter(c => c.category === activeCategory); + + const faqs = [ + { q: "How do I earn cashback?", a: "Simply purchase digital gift cards through the CardFlo app. The cashback reward is instantly calculated and credited directly to your CardFlo vault balance." }, + { q: "Can I transfer cash back to my bank account?", a: "Yes, you can easily cash out your balance to any local bank or electronic wallet instantly with zero transaction fees." }, + { q: "Are there any hidden fees?", a: "No. CardFlo is completely free to use. There are no monthly maintenance fees, hidden service charges, or card activation fees." }, + { q: "How secure is CardFlo?", a: "We use 256-bit encryption standards and secure, read-only tokenization APIs. Your credential data is never stored on our servers." } + ]; + + const toggleFaq = (index: number) => { + setOpenFaq(openFaq === index ? null : index); + }; + return ( -
-
- Next.js logo -
    -
  1. - Get started by editing{" "} - - src/app/page.tsx - - . -
  2. -
  3. - Save and see your changes instantly. -
  4. -
- -
- - Vercel logomark - Deploy now - - - Read our docs - +
+ + {/* 1. NAVIGATION BAR */} +
+ +
+ + {/* 2. HERO SECTION */} +
+ {/* Soft violet backdrop light */} +
+ +
+ + {/* Left Column: Heading and CTAs */} +
+
+ + • Smart digital wallet +
+ +

+ Gift cards that
+ actually{" "} + pay you back. +

+ +

+ Automate your shopping returns. Purchase digital gift cards for top-tier merchants and instantly receive up to 10% cashback yield. Direct transfers to your bank, no hassle. +

+ + + +
+
✦ Instant wallet delivery
+
✦ 200+ partner brands
+
✦ Bank-grade tokenization
+
+
+ + {/* Right Column: Transparent 3D Phone Model */} +
+
+ Transparent 3D Phone Mockup +
+
+ +
+
+ + {/* 3. GIFT CARDS GRID SECTION */} +
+
+
+ • PARTNERS CATALOG +

Find your favorite brands

+

+ Select your card, purchase instantly, and receive high-rate cashback immediately. +

+ + {/* Filter Tabs */} +
+ {["all", "shopping", "dining", "travel", "gaming"].map(cat => ( + + ))} +
+
+ +
+ {filteredCards.map((card, idx) => ( +
+
+
+

{card.name}

+ {card.category} +
+ + {/* Brand Logo */} +
+ {card.name} { + e.currentTarget.style.display = 'none'; + e.currentTarget.nextElementSibling?.classList.remove('hidden'); + }} + /> + LOGO +
+
+ +
+
+ Yield Rate + {card.cashback} +
+ + Select Card → + +
+
+ ))} +
+
+
+ + {/* 4. PROCESS / HOW IT WORKS SECTION */} +
+
+
+ • SYSTEM OPERATIONS +

Three steps to automatic returns

+

+ We simplified transaction logistics so you can accumulate rewards effortlessly. +

+
+ +
+ + {/* Step 1 */} +
+
01
+

Link Card Wallet

+

+ Register your account and secure a read-only bridge to your spending vault. We employ bank-level aggregation pipelines. +

+
+ + {/* Step 2 */} +
+
02
+

Purchase Digital Cards

+

+ Browse our detailed catalog and buy gift cards instantly. Cards are immediately stored and managed inside your app wallet. +

+
+ + {/* Step 3 */} +
+
03
+

Earn Instant Cashback

+

+ Watch rewards automatically compound. Cash out directly to local banks or electronic cash wallets anytime with one click. +

+
+ +
+
+
+ + {/* 5. INTERACTIVE CALCULATOR */} +
+
+ +
+ • SAVINGS ESTIMATION +

Project your annual savings

+

+ Slide to indicate your estimated monthly spend on everyday partner categories. +

+
+ +
+ +
+
+ Monthly Spending + ₱{monthlySpend.toLocaleString()} +
+ + setMonthlySpend(Number(e.target.value))} + className="w-full h-1 bg-slate-900 rounded-lg appearance-none cursor-pointer accent-purple-400" + /> +
+ ₱5,000 + ₱50,000 + ₱100,000+ +
+
+ +
+
+ Average Reward Percentage + 8.0% Cashback Yield +
+ +
+ Estimated Annual Return + ₱{annualSavings.toLocaleString()} +
+
+ +
+
-
-
); }