added cart and store components

This commit is contained in:
Smigz 2024-10-13 11:41:36 -04:00
parent 556a7f8fe2
commit 81d70ec032
13 changed files with 254 additions and 54 deletions

View file

@ -1,15 +1,16 @@
import { useState } from "react";
import "./App.css";
import { Outlet, useParams } from "react-router-dom";
import Main from "./components/main";
import "./App.css";
import Navbar from "./components/navbar";
function App() {
const [count, setCount] = useState(0);
const { path } = useParams();
const [cartItems, setCartItems] = useState(0);
return (
<>
<Navbar />
<Main />
<Navbar cartItems={cartItems} />
{path === "cart" ? <Outlet /> : path === "store" ? <Outlet /> : <Main />}
</>
);
}

View file

@ -1,30 +1,44 @@
import PropTypes from "prop-types";
const Cart = (props) => {
return (
<section>
{props.cart ? (
<div>
<h2>Cart</h2>
{props.cart.map((item) =>
<CartItem item={item} qty={item.qty} />
)}
</div>
) : (<h2>Your cart is empty</h2>)}
</section>
)
return (
<>
<div>
{props.cart ? (
<div>
<h2>Cart</h2>
{props.cart.map((item) => (
<CartItem item={item} key={item.id} />
))}
</div>
) : (
<h2>Your cart is empty</h2>
)}
</div>
</>
);
};
function CartItem({ item }) {
const { name, price, img, qty } = item;
return (
<div>
<img src={img} alt={name} />
<h3>{name}</h3>
<p>Qty: {qty}</p>
<p>{price}</p>
<p>{price * qty}</p>
</div>
);
}
CartItem.propTypes = {
item: PropTypes.object,
};
function CartItem({item, qty}) {
const {name, price, img} = item;
Cart.propTypes = {
cart: PropTypes.array,
};
return (
<div>
<img src={img} alt={name} />
<h3>{name}</h3>
<p>Qty: {qty}</p>
<p>{price}</p>
<p>{price * qty}</p>
</div>
)
}
export default Cart;

View file

@ -0,0 +1,38 @@
import { useEffect, useState } from "react";
import ProductCollection from "./components/productCollection";
export default function Store(props) {
const { items, loading } = useFakeStoreAPI();
return (
<div>
<h1>Smig.Tech Coaching Store</h1>
<ProductCollection loading={loading} items={items} />
</div>
);
}
function useFakeStoreAPI() {
const [items, setItems] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
fetch("https://fakestoreapi.com/products?limit=5", { mode: "cors" })
.then((response) => {
if (response.status >= 400) {
return { error: "unable to fetch items" };
}
return response.json();
})
.then((response) => {
const arr = [];
response.forEach((item) => {
arr.push({ title: item.title, price: item.price, image: item.image });
});
setItems(arr);
})
.catch((error) => console.log(error))
.finally(() => setLoading(false));
}, []);
return { items, loading };
}

View file

@ -3,14 +3,20 @@ import styles from "./main.module.css";
export default function Main(props) {
return (
<main>
<div>
<h1 className={styles.mainHeading}>We help you skill up faster</h1>
<p>
Trying to pivot into tech? There&apos;s a lot to figure out. We can
help you navigate the path. Fast results and guaranteed growth.
</p>
<button>BOOK INTRO CALL</button>
</div>
<Default />
</main>
);
}
function Default() {
return (
<div>
<h1 className={styles.mainHeading}>We help you skill up faster</h1>
<p>
Trying to pivot into tech? There&apos;s a lot to figure out. We can help
you navigate the path. Fast results and guaranteed growth.
</p>
<button>BOOK INTRO CALL</button>
</div>
);
}

View file

@ -1,11 +1,13 @@
import styles from "./navbar.module.css";
import { Link } from "react-router-dom";
import PropTypes from "prop-types";
export default function Navbar(props) {
export default function Navbar({ cartItems }) {
return (
<nav className={styles.nav}>
<h1>Smig.Tech</h1>
<Nav />
<button>I&apos;m Ready</button>
{cartItems ? <h1>{cartItems}</h1> : <button>I&apos;m Ready</button>}
</nav>
);
}
@ -13,8 +15,16 @@ export default function Navbar(props) {
function Nav() {
return (
<ul className={styles.nav}>
<li>home</li>
<li>shop</li>
<li>
<Link to="/">home</Link>
</li>
<li>
<Link to="store">shop</Link>
</li>
</ul>
);
}
Navbar.propTypes = {
cartItems: PropTypes.number,
};

View file

@ -0,0 +1,19 @@
import Product from "./products";
import PropTypes from "prop-types";
export default function ProductCollection({ loading, items }) {
return (
<div>
{!loading
? items.map((item, index) => {
return <Product item={item} key={index} />;
})
: null}
</div>
);
}
ProductCollection.propTypes = {
loading: PropTypes.bool,
items: PropTypes.array,
};

View file

@ -0,0 +1,17 @@
import PropTypes from "prop-types";
import styles from "./products.module.css";
export default function Product({ item }) {
return (
<div className={styles.card}>
<img src={item.image} alt={item.title} className={styles.img} />
<p>{item.title}</p>
<p>${item.price}</p>
</div>
);
}
Product.propTypes = {
item: PropTypes.object,
};

View file

@ -0,0 +1,11 @@
.card {
display: flex;
flex-direction: column;
max-width: 350px;
justify-content: center;
align-items: center;
}
.img {
max-width: 250px;
}

View file

@ -0,0 +1,14 @@
import { Link } from "react-router-dom";
function ErrorPage() {
return (
<div>
<h1>Oh no, this route doesn't exist!</h1>
<Link to="/">
You can go back to the home page by clicking here, though!
</Link>
</div>
);
}
export default ErrorPage;

View file

@ -1,10 +1,13 @@
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import App from './App.jsx'
import './index.css'
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import "./index.css";
import { createBrowserRouter, RouterProvider } from "react-router-dom";
import routes from "./routes";
createRoot(document.getElementById('root')).render(
const router = createBrowserRouter(routes);
createRoot(document.getElementById("root")).render(
<StrictMode>
<App />
<RouterProvider router={router} />
</StrictMode>,
)
);

View file

@ -0,0 +1,25 @@
import App from "./App";
import Cart from "./Cart";
import Store from "./Store";
import ErrorPage from "./errorPage";
const routes = [
{
path: "/",
element: <App />,
errorElement: <ErrorPage />,
children: [
{
path: ":path",
element: <Store />,
index: true,
},
{
path: "store/:path",
element: <Cart />,
},
],
},
];
export default routes;