Skip to content

Commit 91e6f48

Browse files
committed
add shopping cart
1 parent 2c57c41 commit 91e6f48

File tree

10 files changed

+159
-108
lines changed

10 files changed

+159
-108
lines changed

examples/ecommerce-jewellery-store/src/App.tsx

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,9 @@ import Header from "@/components/Header";
33
import Footer from "@/components/Footer";
44
import Contacts from "@/pages/Contacts";
55
import ThankYou from "@/pages/ThankYou";
6-
import ShoppingCart from "@/pages/ShoppingCart";
76
import PaymentDetails from "@/pages/PaymentDetails";
87
import { AllProductsListView } from "./pages/AllProductsListView";
9-
import Home from "@/pages/Home";
8+
import Home from "@/pages/Home";
109
import "@progress/kendo-theme-default/dist/all.css";
1110
import "@progress/kendo-theme-utils/dist/all.scss";
1211
import { SizedParent } from "./components/SizedParent";
@@ -16,20 +15,19 @@ import { ProductDetails } from './pages/ProductsDetails';
1615
function App() {
1716
return (
1817
<Router>
18+
<Header />
1919
<SizedParent>
20-
<Header />
2120
<Routes>
22-
<Route path="/" element={<Home />} />
21+
<Route path="/" element={<Home />} />
2322
<Route path="/paymentdetails" element={<PaymentDetails />} />
24-
<Route path="/shoppingcart" element={<ShoppingCart />} />
2523
<Route path="/thankyou" element={<ThankYou />} />
2624
<Route path="/contacts" element={<Contacts />} />
2725
<Route path="/products" element={<AllProductsListView />} />
2826
<Route path="/category" element={<DetailedCategory />} />
2927
<Route path="/product/:id" element={<ProductDetails />} />
3028
</Routes>
31-
<Footer />
3229
</SizedParent>
30+
<Footer />
3331
</Router>
3432
);
3533
}

examples/ecommerce-jewellery-store/src/components/CategoryList.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { CategoryListProps } from "../data/types";
44
import { Button } from "@progress/kendo-react-buttons";
55
import { CardDescriptor } from "../data/types";
66

