Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
b76e246
chore: initialize project structure
laxman-aqw Nov 13, 2025
ebb1252
refact/ updated the ItemList folder name to Item
laxman-aqw Nov 13, 2025
b20a3d2
refact/ removed package manager form package.json
laxman-aqw Nov 13, 2025
6fd619c
refact/ removed package manager form package.json
laxman-aqw Nov 13, 2025
d10ff0e
refact/ removed package manager form package.json
laxman-aqw Nov 13, 2025
fb781e8
feat/added counter
laxman-aqw Nov 13, 2025
bb8152a
refact/added classNames in button props
laxman-aqw Nov 13, 2025
9511c9d
refact/undo the deleted tags in app.jsx
laxman-aqw Nov 13, 2025
534d40c
refact/enhanced the styling with global font family
laxman-aqw Nov 13, 2025
4c0b900
refact/added removed semicolons
laxman-aqw Nov 13, 2025
1289025
refact/Addressed pr review changes
laxman-aqw Nov 13, 2025
6637855
WIP/ still working on it
laxman-aqw Nov 13, 2025
1fe996b
refact/updated counter to use localstorage to persist the count on re…
laxman-aqw Nov 13, 2025
e8754d6
refact/ enhanced the form styling using BEM
laxman-aqw Nov 13, 2025
b99ea41
refact/updated the useItems hook and css
laxman-aqw Nov 14, 2025
c246504
refact/removed unnecessary code
laxman-aqw Nov 14, 2025
b589b25
refact/updated the toggleTheme with custom hooks
laxman-aqw Nov 14, 2025
9c3d03c
refact/removed unnecessary codes
laxman-aqw Nov 17, 2025
94dd440
Merge branch '01-feat-structure' into laxman
laxman-aqw Nov 17, 2025
090bffc
Merge branch '02-feat-counter' into laxman
laxman-aqw Nov 17, 2025
ac7b177
Merge branch '03-feat-form' into laxman
laxman-aqw Nov 17, 2025
1af33e4
merged branches
laxman-aqw Nov 17, 2025
6f2b917
Merge branch '05-feat-toggle-theme' into laxman
laxman-aqw Nov 17, 2025
ee15de8
refactor/updated the dark mode togggle
laxman-aqw Nov 17, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,6 @@
"typescript": "~5.9.3",
"typescript-eslint": "^8.45.0",
"vite": "^7.1.7"
}
},
"packageManager": "pnpm@10.19.0+sha512.c9fc7236e92adf5c8af42fd5bf1612df99c2ceb62f27047032f4720b33f8eacdde311865e91c411f2774f618d82f320808ecb51718bfa82c060c4ba7c76a32b8"
}
143 changes: 21 additions & 122 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,128 +1,27 @@
import { useEffect, useRef, useState } from "react";
import Counter from "./components/Counter/Counter";
import UserForm from "./components/Form/UserForm/UserForm";
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 [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<string[]>([]);
const [selectedItem, setSelectedItem] = useState<string | null>(null);

const inputRef = useRef<HTMLInputElement>(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<HTMLInputElement>) => {
setName(e.target.value);
};

const handleEmailChange = (e: React.ChangeEvent<HTMLInputElement>) => {
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 (
<div>
<h1 className="text-2xl font-bold">Outside</h1>
<div>
<button onClick={increment}>Increment</button>
<button onClick={decrement}>Decrement</button>
<p>Count: {count}</p>
</div>
<form onSubmit={handleSubmit}>
<div>
<input
type="text"
value={name}
onChange={handleNameChange}
placeholder="Enter your name"
/>
<p>Name: {name}</p>
</div>
<div>
<input
type="email"
value={email}
onChange={handleEmailChange}
placeholder="Enter your email"
/>
<p>Email: {email}</p>
</div>
<div>
<div>
<button onClick={toggleVisibility}>
{isVisible ? "Hide" : "Show"} Items
</button>
{isVisible && (
<div>
<input type="text" ref={inputRef} placeholder="Add item" />
<button onClick={addItem}>Add Item</button>
<ul>
{items.map((item, index) => (
<li key={index} onClick={() => setSelectedItem(item)}>
{item}
</li>
))}
</ul>
</div>
)}
</div>
<div>
<p>Selected Item: {selectedItem}</p>
</div>
</div>
</form>
<div>
<button onClick={() => setIsDarkMode(!isDarkMode)}>
Toggle Dark Mode
</button>
<div className="container">
<Counter />
<UserForm/>
<div className="container items">
<Button className="toggle-visible-btn" value={isVisible ? "Hide" : "Show"} onClick={toggleVisibility}></Button>
{isVisible && (
<>
<AddItem addItem={addItem} inputValue={inputValue} setInputValue={setInputValue} />
<ItemList items={items} setSelectedItem={setSelectedItem}/>
</>
)}
</div>
<ThemeToggle/>
</div>
);
}
}
15 changes: 15 additions & 0 deletions src/components/Button/Button.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import type React from "react";

