This commit is contained in:
YasinShaikh123
2025-02-11 14:47:39 +05:30
16 changed files with 158 additions and 64 deletions

View File

@@ -1,20 +1,20 @@
import { useContext } from 'react';
import { Route, BrowserRouter as Router, Routes } from "react-router-dom";
import GlobalStateContext from './Contexts/GlobalStateContext';
import DefaultLayout from './Layouts/DefaultLayout';
import Login from './Pages/Login';
import { RouteLink } from './Routes/Routes';
import Cookies from "js-cookie";
function App() {
// const context = useContext(GlobalStateContext);
// if (!context) throw new Error('App must be used within a GlobalStateProvider');
// const { isAuthenticate } = context;
const token = Cookies.get("token")
const context = useContext(GlobalStateContext);
if (!context) throw new Error('App must be used within a GlobalStateProvider');
const { isAuthenticate } = context;
return (
<Router>
<Routes>
<Route path="/login" element={<Login />} />
<Route path="/*" element={token ? (<DefaultLayout><Routes>{RouteLink.map(({ path, Component }, index) => (<Route key={index} path={path} element={<Component />} />))}</Routes></DefaultLayout>) : (<Login />)} />
<Route path="/*" element={localStorage.getItem("token")? (<DefaultLayout><Routes>{RouteLink.map(({ path, Component }, index) => (<Route key={index} path={path} element={<Component />} />))}</Routes></DefaultLayout>) : (<Login />)} />
<Route path="*" element={<Login />} />
</Routes>
</Router>

View File

@@ -1,11 +1,11 @@
import { ReactNode, useState } from 'react';
import { ReactNode, useState } from 'react';
import GlobalStateContext from './GlobalStateContext';
const GlobalStateProvider = ({ children }:{children:ReactNode}) => {
const [isAuthenticate, setIsAuthenticate] = useState<boolean>(false);
const GlobalStateProvider = ({ children }: { children: ReactNode }) => {
const [isAuthenticate, setIsAuthenticate] = useState<boolean>(true);
return (
<GlobalStateContext.Provider value={{ isAuthenticate, setIsAuthenticate }}>

View File

@@ -6,8 +6,12 @@ import { nav } from "../Routes/Nav";
import logo from '../assets/logo.svg';
import { AccordionItem, AccordionItemContent, AccordionItemTrigger, AccordionRoot } from "../components/ui/accordion";
import { Avatar } from "../components/ui/avatar";
import { LuLogOut } from "react-icons/lu";
import { logout, setToken } from "../Redux/Service/authSlice";
import { useDispatch } from "react-redux";
const DefaultLayout: FC<{ children: React.ReactNode }> = ({ children }) => {
const dispatch = useDispatch()
const navigate = useNavigate()
const location = useLocation()
@@ -15,25 +19,31 @@ const DefaultLayout: FC<{ children: React.ReactNode }> = ({ children }) => {
return (
<HStack position={'relative'} bg="#F2F2F2" backgroundPosition="center" backgroundRepeat="repeat" backgroundSize="cover" gap={0} w="100%" h="100vh" p={0}>
<HStack overflow={'hidden'} position={'relative'} bg="#F2F2F2" backgroundPosition="center" backgroundRepeat="repeat" backgroundSize="cover" gap={0} w="100%" h="100vh" p={0}>
<VStack zIndex={1} gap={0} rounded={'lg'} h="100%" w="16%" overflow={'scroll'} >
<VStack zIndex={1} gap={0} rounded={'lg'} h="100%" w="16%" overflow={'auto'} >
<HStack w={'100%'} p={3} h={'8%'} justifyContent={'center'}>
<Image w={55} src={logo} />
</HStack>
<VStack w={'100%'} p={4} pt={0}>
<VStack w={'100%'} p={4} pt={0}>
{nav?.map(({ title, path, Icon, type, children }, index) => type === 'single' ?
<NavLink className="link" key={index} to={path} style={{ cursor: 'pointer', borderRadius: '8px', padding: '6px', width: '100%', display: 'flex', alignItems: 'center', gap: 6, border: '1px solid #ffffff', backgroundColor:'#fff', color:'#000', boxShadow:'rgba(99, 99, 99, 0.2) 0px 2px 8px 0px'}} ><Icon style={{ fontSize: '20px' }} /> <Text fontSize={'xs'} w={'100%'}>{title}</Text></NavLink> :
<AccordionRoot bg={'#fff'} rounded={'lg'} collapsible>
<AccordionItem boxShadow={'rgba(99, 99, 99, 0.2) 0px 2px 8px 0px'} borderBottom={'none'} p={0} key={index} value={title}>
<AccordionItem rounded={'lg'} bg={'#fff'} boxShadow={'rgba(99, 99, 99, 0.2) 0px 2px 8px 0px'} borderBottom={'none'} p={0} key={index} value={title}>
<AccordionItemTrigger className="Oxygen" color={'#fff'} onClick={() => navigate(path)} gap={0} style={{ cursor: 'pointer', borderRadius: '8px', padding: '5px', width: '100%', display: 'flex', alignItems: 'center', border: '1px solid #ffffff', backgroundColor:'#fff',color:'#000', fontSize: '14px', }}> <Text fontSize={'xs'} gap={1} display={'flex'} alignItems={'center'} ><Icon style={{ fontSize: '20px' }} />{title}</Text></AccordionItemTrigger>
{children?.map(({ title, path, Icon }, index) => <AccordionItemContent className={`linkChild Oxygen ${location?.pathname === path && 'activeChild'}`} key={index} onClick={()=>navigate(path)} style={{ marginTop: 6, cursor: 'pointer', borderRadius: '8px', padding: '6px', width: '100%', display: 'flex', alignItems: 'center', gap: 6, border: '1px solid #ffffff', backgroundColor:'#fff',color:'#919198' }} ><Icon style={{ fontSize: '20px' }} /> <Text fontSize={'xs'} w={'100%'}>{title}</Text></AccordionItemContent>)}
</AccordionItem>
</AccordionRoot>)}
</VStack>
<VStack w={'100%'} p={3} pt={0}>
<HStack onClick={()=>{dispatch(logout()), navigate('/login')}} className="link" style={{ cursor: 'pointer', borderRadius: '8px', padding: '6px', width: '100%', display: 'flex', alignItems: 'center', gap: 6, border: '1px solid #ffffff', backgroundColor:'#fff', color:'#000', boxShadow:'rgba(99, 99, 99, 0.2) 0px 2px 8px 0px'}} ><LuLogOut style={{ fontSize: '20px' }} /> <Text fontSize={'xs'} w={'100%'}>Logout</Text></HStack>
</VStack>
</VStack>
<VStack gap={0} h="100%" w="85%" >
<HStack h={'8%'} w={'100%'} justifyContent={'flex-end'} pe={3} gap={6}>
<VStack gap={0} h="100%" w="85%" >
<HStack h={'12%'} w={'100%'} justifyContent={'flex-end'} pe={3} gap={6}>
<NavLink to={'/manage-notification'}><RiNotificationLine color="#013e3e" cursor={'pointer'} style={{ fontSize: '22px' }} /></NavLink>
<HStack cursor={'pointer'} onClick={() => navigate('/profile')} >
<Avatar size={'sm'} src="https://i.pinimg.com/736x/d6/cd/0f/d6cd0ffd4634b0763d3958a7325ce26e.jpg" />

View File

@@ -67,8 +67,8 @@ const Dashboard = () => {
return (
<MainFrame>
<Box display={"flex"} p={"20px"} gap={5}>
<Box w={"30%"} boxShadow={"rgba(99, 99, 99, 0.2) 0px 2px 8px 0px"}>
<Box display={"flex"} p={"20px"} pt={'8px'} gap={5}>
<Box rounded={'lg'} w={"30%"} boxShadow={"rgba(99, 99, 99, 0.2) 0px 2px 8px 0px"}>
<Heading fontSize={"sm"} p={2}>
Total Users
</Heading>
@@ -117,6 +117,7 @@ const Dashboard = () => {
<Box
p={"20px"}
w={"50%"}
rounded={'lg'}
boxShadow={"rgba(99, 99, 99, 0.2) 0px 2px 8px 0px"}
>
<HStack alignItems={"center"} mb={4}>
@@ -140,13 +141,14 @@ const Dashboard = () => {
w={"20%"}
boxShadow={"rgba(99, 99, 99, 0.2) 0px 2px 8px 0px"}
p={'10px'}
rounded={'lg'}
>
<Text fontSize={"sm"} fontWeight={500} pt={3}>Number Of Groups created</Text>
<CircularApp />
</Box>
</Box>
<Box p={"20px"} display={"flex"} gap={5}>
<Box w={"50%"} bg={"#f2f2f2"} h={400} p={"10px"} overflow={'scroll'}>
<Box p={"20px"} pt={0} display={"flex"} gap={5}>
<Box w={"50%"} rounded={'lg'} bg={"#f2f2f2"} h={400} p={"10px"} overflow={'auto'}>
<HStack justifyContent={"space-between"} mb={5}>
<Text fontSize={"xs"} fontWeight={500}>Faqs</Text>
<Button
@@ -180,7 +182,7 @@ const Dashboard = () => {
))}
</AccordionRoot>
</Box>
<Box w={"50%"} bg={"#f2f2f2"} h={400} overflow={'scroll'}>
<Box w={"50%"} rounded={'lg'} bg={"#f2f2f2"} h={400} overflow={'auto'}>
<AgencyName />
</Box>
</Box>

View File

@@ -2,9 +2,18 @@ import { Box, HStack, Text } from "@chakra-ui/react";
import MainFrame from "../../../components/MainFrame"
import { p } from "framer-motion/client";
import AboutUsAddModel from "../../ManageCMS/AboutUs/AboutUsAddModel";
import { useGetAboutUsQuery } from "../../../Redux/Service/manage.aboutus.service";
const AboutUs = () => {
const {
data
} = useGetAboutUsQuery()
console.log('====================================');
console.log(data);
console.log('====================================');
return (
<MainFrame>

View File

@@ -32,7 +32,7 @@ const managepost: any[] = [
),
"Description": (<Text>
{`Lorem ipsum dolor, sit amet consectetur adipisicing elit.`.slice(0, 30) + '...'}
{`Lorem ipsum dolor, sit amet consectetur adipisicing elit.}`.slice(0, 30) + '...'}
</Text>),
"Publish Data": "12/01/2025",
"Activate/Deactivate": (

View File

@@ -37,7 +37,7 @@ const registerUser: any[] = [
</Box>
),
"Action": (
<HStack justifyContent="center">
<HStack justifyContent="center">
<ViewRegisterUsers />
<EditRegisterUsers />
{/* <RiDeleteBin5Line style={{ cursor: "pointer" }} /> */}

View File

@@ -33,14 +33,9 @@ const managepost: any[] = [
"Action": (
<HStack justifyContent="center">
{/* <MdOutlineRemoveRedEye
style={{ cursor: "pointer", fontSize: "16px" }}
/> */}
{/* <ViewDailog /> */}
<ViewSubAdmin />
<EditSubAdmin />
{/* <RiDeleteBin5Line style={{ cursor: "pointer" }} /> */}
<AlertDailog
AltertTiggerIcon={RiDeleteBin5Line}
alertText="Delete Users"

View File

@@ -15,7 +15,7 @@ const baseQuery = fetchBaseQuery({
if (token) {
headers.set("Authorization", `Basic ${basicAuth}`);
headers.set("access-token", `Bearer ${token}`);
headers.set("access-token", `${token}`);
}
headers.set("Content-Type", "application/json");
@@ -23,6 +23,7 @@ const baseQuery = fetchBaseQuery({
},
});
// ✅ Handle 401 Errors (Auto Logout)
export const baseQueryWithReauth: BaseQueryFn<
string | FetchArgs,

View File

@@ -1,12 +1,11 @@
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
import Cookies from "js-cookie";
type AuthState = {
token: string | null;
};
const initialState: AuthState = {
token: Cookies.get("token") || null, // Load token from cookies
token: localStorage.getItem("token") || null, // ✅ Ensures token is either a string or null
};
const authSlice = createSlice({
@@ -15,11 +14,11 @@ const authSlice = createSlice({
reducers: {
setToken: (state, action: PayloadAction<string>) => {
state.token = action.payload;
Cookies.set("token", action.payload, { expires: 7, secure: true, sameSite: "Strict" }); // Store in cookies for 7 days
localStorage.setItem("token", action.payload); // Store token in localStorage
},
logout: (state) => {
state.token = null;
Cookies.remove("token");
localStorage.removeItem("token"); // ✅ Remove token from localStorage on logout
},
},
});

View File

@@ -1,26 +1,85 @@
import { createApi } from "@reduxjs/toolkit/query";
import { createApi } from "@reduxjs/toolkit/query/react";
import { baseQueryWithReauth } from "./apiSlice";
export const aboutUs = createApi({
reducerPath: "aboutUs",
baseQuery: baseQueryWithReauth, // Use enhanced baseQuery with error handling
endpoints: (builder) => ({
getPosts: builder.query<Post[], void>({ query: () => "/posts" }),
reducerPath: "aboutUs",
baseQuery: baseQueryWithReauth, // Use enhanced baseQuery with error handling
endpoints: (builder) => ({
// 🔹 GET: Fetch all posts
getAboutUs: builder.query<AboutUs[], void>({
query: () => "/about-us",
}),
});
// 🔹 GET: Fetch a single post by ID
getPostById: builder.query<Post, number>({
query: (id) => `/posts/${id}`,
}),
// 🔹 POST: Create a new post
createPost: builder.mutation<Post, Partial<Post>>({
query: (newPost) => ({
url: "/posts",
method: "POST",
body: newPost,
}),
}),
// 🔹 PUT: Update an existing post
updatePost: builder.mutation<Post, { id: number; updatedData: Partial<Post> }>({
query: ({ id, updatedData }) => ({
url: `/posts/${id}`,
method: "PUT",
body: updatedData,
}),
}),
// 🔹 DELETE: Remove a post by ID
deletePost: builder.mutation<{ success: boolean }, number>({
query: (id) => ({
url: `/posts/${id}`,
method: "DELETE",
}),
}),
}),
});
export const {
useGetAboutUsQuery,
export const { } = aboutUs;
export type Post = {
id: number;
title: string;
body: string;
};
useGetPostByIdQuery,
useCreatePostMutation,
useUpdatePostMutation,
useDeletePostMutation
} = aboutUs;
// Define Post type
export type Post = {
id: number;
title: string;
body: string;
};
export type AboutUs = {
id: number;
language_master_xid: number;
content: string;
is_active: boolean;
};

View File

@@ -94,7 +94,7 @@ const DataTable: React.FC<TableProps> = ({
>
{tableHeadRow.map((heading, colIndex) => (
<Table.Cell
// className="oxygen"
// className="oxygen"
px={4}
p={2}
key={`${index}-${colIndex}`}

View File

@@ -13,13 +13,13 @@ interface MainFrameProps {
const MainFrame: FC<MainFrameProps> = ({ children }) => {
return (
<MotionVStack {...OPACITY_ON_LOAD} w="100%" h="90%" p={0} pb={0}>
<MotionVStack rounded="lg" overflowY={'auto'} overflowX={'hidden'} {...OPACITY_ON_LOAD} w="100%" minH="93%" p={0} pb={2}>
<Box
w="100%"
h="100%"
// h="100%"
bg="#ffffff"
overflow={'scroll'}
// rounded="md"
// overflow={'scroll'}
rounded="lg"
boxShadow={'rgba(99, 99, 99, 0.2) 0px 2px 8px 0px'}
pt={3}
>

View File

@@ -156,12 +156,31 @@ body {
/* Border around the thumb */
}
/* Style the scrollbar thumb on hover */
::-webkit-scrollbar-thumb:hover {
background-color: #555;
/* Darker gray when hovered */
/* Scrollbar width */
::-webkit-scrollbar {
width: 8px;
height: 8px;
cursor: pointer;
}
/* Scrollbar track */
::-webkit-scrollbar-track {
background: transparent; /* No visible track */
}
/* Scrollbar thumb (the draggable part) */
::-webkit-scrollbar-thumb {
background: rgba(0, 0, 0, 0.3); /* Light black (30% opacity) */
border-radius: 10px; /* Rounded edges */
transition: background 0.3s;
}
/* On hover, make it darker */
::-webkit-scrollbar-thumb:hover {
background: rgba(0, 0, 0, 0.5);
}
input:focus-visible {
border: none !important;
}