Compare commits
4 Commits
9ec195870a
...
dev
| Author | SHA1 | Date | |
|---|---|---|---|
| c20f083115 | |||
| 9ac1e0fc4f | |||
| 1f456f4d17 | |||
| adf180bc5f |
@@ -11,7 +11,7 @@ import { makeRouter } from "./routes/routes";
|
|||||||
import { useDarkMode } from "./hooks/useDarkMode";
|
import { useDarkMode } from "./hooks/useDarkMode";
|
||||||
import { ItemWithSubItems } from "./types/userPermissions";
|
import { ItemWithSubItems } from "./types/userPermissions";
|
||||||
import { useFetchProfile } from "./hooks/useFetchProfile";
|
import { useFetchProfile } from "./hooks/useFetchProfile";
|
||||||
import { getInspectionMenuItems } from "./screen/SideBar";
|
import { getInspectionMenuItems } from "./config/menuItems";
|
||||||
|
|
||||||
const versionNumber = "/src/version.txt";
|
const versionNumber = "/src/version.txt";
|
||||||
import "./index.css";
|
import "./index.css";
|
||||||
@@ -127,7 +127,7 @@ export default function App() {
|
|||||||
window.history.replaceState(
|
window.history.replaceState(
|
||||||
{},
|
{},
|
||||||
document.title,
|
document.title,
|
||||||
url.pathname + url.search
|
url.pathname + url.search,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|||||||
@@ -4,99 +4,26 @@ import { useUserProfileStore } from "../context/zustand-store/userStore";
|
|||||||
import { getFaPermissions } from "../utils/getFaPermissions";
|
import { getFaPermissions } from "../utils/getFaPermissions";
|
||||||
import { motion, AnimatePresence } from "framer-motion";
|
import { motion, AnimatePresence } from "framer-motion";
|
||||||
import {
|
import {
|
||||||
UsersIcon,
|
|
||||||
DocumentTextIcon,
|
|
||||||
ChartBarIcon,
|
|
||||||
ChevronDownIcon,
|
ChevronDownIcon,
|
||||||
UserIcon,
|
|
||||||
GlobeAsiaAustraliaIcon,
|
GlobeAsiaAustraliaIcon,
|
||||||
|
MapPinIcon,
|
||||||
} from "@heroicons/react/24/outline";
|
} from "@heroicons/react/24/outline";
|
||||||
import { ItemWithSubItems } from "../types/userPermissions";
|
import { getInspectionMenuItems } from "../config/menuItems";
|
||||||
import { checkMenuPermission } from "../utils/checkMenuPermission";
|
|
||||||
|
|
||||||
const getInspectionMenuItems = (
|
const ADMIN_PROVINCES = [
|
||||||
permissions: string[] = []
|
{ value: "hamedan", label: "همدان" },
|
||||||
): ItemWithSubItems[] => {
|
{ value: "markazi", label: "مرکزی" },
|
||||||
const items: ItemWithSubItems[] = [];
|
] as const;
|
||||||
|
|
||||||
if (checkMenuPermission("nationalinfo", permissions)) {
|
|
||||||
items.push({
|
|
||||||
en: "nationalinfo",
|
|
||||||
fa: "اطلاعات",
|
|
||||||
icon: () => <UserIcon className="w-6 h-6" />,
|
|
||||||
subItems: [
|
|
||||||
{
|
|
||||||
name: "nationalinfo",
|
|
||||||
path: "/nationalinfo",
|
|
||||||
component: () => import("./NationalInfo"),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "ladinginfo",
|
|
||||||
path: "/ladinginfo",
|
|
||||||
component: () => import("./LadingInfo"),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "veterinarytransfer",
|
|
||||||
path: "/veterinarytransfer",
|
|
||||||
component: () => import("./VeterinaryTransfer"),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (checkMenuPermission("users", permissions)) {
|
|
||||||
items.push({
|
|
||||||
en: "users",
|
|
||||||
fa: "کاربران",
|
|
||||||
icon: () => <UsersIcon className="w-6 h-6" />,
|
|
||||||
subItems: [
|
|
||||||
{
|
|
||||||
name: "users",
|
|
||||||
path: "/users",
|
|
||||||
component: () => import("./Users"),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (checkMenuPermission("inspections", permissions)) {
|
|
||||||
items.push({
|
|
||||||
en: "inspections",
|
|
||||||
fa: "سوابق بازرسی",
|
|
||||||
icon: () => <DocumentTextIcon className="w-6 h-6" />,
|
|
||||||
subItems: [
|
|
||||||
{
|
|
||||||
name: "inspections",
|
|
||||||
path: "/inspections",
|
|
||||||
component: () => import("./UserInspections"),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (checkMenuPermission("statics", permissions)) {
|
|
||||||
items.push({
|
|
||||||
en: "statics",
|
|
||||||
fa: "آمار",
|
|
||||||
icon: () => <ChartBarIcon className="w-6 h-6" />,
|
|
||||||
subItems: [
|
|
||||||
{
|
|
||||||
name: "statics",
|
|
||||||
path: "/statics",
|
|
||||||
component: () => import("./Statics"),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return items;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const Menu = () => {
|
export const Menu = () => {
|
||||||
const { profile } = useUserProfileStore();
|
const { profile, updateProfile } = useUserProfileStore();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const menuItems = getInspectionMenuItems(profile?.permissions || []);
|
const menuItems = getInspectionMenuItems(profile?.permissions || []);
|
||||||
const [openIndex, setOpenIndex] = useState<number | null>(null);
|
const [openIndex, setOpenIndex] = useState<number | null>(null);
|
||||||
|
const hasAdmin =
|
||||||
|
Array.isArray(profile?.permissions) &&
|
||||||
|
profile.permissions.includes("admin");
|
||||||
|
const currentProvince = profile?.province || "hamedan";
|
||||||
|
|
||||||
const toggleSubmenu = (index: number) => {
|
const toggleSubmenu = (index: number) => {
|
||||||
setOpenIndex((prev) => (prev === index ? null : index));
|
setOpenIndex((prev) => (prev === index ? null : index));
|
||||||
@@ -110,7 +37,7 @@ export const Menu = () => {
|
|||||||
منو
|
منو
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
<div className="mb-4">
|
<div className="mb-4 space-y-3">
|
||||||
<button
|
<button
|
||||||
onClick={() => navigate({ to: "/" })}
|
onClick={() => navigate({ to: "/" })}
|
||||||
className="w-full flex items-center justify-center gap-2 px-4 py-3 rounded-xl bg-primary-500 hover:bg-primary-600 cursor-pointer dark:bg-primary-800 dark:hover:bg-primary-700 text-white font-semibold text-sm transition-all duration-200 shadow-md hover:shadow-lg"
|
className="w-full flex items-center justify-center gap-2 px-4 py-3 rounded-xl bg-primary-500 hover:bg-primary-600 cursor-pointer dark:bg-primary-800 dark:hover:bg-primary-700 text-white font-semibold text-sm transition-all duration-200 shadow-md hover:shadow-lg"
|
||||||
@@ -118,6 +45,30 @@ export const Menu = () => {
|
|||||||
<GlobeAsiaAustraliaIcon className="w-5 h-5" />
|
<GlobeAsiaAustraliaIcon className="w-5 h-5" />
|
||||||
<span>مشاهده نقشه</span>
|
<span>مشاهده نقشه</span>
|
||||||
</button>
|
</button>
|
||||||
|
{hasAdmin && (
|
||||||
|
<div className="flex flex-col gap-2 p-3 rounded-xl bg-white dark:bg-dark-700 border border-gray-200 dark:border-dark-600">
|
||||||
|
<div className="flex items-center gap-2 text-sm font-medium text-gray-600 dark:text-gray-400">
|
||||||
|
<MapPinIcon className="w-4 h-4 shrink-0" />
|
||||||
|
<span>استان</span>
|
||||||
|
</div>
|
||||||
|
<div className="grid grid-cols-2 gap-2">
|
||||||
|
{ADMIN_PROVINCES.map(({ value, label }) => (
|
||||||
|
<button
|
||||||
|
key={value}
|
||||||
|
type="button"
|
||||||
|
onClick={() => updateProfile({ province: value })}
|
||||||
|
className={`px-4 py-2.5 rounded-lg text-sm font-medium transition-all ${
|
||||||
|
currentProvince === value
|
||||||
|
? "bg-primary-500 text-white dark:bg-primary-600 shadow-md"
|
||||||
|
: "bg-gray-100 dark:bg-dark-600 text-gray-700 dark:text-gray-300 hover:bg-gray-200 dark:hover:bg-dark-500"
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{label}
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
|
|||||||
86
src/config/menuItems.tsx
Normal file
86
src/config/menuItems.tsx
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
import {
|
||||||
|
UsersIcon,
|
||||||
|
DocumentTextIcon,
|
||||||
|
ChartBarIcon,
|
||||||
|
UserIcon,
|
||||||
|
} from "@heroicons/react/24/outline";
|
||||||
|
import { ItemWithSubItems } from "../types/userPermissions";
|
||||||
|
import { checkMenuPermission } from "../utils/checkMenuPermission";
|
||||||
|
|
||||||
|
export const getInspectionMenuItems = (
|
||||||
|
permissions: string[] = [],
|
||||||
|
): ItemWithSubItems[] => {
|
||||||
|
const items: ItemWithSubItems[] = [];
|
||||||
|
|
||||||
|
if (checkMenuPermission("nationalinfo", permissions)) {
|
||||||
|
items.push({
|
||||||
|
en: "nationalinfo",
|
||||||
|
fa: "اطلاعات",
|
||||||
|
icon: () => <UserIcon className="w-6 h-6" />,
|
||||||
|
subItems: [
|
||||||
|
{
|
||||||
|
name: "nationalinfo",
|
||||||
|
path: "/nationalinfo",
|
||||||
|
component: () => import("../Pages/NationalInfo"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ladinginfo",
|
||||||
|
path: "/ladinginfo",
|
||||||
|
component: () => import("../Pages/LadingInfo"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "veterinarytransfer",
|
||||||
|
path: "/veterinarytransfer",
|
||||||
|
component: () => import("../Pages/VeterinaryTransfer"),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (checkMenuPermission("users", permissions)) {
|
||||||
|
items.push({
|
||||||
|
en: "users",
|
||||||
|
fa: "کاربران",
|
||||||
|
icon: () => <UsersIcon className="w-6 h-6" />,
|
||||||
|
subItems: [
|
||||||
|
{
|
||||||
|
name: "users",
|
||||||
|
path: "/users",
|
||||||
|
component: () => import("../Pages/Users"),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (checkMenuPermission("inspections", permissions)) {
|
||||||
|
items.push({
|
||||||
|
en: "inspections",
|
||||||
|
fa: "سوابق بازرسی",
|
||||||
|
icon: () => <DocumentTextIcon className="w-6 h-6" />,
|
||||||
|
subItems: [
|
||||||
|
{
|
||||||
|
name: "inspections",
|
||||||
|
path: "/inspections",
|
||||||
|
component: () => import("../Pages/UserInspections"),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (checkMenuPermission("statics", permissions)) {
|
||||||
|
items.push({
|
||||||
|
en: "statics",
|
||||||
|
fa: "آمار",
|
||||||
|
icon: () => <ChartBarIcon className="w-6 h-6" />,
|
||||||
|
subItems: [
|
||||||
|
{
|
||||||
|
name: "statics",
|
||||||
|
path: "/statics",
|
||||||
|
component: () => import("../Pages/Statics"),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return items;
|
||||||
|
};
|
||||||
@@ -5,12 +5,13 @@ import { useDashboardTabStore } from "./dashboardTabStore";
|
|||||||
interface UseUserProfileStore {
|
interface UseUserProfileStore {
|
||||||
profile?: Record<string, any> | null;
|
profile?: Record<string, any> | null;
|
||||||
setUserProfile: (profile: Record<string, any>) => void;
|
setUserProfile: (profile: Record<string, any>) => void;
|
||||||
|
updateProfile: (updates: Partial<Record<string, any>>) => void;
|
||||||
clearProfile: () => void;
|
clearProfile: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const arePermissionsEqual = (
|
const arePermissionsEqual = (
|
||||||
permissions1?: string[],
|
permissions1?: string[],
|
||||||
permissions2?: string[]
|
permissions2?: string[],
|
||||||
): boolean => {
|
): boolean => {
|
||||||
if (!permissions1 && !permissions2) return true;
|
if (!permissions1 && !permissions2) return true;
|
||||||
if (!permissions1 || !permissions2) return false;
|
if (!permissions1 || !permissions2) return false;
|
||||||
@@ -24,7 +25,7 @@ const arePermissionsEqual = (
|
|||||||
|
|
||||||
const areProfilesEqual = (
|
const areProfilesEqual = (
|
||||||
currentProfile: Record<string, any> | null | undefined,
|
currentProfile: Record<string, any> | null | undefined,
|
||||||
newProfile: Record<string, any>
|
newProfile: Record<string, any>,
|
||||||
): boolean => {
|
): boolean => {
|
||||||
if (!currentProfile) return false;
|
if (!currentProfile) return false;
|
||||||
|
|
||||||
@@ -35,10 +36,10 @@ const areProfilesEqual = (
|
|||||||
}
|
}
|
||||||
|
|
||||||
const currentKeys = Object.keys(currentProfile).filter(
|
const currentKeys = Object.keys(currentProfile).filter(
|
||||||
(key) => key !== "permissions"
|
(key) => key !== "permissions",
|
||||||
);
|
);
|
||||||
const newKeys = Object.keys(newProfile).filter(
|
const newKeys = Object.keys(newProfile).filter(
|
||||||
(key) => key !== "permissions"
|
(key) => key !== "permissions",
|
||||||
);
|
);
|
||||||
|
|
||||||
if (currentKeys.length !== newKeys.length) return false;
|
if (currentKeys.length !== newKeys.length) return false;
|
||||||
@@ -72,10 +73,15 @@ export const useUserProfileStore = create<UseUserProfileStore>()(
|
|||||||
console.log("profile", profile);
|
console.log("profile", profile);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
updateProfile: (updates) => {
|
||||||
|
const currentProfile = get().profile;
|
||||||
|
if (!currentProfile) return;
|
||||||
|
set({ profile: { ...currentProfile, ...updates } });
|
||||||
|
},
|
||||||
clearProfile: () => set({ profile: null }),
|
clearProfile: () => set({ profile: null }),
|
||||||
}),
|
}),
|
||||||
{ name: "userprofile" }
|
{ name: "userprofile" },
|
||||||
)
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
interface UseUserStore {
|
interface UseUserStore {
|
||||||
@@ -97,6 +103,6 @@ export const useUserStore = create<UseUserStore>()(
|
|||||||
}),
|
}),
|
||||||
{
|
{
|
||||||
name: "user",
|
name: "user",
|
||||||
}
|
},
|
||||||
)
|
),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -17,15 +17,7 @@ export function makeRouter(auth: string | null) {
|
|||||||
try {
|
try {
|
||||||
const routeConfigs = getRoutes(auth);
|
const routeConfigs = getRoutes(auth);
|
||||||
|
|
||||||
console.log(
|
|
||||||
"Creating router with routes:",
|
|
||||||
routeConfigs.length,
|
|
||||||
"auth:",
|
|
||||||
!!auth
|
|
||||||
);
|
|
||||||
|
|
||||||
if (routeConfigs.length === 0) {
|
if (routeConfigs.length === 0) {
|
||||||
console.log("No routes found, adding default Auth route");
|
|
||||||
routeConfigs.push({ path: "/", component: Auth });
|
routeConfigs.push({ path: "/", component: Auth });
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -57,7 +49,6 @@ export function makeRouter(auth: string | null) {
|
|||||||
defaultPreload: "intent",
|
defaultPreload: "intent",
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log("Router created successfully");
|
|
||||||
return router;
|
return router;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error creating router:", error);
|
console.error("Error creating router:", error);
|
||||||
|
|||||||
@@ -4,24 +4,25 @@ import { useState } from "react";
|
|||||||
import { motion, AnimatePresence } from "framer-motion";
|
import { motion, AnimatePresence } from "framer-motion";
|
||||||
import { ChevronDownIcon } from "@heroicons/react/24/solid";
|
import { ChevronDownIcon } from "@heroicons/react/24/solid";
|
||||||
import { useUserProfileStore } from "../context/zustand-store/userStore";
|
import { useUserProfileStore } from "../context/zustand-store/userStore";
|
||||||
import { ItemWithSubItems } from "../types/userPermissions";
|
|
||||||
import { useNavigate } from "@tanstack/react-router";
|
import { useNavigate } from "@tanstack/react-router";
|
||||||
import { getFaPermissions } from "../utils/getFaPermissions";
|
import { getFaPermissions } from "../utils/getFaPermissions";
|
||||||
import { useSideBarStore } from "../context/zustand-store/appStore";
|
import { useSideBarStore } from "../context/zustand-store/appStore";
|
||||||
import SVGImage from "../components/SvgImage/SvgImage";
|
import SVGImage from "../components/SvgImage/SvgImage";
|
||||||
import { checkMenuPermission } from "../utils/checkMenuPermission";
|
import { getInspectionMenuItems } from "../config/menuItems";
|
||||||
import {
|
import {
|
||||||
ChevronLeftIcon,
|
ChevronLeftIcon,
|
||||||
ChevronRightIcon,
|
ChevronRightIcon,
|
||||||
MagnifyingGlassIcon,
|
MagnifyingGlassIcon,
|
||||||
BuildingOfficeIcon,
|
BuildingOfficeIcon,
|
||||||
UsersIcon,
|
|
||||||
DocumentTextIcon,
|
|
||||||
ChartBarIcon,
|
|
||||||
UserIcon,
|
|
||||||
GlobeAsiaAustraliaIcon,
|
GlobeAsiaAustraliaIcon,
|
||||||
|
MapPinIcon,
|
||||||
} from "@heroicons/react/24/outline";
|
} from "@heroicons/react/24/outline";
|
||||||
|
|
||||||
|
const ADMIN_PROVINCES = [
|
||||||
|
{ value: "hamedan", label: "همدان" },
|
||||||
|
{ value: "markazi", label: "مرکزی" },
|
||||||
|
] as const;
|
||||||
|
|
||||||
const containerVariants = {
|
const containerVariants = {
|
||||||
hidden: {},
|
hidden: {},
|
||||||
visible: { transition: { staggerChildren: 0.03 } },
|
visible: { transition: { staggerChildren: 0.03 } },
|
||||||
@@ -69,91 +70,14 @@ const sidebarVariants = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getInspectionMenuItems = (
|
|
||||||
permissions: string[] = []
|
|
||||||
): ItemWithSubItems[] => {
|
|
||||||
const items: ItemWithSubItems[] = [];
|
|
||||||
|
|
||||||
if (checkMenuPermission("nationalinfo", permissions)) {
|
|
||||||
items.push({
|
|
||||||
en: "nationalinfo",
|
|
||||||
fa: "اطلاعات",
|
|
||||||
icon: () => <UserIcon className="w-6 h-6" />,
|
|
||||||
subItems: [
|
|
||||||
{
|
|
||||||
name: "nationalinfo",
|
|
||||||
path: "/nationalinfo",
|
|
||||||
component: () => import("../Pages/NationalInfo"),
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
name: "ladinginfo",
|
|
||||||
path: "/ladinginfo",
|
|
||||||
component: () => import("../Pages/LadingInfo"),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "veterinarytransfer",
|
|
||||||
path: "/veterinarytransfer",
|
|
||||||
component: () => import("../Pages/VeterinaryTransfer"),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (checkMenuPermission("users", permissions)) {
|
|
||||||
items.push({
|
|
||||||
en: "users",
|
|
||||||
fa: "کاربران",
|
|
||||||
icon: () => <UsersIcon className="w-6 h-6" />,
|
|
||||||
subItems: [
|
|
||||||
{
|
|
||||||
name: "users",
|
|
||||||
path: "/users",
|
|
||||||
component: () => import("../Pages/Users"),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (checkMenuPermission("inspections", permissions)) {
|
|
||||||
items.push({
|
|
||||||
en: "inspections",
|
|
||||||
fa: "سوابق بازرسی",
|
|
||||||
icon: () => <DocumentTextIcon className="w-6 h-6" />,
|
|
||||||
subItems: [
|
|
||||||
{
|
|
||||||
name: "inspections",
|
|
||||||
path: "/inspections",
|
|
||||||
component: () => import("../Pages/UserInspections"),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (checkMenuPermission("statics", permissions)) {
|
|
||||||
items.push({
|
|
||||||
en: "statics",
|
|
||||||
fa: "آمار",
|
|
||||||
icon: () => <ChartBarIcon className="w-6 h-6" />,
|
|
||||||
subItems: [
|
|
||||||
{
|
|
||||||
name: "statics",
|
|
||||||
path: "/statics",
|
|
||||||
component: () => import("../Pages/Statics"),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return items;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const SideBar = () => {
|
export const SideBar = () => {
|
||||||
const isMobile = checkIsMobile();
|
const isMobile = checkIsMobile();
|
||||||
const { profile } = useUserProfileStore();
|
const { profile, updateProfile } = useUserProfileStore();
|
||||||
const menuItems: ItemWithSubItems[] = getInspectionMenuItems(
|
const menuItems = getInspectionMenuItems(profile?.permissions || []);
|
||||||
profile?.permissions || []
|
const hasAdmin =
|
||||||
);
|
Array.isArray(profile?.permissions) &&
|
||||||
|
profile.permissions.includes("admin");
|
||||||
|
const currentProvince = profile?.province || "hamedan";
|
||||||
const [search, setSearch] = useState("");
|
const [search, setSearch] = useState("");
|
||||||
|
|
||||||
const { isSideBarOpen, toggleSideBar } = useSideBarStore();
|
const { isSideBarOpen, toggleSideBar } = useSideBarStore();
|
||||||
@@ -161,7 +85,7 @@ export const SideBar = () => {
|
|||||||
const getOpenedItem = () => {
|
const getOpenedItem = () => {
|
||||||
if (window.location.pathname !== "/") {
|
if (window.location.pathname !== "/") {
|
||||||
const matchedIndex = menuItems.findIndex((item) =>
|
const matchedIndex = menuItems.findIndex((item) =>
|
||||||
item.subItems.some((sub) => sub.path === window.location.pathname)
|
item.subItems.some((sub) => sub.path === window.location.pathname),
|
||||||
);
|
);
|
||||||
return matchedIndex;
|
return matchedIndex;
|
||||||
} else {
|
} else {
|
||||||
@@ -180,7 +104,7 @@ export const SideBar = () => {
|
|||||||
getFaPermissions(subItem.name)
|
getFaPermissions(subItem.name)
|
||||||
.toLowerCase()
|
.toLowerCase()
|
||||||
.includes(search.toLowerCase()) ||
|
.includes(search.toLowerCase()) ||
|
||||||
subItem.path.toLowerCase().includes(search.toLowerCase())
|
subItem.path.toLowerCase().includes(search.toLowerCase()),
|
||||||
);
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@@ -191,7 +115,7 @@ export const SideBar = () => {
|
|||||||
.filter(
|
.filter(
|
||||||
(item) =>
|
(item) =>
|
||||||
item.subItems.length > 0 ||
|
item.subItems.length > 0 ||
|
||||||
item.fa.toLowerCase().includes(search.toLowerCase())
|
item.fa.toLowerCase().includes(search.toLowerCase()),
|
||||||
);
|
);
|
||||||
|
|
||||||
if (isMobile) return null;
|
if (isMobile) return null;
|
||||||
@@ -287,6 +211,30 @@ export const SideBar = () => {
|
|||||||
<span>مشاهده نقشه</span>
|
<span>مشاهده نقشه</span>
|
||||||
</motion.button>
|
</motion.button>
|
||||||
)}
|
)}
|
||||||
|
{isSideBarOpen && hasAdmin && (
|
||||||
|
<div className="flex flex-col gap-2">
|
||||||
|
<div className="flex items-center gap-2 text-xs font-medium text-gray-600 dark:text-gray-400">
|
||||||
|
<MapPinIcon className="w-4 h-4 shrink-0" />
|
||||||
|
<span>استان</span>
|
||||||
|
</div>
|
||||||
|
<div className="grid grid-cols-2 gap-1.5">
|
||||||
|
{ADMIN_PROVINCES.map(({ value, label }) => (
|
||||||
|
<button
|
||||||
|
key={value}
|
||||||
|
type="button"
|
||||||
|
onClick={() => updateProfile({ province: value })}
|
||||||
|
className={`px-3 py-2 rounded-lg text-sm font-medium transition-all ${
|
||||||
|
currentProvince === value
|
||||||
|
? "bg-primary-500 text-white dark:bg-primary-600 shadow-md"
|
||||||
|
: "bg-gray-100 dark:bg-dark-600 text-gray-700 dark:text-gray-300 hover:bg-gray-200 dark:hover:bg-dark-500"
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{label}
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</motion.div>
|
</motion.div>
|
||||||
)}
|
)}
|
||||||
|
|||||||
Reference in New Issue
Block a user