Changed Code and fetch data from json api

This commit is contained in:
bansh_dml 2025-01-03 10:14:33 +05:30
parent 38335cef91
commit 3426fb7c97
3 changed files with 95 additions and 129 deletions

View file

@ -1,24 +1,14 @@
import React, { useState, useEffect } from "react";
import { useParams, useNavigate } from "react-router-dom";
import React, { useEffect, useState } from "react";
import { useParams, useNavigate, useLocation } from "react-router-dom";
import { useForm, Controller } from "react-hook-form";
const EditUser = () => {
const { id } = useParams();
const navigate = useNavigate();
const location = useLocation();
const [users, setUsers] = useState(location.state?.users || []);
const [users, setUsers] = useState([]);
useEffect(() => {
const storedUsers = JSON.parse(localStorage.getItem("users")) || [];
setUsers(storedUsers);
}, []);
const {
control,
handleSubmit,
reset,
formState: { errors },
} = useForm({
const { control, handleSubmit, reset, formState: { errors } } = useForm({
defaultValues: {
name: "",
email: "",
@ -28,13 +18,23 @@ const EditUser = () => {
});
useEffect(() => {
if (id && id !== "new") {
const existingUser = users.find((user) => user.id === parseInt(id));
if (existingUser) {
reset(existingUser);
}
if (users.length === 0) {
const fetchUsers = async () => {
const response = await fetch("https://jsonplaceholder.typicode.com/users");
const data = await response.json();
setUsers(data);
};
fetchUsers();
}
}, [id, users, reset]);
}, [users]);
const user = users.find((user) => user.id === parseInt(id));
useEffect(() => {
if (user) {
reset(user);
}
}, [user, reset]);
const onSubmit = (data) => {
let updatedUsers;
@ -43,97 +43,62 @@ const EditUser = () => {
updatedUsers = [...users, newUser];
alert("User added successfully!");
} else {
updatedUsers = users.map((user) =>
user.id === parseInt(id) ? { ...data, id: user.id } : user
updatedUsers = users.map((u) =>
u.id === parseInt(id) ? { ...data, id: u.id } : u
);
alert("User updated successfully!");
}
setUsers(updatedUsers);
localStorage.setItem("users", JSON.stringify(updatedUsers));
navigate("/");
navigate("/", { state: { users: updatedUsers } });
};
const handleDelete = () => {
const updatedUsers = users.filter((user) => user.id !== parseInt(id));
setUsers(updatedUsers);
localStorage.setItem("users", JSON.stringify(updatedUsers));
alert(`User with ID ${id} deleted.`);
navigate("/");
navigate("/", { state: { users: updatedUsers } });
};
return (
<div className="form-container">
<h1>{id === "new" ? "Add" : "Edit"} User</h1>
<form onSubmit={handleSubmit(onSubmit)}>
{/* Form Fields */}
<div className="form-group">
<div>
<label>Name</label>
<Controller
name="name"
control={control}
rules={{ required: "Name is required." }}
render={({ field }) => (
<input {...field} className={errors.name ? "error-input" : ""} />
)}
rules={{ required: "Name is required" }}
render={({ field }) => <input {...field} />}
/>
{errors.name && <span>{errors.name.message}</span>}
{errors.name && <p>{errors.name.message}</p>}
</div>
<div className="form-group">
<div>
<label>Email</label>
<Controller
name="email"
control={control}
rules={{
required: "Email is required.",
pattern: {
value: /^[^\s@]+@[^\s@]+\.[^\s@]+$/,
message: "Invalid email format.",
},
}}
render={({ field }) => (
<input {...field} className={errors.email ? "error-input" : ""} />
)}
rules={{ required: "Email is required" }}
render={({ field }) => <input {...field} />}
/>
{errors.email && <span>{errors.email.message}</span>}
{errors.email && <p>{errors.email.message}</p>}
</div>
<div className="form-group">
<div>
<label>Phone</label>
<Controller
name="phone"
control={control}
rules={{
required: "Phone number is required.",
pattern: {
value: /^[0-9]{10}$/,
message: "Phone number must be 10 digits.",
},
}}
render={({ field }) => (
<input {...field} className={errors.phone ? "error-input" : ""} />
)}
render={({ field }) => <input {...field} />}
/>
{errors.phone && <span>{errors.phone.message}</span>}
</div>
<div className="form-group">
<div>
<label>Website</label>
<Controller
name="website"
control={control}
rules={{
pattern: {
value:
/^(https?:\/\/)?([\w\d\-_]+\.)+[\w\d\-_]+(\/[\w\d\-_.?&=]*)*\/?$/,
message: "Invalid website URL.",
},
}}
render={({ field }) => (
<input
{...field}
className={errors.website ? "error-input" : ""}
/>
)}
render={({ field }) => <input {...field} />}
/>
{errors.website && <span>{errors.website.message}</span>}
</div>
<button type="submit" className="submit-button">
Save

View file

@ -1,29 +1,34 @@
import React, { useState, useEffect } from "react";
import { useParams, useNavigate } from "react-router-dom";
import React, { useEffect, useState } from "react";
import { useParams, useNavigate, useLocation } from "react-router-dom";
const UserDetails = () => {
const { id } = useParams();
const navigate = useNavigate();
const location = useLocation();
const [users, setUsers] = useState([]);
const [users, setUsers] = useState(location.state?.users || []);
const [user, setUser] = useState(null);
useEffect(() => {
const storedUsers = JSON.parse(localStorage.getItem("users")) || [];
setUsers(storedUsers);
}, []);
useEffect(() => {
localStorage.setItem("users", JSON.stringify(users));
}, [users]);
const userId = parseInt(id, 10);
const user = users.find((user) => user.id === userId);
if (users.length > 0) {
const foundUser = users.find((user) => user.id === parseInt(id));
setUser(foundUser);
} else {
const fetchUsers = async () => {
const response = await fetch("https://jsonplaceholder.typicode.com/users");
const data = await response.json();
setUsers(data);
const foundUser = data.find((user) => user.id === parseInt(id));
setUser(foundUser);
};
fetchUsers();
}
}, [id, users]);
const handleDelete = () => {
const updatedUsers = users.filter((user) => user.id !== userId);
setUsers(updatedUsers);
const updatedUsers = users.filter((u) => u.id !== parseInt(id));
alert(`User with ID ${id} deleted.`);
navigate("/");
navigate("/", { state: { users: updatedUsers } });
};
if (!user) {

View file

@ -1,34 +1,35 @@
import React, { useState, useEffect } from "react";
import { Link } from "react-router-dom";
import axios from "axios";
import React, { useEffect, useState } from "react";
import { Link, useLocation } from "react-router-dom";
const UserList = () => {
const [users, setUsers] = useState([]);
const [searchTerm, setSearchTerm] = useState("");
const location = useLocation();
const [users, setUsers] = useState(location.state?.users || []);
const [currentPage, setCurrentPage] = useState(1);
const usersPerPage = 5;
useEffect(() => {
const storedUsers = JSON.parse(localStorage.getItem("users")) || [];
setUsers(storedUsers);
}, []);
if (!location.state?.users) {
const fetchUsers = async () => {
const response = await fetch(
"https://jsonplaceholder.typicode.com/users"
);
const data = await response.json();
setUsers(data);
};
fetchUsers();
}
}, [location.state?.users]);
const handleDelete = (id) => {
const updatedUsers = users.filter((user) => user.id !== id);
setUsers(updatedUsers);
localStorage.setItem("users", JSON.stringify(updatedUsers));
alert(`User with ID ${id} deleted.`);
};
const filteredUsers = users.filter(
(user) =>
user.name.toLowerCase().includes(searchTerm.toLowerCase()) ||
user.email.toLowerCase().includes(searchTerm.toLowerCase())
);
const indexOfLastUser = currentPage * usersPerPage;
const indexOfFirstUser = indexOfLastUser - usersPerPage;
const currentUsers = filteredUsers.slice(indexOfFirstUser, indexOfLastUser);
const totalPages = Math.ceil(filteredUsers.length / usersPerPage);
const currentUsers = users.slice(indexOfFirstUser, indexOfLastUser);
const totalPages = Math.ceil(users.length / usersPerPage);
const handlePageChange = (pageNumber) => {
setCurrentPage(pageNumber);
@ -37,18 +38,6 @@ const UserList = () => {
return (
<div className="container">
<h1>User List</h1>
<div className="search-container">
<input
type="text"
placeholder="Search by name or email..."
value={searchTerm}
onChange={(e) => setSearchTerm(e.target.value)}
className="search-input"
/>
<button className="search-button">Search</button>
</div>
<table>
<thead>
<tr>
@ -69,15 +58,23 @@ const UserList = () => {
<td>{user.phone}</td>
<td>{user.website}</td>
<td>
<Link to={`/user/${user.id}`} className="view-button">
<Link
to={`/user/${user.id}`}
className="view-button"
state={{ users }}
>
View
</Link>
<Link to={`/edit/${user.id}`} className="edit-button">
<Link
to={`/edit/${user.id}`}
className="edit-button"
state={{ users }}
>
Edit
</Link>
<button
onClick={() => handleDelete(user.id)}
className="delete-button"
onClick={() => handleDelete(user.id)}
>
Delete
</button>
@ -87,6 +84,7 @@ const UserList = () => {
</tbody>
</table>
{/* Pagination */}
<div className="pagination-container">
{Array.from({ length: totalPages }, (_, index) => (
<button
@ -101,11 +99,9 @@ const UserList = () => {
))}
</div>
<div>
<Link to="/edit/new" className="add-new-button">
Add New User
</Link>
</div>
<Link to="/edit/new" className="add-new-button" state={{ users }}>
Add New User
</Link>
</div>
);
};