Installation and Login Session
Install Node (node --version)
npx create-react-app my-app
cd my-app
npm start
Delete all file except index.html in public folder
Delete all file except index.js in src folder
Remove unwanted code in index.html and index.js
download template and then use this comment npm install for dependeies download then run npm start and npm run dev
Login Session
npm install react-router-dom
import React, { useState, useEffect } from 'react';
import { BrowserRouter as Router, Route, Routes, Navigate } from 'react-router-dom';
const mockUsers = [
{ username: "user1", password: "pass123" },
{ username: "user2", password: "secure456" },
{ username: "user3", password: "mypassword" }
];
const Login = ({ onLogin }) => {
const [username, setUsername] = useState('');
const [password, setPassword] = useState('');
const handleSubmit = (e) => {
e.preventDefault();
const user = mockUsers.find(u => u.username === username && u.password === password);
if (user) {
onLogin(user.username);
} else {
alert('Invalid credentials');
}
};
return (
<div>
<h2>Login</h2>
<form onSubmit={handleSubmit}>
<input type="text" placeholder="Username" value={username} onChange={(e) => setUsername(e.target.value)} required />
<input type="password" placeholder="Password" value={password} onChange={(e) => setPassword(e.target.value)} required />
<button type="submit">Login</button>
</form>
</div>
);
};
const Dashboard = ({ user, onLogout }) => {
useEffect(() => {
const timer = setTimeout(() => {
alert('Session expired. Logging out.');
onLogout();
}, 60000); // 1 minute session timeout
return () => clearTimeout(timer);
}, [onLogout]);
return (
<div>
<h2>Welcome, {user}!</h2>
<button onClick={onLogout}>Logout</button>
</div>
);
};
const App = () => {
const [user, setUser] = useState(() => {
return localStorage.getItem('user') || null;
});
useEffect(() => {
if (user) {
localStorage.setItem('user', user);
} else {
localStorage.removeItem('user');
}
}, [user]);
const handleLogin = (username) => {
setUser(username);
};
const handleLogout = () => {
setUser(null);
};
return (
<Router>
<div>
{user ? (
<Routes>
<Route path="/dashboard" element={<Dashboard user={user} onLogout={handleLogout} />} />
<Route path="/" element={<Navigate to="/dashboard" replace />} />
<Route path="/login" element={<Navigate to="/dashboard" replace />} />
</Routes>
) : (
<Routes>
<Route path="/login" element={<Login onLogin={handleLogin} />} />
<Route path="*" element={<Navigate to="/login" replace />} />
</Routes>
)}
</div>
</Router>
);
};
export default App;
Validation
const validation = () => {
let errors ={}
if(!username.trim()){
errors.username = "Username is required"
}
if(!password.trim()){
errors.password = "Password is required"
}
return errors
}
const handleSubmit = (e) => {
e.preventDefault();
const validationForm = validation()
if(Object.keys(validationForm).length > 0){
setErrors(validationForm)
} else {
//
}
};
{errors.username && <span className="errors ps-3">{errors.username}</span>}
toastify
npm install react-toastify
import React from "react";
import { ToastContainer, toast } from "react-toastify";
import "react-toastify/dist/ReactToastify.css";
const App = () => {
const showToast = () => {
toast.success("This is a success alert!");
toast.error("This is an error alert!");
toast.warning("This is a warning alert!");
toast.info("This is an info alert!");
};
return (
<div>
<h2>React Toast Alert Example</h2>
<button onClick={showToast}>Show Toast</button>
<ToastContainer position="top-right" autoClose={3000} />
</div>
);
};
export default App;
Menu - Navigation, Link, Active Class,...
npm install react-router-dom
import React from 'react';
import { Link, useLocation, useNavigate } from "react-router-dom";
const Header = () => {
const location = useLocation(); // Get current path
const navigate = useNavigate(); // Hook for navigation
// Function to handle navigation and set active class
const handleNavigation = (path) => {
navigate('./page2'); // Navigate to selected path
};
const isCreatePage = location.pathname.includes('/create'); // Check if '/create' is in the path
return (
<div className="header-wrapper">
<div className="nav-bar p-2">
<ul type="none">
<li className={location.pathname === "/" ? "active" : ""} onClick={() => handleNavigation("/")}>
<Link to="/">Home</Link>
</li>
<li className={location.pathname === "/page2" ? "active" : ""} onClick={() => handleNavigation("/page2")}>
<Link to="/page2">Page 2</Link>
</li>
</ul>
</div>
</div>
);
};
export default Header;
Tooltip
import React from 'react';
import { Tooltip, OverlayTrigger, Button } from 'react-bootstrap';
const TooltipExample = () => {
return (
<div className="d-flex justify-content-center align-items-center" style={{ height: '100vh' }}>
<OverlayTrigger
placement="top"
overlay={<Tooltip id="tooltip-top">This is a tooltip!</Tooltip>}
>
<Button variant="primary">Hover me!</Button>
</OverlayTrigger>
</div>
);
};
export default TooltipExample;
ENV - Environment Variables
.env (root path, package.json file folder)
REACT_APP_API_URL= https://67cd5231dd7651e464ee0981.mockapi.io/Gobudget/
const apiUrl = process.env.REACT_APP_API_URL;
<h2>Welcome, {apiUrl}</h2>
//server restart
Axios
import axios from 'axios';
//
useEffect(() => {
axios.get(`${process.env.REACT_APP_API_URL}Category`)
.then(response => {
setCategoryData(response.data);
})
.catch(error => {
console.error('Error fetching data: ', error);
});
}, []);
// Image file also sent
axios.post(url, editRowData, {
headers: {
'Content-Type': 'multipart/form-data',
},
})
.then(response => {
console.log('File successfully uploaded:', response.data);
onDataReceived(false);
window.location.reload();
})
.catch(error => {
console.error('Error uploading file:', error);
});
Create Form
import React, { useState, useEffect } from 'react';
import { Row, Col, FloatingLabel, Tooltip, OverlayTrigger,
Form, Dropdown, DropdownButton,
Button, ButtonGroup, Modal } from 'react-bootstrap';
import axios from 'axios';
import { toast, ToastContainer } from "react-toastify";
import "react-toastify/dist/ReactToastify.css";
import category1Icon from '../../dist/images/icons/categories/1.png'
import category2Icon from '../../dist/images/icons/categories/2.png'
import category3Icon from '../../dist/images/icons/categories/3.png'
import category4Icon from '../../dist/images/icons/categories/4.png'
import category5Icon from '../../dist/images/icons/categories/5.png'
import category6Icon from '../../dist/images/icons/categories/6.png'
import category7Icon from '../../dist/images/icons/categories/7.png'
import category8Icon from '../../dist/images/icons/categories/8.png'
import category9Icon from '../../dist/images/icons/categories/9.png'
const App = () => {
const apiUrl = process.env.REACT_APP_API_URL;
const [addShow, setAddShow] = useState(true);
const handleAddClose = () => onCloseFrom();
const handleAddShow = () => setAddShow(true);
const onCloseFrom = () => {
setCategoryName("");
setCategoryIcon("");
setCategoryType("");
setError({});
setAddShow(false)
}
const [categoryName, setCategoryName] = useState("");
const [CategoryIcon, setCategoryIcon] = useState("");
const [CategoryType, setCategoryType] = useState("1");
const [error, setError] = useState({});
const categoryIcons = {
1: category1Icon,
2: category2Icon,
3: category3Icon,
4: category4Icon,
5: category5Icon,
6: category6Icon,
7: category7Icon,
8: category8Icon,
9: category9Icon,
};
const FormSuccess = () =>
toast.success("Successfully logged in", {
onClose: () => {},
});
const validation = () => {
const newError = {};
if (!categoryName.trim()) {
newError.categoryName = "Category Name is required";
}
if (!CategoryIcon) {
newError.CategoryIcon = "Category Icon is required";
}
if (!CategoryType) {
newError.CategoryType = "Category Type is required";
}
return newError;
};
const handleCreateTemplateSubmit = async (e) => {
e.preventDefault();
const validationForm = validation();
if (Object.keys(validationForm).length > 0) {
setError(validationForm);
} else {
const formData = {
Category: categoryName,
Category_img_id: CategoryIcon,
Category_type: CategoryType,
};
axios
.post(`${apiUrl}/Category/`, formData)
.then((response) => {
onCloseFrom()
toast.success("Category Created")
})
.catch((error) => {
console.error("Error submitting form:", error, `${process.env.REACT_APP_API}/Category/`, formData);
});
}
};
return (
<>
<Modal show={addShow} size="lg" onHide={handleAddClose} animation={false} centered>
<Modal.Body>
<form onSubmit={handleCreateTemplateSubmit} className="bgWhite p-4" id="myForm">
<Row>
<Col xs={12}>
<h4 className="fw-bold mb-5">Create Category</h4>
<Form.Group className="mb-4 " controlId="floatingInput">
<div className="frm-group">
<Form.Label>Category name</Form.Label>
<Form.Control
type="text"
placeholder="Template *"
onChange={(e) => {setCategoryName(e.target.value); error.categoryName = ''}}
value={categoryName}
/>
</div>
{error.categoryName && <p className="errors mt-2">{error.categoryName}</p>}
</Form.Group>
{/* Radio Buttons with Images */}
<Form.Group className="mb-4">
<div className="frm-group">
<Form.Label>Category Icon</Form.Label>
<div className="d-flex gap-3">
{Object.entries(categoryIcons)?.map(([id, icon]) => (
<Form.Check type="radio" className="radio-image">
<Form.Check.Input
type="radio"
name="radioGroup"
value={id}
checked={CategoryIcon === id}
onChange={(e) => {setCategoryIcon(e.target.value); error.CategoryIcon = ''}}
/>
<Form.Check.Label>
<img
src={icon} // Replace with actual image URL
alt={id}
className="radio-img"
/>
</Form.Check.Label>
</Form.Check>
))}
</div>
</div>
{error.CategoryIcon && <p className="errors mt-2">{error.CategoryIcon}</p>}
</Form.Group>
{/* Dropdown */}
<Form.Group className="mb-4">
<div className="frm-group">
<Form.Label>Type</Form.Label>
<Form.Select
aria-label="Default select example"
className="form-control"
value={CategoryType || "Select an option"} // Ensure CategoryType is defined, or use default value
onChange={(e) => setCategoryType(e.target.value)} // Changed onSelect to onChange
>
<option value="1">Income</option>
<option value="2">Expense</option>
</Form.Select>
</div>
{error.CategoryType && <p className="error-msg">{error.CategoryType}</p>}
</Form.Group>
<Col md="auto" className="text-end">
<button type="submit" className="btn-green my-3">
Save
</button>
</Col>
</Col>
</Row>
</form>
</Modal.Body>
</Modal>
</>
);
};
export default App;
Delete data
const [showDeleteMsgPopup, setShowDeleteMsgPopup] = useState(false);
const [dataDeleteId, setDataDeleteId,] = useState(null);
onClick={() => handleDeleteTemplate(data.id)}
const handleDeleteTemplate = (deleteId) => {
setShowDeleteMsgPopup(true);
const deleteID = deleteId;
setDataDeleteId(deleteID)
console.log(deleteID);
};
const handleProposalDeleteCancelled = () => {
setShowDeleteMsgPopup(false);
}
const handleProposalDeleteConfirmed = () => {
setShowDeleteMsgPopup(false);
console.log('Delete', dataDeleteId);
axios.delete(`${process.env.REACT_APP_API}proposal/template_management/${dataDeleteId}/`)
.then(response => {
console.log('Deleted');
setDataDeleteId(null)
if(response.data.status === "GD_02") {
toast.error(response.data.message);
} else {
toast.success(response.data.message);
fetchData()
}
})
.catch(error => {
console.log('Delete Data Error', error);
});
}
<Modal show={showDeleteMsgPopup} onHide={handleProposalDeleteCancelled}>
<Modal.Body closeButton><h4>Are you sure to delete this Data</h4></Modal.Body>
<Modal.Footer>
<button className="btn-green-2" onClick={handleProposalDeleteCancelled}>
Cancel
</button>
<button className="btn-green ms-3" onClick={handleProposalDeleteConfirmed}>
Delete
</button>
</Modal.Footer>
</Modal>
Edit data
import { useLocation, useParams, useNavigate } from 'react-router-dom';
const apiUrl = process.env.REACT_APP_API_URL;
const location = useLocation();
const navigate = useNavigate();
const {id} = useParams()
const isCreatePage = location.pathname.includes('/create');
const [editId, setEditId] = useState(null)
useEffect(() => {
if(id){
setEditId(id)
}
}, [id])
useEffect(() => {
if(isCreatePage || editId){
setAddShow(true)
}
if(editId){
fetchEditData()
}
}, [isCreatePage, editId])
const fetchEditData = () => {
axios.get(`${apiUrl}Category/${editId}`)
.then(response => {
// console.log(response.data);
const data = response.data;
setCategoryName(data.Category)
setCategoryIcon(data.Category_img_id)
setCategoryType(data.Category_type)
})
.catch(error => {
console.error('Error fetching data: ', error,);
});
}
const validation = () => {
const newError = {};
if (!categoryName.trim()) {
newError.categoryName = "Category Name is required";
}
if (!CategoryIcon) {
newError.CategoryIcon = "Category Icon is required";
}
if (!CategoryType) {
newError.CategoryType = "Category Type is required";
}
return newError;
};
const handleCreateTemplateSubmit = async (e) => {
e.preventDefault();
const validationForm = validation();
if (Object.keys(validationForm).length > 0) {
setError(validationForm);
} else {
const formData = {
Category: categoryName,
Category_img_id: CategoryIcon,
Category_type: CategoryType,
};
let sendApi = `${apiUrl}/Category/`
if (editId) {
sendApi = `${apiUrl}/Category/${editId}`
}
const method = editId ? 'put' : 'post';
axios({
method: method,
url: sendApi,
data: formData,
})
.then((response) => {
onCloseFrom()
toast.success("Category Data Submitted")
})
.catch((error) => {
console.error("Error submitting form:", error, `${process.env.REACT_APP_API}/Category/`, formData);
});
}
};
Data Grid
import React from "react";
import DataTable from "react-data-table-component";
// Sample data
const data = [
{ id: 1, name: "John Doe", age: 28, email: "john@example.com" },
{ id: 2, name: "Jane Smith", age: 34, email: "jane@example.com" },
{ id: 3, name: "Sam Green", age: 25, email: "sam@example.com" },
];
// Define columns
const columns = [
{
name: "ID",
selector: (row) => row.id,
sortable: true,
},
{
name: "Name",
selector: (row) => row.name,
sortable: true,
},
{
name: "Age",
selector: (row) => row.age,
sortable: true,
},
{
name: "Email",
selector: (row) => row.email,
// Example of adding HTML inside the cell
cell: (row) => (
<a href={`mailto:${row.email}`} dangerouslySetInnerHTML={{ __html: `<span style="color: blue;">${row.email}</span>` }} />
),
},
{
name: "Actions",
cell: (_, index) => (
<button
// onClick={() => handleDelete(index)}
style={{
backgroundColor: "red",
color: "white",
border: "none",
padding: "5px 10px",
cursor: "pointer",
}}
>
Delete
</button>
),
},
];
const MyDataTable = () => {
return (
<div>
<h2>My Data Table</h2>
<DataTable
columns={columns}
data={data}
pagination
highlightOnHover
/>
</div>
);
};
export default MyDataTable;
Date picker
npm install react-datepicker
npm install date-fns
import React, { useState } from "react";
import DatePicker from "react-datepicker";
import "react-datepicker/dist/react-datepicker.css"; // Import styles for the date picker
const SimpleDatePicker = () => {
const [selectedDate, setSelectedDate] = useState(null);
const handleDateChange = (date) => {
setSelectedDate(date);
};
return (
<div>
<h2>Select a Date</h2>
<DatePicker
selected={selectedDate}
onChange={handleDateChange}
dateFormat="MM/dd/yyyy" // Set the format of the date
placeholderText="Select a date"
/>
</div>
);
};
export default SimpleDatePicker;
Datapicker format changes
import DatePicker from 'react-datepicker';
import { parse, format } from 'date-fns';
const start_time : Fri Dec 27 2024 14:00:00 GMT+0530 (India Standard Time)
const formatTime = (time) => {
return new Date(time).toLocaleTimeString('en-GB', { hour: '2-digit', minute: '2-digit' });
};
const formattime = formatTime(start_time) // method 1 start_time : "14:00"
format(start_time, "hh:mm aa") // method 2 start_time : "2:00 PM"
const start_date : Mon Dec 02 2024 00:00:00 GMT+0530 (India Standard Time)
const formatDateToYYYYMMDD = (date) => {
if (!date) return ''; // handle empty or invalid date
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0'); // Months are 0-based, so add 1
const day = String(date.getDate()).padStart(2, '0');
return `${year}-${month}-${day}`;
};
const formatDate = formatDateToYYYYMMDD(start_date) // method 1 start_date: "2024-12-02"
format(start_date, "yyyy-MM-dd") // method 2 start_date: "2024-12-02"
const start_time = 09:00:00
const convertTimeToDate = (timeString) => {
const currentDate = new Date();
const [hours, minutes, seconds ] = timeString.split(":");
currentDate.setHours(hours);
currentDate.setMinutes(minutes);
currentDate.setSeconds(seconds);
return currentDate;
}
const formatTime = convertTimeToDate(start_time) // method 1 start_time : Fri Dec 27 2024 09:00:00 GMT+0530 (India Standard Time)
start_date = 11-Dec-2024
new Date(start_date)
const [time, setTime] = useState("2:00 PM");
const [formattedTime, setFormattedTime] = useState("");
const handleConvertTime = () => {
// Parse the input time and format it
const parsedDate = parse(time, "h:mm a", new Date());
const formatted = format(parsedDate, "EEE MMM dd yyyy HH:mm:ss 'GMT'xxx (zzzz)");
setFormattedTime(formatted);
};
Image upload with preview
import React, { useState } from 'react';
import { Button, Form, Image } from 'react-bootstrap';
const FileUploadWithPreview = () => {
const [selectedFile, setSelectedFile] = useState(null);
const [preview, setPreview] = useState(null);
const handleFileChange = (event) => {
const file = event.target.files[0];
if (file) {
setSelectedFile(file);
const objectUrl = URL.createObjectURL(file); // Create object URL for preview
setPreview(objectUrl);
}
};
const handleRemovePreview = () => {
setSelectedFile(null);
setPreview(null);
};
return (
<div>
<Form>
<Form.Group controlId="fileUpload">
<Form.Label>Upload File</Form.Label>
<Form.Control
type="file"
onChange={handleFileChange}
accept="image/*" // Only accept images
/>
</Form.Group>
</Form>
{preview && (
<div className="mt-3">
<h5>Preview:</h5>
<Image
src={preview}
alt="Preview"
style={{ width: '200px', height: 'auto' }}
thumbnail
/>
<Button variant="danger" className="mt-2" onClick={handleRemovePreview}>
Remove Preview
</Button>
</div>
)}
</div>
);
};
export default FileUploadWithPreview;
Search
import React, { useState } from "react";
const objectiveLevels = [
{ id: 1, value: "Organization" },
{ id: 2, value: "Organization Unit" },
{ id: 3, value: "Business Unit" },
{ id: 4, value: "Department" },
{ id: 5, value: "Position" },
{ id: 6, value: "Personal" },
];
const ObjectiveSearchQuery = () => {
const [searchQuery, setSearchQuery] = useState("");
// Filter the objectiveLevels based on searchQuery input
const filteredObjectives = objectiveLevels.filter((item) =>
item.value.toLowerCase().includes(searchQuery.toLowerCase())
);
return (
<div className="p-4">
<input
type="text"
placeholder="Search..."
className="border p-2 rounded w-full"
value={searchQuery}
onChange={(e) => setSearchQuery(e.target.value)}
/>
<ul className="mt-4">
{filteredObjectives.length > 0 ? (
filteredObjectives.map((item) => (
<li key={item.id} className="p-2 border-b">
{item.value}
</li>
))
) : (
<li className="p-2 text-gray-500">No results found</li>
)}
</ul>
</div>
);
};
export default ObjectiveSearchQuery;
Number input and e.prevent
onChange={(e) => {
const numValue = e.target.value.replace(/\D/g, "")
handleCurrencyParamsChanges('amount2', numValue ? parseInt(numValue) : '', item.field_name)}
}
//stopping a form from submitting or preventing a link from navigating
e.preventDefault()
//triggering handlers on parent elements
e.stopPropagation()
//e.key (for Keyboard Events)
if (e.key === "Enter") {
console.log("Enter key pressed!");
}
React Router (Passing Data via State)
//PageOne.js
import React from "react";
import { useNavigate } from "react-router-dom";
const PageOne = () => {
const navigate = useNavigate();
const handleNavigate = () => {
navigate("/page-two", { state: { message: "Hello from Page One!" } });
};
return <button onClick={handleNavigate}>Go to Page Two</button>;
};
export default PageOne;
//PageTwo.js
import React from "react";
import { useLocation } from "react-router-dom";
const PageTwo = () => {
const location = useLocation();
const { message } = location.state || {};
return <p>Message: {message}</p>;
};
export default PageTwo;
Props (Passing Data)
<img src={editIcon} onClick={() => handleNewSubtaskChange(data.sub_task_id)}/>
---
const handleNewSubtaskChange = (subTaskId) =>{
CreateSubtask(true); ///-- Edit
setShowNewFormPopup(true);
setPassDataToSubTask({
task_id: viewTaskId,
project_id: projectId,
stage_id: stageId,
edit_id: subTaskId
});
}
---
<div className={`CreatePopupDsn ${showNewFormPopup ? 'show' : ''}`}>
<button type="button" className="popup-close btn btn-primary"
onClick={handleShowNewFormPopup}
></button>
<TaskCreateSubTask passDataToSubTask={passDataToSubTask} />
</div>
---
function TaskCreateSubTask({onDataReceived, passDataToSubTask}) {
useEffect(() => {
if(passDataToSubTask) {
console.log("subtaskValue",passDataToSubTask, passDataToSubTask.project_id)
setProjectValue(passDataToSubTask.project_id);
}
}, [passDataToSubTask]);
-----
function ChildTask({onDataReceived, viewTaskID}) {
onDataReceived(false);
-----
<ChildTask
onDataReceived={handleDataFromChild}
viewTaskID={viewTaskID}
/>
const handleDataFromChild = () => {
setNewTaskPopupForm(false);
setViewTaskID(null);
getProjectData()
};
Date Filter with Monthly, Weekly, and Daily Views
import React, { useState, useEffect } from 'react';
import DatePicker from 'react-datepicker';
import 'react-datepicker/dist/react-datepicker.css';
import { format, addDays, subDays, addMonths, subMonths, startOfMonth, endOfMonth } from 'date-fns';
import { Dropdown } from "react-bootstrap";
const App = () => {
const [dateRangePicker, setDateRangePicker] = useState('Monthly');
const [startDatePicker, setStartDatePicker] = useState(startOfMonth(new Date()));
const [endDatePicker, setEndDatePicker] = useState(endOfMonth(new Date()));
const handlePrev = () => {
if (dateRangePicker === "Day") {
setStartDatePicker(prev => subDays(prev, 1));
setEndDatePicker(prev => subDays(prev, 1));
} else if (dateRangePicker === "Week") {
setStartDatePicker(prev => subDays(prev, 7));
setEndDatePicker(prev => subDays(prev, 7));
} else if (dateRangePicker === "Monthly") {
setStartDatePicker(prev => startOfMonth(subMonths(prev, 1)));
setEndDatePicker(prev => endOfMonth(subMonths(prev, 1)));
}
};
const handleNext = () => {
if (dateRangePicker === "Day") {
setStartDatePicker(prev => addDays(prev, 1));
setEndDatePicker(prev => addDays(prev, 1));
} else if (dateRangePicker === "Week") {
setStartDatePicker(prev => addDays(prev, 7));
setEndDatePicker(prev => addDays(prev, 7));
} else if (dateRangePicker === "Monthly") {
setStartDatePicker(prev => startOfMonth(addMonths(prev, 1)));
setEndDatePicker(prev => endOfMonth(addMonths(prev, 1)));
}
};
const handleDateChange = dateOrDates => {
if (dateRangePicker === "Monthly") {
setStartDatePicker(startOfMonth(dateOrDates));
setEndDatePicker(endOfMonth(dateOrDates));
} else if (Array.isArray(dateOrDates)) {
const [start, end] = dateOrDates;
setStartDatePicker(start);
setEndDatePicker(end);
} else {
setStartDatePicker(dateOrDates);
setEndDatePicker(addDays(dateOrDates, 1));
}
};
const handleDateRange = (e, dateRangeId) => {
setDateRangePicker(dateRangeId);
if (dateRangeId === "Day") {
setStartDatePicker(new Date());
setEndDatePicker(addDays(new Date(), 1));
} else if (dateRangeId === "Week") {
const today = new Date();
const startDate = subDays(today, today.getDay());
const endDate = addDays(startDate, 6);
setStartDatePicker(startDate);
setEndDatePicker(endDate);
} else if (dateRangeId === "Monthly") {
setStartDatePicker(startOfMonth(new Date()));
setEndDatePicker(endOfMonth(new Date()));
}
};
return (
<div>
<div className='d-flex align-items-center justify-content-center'>
<div className={`d-flex align-items-center justify-content-center gap-10 ${dateRangePicker === "Monthly" ? "month-picker" : ''}`}>
<button className='left-arrow' onClick={handlePrev}></button>
{dateRangePicker === "Monthly" && <span>{format(startDatePicker, 'MMM yyyy')}</span>}
<DatePicker
selected={startDatePicker}
onChange={handleDateChange}
startDate={startDatePicker}
endDate={dateRangePicker === "Week" || dateRangePicker === "Monthly" ? endDatePicker : ''}
selectsRange={dateRangePicker === "Week"}
dateFormat={dateRangePicker === "Week" ? "dd-MM-yyyy" : dateRangePicker === "Monthly" ? "MMM-yyyy" : "dd-MMM-yyyy"}
showMonthYearPicker={dateRangePicker === "Monthly"}
/>
<button className='right-arrow' onClick={handleNext}></button>
<Dropdown className="sortDsn borRight">
<Dropdown.Toggle id="dropdown-basic" className="fz-15px py-0">
{dateRangePicker}
</Dropdown.Toggle>
<Dropdown.Menu>
<Dropdown.Item onClick={(e) => handleDateRange(e, 'Monthly')}>Monthly</Dropdown.Item>
<Dropdown.Item onClick={(e) => handleDateRange(e, 'Week')}>Week</Dropdown.Item>
<Dropdown.Item onClick={(e) => handleDateRange(e, 'Day')}>Day</Dropdown.Item>
</Dropdown.Menu>
</Dropdown>
{startDatePicker ? format(startDatePicker, "yyyy-MM-dd") : ""} to {endDatePicker ? format(endDatePicker, "yyyy-MM-dd") : ""}
</div>
</div>
</div>
);
};
export default App;
Added Year and Quarterly
import React, { useState } from 'react';
import DatePicker from 'react-datepicker';
import 'react-datepicker/dist/react-datepicker.css';
import { format, addDays, subDays, addMonths, subMonths, startOfMonth, endOfMonth, startOfYear, endOfYear, addYears, subYears, startOfQuarter, endOfQuarter } from 'date-fns';
import { Dropdown } from "react-bootstrap";
const Records = () => {
const [dateRangePicker, setDateRangePicker] = useState('Monthly');
const [startDatePicker, setStartDatePicker] = useState(startOfMonth(new Date()));
const [endDatePicker, setEndDatePicker] = useState(endOfMonth(new Date()));
const handlePrev = () => {
if (dateRangePicker === "Day") {
setStartDatePicker(prev => subDays(prev, 1));
setEndDatePicker(prev => subDays(prev, 1));
} else if (dateRangePicker === "Week") {
setStartDatePicker(prev => subDays(prev, 7));
setEndDatePicker(prev => subDays(prev, 7));
} else if (dateRangePicker === "Monthly") {
setStartDatePicker(prev => startOfMonth(subMonths(prev, 1)));
setEndDatePicker(prev => endOfMonth(subMonths(prev, 1)));
} else if (dateRangePicker === "Yearly") {
setStartDatePicker(prev => startOfYear(subYears(prev, 1)));
setEndDatePicker(prev => endOfYear(subYears(prev, 1)));
} else if (dateRangePicker === "Quarterly") {
setStartDatePicker(prev => startOfQuarter(subMonths(prev, 3)));
setEndDatePicker(prev => endOfQuarter(subMonths(prev, 3)));
}
};
const handleNext = () => {
if (dateRangePicker === "Day") {
setStartDatePicker(prev => addDays(prev, 1));
setEndDatePicker(prev => addDays(prev, 1));
} else if (dateRangePicker === "Week") {
setStartDatePicker(prev => addDays(prev, 7));
setEndDatePicker(prev => addDays(prev, 7));
} else if (dateRangePicker === "Monthly") {
setStartDatePicker(prev => startOfMonth(addMonths(prev, 1)));
setEndDatePicker(prev => endOfMonth(addMonths(prev, 1)));
} else if (dateRangePicker === "Yearly") {
setStartDatePicker(prev => startOfYear(addYears(prev, 1)));
setEndDatePicker(prev => endOfYear(addYears(prev, 1)));
} else if (dateRangePicker === "Quarterly") {
setStartDatePicker(prev => startOfQuarter(addMonths(prev, 3)));
setEndDatePicker(prev => endOfQuarter(addMonths(prev, 3)));
}
};
const handleDateChange = dateOrDates => {
if (dateRangePicker === "Monthly") {
setStartDatePicker(startOfMonth(dateOrDates));
setEndDatePicker(endOfMonth(dateOrDates));
} else if (dateRangePicker === "Yearly") {
setStartDatePicker(startOfYear(dateOrDates));
setEndDatePicker(endOfYear(dateOrDates));
} else if (dateRangePicker === "Quarterly") {
setStartDatePicker(startOfQuarter(dateOrDates));
setEndDatePicker(endOfQuarter(dateOrDates));
} else if (Array.isArray(dateOrDates)) {
const [start, end] = dateOrDates;
setStartDatePicker(start);
setEndDatePicker(end);
} else {
setStartDatePicker(dateOrDates);
setEndDatePicker(addDays(dateOrDates, 1));
}
};
const handleDateRange = (e, dateRangeId) => {
setDateRangePicker(dateRangeId);
const today = new Date();
if (dateRangeId === "Day") {
setStartDatePicker(today);
setEndDatePicker(addDays(today, 1));
} else if (dateRangeId === "Week") {
const startDate = subDays(today, today.getDay());
const endDate = addDays(startDate, 6);
setStartDatePicker(startDate);
setEndDatePicker(endDate);
} else if (dateRangeId === "Monthly") {
setStartDatePicker(startOfMonth(today));
setEndDatePicker(endOfMonth(today));
} else if (dateRangeId === "Yearly") {
setStartDatePicker(startOfYear(today));
setEndDatePicker(endOfYear(today));
} else if (dateRangeId === "Quarterly") {
setStartDatePicker(startOfQuarter(today));
setEndDatePicker(endOfQuarter(today));
}
};
return (
<div>
<br /><br /><br />
<div className='d-flex align-items-center justify-content-center'>
<div className={`d-flex align-items-center justify-content-center gap-10 ${dateRangePicker === "Monthly" ? "month-picker" : ''}`}>
<button className='left-arrow' onClick={handlePrev}></button>
{dateRangePicker === "Monthly" && <span>{format(startDatePicker, 'MMM yyyy')}</span>}
{dateRangePicker === "Yearly" && <span>{format(startDatePicker, 'yyyy')}</span>}
{dateRangePicker === "Quarterly" && <span>{`Q${Math.ceil((startDatePicker.getMonth() + 1) / 3)} ${format(startDatePicker, 'yyyy')}`}</span>}
<DatePicker
selected={startDatePicker}
onChange={handleDateChange}
startDate={startDatePicker}
endDate={dateRangePicker === "Week" || dateRangePicker === "Monthly" || dateRangePicker === "Yearly" || dateRangePicker === "Quarterly" ? endDatePicker : ''}
selectsRange={dateRangePicker === "Week"}
dateFormat={dateRangePicker === "Yearly" ? "yyyy" : dateRangePicker === "Monthly" ? "MMM-yyyy" : dateRangePicker === "Quarterly" ? "MMM-yyyy" : "dd-MMM-yyyy"}
showMonthYearPicker={dateRangePicker === "Monthly" || dateRangePicker === "Quarterly"}
showYearPicker={dateRangePicker === "Yearly"}
/>
<button className='right-arrow' onClick={handleNext}></button>
<Dropdown className="sortDsn borRight">
<Dropdown.Toggle id="dropdown-basic" className="fz-15px py-0">
{dateRangePicker}
</Dropdown.Toggle>
<Dropdown.Menu>
<Dropdown.Item onClick={(e) => handleDateRange(e, 'Monthly')}>Monthly</Dropdown.Item>
<Dropdown.Item onClick={(e) => handleDateRange(e, 'Week')}>Week</Dropdown.Item>
<Dropdown.Item onClick={(e) => handleDateRange(e, 'Day')}>Day</Dropdown.Item>
<Dropdown.Item onClick={(e) => handleDateRange(e, 'Yearly')}>Yearly</Dropdown.Item>
<Dropdown.Item onClick={(e) => handleDateRange(e, 'Quarterly')}>Quarterly</Dropdown.Item>
</Dropdown.Menu>
</Dropdown>
{startDatePicker ? format(startDatePicker, "yyyy-MM-dd") : ""} to {endDatePicker ? format(endDatePicker, "yyyy-MM-dd") : ""}
</div>
</div>
</div>
);
};
export default Records;
Added Year and Quarterly
import React, { useState, useEffect } from 'react';
import DatePicker from 'react-datepicker';
import 'react-datepicker/dist/react-datepicker.css';
import { format, addDays, subDays, addMonths, subMonths, startOfMonth, endOfMonth, startOfYear, endOfYear, addYears, subYears, startOfQuarter, endOfQuarter } from 'date-fns';
import { Dropdown } from "react-bootstrap";
const Records = () => {
const [dateRangePicker, setDateRangePicker] = useState('Yearly');
const [startDatePicker, setStartDatePicker] = useState(startOfMonth(new Date()));
const [endDatePicker, setEndDatePicker] = useState(endOfMonth(new Date()));
const [selectedYear, setSelectedYear]= useState(new Date())
const [dateRangeLimits, setDateRangeLimits]= useState({
start_date : '',
end_date: ''
})
const handlePrev = () => {
if (dateRangePicker === "Day") {
setStartDatePicker(prev => subDays(prev, 1));
setEndDatePicker(prev => subDays(prev, 1));
} else if (dateRangePicker === "Custom") {
setStartDatePicker(prev => subDays(prev, 7));
setEndDatePicker(prev => subDays(prev, 7));
} else if (dateRangePicker === "Monthly") {
setStartDatePicker(prev => startOfMonth(subMonths(prev, 1)));
setEndDatePicker(prev => endOfMonth(subMonths(prev, 1)));
} else if (dateRangePicker === "Yearly") {
setStartDatePicker(prev => startOfYear(subYears(prev, 1)));
setEndDatePicker(prev => endOfYear(subYears(prev, 1)));
} else if (dateRangePicker === "Quarterly") {
setStartDatePicker(prev => startOfQuarter(subMonths(prev, 3)));
setEndDatePicker(prev => endOfQuarter(subMonths(prev, 3)));
}
};
const handleNext = () => {
if (dateRangePicker === "Day") {
setStartDatePicker(prev => addDays(prev, 1));
setEndDatePicker(prev => addDays(prev, 1));
} else if (dateRangePicker === "Custom") {
setStartDatePicker(prev => addDays(prev, 7));
setEndDatePicker(prev => addDays(prev, 7));
} else if (dateRangePicker === "Monthly") {
setStartDatePicker(prev => startOfMonth(addMonths(prev, 1)));
setEndDatePicker(prev => endOfMonth(addMonths(prev, 1)));
} else if (dateRangePicker === "Yearly") {
setStartDatePicker(prev => startOfYear(addYears(prev, 1)));
setEndDatePicker(prev => endOfYear(addYears(prev, 1)));
} else if (dateRangePicker === "Quarterly") {
setStartDatePicker(prev => startOfQuarter(addMonths(prev, 3)));
setEndDatePicker(prev => endOfQuarter(addMonths(prev, 3)));
}
};
const handleDateChange = dateOrDates => {
if (dateRangePicker === "Monthly") {
setStartDatePicker(startOfMonth(dateOrDates));
setEndDatePicker(endOfMonth(dateOrDates));
} else if (dateRangePicker === "Yearly") {
setStartDatePicker(startOfYear(dateOrDates));
setEndDatePicker(endOfYear(dateOrDates));
} else if (dateRangePicker === "Quarterly") {
setStartDatePicker(startOfQuarter(dateOrDates));
setEndDatePicker(endOfQuarter(dateOrDates));
} else if (Array.isArray(dateOrDates)) {
const [start, end] = dateOrDates;
setStartDatePicker(start);
setEndDatePicker(end);
} else {
setStartDatePicker(dateOrDates);
setEndDatePicker(addDays(dateOrDates, 1));
}
};
const handleDateRange = (e, dateRangeId) => {
setDateRangePicker(dateRangeId);
const today = new Date(selectedYear);
if (dateRangeId === "Day") {
setStartDatePicker(today);
setEndDatePicker(addDays(today, 1));
} else if (dateRangeId === "Custom") {
const startDate = subDays(today, today.getDay());
const endDate = addDays(startDate, 6);
setStartDatePicker(startDate);
setEndDatePicker(endDate);
} else if (dateRangeId === "Monthly") {
setStartDatePicker(startOfMonth(today));
setEndDatePicker(endOfMonth(today));
} else if (dateRangeId === "Yearly") {
setStartDatePicker(startOfYear(today));
setEndDatePicker(endOfYear(today));
} else if (dateRangeId === "Quarterly") {
setStartDatePicker(startOfQuarter(today));
setEndDatePicker(endOfQuarter(today));
}
};
const handleYearChange = (date) => {
setSelectedYear(date);
};
useEffect(()=>{
const end = new Date(selectedYear.getFullYear(), 11, 31);
setDateRangeLimits({
start_date : new Date(selectedYear.getFullYear(), 0, 1),
end_date: end,
});
setDateRangePicker("Yearly")
setStartDatePicker(startOfYear(selectedYear));
setEndDatePicker(endOfYear(selectedYear));
},[selectedYear])
return (
<div>
<div className='d-flex align-items-center justify-content-center'>
<div className={`d-flex align-items-center justify-content-center gap-10 ${dateRangePicker === "Monthly" ? "month-picker" : ''}`}>
<button className='left-arrow' onClick={handlePrev}><</button>
<DatePicker
selected={startDatePicker}
onChange={handleDateChange}
startDate={startDatePicker}
endDate={dateRangePicker === "Custom" || dateRangePicker === "Monthly" || dateRangePicker === "Yearly" || dateRangePicker === "Quarterly" ? endDatePicker : ''}
selectsRange={dateRangePicker === "Custom"}
dateFormat={dateRangePicker === "Yearly" ? "yyyy" : dateRangePicker === "Monthly" ? "MMM-yyyy" : dateRangePicker === "Quarterly" ? "yyyy, QQQ" : "dd-MMM-yyyy"}
showMonthYearPicker={dateRangePicker === "Monthly"}
showQuarterYearPicker={dateRangePicker === "Quarterly"}
disabled={dateRangePicker === "Yearly"}
minDate={dateRangeLimits.start_date}
maxDate={dateRangeLimits.end_date}
/>
<button className='right-arrow' onClick={handleNext}>></button>
<Dropdown className="sortDsn borRight">
<Dropdown.Toggle id="dropdown-basic" className="fz-15px py-0">
{dateRangePicker}
</Dropdown.Toggle>
<Dropdown.Menu>
<Dropdown.Item onClick={(e) => handleDateRange(e, 'Yearly')}>Yearly</Dropdown.Item>
<Dropdown.Item onClick={(e) => handleDateRange(e, 'Quarterly')}>Quarterly</Dropdown.Item>
<Dropdown.Item onClick={(e) => handleDateRange(e, 'Monthly')}>Monthly</Dropdown.Item>
<Dropdown.Item onClick={(e) => handleDateRange(e, 'Custom')}>Custom</Dropdown.Item>
<Dropdown.Item onClick={(e) => handleDateRange(e, 'Day')}>Day</Dropdown.Item>
</Dropdown.Menu>
</Dropdown>
<DatePicker
selected={selectedYear}
onChange={handleYearChange}
showYearPicker
dateFormat="yyyy"
dropdownMode="select"
/>
{selectedYear? format(selectedYear, "yyyy") : ""} ----
{startDatePicker ? format(startDatePicker, "yyyy-MM-dd") : ""} to {endDatePicker ? format(endDatePicker, "yyyy-MM-dd") : ""}
</div>
</div>
</div>
);
};
export default Records;
Json Data Filter
import React, { useEffect, useState, useMemo } from "react";
import DatePicker from "react-datepicker";
import "react-datepicker/dist/react-datepicker.css";
const budgetData = [
{ no: 1, name: "Coffee", date: "2025-01-15T18:30:00.000Z", amount: 150, category: 1 },
{ no: 2, name: "Groceries", date: "2025-01-16T18:30:00.000Z", amount: 1200, category: 1 },
{ no: 3, name: "Movie Ticket", date: "2025-01-17T18:30:00.000Z", amount: 400, category: 3, sub_budget: [
{ sub_no: 1, name: "Parking", amount: 50 },
{ sub_no: 2, name: "Ticket", amount: 250, sub_budget: [
{ sub_sub_no: 1, name: "Premium Seat", amount: 100 }
] },
{ sub_no: 3, name: "Popcorn", amount: 100 }
] },
{ no: 4, name: "Gym Membership", date: "2025-01-18T18:30:00.000Z", amount: 2000, category: 3 },
{ no: 5, name: "Dinner", date: "2025-01-19T18:30:00.000Z", amount: 850, category: 1 },
{ no: 6, name: "Electricity Bill", date: "2025-01-20T18:30:00.000Z", amount: 3000, category: 2 },
{ no: 7, name: "Internet Bill", date: "2025-01-21T18:30:00.000Z", amount: 1200, category: 2 },
{ no: 8, name: "Books", date: "2025-01-22T18:30:00.000Z", amount: 750, category: 3 },
{ no: 9, name: "Taxi", date: "2025-01-23T18:30:00.000Z", amount: 500, category: 4 },
{ no: 10, name: "Shopping", date: "2025-01-24T18:30:00.000Z", amount: 2500, category: 3 },
{ no: 11, name: "Subscription", date: "2025-01-25T18:30:00.000Z", amount: 999, category: 3 },
{ no: 12, name: "Lunch", date: "2025-01-26T18:30:00.000Z", amount: 600, category: 1 },
{ no: 13, name: "Water Bill", date: "2025-01-27T18:30:00.000Z", amount: 700, category: 2 },
{ no: 14, name: "Concert Ticket", date: "2025-01-28T18:30:00.000Z", amount: 1800, category: 3 },
{ no: 15, name: "Gas", date: "2025-01-29T18:30:00.000Z", amount: 2200, category: 4 }
];
const BudgetFilter = () => {
const [startDate, setStartDate] = useState(null);
const [endDate, setEndDate] = useState(null);
const [groupType, setGroupType] = useState("category");
const [filterData, setFilterData] = useState({});
// Memoize filteredData to prevent recalculating on every render
const filteredData = useMemo(() => {
return budgetData.filter(item => {
const itemDate = new Date(item.date);
return (
(!startDate || itemDate >= startDate) &&
(!endDate || itemDate <= endDate)
);
});
}, [startDate, endDate, budgetData]);
// Memoize groupedData to prevent recalculating on every render
const groupedData = useMemo(() => {
return filteredData.reduce((acc, item) => {
//const groupKey = item[groupType];
const groupKey = groupType === "date" ? new Date(item.date).toISOString().split("T")[0] : item[groupType];
if (!acc[groupKey]) {
acc[groupKey] = { group: groupKey, group_data: [] };
}
acc[groupKey].group_data.push(item);
return acc;
}, {});
}, [filteredData, groupType]);
useEffect(() => {
setFilterData(groupedData);
}, [groupedData]);
const renderSubBudget = (subBudget, level = 1) => {
return (
<ul style={{ paddingLeft: `${level * 20}px` }}>
{subBudget.map(sub => (
<li key={sub.sub_no || sub.sub_sub_no}>
{sub.name} - {sub.amount}
{sub.sub_budget && renderSubBudget(sub.sub_budget, level + 1)}
</li>
))}
</ul>
);
};
return (
<div>
<h2>Budget Data Filter</h2>
<label>Start Date:</label>
<DatePicker
selected={startDate}
onChange={date => setStartDate(date)}
dateFormat="yyyy-MM-dd"
/>
<label>End Date:</label>
<DatePicker
selected={endDate}
onChange={date => setEndDate(date)}
dateFormat="yyyy-MM-dd"
/>
<label>Group By:</label>
<select value={groupType} onChange={(e) => setGroupType(e.target.value)}>
<option value="amount">Amount</option>
<option value="category">Category</option>
<option value="date">Date</option>
</select>
<h3>Filtered Results</h3>
{Object.values(filterData).map(group => (
<div key={group.group}>
<h4>{groupType.charAt(0).toUpperCase() + groupType.slice(1)} {group.group}</h4>
<ul>
{group.group_data.map(item => (
<li key={item.no}>
{item.name} - {item.amount} ({new Date(item.date).toLocaleDateString()})
{item.sub_budget && renderSubBudget(item.sub_budget)}
</li>
))}
</ul>
</div>
))}
</div>
);
};
export default BudgetFilter;
Context API
What is useContext in React?
useContext is a React Hook that lets you read data from a Context inside any component.
A Context is a way to share data (like theme, user login info, language, etc.) across many components, without passing props manually through every level.
Purpose of useContext
It makes your code cleaner, shorter, and easier to manage.
To make global values (like settings, user data) easily available anywhere in the app..
To avoid "prop drilling" — meaning you don't have to pass the same data from parent → child → grandchild → great-grandchild, etc.
//App.js
import React from "react";
import DataProvider from "./Components/DataContext";
import ComponentOne from "./Components/ComponentOne";
import ComponentTwo from "./Components/ComponentTwo";
const App = () => {
return (
<DataProvider>
<ComponentOne />
<ComponentTwo />
</DataProvider>
);
};
export default App;
//DataContext.js
import React, { createContext, useState } from "react";
export const DataContext = createContext();
const DataProvider = ({ children }) => {
const [data, setData] = useState("Global Data");
const [newdata, setNewData] = useState("Global new Data");
return (
<DataContext.Provider value={{ data, setData, newdata, setNewData }}>
{children}
</DataContext.Provider>
);
};
export default DataProvider;
//ComponentOne.js
import React, { useContext, useState } from "react";
import { DataContext } from "./DataContext";
const ComponentOne = () => {
const { setData, setNewData } = useContext(DataContext);
const [userName, setUserName] =useState('')
const handleNamechange = () => {
setNewData(userName);
}
return (
<>
<button onClick={() => setData("Updated Data from Component One")}>
Update Data
</button>
<input type="text" value={userName} placeholder="Enter your Name" onChange={(e) => setUserName(e.target.value)} />
<button onClick={() => handleNamechange()}>
Update Data
</button>
</>
);
};
export default ComponentOne;
//ComponentTwo.js
import React, { useContext } from "react";
import { DataContext } from "./DataContext";
const ComponentTwo = () => {
const { data } = useContext(DataContext);
const { newdata } = useContext(DataContext);
return <p>Hi {newdata}, Data from Context: {data}</p>;
};
export default ComponentTwo;
Redux
Redux is for JavaScript applications
Redux is not tied to React
Can be used with React, Angular, Vue or even vanilla JavaScript
Redux is a library for JavaScript applications
Redux is State Container
Redux is Prectable State Container for JavaScript app
|
Redux
|
Redux toolkit
|
| Not much organised |
organised |
| Lot of repetition |
CreateSlice (cleaner and smaller) |
| Manual Configration |
Auto Configration |
| Config redux devtool extension |
Auto support |
manually handle and change state immutably
(immutable state means always written a new state)
|
immer.js support(auto change code) |
| Stoer too complication
|
- |
| Class based implementation
|
function based with typescript and support of hooks |
npm install @reduxjs/toolkit react-redux
// src/features/counter/counterSlice.js
import { createSlice } from '@reduxjs/toolkit';
const initialState = {
value: 0
};
const counterSlice = createSlice({
name: 'counter',
initialState,
reducers: {
increment: (state) => {
state.value += 1;
},
decrement: (state) => {
state.value -= 1;
},
reset: (state) => {
state.value = 0;
},
incrementByAmount: (state, action) => {
state.value += action.payload;
},
},
});
export const { increment, decrement, reset, incrementByAmount } = counterSlice.actions;
export default counterSlice.reducer;
// src/app/store.js
import { configureStore } from '@reduxjs/toolkit';
import counterReducer from '../features/counter/counterSlice';
export const store = configureStore({
reducer: {
counter: counterReducer,
},
});
// src/index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import { Provider } from 'react-redux';
import { store } from './app/store';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<Provider store={store}>
<App />
</Provider>
);
// src/features/counter/Counter.js
import React, { useState } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import {
increment,
decrement,
reset,
incrementByAmount,
} from './counterSlice';
const Counter = () => {
const count = useSelector((state) => state.counter.value);
const dispatch = useDispatch();
const [amount, setAmount] = useState(0);
return (
<div>
<h2>Count: {count}</h2>
<button onClick={() => dispatch(increment())}>+1</button>
<button onClick={() => dispatch(decrement())}>-1</button>
<button onClick={() => dispatch(reset())}>Reset</button>
<div>
<input
type="number"
value={amount}
onChange={(e) => setAmount(Number(e.target.value))}
/>
<button onClick={() => dispatch(incrementByAmount(amount))}>
Increment by Amount
</button>
</div>
</div>
);
};
export default Counter;