Skip to content

Commit

Permalink
added product list page (#14)
Browse files Browse the repository at this point in the history
* added product list page

* updated router and product list and product page
  • Loading branch information
benhalverson authored Oct 30, 2024
1 parent 2c43d52 commit e7796c3
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 33 deletions.
13 changes: 8 additions & 5 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,14 @@ function App() {
<>

<ColorProvider>
<Routes>
<Route path="/" element={<Layout />} />
<Route index element={<ProductPage />} />
<Route path="list" element={<ProductList />} />
</Routes>
<Routes>
{/* Set ProductList as the default page */}
<Route path="/" element={<Layout />}>
<Route index element={<ProductList />} />
{/* Route to ProductPage with a dynamic product ID */}
<Route path="product/:id" element={<ProductPage />} />
</Route>
</Routes>
</ColorProvider>

</>
Expand Down
41 changes: 27 additions & 14 deletions src/pages/Product.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,34 @@
/* eslint-disable react-hooks/exhaustive-deps */
import { lazy, Suspense, useState } from "react";
import { lazy, Suspense, useState, useEffect } from "react";
import { useParams } from "react-router-dom";
import { ShoppingBagIcon, UserIcon } from "@heroicons/react/24/outline";
import ColorPicker from "../components/ColorPicker";
import FilamentDropdown from '../components/FilamentDropdown';
import FilamentDropdown from "../components/FilamentDropdown";

const PreviewComponent = lazy(() => import("../components/PreviewComponent"));

const product = {
name: "RC Wheels",
price: "$35",
description: `
<p>This is a 12mm RC buggy wheel that will fit any modern buggy for 1/10 scale racing.</p>
`,
};

export default function ProductPage() {
const [selectedFilament, setSelectedFilament] = useState<string>("PLA");
const { id } = useParams<{ id: string }>();
const [product, setProduct] = useState<any | null>(null);
const [selectedFilament, setSelectedFilament] = useState<string>("PLA");

// Fetch product data based on ID
useEffect(() => {
const fetchProduct = async () => {
try {
const response = await fetch(`https://3dprinter-web-api.benhalverson.workers.dev/product/${id}`);
const data = await response.json();
setProduct(data);
console.log('data', data);
} catch (error) {
console.error("Error fetching product:", error);
}
};

if (id) fetchProduct();
}, [id]);

if (!product) return <div>Loading product...</div>;

return (
<div className="bg-white">
Expand Down Expand Up @@ -79,8 +92,9 @@ export default function ProductPage() {

<div className="grid grid-cols-1 lg:grid-cols-2 lg:grid-rows-3 lg:gap-8">
<Suspense fallback={<div data-id="loading">Loading...</div>}>

<PreviewComponent
url="https://pub-0ec69c7d5c064de8b57f5d594f07bc02.r2.dev/pyramidv10.stl"
url={product.stl} // Use the STL file URL from the API response
onExceedsLimit={() => false}
onError={() => (
<div>
Expand All @@ -100,8 +114,7 @@ export default function ProductPage() {
</div>
<div>
<h2 className="text-sm font-medium text-gray-900">Color</h2>

<ColorPicker filamentType={selectedFilament}/>
<ColorPicker filamentType={selectedFilament} />
</div>

<button
Expand Down
52 changes: 38 additions & 14 deletions src/pages/ProductList.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
/* eslint-disable react-hooks/exhaustive-deps */
import { useEffect, useState } from "react";
import { Link } from 'react-router-dom';
// import { ProductResponse } from '../interfaces';

const BASE_URL = "https://3dprinter-web-api.benhalverson.workers.dev/list";
const BASE_URL = "https://3dprinter-web-api.benhalverson.workers.dev/products";
// const BASE_URL = "http://localhost:8787/products";

function ProductList() {
Expand All @@ -24,23 +25,46 @@ function ProductList() {
getData();
}, []);
return (
<ul>
{products.map((product, i) => (
<li key={i}>{product.name}</li>
))}
</ul>
<div className='bg-white'>
<div className='container mx-auto px-4 py-8'>
<h1 className='text-3xl font-semibold'>Products</h1>
<div className='grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4 mt-8'>
{products.map((product) => (
<div key={product.id} className='bg-white rounded-lg shadow-md'>
<img
src={product.image}
alt={product.name}
className='w-full h-48 object-cover object-center rounded-t-lg'
/>
<div className='p-4'>
<h2 className='text-xl font-semibold'>{product.name}</h2>
<p className='text-gray-500 mt-2'>{product.description}</p>
<p className='text-gray-500 mt-2'>{product.price}</p>
<Link
to={`/product/${product.id}`}
className='block bg-blue-500 hover:bg-blue-400 text-white font-semibold text-center rounded-lg px-4 py-2 mt-4'
>
View Product
</Link>
</div>
</div>
))}
</div>
</div>
</div>
);
}

export default ProductList;


interface ProductResponse {
name: string;
id: string;
stl: string;
description: string;
image: string;
price: number;
export interface ProductResponse {
id: number;
name: string;
description: string;
image: string;
stl: string;
price: number;
filamentType: string;
}
color: string;
}

0 comments on commit e7796c3

Please sign in to comment.