Commit 266d9fcc authored by Ajay R's avatar Ajay R

CRUD Operation using open API

parent 7828acd0
......@@ -8,11 +8,15 @@
"name": "crud-api-call",
"version": "0.1.0",
"dependencies": {
"@reduxjs/toolkit": "^1.9.3",
"@testing-library/jest-dom": "^5.17.0",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"bootstrap": "^5.3.2",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-redux": "^8.0.5",
"react-router-dom": "^6.9.0",
"react-scripts": "5.0.1",
"web-vitals": "^2.1.4"
}
......@@ -3257,6 +3261,37 @@
}
}
},
"node_modules/@reduxjs/toolkit": {
"version": "1.9.5",
"resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-1.9.5.tgz",
"integrity": "sha512-Rt97jHmfTeaxL4swLRNPD/zV4OxTes4la07Xc4hetpUW/vc75t5m1ANyxG6ymnEQ2FsLQsoMlYB2vV1sO3m8tQ==",
"dependencies": {
"immer": "^9.0.21",
"redux": "^4.2.1",
"redux-thunk": "^2.4.2",
"reselect": "^4.1.8"
},
"peerDependencies": {
"react": "^16.9.0 || ^17.0.0 || ^18",
"react-redux": "^7.2.1 || ^8.0.2"
},
"peerDependenciesMeta": {
"react": {
"optional": true
},
"react-redux": {
"optional": true
}
}
},
"node_modules/@remix-run/router": {
"version": "1.9.0",
"resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.9.0.tgz",
"integrity": "sha512-bV63itrKBC0zdT27qYm6SDZHlkXwFL1xMBuhkn+X7l0+IIhNaH5wuuvZKp6eKhCD4KFhujhfhCT1YxXW6esUIA==",
"engines": {
"node": ">=14.0.0"
}
},
"node_modules/@rollup/plugin-babel": {
"version": "5.3.1",
"resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz",
......@@ -3924,6 +3959,15 @@
"@types/node": "*"
}
},
"node_modules/@types/hoist-non-react-statics": {
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
"integrity": "sha512-YIQtIg4PKr7ZyqNPZObpxfHsHEmuB8dXCxd6qVcGuQVDK2bpsF7bYNnBJ4Nn7giuACZg+WewExgrtAJ3XnA4Xw==",
"dependencies": {
"@types/react": "*",
"hoist-non-react-statics": "^3.3.0"
}
},
"node_modules/@types/html-minifier-terser": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz",
......@@ -4343,6 +4387,11 @@
"resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.4.tgz",
"integrity": "sha512-IDaobHimLQhjwsQ/NMwRVfa/yL7L/wriQPMhw1ZJall0KX6E1oxk29XMDeilW5qTIg5aoiqf5Udy8U/51aNoQQ=="
},
"node_modules/@types/use-sync-external-store": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz",
"integrity": "sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA=="
},
"node_modules/@types/ws": {
"version": "8.5.5",
"resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.5.tgz",
......@@ -5608,6 +5657,24 @@
"resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
"integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww=="
},
"node_modules/bootstrap": {
"version": "5.3.2",
"resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.3.2.tgz",
"integrity": "sha512-D32nmNWiQHo94BKHLmOrdjlL05q1c8oxbtBphQFb9Z5to6eGRDCm0QgeaZ4zFBHzfg2++rqa2JkqCcxDy0sH0g==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/twbs"
},
{
"type": "opencollective",
"url": "https://opencollective.com/bootstrap"
}
],
"peerDependencies": {
"@popperjs/core": "^2.11.8"
}
},
"node_modules/brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
......@@ -8822,6 +8889,19 @@
"he": "bin/he"
}
},
"node_modules/hoist-non-react-statics": {
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
"integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==",
"dependencies": {
"react-is": "^16.7.0"
}
},
"node_modules/hoist-non-react-statics/node_modules/react-is": {
"version": "16.13.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
},
"node_modules/hoopy": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz",
......@@ -14596,6 +14676,49 @@
"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
"integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w=="
},
"node_modules/react-redux": {
"version": "8.1.2",
"resolved": "https://registry.npmjs.org/react-redux/-/react-redux-8.1.2.tgz",
"integrity": "sha512-xJKYI189VwfsFc4CJvHqHlDrzyFTY/3vZACbE+rr/zQ34Xx1wQfB4OTOSeOSNrF6BDVe8OOdxIrAnMGXA3ggfw==",
"dependencies": {
"@babel/runtime": "^7.12.1",
"@types/hoist-non-react-statics": "^3.3.1",
"@types/use-sync-external-store": "^0.0.3",
"hoist-non-react-statics": "^3.3.2",
"react-is": "^18.0.0",
"use-sync-external-store": "^1.0.0"
},
"peerDependencies": {
"@types/react": "^16.8 || ^17.0 || ^18.0",
"@types/react-dom": "^16.8 || ^17.0 || ^18.0",
"react": "^16.8 || ^17.0 || ^18.0",
"react-dom": "^16.8 || ^17.0 || ^18.0",
"react-native": ">=0.59",
"redux": "^4 || ^5.0.0-beta.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
},
"@types/react-dom": {
"optional": true
},
"react-dom": {
"optional": true
},
"react-native": {
"optional": true
},
"redux": {
"optional": true
}
}
},
"node_modules/react-redux/node_modules/react-is": {
"version": "18.2.0",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
"integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w=="
},
"node_modules/react-refresh": {
"version": "0.11.0",
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz",
......@@ -14604,6 +14727,36 @@
"node": ">=0.10.0"
}
},
"node_modules/react-router": {
"version": "6.16.0",
"resolved": "https://registry.npmjs.org/react-router/-/react-router-6.16.0.tgz",
"integrity": "sha512-VT4Mmc4jj5YyjpOi5jOf0I+TYzGpvzERy4ckNSvSh2RArv8LLoCxlsZ2D+tc7zgjxcY34oTz2hZaeX5RVprKqA==",
"dependencies": {
"@remix-run/router": "1.9.0"
},
"engines": {
"node": ">=14.0.0"
},
"peerDependencies": {
"react": ">=16.8"
}
},
"node_modules/react-router-dom": {
"version": "6.16.0",
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.16.0.tgz",
"integrity": "sha512-aTfBLv3mk/gaKLxgRDUPbPw+s4Y/O+ma3rEN1u8EgEpLpPe6gNjIsWt9rxushMHHMb7mSwxRGdGlGdvmFsyPIg==",
"dependencies": {
"@remix-run/router": "1.9.0",
"react-router": "6.16.0"
},
"engines": {
"node": ">=14.0.0"
},
"peerDependencies": {
"react": ">=16.8",
"react-dom": ">=16.8"
}
},
"node_modules/react-scripts": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-5.0.1.tgz",
......@@ -14731,6 +14884,22 @@
"node": ">=8"
}
},
"node_modules/redux": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz",
"integrity": "sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==",
"dependencies": {
"@babel/runtime": "^7.9.2"
}
},
"node_modules/redux-thunk": {
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.4.2.tgz",
"integrity": "sha512-+P3TjtnP0k/FEjcBL5FZpoovtvrTNT/UXd4/sluaSyrURlSlhLSzEdfsTBW7WsKB6yPvgd7q/iZPICFjW4o57Q==",
"peerDependencies": {
"redux": "^4"
}
},
"node_modules/reflect.getprototypeof": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.4.tgz",
......@@ -14876,6 +15045,11 @@
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
"integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ=="
},
"node_modules/reselect": {
"version": "4.1.8",
"resolved": "https://registry.npmjs.org/reselect/-/reselect-4.1.8.tgz",
"integrity": "sha512-ab9EmR80F/zQTMNeneUr4cv+jSwPJgIlvEmVwLerwrWVbpLlBuls9XHzIeTFy4cegU2NHBp3va0LKOzU5qFEYQ=="
},
"node_modules/resolve": {
"version": "1.22.6",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.6.tgz",
......@@ -16712,6 +16886,14 @@
"requires-port": "^1.0.0"
}
},
"node_modules/use-sync-external-store": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz",
"integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==",
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0 || ^18.0.0"
}
},
"node_modules/util-deprecate": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
......
......@@ -3,11 +3,15 @@
"version": "0.1.0",
"private": true,
"dependencies": {
"@reduxjs/toolkit": "^1.9.3",
"@testing-library/jest-dom": "^5.17.0",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"bootstrap": "^5.3.2",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-redux": "^8.0.5",
"react-router-dom": "^6.9.0",
"react-scripts": "5.0.1",
"web-vitals": "^2.1.4"
},
......
import logo from './logo.svg';
import './App.css';
import "./App.css";
import Create from "./components/Create";
import Navbar from "./components/Navbar";
import { BrowserRouter, Route, Routes } from "react-router-dom";
import Read from "./components/Read";
import Update from "./components/Update";
import { showUser } from "./features/userDetailSlice";
import { useEffect } from "react";
import { useDispatch } from "react-redux";
function App() {
const dispatch = useDispatch();
useEffect(() => {
dispatch(showUser());
}, []);
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
Edit <code>src/App.js</code> and save to reload.
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
</header>
<BrowserRouter>
<Navbar />
<Routes>
<Route exact path="/" element={<Create />} />
<Route exact path="/read" element={<Read />} />
<Route exact path="/edit/:id" element={<Update />} />
</Routes>
</BrowserRouter>
</div>
);
}
......
// api/schema.js
const { gql } = require('apollo-server');
const typeDefs = gql`
type User {
id: ID!
name: String!
email: String!
}
type Query {
users: [User]
}
type Mutation {
createUser(input: UserInput!): User
}
input UserInput {
name: String!
email: String!
}
`;
module.exports = typeDefs;
import { configureStore } from "@reduxjs/toolkit";
import userDetail from "../features/userDetailSlice";
export const store = configureStore({
reducer: {
app: userDetail,
},
});
import React, { useState } from "react";
import { useDispatch } from "react-redux";
import { useNavigate } from "react-router-dom";
import { createUser } from "../features/userDetailSlice";
const Create = () => {
const [users, setUsers] = useState({});
const navigate = useNavigate();
const dispatch = useDispatch();
const getUserData = (e) => {
setUsers({ ...users, [e.target.name]: e.target.value });
};
const handleSubmit = (e) => {
e.preventDefault();
console.log("users...", users);
dispatch(createUser(users));
navigate("/read");
};
return (
<div>
<h2 className="my-2">Fill the data</h2>
<form className="w-50 mx-auto my-5" onSubmit={handleSubmit}>
<div class="mb-3">
<label class="form-label">Name</label>
<input
type="text"
name="name"
class="form-control"
onChange={getUserData}
required
/>
</div>
<div class="mb-3">
<label class="form-label">Email</label>
<input
type="email"
name="email"
class="form-control"
onChange={getUserData}
required
/>
</div>
<div class="mb-3">
<label class="form-label">Age</label>
<input
type="text"
name="age"
class="form-control"
onChange={getUserData}
required
/>
</div>
<div class="mb-3">
<input
class="form-check-input"
name="gender"
value="Male"
type="radio"
onChange={getUserData}
required
/>
<label class="form-check-label">Male</label>
</div>
<div class="mb-3">
<input
class="form-check-input"
name="gender"
value="Female"
type="radio"
onChange={getUserData}
/>
<label class="form-check-label">Female</label>
</div>
<button type="submit" class="btn btn-primary">
Submit
</button>
</form>
</div>
);
};
export default Create;
.modalBackground {
position: fixed;
background-color: #e8e8e8;
top: 0;
bottom: 0;
left: 0;
right: 0;
display: flex;
justify-content: center;
align-items: center;
z-index: 99;
opacity: 1;
}
.modalContainer {
background-color: white;
box-shadow: 0px 0px 0px #888;
padding: 10px;
border-radius: 10px;
height: 400px;
width: 400px;
}
import React from "react";
import { useSelector } from "react-redux";
import "./CustomModal.css";
const CustomModal = ({ id, setShowPopup }) => {
const allusers = useSelector((state) => state.app.users);
const singleUser = allusers.filter((ele) => ele.id === id);
console.log("singleuser", singleUser);
return (
<div className="modalBackground">
<div className="modalContainer">
<button onClick={() => setShowPopup(false)}>Close</button>
<h2>{singleUser[0].name}</h2>
<h3>{singleUser[0].email}</h3>
<h4>{singleUser[0].age}</h4>
<p>{singleUser[0].gender}</p>
</div>
</div>
);
};
export default CustomModal;
import { useSelector } from "react-redux";
import { Link } from "react-router-dom";
const Navbar = () => {
const allusers = useSelector((state) => state.app.users);
return (
<div>
<nav className="navbar navbar-expand-lg navbar-light bg-light">
<div className="container-fluid ">
<div className="collapse navbar-collapse">
<ul className="navbar-nav me-auto mb-2 mb-lg-0">
<li className="nav-item">
<Link to="/" className="nav-link">
Create Post
</Link>
</li>
<li className="nav-item">
<Link to="/read" className="nav-link">
All Post ({allusers.length})
</Link>
</li>
</ul>
</div>
</div>
</nav>
</div>
);
};
export default Navbar;
import React, { useState } from "react";
import { useDispatch, useSelector } from "react-redux";
import { Link } from "react-router-dom";
import { deleteUser } from "../features/userDetailSlice";
import CustomModal from "./CustomModal";
const Read = () => {
const dispatch = useDispatch();
const [id, setId] = useState();
const [showPopup, setShowPopup] = useState(false);
const { users, loading } = useSelector((state) => state.app);
if (loading) {
return <h2>Loading</h2>;
}
return (
<div>
{showPopup && (
<CustomModal
id={id}
showPopup={showPopup}
setShowPopup={setShowPopup}
/>
)}
<h2>All data</h2>
<div>
{users &&
users.map((ele) => (
<div key={ele.id} className="card w-50 mx-auto my-2">
<div className="card-body">
<h5 className="card-title">{ele.name}</h5>
<h6 className="card-subtitle mb-2 text-muted">{ele.email}</h6>
<p className="card-text">{ele.gender}</p>
<button
className="card-link"
onClick={() => [setId(ele.id), setShowPopup(true)]}
>
View
</button>
<Link to={`/edit/${ele.id}`} className="card-link">
Edit
</Link>
<Link
onClick={() => dispatch(deleteUser(ele.id))}
className="card-link"
>
Delete
</Link>
</div>
</div>
))}
</div>
</div>
);
};
export default Read;
import React, { useEffect, useState } from "react";
import { useDispatch, useSelector } from "react-redux";
import { useNavigate, useParams } from "react-router-dom";
import { updateUser } from "../features/userDetailSlice";
const Update = () => {
const { id } = useParams();
const dispatch = useDispatch();
const navigate = useNavigate();
const [updateData, setUpdateData] = useState();
const { users } = useSelector((state) => state.app);
useEffect(() => {
if (id) {
const singleUser = users.filter((ele) => ele.id === id);
setUpdateData(singleUser[0]);
}
}, []);
const newData = (e) => {
setUpdateData({ ...updateData, [e.target.name]: e.target.value });
};
console.log("updated data", updateData);
const handleUpdate = (e) => {
e.preventDefault();
dispatch(updateUser(updateData));
navigate("/read");
};
return (
<div>
<h2 className="my-2">Edit the data</h2>
<form className="w-50 mx-auto my-5" onSubmit={handleUpdate}>
<div class="mb-3">
<label class="form-label">Name</label>
<input
type="text"
name="name"
class="form-control"
value={updateData && updateData.name}
onChange={newData}
/>
</div>
<div class="mb-3">
<label class="form-label">Email</label>
<input
type="email"
name="email"
class="form-control"
value={updateData && updateData.email}
onChange={newData}
/>
</div>
<div class="mb-3">
<label class="form-label">Age</label>
<input
type="text"
name="age"
class="form-control"
value={updateData && updateData.age}
onChange={newData}
/>
</div>
<div class="mb-3">
<input
class="form-check-input"
name="gender"
value="Male"
type="radio"
checked={updateData && updateData.gender === "Male"}
onChange={newData}
/>
<label class="form-check-label">Male</label>
</div>
<div class="mb-3">
<input
class="form-check-input"
name="gender"
value="Female"
type="radio"
checked={updateData && updateData.gender === "Female"}
onChange={newData}
/>
<label class="form-check-label">Female</label>
</div>
<button type="submit" class="btn btn-primary">
Submit
</button>
</form>
</div>
);
};
export default Update;
import { createSlice, createAsyncThunk } from "@reduxjs/toolkit";
//create action
export const createUser = createAsyncThunk(
"createUser",
async (data, { rejectWithValue }) => {
console.log("data", data);
const response = await fetch(
"https://641dd63d945125fff3d75742.mockapi.io/crud",
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(data),
}
);
try {
const result = await response.json();
return result;
} catch (error) {
return rejectWithValue(error);
}
}
);
//read action
export const showUser = createAsyncThunk(
"showUser",
async (args, { rejectWithValue }) => {
const response = await fetch(
"https://641dd63d945125fff3d75742.mockapi.io/crud"
);
try {
const result = await response.json();
console.log(result);
return result;
} catch (error) {
return rejectWithValue(error);
}
}
);
//delete action
export const deleteUser = createAsyncThunk(
"deleteUser",
async (id, { rejectWithValue }) => {
const response = await fetch(
`https://641dd63d945125fff3d75742.mockapi.io/crud/${id}`,
{ method: "DELETE" }
);
try {
const result = await response.json();
console.log(result);
return result;
} catch (error) {
return rejectWithValue(error);
}
}
);
//update action
export const updateUser = createAsyncThunk(
"updateUser",
async (data, { rejectWithValue }) => {
console.log("updated data", data);
const response = await fetch(
`https://641dd63d945125fff3d75742.mockapi.io/crud/${data.id}`,
{
method: "PUT",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(data),
}
);
try {
const result = await response.json();
return result;
} catch (error) {
return rejectWithValue(error);
}
}
);
export const userDetail = createSlice({
name: "userDetail",
initialState: {
users: [],
loading: false,
error: null,
},
reducers: {
},
extraReducers: {
[createUser.pending]: (state) => {
state.loading = true;
},
[createUser.fulfilled]: (state, action) => {
state.loading = false;
state.users.push(action.payload);
},
[createUser.rejected]: (state, action) => {
state.loading = false;
state.error = action.payload.message;
},
[showUser.pending]: (state) => {
state.loading = true;
},
[showUser.fulfilled]: (state, action) => {
state.loading = false;
state.users = action.payload;
},
[showUser.rejected]: (state, action) => {
state.loading = false;
state.error = action.payload;
},
[deleteUser.pending]: (state) => {
state.loading = true;
},
[deleteUser.fulfilled]: (state, action) => {
state.loading = false;
const { id } = action.payload;
if (id) {
state.users = state.users.filter((ele) => ele.id !== id);
}
},
[deleteUser.rejected]: (state, action) => {
state.loading = false;
state.error = action.payload;
},
[updateUser.pending]: (state) => {
state.loading = true;
},
[updateUser.fulfilled]: (state, action) => {
state.loading = false;
state.users = state.users.map((ele) =>
ele.id === action.payload.id ? action.payload : ele
);
},
[updateUser.rejected]: (state, action) => {
state.loading = false;
state.error = action.payload.message;
},
},
});
export default userDetail.reducer;
export const { searchUser } = userDetail.actions;
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import React from "react";
import ReactDOM from "react-dom/client";
import "./index.css";
import App from "./App";
import { store } from "./app/store";
import { Provider } from "react-redux";
import "bootstrap/dist/css/bootstrap.min.css";
import reportWebVitals from "./reportWebVitals";
const root = ReactDOM.createRoot(document.getElementById('root'));
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
<React.StrictMode>
<App />
<Provider store={store}>
<App />
</Provider>
</React.StrictMode>
);
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment