From f5cb53e3c1e151bcf7b0c64d62bd5d62a2015c53 Mon Sep 17 00:00:00 2001 From: Caleb Hill Date: Mon, 18 Nov 2024 13:14:15 -0700 Subject: [PATCH 1/9] add favicons I was bothered by the 404 errors popping up in the console caused by a missing favicon --- web/apple-touch-icon.png | Bin 0 -> 35035 bytes web/favicon-16x16.png | Bin 0 -> 794 bytes web/favicon-32x32.png | Bin 0 -> 2218 bytes web/favicon.ico | Bin 0 -> 15406 bytes web/index.html | 4 +++- 5 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 web/apple-touch-icon.png create mode 100644 web/favicon-16x16.png create mode 100644 web/favicon-32x32.png create mode 100644 web/favicon.ico diff --git a/web/apple-touch-icon.png b/web/apple-touch-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..70aee55ff10c6b2108b581ee74c542c621c052d5 GIT binary patch literal 35035 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

-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 Hu0mjf2ARfP literal 0 HcmV?d00001 diff --git a/web/favicon-16x16.png b/web/favicon-16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..2cda934b327a262435375124644af3d42e3f1223 GIT binary patch literal 794 zcmV+#1LgdQP)e{C>0eWBycsIz|{gl(Iw;CK$+k0GpIV@BD&y!oPh%l!qCano9SeozCE znGd&Yf`MG-uuwylgawo$5>wFB=0ne?5M-*LxG)=Ms@5SlTLjTda+1oWd88O|lVMNI zaf69INYBYZbb-g~t{~p^g<-dgDBtUVn8u;=?F5E~xZR?UBHvY8T}A6{<>`sqUWz+04tV2UFc_t%(49ZO-3nNTqH%IR4*O!fZfnhE_WuV}5l^mttS zPRVdgmF63S#AJaj;sxc!9%@{5&2aX|%akys`wNiT`0R0swpjFpHSujsto^xE@y~+4 Y0dDkCLJAZRumAu607*qoM6N<$f@CLnx&QzG literal 0 HcmV?d00001 diff --git a/web/favicon-32x32.png b/web/favicon-32x32.png new file mode 100644 index 0000000000000000000000000000000000000000..03ae2bcceaa955b1857cd273418f1ae1889d206f GIT binary patch literal 2218 zcmV;b2vzrqP)oimA2v(*%LjY+(9P3b>q2oV} z1HufIsReCH15vTlL8qmq+9?%LXD9(uN}6OJNl3|Kvzy(!dmnz^Id=mBG6Byfdw0)0 z=lg!&@B4n=xhwF0499VV(a~BTxN~}^5DSa9V@ll4rna^g{}jL3;IY!1e0Fw$t@%H) zJhA8Wdf!1I8mwEfc}oD^er@l>g|j1%YlXq5g*keMfC)zfJeC7ncwu{@X9hCUEotqvW{IMwHzqN3-?pwN~3KbDQ1?nLH7K9Cq7H#~qZ5YQ+^kF#X zZTIVepVxc+%}u*@88>6(rT{V*e>bm?9sJ>6-fVAp_g@3v(L6=!6j2e@@W7%f+<#9s zJer1+rw8!P$v*V-7wEnNpGRQU%m^NSa9Zc|X;r_>*=74`=P%3N2*?cqjC8#GfG`H0 z(ag-(g>7gyG^8#S@YZ|%IMwzEa(Rm!3B=0O_De&wf>Po4I+#5pim%*XgHKJ<;rD=c z3Roi0Z+Y~c5q;{f#EeIVt_Cs&z;RkUnG41@J=V}>VPzJ>E(oe}2*+JcD{aSv3!Mh` zwX`GAZ@{!H6l@cq`RZ~nmOomLd*?;rWyl23CQy9kLB>$@h6XGV+2hfxcSmM4^vZdD z8$7x5(Llg?ULZY-+z@ISv;p*I5dzH;$Wfu4ZXd=QfA2*{cOHh}z%mQ$0mAD;$mc^% z%!{Rqsj7s89TZIl3#e^_%Y6c$Upu`+nQep*M< zw4e9n$k7>ceC$L&KJLw-NI*1?h3R!6d}(nl!XXdcyMzl}Srkn&PEKlwjjw)wG8WD& zLnNpXMq35KIE)OO#A%p)@u6SzKT)Xwyt?8jis^?muNU5mD1y;)+Tg>f57Kz^{T`(H zizGAV#X()I4-bD~D(26cfPjx7QjY1;-ZhHX-$~*kU2Wo?f+t1=AEfFefJF21BQQt4QDVxXiu%oa1+*u8@ClL`t(r73fG^)yhXr$@ z2nUH;jz;oJkYL$ zAhC`7sDU@$zKESix-l?Xz_PiQvH5d-w2yjDJtB){Z zKfXV|7aQgel5-aT&6@g@KkDl{A5jb(Uf(P-iElI4Y{#b8>7-zo9NSpw04U~3C2yWCWEY;U6DJ4FKLq;5B>GKjKv*5zMn#i$W z#)487NrpAQ);FeBx;3!wC6P%kR}{(8c8y4J$xs|Ohx}beNprzmH_ArN%1+0;Dw?nJ zdEEqCD2A%{>Kl7jy9}&*(HTiSd8NC!>0&U_8NHJaWt&byj+j0L^GRZ$P3FGjR~E1w zTstl&a!!3$;8}*XdqYi01t5NS?LLw1S@GXcxgPkx1V$C41VFXIO(>X;qkQjAe@Rr0PLYuGAx+D_l01J-%m#Yj=m65{;?|4>kQ%WRuS-6(|R#dK`1; zs)JjuqYeQHpget!0GLuCYHvvm9H<+$w8$i|J5GZi#c=g@eSODs5H*Fith+_}0@f31f9NVZ-&vx<&Kt>qO#SzU= zCnSZ?39sbHQqzcPU&T37kL}RwCms}EJkBz>;TT8X0?r@VG9i-dZ$e>ovuzp`T!b98 zOu+~pM)E0#m?4&|P(_=qPx)DBhTeKJ$2U#E|3Vx8^QM?HF!Z!j$TkYQFd<}g$-{_i z-SkJ#7WK*7k4EqOeM7^casNIX7X#M<`uO!{YJ-`}KMD+=Ul}TP#w~sF4*d@Ox8sTU sT3fdTpkyT8@>pyNFf48%;%fo?2R6DR-|~s;IRF3v07*qoM6N<$g2b8{P5=M^ literal 0 HcmV?d00001 diff --git a/web/favicon.ico b/web/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..ee45eaf39c6d1ed123601bcd391809fca45d9ce5 GIT binary patch literal 15406 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 literal 0 HcmV?d00001 diff --git a/web/index.html b/web/index.html index 790d463..be10c1e 100644 --- a/web/index.html +++ b/web/index.html @@ -3,7 +3,9 @@ - + + + From dc2f9e53d05dc94bc5ee4233f06c6e264a78c708 Mon Sep 17 00:00:00 2001 From: Caleb Hill Date: Mon, 18 Nov 2024 13:15:04 -0700 Subject: [PATCH 2/9] make rows look clickable just making the background change color and the mouse cursor change to the pointer icon --- web/src/app.css | 8 +++++++- web/src/components/Table.tsx | 2 +- web/src/index.css | 2 +- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/web/src/app.css b/web/src/app.css index 4a60b9d..17cb48a 100644 --- a/web/src/app.css +++ b/web/src/app.css @@ -63,6 +63,12 @@ header { justify-content: space-around; } +.clickableRow:hover td { + background-color: #fff4e6; /* Soft orange-beige background */ + transition: background-color 0.2s ease, border 0.2s ease; + cursor: pointer; +} + .inventoryPage { height: 100vh; } @@ -90,4 +96,4 @@ header { .modal-content img { max-width: 100%; height: auto; -} \ No newline at end of file +} diff --git a/web/src/components/Table.tsx b/web/src/components/Table.tsx index c5a6fad..0c1fefa 100644 --- a/web/src/components/Table.tsx +++ b/web/src/components/Table.tsx @@ -104,7 +104,7 @@ export const Table: React.FC = ({ items, onRowClick }) => { {table.getRowModel().rows.map(row => ( - onRowClick(items[row.index])}> + onRowClick(items[row.index])} className='clickableRow'> {row.getVisibleCells().map(cell => ( {flexRender(cell.column.columnDef.cell, cell.getContext())} diff --git a/web/src/index.css b/web/src/index.css index a1c9aa3..da92873 100644 --- a/web/src/index.css +++ b/web/src/index.css @@ -10,4 +10,4 @@ body { code { font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', monospace; -} \ No newline at end of file +} From 68c338112509a03837f353c64ed5bcb8b5bf56d0 Mon Sep 17 00:00:00 2001 From: Caleb Hill Date: Mon, 18 Nov 2024 13:15:19 -0700 Subject: [PATCH 3/9] make item modals close with Esc key --- web/src/components/ItemModal.tsx | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/web/src/components/ItemModal.tsx b/web/src/components/ItemModal.tsx index f74569a..22c9e05 100644 --- a/web/src/components/ItemModal.tsx +++ b/web/src/components/ItemModal.tsx @@ -1,4 +1,4 @@ -import React from 'react' +import React, { useEffect } from 'react' import { InventoryItem } from '../util/types' interface ItemModalProps { @@ -8,6 +8,23 @@ interface ItemModalProps { } export const ItemModal: React.FC = ({ item, isOpen, onClose }) => { + useEffect(() => { + // Function to close modal when you hit 'Esc' + const handleKeyDown = (event: KeyboardEvent): void => { + if (isOpen && event.key === 'Escape') { + onClose() // Call the onClose callback if Escape is pressed + } + } + + if (isOpen) { // Add event listener when the modal is open + document.addEventListener('keydown', handleKeyDown) + } + + return () => { // Clean up the event listener when the modal closes or unmounts + document.removeEventListener('keydown', handleKeyDown) + } + }, [isOpen, onClose]) + if (!isOpen || (item == null)) return null return ( From b5df350efa5f83e666107579c76d0c8aa33fc32d Mon Sep 17 00:00:00 2001 From: Caleb Hill Date: Mon, 18 Nov 2024 13:15:35 -0700 Subject: [PATCH 4/9] Make page indexes 1-based and inclusive --- web/src/components/Table.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/src/components/Table.tsx b/web/src/components/Table.tsx index 0c1fefa..b67ae14 100644 --- a/web/src/components/Table.tsx +++ b/web/src/components/Table.tsx @@ -118,7 +118,7 @@ export const Table: React.FC = ({ items, onRowClick }) => { -

