This commit is contained in:
AnsariTufail
2025-02-11 14:54:12 +05:30
40 changed files with 884 additions and 226 deletions

5
.env
View File

@@ -1,4 +1,5 @@
VITE_API_URL=https://ssa.betadelivery.com/apia/v1
VITE_API_URL='https://ssa.betadelivery.com/apia/v1'
# VITE_API_URL='http://192.16.50.44/seo-backend/apia/v1'
VITE_USER_NAME="Admin"
VITE_PASSWORD="71%@L%es^bUX94`J9XT*%4&^%tUU^%Q^ffgt"
VITE_PASSWORD="71%@L%es^bUX94`J9XT*@bh,._WWM{$%^^&&"
VITE_APP_NAME=MyViteApp

View File

@@ -82,7 +82,7 @@ define(['./workbox-54d0af47'], (function (workbox) { 'use strict';
"revision": "3ca0b8505b4bec776b69afdba2768812"
}, {
"url": "index.html",
"revision": "0.86j4c86n9j8"
"revision": "0.s1fup7lrbig"
}], {});
workbox.cleanupOutdatedCaches();
workbox.registerRoute(new workbox.NavigationRoute(workbox.createHandlerBoundToURL("index.html"), {

18
package-lock.json generated
View File

@@ -15,6 +15,7 @@
"axios": "^1.7.9",
"chart.js": "^4.4.7",
"framer-motion": "^11.18.0",
"js-cookie": "^3.0.5",
"next-themes": "^0.4.4",
"react": "^18.3.1",
"react-chartjs-2": "^5.3.0",
@@ -28,6 +29,7 @@
"devDependencies": {
"@chakra-ui/cli": "^3.2.3",
"@eslint/js": "^9.17.0",
"@types/js-cookie": "^3.0.6",
"@types/react": "^18.3.18",
"@types/react-dom": "^18.3.5",
"@vitejs/plugin-react": "^4.3.4",
@@ -3248,6 +3250,13 @@
"integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==",
"license": "MIT"
},
"node_modules/@types/js-cookie": {
"version": "3.0.6",
"resolved": "https://registry.npmjs.org/@types/js-cookie/-/js-cookie-3.0.6.tgz",
"integrity": "sha512-wkw9yd1kEXOPnvEeEV1Go1MmxtBJL0RR79aOTAApecWFVu7w0NNXNqhcWgvw2YgZDYadliXkl14pa3WXw5jlCQ==",
"dev": true,
"license": "MIT"
},
"node_modules/@types/json-schema": {
"version": "7.0.15",
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
@@ -7349,6 +7358,15 @@
"node": ">=10"
}
},
"node_modules/js-cookie": {
"version": "3.0.5",
"resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-3.0.5.tgz",
"integrity": "sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==",
"license": "MIT",
"engines": {
"node": ">=14"
}
},
"node_modules/js-tokens": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",

View File

@@ -17,6 +17,7 @@
"axios": "^1.7.9",
"chart.js": "^4.4.7",
"framer-motion": "^11.18.0",
"js-cookie": "^3.0.5",
"next-themes": "^0.4.4",
"react": "^18.3.1",
"react-chartjs-2": "^5.3.0",
@@ -30,6 +31,7 @@
"devDependencies": {
"@chakra-ui/cli": "^3.2.3",
"@eslint/js": "^9.17.0",
"@types/js-cookie": "^3.0.6",
"@types/react": "^18.3.18",
"@types/react-dom": "^18.3.5",
"@vitejs/plugin-react": "^4.3.4",

View File

@@ -14,7 +14,7 @@ function App() {
<Router>
<Routes>
<Route path="/login" element={<Login />} />
<Route path="/*" element={isAuthenticate === true ? (<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

@@ -9,6 +9,8 @@ import logo from '../assets/logo.svg'
import { Button } from "../components/ui/button"
import { Field } from "../components/ui/field"
import { Toaster } from "../components/ui/toaster"
import { PasswordInput } from "../components/ui/password-input"
import { useNavigate } from "react-router-dom"
interface FormValues {
mobileNumber: number
@@ -16,6 +18,7 @@ interface FormValues {
}
const Login = () => {
const navigate = useNavigate()
const dispatch = useDispatch()
const [isLoading, setIsLoading] = useState<boolean>(false)
const context = useContext(GlobalStateContext);
@@ -33,15 +36,15 @@ const Login = () => {
setIsLoading(true);
// Encode Basic Auth Credentials
const username = import.meta.env.VITE_USER_NAME || ''; // Replace with actual username
const password = import.meta.env.VITE_PASSWORD || ''; // Replace with actual password
const basicAuth = btoa(`${username}:${password}`); // Encode to Base64
const username = import.meta.env.VITE_USER_NAME||''; // Replace with actual username
const password = import.meta.env.VITE_PASSWORD||''; // Replace with actual password
const basicAuth = `${username} : ${password}`; // Encode to Base64
try {
const response = await axios.post(
`${import.meta.env.VITE_API_URL}/v1/login`,
const res = await axios.post(
`${import.meta.env.VITE_API_URL}/login`,
{
mobile_number: data.mobileNumber,
mobile_number: Number(data.mobileNumber),
password: data.password,
},
{
@@ -53,10 +56,21 @@ const Login = () => {
}
);
console.log("====================================");
console.log(response);
console.log("====================================");
dispatch(setToken(String(response.data["access-token"])));
if (res.data) {
setIsAuthenticate(true)
console.log('====================================');
console.log(res.data?.data);
console.log('====================================');
navigate('/')
dispatch(setToken(String(res.data?.data["access-token"])));
} else {
console.log("====================================");
console.log(res);
console.log("====================================");
}
} catch (error) {
if (error) {
@@ -102,12 +116,12 @@ const Login = () => {
<VStack mt={6} gap={4} w={'full'}>
<Field color={'#313039'} label={'Enter Mobile Number'} w={'100%'} invalid={!!errors.mobileNumber} errorText={errors.mobileNumber?.message} >
<Input ps={3} {...register("mobileNumber", { required: "Mobile Number address is required" })} placeholder="Mobile Number Address" />
{/* <Text as={'span'} w={'100%'} fontSize={'xs'} fontWeight={'normal'} color={'#686677'}>Forget password</Text> */}
<Input type="number" ps={3} {...register("mobileNumber", { required: "Mobile Number address is required" })} placeholder="Mobile Number Address" />
{/* <Text as={'span'} w={'100%'} fontSize={'xs'} fontWeight={'normal'} color={'#686677'}>Forget password</Text> */}
</Field>
<Field color={'#313039'} label={'Enter Mobile Number'} w={'100%'} invalid={!!errors.password} errorText={errors.password?.message} >
<Input ps={3} {...register("password", { required: "Pasword is required" })} type="password" placeholder="Enter password" />
{/* <Text as={'span'} w={'100%'} fontSize={'xs'} fontWeight={'normal'} color={'#686677'}>Forget password</Text> */}
<Field color={'#313039'} label={'Enter Mobile Number'} w={'100%'} invalid={!!errors.password} errorText={errors.password?.message} >
<PasswordInput ps={3} {...register("password", { required: "Pasword is required" })} placeholder="Enter password" />
{/* <Text as={'span'} w={'100%'} fontSize={'xs'} fontWeight={'normal'} color={'#686677'}>Forget password</Text> */}
</Field>
<Button loading={isLoading} mt={4} size={'sm'} bg={'#02A0A0'} rounded={'md'} w={'100%'} color={'#ffffff'} type="submit">Login</Button>

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

@@ -25,7 +25,6 @@ const managepost: any[] = [
"Action": (
<HStack justifyContent="center">
<PendingRequests />
</HStack>
),
})),

View File

@@ -1,77 +1,105 @@
import { Button } from "../../components/ui/button"
import { DialogBody, DialogCloseTrigger, DialogContent, DialogFooter, DialogHeader, DialogRoot, DialogTitle, DialogTrigger } from "../../components/ui/dialog"
import { Field, HStack, Input, Stack, Textarea, } from "@chakra-ui/react"
import { Button } from "../../components/ui/button";
import {
DialogBody,
DialogCloseTrigger,
DialogContent,
DialogFooter,
DialogHeader,
DialogRoot,
DialogTitle,
DialogTrigger,
} from "../../components/ui/dialog";
import { Badge, Field, HStack, Input, Stack, Textarea } from "@chakra-ui/react";
function PendingRequests() {
return (
return (
<DialogRoot placement="center">
<DialogTrigger asChild>
<Badge fontSize={"xs"} px={2} bg={'#02a0a01f'}>
Answer request
</Badge>
</DialogTrigger>
<DialogRoot placement="center">
<DialogTrigger asChild>
<Button bg={"transparent"} fontSize={"xs"} color="#000000CC" fontWeight="700" textDecoration="underline">
{/* <MdOutlineRemoveRedEye style={{ cursor: "pointer", }} /> */}
Answer request
</Button>
{/* <Button><FaRegEdit /></Button> */}
<DialogContent
bg={"#fff"}
w={{ base: "90%", md: "400px" }}
height={"auto"}
p={3} // Reduced padding
bgSize={"md"}
>
<DialogHeader bg="white">
<DialogTitle alignSelf="center" color="black" fontSize="14px">
Pending Requests
</DialogTitle>
</DialogHeader>
</DialogTrigger>
<DialogBody bg="white">
<Stack py={3}>
<Field.Root>
<Field.Label color="black" pt={1} fontSize="12px">
Request Type
</Field.Label>
<Input
placeholder="Message"
bgColor="#EEEEEE"
color="black"
border="none"
pl={1}
fontSize="12px"
height="30px"
/>
<DialogContent
bg={"#fff"}
w={{ base: '90%', md: '400px' }}
height={"auto"}
p={3} // Reduced padding
bgSize={'md'}
<Field.Label color="black" pt={1} fontSize="12px">
Solution
</Field.Label>
<Textarea
placeholder=""
bgColor="#EEEEEE"
color="black"
border="none"
pl={1}
fontSize="12px"
height="80px"
pt={1.5}
/>
</Field.Root>
</Stack>
</DialogBody>
<DialogFooter
display={{ base: "block", md: "flex" }}
justifyContent="center"
gap={1}
pt={2}
>
<HStack mt={2} mb={3} width={"100%"} justifyContent={"space-between"}>
<Button
width={"48%"}
color="black"
_hover={{ bgColor: "white" }}
variant="outline"
borderRadius="sm"
border="1px solid #02A0A0"
size={"xs"}
>
<DialogHeader bg="white">
<DialogTitle alignSelf="center" color="black" fontSize="14px">Pending Requests</DialogTitle>
</DialogHeader>
Unresolved
</Button>
<Button
width={"48%"}
borderRadius="sm"
// bgColor="#007F33"
bgColor={"#02A0A0"}
color="white"
// colorPalette="#007F33"
size={"xs"}
>
Resolved
</Button>
</HStack>
</DialogFooter>
<DialogBody bg="white">
<Stack py={3}>
<Field.Root>
<Field.Label color="black" pt={1} fontSize="12px">Request Type</Field.Label>
<Input placeholder="Message" bgColor="#EEEEEE" color="black" border="none" pl={1} fontSize="12px" height="30px" />
<Field.Label color="black" pt={1} fontSize="12px">Solution</Field.Label>
<Textarea placeholder="" bgColor="#EEEEEE" color="black" border="none" pl={1} fontSize="12px" height="80px" pt={1.5} />
</Field.Root>
</Stack>
</DialogBody>
<DialogFooter display={{ base: 'block', md: 'flex' }} justifyContent="center" gap={1} pt={2}>
<HStack mt={2} width={"100%"}
justifyContent={"space-between"}>
<Button
width={"48%"}
color="black"
_hover={{ bgColor: "white" }}
variant="outline"
borderRadius="sm"
border="1px solid black"
size={"xs"}
>
Unresolved
</Button>
<Button
width={"48%"}
borderRadius="sm"
// bgColor="#007F33"
bgColor={'#02A0A0'}
color="white"
// colorPalette="#007F33"
size={"xs"}
>
Resolved{" "}
</Button>
</HStack>
</DialogFooter>
<DialogCloseTrigger color="black" />
</DialogContent>
</DialogRoot >
)
<DialogCloseTrigger color="black" />
</DialogContent>
</DialogRoot>
);
}
export default PendingRequests
export default PendingRequests;

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

@@ -1,17 +1,13 @@
import { Box, HStack, Image, Input, Text } from "@chakra-ui/react";
import MainFrame from "../../../components/MainFrame";
import AlertDailog from "../../../components/AlertDailog";
import { NavLink } from "react-router-dom";
import { RiDeleteBin5Line } from "react-icons/ri";
import DataTable from "../../../components/DataTable";
import { Switch } from "../../../components/ui/switch";
import { InputGroup } from "../../../components/ui/input-group";
import { LuSearch } from "react-icons/lu";
import { BiEdit } from "react-icons/bi";
import ViewRegisterUsers from "./ViewRegisterUsers";
import EditRegisterUsers from "./EditRegisterUsers";
import { Button } from "../../../components/ui/button";
import { IoMdAdd } from "react-icons/io";
import AddRegisterUsers from "./AddRegisterUsers";
const tableHeadRow = [
@@ -41,7 +37,7 @@ const registerUser: any[] = [
</Box>
),
"Action": (
<HStack justifyContent="center">
<HStack justifyContent="center">
<ViewRegisterUsers />
<EditRegisterUsers />
{/* <RiDeleteBin5Line style={{ cursor: "pointer" }} /> */}
@@ -74,7 +70,7 @@ const RegisterUsers = () => {
Register Users
</Text>
<HStack>
<HStack>
<InputGroup
startElement={
<LuSearch fontSize={"xs"} style={{ position: 'relative', left: '10px' }} />

View File

@@ -12,7 +12,7 @@ function AddModel() {
{/* <Button bg={"transparent"} size="sm">
<MdOutlineRemoveRedEye style={{ cursor: "pointer", fontSize: "16px" }} />
</Button> */}
<Button px={4} size={"xs"} bg={"#02A0A0"}><IoMdAdd /> <Text>Add</Text></Button>
<Button px={4} size={"xs"} bg={"#02A0A0"}><IoMdAdd /> Add</Button>
</DialogTrigger>
@@ -65,7 +65,7 @@ function AddModel() {
</Stack>
</DialogBody>
<DialogFooter display="flex" justifyContent="center" pt={"2"}>
<Button w="100%" bg="#02A0A0" color={"#fff"}>
<Button size={'xs'} w="100%" bg="#02A0A0" color={"#fff"}>
Save
</Button>
</DialogFooter>

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

@@ -67,9 +67,9 @@ function ViewSubAdmin() {
</Stack>
</DialogBody>
<DialogFooter display="flex" justifyContent="center" pt={"2"} >
<Button w="100%" bg="#02A0A0" color={"#fff"}>
{/* <Button w="100%" bg="#02A0A0" color={"#fff"}>
Save
</Button>
</Button> */}
</DialogFooter>
<DialogCloseTrigger color="black" />

View File

@@ -6,17 +6,26 @@ import { RootState } from "../Store";
const baseQuery = fetchBaseQuery({
baseUrl: `${import.meta.env.VITE_API_URL}`,
prepareHeaders: (headers, { getState }) => {
const token = (getState() as RootState).auth.token; // Get token from Redux store
// Encode Basic Auth Credentials
const username = import.meta.env.VITE_USER_NAME||''; // Replace with actual username
const password = import.meta.env.VITE_PASSWORD||''; // Replace with actual password
const basicAuth = `${username} : ${password}`; // Encode to Base64
if (token) {
headers.set("Authorization", `Bearer ${token}`);
headers.set("Authorization", `Basic ${basicAuth}`);
headers.set("access-token", `${token}`);
}
headers.set("Content-Type", "application/json");
return headers;
},
});
// ✅ Handle 401 Errors (Auto Logout)
const baseQueryWithReauth: BaseQueryFn<
export const baseQueryWithReauth: BaseQueryFn<
string | FetchArgs,
unknown,
FetchBaseQueryError
@@ -30,7 +39,10 @@ const baseQueryWithReauth: BaseQueryFn<
return result;
};
export const apiSlice = createApi({
export const dashboard = createApi({
reducerPath: "api",
baseQuery: baseQueryWithReauth, // Use enhanced baseQuery with error handling
endpoints: (builder) => ({
@@ -46,7 +58,7 @@ export const apiSlice = createApi({
}),
});
export const { useGetPostsQuery } = apiSlice;
export const { useGetPostsQuery } = dashboard;
export type Post = {
id: number;

View File

@@ -5,8 +5,13 @@ type AuthState = {
};
const initialState: AuthState = {
<<<<<<< HEAD
token: localStorage.getItem("token"), // Load token from localStorage
};
=======
token: localStorage.getItem("token") || null, // ✅ Ensures token is either a string or null
};
>>>>>>> 7a7aeab5b877a665b488245d14c520a0dc3df1c9
const authSlice = createSlice({
name: "auth",
@@ -14,11 +19,11 @@ const authSlice = createSlice({
reducers: {
setToken: (state, action: PayloadAction<string>) => {
state.token = action.payload;
localStorage.setItem("token", action.payload);
localStorage.setItem("token", action.payload); // ✅ Store token in localStorage
},
logout: (state) => {
state.token = null;
localStorage.removeItem("token");
localStorage.removeItem("token"); // ✅ Remove token from localStorage on logout
},
},
});

View File

@@ -0,0 +1,26 @@
import { createApi } from "@reduxjs/toolkit/query";
import { baseQueryWithReauth } from "./apiSlice";
export const deactivatedAccounts = createApi({
reducerPath: "deactivatedAccounts",
baseQuery: baseQueryWithReauth, // Use enhanced baseQuery with error handling
endpoints: (builder) => ({
getPosts: builder.query<Post[], void>({ query: () => "/posts" }),
}),
});
export const { } = deactivatedAccounts;
export type Post = {
id: number;
title: string;
body: string;
};

View File

@@ -0,0 +1,26 @@
import { createApi } from "@reduxjs/toolkit/query";
import { baseQueryWithReauth } from "./apiSlice";
export const faqs = createApi({
reducerPath: "faqs",
baseQuery: baseQueryWithReauth, // Use enhanced baseQuery with error handling
endpoints: (builder) => ({
getPosts: builder.query<Post[], void>({ query: () => "/posts" }),
}),
});
export const { } = faqs;
export type Post = {
id: number;
title: string;
body: string;
};

View File

@@ -0,0 +1,85 @@
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) => ({
// 🔹 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,
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

@@ -0,0 +1,26 @@
import { createApi } from "@reduxjs/toolkit/query";
import { baseQueryWithReauth } from "./apiSlice";
export const manageContactUs = createApi({
reducerPath: "manageContactUs",
baseQuery: baseQueryWithReauth, // Use enhanced baseQuery with error handling
endpoints: (builder) => ({
getPosts: builder.query<Post[], void>({ query: () => "/posts" }),
}),
});
export const { } = manageContactUs;
export type Post = {
id: number;
title: string;
body: string;
};

View File

@@ -0,0 +1,26 @@
import { createApi } from "@reduxjs/toolkit/query";
import { baseQueryWithReauth } from "./apiSlice";
export const manageGroups = createApi({
reducerPath: "manageGroups",
baseQuery: baseQueryWithReauth, // Use enhanced baseQuery with error handling
endpoints: (builder) => ({
getPosts: builder.query<Post[], void>({ query: () => "/posts" }),
}),
});
export const { } = manageGroups;
export type Post = {
id: number;
title: string;
body: string;
};

View File

@@ -0,0 +1,26 @@
import { createApi } from "@reduxjs/toolkit/query";
import { baseQueryWithReauth } from "./apiSlice";
export const manageJobs = createApi({
reducerPath: "manageJobs",
baseQuery: baseQueryWithReauth, // Use enhanced baseQuery with error handling
endpoints: (builder) => ({
getPosts: builder.query<Post[], void>({ query: () => "/posts" }),
}),
});
export const { } = manageJobs;
export type Post = {
id: number;
title: string;
body: string;
};

View File

@@ -0,0 +1,26 @@
import { createApi } from "@reduxjs/toolkit/query";
import { baseQueryWithReauth } from "./apiSlice";
export const managePosts = createApi({
reducerPath: "managePosts",
baseQuery: baseQueryWithReauth, // Use enhanced baseQuery with error handling
endpoints: (builder) => ({
getPosts: builder.query<Post[], void>({ query: () => "/posts" }),
}),
});
export const { } = managePosts;
export type Post = {
id: number;
title: string;
body: string;
};

View File

@@ -0,0 +1,26 @@
import { createApi } from "@reduxjs/toolkit/query";
import { baseQueryWithReauth } from "./apiSlice";
export const manageSubAdmin = createApi({
reducerPath: "manageSubAdmin",
baseQuery: baseQueryWithReauth, // Use enhanced baseQuery with error handling
endpoints: (builder) => ({
getPosts: builder.query<Post[], void>({ query: () => "/posts" }),
}),
});
export const { } = manageSubAdmin;
export type Post = {
id: number;
title: string;
body: string;
};

View File

@@ -0,0 +1,26 @@
import { createApi } from "@reduxjs/toolkit/query";
import { baseQueryWithReauth } from "./apiSlice";
export const masterModule = createApi({
reducerPath: "masterModule",
baseQuery: baseQueryWithReauth, // Use enhanced baseQuery with error handling
endpoints: (builder) => ({
getPosts: builder.query<Post[], void>({ query: () => "/posts" }),
}),
});
export const { } = masterModule;
export type Post = {
id: number;
title: string;
body: string;
};

View File

@@ -0,0 +1,26 @@
import { createApi } from "@reduxjs/toolkit/query";
import { baseQueryWithReauth } from "./apiSlice";
export const myProfile = createApi({
reducerPath: "myProfile",
baseQuery: baseQueryWithReauth, // Use enhanced baseQuery with error handling
endpoints: (builder) => ({
getPosts: builder.query<Post[], void>({ query: () => "/posts" }),
}),
});
export const { } = myProfile;
export type Post = {
id: number;
title: string;
body: string;
};

View File

@@ -0,0 +1,26 @@
import { createApi } from "@reduxjs/toolkit/query";
import { baseQueryWithReauth } from "./apiSlice";
export const privacyPolicy = createApi({
reducerPath: "privacyPolicy",
baseQuery: baseQueryWithReauth, // Use enhanced baseQuery with error handling
endpoints: (builder) => ({
getPosts: builder.query<Post[], void>({ query: () => "/posts" }),
}),
});
export const { } = privacyPolicy;
export type Post = {
id: number;
title: string;
body: string;
};

View File

@@ -0,0 +1,26 @@
import { createApi } from "@reduxjs/toolkit/query";
import { baseQueryWithReauth } from "./apiSlice";
export const privacy = createApi({
reducerPath: "privacy",
baseQuery: baseQueryWithReauth, // Use enhanced baseQuery with error handling
endpoints: (builder) => ({
getPosts: builder.query<Post[], void>({ query: () => "/posts" }),
}),
});
export const { } = privacy;
export type Post = {
id: number;
title: string;
body: string;
};

View File

@@ -0,0 +1,26 @@
import { createApi } from "@reduxjs/toolkit/query";
import { baseQueryWithReauth } from "./apiSlice";
export const registerUser = createApi({
reducerPath: "registerUser",
baseQuery: baseQueryWithReauth, // Use enhanced baseQuery with error handling
endpoints: (builder) => ({
getPosts: builder.query<Post[], void>({ query: () => "/posts" }),
}),
});
export const { } = registerUser;
export type Post = {
id: number;
title: string;
body: string;
};

View File

@@ -0,0 +1,26 @@
import { createApi } from "@reduxjs/toolkit/query";
import { baseQueryWithReauth } from "./apiSlice";
export const termsAndCondition = createApi({
reducerPath: "api",
baseQuery: baseQueryWithReauth, // Use enhanced baseQuery with error handling
endpoints: (builder) => ({
getPosts: builder.query<Post[], void>({ query: () => "/posts" }),
}),
});
export const { } = termsAndCondition;
export type Post = {
id: number;
title: string;
body: string;
};

View File

@@ -1,14 +1,54 @@
import { configureStore } from "@reduxjs/toolkit";
import { apiSlice } from "./Service/apiSlice";
import authReducer from "./Service/authSlice"
import { dashboard } from "./Service/apiSlice";
import authReducer from "./Service/authSlice";
import { registerUser } from "./Service/register.user.service";
import { deactivatedAccounts } from "./Service/deactivated.account.service";
import { faqs } from "./Service/faqs.service";
import { managePosts } from "./Service/manage.posts.service";
import { manageSubAdmin } from "./Service/manage.subadmin.service";
import { manageJobs } from "./Service/manage.jobs.service";
import { manageGroups } from "./Service/manage.groups.service";
import { manageContactUs } from "./Service/manage.contactus.service";
import { aboutUs } from "./Service/manage.aboutus.service";
import { privacyPolicy } from "./Service/privacy.policy.service";
import { privacy } from "./Service/privacy.service";
import { myProfile } from "./Service/myprofie.service";
import { masterModule } from "./Service/master.module.service";
export const store = configureStore({
reducer: {
[apiSlice.reducerPath]: apiSlice.reducer,
[dashboard.reducerPath]: dashboard.reducer,
[registerUser.reducerPath]: registerUser.reducer,
[deactivatedAccounts.reducerPath]: deactivatedAccounts.reducer,
[faqs.reducerPath]: faqs.reducer,
[managePosts.reducerPath]: managePosts.reducer,
[manageSubAdmin.reducerPath]: manageSubAdmin.reducer,
[manageJobs.reducerPath]: manageJobs.reducer,
[manageGroups.reducerPath]: manageGroups.reducer,
[manageContactUs.reducerPath]: manageContactUs.reducer,
[aboutUs.reducerPath]: aboutUs.reducer,
[privacyPolicy.reducerPath]: privacyPolicy.reducer,
[privacy.reducerPath]: privacy.reducer,
[myProfile.reducerPath]: myProfile.reducer,
[masterModule.reducerPath]: masterModule.reducer,
auth: authReducer,
},
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware().concat(apiSlice.middleware),
getDefaultMiddleware().concat(
dashboard.middleware,
deactivatedAccounts.middleware,
managePosts.middleware,
faqs.middleware,
manageSubAdmin.middleware,
manageJobs.middleware,
manageGroups.middleware,
manageContactUs.middleware,
aboutUs.middleware,
privacyPolicy.middleware,
privacy.middleware,
myProfile.middleware,
masterModule.middleware,
),
});
export type RootState = ReturnType<typeof store.getState>;

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

@@ -1,79 +1,160 @@
import { Button } from "./ui/button"
import { DialogBody, DialogCloseTrigger, DialogContent, DialogFooter, DialogHeader, DialogRoot, DialogTitle, DialogTrigger } from "./ui/dialog"
import { Field, Grid, Heading, Input, Stack, Text } from "@chakra-ui/react"
import { Checkbox } from "./ui/checkbox"
import { Button } from "./ui/button";
import {
DialogBody,
DialogCloseTrigger,
DialogContent,
DialogFooter,
DialogHeader,
DialogRoot,
DialogTitle,
DialogTrigger,
} from "./ui/dialog";
import { Field, Grid, Heading, Input, Stack, Text } from "@chakra-ui/react";
import { Checkbox } from "./ui/checkbox";
import { FaRegEdit } from "react-icons/fa";
function EditSubAdmin() {
return (
return (
<DialogRoot placement="center">
<DialogTrigger asChild>
<Button bg={"transparent"} size="sm">
<FaRegEdit style={{ cursor: "pointer" }} color="#000" />
</Button>
{/* <Button><FaRegEdit /></Button> */}
</DialogTrigger>
<DialogRoot placement="center">
<DialogTrigger asChild>
<FaRegEdit style={{ cursor: "pointer", fontSize:'16px' }} color="#000" />
{/* <Button><FaRegEdit /></Button> */}
<DialogContent
bg={"#fff"}
w={{ base: "90%", md: "400px" }}
height={"80vh"}
overflow={"scroll"}
overflowX="hidden"
p={3} // Reduced padding
bgSize={"md"}
>
<DialogHeader bg="white">
<DialogTitle alignSelf="center" color="black" fontSize="14px">
Edit Sub Admin Account
</DialogTitle>
</DialogHeader>
</DialogTrigger>
<DialogBody bg="white">
<Stack py={3}>
<Field.Root>
<Field.Label color="black" pt={1} fontSize="12px">
First Name
</Field.Label>
<Input
placeholder="Enter the First Name"
bgColor="#EEEEEE"
color="black"
border="none"
pl={1}
fontSize="12px"
height="30px"
/>
<Field.Label color="black" pt={1} fontSize="12px">
First Name
</Field.Label>
<Input
placeholder="Enter the First Name"
bgColor="#EEEEEE"
color="black"
border="none"
pl={1}
fontSize="12px"
height="30px"
/>
<Field.Label color="black" pt={1} fontSize="12px">
Last Name
</Field.Label>
<Input
placeholder="Enter the Last Name"
bgColor="#EEEEEE"
color="black"
border="none"
pl={1}
fontSize="12px"
height="30px"
/>
<DialogContent
bg={"#fff"}
w={{ base: '90%', md: '400px' }}
height={'80vh'}
overflow={'scroll'}
overflowX="hidden"
p={3} // Reduced padding
bgSize={'md'}
>
<DialogHeader bg="white">
<DialogTitle alignSelf="center" color="black" fontSize="14px">Edit Sub Admin Account</DialogTitle>
</DialogHeader>
<Field.Label color="black" pt={1} fontSize="12px">
DOB
</Field.Label>
<Input
placeholder="Enter the DOB"
bgColor="#EEEEEE"
color="black"
border="none"
pl={1}
fontSize="12px"
height="30px"
/>
<DialogBody bg="white">
<Stack py={3} >
<Field.Root>
<Field.Label color="black" pt={1} fontSize="12px">First Name</Field.Label>
<Input placeholder="Enter the First Name" bgColor="#EEEEEE" color="black" border="none" pl={1} fontSize="12px" height="30px" />
<Field.Label color="black" pt={1} fontSize="12px">First Name</Field.Label>
<Input placeholder="Enter the First Name" bgColor="#EEEEEE" color="black" border="none" pl={1} fontSize="12px" height="30px" />
<Field.Label color="black" pt={1} fontSize="12px">Last Name</Field.Label>
<Input placeholder="Enter the Last Name" bgColor="#EEEEEE" color="black" border="none" pl={1} fontSize="12px" height="30px" />
<Field.Label color="black" pt={1} fontSize="12px">DOB</Field.Label>
<Input placeholder="Enter the DOB" bgColor="#EEEEEE" color="black" border="none" pl={1} fontSize="12px" height="30px" />
<Field.Label color="black" pt={1} fontSize="12px">Gender</Field.Label>
<Input placeholder="Enter the Gender" bgColor="#EEEEEE" color="black" border="none" pl={1} fontSize="12px" height="30px" />
<Heading mt={5} color={'#000'} fontSize={'sm'}>Permissions</Heading>
</Field.Root>
<Grid templateColumns="repeat(2, 1fr)" gap={4}>
<Checkbox size={'sm'} color={"black"} ><Text fontSize={12}>Dashboard</Text></Checkbox>
<Checkbox size={'sm'} color={"black"} ><Text fontSize={12}>Manage contact us</Text></Checkbox>
<Checkbox size={'sm'} color={"black"} ><Text fontSize={12}>manage User</Text></Checkbox>
<Checkbox size={'sm'} color={"black"} ><Text fontSize={12}>Manage CMS</Text></Checkbox>
<Checkbox size={'sm'} color={"black"} ><Text fontSize={12}>Manage Post</Text></Checkbox>
<Checkbox size={'sm'} color={"black"} ><Text fontSize={12}>Manage Reports</Text></Checkbox>
<Checkbox size={'sm'} color={"black"} ><Text fontSize={12}>manage Sub-Admin</Text></Checkbox>
<Checkbox size={'sm'} color={"black"} ><Text fontSize={12}>My profile</Text></Checkbox>
<Checkbox size={'sm'} color={"black"} ><Text fontSize={12}>Manage Jobs</Text> </Checkbox>
<Checkbox size={'sm'} color={"black"} ><Text fontSize={12}> manage feedbacks</Text></Checkbox>
<Checkbox size={'sm'} color={"black"} ><Text fontSize={12}>Manage community</Text> </Checkbox>
<Checkbox size={'sm'} color={"black"} ><Text fontSize={12}> Notification</Text></Checkbox>
</Grid>
</Stack>
</DialogBody>
<DialogFooter display="flex" justifyContent="center" pt={"2"}>
<Button w="100%" bg="#02A0A0" color={"#fff"}>
Save
</Button>
</DialogFooter>
<DialogCloseTrigger color="black" />
</DialogContent>
</DialogRoot >
)
<Field.Label color="black" pt={1} fontSize="12px">
Gender
</Field.Label>
<Input
placeholder="Enter the Gender"
bgColor="#EEEEEE"
color="black"
border="none"
pl={1}
fontSize="12px"
height="30px"
/>
<Heading mt={5} color={"#000"} fontSize={"sm"}>
Permissions
</Heading>
</Field.Root>
<Grid templateColumns="repeat(2, 1fr)" gap={4}>
<Checkbox size={"sm"} color={"black"}>
<Text fontSize={12}>Dashboard</Text>
</Checkbox>
<Checkbox size={"sm"} color={"black"}>
<Text fontSize={12}>Manage contact us</Text>
</Checkbox>
<Checkbox size={"sm"} color={"black"}>
<Text fontSize={12}>manage User</Text>
</Checkbox>
<Checkbox size={"sm"} color={"black"}>
<Text fontSize={12}>Manage CMS</Text>
</Checkbox>
<Checkbox size={"sm"} color={"black"}>
<Text fontSize={12}>Manage Post</Text>
</Checkbox>
<Checkbox size={"sm"} color={"black"}>
<Text fontSize={12}>Manage Reports</Text>
</Checkbox>
<Checkbox size={"sm"} color={"black"}>
<Text fontSize={12}>manage Sub-Admin</Text>
</Checkbox>
<Checkbox size={"sm"} color={"black"}>
<Text fontSize={12}>My profile</Text>
</Checkbox>
<Checkbox size={"sm"} color={"black"}>
<Text fontSize={12}>Manage Jobs</Text>{" "}
</Checkbox>
<Checkbox size={"sm"} color={"black"}>
<Text fontSize={12}> manage feedbacks</Text>
</Checkbox>
<Checkbox size={"sm"} color={"black"}>
<Text fontSize={12}>Manage community</Text>{" "}
</Checkbox>
<Checkbox size={"sm"} color={"black"}>
<Text fontSize={12}> Notification</Text>
</Checkbox>
</Grid>
</Stack>
</DialogBody>
<DialogFooter display="flex" justifyContent="center" pt={"2"}>
<Button size={"xs"} w="100%" bg="#02A0A0" color={"#fff"}>
Save
</Button>
</DialogFooter>
<DialogCloseTrigger color="black" />
</DialogContent>
</DialogRoot>
);
}
export default EditSubAdmin
export default EditSubAdmin;

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;
}

View File

@@ -1,23 +1,27 @@
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App'
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
import { Provider as ReduxProvider } from "react-redux";
import { Provider } from './components/ui/provider'
import GlobalStateProvider from './Contexts/GlobalStateProvider'
import './index.css'
import { Theme } from '@chakra-ui/react'
import { store } from './Redux/Store'
import { Provider } from "./components/ui/provider";
import GlobalStateProvider from "./Contexts/GlobalStateProvider";
import "./index.css";
import { Theme } from "@chakra-ui/react";
import { store } from "./Redux/Store";
ReactDOM.createRoot(document.getElementById('root')!).render(
<React.StrictMode>
<ReduxProvider store={store}> {/* ✅ Wrap with Redux Provider */}
ReactDOM.createRoot(document.getElementById("root")!).render(
<React.StrictMode>
<ReduxProvider store={store}>
{" "}
{/* ✅ Wrap with Redux Provider */}
<GlobalStateProvider>
<Provider> {/* ✅ Wrap with Provider */}
<Theme appearance='light'>
<App />
<Provider>
{" "}
{/* ✅ Wrap with Provider */}
<Theme appearance="light">
<App />
</Theme>
</Provider>
</GlobalStateProvider>
</ReduxProvider>
</React.StrictMode>
)
);

View File

@@ -6,7 +6,7 @@ import { VitePWA } from "vite-plugin-pwa";
export default defineConfig({
server: {
host: "0.0.0.0",
port: 3001, // You can use any port
port: 3000, // You can use any port
},
plugins: [
react(),