dev-jaanvi #1

Open
jaanvi wants to merge 155 commits from dev-jaanvi into main
10 changed files with 20745 additions and 8365 deletions
Showing only changes of commit 575e122b02 - Show all commits

13559
package-lock.json generated Normal file

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -45,7 +45,7 @@ const AddEditCategoryModal: React.FC<AddEditCategoryModalProps> = ({ open, handl
onSubmit: handleSubmit(onSubmit),
}}
>
<DialogTitle>{editRow ? "Edit" : 'Add'} Category</DialogTitle>
<DialogTitle>{editRow ? "Editwefwefwe" : 'Add'} Category</DialogTitle>
<DialogContent>
<Controller
name="category"

View file

@ -45,7 +45,7 @@ const AddEditTagsModal: React.FC<AddEditTagsModalProps> = ({ open, handleClose,e
onSubmit: handleSubmit(onSubmit),
}}
>
<DialogTitle>{editRow ? "Edit" : 'Add'} Tag</DialogTitle>
<DialogTitle>{editRow ? "Editsefwefwe" : 'Add'} Tag</DialogTitle>
<DialogContent>
<Controller
name="tag"

View file

@ -6,6 +6,7 @@ import ListItemText from '@mui/material/ListItemText';
import Stack from '@mui/material/Stack';
import HomeRoundedIcon from '@mui/icons-material/HomeRounded';
import AnalyticsRoundedIcon from '@mui/icons-material/AnalyticsRounded';
import FormatListBulletedIcon from '@mui/icons-material/FormatListBulleted';
import { Link, useLocation } from 'react-router-dom';
const mainListItems = [
@ -19,6 +20,12 @@ const mainListItems = [
icon: <AnalyticsRoundedIcon />,
url: '/panel/vehicles',
},
//created by Eknnor and Jaanvi
{
text: 'Admin List',
icon: <FormatListBulletedIcon />,
url: '/panel/adminlist',
},
];
type PropType = {

View file

@ -1,16 +1,45 @@
import axios from 'axios';
// import axios from 'axios';
const http = axios.create({
// const http = axios.create({
// baseURL: process.env.REACT_APP_BACKEND_URL,
// });
// console.log(process.env.REACT_APP_BACKEND_URL);
// http.interceptors.request.use((config) => {
// const authToken = localStorage.getItem('authToken');
// if (authToken) {
// config.headers.Authorization = authToken;
// }
// return config;
// });
// export default http;
import axios, { AxiosInstance } from 'axios';
// Axios instance for the production backend
const backendHttp = axios.create({
baseURL: process.env.REACT_APP_BACKEND_URL,
});
console.log(process.env.REACT_APP_BACKEND_URL);
http.interceptors.request.use((config) => {
const authToken = localStorage.getItem('authToken');
if (authToken) {
config.headers.Authorization = authToken;
}
return config;
// Axios instance for the local API
const apiHttp = axios.create({
baseURL: "http://localhost:5000/api",
});
export default http;
// Add interceptors to both instances
const addAuthInterceptor = (instance: AxiosInstance) => {
instance.interceptors.request.use((config) => {
const authToken = localStorage.getItem('authToken');
if (authToken) {
config.headers.Authorization = authToken;
}
return config;
});
};
addAuthInterceptor(backendHttp);
addAuthInterceptor(apiHttp);
export { backendHttp, apiHttp };

View file

@ -0,0 +1,115 @@
import React, { useEffect, useState } from "react"
import { Box, Button, Typography } from "@mui/material"
import AddEditCategoryModal from "../../components/AddEditCategoryModal"
import { useForm } from "react-hook-form"
import CustomTable from "../../components/CustomTable"
import DeleteModal from "../../components/Modals/DeleteModal/DeleteModal"
import { useDispatch, useSelector } from "react-redux"
import { adminList } from "../../redux/slices/authSlice"
import { AppDispatch, RootState } from "../../redux/store/store" // Import RootState for selector
// Sample data for categories
export default function AdminList() {
const [modalOpen, setModalOpen] = useState(false)
const [editRow, setEditRow] = useState<any>(null)
const { reset } = useForm()
const [deleteModal, setDeleteModal] = React.useState<boolean>(false)
const [rowData, setRowData] = React.useState<any | null>(null)
const dispatch = useDispatch<AppDispatch>();
// Fetching admin data from the Redux store
const admins = useSelector((state: RootState) => state.auth.admins);
console.log(admins, "woihfiuwhfownfownefoi")
// Dispatching the API call when the component mounts
useEffect(() => {
dispatch(adminList());
}, [dispatch]);
const handleClickOpen = () => {
setModalOpen(true)
setEditRow(null)
}
const handleCloseModal = () => {
setModalOpen(false)
reset()
}
const handleDelete = () => {
setDeleteModal(false)
}
const categoryColumns = [
{ id: "srno", label: "Sr No" },
{ id: "name", label: "Name" },
{ id: "role", label: "Role" },
{ id: "action", label: "Action", align: "center" },
]
// If no admins are available, display the sample data
const categoryRows = admins?.length ? admins?.map((admin: { name: any; role: any }, index: number) => ({
srno: index + 1,
name: admin?.name,
role: admin.role,
})) : []
return (
<>
<Box
sx={{
width: "100%",
maxWidth: {
sm: "100%",
display: "flex",
justifyContent: "space-between",
alignItems: "center",
},
}}
>
{/* 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
columns={categoryColumns}
rows={categoryRows}
editRow={editRow}
setDeleteModal={setDeleteModal}
setRowData={setRowData}
setModalOpen={setModalOpen}
/>
<AddEditCategoryModal
open={modalOpen}
handleClose={handleCloseModal}
editRow={rowData}
/>
<DeleteModal
open={deleteModal}
setDeleteModal={setDeleteModal}
handleDelete={handleDelete}
/>
</>
)
}

View file

@ -1,19 +1,26 @@
import { createSlice, createAsyncThunk, PayloadAction } from "@reduxjs/toolkit"
import axios from "axios"
import http from "../../lib/https"
import { backendHttp, apiHttp } from "../../lib/https"
import { toast } from "react-toastify"
// Define types for state
interface User {
map(arg0: (admin: { name: any; role: any }, index: number) => { srno: number; name: any; role: any }): unknown
id: string
email: string
}
interface Admin {
id: string,
name: string,
role: string
}
interface AuthState {
user: User | null
isAuthenticated: boolean
isLoading: boolean
error: string | null
user: User | null;
admins: Admin[];
isAuthenticated: boolean;
isLoading: boolean;
error: string | null;
}
// Async thunk for login
@ -23,7 +30,7 @@ export const loginUser = createAsyncThunk<
{ rejectValue: string }
>("auth/login", async ({ email, password }, { rejectWithValue }) => {
try {
const response = await http.post("admin/login", { email, password })
const response = await backendHttp.post("admin/login", { email, password })
localStorage.setItem("authToken", response.data?.data?.token) // Save token
toast.success(response.data?.message)
return response.data
@ -53,12 +60,33 @@ export const registerUser = createAsyncThunk<
}
})
export const adminList = createAsyncThunk<
Admin[],
void,
{ rejectValue: string }
>("/auth", async (_, { rejectWithValue }) => {
try {
const response = await apiHttp.get("/auth");
console.log(response)
return response?.data?.data?.map((admin: { name: string; role: string }) => ({
name: admin?.name,
role: admin?.role || "N/A",
}));
console.log(response.data.data)
} catch (error: any) {
return rejectWithValue(error.response?.data?.message || "An error occurred");
}
});
const initialState: AuthState = {
user: null,
admins: [],
isAuthenticated: false,
isLoading: false,
error: null,
}
};
const authSlice = createSlice({
name: "auth",
@ -111,6 +139,25 @@ const authSlice = createSlice({
state.error = action.payload || "An error occurred"
}
)
// created by Jaanvi and Eknoor
.addCase(adminList.pending, (state) => {
state.isLoading = true
state.error = null
})
.addCase(adminList.fulfilled, (state, action: PayloadAction<Admin[]>) => {
state.isLoading = false;
state.admins = action.payload; // ✅ Store admins correctly
})
.addCase(
adminList.rejected,
(state, action: PayloadAction<string | undefined>) => {
state.isLoading = false
state.error = action.payload || "An error occurred"
}
)
},
})

View file

@ -1,54 +1,74 @@
import { Routes as BaseRoutes, Navigate, Route } from 'react-router-dom';
import { Routes as BaseRoutes, Navigate, Route } from "react-router-dom"
// import useAuth from "./hooks/useAuth";
import React, { Suspense } from 'react';
import LoadingComponent from './components/Loading';
import DashboardLayout from './layouts/DashboardLayout';
import Login from './pages/Auth/Login';
import SignUp from './pages/Auth/SignUp';
import Dashboard from './pages/Dashboard';
import Vehicles from './pages/Vechiles';
import React, { Suspense } from "react"
import LoadingComponent from "./components/Loading"
import DashboardLayout from "./layouts/DashboardLayout"
import Login from "./pages/Auth/Login"
import SignUp from "./pages/Auth/SignUp"
import Dashboard from "./pages/Dashboard"
import Vehicles from "./pages/Vechiles"
import AdminList from "./pages/AdminList"
function ProtectedRoute({
caps,
component,
caps,
component,
}: {
caps: string[];
component: React.ReactNode;
caps: string[]
component: React.ReactNode
}) {
if (!localStorage.getItem('authToken'))
return <Navigate to={`/auth/login`} replace />;
if (!localStorage.getItem("authToken"))
return <Navigate to={`/auth/login`} replace />
return component;
return component
}
export default function AppRouter() {
return (
<Suspense fallback={<LoadingComponent />}>
<BaseRoutes>
<Route element={<Navigate to="/auth/login" replace />} index />
return (
<Suspense fallback={<LoadingComponent />}>
<BaseRoutes>
<Route element={<Navigate to="/auth/login" replace />} index />
<Route path="/auth">
<Route
path=""
element={<Navigate to="/auth/login" replace />}
index
/>
<Route path="login" element={<Login />} />
<Route path="signup" element={<SignUp />} />
</Route>
<Route path="/panel" element={<DashboardLayout />}>
<Route
path="dashboard"
element={<ProtectedRoute caps={[]} component={<Dashboard />} />}
/>
<Route
path="vehicles"
element={<ProtectedRoute caps={[]} component={<Vehicles />} />}
/>
<Route path="*" element={<>404</>} />
</Route>
<Route path="*" element={<>404</>} />
</BaseRoutes>
</Suspense>
);
<Route path="/auth">
<Route
path=""
element={<Navigate to="/auth/login" replace />}
index
/>
<Route path="login" element={<Login />} />
<Route path="signup" element={<SignUp />} />
</Route>
<Route path="/panel" element={<DashboardLayout />}>
<Route
path="dashboard"
element={
<ProtectedRoute
caps={[]}
component={<Dashboard />}
/>
}
/>
<Route
path="vehicles"
element={
<ProtectedRoute
caps={[]}
component={<Vehicles />}
/>
}
/>
<Route
path="adminlist"
element={
<ProtectedRoute
caps={[]}
component={<AdminList />}
/>
}
/>
<Route path="*" element={<>404</>} />
</Route>
<Route path="*" element={<>404</>} />
</BaseRoutes>
</Suspense>
)
}