Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1fb7758e17 | |||
| 96bff63066 | |||
| b7b936fc38 | |||
| 7687a9b6f9 | |||
| 03c1c55d3a | |||
| 57b6b4b3e0 |
146
src/app/cart/page.tsx
Normal file
146
src/app/cart/page.tsx
Normal file
@@ -0,0 +1,146 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import { ThemeProvider } from "@/providers/themeProvider/ThemeProvider";
|
||||||
|
import NavbarLayoutFloatingOverlay from "@/components/navbar/NavbarLayoutFloatingOverlay/NavbarLayoutFloatingOverlay";
|
||||||
|
import { useState } from "react";
|
||||||
|
import { ShoppingCart, Trash2, Minus, Plus } from "lucide-react";
|
||||||
|
import Link from "next/link";
|
||||||
|
|
||||||
|
interface CartItem {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
price: string;
|
||||||
|
quantity: number;
|
||||||
|
imageSrc: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function CartPage() {
|
||||||
|
const [cartItems, setCartItems] = useState<CartItem[]>([
|
||||||
|
{
|
||||||
|
id: "1", name: "Classic Rainbow Lollipops", price: "$12.99", quantity: 2,
|
||||||
|
imageSrc: "http://img.b2bpic.net/free-photo/valentines-day-postcard-with-red-lollipops-white-background_1268-31406.jpg?_wi=2"},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const handleQuantityChange = (id: string, newQuantity: number) => {
|
||||||
|
if (newQuantity < 1) return;
|
||||||
|
setCartItems(cartItems.map(item =>
|
||||||
|
item.id === id ? { ...item, quantity: newQuantity } : item
|
||||||
|
));
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleRemove = (id: string) => {
|
||||||
|
setCartItems(cartItems.filter(item => item.id !== id));
|
||||||
|
};
|
||||||
|
|
||||||
|
const calculateTotal = () => {
|
||||||
|
return cartItems.reduce((total, item) => {
|
||||||
|
const price = parseFloat(item.price.replace("$", ""));
|
||||||
|
return total + (price * item.quantity);
|
||||||
|
}, 0).toFixed(2);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ThemeProvider
|
||||||
|
defaultButtonVariant="icon-arrow"
|
||||||
|
defaultTextAnimation="background-highlight"
|
||||||
|
borderRadius="pill"
|
||||||
|
contentWidth="smallMedium"
|
||||||
|
sizing="largeSmallSizeLargeTitles"
|
||||||
|
background="circleGradient"
|
||||||
|
cardStyle="gradient-bordered"
|
||||||
|
primaryButtonStyle="diagonal-gradient"
|
||||||
|
secondaryButtonStyle="layered"
|
||||||
|
headingFontWeight="normal"
|
||||||
|
>
|
||||||
|
<div id="nav" data-section="nav">
|
||||||
|
<NavbarLayoutFloatingOverlay
|
||||||
|
brandName="Sweet Baby C's"
|
||||||
|
navItems={[
|
||||||
|
{ name: "Home", id: "/" },
|
||||||
|
{ name: "Our Story", id: "about" },
|
||||||
|
{ name: "Products", id: "products" },
|
||||||
|
{ name: "Reviews", id: "testimonials" },
|
||||||
|
{ name: "FAQ", id: "faq" },
|
||||||
|
]}
|
||||||
|
button={{ text: "Continue Shopping", href: "/" }}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="min-h-screen py-20 px-4 md:px-8">
|
||||||
|
<div className="max-w-4xl mx-auto">
|
||||||
|
<div className="flex items-center gap-3 mb-8">
|
||||||
|
<ShoppingCart className="w-8 h-8" />
|
||||||
|
<h1 className="text-4xl font-bold">Shopping Cart</h1>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{cartItems.length === 0 ? (
|
||||||
|
<div className="text-center py-12">
|
||||||
|
<p className="text-xl mb-6">Your cart is empty</p>
|
||||||
|
<Link
|
||||||
|
href="/"
|
||||||
|
className="inline-block px-6 py-3 bg-[var(--primary-cta)] text-[var(--primary-cta-text)] rounded-full font-semibold hover:opacity-90 transition-opacity"
|
||||||
|
>
|
||||||
|
Continue Shopping
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<div className="space-y-4 mb-8">
|
||||||
|
{cartItems.map((item) => (
|
||||||
|
<div
|
||||||
|
key={item.id}
|
||||||
|
className="flex gap-4 p-4 bg-[var(--card)] rounded-lg border border-[var(--accent)]"
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
src={item.imageSrc}
|
||||||
|
alt={item.name}
|
||||||
|
className="w-24 h-24 object-cover rounded-lg"
|
||||||
|
/>
|
||||||
|
<div className="flex-1">
|
||||||
|
<h3 className="font-semibold mb-2">{item.name}</h3>
|
||||||
|
<p className="text-lg font-bold mb-4">{item.price}</p>
|
||||||
|
<div className="flex items-center gap-3">
|
||||||
|
<button
|
||||||
|
onClick={() => handleQuantityChange(item.id, item.quantity - 1)}
|
||||||
|
className="p-1 rounded hover:bg-[var(--background-accent)] transition-colors"
|
||||||
|
aria-label="Decrease quantity"
|
||||||
|
>
|
||||||
|
<Minus className="w-4 h-4" />
|
||||||
|
</button>
|
||||||
|
<span className="w-8 text-center font-semibold">{item.quantity}</span>
|
||||||
|
<button
|
||||||
|
onClick={() => handleQuantityChange(item.id, item.quantity + 1)}
|
||||||
|
className="p-1 rounded hover:bg-[var(--background-accent)] transition-colors"
|
||||||
|
aria-label="Increase quantity"
|
||||||
|
>
|
||||||
|
<Plus className="w-4 h-4" />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<button
|
||||||
|
onClick={() => handleRemove(item.id)}
|
||||||
|
className="p-2 rounded hover:bg-red-100 text-red-600 transition-colors self-start"
|
||||||
|
aria-label="Remove item"
|
||||||
|
>
|
||||||
|
<Trash2 className="w-5 h-5" />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="bg-[var(--card)] rounded-lg p-6 border border-[var(--accent)]">
|
||||||
|
<div className="flex justify-between items-center mb-6">
|
||||||
|
<span className="text-xl font-semibold">Total:</span>
|
||||||
|
<span className="text-3xl font-bold text-[var(--primary-cta)]">${calculateTotal()}</span>
|
||||||
|
</div>
|
||||||
|
<button className="w-full py-3 bg-[var(--primary-cta)] text-[var(--primary-cta-text)] rounded-full font-semibold hover:opacity-90 transition-opacity">
|
||||||
|
Proceed to Checkout
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ThemeProvider>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,11 +1,13 @@
|
|||||||
import type { Metadata } from "next";
|
import type { Metadata } from "next";
|
||||||
import { Inter } from "next/font/google";
|
import { Inter } from "next/font/google";
|
||||||
import "./globals.css";
|
import "./globals.css";
|
||||||
|
import "./styles/variables.css";
|
||||||
|
import "./styles/base.css";
|
||||||
|
|
||||||
const inter = Inter({ subsets: ["latin"] });
|
const inter = Inter({ subsets: ["latin"] });
|
||||||
|
|
||||||
export const metadata: Metadata = {
|
export const metadata: Metadata = {
|
||||||
title: "Sweet Baby C's - Premium Handcrafted Lollipops & Popsicles", description: "Discover our premium collection of handcrafted lollipops and popsicles made with the finest natural ingredients."};
|
title: "Sweet Baby C's - Premium Lollipops & Popsicles", description: "Discover handcrafted premium lollipops and popsicles made with natural ingredients."};
|
||||||
|
|
||||||
export default function RootLayout({
|
export default function RootLayout({
|
||||||
children,
|
children,
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import SocialProofOne from "@/components/sections/socialProof/SocialProofOne";
|
|||||||
import TestimonialCardFive from "@/components/sections/testimonial/TestimonialCardFive";
|
import TestimonialCardFive from "@/components/sections/testimonial/TestimonialCardFive";
|
||||||
import FaqDouble from "@/components/sections/faq/FaqDouble";
|
import FaqDouble from "@/components/sections/faq/FaqDouble";
|
||||||
import FooterLogoEmphasis from "@/components/sections/footer/FooterLogoEmphasis";
|
import FooterLogoEmphasis from "@/components/sections/footer/FooterLogoEmphasis";
|
||||||
import { Sparkles, Heart, Zap, Users, Star, HelpCircle } from "lucide-react";
|
import { Sparkles, Heart, Zap, Users, Star, HelpCircle, ShoppingCart } from "lucide-react";
|
||||||
|
|
||||||
export default function LandingPage() {
|
export default function LandingPage() {
|
||||||
return (
|
return (
|
||||||
@@ -35,7 +35,7 @@ export default function LandingPage() {
|
|||||||
{ name: "Reviews", id: "testimonials" },
|
{ name: "Reviews", id: "testimonials" },
|
||||||
{ name: "FAQ", id: "faq" },
|
{ name: "FAQ", id: "faq" },
|
||||||
]}
|
]}
|
||||||
button={{ text: "Order Now", href: "#products" }}
|
button={{ text: "Shop Now", href: "#products" }}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -48,7 +48,7 @@ export default function LandingPage() {
|
|||||||
tagAnimation="slide-up"
|
tagAnimation="slide-up"
|
||||||
background={{ variant: "plain" }}
|
background={{ variant: "plain" }}
|
||||||
buttons={[
|
buttons={[
|
||||||
{ text: "Browse Products", href: "#products" },
|
{ text: "Shop Lollipops", href: "#products" },
|
||||||
{ text: "Learn More", href: "#about" },
|
{ text: "Learn More", href: "#about" },
|
||||||
]}
|
]}
|
||||||
buttonAnimation="slide-up"
|
buttonAnimation="slide-up"
|
||||||
@@ -98,17 +98,17 @@ export default function LandingPage() {
|
|||||||
tagAnimation="slide-up"
|
tagAnimation="slide-up"
|
||||||
products={[
|
products={[
|
||||||
{
|
{
|
||||||
id: "1", name: "Classic Rainbow Lollipops", price: "$12.99", imageSrc: "http://img.b2bpic.net/free-photo/valentines-day-postcard-with-red-lollipops-white-background_1268-31406.jpg", imageAlt: "Classic rainbow lollipop", initialQuantity: 1,
|
id: "1", name: "Classic Rainbow Lollipops", price: "$12.99", imageSrc: "http://img.b2bpic.net/free-photo/valentines-day-postcard-with-red-lollipops-white-background_1268-31406.jpg?_wi=1", imageAlt: "Classic rainbow lollipop", initialQuantity: 1,
|
||||||
},
|
onProductClick: () => window.location.href = "/cart"},
|
||||||
{
|
{
|
||||||
id: "2", name: "Tropical Popsicles Mix", price: "$14.99", imageSrc: "http://img.b2bpic.net/free-vector/realistic-summer-background_23-2148965901.jpg", imageAlt: "Tropical popsicle collection", initialQuantity: 1,
|
id: "2", name: "Tropical Popsicles Mix", price: "$14.99", imageSrc: "http://img.b2bpic.net/free-vector/realistic-summer-background_23-2148965901.jpg", imageAlt: "Tropical popsicle collection", initialQuantity: 1,
|
||||||
},
|
onProductClick: () => window.location.href = "/cart"},
|
||||||
{
|
{
|
||||||
id: "3", name: "Berry Burst Lollipops", price: "$13.99", imageSrc: "http://img.b2bpic.net/free-photo/top-view-colored-icicle-with-marmalade-form-raspberries-blackberries-blue-background_141793-11426.jpg", imageAlt: "Berry flavored lollipops", initialQuantity: 1,
|
id: "3", name: "Berry Burst Lollipops", price: "$13.99", imageSrc: "http://img.b2bpic.net/free-photo/top-view-colored-icicle-with-marmalade-form-raspberries-blackberries-blue-background_141793-11426.jpg", imageAlt: "Berry flavored lollipops", initialQuantity: 1,
|
||||||
},
|
onProductClick: () => window.location.href = "/cart"},
|
||||||
{
|
{
|
||||||
id: "4", name: "Citrus Sunshine Popsicles", price: "$15.99", imageSrc: "http://img.b2bpic.net/free-photo/top-view-yummy-popsicles-with-mint-orange_23-2148763611.jpg", imageAlt: "Citrus popsicle assortment", initialQuantity: 1,
|
id: "4", name: "Citrus Sunshine Popsicles", price: "$15.99", imageSrc: "http://img.b2bpic.net/free-photo/top-view-yummy-popsicles-with-mint-orange_23-2148763611.jpg", imageAlt: "Citrus popsicle assortment", initialQuantity: 1,
|
||||||
},
|
onProductClick: () => window.location.href = "/cart"},
|
||||||
]}
|
]}
|
||||||
gridVariant="four-items-2x2-equal-grid"
|
gridVariant="four-items-2x2-equal-grid"
|
||||||
animationType="slide-up"
|
animationType="slide-up"
|
||||||
|
|||||||
Reference in New Issue
Block a user