From 85fe32c2f53bf20cf80c889e4ff806f82cccf098 Mon Sep 17 00:00:00 2001 From: Falak Zahra Date: Thu, 22 Aug 2024 17:16:18 -0600 Subject: [PATCH 1/5] Add new list and render it on Home page --- src/App.jsx | 9 ++++++++- src/views/Home.jsx | 27 +++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/src/App.jsx b/src/App.jsx index f5e6008..f98b2f3 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -47,7 +47,14 @@ export function App() { }> } + element={ + + } /> } /> } /> diff --git a/src/views/Home.jsx b/src/views/Home.jsx index b86dadf..fc9de05 100644 --- a/src/views/Home.jsx +++ b/src/views/Home.jsx @@ -1,8 +1,26 @@ import './Home.css'; import { SingleList } from '../components'; +import { useState } from 'react'; +import { createList, useAuth } from '../api'; export function Home({ data, setListPath }) { const hasList = data.length !== 0; + + const { user } = useAuth(); + const userId = user?.uid; + const userEmail = user?.email; + + const [inputValue, setInputValue] = useState(''); + + const handleSubmit = (e) => { + e.preventDefault(); + createList(userId, userEmail, inputValue); + setInputValue(''); + }; + + const handleChange = (e) => { + setInputValue(e.target.value); + }; return (

@@ -19,6 +37,15 @@ export function Home({ data, setListPath }) { /> ))} + +

+

Create New Shopping List

+ +
+ +
+ +
); } From 1f7c03f8eb9d6c1441b801dd3246e737f3510fb9 Mon Sep 17 00:00:00 2001 From: Falak Zahra Date: Thu, 22 Aug 2024 21:29:55 -0600 Subject: [PATCH 2/5] Add alerts for success and failure. Redirect to list view on success. --- src/views/Home.jsx | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/src/views/Home.jsx b/src/views/Home.jsx index fc9de05..10a8b91 100644 --- a/src/views/Home.jsx +++ b/src/views/Home.jsx @@ -2,6 +2,7 @@ import './Home.css'; import { SingleList } from '../components'; import { useState } from 'react'; import { createList, useAuth } from '../api'; +import { useNavigate } from 'react-router-dom'; export function Home({ data, setListPath }) { const hasList = data.length !== 0; @@ -11,11 +12,22 @@ export function Home({ data, setListPath }) { const userEmail = user?.email; const [inputValue, setInputValue] = useState(''); + const navigate = useNavigate(); - const handleSubmit = (e) => { + const handleSubmit = async (e) => { e.preventDefault(); - createList(userId, userEmail, inputValue); - setInputValue(''); + + try { + await createList(userId, userEmail, inputValue); + const path = `${user.uid}/${inputValue}`; + setListPath(path); + setInputValue(''); + alert('Success: Your New List is Created!'); + navigate('/list'); + } catch { + console.error('Error creating list:', error); + alert('Failed to create the list. Please try again.'); + } }; const handleChange = (e) => { @@ -42,9 +54,17 @@ export function Home({ data, setListPath }) {

Create New Shopping List


- +
- + ); From 1479c6b4e1dad20debf04bf9c0cc4a837f67ef6f Mon Sep 17 00:00:00 2001 From: Falak Zahra Date: Sun, 25 Aug 2024 09:05:44 -0600 Subject: [PATCH 3/5] Add form validation and react-hot-toast notifications on submit. --- package-lock.json | 30 +++++++++++++++ package.json | 1 + src/views/Home.jsx | 91 +++++++++++++++++++++++++--------------------- 3 files changed, 81 insertions(+), 41 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5671142..1ee7cf2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,6 +9,7 @@ "firebase": "^10.12.5", "react": "^18.3.1", "react-dom": "^18.3.1", + "react-hot-toast": "^2.4.1", "react-router-dom": "^6.26.0" }, "devDependencies": { @@ -4916,6 +4917,12 @@ "dev": true, "license": "MIT" }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "peer": true + }, "node_modules/damerau-levenshtein": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", @@ -6248,6 +6255,14 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/goober": { + "version": "2.1.14", + "resolved": "https://registry.npmjs.org/goober/-/goober-2.1.14.tgz", + "integrity": "sha512-4UpC0NdGyAFqLNPnhCT2iHpza2q+RAY3GV85a/mRPdzyPQMsj0KmMMuetdIkzWRbJ+Hgau1EZztq8ImmiMGhsg==", + "peerDependencies": { + "csstype": "^3.0.10" + } + }, "node_modules/gopd": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", @@ -8311,6 +8326,21 @@ "react": "^18.3.1" } }, + "node_modules/react-hot-toast": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/react-hot-toast/-/react-hot-toast-2.4.1.tgz", + "integrity": "sha512-j8z+cQbWIM5LY37pR6uZR6D4LfseplqnuAO4co4u8917hBUvXlEqyP1ZzqVLcqoyUesZZv/ImreoCeHVDpE5pQ==", + "dependencies": { + "goober": "^2.1.10" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "react": ">=16", + "react-dom": ">=16" + } + }, "node_modules/react-is": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", diff --git a/package.json b/package.json index 1f74c3e..d5128ae 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ "firebase": "^10.12.5", "react": "^18.3.1", "react-dom": "^18.3.1", + "react-hot-toast": "^2.4.1", "react-router-dom": "^6.26.0" }, "devDependencies": { diff --git a/src/views/Home.jsx b/src/views/Home.jsx index 10a8b91..733ad61 100644 --- a/src/views/Home.jsx +++ b/src/views/Home.jsx @@ -1,32 +1,38 @@ import './Home.css'; import { SingleList } from '../components'; import { useState } from 'react'; -import { createList, useAuth } from '../api'; +import { createList } from '../api'; import { useNavigate } from 'react-router-dom'; +import toast, { Toaster } from 'react-hot-toast'; -export function Home({ data, setListPath }) { +export function Home({ data, setListPath, userId, userEmail }) { const hasList = data.length !== 0; - const { user } = useAuth(); - const userId = user?.uid; - const userEmail = user?.email; - const [inputValue, setInputValue] = useState(''); const navigate = useNavigate(); const handleSubmit = async (e) => { e.preventDefault(); + // Ensure inputValue has a length > 0 after trimming + if (!inputValue.trim()) { + toast.error('List name cannot be empty.'); + return; + } + try { await createList(userId, userEmail, inputValue); const path = `${user.uid}/${inputValue}`; setListPath(path); setInputValue(''); - alert('Success: Your New List is Created!'); - navigate('/list'); + toast.success('Success: Your New List is Created!'); + // Delay for toast notification before redirecting + setTimeout(() => { + navigate('/list'); + }, 1500); // 1.5 seconds delay } catch { console.error('Error creating list:', error); - alert('Failed to create the list. Please try again.'); + toast.error('Failed to create the list. Please try again.'); } }; @@ -34,38 +40,41 @@ export function Home({ data, setListPath }) { setInputValue(e.target.value); }; return ( -
-

- Hello from the home (/) page! -

-
    - {hasList && - data.map((list, index) => ( - - ))} -
+ <> +
+

+ Hello from the home (/) page! +

+
    + {hasList && + data.map((list, index) => ( + + ))} +
-
-

Create New Shopping List

- -
- -
- -
-
+
+

Create New Shopping List

+ +
+ +
+ +
+ +
+ ); } From be221751ac2fc2dd53d13e69d29a54e8127c7828 Mon Sep 17 00:00:00 2001 From: Falak Zahra Date: Sun, 25 Aug 2024 10:54:52 -0600 Subject: [PATCH 4/5] Move the code for creating new list into it's own component --- src/components/CreateList.jsx | 61 +++++++++++++++++++++++++++++++++++ src/views/Home.jsx | 61 +++++------------------------------ 2 files changed, 69 insertions(+), 53 deletions(-) create mode 100644 src/components/CreateList.jsx diff --git a/src/components/CreateList.jsx b/src/components/CreateList.jsx new file mode 100644 index 0000000..9bb9231 --- /dev/null +++ b/src/components/CreateList.jsx @@ -0,0 +1,61 @@ +import { useState } from 'react'; +import { createList } from '../api'; +import { useNavigate } from 'react-router-dom'; +import toast, { Toaster } from 'react-hot-toast'; + +export function CreateList({ userId, userEmail, setListPath }) { + const [inputValue, setInputValue] = useState(''); + const navigate = useNavigate(); + + const handleSubmit = async (e) => { + e.preventDefault(); + + // Ensure inputValue has a length > 0 after trimming + if (!inputValue.trim()) { + toast.error('List name cannot be empty.'); + return; + } + + try { + await createList(userId, userEmail, inputValue); + const path = `${userId}/${inputValue}`; + setListPath(path); + setInputValue(''); + toast.success('Success: Your New List is Created!'); + // Delay for toast notification before redirecting + setTimeout(() => { + navigate('/list'); + }, 1500); // 1.5 seconds delay + } catch (error) { + console.error('Error creating list:', error); + toast.error('Failed to create the list. Please try again.'); + } + }; + + const handleChange = (e) => { + setInputValue(e.target.value); + }; + return ( + <> +
  • +
    +

    Create New Shopping List

    + +
    + +
    + +
    + +
  • + + ); +} diff --git a/src/views/Home.jsx b/src/views/Home.jsx index 733ad61..6c5bd57 100644 --- a/src/views/Home.jsx +++ b/src/views/Home.jsx @@ -1,44 +1,10 @@ import './Home.css'; import { SingleList } from '../components'; -import { useState } from 'react'; -import { createList } from '../api'; -import { useNavigate } from 'react-router-dom'; -import toast, { Toaster } from 'react-hot-toast'; +import { CreateList } from '../components/CreateList'; export function Home({ data, setListPath, userId, userEmail }) { const hasList = data.length !== 0; - const [inputValue, setInputValue] = useState(''); - const navigate = useNavigate(); - - const handleSubmit = async (e) => { - e.preventDefault(); - - // Ensure inputValue has a length > 0 after trimming - if (!inputValue.trim()) { - toast.error('List name cannot be empty.'); - return; - } - - try { - await createList(userId, userEmail, inputValue); - const path = `${user.uid}/${inputValue}`; - setListPath(path); - setInputValue(''); - toast.success('Success: Your New List is Created!'); - // Delay for toast notification before redirecting - setTimeout(() => { - navigate('/list'); - }, 1500); // 1.5 seconds delay - } catch { - console.error('Error creating list:', error); - toast.error('Failed to create the list. Please try again.'); - } - }; - - const handleChange = (e) => { - setInputValue(e.target.value); - }; return ( <>
    @@ -55,25 +21,14 @@ export function Home({ data, setListPath, userId, userEmail }) { setListPath={setListPath} /> ))} + { + + } - -
    -

    Create New Shopping List

    - -
    - -
    - -
    -
    ); From f63da1f323d685eeadcd3d21cbca8a64076c133b Mon Sep 17 00:00:00 2001 From: Falak Zahra Date: Sun, 25 Aug 2024 12:16:13 -0600 Subject: [PATCH 5/5] Resolve conflict with package lock --- package-lock.json | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 1ee7cf2..8a84077 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4921,6 +4921,7 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "license": "MIT", "peer": true }, "node_modules/damerau-levenshtein": { @@ -6259,6 +6260,7 @@ "version": "2.1.14", "resolved": "https://registry.npmjs.org/goober/-/goober-2.1.14.tgz", "integrity": "sha512-4UpC0NdGyAFqLNPnhCT2iHpza2q+RAY3GV85a/mRPdzyPQMsj0KmMMuetdIkzWRbJ+Hgau1EZztq8ImmiMGhsg==", + "license": "MIT", "peerDependencies": { "csstype": "^3.0.10" } @@ -7314,9 +7316,9 @@ "license": "MIT" }, "node_modules/lint-staged": { - "version": "15.2.8", - "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-15.2.8.tgz", - "integrity": "sha512-PUWFf2zQzsd9EFU+kM1d7UP+AZDbKFKuj+9JNVTBkhUFhbg4MAt6WfyMMwBfM4lYqd4D2Jwac5iuTu9rVj4zCQ==", + "version": "15.2.9", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-15.2.9.tgz", + "integrity": "sha512-BZAt8Lk3sEnxw7tfxM7jeZlPRuT4M68O0/CwZhhaw6eeWu0Lz5eERE3m386InivXB64fp/mDID452h48tvKlRQ==", "dev": true, "dependencies": { "chalk": "~5.3.0", @@ -8330,6 +8332,7 @@ "version": "2.4.1", "resolved": "https://registry.npmjs.org/react-hot-toast/-/react-hot-toast-2.4.1.tgz", "integrity": "sha512-j8z+cQbWIM5LY37pR6uZR6D4LfseplqnuAO4co4u8917hBUvXlEqyP1ZzqVLcqoyUesZZv/ImreoCeHVDpE5pQ==", + "license": "MIT", "dependencies": { "goober": "^2.1.10" },