interface ButtonProps {
value: string;
onClick?: (event: React.MouseEvent<HTMLButtonElement>) => void;
className?:string;
}

const Button = ({ value, onClick, className }: ButtonProps) => {
return (
<button className={className} onClick={onClick}>{value}</button>
);
};

export default Button;
21 changes: 21 additions & 0 deletions src/components/Counter/Counter.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import Button from "../Button/Button";
import styles from "./style.module.css"
import { useCounter } from "../../hooks/useCounters";


const Counter = () => {
const { count, handleIncrement, handleDecrement } = useCounter();
return (
<div className='container'>
<section className={styles.background}>
<p className={styles.count}>COUNT: {count}</p>
<div className={styles.buttonSection}>
<Button className={styles.increment} value="Increment" onClick={handleIncrement} />
<Button className={styles.decrement} value="Decrement" onClick={handleDecrement} />
</div>
</section>
</div>
)
}

export default Counter
40 changes: 40 additions & 0 deletions src/components/Counter/style.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
.increment, .decrement{
background-color: rgb(32, 175, 32);
Copy link

@Aayush1011 Aayush1011 Nov 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a suggestion but it might be a better idea to use only rgb color or hex code everywhere as I noticed you're using both

padding: 15px 20px;
color: white;
border-radius: 12px;
border: none;
font-size: 15px;
font-weight: 700;
margin: 10px 10px;
cursor: pointer;
box-shadow:
1px 1px rgb(161, 161, 161),
-0.4em 0 0.4em rgb(155, 155, 154);
}

.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;
font-weight: 700;
}

.background{
/* background-color: rgb(217, 217, 218); */
padding: 10px 10px;
}

.buttonSection{
display: flex;
justify-content: center;
}
28 changes: 28 additions & 0 deletions src/components/Form/InputField/InputField.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import type React from "react";
import styles from "./style.module.css";

interface InputFieldProps {
label: string;
type: string;
value: string;
onChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
}

const InputField = ({ label, type, value, onChange }: InputFieldProps) => {
return (
<div className={styles["input-field"]}>
<label className={styles["input-field__label"]}>
{label.charAt(0).toUpperCase() + label.slice(1)}
</label>
Comment on lines +14 to +16

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can use css text-transform: capitalize here instead of capitalizing the first letter through js

<input
type={type}
value={value}
onChange={onChange}
placeholder={`Enter your ${label}`}
className={styles["input-field__input"]}
/>
</div>
);
};

export default InputField;
37 changes: 37 additions & 0 deletions src/components/Form/InputField/style.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
.input-field {
display: flex;
flex-direction: column;
margin-bottom: 16px;
width: 100%;
max-width: 400px;
margin: auto;
padding: 20px 20px;
}

.input-field__label {
font-weight: 600;
margin-bottom: 6px;
color: #333;
font-size: 14px;
}

.input-field__input {
padding: 8px 12px;
border: 1px solid #ccc;
border-radius: 6px;
font-size: 14px;
transition: border-color 0.2s, box-shadow 0.2s;
}

.input-field__input:focus {
outline: none;
border-color: #007bff;
box-shadow: 0 0 5px rgba(0, 123, 255, 0.5);
}

.input-field__value {
margin-top: 4px;
font-size: 12px;
color: #555;
font-style: italic;
}
Comment on lines +32 to +37

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this class and its associated properties appear to be unused

36 changes: 36 additions & 0 deletions src/components/Form/UserForm/UserForm.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import React, { useState } from 'react';
import InputField from '../InputField/InputField';
import useFormFields from '../../../hooks/useFormFields';
import Button from '../../Button/Button';
import styles from './style.module.css';

const UserForm = () => {
const { name, email, setName, setEmail } = useFormFields();
const [submittedName, setSubmittedName] = useState<string | null>(null);

const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
setSubmittedName(name);
setName('');
setEmail('');
};

return (
<div className='container '>
<div className={`${styles['user-form']} container`}>
<form className={`${styles['user-form__form']} container`} onSubmit={handleSubmit}>
<InputField label='name' type='text' value={name} onChange={(e) => setName(e.target.value)} />
<InputField label='email' type='text' value={email} onChange={(e) => setEmail(e.target.value)} />
<Button value="Submit" className={styles['user-form__button']} />
</form>
{submittedName && (
<p className={`${styles['user-form__welcome']} container`}>
Welcome, {submittedName}!
</p>
)}
</div>
</div>
);
};

export default UserForm;
50 changes: 50 additions & 0 deletions src/components/Form/UserForm/style.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
.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:30%;
margin: auto;
}

.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: black;
text-align: center;
}

.user-form__welcome .dark {
margin-top: 16px;
font-size: 16px;
font-weight: 500;
color: white;
text-align: center;;
}
Loading