Bob AI: Add cart page
This commit is contained in:
@@ -3,12 +3,14 @@ import Layout from './components/Layout';
|
||||
import HomePage from './pages/HomePage';
|
||||
|
||||
import MenuOrderPage from "@/pages/MenuOrderPage";
|
||||
import CartPage from "@/pages/CartPage";
|
||||
export default function App() {
|
||||
return (
|
||||
<Routes>
|
||||
<Route element={<Layout />}>
|
||||
<Route path="/" element={<HomePage />} />
|
||||
<Route path="/menu-order" element={<MenuOrderPage />} />
|
||||
<Route path="/cart" element={<CartPage />} />
|
||||
</Route>
|
||||
</Routes>
|
||||
);
|
||||
|
||||
@@ -36,6 +36,8 @@ export default function Layout() {
|
||||
"href": "#social-proof"
|
||||
},
|
||||
{ name: "Menu Order", href: "/menu-order" },
|
||||
{ name: "Cart", href: "/cart" },
|
||||
|
||||
|
||||
];
|
||||
|
||||
|
||||
110
src/pages/CartPage.tsx
Normal file
110
src/pages/CartPage.tsx
Normal file
@@ -0,0 +1,110 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import NavbarCentered from "@/components/ui/NavbarCentered";
|
||||
import FooterSimple from "@/components/sections/footer/FooterSimple";
|
||||
import Button from "@/components/ui/Button";
|
||||
import Card from "@/components/ui/Card";
|
||||
import Separator from "@/components/ui/Separator";
|
||||
import { routes } from "@/routes";
|
||||
|
||||
interface CartItem {
|
||||
id: string;
|
||||
name: string;
|
||||
price: number;
|
||||
quantity: number;
|
||||
}
|
||||
|
||||
const CartPage: React.FC = () => {
|
||||
const [cartItems, setCartItems] = useState<CartItem[]>([]);
|
||||
|
||||
useEffect(() => {
|
||||
const storedCart = localStorage.getItem("cart");
|
||||
if (storedCart) {
|
||||
setCartItems(JSON.parse(storedCart));
|
||||
} else {
|
||||
// Simulate some items being added to cart from other pages for demonstration
|
||||
const dummyItems: CartItem[] = [
|
||||
{ id: "1", name: "Wireless Headphones", price: 99.99, quantity: 1 },
|
||||
{ id: "2", name: "Smartwatch", price: 199.99, quantity: 2 },
|
||||
];
|
||||
localStorage.setItem("cart", JSON.stringify(dummyItems));
|
||||
setCartItems(dummyItems);
|
||||
}
|
||||
}, []);
|
||||
|
||||
const removeItem = (id: string) => {
|
||||
const updatedCart = cartItems.filter((item) => item.id !== id);
|
||||
setCartItems(updatedCart);
|
||||
localStorage.setItem("cart", JSON.stringify(updatedCart));
|
||||
};
|
||||
|
||||
const total = cartItems.reduce((sum, item) => sum + item.price * item.quantity, 0);
|
||||
|
||||
return (
|
||||
<div className="flex min-h-screen flex-col bg-background text-foreground">
|
||||
<NavbarCentered
|
||||
logo="Webild"
|
||||
navItems={routes.map((r) => ({ name: r.label, href: r.path }))}
|
||||
ctaButton={{ text: "Get Started", href: "/contact" }}
|
||||
/>
|
||||
|
||||
<main className="container mx-auto flex-grow px-4 py-12 md:px-6 lg:py-16">
|
||||
<h1 className="mb-8 text-center text-4xl font-bold tracking-tight lg:text-5xl">
|
||||
Your Shopping Cart
|
||||
</h1>
|
||||
|
||||
{cartItems.length === 0 ? (
|
||||
<p className="text-center text-muted-foreground">Your cart is empty.</p>
|
||||
) : (
|
||||
<div className="mx-auto max-w-3xl">
|
||||
<div className="space-y-4">
|
||||
{cartItems.map((item) => (
|
||||
<Card key={item.id} className="flex items-center justify-between p-4">
|
||||
<div>
|
||||
<h3 className="font-semibold">{item.name}</h3>
|
||||
<p className="text-muted-foreground text-sm">
|
||||
${item.price.toFixed(2)} x {item.quantity}
|
||||
</p>
|
||||
</div>
|
||||
<Button
|
||||
text="Remove"
|
||||
variant="secondary"
|
||||
onClick={() => removeItem(item.id)}
|
||||
/>
|
||||
</Card>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<Separator className="my-8" />
|
||||
|
||||
<div className="flex items-center justify-between text-2xl font-bold">
|
||||
<span>Total:</span>
|
||||
<span>${total.toFixed(2)}</span>
|
||||
</div>
|
||||
|
||||
<div className="mt-8 text-center">
|
||||
<Button text="Proceed to Checkout" href="/checkout" />
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</main>
|
||||
|
||||
<FooterSimple
|
||||
brand="Webild"
|
||||
columns={[
|
||||
{
|
||||
title: "Product",
|
||||
items: [{ label: "Features", href: "/features" }],
|
||||
},
|
||||
{
|
||||
title: "Company",
|
||||
items: [{ label: "About", href: "/about" }],
|
||||
},
|
||||
]}
|
||||
copyright="© 2024 Webild. All rights reserved."
|
||||
links={[{ label: "Privacy Policy", href: "/privacy" }]}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default CartPage;
|
||||
@@ -7,4 +7,5 @@ export interface Route {
|
||||
export const routes: Route[] = [
|
||||
{ path: '/', label: 'Home', pageFile: 'HomePage' },
|
||||
{ path: '/menu-order', label: 'Menu Order', pageFile: 'MenuOrderPage' },
|
||||
{ path: '/cart', label: 'Cart', pageFile: 'CartPage' },
|
||||
];
|
||||
|
||||
Reference in New Issue
Block a user