From d3dc135a85f666e926187a2979ef7ef141455afd Mon Sep 17 00:00:00 2001 From: hmcclew <122323895+hmcclew@users.noreply.github.com> Date: Wed, 11 Oct 2023 13:07:32 -0400 Subject: [PATCH 1/4] initial collection pages with mock types --- client/package-lock.json | 195 ++++++++++++++++++++--- client/package.json | 3 +- client/src/App.tsx | 2 + client/src/components/CollectionForm.tsx | 76 +++++++++ client/src/components/CollectionItem.tsx | 23 +++ client/src/components/GiftSelector.tsx | 0 client/src/pages/CollectionsPage.tsx | 138 ++++++++++++++++ client/src/pages/HomePage.tsx | 4 + client/vite.config.ts | 3 + 9 files changed, 419 insertions(+), 25 deletions(-) create mode 100644 client/src/components/CollectionForm.tsx create mode 100644 client/src/components/CollectionItem.tsx create mode 100644 client/src/components/GiftSelector.tsx create mode 100644 client/src/pages/CollectionsPage.tsx diff --git a/client/package-lock.json b/client/package-lock.json index 05a4fd6..d5318da 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -28,7 +28,7 @@ "postcss": "^8.4.29", "tailwindcss": "^3.3.3", "typescript": "^5.0.2", - "vite": "^4.4.5" + "vite": "^4.4.11" } }, "node_modules/@aashutoshrathi/word-wrap": { @@ -578,12 +578,14 @@ } }, "node_modules/@swc/core": { - "version": "1.3.84", + "version": "1.3.92", + "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.3.92.tgz", + "integrity": "sha512-vx0vUrf4YTEw59njOJ46Ha5i0cZTMYdRHQ7KXU29efN1MxcmJH2RajWLPlvQarOP1ab9iv9cApD7SMchDyx2vA==", "devOptional": true, "hasInstallScript": true, - "license": "Apache-2.0", "dependencies": { - "@swc/types": "^0.1.4" + "@swc/counter": "^0.1.1", + "@swc/types": "^0.1.5" }, "engines": { "node": ">=10" @@ -593,16 +595,16 @@ "url": "https://opencollective.com/swc" }, "optionalDependencies": { - "@swc/core-darwin-arm64": "1.3.84", - "@swc/core-darwin-x64": "1.3.84", - "@swc/core-linux-arm-gnueabihf": "1.3.84", - "@swc/core-linux-arm64-gnu": "1.3.84", - "@swc/core-linux-arm64-musl": "1.3.84", - "@swc/core-linux-x64-gnu": "1.3.84", - "@swc/core-linux-x64-musl": "1.3.84", - "@swc/core-win32-arm64-msvc": "1.3.84", - "@swc/core-win32-ia32-msvc": "1.3.84", - "@swc/core-win32-x64-msvc": "1.3.84" + "@swc/core-darwin-arm64": "1.3.92", + "@swc/core-darwin-x64": "1.3.92", + "@swc/core-linux-arm-gnueabihf": "1.3.92", + "@swc/core-linux-arm64-gnu": "1.3.92", + "@swc/core-linux-arm64-musl": "1.3.92", + "@swc/core-linux-x64-gnu": "1.3.92", + "@swc/core-linux-x64-musl": "1.3.92", + "@swc/core-win32-arm64-msvc": "1.3.92", + "@swc/core-win32-ia32-msvc": "1.3.92", + "@swc/core-win32-x64-msvc": "1.3.92" }, "peerDependencies": { "@swc/helpers": "^0.5.0" @@ -613,12 +615,148 @@ } } }, + "node_modules/@swc/core-darwin-arm64": { + "version": "1.3.92", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.3.92.tgz", + "integrity": "sha512-v7PqZUBtIF6Q5Cp48gqUiG8zQQnEICpnfNdoiY3xjQAglCGIQCjJIDjreZBoeZQZspB27lQN4eZ43CX18+2SnA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-darwin-x64": { + "version": "1.3.92", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.3.92.tgz", + "integrity": "sha512-Q3XIgQfXyxxxms3bPN+xGgvwk0TtG9l89IomApu+yTKzaIIlf051mS+lGngjnh9L0aUiCp6ICyjDLtutWP54fw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-arm-gnueabihf": { + "version": "1.3.92", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.3.92.tgz", + "integrity": "sha512-tnOCoCpNVXC+0FCfG84PBZJyLlz0Vfj9MQhyhCvlJz9hQmvpf8nTdKH7RHrOn8VfxtUBLdVi80dXgIFgbvl7qA==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-arm64-gnu": { + "version": "1.3.92", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.3.92.tgz", + "integrity": "sha512-lFfGhX32w8h1j74Iyz0Wv7JByXIwX11OE9UxG+oT7lG0RyXkF4zKyxP8EoxfLrDXse4Oop434p95e3UNC3IfCw==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-arm64-musl": { + "version": "1.3.92", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.3.92.tgz", + "integrity": "sha512-rOZtRcLj57MSAbiecMsqjzBcZDuaCZ8F6l6JDwGkQ7u1NYR57cqF0QDyU7RKS1Jq27Z/Vg21z5cwqoH5fLN+Sg==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-x64-gnu": { + "version": "1.3.92", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.3.92.tgz", + "integrity": "sha512-qptoMGnBL6v89x/Qpn+l1TH1Y0ed+v0qhNfAEVzZvCvzEMTFXphhlhYbDdpxbzRmCjH6GOGq7Y+xrWt9T1/ARg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-x64-musl": { + "version": "1.3.92", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.3.92.tgz", + "integrity": "sha512-g2KrJ43bZkCZHH4zsIV5ErojuV1OIpUHaEyW1gf7JWKaFBpWYVyubzFPvPkjcxHGLbMsEzO7w/NVfxtGMlFH/Q==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-win32-arm64-msvc": { + "version": "1.3.92", + "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.3.92.tgz", + "integrity": "sha512-3MCRGPAYDoQ8Yyd3WsCMc8eFSyKXY5kQLyg/R5zEqA0uthomo0m0F5/fxAJMZGaSdYkU1DgF73ctOWOf+Z/EzQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-win32-ia32-msvc": { + "version": "1.3.92", + "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.3.92.tgz", + "integrity": "sha512-zqTBKQhgfWm73SVGS8FKhFYDovyRl1f5dTX1IwSKynO0qHkRCqJwauFJv/yevkpJWsI2pFh03xsRs9HncTQKSA==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, "node_modules/@swc/core-win32-x64-msvc": { - "version": "1.3.84", + "version": "1.3.92", + "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.3.92.tgz", + "integrity": "sha512-41bE66ddr9o/Fi1FBh0sHdaKdENPTuDpv1IFHxSg0dJyM/jX8LbkjnpdInYXHBxhcLVAPraVRrNsC4SaoPw2Pg==", "cpu": [ "x64" ], - "license": "Apache-2.0 AND MIT", "optional": true, "os": [ "win32" @@ -627,10 +765,17 @@ "node": ">=10" } }, + "node_modules/@swc/counter": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.2.tgz", + "integrity": "sha512-9F4ys4C74eSTEUNndnER3VJ15oru2NumfQxS8geE+f3eB5xvfxpWyqE5XlVnxb/R14uoXi6SLbBwwiDSkv+XEw==", + "devOptional": true + }, "node_modules/@swc/types": { - "version": "0.1.4", - "devOptional": true, - "license": "Apache-2.0" + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.5.tgz", + "integrity": "sha512-myfUej5naTBWnqOCc/MdVOLVjXUXtIA+NpDrDBKJtLLg2shUjBu3cZmB/85RyitKc55+lUUyl7oRfLOvkr2hsw==", + "devOptional": true }, "node_modules/@tsconfig/node10": { "version": "1.0.9", @@ -888,11 +1033,12 @@ } }, "node_modules/@vitejs/plugin-react-swc": { - "version": "3.3.2", + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react-swc/-/plugin-react-swc-3.4.0.tgz", + "integrity": "sha512-m7UaA4Uvz82N/0EOVpZL4XsFIakRqrFKeSNxa1FBLSXGvWrWRBwmZb4qxk+ZIVAZcW3c3dn5YosomDgx62XWcQ==", "dev": true, - "license": "MIT", "dependencies": { - "@swc/core": "^1.3.61" + "@swc/core": "^1.3.85" }, "peerDependencies": { "vite": "^4" @@ -3143,9 +3289,10 @@ "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==" }, "node_modules/vite": { - "version": "4.4.9", + "version": "4.4.11", + "resolved": "https://registry.npmjs.org/vite/-/vite-4.4.11.tgz", + "integrity": "sha512-ksNZJlkcU9b0lBwAGZGGaZHCMqHsc8OpgtoYhsQ4/I2v5cnpmmmqe5pM4nv/4Hn6G/2GhTdj0DhZh2e+Er1q5A==", "dev": true, - "license": "MIT", "dependencies": { "esbuild": "^0.18.10", "postcss": "^8.4.27", diff --git a/client/package.json b/client/package.json index 0bc8b2a..a580da2 100644 --- a/client/package.json +++ b/client/package.json @@ -5,6 +5,7 @@ "type": "module", "scripts": { "dev": "vite", + "start": "vite", "build": "tsc && vite build", "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0", "preview": "vite preview" @@ -30,6 +31,6 @@ "postcss": "^8.4.29", "tailwindcss": "^3.3.3", "typescript": "^5.0.2", - "vite": "^4.4.5" + "vite": "^4.4.11" } } diff --git a/client/src/App.tsx b/client/src/App.tsx index b1f5666..1aa2f94 100644 --- a/client/src/App.tsx +++ b/client/src/App.tsx @@ -2,6 +2,7 @@ import { BrowserRouter as Router, Route, Routes } from "react-router-dom"; import HomePage from "./pages/HomePage"; import RequestsPage from "./pages/RequestsPage"; +import CollectionPage from './pages/CollectionsPage'; function App() { return ( @@ -9,6 +10,7 @@ function App() { } /> } /> + } /> ); diff --git a/client/src/components/CollectionForm.tsx b/client/src/components/CollectionForm.tsx new file mode 100644 index 0000000..a3207cc --- /dev/null +++ b/client/src/components/CollectionForm.tsx @@ -0,0 +1,76 @@ +import React, { useState, ChangeEvent, FormEvent } from 'react'; + +type Collection = { + id: number; + name: string; + gifts: string[]; +}; + +type EditFormProps = { + collection: Collection; + onSave: (collection: Collection) => void; + onClose: () => void; +}; + +function CollectionForm({ collection, onSave, onClose }: EditFormProps) { + const [editedName, setEditedName] = useState(collection.name); + const [editedGifts, setEditedGifts] = useState(collection.gifts.join(', ')); + + const handleNameChange = (e: ChangeEvent) => { + setEditedName(e.target.value); + }; + + const handleGiftsChange = (e: ChangeEvent) => { + setEditedGifts(e.target.value); + }; + + const handleSubmit = (e: FormEvent) => { + e.preventDefault(); + onSave({ + id: collection.id, + name: editedName, + gifts: editedGifts.split(',').map((gift) => gift.trim()), + }); + onClose(); + }; + + + return ( + + + + Name: + + + + Gifts: + + + + Save + + + Cancel + + + + ); +} + +export default CollectionForm; diff --git a/client/src/components/CollectionItem.tsx b/client/src/components/CollectionItem.tsx new file mode 100644 index 0000000..fd38114 --- /dev/null +++ b/client/src/components/CollectionItem.tsx @@ -0,0 +1,23 @@ +type CollectionItemProps = { + name: string; + gifts: string[]; + }; + + function CollectionItem({ name, gifts }: CollectionItemProps) { + return ( + + {name} + + {gifts.map((gift, index) => ( + {gift} + ))} + + + ); + } + + export default CollectionItem; + + + + diff --git a/client/src/components/GiftSelector.tsx b/client/src/components/GiftSelector.tsx new file mode 100644 index 0000000..e69de29 diff --git a/client/src/pages/CollectionsPage.tsx b/client/src/pages/CollectionsPage.tsx new file mode 100644 index 0000000..2cc7dc4 --- /dev/null +++ b/client/src/pages/CollectionsPage.tsx @@ -0,0 +1,138 @@ +import { useState } from 'react'; +import CollectionItem from '../components/CollectionItem'; +import EditForm from '../components/CollectionForm'; + +const CollectionsPage = () => { + const [collections, setCollections] = useState([ + { + id: 1, + name: 'Birthday Gifts', + gifts: ['Toy car', 'Art supplies', 'Book', 'Candy'], + }, + { + id: 2, + name: 'Christmas Gifts', + gifts: ['Sweater', 'Toys', 'Cookies'], + }, + { + id: 3, + name: 'Birthday Gifts', + gifts: ['Toy car', 'Art supplies', 'Book', 'Candy'], + }, + { + id: 4, + name: 'Christmas Gifts', + gifts: ['Sweater', 'Toys', 'Cookies'], + }, + { + id: 5, + name: 'Birthday Gifts', + gifts: ['Toy car', 'Art supplies', 'Book', 'Candy'], + }, + { + id: 6, + name: 'Christmas Gifts', + gifts: ['Sweater', 'Toys', 'Cookies'], + }, + { + id: 7, + name: 'Birthday Gifts', + gifts: ['Toy car', 'Art supplies', 'Book', 'Candy'], + }, + { + id: 8, + name: 'Christmas Gifts', + gifts: ['Sweater', 'Toys', 'Cookies'], + }, + { + id: 9, + name: 'Birthday Gifts', + gifts: ['Toy car', 'Art supplies', 'Book', 'Candy'], + }, + { + id: 10, + name: 'Christmas Gifts', + gifts: ['Sweater', 'Toys', 'Cookies'], + }, + { + id: 11, + name: 'Birthday Gifts', + gifts: ['Toy car', 'Art supplies', 'Book', 'Candy'], + }, + { + id: 12, + name: 'Christmas Gifts', + gifts: ['Sweater', 'Toys', 'Cookies'], + }, + { + id: 13, + name: 'Birthday Gifts', + gifts: ['Toy car', 'Art supplies', 'Book', 'Candy'], + }, + { + id: 14, + name: 'Christmas Gifts', + gifts: ['Sweater', 'Toys', 'Cookies'], + }, + + ]); + + const [showEditForm, setShowEditForm] = useState(false); + const [editCollectionId, setEditCollectionId] = useState(null); + + const handleEditCollection = (collectionId) => { + setEditCollectionId(collectionId); + setShowEditForm(true); + }; + + const handleSaveCollection = (updatedCollection) => { + setCollections((prevCollections) => + prevCollections.map((collection) => + collection.id === updatedCollection.id ? updatedCollection : collection + ) + ); + setShowEditForm(false); + }; + + const handleCloseEditForm = () => { + setEditCollectionId(null); + setShowEditForm(false); + }; + + const handleDeleteCollection = (collectionId) => { + setCollections((prevCollections) => prevCollections.filter((collection) => collection.id !== collectionId)); + }; + + return ( + + + + {collections.map((collection) => ( + + + + handleEditCollection(collection.id)} className="m-2"> + Edit + + handleDeleteCollection(collection.id)} className="m-2 text-red-500"> + Delete + + + + ))} + + + {showEditForm && ( + + c.id === editCollectionId)} + onSave={handleSaveCollection} + onClose={handleCloseEditForm} + /> + + )} + + ); +}; + +export default CollectionsPage; diff --git a/client/src/pages/HomePage.tsx b/client/src/pages/HomePage.tsx index b57d552..915c1c5 100644 --- a/client/src/pages/HomePage.tsx +++ b/client/src/pages/HomePage.tsx @@ -1,9 +1,13 @@ const HomePage = () => { + + return ( Caits Curates + + ); } diff --git a/client/vite.config.ts b/client/vite.config.ts index e7d4c74..ec1ff02 100644 --- a/client/vite.config.ts +++ b/client/vite.config.ts @@ -5,6 +5,9 @@ import react from '@vitejs/plugin-react-swc' export default defineConfig({ plugins: [react()], server : { + hmr: { + overlay: false, + }, proxy : { '/api': { target: 'http://localhost:8080', From bd3772d3cca3b91bf52bf247b07178e1768f63f2 Mon Sep 17 00:00:00 2001 From: hmcclew <122323895+hmcclew@users.noreply.github.com> Date: Thu, 12 Oct 2023 10:49:06 -0400 Subject: [PATCH 2/4] completed ticket using mocked tsx types --- client/src/components/CollectionForm.tsx | 42 ++++++++++++++------ client/src/pages/CollectionsPage.tsx | 50 ++++++++++++++++++------ 2 files changed, 69 insertions(+), 23 deletions(-) diff --git a/client/src/components/CollectionForm.tsx b/client/src/components/CollectionForm.tsx index a3207cc..e432286 100644 --- a/client/src/components/CollectionForm.tsx +++ b/client/src/components/CollectionForm.tsx @@ -12,16 +12,24 @@ type EditFormProps = { onClose: () => void; }; +const predefinedGifts = ["Gift 1", "Gift 2", "Gift 3", "Gift 4", "Gift 5"]; + function CollectionForm({ collection, onSave, onClose }: EditFormProps) { const [editedName, setEditedName] = useState(collection.name); - const [editedGifts, setEditedGifts] = useState(collection.gifts.join(', ')); + const [editedGifts, setEditedGifts] = useState(collection.gifts); const handleNameChange = (e: ChangeEvent) => { setEditedName(e.target.value); }; - const handleGiftsChange = (e: ChangeEvent) => { - setEditedGifts(e.target.value); + const handleGiftsChange = (e: ChangeEvent) => { + const selectedOptions = Array.from(e.target.options); + const selectedGifts = selectedOptions + .filter((option) => option.selected) + .map((option) => option.value); + + // Here, we concatenate the selected gifts with the existing gifts + setEditedGifts([...editedGifts, ...selectedGifts]); }; const handleSubmit = (e: FormEvent) => { @@ -29,17 +37,18 @@ function CollectionForm({ collection, onSave, onClose }: EditFormProps) { onSave({ id: collection.id, name: editedName, - gifts: editedGifts.split(',').map((gift) => gift.trim()), + gifts: editedGifts, }); onClose(); }; - return ( - Name: + + Name: + - Gifts: - + Select a Gift to Add: + + + > + {predefinedGifts.map((gift) => ( + + {gift} + + ))} + - + Save { const [collections, setCollections] = useState([ { @@ -77,15 +83,28 @@ const CollectionsPage = () => { ]); - const [showEditForm, setShowEditForm] = useState(false); - const [editCollectionId, setEditCollectionId] = useState(null); + const handleCreateCollection = () => { + const newCollection: Collection = { + id: Date.now(), + name: 'New Collection', + gifts: [], + }; - const handleEditCollection = (collectionId) => { + // Add the new collection to the state + setCollections((prevCollections) => [...prevCollections, newCollection]); + setEditCollectionId(newCollection.id); + setShowEditForm(true); + }; + + const [showEditForm, setShowEditForm] = useState(false); + const [editCollectionId, setEditCollectionId] = useState(null); + + const handleEditCollection = (collectionId: number) => { setEditCollectionId(collectionId); setShowEditForm(true); }; - const handleSaveCollection = (updatedCollection) => { + const handleSaveCollection = (updatedCollection: Collection) => { setCollections((prevCollections) => prevCollections.map((collection) => collection.id === updatedCollection.id ? updatedCollection : collection @@ -99,12 +118,12 @@ const CollectionsPage = () => { setShowEditForm(false); }; - const handleDeleteCollection = (collectionId) => { + const handleDeleteCollection = (collectionId: number) => { setCollections((prevCollections) => prevCollections.filter((collection) => collection.id !== collectionId)); }; return ( - + {collections.map((collection) => ( @@ -124,15 +143,22 @@ const CollectionsPage = () => { {showEditForm && ( - c.id === editCollectionId)} - onSave={handleSaveCollection} - onClose={handleCloseEditForm} - /> + + c.id === editCollectionId)!} + onSave={handleSaveCollection} + onClose={handleCloseEditForm} + /> + )} + + + Create New Collection + + ); }; -export default CollectionsPage; +export default CollectionsPage; \ No newline at end of file From f92656c68ae36292c4eff493d251d1568f7004fb Mon Sep 17 00:00:00 2001 From: hmcclew <122323895+hmcclew@users.noreply.github.com> Date: Thu, 12 Oct 2023 14:29:41 -0400 Subject: [PATCH 3/4] delete unnecessary files --- client/src/components/GiftSelector.tsx | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 client/src/components/GiftSelector.tsx diff --git a/client/src/components/GiftSelector.tsx b/client/src/components/GiftSelector.tsx deleted file mode 100644 index e69de29..0000000 From 9fc850708ced8af628f5e8679d84b2c1ac775297 Mon Sep 17 00:00:00 2001 From: hmcclew <122323895+hmcclew@users.noreply.github.com> Date: Tue, 17 Oct 2023 17:40:16 -0400 Subject: [PATCH 4/4] updated to use mock gift type --- client/src/components/CollectionForm.tsx | 60 +++++++++++++++-- client/src/components/CollectionItem.tsx | 45 ++++++++----- client/src/pages/CollectionsPage.tsx | 85 ++++++++++++++++++------ 3 files changed, 146 insertions(+), 44 deletions(-) diff --git a/client/src/components/CollectionForm.tsx b/client/src/components/CollectionForm.tsx index e432286..901822f 100644 --- a/client/src/components/CollectionForm.tsx +++ b/client/src/components/CollectionForm.tsx @@ -1,9 +1,15 @@ import React, { useState, ChangeEvent, FormEvent } from 'react'; +type Gift = { + name: string; + description: string; + price: number; +}; + type Collection = { id: number; name: string; - gifts: string[]; + gifts: Gift[]; }; type EditFormProps = { @@ -12,7 +18,43 @@ type EditFormProps = { onClose: () => void; }; -const predefinedGifts = ["Gift 1", "Gift 2", "Gift 3", "Gift 4", "Gift 5"]; +const predefinedGifts: Gift[] = [ + { + name: "Gift 1", + description: "Description of Gift 1", + price: 10, + }, + { + name: "Gift 2", + description: "Description of Gift 2", + price: 20, + }, + { + name: "Gift 3", + description: "Description of Gift 3", + price: 30, + }, + { + name: "Gift 4", + description: "Description of Gift 4", + price: 40, + }, + { + name: "Gift 5", + description: "Description of Gift 5", + price: 50, + }, + { + name: "Gift 10", + description: "Description of Gift 1", + price: 10, + }, + { + name: "Gift 11", + description: "Description of Gift 2", + price: 20, + }, +]; function CollectionForm({ collection, onSave, onClose }: EditFormProps) { const [editedName, setEditedName] = useState(collection.name); @@ -26,7 +68,11 @@ function CollectionForm({ collection, onSave, onClose }: EditFormProps) { const selectedOptions = Array.from(e.target.options); const selectedGifts = selectedOptions .filter((option) => option.selected) - .map((option) => option.value); + .map((option) => ({ + name: option.value, + description: "", + price: 0, + })); // Here, we concatenate the selected gifts with the existing gifts setEditedGifts([...editedGifts, ...selectedGifts]); @@ -65,12 +111,12 @@ function CollectionForm({ collection, onSave, onClose }: EditFormProps) { id="gifts" className="border border-blue-500 rounded-md w-64 p-2 mx-auto" multiple - value={editedGifts} + value={editedGifts.map((gift) => gift.name)} onChange={handleGiftsChange} > - {predefinedGifts.map((gift) => ( - - {gift} + {predefinedGifts.map((gift, index) => ( + + {gift.name} ))} diff --git a/client/src/components/CollectionItem.tsx b/client/src/components/CollectionItem.tsx index fd38114..a49369c 100644 --- a/client/src/components/CollectionItem.tsx +++ b/client/src/components/CollectionItem.tsx @@ -1,22 +1,31 @@ +type Gift = { + name: string; + description: string; + price: number; +}; + type CollectionItemProps = { - name: string; - gifts: string[]; - }; - - function CollectionItem({ name, gifts }: CollectionItemProps) { - return ( - - {name} - - {gifts.map((gift, index) => ( - {gift} - ))} - - - ); - } - - export default CollectionItem; + name: string; + gifts: Gift[]; +}; + +function CollectionItem({ name, gifts }: CollectionItemProps) { + return ( + + {name} + + {gifts.map((gift, index) => ( + + {gift.name} + + ))} + + + ); +} + +export default CollectionItem; + diff --git a/client/src/pages/CollectionsPage.tsx b/client/src/pages/CollectionsPage.tsx index fb5e526..0d55fdc 100644 --- a/client/src/pages/CollectionsPage.tsx +++ b/client/src/pages/CollectionsPage.tsx @@ -2,83 +2,130 @@ import { useState } from 'react'; import CollectionItem from '../components/CollectionItem'; import EditForm from '../components/CollectionForm'; +type Gift = { + name: string; + description: string; + price: number; +}; + type Collection = { - id: number; - name: string; - gifts: string[]; - }; + id: number; + name: string; + gifts: Gift[]; +}; + +const predefinedGifts: Gift[] = [ + { + name: "Gift 1", + description: "Description of Gift 1", + price: 10, + }, + { + name: "Gift 2", + description: "Description of Gift 2", + price: 20, + }, + { + name: "Gift 3", + description: "Description of Gift 3", + price: 30, + }, + { + name: "Gift 4", + description: "Description of Gift 4", + price: 40, + }, + { + name: "Gift 5", + description: "Description of Gift 5", + price: 50, + }, +]; + +const predefinedGifts2: Gift[] = [ + { + name: "Gift 10", + description: "Description of Gift 1", + price: 10, + }, + { + name: "Gift 11", + description: "Description of Gift 2", + price: 20, + }, +]; const CollectionsPage = () => { const [collections, setCollections] = useState([ { id: 1, name: 'Birthday Gifts', - gifts: ['Toy car', 'Art supplies', 'Book', 'Candy'], + gifts: [], }, { id: 2, name: 'Christmas Gifts', - gifts: ['Sweater', 'Toys', 'Cookies'], + gifts: predefinedGifts, }, { id: 3, name: 'Birthday Gifts', - gifts: ['Toy car', 'Art supplies', 'Book', 'Candy'], + gifts: predefinedGifts2, }, { id: 4, name: 'Christmas Gifts', - gifts: ['Sweater', 'Toys', 'Cookies'], + gifts: predefinedGifts, }, { id: 5, name: 'Birthday Gifts', - gifts: ['Toy car', 'Art supplies', 'Book', 'Candy'], + gifts: predefinedGifts, }, { id: 6, name: 'Christmas Gifts', - gifts: ['Sweater', 'Toys', 'Cookies'], + gifts: predefinedGifts, }, { id: 7, name: 'Birthday Gifts', - gifts: ['Toy car', 'Art supplies', 'Book', 'Candy'], + gifts: predefinedGifts, }, { id: 8, name: 'Christmas Gifts', - gifts: ['Sweater', 'Toys', 'Cookies'], + gifts: predefinedGifts, }, { id: 9, name: 'Birthday Gifts', - gifts: ['Toy car', 'Art supplies', 'Book', 'Candy'], + gifts: predefinedGifts, }, { id: 10, name: 'Christmas Gifts', - gifts: ['Sweater', 'Toys', 'Cookies'], + gifts: predefinedGifts, }, { id: 11, name: 'Birthday Gifts', - gifts: ['Toy car', 'Art supplies', 'Book', 'Candy'], + gifts: predefinedGifts }, { id: 12, name: 'Christmas Gifts', - gifts: ['Sweater', 'Toys', 'Cookies'], + gifts: predefinedGifts }, { id: 13, name: 'Birthday Gifts', - gifts: ['Toy car', 'Art supplies', 'Book', 'Candy'], + gifts: predefinedGifts, }, { id: 14, name: 'Christmas Gifts', - gifts: ['Sweater', 'Toys', 'Cookies'], + gifts: predefinedGifts, }, ]); @@ -124,7 +171,7 @@ const CollectionsPage = () => { return ( - + {collections.map((collection) => (
Caits Curates