diff --git a/src/app/checkout/page.tsx b/src/app/checkout/page.tsx new file mode 100644 index 0000000..bdbe4e0 --- /dev/null +++ b/src/app/checkout/page.tsx @@ -0,0 +1,305 @@ +"use client"; + +import { ThemeProvider } from "@/providers/themeProvider/ThemeProvider"; +import ReactLenis from "lenis/react"; +import NavbarStyleCentered from '@/components/navbar/NavbarStyleCentered/NavbarStyleCentered'; +import FooterBaseReveal from '@/components/sections/footer/FooterBaseReveal'; +import Input from '@/components/form/Input'; +import ButtonHoverBubble from '@/components/button/ButtonHoverBubble'; +import { useState } from "react"; + +export default function CheckoutPage() { + const [shippingInfo, setShippingInfo] = useState({ + fullName: "", address: "", city: "", state: "", zipCode: "", country: "" + }); + + const [paymentInfo, setPaymentInfo] = useState({ + cardNumber: "", cardName: "", expiryDate: "", cvv: "" + }); + + const [orderConfirmed, setOrderConfirmed] = useState(false); + + const handleShippingChange = (field: string, value: string) => { + setShippingInfo((prev) => ({ ...prev, [field]: value })); + }; + + const handlePaymentChange = (field: string, value: string) => { + setPaymentInfo((prev) => ({ ...prev, [field]: value })); + }; + + const handlePlaceOrder = async (e: React.FormEvent) => { + e.preventDefault(); + // Simulate API call for order placement + console.log("Placing order with:", shippingInfo, paymentInfo); + // In a real app, you'd send this to an API endpoint + const response = await fetch('/api/checkout', { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ shippingInfo, paymentInfo, items: [] }) // Add actual cart items + }); + + if (response.ok) { + setOrderConfirmed(true); + console.log("Order placed successfully!"); + // Optionally clear cart or redirect + } else { + console.error("Order failed:", await response.json()); + alert("Order placement failed. Please try again."); + } + }; + + // Dummy order summary data + const orderItems = [ + { id: "prod-1", name: "Luxury Velocity Runner", price: 12500, quantity: 1 }, + { id: "prod-4", name: "Aura X Wireless Earbuds", price: 8999, quantity: 1 } + ]; + const subtotal = orderItems.reduce((sum, item) => sum + item.price * item.quantity, 0); + const shippingCost = 500; // Example + const total = subtotal + shippingCost; + + + if (orderConfirmed) { + return ( + + + + +
+

Order Confirmed!

+

Thank you for your purchase. Your order has been successfully placed.

+ +
+ + +
+
+ ); + } + + + return ( + + + + +
+
+

Checkout

+ +
+ {/* Shipping Information */} +
+

Shipping Information

+
+ handleShippingChange("fullName", val)} + placeholder="Full Name" + required + ariaLabel="Full Name" + /> + handleShippingChange("address", val)} + placeholder="Address" + required + ariaLabel="Address" + /> +
+ handleShippingChange("city", val)} + placeholder="City" + required + ariaLabel="City" + /> + handleShippingChange("state", val)} + placeholder="State/Province" + required + ariaLabel="State/Province" + /> +
+
+ handleShippingChange("zipCode", val)} + placeholder="Zip Code" + required + ariaLabel="Zip Code" + /> + handleShippingChange("country", val)} + placeholder="Country" + required + ariaLabel="Country" + /> +
+
+
+ + {/* Order Summary & Payment */} +
+ {/* Order Summary */} +
+

Order Summary

+
+ {orderItems.map((item) => ( +
+ {item.name} (x{item.quantity}) + ₹{(item.price * item.quantity).toLocaleString()} +
+ ))} +
+
+ Subtotal + ₹{subtotal.toLocaleString()} +
+
+ Shipping + ₹{shippingCost.toLocaleString()} +
+
+ Total + ₹{total.toLocaleString()} +
+
+
+
+ + {/* Payment Information */} +
+

