feat: hide statistics, work time, expenses and finances from regular users
This commit is contained in:
		@@ -15,10 +15,11 @@ import {
 | 
				
			|||||||
    IconSun,
 | 
					    IconSun,
 | 
				
			||||||
} from "@tabler/icons-react";
 | 
					} from "@tabler/icons-react";
 | 
				
			||||||
import classes from "./Navbar.module.css";
 | 
					import classes from "./Navbar.module.css";
 | 
				
			||||||
import { useAppDispatch } from "../../redux/store.ts";
 | 
					import { RootState, useAppDispatch } from "../../redux/store.ts";
 | 
				
			||||||
import { logout } from "../../features/authSlice.ts";
 | 
					import { logout } from "../../features/authSlice.ts";
 | 
				
			||||||
import { useNavigate, useRouterState } from "@tanstack/react-router";
 | 
					import { useNavigate, useRouterState } from "@tanstack/react-router";
 | 
				
			||||||
import { setHideNavbar } from "../../features/uiSlice.ts";
 | 
					import { setHideNavbar } from "../../features/uiSlice.ts";
 | 
				
			||||||
 | 
					import { useSelector } from "react-redux";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
interface NavbarLinkProps {
 | 
					interface NavbarLinkProps {
 | 
				
			||||||
    icon: typeof IconHome2;
 | 
					    icon: typeof IconHome2;
 | 
				
			||||||
@@ -93,17 +94,21 @@ const mockdata = [
 | 
				
			|||||||
        label: "Маркетплейсы",
 | 
					        label: "Маркетплейсы",
 | 
				
			||||||
        href: "/marketplaces",
 | 
					        href: "/marketplaces",
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const adminMockdata = [
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        icon: IconChartDots,
 | 
					        icon: IconChartDots,
 | 
				
			||||||
        label: "Статистика",
 | 
					        label: "Статистика",
 | 
				
			||||||
        href: "/statistics",
 | 
					        href: "/statistics",
 | 
				
			||||||
    }
 | 
					    },
 | 
				