7-
export const CategoryList: React.FC<CategoryListProps> = ({data, title, subtitle, colSpan=4}) => {
7+
export const CategoryList: React.FC<CategoryListProps> = ({ data, title, subtitle, colSpan = 4 }) => {
88
const navigate = useNavigate();
99

1010
const onNavigate = (card: CardDescriptor) => {

examples/ecommerce-jewellery-store/src/components/ProductCard.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import { Button } from "@progress/kendo-react-buttons";
55

66
export const ProductCard = (props: ProductCardProps) => {
77

8+
const onAddToCartClick = () => {
9+
}
810

911
return (
1012
<>
@@ -54,7 +56,7 @@ export const ProductCard = (props: ProductCardProps) => {
5456
<NumericTextBox spinners={true} style={{
5557
width: "84px"
5658
}} value={1}></NumericTextBox>
57-
<Button themeColor={"primary"}>Add to Cart</Button>
59+
<Button themeColor={"primary"} onClick={onAddToCartClick}>Add to Cart</Button>
5860
</div>
5961

6062
</div>
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
export const ShoppingCartList: React.FC = () => {
2+
3+
return (
4+
<>
5+
Shopping Cart
6+
</>
7+
);
8+
};

examples/ecommerce-jewellery-store/src/components/Testemonials.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,16 +29,16 @@ const testemonialsData: TestemonialsDataDescriptor[] = [
2929

3030
export const Testemonials = () => {
3131
return (
32-
<div className="k-d-flex k-flex-col k-align-items-center k-py-12 k-px-10 k-mx-auto k-bg-surface">
32+
<div className="k-d-flex k-flex-col k-align-items-center k-py-12 k-px-10 k-mx-auto">
3333
<div className="k-d-flex k-flex-col k-align-items-center k-gap-4 k-mb-10">
3434
<h2 className="k-h2">Customers words</h2>
3535
<p className="k-font-size-xl k-color-subtle">
3636
What do they say about us?
3737
</p>
3838
</div>
3939
<div className="k-d-grid k-grid-cols-3 k-gap-5 k-mb-6">
40-
{testemonialsData.map((item) => (
41-
<div className="k-d-flex k-flex-col k-border-solid k-border k-bg-app-surface k-rounded-lg k-border-border">
40+
{testemonialsData.map((item, index) => (
41+
<div key={index} className="k-d-flex k-flex-col k-border-solid k-border k-bg-surface k-bg-app-surface k-rounded-lg k-border-border">
4242
<div className="k-d-grid k-grid-cols-3 k-justify-items-center k-px-4 k-py-3 k-gap-y-3">
4343
<div className="k-col-start-1 k-col-end-4 k-d-grid k-grid-cols-3 k-justify-items-center k-w-full">
4444
<Avatar

examples/ecommerce-jewellery-store/src/data/listData.ts

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,18 +18,7 @@ import handmadeDiamongRing from "../assets/listViewImages/handmadeDiamongRing.pn
1818
import diamondRingRuby from "../assets/listViewImages/diamondRingRuby.png";
1919
import stainlessSteelWatch from "../assets/listViewImages/stainlessSteelWatch.png";
2020
import goldEarringsGarnet from "../assets/listViewImages/goldEarringsGarnet.png";
21-
22-
type ListDataDescriptor = {
23-
id: number;
24-
img: string | null;
25-
status: string | null;
26-
title: string;
27-
category: "Bracelets" | "Earrings" | "Rings" | "Watches" | "Necklaces";
28-
material: "Silver" | "Gold";
29-
oldPrice: number | null;
30-
newPrice: number;
31-
rating: number;
32-
};
21+
import { ListDataDescriptor } from "./types";
3322

3423
export const listData: ListDataDescriptor[] = [{
3524
img: diamongWeddingRing,
@@ -83,7 +72,7 @@ export const listData: ListDataDescriptor[] = [{
8372
}, {
8473
img: diamondWeddingBands,
8574
status: "recommended",
86-
title: "Diamong Wedding Bands",
75+
title: "Diamond Wedding Bands",
8776
material: "Gold",
8877
category: "Rings",
8978
oldPrice: null,

examples/ecommerce-jewellery-store/src/data/types.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,4 +72,23 @@ export type TestemonialsDataDescriptor = {
7272
name: string;
7373
description: string;
7474
rating: number;
75+
}
76+
77+
export type CartItemDescriptor = {
78+
id: number;
79+
image: string;
80+
title: string;
81+
description: string;
82+
price: number;
83+
quantity: number;
84+
total: number;
85+
}
86+
87+
export type CartContextProps = {
88+
children: React.ReactNode;
89+
}
90+
91+
export type CartContextDescriptor = {
92+
id: number;
93+
quantity: number;
7594
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import { createContext, useState, useContext, ReactNode } from 'react';
2+
import { CartContextDescriptor } from '../data/types';
3+
4+
interface CartContextType {
5+
cart: CartContextDescriptor[];
6+
addItemToCart: (item: CartContextDescriptor) => void;
7+
}
8+
9+
const ShoppingCartContext = createContext<CartContextType | null>(null);
10+
11+
interface CartProviderProps {
12+
children: ReactNode;
13+
}
14+
15+
export const CartProvider = ({ children }: CartProviderProps) => {
16+
const [shoppingCart, setShoppingCart] = useState<CartContextDescriptor[]>([]);
17+
18+
const addItemToCart = (item: CartContextDescriptor) => {
19+
const itemExists = shoppingCart.some(x => x.id === item.id);
20+
21+
if (itemExists) {
22+
setShoppingCart(shoppingCart.map(cartItem =>
23+
cartItem.id === item.id
24+
? { ...cartItem, quantity: cartItem?.quantity + 1 }
25+
: cartItem
26+
));
27+
} else {
28+
setShoppingCart([...shoppingCart, { ...item, quantity: 1 }]);
29+
}
30+
};
31+
32+
return (
33+
<ShoppingCartContext.Provider value={{ cart: shoppingCart, addItemToCart }}>
34+
{children}
35+
</ShoppingCartContext.Provider>
36+
);
37+
};
38+
39+
export const useCart = () => {
40+
const context = useContext(ShoppingCartContext);
41+
if (context === null) {
42+
throw new Error('useCart must be used within a CartProvider');
43+
}
44+
return context;
45+
};

examples/ecommerce-jewellery-store/src/pages/Home.tsx

Lines changed: 74 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -73,79 +73,80 @@ const Home: React.FC = () => {
7373
<BackgroundImage title={title}
7474
subtitle={subtitle}
7575
buttonText={buttonText}
76-
img={model}></BackgroundImage>
77-
<Layout>
78-
<section
79-
className="k-d-grid k-grid-cols-12 k-justify-content-center k-align-items-center k-col-span-12"
80-
style={{
81-
paddingTop: "60px",
82-
}}
83-
>
84-
<CategoryList title='Our Bestsellers' subtitle='Enjoy an excellent selection of fine jewelry'
85-
data={data}></CategoryList>
86-
</section>
87-
</Layout>
88-
<Layout>
89-
<CustomSection>
90-
<OrderedImgText
91-
title='Timeless Classics'
92-
subtitle='Get our unique handmade collections'
93-
contentText='Jewelry enhances style and adds elegance, with each piece telling a unique story.'
94-
img={homeModel2}
95-
order='first'
96-
link="Shop Now"
97-
></OrderedImgText>
98-
</CustomSection>
99-
</Layout>
100-
<Layout>
101-
<CustomSection>
102-
<OrderedImgText
103-
title='Fine Jewelry'
104-
subtitle='Get our unique handmade collections'
105-
contentText="Jewelry elevates one's style and brings sophistication, with every piece narrating a distinct tale."
106-
img={homeModel3}
107-
order='last'
108-
link="Shop Now"
109-
></OrderedImgText>
110-
</CustomSection>
111-
</Layout>
112-
<Layout>
113-
<CustomSection>
114-
<CategoryList colSpan={6} title='Our Rings' subtitle='Enjoy an excellent selection of fine rings' data={ringsData}></CategoryList>
115-
</CustomSection>
116-
</Layout>
117-
<Layout>
118-
<CustomSection>
119-
<OrderedImgText
120-
title='Always On Time'
121-
subtitle='Get our unique watches'
122-
contentText='High-end gold watches for men are the epitome of luxury, combining precision with sophisticated craftsmanship.'
123-
img={homeWatch1}
124-
order='first'
125-
link="Shop Now"
126-
></OrderedImgText>
127-
</CustomSection>
128-
</Layout>
129-
<Layout>
130-
<CustomSection>
131-
<CategoryList title='Our Watches' subtitle='Enjoy an excellent selection of watches ' data={watchData}></CategoryList>
132-
</CustomSection>
133-
</Layout>
134-
<Layout>
135-
<CustomSection>
136-
<OrderedImgText
137-
title='Services'
138-
subtitle='Explore expert repairs to elevate your experience'
139-
contentText='Vilora provides services like custom designs, repairs, and appraisals to enhance the customer experience.'
140-
img={homeServicesImage}
141-
order='last'
142-
link="Learn More"
143-
></OrderedImgText>
144-
</CustomSection>
145-
</Layout>
146-
<Layout>
147-
<Testemonials></Testemonials>
148-
</Layout>
76+
img={model}>
77+
</BackgroundImage>
78+
<Layout>
79+
<section
80+
className="k-d-grid k-grid-cols-12 k-justify-content-center k-align-items-center k-col-span-12"
81+
style={{
82+
paddingTop: "60px",
83+
}}
84+
>
85+
<CategoryList title='Our Bestsellers' subtitle='Enjoy an excellent selection of fine jewelry'
86+
data={data}></CategoryList>
87+
</section>
88+
</Layout>
89+
<Layout>
90+
<CustomSection>
91+
<OrderedImgText
92+
title='Timeless Classics'
93+
subtitle='Get our unique handmade collections'
94+
contentText='Jewelry enhances style and adds elegance, with each piece telling a unique story.'
95+
img={homeModel2}
96+
order='first'
97+
link="Shop Now"
98+
></OrderedImgText>
99+
</CustomSection>
100+
</Layout>
101+
<Layout>
102+
<CustomSection>
103+
<OrderedImgText
104+
title='Fine Jewelry'
105+
subtitle='Get our unique handmade collections'
106+
contentText="Jewelry elevates one's style and brings sophistication, with every piece narrating a distinct tale."
107+
img={homeModel3}
108+
order='last'
109+
link="Shop Now"
110+
></OrderedImgText>
111+
</CustomSection>
112+
</Layout>
113+
<Layout>
114+
<CustomSection>
115+
<CategoryList colSpan={6} title='Our Rings' subtitle='Enjoy an excellent selection of fine rings' data={ringsData}></CategoryList>
116+
</CustomSection>
117+
</Layout>
118+
<Layout>
119+
<CustomSection>
120+
<OrderedImgText
121+
title='Always On Time'
122+
subtitle='Get our unique watches'
123+
contentText='High-end gold watches for men are the epitome of luxury, combining precision with sophisticated craftsmanship.'
124+
img={homeWatch1}
125+
order='first'
126+
link="Shop Now"
127+
></OrderedImgText>
128+
</CustomSection>
129+
</Layout>
130+
<Layout>
131+
<CustomSection>
132+
<CategoryList title='Our Watches' subtitle='Enjoy an excellent selection of watches ' data={watchData}></CategoryList>
133+
</CustomSection>
134+
</Layout>
135+
<Layout>
136+
<CustomSection>
137+
<OrderedImgText
138+
title='Services'
139+
subtitle='Explore expert repairs to elevate your experience'
140+
contentText='Vilora provides services like custom designs, repairs, and appraisals to enhance the customer experience.'
141+
img={homeServicesImage}
142+
order='last'
143+
link="Learn More"
144+
></OrderedImgText>
145+
</CustomSection>
146+
</Layout>
147+
<Layout>
148+
<Testemonials></Testemonials>
149+
</Layout>
149150
</>
150151
);
151152
};

examples/ecommerce-jewellery-store/src/pages/ShoppingCart.tsx

Lines changed: 0 additions & 11 deletions
This file was deleted.

0 commit comments

Comments
 (0)