Viewing {pageIndex * pageSize}-{Math.min((pageIndex + 1) * pageSize, items.length)} Out Of {items.length} Items
+
Viewing {1 + (pageIndex * pageSize)}-{Math.min((pageIndex + 1) * pageSize, items.length)} out of {items.length} items
From 18139929796b1eef018ec22e2faceecba5f5e48f Mon Sep 17 00:00:00 2001 From: Caleb Hill Date: Mon, 18 Nov 2024 13:31:31 -0700 Subject: [PATCH 5/9] make image id optional There is one of the snowboards (the 16th in the list) that doesn't have ids for its images which causes the backend query to fail. --- shared/src/model/image.model.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared/src/model/image.model.ts b/shared/src/model/image.model.ts index c6b1921..6c5c184 100644 --- a/shared/src/model/image.model.ts +++ b/shared/src/model/image.model.ts @@ -2,6 +2,6 @@ import { Static, Type } from '@fastify/type-provider-typebox' export const ImageObjSchema = Type.Object({ url: Type.String(), - id: Type.String() + id: Type.Optional(Type.String()) }) export type ImageObj = Static From 2115e1f3dbe0bc23044bbbb664e45a3d513d69f2 Mon Sep 17 00:00:00 2001 From: Caleb Hill Date: Mon, 18 Nov 2024 14:06:27 -0700 Subject: [PATCH 6/9] remove add route --- server/src/routes/add/root.ts | 29 ----------------------------- 1 file changed, 29 deletions(-) delete mode 100644 server/src/routes/add/root.ts diff --git a/server/src/routes/add/root.ts b/server/src/routes/add/root.ts deleted file mode 100644 index e63f7ef..0000000 --- a/server/src/routes/add/root.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { TypeBoxTypeProvider, FastifyPluginAsyncTypebox } from '@fastify/type-provider-typebox' -import { AddResponseSchema, AddRequestSchema } from 'shared' -import { Value } from '@sinclair/typebox/value' - -// maybe use a generic argument for FastifyPluginAsync if we use options with fastify instance -const add: FastifyPluginAsyncTypebox = async (fastifyApp): Promise => { - const fastify = fastifyApp.withTypeProvider() - - fastify.get('/', { - schema: { - querystring: AddRequestSchema, - response: { - 200: AddResponseSchema - } - } - }, async (request, reply) => { - // Example of implementing the route - // const { a, b } = request.query - // const response = { result: a + b } - - // Example of mocking a route with Typebox - const response = Value.Create(AddResponseSchema) - - // eslint-disable-next-line @typescript-eslint/no-floating-promises - reply.status(200).send(response) - }) -} - -export default add From cd992ab0d5272af020596d38f419e9a3b4c46075 Mon Sep 17 00:00:00 2001 From: Caleb Hill Date: Mon, 18 Nov 2024 14:06:57 -0700 Subject: [PATCH 7/9] add 400 error responses for view in /spec --- server/src/routes/get-product/root.ts | 1 + server/src/routes/products/root.ts | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/server/src/routes/get-product/root.ts b/server/src/routes/get-product/root.ts index 6b1fbcc..9c49fdf 100644 --- a/server/src/routes/get-product/root.ts +++ b/server/src/routes/get-product/root.ts @@ -14,6 +14,7 @@ const getProduct: FastifyPluginAsyncTypebox = async (fastifyApp, querystring: GetProductRequestSchema, response: { 200: GetProductResponseSchema, + 400: ErrorResSchema, 404: ErrorResSchema } } diff --git a/server/src/routes/products/root.ts b/server/src/routes/products/root.ts index e400f59..ec55cd4 100644 --- a/server/src/routes/products/root.ts +++ b/server/src/routes/products/root.ts @@ -5,6 +5,7 @@ import { } from 'shared' import { getProducts } from '../../shopify/product' import { ServerOptions } from '../../server' +import { ErrorResSchema } from '../../models/errors.model' // maybe use a generic argument for FastifyPluginAsync if we use options with fastify instance const getProduct: FastifyPluginAsyncTypebox = async (fastifyApp, { shopifyClient }): Promise => { @@ -14,7 +15,8 @@ const getProduct: FastifyPluginAsyncTypebox = async (fastifyApp, schema: { querystring: GetProductsRequestSchema, response: { - 200: GetProductsResponseSchema + 200: GetProductsResponseSchema, + 400: ErrorResSchema } } }, async (request, reply) => { From 41668c2a104136a2d685f7941f382f68a0e13a9d Mon Sep 17 00:00:00 2001 From: Caleb Hill Date: Mon, 18 Nov 2024 14:07:33 -0700 Subject: [PATCH 8/9] expand arbitrary api request size --- web/src/pages/InventoryPage.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/web/src/pages/InventoryPage.tsx b/web/src/pages/InventoryPage.tsx index 99e8380..8a9d40b 100644 --- a/web/src/pages/InventoryPage.tsx +++ b/web/src/pages/InventoryPage.tsx @@ -25,7 +25,10 @@ export const InventoryPage: React.FC = () => { if (client == null) { return } - const response = await getProducts(client, { pageSize: 15 }) + // This page size is kind of silly now since we're just doing fake client-side pagination, ultimately we should be + // doing server-side pagination instead where we fetch each page from the server + // but I don't really want to do the work to refactor the frontend to do that so it's fine + const response = await getProducts(client, { pageSize: 200 }) return (response?.result ?? []).map((product) => ({ productName: product.title, imageUrl: product.images?.nodes?.[0]?.url, From b536f717c455a048ce6f7ec5216116c0f4464598 Mon Sep 17 00:00:00 2001 From: Caleb Hill Date: Mon, 18 Nov 2024 14:07:39 -0700 Subject: [PATCH 9/9] make modal images not too big --- web/src/app.css | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/web/src/app.css b/web/src/app.css index 17cb48a..3b11ac8 100644 --- a/web/src/app.css +++ b/web/src/app.css @@ -94,6 +94,5 @@ header { } .modal-content img { - max-width: 100%; - height: auto; + max-width: 50%; }