Skip to content
This repository has been archived by the owner on Dec 16, 2024. It is now read-only.

Commit

Permalink
feat: add basic product list and page (#7)
Browse files Browse the repository at this point in the history
  • Loading branch information
wesbillman authored Nov 7, 2023
1 parent db32134 commit b1beace
Show file tree
Hide file tree
Showing 7 changed files with 188 additions and 231 deletions.
299 changes: 74 additions & 225 deletions frontend/web/package-lock.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions frontend/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"test:watch": "jest ./src --watch --verbose"
},
"dependencies": {
"@tailwindcss/aspect-ratio": "^0.4.2",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^6.18.0"
Expand Down
2 changes: 2 additions & 0 deletions frontend/web/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import { Route, Routes } from 'react-router-dom'
import { Layout } from './layout/Layout'
import { ProductsPage } from './features/products/ProductsPage'
import { ProductPage } from './features/products/ProductPage'

export const App = () => {
return (
<Routes>
<Route path='/' element={<Layout />}>
<Route path='/' element={<ProductsPage />} />
<Route path='products' element={<ProductsPage />} />
<Route path='products/:productId' element={<ProductPage />} />
</Route>
</Routes>
)
Expand Down
76 changes: 76 additions & 0 deletions frontend/web/src/features/products/ProductPage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import { useEffect, useState } from 'react'
import { Product, ProductcatalogClient } from '../../api/productcatalog'
import { useParams } from 'react-router-dom'
import { formatMoney } from '../../utils/money.utils'

export const ProductPage = () => {
const { productId } = useParams()
const [product, setProduct] = useState<Product | undefined>()

useEffect(() => {
const productsClient = new ProductcatalogClient('http://localhost:8892/ingress')
productsClient.list({}).then((response) => {
setProduct(response.products.find((product) => product.id.toLowerCase() === productId?.toLowerCase()))
})
}, [])

return (
<div className='bg-white'>
<div className='pb-16 pt-6 sm:pb-24'>
<div className='mx-auto mt-8 max-w-2xl px-4 sm:px-6 lg:max-w-7xl lg:px-8'>
<div className='lg:grid lg:auto-rows-min lg:grid-cols-12 lg:gap-x-8'>
<div className='lg:col-span-5 lg:col-start-8'>
<div className='flex justify-between'>
<h1 className='text-xl font-medium text-gray-900'>{product?.name}</h1>
{product?.priceUSD && (
<p className='text-xl font-medium text-gray-900'>{formatMoney(product.priceUSD)}</p>
)}
</div>
<div className='mt-4'>
{product?.categories.map((category) => (
<span
key={category}
className='inline-flex items-center rounded-md bg-gray-100 px-2 py-1 text-xs font-medium text-gray-600 mr-2'
>
{category}
</span>
))}
</div>

<div className='mt-10'>
<h2 className='text-sm font-medium text-gray-900'>Description</h2>

<div
className='prose prose-sm mt-4 text-gray-500'
dangerouslySetInnerHTML={{ __html: product?.description ?? '' }}
/>
</div>

<div className='mt-8 lg:col-span-5'>
<form>
<button
type='submit'
className='mt-8 flex w-full items-center justify-center rounded-md border border-transparent bg-indigo-600 px-8 py-3 text-base font-medium text-white hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2'
>
Add to cart
</button>
</form>
</div>
</div>

<div className='mt-8 lg:col-span-7 lg:col-start-1 lg:row-span-3 lg:row-start-1 lg:mt-0'>
<div className='grid grid-cols-1 lg:grid-cols-2 lg:grid-rows-3 lg:gap-8'>
<img
key={product?.id}
src={product?.picture}
alt={product?.name}
className='lg:col-span-2 lg:row-span-2 rounded-lg'
/>
</div>
</div>
</div>
</div>
</div>
</div>
)
}
32 changes: 27 additions & 5 deletions frontend/web/src/features/products/ProductsPage.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { useEffect, useState } from 'react'
import { Product, ProductcatalogClient } from '../../api/productcatalog'
import { formatMoney } from '../../utils/money.utils'
import { Link } from 'react-router-dom'

export const ProductsPage = () => {
const [products, setProducts] = useState<Product[]>([])
Expand All @@ -10,13 +12,33 @@ export const ProductsPage = () => {
}, [])

return (
<div className='p-4'>
<h1 className='text-3xl font-bold underline'>Products</h1>
<ul className='py-2'>
<div className='mx-auto max-w-2xl px-4 py-16 sm:px-6 lg:max-w-7xl lg:px-8'>
<h2 className='text-2xl font-bold tracking-tight text-gray-900'>Products</h2>
<div className='mt-6 grid grid-cols-1 gap-x-6 gap-y-10 sm:grid-cols-2 lg:grid-cols-4 xl:gap-x-8'>
{products.map((product) => (
<li key={product.id}>{product.name}</li>
<Link to={`/products/${product.id.toLowerCase()}`} key={product.id}>
<div className='group relative'>
<div className='aspect-h-1 aspect-w-1 w-full overflow-hidden rounded-md bg-gray-200 lg:aspect-none group-hover:opacity-75 lg:h-80'>
<img
src={product.picture}
alt={product.description}
className='h-full w-full object-cover object-center lg:h-full lg:w-full'
/>
</div>
<div className='mt-4 flex justify-between'>
<div>
<h3 className='text-sm text-gray-700'>
<span aria-hidden='true' className='absolute inset-0'></span>
{product.name}
</h3>
<p className='mt-1 text-sm text-gray-500'>{product.categories.join(', ')}</p>
</div>
<p className='text-sm font-medium text-gray-900'>{formatMoney(product.priceUSD)}</p>
</div>
</div>
</Link>
))}
</ul>
</div>
</div>
)
}
7 changes: 7 additions & 0 deletions frontend/web/src/utils/money.utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { Money } from '../api/productcatalog'

export const formatMoney = (money: Money): string => {
const fractionalAmount = money.nanos / 1e9
const totalAmount = money.units + fractionalAmount
return `$${totalAmount.toFixed(2)}`
}
2 changes: 1 addition & 1 deletion frontend/web/tailwind.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@ export default {
},
},
},
plugins: [],
plugins: [require('@tailwindcss/aspect-ratio'),],
}

0 comments on commit b1beace

Please sign in to comment.