API's working in real time
This commit is contained in:
parent
47a13ad356
commit
85dbeb7537
|
@ -1,82 +1,149 @@
|
||||||
import React,{useEffect} from "react";
|
import React, { useEffect } from "react";
|
||||||
import { Button, Dialog, DialogActions, DialogContent, DialogTitle, TextField } from "@mui/material";
|
import {
|
||||||
|
Button,
|
||||||
|
Dialog,
|
||||||
|
DialogActions,
|
||||||
|
DialogContent,
|
||||||
|
DialogTitle,
|
||||||
|
TextField,
|
||||||
|
} from "@mui/material";
|
||||||
import { useForm, Controller } from "react-hook-form";
|
import { useForm, Controller } from "react-hook-form";
|
||||||
|
|
||||||
interface AddEditCategoryModalProps {
|
interface AddEditCategoryModalProps {
|
||||||
open: boolean;
|
open: boolean;
|
||||||
handleClose: () => void;
|
handleClose: () => void;
|
||||||
editRow:any;
|
handleUpdate: (id: string, name: string, role: string) => void;
|
||||||
|
editRow: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface FormData {
|
interface FormData {
|
||||||
category: string;
|
category: string;
|
||||||
|
role: string;
|
||||||
|
name: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const AddEditCategoryModal: React.FC<AddEditCategoryModalProps> = ({ open, handleClose,editRow }) => {
|
const AddEditCategoryModal: React.FC<AddEditCategoryModalProps> = ({
|
||||||
const { control, handleSubmit, formState: { errors },setValue,reset } = useForm<FormData>({
|
open,
|
||||||
defaultValues: {
|
handleClose,
|
||||||
category: "",
|
editRow,
|
||||||
},
|
handleUpdate,
|
||||||
});
|
}) => {
|
||||||
|
const {
|
||||||
|
control,
|
||||||
|
handleSubmit,
|
||||||
|
formState: { errors },
|
||||||
|
setValue,
|
||||||
|
reset,
|
||||||
|
} = useForm<FormData>({
|
||||||
|
defaultValues: {
|
||||||
|
category: "",
|
||||||
|
name: "",
|
||||||
|
role: "",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const onSubmit = (data: FormData) => {
|
const onSubmit = (data: FormData) => {
|
||||||
console.log(data.category);
|
if (editRow) {
|
||||||
handleClose();
|
handleUpdate(editRow.id, data.name, data.role);
|
||||||
reset();
|
}
|
||||||
};
|
handleClose();
|
||||||
|
reset();
|
||||||
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (editRow) {
|
if (editRow) {
|
||||||
setValue('category', editRow.name);
|
setValue("category", editRow.name);
|
||||||
} else {
|
setValue("name", editRow.name);
|
||||||
reset();
|
setValue("role", editRow.role);
|
||||||
}
|
} else {
|
||||||
}, [editRow, setValue, reset]);
|
reset();
|
||||||
|
}
|
||||||
|
}, [editRow, setValue, reset]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Dialog
|
<Dialog
|
||||||
open={open}
|
open={open}
|
||||||
onClose={handleClose}
|
onClose={handleClose}
|
||||||
maxWidth="md"
|
maxWidth="md"
|
||||||
fullWidth
|
fullWidth
|
||||||
PaperProps={{
|
PaperProps={{
|
||||||
component: 'form',
|
component: "form",
|
||||||
onSubmit: handleSubmit(onSubmit),
|
onSubmit: handleSubmit(onSubmit),
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<DialogTitle>{editRow ? "Edit" : 'Add'} Category</DialogTitle>
|
<DialogTitle>{editRow ? "Edit" : "Add"} Category</DialogTitle>
|
||||||
<DialogContent>
|
<DialogContent>
|
||||||
<Controller
|
<Controller
|
||||||
name="category"
|
name="category"
|
||||||
control={control}
|
control={control}
|
||||||
rules={{
|
rules={{
|
||||||
required: "Category Name is required",
|
required: "Category Name is required",
|
||||||
|
}}
|
||||||
}}
|
render={({ field }) => (
|
||||||
render={({ field }) => (
|
<TextField
|
||||||
<TextField
|
{...field}
|
||||||
{...field}
|
autoFocus
|
||||||
autoFocus
|
required
|
||||||
required
|
margin="dense"
|
||||||
margin="dense"
|
label="Add Category Name"
|
||||||
label="Add Category Name"
|
type="text"
|
||||||
type="text"
|
fullWidth
|
||||||
fullWidth
|
variant="standard"
|
||||||
variant="standard"
|
error={!!errors.category}
|
||||||
error={!!errors.category}
|
helperText={errors.category?.message}
|
||||||
helperText={errors.category?.message}
|
/>
|
||||||
/>
|
)}
|
||||||
)}
|
/>
|
||||||
/>
|
<Controller
|
||||||
</DialogContent>
|
name="name"
|
||||||
<DialogActions>
|
control={control}
|
||||||
<Button onClick={handleClose}>Cancel</Button>
|
rules={{
|
||||||
<Button type="submit">Save</Button>
|
required: "Admin Name is required",
|
||||||
</DialogActions>
|
}}
|
||||||
</Dialog>
|
render={({ field }) => (
|
||||||
</>
|
<TextField
|
||||||
);
|
{...field}
|
||||||
|
autoFocus
|
||||||
|
required
|
||||||
|
margin="dense"
|
||||||
|
label="Admin Name"
|
||||||
|
type="text"
|
||||||
|
fullWidth
|
||||||
|
variant="standard"
|
||||||
|
error={!!errors.name}
|
||||||
|
helperText={errors.name?.message}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Controller
|
||||||
|
name="role"
|
||||||
|
control={control}
|
||||||
|
rules={{
|
||||||
|
required: "Role is required",
|
||||||
|
}}
|
||||||
|
render={({ field }) => (
|
||||||
|
<TextField
|
||||||
|
{...field}
|
||||||
|
margin="dense"
|
||||||
|
label="Role"
|
||||||
|
type="text"
|
||||||
|
fullWidth
|
||||||
|
variant="standard"
|
||||||
|
error={!!errors.role}
|
||||||
|
helperText={errors.role?.message}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</DialogContent>
|
||||||
|
<DialogActions>
|
||||||
|
<Button onClick={handleClose}>Cancel</Button>
|
||||||
|
<Button type="submit">Save</Button>
|
||||||
|
</DialogActions>
|
||||||
|
</Dialog>
|
||||||
|
</>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default AddEditCategoryModal;
|
export default AddEditCategoryModal;
|
||||||
|
|
|
@ -41,7 +41,7 @@ const StyledTableRow = styled(TableRow)(({ theme }) => ({
|
||||||
},
|
},
|
||||||
}))
|
}))
|
||||||
|
|
||||||
interface Column {
|
export interface Column {
|
||||||
id: string
|
id: string
|
||||||
label: string
|
label: string
|
||||||
align?: "left" | "center" | "right"
|
align?: "left" | "center" | "right"
|
||||||
|
@ -137,7 +137,7 @@ const CustomTable: React.FC<CustomTableProps> = ({
|
||||||
<IconButton
|
<IconButton
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
handleClick(e, row)
|
handleClick(e, row)
|
||||||
setSelectedRow(row) // Store the selected row
|
setRowData(row) // Store the selected row
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<MoreVertRoundedIcon />
|
<MoreVertRoundedIcon />
|
||||||
|
|
|
@ -1,89 +1,89 @@
|
||||||
import * as React from 'react';
|
import * as React from "react";
|
||||||
import { styled } from '@mui/material/styles';
|
import { styled } from "@mui/material/styles";
|
||||||
import Divider, { dividerClasses } from '@mui/material/Divider';
|
import Divider, { dividerClasses } from "@mui/material/Divider";
|
||||||
import Menu from '@mui/material/Menu';
|
import Menu from "@mui/material/Menu";
|
||||||
import MuiMenuItem from '@mui/material/MenuItem';
|
import MuiMenuItem from "@mui/material/MenuItem";
|
||||||
import { paperClasses } from '@mui/material/Paper';
|
import { paperClasses } from "@mui/material/Paper";
|
||||||
import { listClasses } from '@mui/material/List';
|
import { listClasses } from "@mui/material/List";
|
||||||
import ListItemText from '@mui/material/ListItemText';
|
import ListItemText from "@mui/material/ListItemText";
|
||||||
import ListItemIcon, { listItemIconClasses } from '@mui/material/ListItemIcon';
|
import ListItemIcon, { listItemIconClasses } from "@mui/material/ListItemIcon";
|
||||||
import LogoutRoundedIcon from '@mui/icons-material/LogoutRounded';
|
import LogoutRoundedIcon from "@mui/icons-material/LogoutRounded";
|
||||||
import MoreVertRoundedIcon from '@mui/icons-material/MoreVertRounded';
|
import MoreVertRoundedIcon from "@mui/icons-material/MoreVertRounded";
|
||||||
import MenuButton from '../MenuButton';
|
import MenuButton from "../MenuButton";
|
||||||
import { Avatar } from '@mui/material';
|
import { Avatar } from "@mui/material";
|
||||||
|
|
||||||
const MenuItem = styled(MuiMenuItem)({
|
const MenuItem = styled(MuiMenuItem)({
|
||||||
margin: '2px 0',
|
margin: "2px 0",
|
||||||
});
|
});
|
||||||
|
|
||||||
export default function OptionsMenu({ avatar }: { avatar?: boolean }) {
|
export default function OptionsMenu({ avatar }: { avatar?: boolean }) {
|
||||||
const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null);
|
const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null);
|
||||||
const open = Boolean(anchorEl);
|
const open = Boolean(anchorEl);
|
||||||
const handleClick = (event: React.MouseEvent<HTMLElement>) => {
|
const handleClick = (event: React.MouseEvent<HTMLElement>) => {
|
||||||
setAnchorEl(event.currentTarget);
|
setAnchorEl(event.currentTarget);
|
||||||
};
|
};
|
||||||
const handleClose = () => {
|
const handleClose = () => {
|
||||||
setAnchorEl(null);
|
setAnchorEl(null);
|
||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
<MenuButton
|
<MenuButton
|
||||||
aria-label="Open menu"
|
aria-label="Open menu"
|
||||||
onClick={handleClick}
|
onClick={handleClick}
|
||||||
sx={{ borderColor: 'transparent' }}
|
sx={{ borderColor: "transparent" }}
|
||||||
>
|
>
|
||||||
{avatar ? (
|
{avatar ? (
|
||||||
<MoreVertRoundedIcon />
|
<MoreVertRoundedIcon />
|
||||||
) : (
|
) : (
|
||||||
<Avatar
|
<Avatar
|
||||||
sizes="small"
|
sizes="small"
|
||||||
alt="Riley Carter"
|
alt="Riley Carter"
|
||||||
src="/static/images/avatar/7.jpg"
|
src="/static/images/avatar/7.jpg"
|
||||||
sx={{ width: 36, height: 36 }}
|
sx={{ width: 36, height: 36 }}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</MenuButton>
|
</MenuButton>
|
||||||
<Menu
|
<Menu
|
||||||
anchorEl={anchorEl}
|
anchorEl={anchorEl}
|
||||||
id="menu"
|
id="menu"
|
||||||
open={open}
|
open={open}
|
||||||
onClose={handleClose}
|
onClose={handleClose}
|
||||||
onClick={handleClose}
|
onClick={handleClose}
|
||||||
transformOrigin={{ horizontal: 'right', vertical: 'top' }}
|
transformOrigin={{ horizontal: "right", vertical: "top" }}
|
||||||
anchorOrigin={{ horizontal: 'right', vertical: 'bottom' }}
|
anchorOrigin={{ horizontal: "right", vertical: "bottom" }}
|
||||||
sx={{
|
sx={{
|
||||||
[`& .${listClasses.root}`]: {
|
[`& .${listClasses.root}`]: {
|
||||||
padding: '4px',
|
padding: "4px",
|
||||||
},
|
},
|
||||||
[`& .${paperClasses.root}`]: {
|
[`& .${paperClasses.root}`]: {
|
||||||
padding: 0,
|
padding: 0,
|
||||||
},
|
},
|
||||||
[`& .${dividerClasses.root}`]: {
|
[`& .${dividerClasses.root}`]: {
|
||||||
margin: '4px -4px',
|
margin: "4px -4px",
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<MenuItem onClick={handleClose}>Profile</MenuItem>
|
<MenuItem onClick={handleClose}>Profile</MenuItem>
|
||||||
<MenuItem onClick={handleClose}>My account</MenuItem>
|
<MenuItem onClick={handleClose}>My account</MenuItem>
|
||||||
<Divider />
|
<Divider />
|
||||||
<MenuItem onClick={handleClose}>Add another account</MenuItem>
|
<MenuItem onClick={handleClose}>Add another account</MenuItem>
|
||||||
<MenuItem onClick={handleClose}>Settings</MenuItem>
|
<MenuItem onClick={handleClose}>Settings</MenuItem>
|
||||||
<Divider />
|
<Divider />
|
||||||
<MenuItem
|
<MenuItem
|
||||||
onClick={handleClose}
|
onClick={handleClose}
|
||||||
sx={{
|
sx={{
|
||||||
[`& .${listItemIconClasses.root}`]: {
|
[`& .${listItemIconClasses.root}`]: {
|
||||||
ml: 'auto',
|
ml: "auto",
|
||||||
minWidth: 0,
|
minWidth: 0,
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<ListItemText>Logout</ListItemText>
|
<ListItemText>Logout</ListItemText>
|
||||||
<ListItemIcon>
|
<ListItemIcon>
|
||||||
<LogoutRoundedIcon fontSize="small" />
|
<LogoutRoundedIcon fontSize="small" />
|
||||||
</ListItemIcon>
|
</ListItemIcon>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
</Menu>
|
</Menu>
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,118 +1,114 @@
|
||||||
import React, { useEffect, useState } from "react"
|
import React, { useEffect, useState } from "react";
|
||||||
import { Box, Button, Typography } from "@mui/material"
|
import { Box, Button, Typography } from "@mui/material";
|
||||||
import AddEditCategoryModal from "../../components/AddEditCategoryModal"
|
import AddEditCategoryModal from "../../components/AddEditCategoryModal";
|
||||||
import { useForm } from "react-hook-form"
|
import { useForm } from "react-hook-form";
|
||||||
import CustomTable from "../../components/CustomTable"
|
import CustomTable, { Column } from "../../components/CustomTable";
|
||||||
// import DeleteModal from "../../components/Modals/DeleteModal/DeleteModal"
|
import { useDispatch, useSelector } from "react-redux";
|
||||||
import { useDispatch, useSelector } from "react-redux"
|
import { adminList, updateAdmin } from "../../redux/slices/authSlice";
|
||||||
import { adminList } from "../../redux/slices/authSlice"
|
import { AppDispatch, RootState } from "../../redux/store/store"; // Import RootState for selector
|
||||||
import { AppDispatch, RootState } from "../../redux/store/store" // Import RootState for selector
|
|
||||||
|
|
||||||
// Sample data for categories
|
|
||||||
|
|
||||||
export default function AdminList() {
|
export default function AdminList() {
|
||||||
const [modalOpen, setModalOpen] = useState(false)
|
const [modalOpen, setModalOpen] = useState(false);
|
||||||
const [editRow, setEditRow] = useState<any>(null)
|
const { reset } = useForm();
|
||||||
const { reset } = useForm()
|
|
||||||
|
|
||||||
const [deleteModal, setDeleteModal] = React.useState<boolean>(false)
|
const [deleteModal, setDeleteModal] = React.useState<boolean>(false);
|
||||||
const [rowData, setRowData] = React.useState<any | null>(null)
|
const [rowData, setRowData] = React.useState<any | null>(null);
|
||||||
|
|
||||||
const dispatch = useDispatch<AppDispatch>()
|
const dispatch = useDispatch<AppDispatch>();
|
||||||
|
|
||||||
// Fetching admin data from the Redux store
|
// Fetching admin data from the Redux store
|
||||||
const admins = useSelector((state: RootState) => state.auth.admins)
|
const admins = useSelector((state: RootState) => state.auth.admins);
|
||||||
// Dispatching the API call when the component mounts
|
|
||||||
useEffect(() => {
|
|
||||||
dispatch(adminList())
|
|
||||||
}, [dispatch])
|
|
||||||
|
|
||||||
const handleClickOpen = () => {
|
// Dispatching the API call when the component mounts
|
||||||
setModalOpen(true)
|
useEffect(() => {
|
||||||
setEditRow(null)
|
dispatch(adminList());
|
||||||
}
|
}, [dispatch]);
|
||||||
|
|
||||||
const handleCloseModal = () => {
|
const handleClickOpen = () => {
|
||||||
setModalOpen(false)
|
setModalOpen(true);
|
||||||
reset()
|
};
|
||||||
}
|
|
||||||
|
|
||||||
// const handleDelete = () => {
|
const handleCloseModal = () => {
|
||||||
// setDeleteModal(false)
|
setModalOpen(false);
|
||||||
// }
|
reset();
|
||||||
|
};
|
||||||
|
|
||||||
const categoryColumns = [
|
const handleUpdate = async (id: string, name: string, role: string) => {
|
||||||
{ id: "srno", label: "Sr No" },
|
try {
|
||||||
{ id: "name", label: "Name" },
|
await dispatch(updateAdmin({ id, name, role }));
|
||||||
{ id: "role", label: "Role" },
|
await dispatch(adminList()); // Fetch updated admins list after update
|
||||||
{ id: "action", label: "Action", align: "center" },
|
} catch (error) {
|
||||||
]
|
console.error("Update failed", error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// If no admins are available, display the sample data
|
const categoryColumns: Column[] = [
|
||||||
const categoryRows = admins?.length
|
{ id: "srno", label: "Sr No" },
|
||||||
? admins?.map(
|
{ id: "name", label: "Name" },
|
||||||
(
|
{ id: "role", label: "Role" },
|
||||||
admin: { id: string; name: string; role: string },
|
{ id: "action", label: "Action", align: "center" },
|
||||||
index: number
|
];
|
||||||
) => ({
|
|
||||||
id: admin.id,
|
|
||||||
srno: index + 1,
|
|
||||||
name: admin?.name,
|
|
||||||
role: admin.role,
|
|
||||||
})
|
|
||||||
)
|
|
||||||
: []
|
|
||||||
|
|
||||||
return (
|
// If no admins are available, display the sample data
|
||||||
<>
|
const categoryRows = admins?.length
|
||||||
<Box
|
? admins?.map(
|
||||||
sx={{
|
(
|
||||||
width: "100%",
|
admin: { id: string; name: string; role: string },
|
||||||
maxWidth: {
|
index: number
|
||||||
sm: "100%",
|
) => ({
|
||||||
display: "flex",
|
id: admin?.id,
|
||||||
justifyContent: "space-between",
|
srno: index + 1,
|
||||||
alignItems: "center",
|
name: admin?.name,
|
||||||
},
|
role: admin?.role,
|
||||||
}}
|
})
|
||||||
>
|
)
|
||||||
{/* Title and Add Category button */}
|
: [];
|
||||||
<Typography
|
|
||||||
component="h2"
|
|
||||||
variant="h6"
|
|
||||||
sx={{ mt: 2, fontWeight: 600 }}
|
|
||||||
>
|
|
||||||
Admins
|
|
||||||
</Typography>
|
|
||||||
<Button
|
|
||||||
variant="contained"
|
|
||||||
size="medium"
|
|
||||||
sx={{ textAlign: "right" }}
|
|
||||||
onClick={handleClickOpen}
|
|
||||||
>
|
|
||||||
Add Category
|
|
||||||
</Button>
|
|
||||||
</Box>
|
|
||||||
|
|
||||||
<CustomTable
|
return (
|
||||||
columns={categoryColumns}
|
<>
|
||||||
rows={categoryRows}
|
<Box
|
||||||
editRow={editRow}
|
sx={{
|
||||||
setDeleteModal={setDeleteModal}
|
width: "100%",
|
||||||
deleteModal={deleteModal}
|
maxWidth: {
|
||||||
setRowData={setRowData}
|
sm: "100%",
|
||||||
setModalOpen={setModalOpen}
|
display: "flex",
|
||||||
/>
|
justifyContent: "space-between",
|
||||||
<AddEditCategoryModal
|
alignItems: "center",
|
||||||
open={modalOpen}
|
},
|
||||||
handleClose={handleCloseModal}
|
}}
|
||||||
editRow={rowData}
|
>
|
||||||
/>
|
{/* Title and Add Category button */}
|
||||||
{/* <DeleteModal
|
<Typography
|
||||||
open={deleteModal}
|
component="h2"
|
||||||
setDeleteModal={setDeleteModal}
|
variant="h6"
|
||||||
handleDelete={handleDelete}
|
sx={{ mt: 2, fontWeight: 600 }}
|
||||||
/> */}
|
>
|
||||||
</>
|
Admins
|
||||||
)
|
</Typography>
|
||||||
|
<Button
|
||||||
|
variant="contained"
|
||||||
|
size="medium"
|
||||||
|
sx={{ textAlign: "right" }}
|
||||||
|
onClick={handleClickOpen}
|
||||||
|
>
|
||||||
|
Add Category
|
||||||
|
</Button>
|
||||||
|
</Box>
|
||||||
|
|
||||||
|
<CustomTable
|
||||||
|
columns={categoryColumns}
|
||||||
|
rows={categoryRows}
|
||||||
|
setDeleteModal={setDeleteModal}
|
||||||
|
deleteModal={deleteModal}
|
||||||
|
setRowData={setRowData}
|
||||||
|
setModalOpen={setModalOpen}
|
||||||
|
/>
|
||||||
|
<AddEditCategoryModal
|
||||||
|
open={modalOpen}
|
||||||
|
handleClose={handleCloseModal}
|
||||||
|
editRow={rowData}
|
||||||
|
handleUpdate={handleUpdate}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,249 +1,260 @@
|
||||||
import {
|
import {
|
||||||
createSlice,
|
createSlice,
|
||||||
createAsyncThunk,
|
createAsyncThunk,
|
||||||
PayloadAction,
|
PayloadAction,
|
||||||
isRejectedWithValue,
|
} from "@reduxjs/toolkit";
|
||||||
} from "@reduxjs/toolkit"
|
import axios from "axios";
|
||||||
import axios from "axios"
|
import { backendHttp, apiHttp } from "../../lib/https";
|
||||||
import { backendHttp, apiHttp } from "../../lib/https"
|
import { toast } from "react-toastify";
|
||||||
import { toast } from "react-toastify"
|
|
||||||
|
|
||||||
// Define types for state
|
// Define types for state
|
||||||
interface User {
|
interface User {
|
||||||
map(
|
map(
|
||||||
arg0: (
|
arg0: (
|
||||||
admin: { name: any; role: any },
|
admin: { name: any; role: any },
|
||||||
index: number
|
index: number
|
||||||
) => { srno: number; name: any; role: any }
|
) => { srno: number; name: any; role: any }
|
||||||
): unknown
|
): unknown;
|
||||||
id: string
|
id: string;
|
||||||
email: string
|
email: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Admin {
|
interface Admin {
|
||||||
id: string
|
id: string;
|
||||||
name: string
|
name: string;
|
||||||
role: string
|
role: string;
|
||||||
}
|
}
|
||||||
interface AuthState {
|
interface AuthState {
|
||||||
user: User | null
|
user: User | null;
|
||||||
admins: Admin[]
|
admins: Admin[];
|
||||||
isAuthenticated: boolean
|
isAuthenticated: boolean;
|
||||||
isLoading: boolean
|
isLoading: boolean;
|
||||||
error: string | null
|
error: object | string | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Async thunk for login
|
// Async thunk for login
|
||||||
export const loginUser = createAsyncThunk<
|
export const loginUser = createAsyncThunk<
|
||||||
User,
|
User,
|
||||||
{ email: string; password: string },
|
{ email: string; password: string },
|
||||||
{ rejectValue: string }
|
{ rejectValue: string }
|
||||||
>("auth/login", async ({ email, password }, { rejectWithValue }) => {
|
>("auth/login", async ({ email, password }, { rejectWithValue }) => {
|
||||||
try {
|
try {
|
||||||
const response = await backendHttp.post("admin/login", {
|
const response = await backendHttp.post("admin/login", {
|
||||||
email,
|
email,
|
||||||
password,
|
password,
|
||||||
})
|
});
|
||||||
localStorage.setItem("authToken", response.data?.data?.token) // Save token
|
localStorage.setItem("authToken", response.data?.data?.token); // Save token
|
||||||
toast.success(response.data?.message)
|
toast.success(response.data?.message);
|
||||||
return response.data
|
return response.data;
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
return rejectWithValue(
|
return rejectWithValue(
|
||||||
error.response?.data?.message || "An error occurred"
|
error.response?.data?.message || "An error occurred"
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
|
|
||||||
// Async thunk for register
|
// Async thunk for register
|
||||||
export const registerUser = createAsyncThunk<
|
export const registerUser = createAsyncThunk<
|
||||||
User,
|
User,
|
||||||
{ email: string; password: string },
|
{ email: string; password: string },
|
||||||
{ rejectValue: string }
|
{ rejectValue: string }
|
||||||
>("auth/register", async (data, { rejectWithValue }) => {
|
>("auth/register", async (data, { rejectWithValue }) => {
|
||||||
try {
|
try {
|
||||||
const response = await axios.post(
|
const response = await axios.post(
|
||||||
"https://health-digi.dmlabs.in/auth/register",
|
"https://health-digi.dmlabs.in/auth/register",
|
||||||
data
|
data
|
||||||
)
|
);
|
||||||
return response.data
|
return response.data;
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
return rejectWithValue(
|
return rejectWithValue(
|
||||||
error.response?.data?.message || "An error occurred"
|
error.response?.data?.message || "An error occurred"
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
|
|
||||||
|
//created by Eknoor and jaanvi
|
||||||
|
//date: 10-Feb-2025
|
||||||
|
//Fetching list of admins
|
||||||
|
|
||||||
export const adminList = createAsyncThunk<
|
export const adminList = createAsyncThunk<
|
||||||
Admin[],
|
Admin[],
|
||||||
void,
|
void,
|
||||||
{ rejectValue: string }
|
{ rejectValue: string }
|
||||||
>("/auth", async (_, { rejectWithValue }) => {
|
>("/auth", async (_, { rejectWithValue }) => {
|
||||||
try {
|
try {
|
||||||
const response = await apiHttp.get("/auth")
|
const response = await apiHttp.get("/auth");
|
||||||
console.log(response?.data?.data)
|
console.log(response?.data?.data);
|
||||||
return response?.data?.data?.map(
|
return response?.data?.data?.map(
|
||||||
(admin: { id: string; name: string; role: string }) => ({
|
(admin: { id: string; name: string; role: string }) => ({
|
||||||
id: admin.id,
|
id: admin.id,
|
||||||
name: admin?.name,
|
name: admin?.name,
|
||||||
role: admin?.role || "N/A",
|
role: admin?.role || "N/A",
|
||||||
})
|
})
|
||||||
)
|
);
|
||||||
console.log(response.data.data)
|
} catch (error: any) {
|
||||||
} catch (error: any) {
|
return rejectWithValue(
|
||||||
return rejectWithValue(
|
error.response?.data?.message || "An error occurred"
|
||||||
error.response?.data?.message || "An error occurred"
|
);
|
||||||
)
|
}
|
||||||
}
|
});
|
||||||
})
|
|
||||||
|
//created by Eknoor
|
||||||
|
//date: 11-Feb-2025
|
||||||
|
//function for deleting admin
|
||||||
|
|
||||||
export const deleteAdmin = createAsyncThunk<
|
export const deleteAdmin = createAsyncThunk<
|
||||||
string,
|
string,
|
||||||
string,
|
string,
|
||||||
{ rejectValue: string }
|
{ rejectValue: string }
|
||||||
>("deleteAdmin", async (id, { rejectWithValue }) => {
|
>("deleteAdmin", async (id, { rejectWithValue }) => {
|
||||||
try {
|
try {
|
||||||
const response = await apiHttp.delete(`/auth/${id}`)
|
const response = await apiHttp.delete(`/auth/${id}`);
|
||||||
// console.log(response, "response of deletion")
|
toast.success(response.data?.message);
|
||||||
return id // Returning the deleted admin's ID
|
return id;
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
return rejectWithValue(
|
return rejectWithValue(
|
||||||
error.response?.data?.message || "An error occurred"
|
error.response?.data?.message || "An error occurred"
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
|
|
||||||
// export const putAdmin = createAsyncThunk<
|
export const updateAdmin = createAsyncThunk(
|
||||||
// Admin, // Return type (updated admin object)
|
"/auth/id",
|
||||||
// { id: string; data: Partial<Admin> }, // Argument type
|
async (
|
||||||
// { rejectValue: string } // Rejection type
|
{ id, name, role }: { id: any; name: string; role: string },
|
||||||
// >(
|
{ rejectWithValue }
|
||||||
// "updateAdmin",
|
) => {
|
||||||
// async ({ id, data }, { rejectWithValue }) => {
|
try {
|
||||||
// try {
|
const response = await apiHttp.put(`/auth/${id}`, { name, role });
|
||||||
// const response = await apiHttp.put(`/auth/${id}`, data)
|
toast.success("Admin updated successfully");
|
||||||
// return response.data // Ensure response contains the updated admin object
|
console.log(response.data);
|
||||||
// } catch (error: any) {
|
return response.data;
|
||||||
// return rejectWithValue(
|
} catch (error: any) {
|
||||||
// error.response?.data?.message || "An error occurred"
|
return rejectWithValue(
|
||||||
// )
|
error.response?.data?.message || "An error occurred"
|
||||||
// }
|
);
|
||||||
// }
|
}
|
||||||
// )
|
}
|
||||||
|
);
|
||||||
|
|
||||||
const initialState: AuthState = {
|
const initialState: AuthState = {
|
||||||
user: null,
|
user: null,
|
||||||
admins: [],
|
admins: [],
|
||||||
isAuthenticated: false,
|
isAuthenticated: false,
|
||||||
isLoading: false,
|
isLoading: false,
|
||||||
error: null,
|
error: null,
|
||||||
}
|
};
|
||||||
|
|
||||||
const authSlice = createSlice({
|
const authSlice = createSlice({
|
||||||
name: "auth",
|
name: "auth",
|
||||||
initialState,
|
initialState,
|
||||||
reducers: {
|
reducers: {
|
||||||
logout: (state) => {
|
logout: (state) => {
|
||||||
state.user = null
|
state.user = null;
|
||||||
state.isAuthenticated = false
|
state.isAuthenticated = false;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
extraReducers: (builder) => {
|
extraReducers: (builder) => {
|
||||||
builder
|
builder
|
||||||
// Login
|
// Login
|
||||||
.addCase(loginUser.pending, (state) => {
|
.addCase(loginUser.pending, (state) => {
|
||||||
state.isLoading = true
|
state.isLoading = true;
|
||||||
state.error = null
|
state.error = null;
|
||||||
})
|
})
|
||||||
.addCase(
|
.addCase(
|
||||||
loginUser.fulfilled,
|
loginUser.fulfilled,
|
||||||
(state, action: PayloadAction<User>) => {
|
(state, action: PayloadAction<User>) => {
|
||||||
state.isLoading = false
|
state.isLoading = false;
|
||||||
state.isAuthenticated = true
|
state.isAuthenticated = true;
|
||||||
state.user = action.payload
|
state.user = action.payload;
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
.addCase(
|
.addCase(
|
||||||
loginUser.rejected,
|
loginUser.rejected,
|
||||||
(state, action: PayloadAction<string | undefined>) => {
|
(state, action: PayloadAction<string | undefined>) => {
|
||||||
state.isLoading = false
|
state.isLoading = false;
|
||||||
state.error = action.payload || "An error occurred"
|
state.error = action.payload || "An error occurred";
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
// Register
|
// Register
|
||||||
.addCase(registerUser.pending, (state) => {
|
.addCase(registerUser.pending, (state) => {
|
||||||
state.isLoading = true
|
state.isLoading = true;
|
||||||
state.error = null
|
state.error = null;
|
||||||
})
|
})
|
||||||
.addCase(
|
.addCase(
|
||||||
registerUser.fulfilled,
|
registerUser.fulfilled,
|
||||||
(state, action: PayloadAction<User>) => {
|
(state, action: PayloadAction<User>) => {
|
||||||
state.isLoading = false
|
state.isLoading = false;
|
||||||
state.isAuthenticated = true
|
state.isAuthenticated = true;
|
||||||
state.user = action.payload
|
state.user = action.payload;
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
.addCase(
|
.addCase(
|
||||||
registerUser.rejected,
|
registerUser.rejected,
|
||||||
(state, action: PayloadAction<string | undefined>) => {
|
(state, action: PayloadAction<string | undefined>) => {
|
||||||
state.isLoading = false
|
state.isLoading = false;
|
||||||
state.error = action.payload || "An error occurred"
|
state.error = action.payload || "An error occurred";
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
// created by Jaanvi and Eknoor
|
// created by Jaanvi and Eknoor
|
||||||
//AdminList
|
//AdminList
|
||||||
.addCase(adminList.pending, (state) => {
|
.addCase(adminList.pending, (state) => {
|
||||||
state.isLoading = true
|
state.isLoading = true;
|
||||||
state.error = null
|
state.error = null;
|
||||||
})
|
})
|
||||||
.addCase(
|
.addCase(
|
||||||
adminList.fulfilled,
|
adminList.fulfilled,
|
||||||
(state, action: PayloadAction<Admin[]>) => {
|
(state, action: PayloadAction<Admin[]>) => {
|
||||||
state.isLoading = false
|
state.isLoading = false;
|
||||||
state.admins = action.payload
|
state.admins = action.payload;
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
.addCase(
|
.addCase(
|
||||||
adminList.rejected,
|
adminList.rejected,
|
||||||
(state, action: PayloadAction<string | undefined>) => {
|
(state, action: PayloadAction<string | undefined>) => {
|
||||||
state.isLoading = false
|
state.isLoading = false;
|
||||||
state.error = action.payload || "An error occurred"
|
state.error = action.payload || "An error occurred";
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
.addCase(deleteAdmin.pending, (state) => {
|
//created by Eknoor
|
||||||
state.isLoading = true
|
//date: 11-Feb-2025
|
||||||
})
|
//cases for deleting admin
|
||||||
.addCase(deleteAdmin.fulfilled, (state, action) => {
|
.addCase(deleteAdmin.pending, (state) => {
|
||||||
state.isLoading = false
|
state.isLoading = true;
|
||||||
state.admins = state.admins.filter(
|
})
|
||||||
(admin) => String(admin.id) !== String(action.payload)
|
.addCase(deleteAdmin.fulfilled, (state, action) => {
|
||||||
)
|
state.isLoading = false;
|
||||||
})
|
state.admins = state.admins.filter(
|
||||||
.addCase(deleteAdmin.rejected, (state, action) => {
|
(admin) => String(admin.id) !== String(action.payload)
|
||||||
state.isLoading = false
|
);
|
||||||
state.error = action.payload || "Failed to delete admin"
|
})
|
||||||
})
|
.addCase(deleteAdmin.rejected, (state, action) => {
|
||||||
//update Admin
|
state.isLoading = false;
|
||||||
|
state.error = action.payload || "Failed to delete admin";
|
||||||
|
})
|
||||||
|
.addCase(updateAdmin.pending, (state) => {
|
||||||
|
state.isLoading = true;
|
||||||
|
state.error = null;
|
||||||
|
})
|
||||||
|
.addCase(updateAdmin.fulfilled, (state, action) => {
|
||||||
|
const updatedAdmin = action.payload;
|
||||||
|
state.admins = state.admins.map((admin) =>
|
||||||
|
admin.id === updatedAdmin.id ? updatedAdmin : admin
|
||||||
|
);
|
||||||
|
|
||||||
// .addCase(putAdmin.pending, (state) => {
|
state.isLoading = false;
|
||||||
// state.isLoading = true
|
})
|
||||||
// state.error = null
|
.addCase(updateAdmin.rejected, (state, action) => {
|
||||||
// })
|
state.isLoading = false;
|
||||||
// .addCase(putAdmin.fulfilled, (state, action: PayloadAction<Admin>) => {
|
state.error =
|
||||||
// state.isLoading = false
|
action.payload ||
|
||||||
// state.admins = state.admins.map((admin) =>
|
"Something went wrong while updating Admin!!";
|
||||||
// admin.id === action.payload.id ? action.payload : admin
|
});
|
||||||
// )
|
},
|
||||||
// })
|
});
|
||||||
// .addCase(putAdmin.rejected, (state, action: PayloadAction<string | undefined>) => {
|
|
||||||
// state.isLoading = false
|
|
||||||
// state.error = action.payload || "Failed to update admin"
|
|
||||||
// })
|
|
||||||
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
export const { logout } = authSlice.actions
|
export const { logout } = authSlice.actions;
|
||||||
export default authSlice.reducer
|
export default authSlice.reducer;
|
||||||
|
|
Loading…
Reference in a new issue