From b76e24678b8c75a39ef8f662ae4083fa1692ff5b Mon Sep 17 00:00:00 2001 From: Laxman Rumba Date: Thu, 13 Nov 2025 15:52:26 +0545 Subject: [PATCH 01/18] chore: initialize project structure --- package.json | 3 ++- src/components/Button/Button.tsx | 16 ++++++++++++++++ src/components/Form/InputField/InputField.tsx | 9 +++++++++ src/components/Form/UserForm/UserForm.tsx | 0 src/components/ItemList/AddItem/AddItem.tsx | 9 +++++++++ src/components/ItemList/ItemList/ItemList.tsx | 9 +++++++++ src/components/ThemeToggle/ThemeToggle.tsx | 0 src/hooks/useCounters.ts | 0 src/hooks/useDarkMode.ts | 0 src/hooks/useFormFields.ts | 0 src/hooks/useItems.ts | 0 11 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 src/components/Button/Button.tsx create mode 100644 src/components/Form/InputField/InputField.tsx create mode 100644 src/components/Form/UserForm/UserForm.tsx create mode 100644 src/components/ItemList/AddItem/AddItem.tsx create mode 100644 src/components/ItemList/ItemList/ItemList.tsx create mode 100644 src/components/ThemeToggle/ThemeToggle.tsx create mode 100644 src/hooks/useCounters.ts create mode 100644 src/hooks/useDarkMode.ts create mode 100644 src/hooks/useFormFields.ts create mode 100644 src/hooks/useItems.ts diff --git a/package.json b/package.json index adc4a01..26207de 100644 --- a/package.json +++ b/package.json @@ -26,5 +26,6 @@ "typescript": "~5.9.3", "typescript-eslint": "^8.45.0", "vite": "^7.1.7" - } + }, + "packageManager": "pnpm@10.19.0+sha512.c9fc7236e92adf5c8af42fd5bf1612df99c2ceb62f27047032f4720b33f8eacdde311865e91c411f2774f618d82f320808ecb51718bfa82c060c4ba7c76a32b8" } diff --git a/src/components/Button/Button.tsx b/src/components/Button/Button.tsx new file mode 100644 index 0000000..bb4ac46 --- /dev/null +++ b/src/components/Button/Button.tsx @@ -0,0 +1,16 @@ +import type React from "react"; + +interface ButtonProps { + value: string; + onClick?: (event: React.MouseEvent) => void; +} + +const Button = ({ value, onClick }: ButtonProps) => { + return ( +
+ +
+ ); +}; + +export default Button; \ No newline at end of file diff --git a/src/components/Form/InputField/InputField.tsx b/src/components/Form/InputField/InputField.tsx new file mode 100644 index 0000000..020eaf7 --- /dev/null +++ b/src/components/Form/InputField/InputField.tsx @@ -0,0 +1,9 @@ +const InputField = () => { + return ( +
+ +
+ ) +} + +export default InputField diff --git a/src/components/Form/UserForm/UserForm.tsx b/src/components/Form/UserForm/UserForm.tsx new file mode 100644 index 0000000..e69de29 diff --git a/src/components/ItemList/AddItem/AddItem.tsx b/src/components/ItemList/AddItem/AddItem.tsx new file mode 100644 index 0000000..0b07ccf --- /dev/null +++ b/src/components/ItemList/AddItem/AddItem.tsx @@ -0,0 +1,9 @@ +const AddItem = () => { + return ( +
+ +
+ ) +} + +export default AddItem diff --git a/src/components/ItemList/ItemList/ItemList.tsx b/src/components/ItemList/ItemList/ItemList.tsx new file mode 100644 index 0000000..ce58dc0 --- /dev/null +++ b/src/components/ItemList/ItemList/ItemList.tsx @@ -0,0 +1,9 @@ +const ItemList = () => { + return ( +
+ +
+ ) +} + +export default ItemList diff --git a/src/components/ThemeToggle/ThemeToggle.tsx b/src/components/ThemeToggle/ThemeToggle.tsx new file mode 100644 index 0000000..e69de29 diff --git a/src/hooks/useCounters.ts b/src/hooks/useCounters.ts new file mode 100644 index 0000000..e69de29 diff --git a/src/hooks/useDarkMode.ts b/src/hooks/useDarkMode.ts new file mode 100644 index 0000000..e69de29 diff --git a/src/hooks/useFormFields.ts b/src/hooks/useFormFields.ts new file mode 100644 index 0000000..e69de29 diff --git a/src/hooks/useItems.ts b/src/hooks/useItems.ts new file mode 100644 index 0000000..e69de29 From ebb12526e0515a7b123f33a9833c07864d96c34c Mon Sep 17 00:00:00 2001 From: Laxman Rumba Date: Thu, 13 Nov 2025 16:01:52 +0545 Subject: [PATCH 02/18] refact/ updated the ItemList folder name to Item --- src/components/{ItemList => Item}/AddItem/AddItem.tsx | 0 src/components/{ItemList => Item}/ItemList/ItemList.tsx | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename src/components/{ItemList => Item}/AddItem/AddItem.tsx (100%) rename src/components/{ItemList => Item}/ItemList/ItemList.tsx (100%) diff --git a/src/components/ItemList/AddItem/AddItem.tsx b/src/components/Item/AddItem/AddItem.tsx similarity index 100% rename from src/components/ItemList/AddItem/AddItem.tsx rename to src/components/Item/AddItem/AddItem.tsx diff --git a/src/components/ItemList/ItemList/ItemList.tsx b/src/components/Item/ItemList/ItemList.tsx similarity index 100% rename from src/components/ItemList/ItemList/ItemList.tsx rename to src/components/Item/ItemList/ItemList.tsx From b20a3d2bf56c1cc5cf42cb5f324e0334c74a442b Mon Sep 17 00:00:00 2001 From: Laxman Rumba Date: Thu, 13 Nov 2025 16:25:36 +0545 Subject: [PATCH 03/18] refact/ removed package manager form package.json --- package.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/package.json b/package.json index 26207de..adc4a01 100644 --- a/package.json +++ b/package.json @@ -26,6 +26,5 @@ "typescript": "~5.9.3", "typescript-eslint": "^8.45.0", "vite": "^7.1.7" - }, - "packageManager": "pnpm@10.19.0+sha512.c9fc7236e92adf5c8af42fd5bf1612df99c2ceb62f27047032f4720b33f8eacdde311865e91c411f2774f618d82f320808ecb51718bfa82c060c4ba7c76a32b8" + } } From 6fd619c4c02336188399b93185d6d29f099f0242 Mon Sep 17 00:00:00 2001 From: Laxman Rumba Date: Thu, 13 Nov 2025 16:26:33 +0545 Subject: [PATCH 04/18] refact/ removed package manager form package.json --- package.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/package.json b/package.json index 26207de..adc4a01 100644 --- a/package.json +++ b/package.json @@ -26,6 +26,5 @@ "typescript": "~5.9.3", "typescript-eslint": "^8.45.0", "vite": "^7.1.7" - }, - "packageManager": "pnpm@10.19.0+sha512.c9fc7236e92adf5c8af42fd5bf1612df99c2ceb62f27047032f4720b33f8eacdde311865e91c411f2774f618d82f320808ecb51718bfa82c060c4ba7c76a32b8" + } } From d10ff0e752f970a9c203e51c5abde705573043d2 Mon Sep 17 00:00:00 2001 From: Laxman Rumba Date: Thu, 13 Nov 2025 16:27:28 +0545 Subject: [PATCH 05/18] refact/ removed package manager form package.json --- package.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/package.json b/package.json index 26207de..adc4a01 100644 --- a/package.json +++ b/package.json @@ -26,6 +26,5 @@ "typescript": "~5.9.3", "typescript-eslint": "^8.45.0", "vite": "^7.1.7" - }, - "packageManager": "pnpm@10.19.0+sha512.c9fc7236e92adf5c8af42fd5bf1612df99c2ceb62f27047032f4720b33f8eacdde311865e91c411f2774f618d82f320808ecb51718bfa82c060c4ba7c76a32b8" + } } From fb781e83597f3f723b378148d51f6084b87b0464 Mon Sep 17 00:00:00 2001 From: Laxman Rumba Date: Thu, 13 Nov 2025 17:34:48 +0545 Subject: [PATCH 06/18] feat/added counter --- package.json | 3 +- src/App.tsx | 125 +----------------------- src/components/Button/Button.tsx | 5 +- src/components/Counter/Counter.tsx | 19 ++++ src/components/Counter/style.module.css | 35 +++++++ src/hooks/useCounters.ts | 11 +++ 6 files changed, 74 insertions(+), 124 deletions(-) create mode 100644 src/components/Counter/Counter.tsx create mode 100644 src/components/Counter/style.module.css diff --git a/package.json b/package.json index adc4a01..26207de 100644 --- a/package.json +++ b/package.json @@ -26,5 +26,6 @@ "typescript": "~5.9.3", "typescript-eslint": "^8.45.0", "vite": "^7.1.7" - } + }, + "packageManager": "pnpm@10.19.0+sha512.c9fc7236e92adf5c8af42fd5bf1612df99c2ceb62f27047032f4720b33f8eacdde311865e91c411f2774f618d82f320808ecb51718bfa82c060c4ba7c76a32b8" } diff --git a/src/App.tsx b/src/App.tsx index 42be7aa..3ad0715 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,128 +1,11 @@ -import { useEffect, useRef, useState } from "react"; +import Counter from "./components/Counter/Counter"; export default function App() { - const [count, setCount] = useState(0); - const [isDarkMode, setIsDarkMode] = useState(false); - const [name, setName] = useState(""); - const [email, setEmail] = useState(""); - const [isVisible, setIsVisible] = useState(true); - const [items, setItems] = useState([]); - const [selectedItem, setSelectedItem] = useState(null); - - const inputRef = useRef(null); - - useEffect(() => { - const storedCount = localStorage.getItem("count"); - if (storedCount) { - setCount(parseInt(storedCount)); - } - }, []); - - useEffect(() => { - localStorage.setItem("count", count.toString()); - }, [count]); - - useEffect(() => { - document.title = `Hello ${name}`; - }, [name]); - - useEffect(() => { - if (selectedItem) { - console.log(selectedItem); - } - }, [selectedItem]); - - useEffect(() => { - document.body.classList.toggle("dark", isDarkMode); - }, [isDarkMode]); - - const increment = () => { - setCount(count + 1); - }; - - const decrement = () => { - setCount(count - 1); - }; - - const handleNameChange = (e: React.ChangeEvent) => { - setName(e.target.value); - }; - - const handleEmailChange = (e: React.ChangeEvent) => { - setEmail(e.target.value); - }; - - const toggleVisibility = () => { - setIsVisible(!isVisible); - }; - - function addItem() { - if (inputRef.current && inputRef.current.value) { - setItems([...items, inputRef.current.value]); - inputRef.current.value = ""; - } - } - - async function handleSubmit() { - // Do something with data... - } - return (
-

Outside

-
- - -

Count: {count}

-
-
-
- -

Name: {name}

-
-
- -

Email: {email}

-
-
-
- - {isVisible && ( -
- - -
    - {items.map((item, index) => ( -
  • setSelectedItem(item)}> - {item} -
  • - ))} -
-
- )} -
-
-

Selected Item: {selectedItem}

-
-
-
-
- -
+
+ +
); } diff --git a/src/components/Button/Button.tsx b/src/components/Button/Button.tsx index bb4ac46..b4386a4 100644 --- a/src/components/Button/Button.tsx +++ b/src/components/Button/Button.tsx @@ -3,12 +3,13 @@ import type React from "react"; interface ButtonProps { value: string; onClick?: (event: React.MouseEvent) => void; + className?:string } -const Button = ({ value, onClick }: ButtonProps) => { +const Button = ({ value, onClick, className }: ButtonProps) => { return (
- +
); }; diff --git a/src/components/Counter/Counter.tsx b/src/components/Counter/Counter.tsx new file mode 100644 index 0000000..cb75e09 --- /dev/null +++ b/src/components/Counter/Counter.tsx @@ -0,0 +1,19 @@ +import Button from "../Button/Button"; +import styles from "./style.module.css" +import { useCounter } from "../../hooks/useCounters"; + + +const Counter = () => { + const { count, increment, decrement } = useCounter(); + return ( +
+

Count: {count}

+
+ + +
+
+ ) +} + +export default Counter diff --git a/src/components/Counter/style.module.css b/src/components/Counter/style.module.css new file mode 100644 index 0000000..e3e7a00 --- /dev/null +++ b/src/components/Counter/style.module.css @@ -0,0 +1,35 @@ +.increment, .decrement{ + background-color: rgb(61, 185, 61); + padding: 15px 20px; + color: white; + border-radius: 12px; + border: none; + font-size: 15px; + margin: 10px 10px; + cursor: pointer; +} + +.increment:hover, +.decrement:hover{ + opacity: 0.7; +} + +.decrement{ + background-color: rgb(240, 66, 35); +} + +.count{ + color: rgb(72, 72, 240); + font-size: 3rem; + text-align: center; +} + +.background{ + background-color: rgb(183, 184, 185); + padding: 10px 10px; +} + +.buttonSection{ + display: flex; + justify-content: center; +} \ No newline at end of file diff --git a/src/hooks/useCounters.ts b/src/hooks/useCounters.ts index e69de29..7f70544 100644 --- a/src/hooks/useCounters.ts +++ b/src/hooks/useCounters.ts @@ -0,0 +1,11 @@ +import { useCallback, useState } from "react"; + +export function useCounter() { + const [count, setCount] = useState(0); + const increment = useCallback(() => setCount((count) => count + 1), []); + const decrement = useCallback( + () => setCount((count) => Math.max(count - 1, 0)), + [] + ); + return { count, increment, decrement }; +} From bb8152ae773b31450fe1884c976d885879ca5c02 Mon Sep 17 00:00:00 2001 From: Laxman Rumba Date: Thu, 13 Nov 2025 17:36:27 +0545 Subject: [PATCH 07/18] refact/added classNames in button props --- src/components/Button/Button.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/Button/Button.tsx b/src/components/Button/Button.tsx index bb4ac46..319a1e8 100644 --- a/src/components/Button/Button.tsx +++ b/src/components/Button/Button.tsx @@ -3,6 +3,7 @@ import type React from "react"; interface ButtonProps { value: string; onClick?: (event: React.MouseEvent) => void; + className?:string; } const Button = ({ value, onClick }: ButtonProps) => { From 9511c9db0bf2ca1a420e9b10fc9ed8c6ed317b15 Mon Sep 17 00:00:00 2001 From: Laxman Rumba Date: Thu, 13 Nov 2025 17:39:12 +0545 Subject: [PATCH 08/18] refact/undo the deleted tags in app.jsx --- src/App.tsx | 119 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 116 insertions(+), 3 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 3ad0715..91fe011 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,11 +1,124 @@ +import { useEffect, useRef, useState } from "react"; import Counter from "./components/Counter/Counter"; export default function App() { + const [count, setCount] = useState(0); + const [isDarkMode, setIsDarkMode] = useState(false); + const [name, setName] = useState(""); + const [email, setEmail] = useState(""); + const [isVisible, setIsVisible] = useState(true); + const [items, setItems] = useState([]); + const [selectedItem, setSelectedItem] = useState(null); + + const inputRef = useRef(null); + + useEffect(() => { + const storedCount = localStorage.getItem("count"); + if (storedCount) { + setCount(parseInt(storedCount)); + } + }, []); + + useEffect(() => { + localStorage.setItem("count", count.toString()); + }, [count]); + + useEffect(() => { + document.title = `Hello ${name}`; + }, [name]); + + useEffect(() => { + if (selectedItem) { + console.log(selectedItem); + } + }, [selectedItem]); + + useEffect(() => { + document.body.classList.toggle("dark", isDarkMode); + }, [isDarkMode]); + + const increment = () => { + setCount(count + 1); + }; + + const decrement = () => { + setCount(count - 1); + }; + + const handleNameChange = (e: React.ChangeEvent) => { + setName(e.target.value); + }; + + const handleEmailChange = (e: React.ChangeEvent) => { + setEmail(e.target.value); + }; + + const toggleVisibility = () => { + setIsVisible(!isVisible); + }; + + function addItem() { + if (inputRef.current && inputRef.current.value) { + setItems([...items, inputRef.current.value]); + inputRef.current.value = ""; + } + } + + async function handleSubmit() { + // Do something with data... + } + return (
-
-
+
+
+ +

Name: {name}

+
+
+ +

Email: {email}

+
+
+
+ + {isVisible && ( +
+ + +
    + {items.map((item, index) => ( +
  • setSelectedItem(item)}> + {item} +
  • + ))} +
+
+ )} +
+
+

Selected Item: {selectedItem}

+
+
+
+
+ +
); -} +} \ No newline at end of file From 4c0b900504317032ab7bcf929d573b17a139b1c0 Mon Sep 17 00:00:00 2001 From: Laxman Rumba Date: Thu, 13 Nov 2025 17:54:07 +0545 Subject: [PATCH 09/18] refact/added removed semicolons --- src/components/Button/Button.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Button/Button.tsx b/src/components/Button/Button.tsx index b4386a4..35c3afd 100644 --- a/src/components/Button/Button.tsx +++ b/src/components/Button/Button.tsx @@ -3,7 +3,7 @@ import type React from "react"; interface ButtonProps { value: string; onClick?: (event: React.MouseEvent) => void; - className?:string + className?:string; } const Button = ({ value, onClick, className }: ButtonProps) => { From 1289025b01d995fc836485c7097b40340b1c8a40 Mon Sep 17 00:00:00 2001 From: Laxman Rumba Date: Thu, 13 Nov 2025 20:42:03 +0545 Subject: [PATCH 10/18] refact/Addressed pr review changes --- src/App.tsx | 2 +- src/components/Button/Button.tsx | 2 -- src/components/Counter/Counter.tsx | 8 ++++---- src/hooks/useCounters.ts | 6 +++--- src/style.css | 2 ++ 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 8e0ead3..5e4fe93 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -63,7 +63,7 @@ export default function App() { return (
- +
{ return ( -
-
); }; diff --git a/src/components/Counter/Counter.tsx b/src/components/Counter/Counter.tsx index 1f1d520..62890a1 100644 --- a/src/components/Counter/Counter.tsx +++ b/src/components/Counter/Counter.tsx @@ -4,16 +4,16 @@ import { useCounter } from "../../hooks/useCounters"; const Counter = () => { - const { count, increment, decrement } = useCounter(); + const { count, handleIncrement, handleDecrement } = useCounter(); return (

COUNT: {count}

- - +
) } -export default Counter +export default Counter \ No newline at end of file diff --git a/src/hooks/useCounters.ts b/src/hooks/useCounters.ts index 7f70544..bca04f4 100644 --- a/src/hooks/useCounters.ts +++ b/src/hooks/useCounters.ts @@ -2,10 +2,10 @@ import { useCallback, useState } from "react"; export function useCounter() { const [count, setCount] = useState(0); - const increment = useCallback(() => setCount((count) => count + 1), []); - const decrement = useCallback( + const handleIncrement = useCallback(() => setCount((count) => count + 1), []); + const handleDecrement = useCallback( () => setCount((count) => Math.max(count - 1, 0)), [] ); - return { count, increment, decrement }; + return { count, handleIncrement, handleDecrement }; } diff --git a/src/style.css b/src/style.css index 2a5f689..dd27db3 100644 --- a/src/style.css +++ b/src/style.css @@ -1,3 +1,5 @@ *{ font-family: Helvetica, sans-serif; + margin: 0; + padding: 0; } \ No newline at end of file From 663785580e339c319dd56d23c8b5348c3410fb20 Mon Sep 17 00:00:00 2001 From: Laxman Rumba Date: Thu, 13 Nov 2025 21:47:24 +0545 Subject: [PATCH 11/18] WIP/ still working on it --- src/components/Form/InputField/InputField.tsx | 14 +++++++++++-- src/components/Form/UserForm/UserForm.tsx | 21 +++++++++++++++++++ src/hooks/useFormFields.ts | 10 +++++++++ 3 files changed, 43 insertions(+), 2 deletions(-) diff --git a/src/components/Form/InputField/InputField.tsx b/src/components/Form/InputField/InputField.tsx index 020eaf7..9718a94 100644 --- a/src/components/Form/InputField/InputField.tsx +++ b/src/components/Form/InputField/InputField.tsx @@ -1,7 +1,17 @@ -const InputField = () => { +import type React from "react"; + +interface InputFieldProps { + label: string; + type:string; + value:string; + onChange: (e: React.ChangeEvent)=>void; +} + +const InputField = ({ label, type, value, onChange }: InputFieldProps) => { return (
- + +

{label}:{value}

) } diff --git a/src/components/Form/UserForm/UserForm.tsx b/src/components/Form/UserForm/UserForm.tsx index e69de29..a97a391 100644 --- a/src/components/Form/UserForm/UserForm.tsx +++ b/src/components/Form/UserForm/UserForm.tsx @@ -0,0 +1,21 @@ +import React from 'react' +import InputField from '../InputField/InputField'; +import useFormFields from '../../../hooks/useFormFields'; + +const UserForm = () => { + const {name, email, setName, setEmail} = useFormFields(); + +const handleSubmit = (e: React.FormEvent)=>{ + e.preventDefault(); +} + + return ( + + setName(e.target.value)}/> + setEmail(e.target.value)}/> + + ) +} + + +export default UserForm diff --git a/src/hooks/useFormFields.ts b/src/hooks/useFormFields.ts index e69de29..639b9ee 100644 --- a/src/hooks/useFormFields.ts +++ b/src/hooks/useFormFields.ts @@ -0,0 +1,10 @@ +import { useState } from "react"; + +const useFormFields = () => { + const [name, setName] = useState(""); + const [email, setEmail] = useState(""); + + return { name, setName, email, setEmail }; +}; + +export default useFormFields; From 1fe996b249f91d8a04ff9b2a67c34f9f5f5dbd0b Mon Sep 17 00:00:00 2001 From: Laxman Rumba Date: Thu, 13 Nov 2025 21:51:48 +0545 Subject: [PATCH 12/18] refact/updated counter to use localstorage to persist the count on reload --- src/hooks/useCounters.ts | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/hooks/useCounters.ts b/src/hooks/useCounters.ts index bca04f4..82e3799 100644 --- a/src/hooks/useCounters.ts +++ b/src/hooks/useCounters.ts @@ -1,7 +1,15 @@ -import { useCallback, useState } from "react"; +import { useCallback, useEffect, useState } from "react"; export function useCounter() { - const [count, setCount] = useState(0); + const [count, setCount] = useState(() => { + const storedCount = localStorage.getItem("count"); + return storedCount ? parseInt(storedCount, 10) : 0; + }); + + useEffect(() => { + localStorage.setItem("count", count.toString()); + }, [count]); + const handleIncrement = useCallback(() => setCount((count) => count + 1), []); const handleDecrement = useCallback( () => setCount((count) => Math.max(count - 1, 0)), From e8754d6fa63ddbb1473a4a08e84e2078f1b84f6e Mon Sep 17 00:00:00 2001 From: Laxman Rumba Date: Thu, 13 Nov 2025 22:28:05 +0545 Subject: [PATCH 13/18] refact/ enhanced the form styling using BEM --- src/App.tsx | 36 ++-------------- src/components/Form/InputField/InputField.tsx | 30 ++++++++++---- .../Form/InputField/style.module.css | 37 +++++++++++++++++ src/components/Form/UserForm/UserForm.tsx | 36 +++++++++++----- src/components/Form/UserForm/style.module.css | 41 +++++++++++++++++++ src/hooks/useFormFields.ts | 6 ++- 6 files changed, 133 insertions(+), 53 deletions(-) create mode 100644 src/components/Form/InputField/style.module.css create mode 100644 src/components/Form/UserForm/style.module.css diff --git a/src/App.tsx b/src/App.tsx index 5e4fe93..353935e 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,11 +1,10 @@ import { useEffect, useRef, useState } from "react"; import Counter from "./components/Counter/Counter"; +import UserForm from "./components/Form/UserForm/UserForm"; export default function App() { const [count, setCount] = useState(0); const [isDarkMode, setIsDarkMode] = useState(false); - const [name, setName] = useState(""); - const [email, setEmail] = useState(""); const [isVisible, setIsVisible] = useState(true); const [items, setItems] = useState([]); const [selectedItem, setSelectedItem] = useState(null); @@ -23,10 +22,6 @@ export default function App() { localStorage.setItem("count", count.toString()); }, [count]); - useEffect(() => { - document.title = `Hello ${name}`; - }, [name]); - useEffect(() => { if (selectedItem) { console.log(selectedItem); @@ -38,14 +33,6 @@ export default function App() { }, [isDarkMode]); - const handleNameChange = (e: React.ChangeEvent) => { - setName(e.target.value); - }; - - const handleEmailChange = (e: React.ChangeEvent) => { - setEmail(e.target.value); - }; - const toggleVisibility = () => { setIsVisible(!isVisible); }; @@ -64,25 +51,10 @@ export default function App() { return (
+ + +
-
- -

Name: {name}

-
-
- -

Email: {email}

-
+ ); +}; -export default UserForm +export default UserForm; diff --git a/src/components/Form/UserForm/style.module.css b/src/components/Form/UserForm/style.module.css new file mode 100644 index 0000000..4649075 --- /dev/null +++ b/src/components/Form/UserForm/style.module.css @@ -0,0 +1,41 @@ +.user-form { + display: flex; + flex-direction: column; + align-items: center; + padding: 24px; + background-color: #f9f9f9; + border-radius: 12px; + max-width: 450px; + margin: 20px auto; + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); +} + +.user-form__form { + display: flex; + flex-direction: column; + width: 100%; +} + +.user-form__button { + margin-top: 12px; + padding: 10px 16px; + background-color: #007bff; + border: none; + border-radius: 6px; + color: #fff; + font-weight: 600; + cursor: pointer; + transition: background-color 0.2s; +} + +.user-form__button:hover { + background-color: #0056b3; +} + +.user-form__welcome { + margin-top: 16px; + font-size: 16px; + font-weight: 500; + color: #333; + text-align: center; +} diff --git a/src/hooks/useFormFields.ts b/src/hooks/useFormFields.ts index 639b9ee..04eb95e 100644 --- a/src/hooks/useFormFields.ts +++ b/src/hooks/useFormFields.ts @@ -1,9 +1,13 @@ -import { useState } from "react"; +import { useEffect, useState } from "react"; const useFormFields = () => { const [name, setName] = useState(""); const [email, setEmail] = useState(""); + useEffect(() => { + document.title = name ? `Hello ${name}` : "React App"; + }, [name]); + return { name, setName, email, setEmail }; }; From b99ea41e7288d9e159d591ac5679e16dea9902b9 Mon Sep 17 00:00:00 2001 From: Laxman Rumba Date: Fri, 14 Nov 2025 07:12:26 +0545 Subject: [PATCH 14/18] refact/updated the useItems hook and css --- package.json | 3 +- src/App.tsx | 113 +++--------------- src/components/Item/AddItem/AddItem.tsx | 19 +-- src/components/Item/AddItem/style.module.css | 36 ++++++ src/components/Item/ItemList/ItemList.tsx | 20 ++-- src/components/Item/ItemList/style.module.css | 39 ++++++ src/hooks/useItems.ts | 32 +++++ src/style.css | 27 +++++ 8 files changed, 177 insertions(+), 112 deletions(-) create mode 100644 src/components/Item/AddItem/style.module.css create mode 100644 src/components/Item/ItemList/style.module.css diff --git a/package.json b/package.json index adc4a01..26207de 100644 --- a/package.json +++ b/package.json @@ -26,5 +26,6 @@ "typescript": "~5.9.3", "typescript-eslint": "^8.45.0", "vite": "^7.1.7" - } + }, + "packageManager": "pnpm@10.19.0+sha512.c9fc7236e92adf5c8af42fd5bf1612df99c2ceb62f27047032f4720b33f8eacdde311865e91c411f2774f618d82f320808ecb51718bfa82c060c4ba7c76a32b8" } diff --git a/src/App.tsx b/src/App.tsx index 5e4fe93..c0126f9 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,112 +1,31 @@ import { useEffect, useRef, useState } from "react"; import Counter from "./components/Counter/Counter"; +import { AddItem } from './components/Item/AddItem/AddItem'; +import { useItems } from "./hooks/useItems"; +import Button from "./components/Button/Button"; +import { ItemList } from "./components/Item/ItemList/ItemList"; export default function App() { - const [count, setCount] = useState(0); const [isDarkMode, setIsDarkMode] = useState(false); - const [name, setName] = useState(""); - const [email, setEmail] = useState(""); - const [isVisible, setIsVisible] = useState(true); - const [items, setItems] = useState([]); - const [selectedItem, setSelectedItem] = useState(null); - - const inputRef = useRef(null); - - useEffect(() => { - const storedCount = localStorage.getItem("count"); - if (storedCount) { - setCount(parseInt(storedCount)); - } - }, []); - - useEffect(() => { - localStorage.setItem("count", count.toString()); - }, [count]); - - useEffect(() => { - document.title = `Hello ${name}`; - }, [name]); - - useEffect(() => { - if (selectedItem) { - console.log(selectedItem); - } - }, [selectedItem]); - useEffect(() => { document.body.classList.toggle("dark", isDarkMode); }, [isDarkMode]); - const handleNameChange = (e: React.ChangeEvent) => { - setName(e.target.value); - }; - - const handleEmailChange = (e: React.ChangeEvent) => { - setEmail(e.target.value); - }; - - const toggleVisibility = () => { - setIsVisible(!isVisible); - }; - - function addItem() { - if (inputRef.current && inputRef.current.value) { - setItems([...items, inputRef.current.value]); - inputRef.current.value = ""; - } - } - - async function handleSubmit() { - // Do something with data... - } - + const { items, isVisible, inputValue, setInputValue,setSelectedItem, addItem, toggleVisibility } = useItems(); return (
- -
-
- -

Name: {name}

-
-
- -

Email: {email}

-
-
-
- - {isVisible && ( -
- - -
    - {items.map((item, index) => ( -
  • setSelectedItem(item)}> - {item} -
  • - ))} -
-
- )} -
-
-

Selected Item: {selectedItem}

-
-
-
+ +
+ + {isVisible && ( + <> + + + + )} +
+
+); \ No newline at end of file diff --git a/src/components/Item/AddItem/style.module.css b/src/components/Item/AddItem/style.module.css new file mode 100644 index 0000000..72dcbbc --- /dev/null +++ b/src/components/Item/AddItem/style.module.css @@ -0,0 +1,36 @@ +.add-item { + display: flex; + align-items: center; + gap: 8px; + margin-bottom: 16px; +} + +.add-item__input { + flex: 1; + padding: 8px 12px; + border: 1px solid #ccc; + border-radius: 6px; + font-size: 14px; + transition: border-color 0.2s, box-shadow 0.2s; +} + +.add-item__input:focus { + outline: none; + border-color: #007bff; + box-shadow: 0 0 5px rgba(0, 123, 255, 0.5); +} + +.add-item__button { + padding: 8px 16px; + background-color: #007bff; + color: #fff; + border: none; + border-radius: 6px; + font-weight: 600; + cursor: pointer; + transition: background-color 0.2s; +} + +.add-item__button:hover { + background-color: #0056b3; +} diff --git a/src/components/Item/ItemList/ItemList.tsx b/src/components/Item/ItemList/ItemList.tsx index ce58dc0..2616d52 100644 --- a/src/components/Item/ItemList/ItemList.tsx +++ b/src/components/Item/ItemList/ItemList.tsx @@ -1,9 +1,15 @@ -const ItemList = () => { - return ( -
- -
- ) +import styles from './style.module.css' +interface ItemListProps { + items: string[]; + setSelectedItem: (item: string) => void; } -export default ItemList +export const ItemList = ({ items, setSelectedItem }: ItemListProps) => ( +
    + {items.map((item, index) => ( +
  • setSelectedItem(item)}> + {item} +
  • + ))} +
+); \ No newline at end of file diff --git a/src/components/Item/ItemList/style.module.css b/src/components/Item/ItemList/style.module.css new file mode 100644 index 0000000..6d1e9b3 --- /dev/null +++ b/src/components/Item/ItemList/style.module.css @@ -0,0 +1,39 @@ +.item-list { + list-style: none; + padding: 0; + margin: 0; + width: fit-content; +} + +.item-list__item { + position: relative; + padding: 6px 12px 6px 26px; + border-radius: 6px; + margin-bottom: 6px; + cursor: pointer; + transition: + background-color 0.25s ease, + transform 0.15s ease; +} + +.item-list__item::before { + content: ""; + position: absolute; + left: 10px; + top: 50%; + transform: translateY(-50%); + width: 6px; + height: 6px; + border-radius: 50%; + background-color: #007bff55; + transition: background-color 0.2s ease; +} + +.item-list__item:hover { + background-color: #eef6ff; + transform: translateX(3px); +} + +.item-list__item:hover::before { + background-color: #007bff; +} diff --git a/src/hooks/useItems.ts b/src/hooks/useItems.ts index e69de29..a875651 100644 --- a/src/hooks/useItems.ts +++ b/src/hooks/useItems.ts @@ -0,0 +1,32 @@ +import { useState, useEffect } from "react"; + +export function useItems() { + const [items, setItems] = useState([]); + const [selectedItem, setSelectedItem] = useState(null); + const [isVisible, setIsVisible] = useState(true); + const [inputValue, setInputValue] = useState(""); + + useEffect(() => { + if (selectedItem) console.log(selectedItem); + }, [selectedItem]); + + const addItem = () => { + if (inputValue) { + setItems((prev) => [...prev, inputValue.trim()]); + setInputValue(""); + } + }; + + const toggleVisibility = () => setIsVisible((prev) => !prev); + + return { + items, + selectedItem, + isVisible, + inputValue, + setInputValue, + setSelectedItem, + addItem, + toggleVisibility, + }; +} diff --git a/src/style.css b/src/style.css index dd27db3..d63d848 100644 --- a/src/style.css +++ b/src/style.css @@ -2,4 +2,31 @@ font-family: Helvetica, sans-serif; margin: 0; padding: 0; +} + +.items{ + width: max-100vh; + background-color: rgb(212, 212, 212); + padding: 20px 20px; +} + +.toggle-visible-btn { + padding: 8px 16px; + margin-bottom: 12px; + background-color: #6c757d; /* neutral gray */ + color: #fff; + border: none; + border-radius: 6px; + font-weight: 600; + cursor: pointer; + transition: background-color 0.2s, transform 0.1s; +} + +.toggle-visible-btn:hover { + background-color: #5a6268; + transform: translateY(-1px); +} + +.toggle-visible-btn:active { + transform: translateY(0); } \ No newline at end of file From c246504153170289ebad0edc0001143894c6e20d Mon Sep 17 00:00:00 2001 From: Laxman Rumba Date: Fri, 14 Nov 2025 07:17:50 +0545 Subject: [PATCH 15/18] refact/removed unnecessary code --- src/App.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/App.tsx b/src/App.tsx index c0126f9..d9539d8 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,4 +1,4 @@ -import { useEffect, useRef, useState } from "react"; +import { useEffect, useState } from "react"; import Counter from "./components/Counter/Counter"; import { AddItem } from './components/Item/AddItem/AddItem'; import { useItems } from "./hooks/useItems"; From b589b2522b5d2f21d8cb88cec4fc7f88c4677f3f Mon Sep 17 00:00:00 2001 From: Laxman Rumba Date: Fri, 14 Nov 2025 07:44:59 +0545 Subject: [PATCH 16/18] refact/updated the toggleTheme with custom hooks --- src/App.tsx | 10 ++-------- src/components/ThemeToggle/ThemeToggle.tsx | 10 ++++++++++ src/components/ThemeToggle/style.module.css | 20 ++++++++++++++++++++ src/hooks/useDarkMode.ts | 13 +++++++++++++ src/style.css | 12 ++++++++++++ 5 files changed, 57 insertions(+), 8 deletions(-) create mode 100644 src/components/ThemeToggle/style.module.css diff --git a/src/App.tsx b/src/App.tsx index 5e4fe93..fac16f4 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,9 +1,9 @@ import { useEffect, useRef, useState } from "react"; import Counter from "./components/Counter/Counter"; +import { ThemeToggle } from './components/ThemeToggle/ThemeToggle'; export default function App() { const [count, setCount] = useState(0); - const [isDarkMode, setIsDarkMode] = useState(false); const [name, setName] = useState(""); const [email, setEmail] = useState(""); const [isVisible, setIsVisible] = useState(true); @@ -33,10 +33,6 @@ export default function App() { } }, [selectedItem]); - useEffect(() => { - document.body.classList.toggle("dark", isDarkMode); - }, [isDarkMode]); - const handleNameChange = (e: React.ChangeEvent) => { setName(e.target.value); @@ -108,9 +104,7 @@ export default function App() {
- +
); diff --git a/src/components/ThemeToggle/ThemeToggle.tsx b/src/components/ThemeToggle/ThemeToggle.tsx index e69de29..07f3e13 100644 --- a/src/components/ThemeToggle/ThemeToggle.tsx +++ b/src/components/ThemeToggle/ThemeToggle.tsx @@ -0,0 +1,10 @@ +import Button from "../Button/Button"; +import { useDarkMode } from "../../hooks/useDarkMode"; +import styles from './style.module.css' + +export const ThemeToggle = () => { + const { isDarkMode, toggleDarkMode } = useDarkMode(); + return ( +
); }; From ee15de824ca9438f4aa3d7ce16777084ef939881 Mon Sep 17 00:00:00 2001 From: Laxman Rumba Date: Mon, 17 Nov 2025 16:47:30 +0545 Subject: [PATCH 18/18] refactor/updated the dark mode togggle --- src/App.tsx | 8 +++----- src/components/Counter/Counter.tsx | 16 +++++++++------- src/components/Counter/style.module.css | 4 ++-- src/components/Form/UserForm/UserForm.tsx | 9 +++++---- src/components/Form/UserForm/style.module.css | 15 ++++++++++++--- src/components/Item/AddItem/AddItem.tsx | 12 ++++++++---- src/components/Item/ItemList/ItemList.tsx | 3 +++ src/hooks/useDarkMode.ts | 6 +++++- src/style.css | 19 ++++++++++++++++--- 9 files changed, 63 insertions(+), 29 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index fc70a6a..b61f4ec 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,19 +1,18 @@ import Counter from "./components/Counter/Counter"; import UserForm from "./components/Form/UserForm/UserForm"; -import { AddItem } from './components/Item/AddItem/AddItem'; import { useItems } from "./hooks/useItems"; import Button from "./components/Button/Button"; import { ItemList } from "./components/Item/ItemList/ItemList"; import { ThemeToggle } from './components/ThemeToggle/ThemeToggle'; +import AddItem from "./components/Item/AddItem/AddItem"; export default function App() { const { items, isVisible, inputValue, setInputValue,setSelectedItem, addItem, toggleVisibility } = useItems(); return ( -
-
+
-
+
{isVisible && ( <> @@ -24,6 +23,5 @@ export default function App() {
-
); } \ No newline at end of file diff --git a/src/components/Counter/Counter.tsx b/src/components/Counter/Counter.tsx index 62890a1..3b62e09 100644 --- a/src/components/Counter/Counter.tsx +++ b/src/components/Counter/Counter.tsx @@ -6,13 +6,15 @@ import { useCounter } from "../../hooks/useCounters"; const Counter = () => { const { count, handleIncrement, handleDecrement } = useCounter(); return ( -
-

COUNT: {count}

-
-
-
+
+
+

COUNT: {count}

+
+
+
+
) } diff --git a/src/components/Counter/style.module.css b/src/components/Counter/style.module.css index 5fb07e1..986a21f 100644 --- a/src/components/Counter/style.module.css +++ b/src/components/Counter/style.module.css @@ -30,11 +30,11 @@ } .background{ - background-color: rgb(217, 217, 218); + /* background-color: rgb(217, 217, 218); */ padding: 10px 10px; } .buttonSection{ display: flex; justify-content: center; -} \ No newline at end of file +} diff --git a/src/components/Form/UserForm/UserForm.tsx b/src/components/Form/UserForm/UserForm.tsx index eb9b294..f868a3a 100644 --- a/src/components/Form/UserForm/UserForm.tsx +++ b/src/components/Form/UserForm/UserForm.tsx @@ -16,19 +16,20 @@ const UserForm = () => { }; return ( -
-
+
+
+ setName(e.target.value)} /> setEmail(e.target.value)} />
+
); }; diff --git a/src/components/Form/UserForm/style.module.css b/src/components/Form/UserForm/style.module.css index 4649075..65b47f9 100644 --- a/src/components/Form/UserForm/style.module.css +++ b/src/components/Form/UserForm/style.module.css @@ -13,7 +13,8 @@ .user-form__form { display: flex; flex-direction: column; - width: 100%; + width:30%; + margin: auto; } .user-form__button { @@ -32,10 +33,18 @@ background-color: #0056b3; } -.user-form__welcome { +.user-form__welcome{ margin-top: 16px; font-size: 16px; font-weight: 500; - color: #333; + color: black; text-align: center; } + +.user-form__welcome .dark { + margin-top: 16px; + font-size: 16px; + font-weight: 500; + color: white; + text-align: center;; +} diff --git a/src/components/Item/AddItem/AddItem.tsx b/src/components/Item/AddItem/AddItem.tsx index 409bbc6..f1c46c0 100644 --- a/src/components/Item/AddItem/AddItem.tsx +++ b/src/components/Item/AddItem/AddItem.tsx @@ -6,9 +6,13 @@ interface AddItemProps { setInputValue: (value: string) => void; } -export const AddItem = ({ addItem, inputValue, setInputValue }: AddItemProps) => ( -
+const AddItem = ({ addItem, inputValue, setInputValue }: AddItemProps) =>{ + return ( +
setInputValue(e.target.value)} type="text" placeholder="Add item" className={styles["add-item__input"]}/>
-); \ No newline at end of file +
); + +}; + +export default AddItem; \ No newline at end of file diff --git a/src/components/Item/ItemList/ItemList.tsx b/src/components/Item/ItemList/ItemList.tsx index 2616d52..14508b9 100644 --- a/src/components/Item/ItemList/ItemList.tsx +++ b/src/components/Item/ItemList/ItemList.tsx @@ -5,6 +5,8 @@ interface ItemListProps { } export const ItemList = ({ items, setSelectedItem }: ItemListProps) => ( +
+
    {items.map((item, index) => (
  • setSelectedItem(item)}> @@ -12,4 +14,5 @@ export const ItemList = ({ items, setSelectedItem }: ItemListProps) => (
  • ))}
+
); \ No newline at end of file diff --git a/src/hooks/useDarkMode.ts b/src/hooks/useDarkMode.ts index 6b31d8c..226c02c 100644 --- a/src/hooks/useDarkMode.ts +++ b/src/hooks/useDarkMode.ts @@ -1,10 +1,14 @@ import { useEffect, useState } from "react"; export function useDarkMode() { + const container = document.getElementsByClassName("container"); const [isDarkMode, setIsDarkMode] = useState(false); - + const elements = Array.from(container); useEffect(() => { document.body.classList.toggle("dark", isDarkMode); + elements.forEach((element) => { + element.classList.toggle("dark", isDarkMode); + }); }, [isDarkMode]); const toggleDarkMode = () => setIsDarkMode((prev) => !prev); diff --git a/src/style.css b/src/style.css index b50c7ae..c7228f9 100644 --- a/src/style.css +++ b/src/style.css @@ -13,7 +13,7 @@ .toggle-visible-btn { padding: 8px 16px; margin-bottom: 12px; - background-color: #6c757d; /* neutral gray */ + background-color: #6c757d; color: #fff; border: none; border-radius: 6px; @@ -29,15 +29,28 @@ .toggle-visible-btn:active { transform: translateY(0); -body { +} + +.container { background-color: white; color: black; transition: background-color 0.3s, color 0.3s; } + +.container.dark{ + background-color: black; + color: white; + transition: background-color 0.3s, color 0.3s; +} + +body { + background-color: white; + color: black; + transition: background-color 0.3s, color 0.3s; } body.dark{ background-color: black; color: white; transition: background-color 0.3s, color 0.3s; -} \ No newline at end of file +}