			||||||
];
 | 
					];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export function Navbar() {
 | 
					export function Navbar() {
 | 
				
			||||||
    const dispatch = useAppDispatch();
 | 
					    const dispatch = useAppDispatch();
 | 
				
			||||||
    const navigate = useNavigate();
 | 
					    const navigate = useNavigate();
 | 
				
			||||||
    const router = useRouterState();
 | 
					    const router = useRouterState();
 | 
				
			||||||
 | 
					    const role = useSelector((state: RootState) => state.auth.role);
 | 
				
			||||||
    const { colorScheme, toggleColorScheme } = useMantineColorScheme({
 | 
					    const { colorScheme, toggleColorScheme } = useMantineColorScheme({
 | 
				
			||||||
        keepTransitions: true,
 | 
					        keepTransitions: true,
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
@@ -114,9 +119,17 @@ export function Navbar() {
 | 
				
			|||||||
    const onNavlinkClick = (props: NavbarLinkProps) => {
 | 
					    const onNavlinkClick = (props: NavbarLinkProps) => {
 | 
				
			||||||
        navigate({ to: props.href });
 | 
					        navigate({ to: props.href });
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
    const links = mockdata.map((link, index) => (
 | 
					 | 
				
			||||||
        <NavbarLink
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const getLinksData = () => {
 | 
				
			||||||
 | 
					        let data = mockdata;
 | 
				
			||||||
 | 
					        if (role === "admin") {
 | 
				
			||||||
 | 
					            data = data.concat(adminMockdata);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return data;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const links = getLinksData().map((link, index) => (
 | 
				
			||||||
 | 
					        <NavbarLink
 | 
				
			||||||
            {...link}
 | 
					            {...link}
 | 
				
			||||||
            index={index}
 | 
					            index={index}
 | 
				
			||||||
            key={link.label}
 | 
					            key={link.label}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,10 +1,11 @@
 | 
				
			|||||||
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
 | 
					import { createSlice, PayloadAction } from "@reduxjs/toolkit";
 | 
				
			||||||
import { jwtDecode, JwtPayload } from "jwt-decode";
 | 
					import { jwtDecode, JwtPayload as JwtPayloadBase } from "jwt-decode";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
interface AuthState {
 | 
					interface AuthState {
 | 
				
			||||||
    isAuthorized: boolean;
 | 
					    isAuthorized: boolean;
 | 
				
			||||||
    accessToken: string;
 | 
					    accessToken: string;
 | 
				
			||||||
    isGuest: boolean;
 | 
					    isGuest: boolean;
 | 
				
			||||||
 | 
					    role: string;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const initialState = (): AuthState => {
 | 
					const initialState = (): AuthState => {
 | 
				
			||||||
@@ -16,20 +17,26 @@ const initialState = (): AuthState => {
 | 
				
			|||||||
        accessToken: "",
 | 
					        accessToken: "",
 | 
				
			||||||
        isAuthorized: false,
 | 
					        isAuthorized: false,
 | 
				
			||||||
        isGuest: false,
 | 
					        isGuest: false,
 | 
				
			||||||
 | 
					        role: "user",
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					interface JwtPayload extends JwtPayloadBase {
 | 
				
			||||||
 | 
					    role: string;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const authSlice = createSlice({
 | 
					const authSlice = createSlice({
 | 
				
			||||||
    name: "auth",
 | 
					    name: "auth",
 | 
				
			||||||
    initialState,
 | 
					    initialState,
 | 
				
			||||||
    reducers: {
 | 
					    reducers: {
 | 
				
			||||||
        login: (state, action: PayloadAction<{ accessToken: string }>) => {
 | 
					        login: (state, action: PayloadAction<{ accessToken: string }>) => {
 | 
				
			||||||
            try {
 | 
					            try {
 | 
				
			||||||
                const { sub } = jwtDecode<JwtPayload>(
 | 
					                const { sub, role } = jwtDecode<JwtPayload>(
 | 
				
			||||||
                    action.payload.accessToken
 | 
					                    action.payload.accessToken,
 | 
				
			||||||
                );
 | 
					                );
 | 
				
			||||||
                state.accessToken = action.payload.accessToken;
 | 
					                state.accessToken = action.payload.accessToken;
 | 
				
			||||||
                state.isAuthorized = true;
 | 
					                state.isAuthorized = true;
 | 
				
			||||||
 | 
					                state.role = role;
 | 
				
			||||||
                if (sub === "guest") state.isGuest = true;
 | 
					                if (sub === "guest") state.isGuest = true;
 | 
				
			||||||
            } catch (_) {
 | 
					            } catch (_) {
 | 
				
			||||||
                const url = window.location.href;
 | 
					                const url = window.location.href;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,8 +3,10 @@ import { Tabs } from "@mantine/core";
 | 
				
			|||||||
import PageBlock from "../../components/PageBlock/PageBlock.tsx";
 | 
					import PageBlock from "../../components/PageBlock/PageBlock.tsx";
 | 
				
			||||||
import {
 | 
					import {
 | 
				
			||||||
    IconBriefcase,
 | 
					    IconBriefcase,
 | 
				
			||||||
    IconCalendarUser, IconCoins,
 | 
					    IconCalendarUser,
 | 
				
			||||||
    IconCurrencyDollar, IconQrcode,
 | 
					    IconCoins,
 | 
				
			||||||
 | 
					    IconCurrencyDollar,
 | 
				
			||||||
 | 
					    IconQrcode,
 | 
				
			||||||
    IconUser,
 | 
					    IconUser,
 | 
				
			||||||
} from "@tabler/icons-react";
 | 
					} from "@tabler/icons-react";
 | 
				
			||||||
import RolesAndPositionsTab from "./tabs/RolesAndPositions/RolesAndPositionsTab.tsx";
 | 
					import RolesAndPositionsTab from "./tabs/RolesAndPositions/RolesAndPositionsTab.tsx";
 | 
				
			||||||
@@ -14,8 +16,13 @@ import FinancesTab from "./tabs/Finances/FinancesTab.tsx";
 | 
				
			|||||||
import WorkTimeTable from "./tabs/WorkTimeTable/ui/WorkTimeTable.tsx";
 | 
					import WorkTimeTable from "./tabs/WorkTimeTable/ui/WorkTimeTable.tsx";
 | 
				
			||||||
import { WorkShiftsTab } from "./tabs/WorkShifts/WorkShiftsTab.tsx";
 | 
					import { WorkShiftsTab } from "./tabs/WorkShifts/WorkShiftsTab.tsx";
 | 
				
			||||||
import { ExpensesTab } from "./tabs/Expenses/ExpensesTab.tsx";
 | 
					import { ExpensesTab } from "./tabs/Expenses/ExpensesTab.tsx";
 | 
				
			||||||
 | 
					import { useSelector } from "react-redux";
 | 
				
			||||||
 | 
					import { RootState } from "../../redux/store.ts";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const AdminPage = () => {
 | 
					const AdminPage = () => {
 | 
				
			||||||
 | 
					    const userRole = useSelector((state: RootState) => state.auth.role);
 | 
				
			||||||
 | 
					    const isAdmin = userRole === "admin";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return (
 | 
					    return (
 | 
				
			||||||
        <div className={styles["container"]}>
 | 
					        <div className={styles["container"]}>
 | 
				
			||||||
            <PageBlock fullHeight>
 | 
					            <PageBlock fullHeight>
 | 
				
			||||||
@@ -29,31 +36,37 @@ const AdminPage = () => {
 | 
				
			|||||||
                            leftSection={<IconUser />}>
 | 
					                            leftSection={<IconUser />}>
 | 
				
			||||||
                            Пользователи
 | 
					                            Пользователи
 | 
				
			||||||
                        </Tabs.Tab>
 | 
					                        </Tabs.Tab>
 | 
				
			||||||
                        <Tabs.Tab
 | 
					                        {isAdmin && (
 | 
				
			||||||
                            value={"finances"}
 | 
					                            <Tabs.Tab
 | 
				
			||||||
                            leftSection={<IconCurrencyDollar />}>
 | 
					                                value={"finances"}
 | 
				
			||||||
                            Финансы
 | 
					                                leftSection={<IconCurrencyDollar />}>
 | 
				
			||||||
                        </Tabs.Tab>
 | 
					                                Финансы
 | 
				
			||||||
 | 
					                            </Tabs.Tab>
 | 
				
			||||||
 | 
					                        )}
 | 
				
			||||||
                        <Tabs.Tab
 | 
					                        <Tabs.Tab
 | 
				
			||||||
                            value={"rolesAndPositions"}
 | 
					                            value={"rolesAndPositions"}
 | 
				
			||||||
                            leftSection={<IconBriefcase />}>
 | 
					                            leftSection={<IconBriefcase />}>
 | 
				
			||||||
                            Должности
 | 
					                            Должности
 | 
				
			||||||
                        </Tabs.Tab>
 | 
					                        </Tabs.Tab>
 | 
				
			||||||
                        <Tabs.Tab
 | 
					                        {isAdmin && (
 | 
				
			||||||
                            value={"workTimeTable"}
 | 
					                            <Tabs.Tab
 | 
				
			||||||
                            leftSection={<IconCalendarUser />}>
 | 
					                                value={"workTimeTable"}
 | 
				
			||||||
                            Рабочее время
 | 
					                                leftSection={<IconCalendarUser />}>
 | 
				
			||||||
                        </Tabs.Tab>
 | 
					                                Рабочее время
 | 
				
			||||||
 | 
					                            </Tabs.Tab>
 | 
				
			||||||
 | 
					                        )}
 | 
				
			||||||
                        <Tabs.Tab
 | 
					                        <Tabs.Tab
 | 
				
			||||||
                            value={"workShifts"}
 | 
					                            value={"workShifts"}
 | 
				
			||||||
                            leftSection={<IconQrcode />}>
 | 
					                            leftSection={<IconQrcode />}>
 | 
				
			||||||
                            Смены
 | 
					                            Смены
 | 
				
			||||||
                        </Tabs.Tab>
 | 
					                        </Tabs.Tab>
 | 
				
			||||||
                        <Tabs.Tab
 | 
					                        {isAdmin && (
 | 
				
			||||||
                            value={"expenses"}
 | 
					                            <Tabs.Tab
 | 
				
			||||||
                            leftSection={<IconCoins />}>
 | 
					                                value={"expenses"}
 | 
				
			||||||
                            Расходы
 | 
					                                leftSection={<IconCoins />}>
 | 
				
			||||||
                        </Tabs.Tab>
 | 
					                                Расходы
 | 
				
			||||||
 | 
					                            </Tabs.Tab>
 | 
				
			||||||
 | 
					                        )}
 | 
				
			||||||
                    </Tabs.List>
 | 
					                    </Tabs.List>
 | 
				
			||||||
                    <Tabs.Panel value={"users"}>
 | 
					                    <Tabs.Panel value={"users"}>
 | 
				
			||||||
                        <motion.div
 | 
					                        <motion.div
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,8 +1,17 @@
 | 
				
			|||||||
import { StatisticsTab } from "../components/StatisticsTabSegmentedControl/StatisticsTabSegmentedControl.tsx";
 | 
					import { StatisticsTab } from "../components/StatisticsTabSegmentedControl/StatisticsTabSegmentedControl.tsx";
 | 
				
			||||||
import styles from "./StatisticsPage.module.css";
 | 
					import styles from "./StatisticsPage.module.css";
 | 
				
			||||||
import { ProfitTab } from "../tabs/ProfitTab/ProfitTab.tsx";
 | 
					import { ProfitTab } from "../tabs/ProfitTab/ProfitTab.tsx";
 | 
				
			||||||
 | 
					import { useSelector } from "react-redux";
 | 
				
			||||||
 | 
					import { RootState } from "../../../redux/store.ts";
 | 
				
			||||||
 | 
					import { Navigate } from "@tanstack/react-router";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const StatisticsPage = () => {
 | 
					export const StatisticsPage = () => {
 | 
				
			||||||
 | 
					    const userRole = useSelector((state: RootState) => state.auth.role);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (userRole !== "admin") {
 | 
				
			||||||
 | 
					        return <Navigate to={"/leads"} />;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const serviceType = StatisticsTab.PROFIT;
 | 
					    const serviceType = StatisticsTab.PROFIT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const getBody = () => {
 | 
					    const getBody = () => {
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user