Payment Information

+
+ handlePaymentChange("cardName", val)} + placeholder="Name on Card" + required + ariaLabel="Name on Card" + /> + handlePaymentChange("cardNumber", val)} + placeholder="Card Number" + type="text" + inputMode="numeric" + pattern="[0-9]{13,16}" // Basic card number pattern + required + ariaLabel="Card Number" + /> +
+ handlePaymentChange("expiryDate", val)} + placeholder="MM/YY" + type="text" + pattern="(0[1-9]|1[0-2])\/?([0-9]{2})" // MM/YY pattern + required + ariaLabel="Expiry Date" + /> + handlePaymentChange("cvv", val)} + placeholder="CVV" + type="text" + pattern="[0-9]{3,4}" // CVV pattern + required + ariaLabel="CVV" + /> +
+
+
+ + {/* Place Order Button */} +
+ +
+
+
+
+
+ + +
+
+ ); +} diff --git a/src/app/page.tsx b/src/app/page.tsx index e97803f..d904158 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -40,6 +40,8 @@ export default function LandingPage() { name: "About", id: "/about"}, { name: "Contact", id: "/contact"}, + { + name: "My Account", id: "/user/dashboard"} ]} button={{ text: "Admin Login", href: "/admin"}} @@ -163,4 +165,4 @@ export default function LandingPage() { ); -} +} \ No newline at end of file diff --git a/src/app/products/[productId]/page.tsx b/src/app/products/[productId]/page.tsx new file mode 100644 index 0000000..eb85a76 --- /dev/null +++ b/src/app/products/[productId]/page.tsx @@ -0,0 +1,98 @@ +"use client"; + +import { ThemeProvider } from "@/providers/themeProvider/ThemeProvider"; +import ReactLenis from "lenis/react"; +import NavbarStyleCentered from '@/components/navbar/NavbarStyleCentered/NavbarStyleCentered'; +import FooterBaseReveal from '@/components/sections/footer/FooterBaseReveal'; +import ProductDetailCard from '@/components/ecommerce/productDetail/ProductDetailCard'; +import { Star } from 'lucide-react'; + +export default function ProductDetailPage({ params }: { params: { productId: string } }) { + // In a real application, you would fetch product data based on params.productId + const productData = { + id: params.productId, + name: "Luxury Velocity Runner", price: "₹12,500", description: "Experience unparalleled comfort and style with our Luxury Velocity Runner. Crafted from premium materials, these sneakers offer superior cushioning and dynamic support for your everyday adventures. Featuring a sleek design and advanced sole technology, they are perfect for both athletic performance and casual wear. Available in multiple sizes and limited-edition colors.", images: [ + { src: "http://img.b2bpic.net/free-photo/view-white-ice-skates-with-cherries-tangerines_23-2150806813.jpg", alt: "Luxury Velocity Runner front view" }, + { src: "http://img.b2bpic.net/free-photo/white-sneakers-with-red-sole-against-white-background_23-2147746592.jpg", alt: "Luxury Velocity Runner side view" }, + { src: "http://img.b2bpic.net/free-photo/pair-white-sneakers_23-2147746591.jpg", alt: "Luxury Velocity Runner top view" } + ], + variants: [ + { + label: "Size", options: ["US 7", "US 8", "US 9", "US 10", "US 11", "US 12"], + selected: "US 9", onChange: (value: string) => console.log("Selected size:", value) + }, + { + label: "Color", options: ["White", "Black", "Grey", "Blue"], + selected: "White", onChange: (value: string) => console.log("Selected color:", value) + } + ], + quantity: { + label: "Quantity", options: ["1", "2", "3", "4", "5"], + selected: "1", onChange: (value: string) => console.log("Selected quantity:", value) + }, + rating: 4.5, + stock: 15 + }; + + const navItems = [ + { name: "Home", id: "/" }, + { name: "Shop", id: "/products/prod-1" } + ]; + + return ( + + + + +
+ alert(`Buying ${productData.name} (ID: ${productData.id})`) } + ]} + /> +
+ + +
+
+ ); +} diff --git a/src/app/user/dashboard/page.tsx b/src/app/user/dashboard/page.tsx new file mode 100644 index 0000000..94a92db --- /dev/null +++ b/src/app/user/dashboard/page.tsx @@ -0,0 +1,74 @@ +"use client"; + +import { ThemeProvider } from "@/providers/themeProvider/ThemeProvider"; +import ReactLenis from "lenis/react"; +import NavbarStyleCentered from '@/components/navbar/NavbarStyleCentered/NavbarStyleCentered'; +import FooterBaseReveal from '@/components/sections/footer/FooterBaseReveal'; + +export default function UserDashboardPage() { + return ( + + + + +
+

My Account & Order History

+
+
+

Order History

+

No orders found. Start shopping today!

+ {/* Placeholder for order list */} +
+
+

Account Details

+

Manage your profile, addresses, and payment methods here.

+ {/* Placeholder for account details */} +
+
+

Order Tracking

+

Enter your order number to track your shipment.

+ {/* Placeholder for tracking input and status */} +
+
+
+ + +
+
+ ); +} \ No newline at end of file diff --git a/src/context/CartContext.tsx b/src/context/CartContext.tsx new file mode 100644 index 0000000..6df19a2 --- /dev/null +++ b/src/context/CartContext.tsx @@ -0,0 +1,106 @@ +"use client"; + +import React, { createContext, useContext, useState, useEffect, ReactNode } from 'react'; + +interface CartItem { + id: string; + name: string; + price: number; // Store price as number for calculations + imageSrc: string; + quantity: number; +} + +interface CartContextType { + cartItems: CartItem[]; + addToCart: (item: Omit) => void; + removeFromCart: (id: string) => void; + updateQuantity: (id: string, quantity: number) => void; + clearCart: () => void; + cartTotal: number; +} + +const CartContext = createContext(undefined); + +export const CartProvider = ({ children }: { children: ReactNode }) => { + const [cartItems, setCartItems] = useState([]); + + useEffect(() => { + // Load cart from localStorage on mount + if (typeof window !== 'undefined') { + const storedCart = localStorage.getItem('cart'); + if (storedCart) { + setCartItems(JSON.parse(storedCart)); + } + } + }, []); + + useEffect(() => { + // Save cart to localStorage whenever it changes + if (typeof window !== 'undefined') { + localStorage.setItem('cart', JSON.stringify(cartItems)); + } + }, [cartItems]); + + const addToCart = (item: Omit) => { + setCartItems((prevItems) => { + const existingItem = prevItems.find((cartItem) => cartItem.id === item.id); + if (existingItem) { + return prevItems.map((cartItem) => + cartItem.id === item.id + ? { ...cartItem, quantity: cartItem.quantity + 1 } + : cartItem + ); + } else { + return [...prevItems, { ...item, quantity: 1 }]; + } + }); + }; + + const removeFromCart = (id: string) => { + setCartItems((prevItems) => prevItems.filter((item) => item.id !== id)); + }; + + const updateQuantity = (id: string, quantity: number) => { + if (quantity <= 0) { + removeFromCart(id); + return; + } + setCartItems((prevItems) => + prevItems.map((item) => + item.id === id ? { ...item, quantity: quantity } : item + ) + ); + }; + + const clearCart = () => { + setCartItems([]); + }; + + const cartTotal = cartItems.reduce( + (total, item) => total + item.price * item.quantity, + 0 + ); + + return ( + + {children} + + ); +}; + +export const useCart = () => { + const context = useContext(CartContext); + if (context === undefined) { + throw new Error('useCart must be used within a CartProvider'); + } + return context; +};