1.3
This commit is contained in:
parent
d54cc70b09
commit
2d662fb9cc
7
.gitignore
vendored
Normal file
7
.gitignore
vendored
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
node_modules/
|
||||||
|
*/node_modules/
|
||||||
|
**/node_modules/
|
||||||
|
*/build/
|
||||||
|
**/build/
|
||||||
|
.DS_Store
|
||||||
|
.env
|
||||||
1
frontend/json/runtimeError.json
Normal file
1
frontend/json/runtimeError.json
Normal file
@ -0,0 +1 @@
|
|||||||
|
{"message":"setWidgetsRole is not defined","stack":"\n at Dashboard (webpack-internal:///./src/pages/dashboard.tsx:36:84)\n at ErrorBoundary (webpack-internal:///./src/components/ErrorBoundary.tsx:233:9)\n at div (<anonymous>)\n at div (<anonymous>)\n at LayoutAuthenticated (webpack-internal:///./src/layouts/Authenticated.tsx:44:11)\n at Provider (webpack-internal:///./node_modules/react-redux/es/components/Provider.js:13:3)\n at MyApp (webpack-internal:///./src/pages/_app.tsx:36:11)\n at PathnameContextProviderAdapter (webpack-internal:///./node_modules/next/dist/shared/lib/router/adapters.js:81:11)\n at ErrorBoundary (webpack-internal:///./node_modules/next/dist/client/components/react-dev-overlay/pages/ErrorBoundary.js:41:9)\n at ReactDevOverlay (webpack-internal:///./node_modules/next/dist/client/components/react-dev-overlay/pages/ReactDevOverlay.js:33:11)\n at Container (webpack-internal:///./node_modules/next/dist/client/index.js:81:1)\n at AppContainer (webpack-internal:///./node_modules/next/dist/client/index.js:189:11)\n at Root (webpack-internal:///./node_modules/next/dist/client/index.js:413:11)"}
|
||||||
@ -13,7 +13,6 @@ import Link from 'next/link';
|
|||||||
import { hasPermission } from '../helpers/userPermissions';
|
import { hasPermission } from '../helpers/userPermissions';
|
||||||
import { fetchWidgets } from '../stores/roles/rolesSlice';
|
import { fetchWidgets } from '../stores/roles/rolesSlice';
|
||||||
import { WidgetCreator } from '../components/WidgetCreator/WidgetCreator';
|
import { WidgetCreator } from '../components/WidgetCreator/WidgetCreator';
|
||||||
import { SmartWidget } from '../components/SmartWidget/SmartWidget';
|
|
||||||
|
|
||||||
import { useAppDispatch, useAppSelector } from '../stores/hooks';
|
import { useAppDispatch, useAppSelector } from '../stores/hooks';
|
||||||
const Dashboard = () => {
|
const Dashboard = () => {
|
||||||
@ -36,9 +35,6 @@ const Dashboard = () => {
|
|||||||
const [staff, setStaff] = React.useState('Loading...');
|
const [staff, setStaff] = React.useState('Loading...');
|
||||||
const [clients, setClients] = React.useState('Loading...');
|
const [clients, setClients] = React.useState('Loading...');
|
||||||
|
|
||||||
const [widgetsRole, setWidgetsRole] = React.useState({
|
|
||||||
role: { value: '', label: '' },
|
|
||||||
});
|
|
||||||
const { currentUser } = useAppSelector((state) => state.auth);
|
const { currentUser } = useAppSelector((state) => state.auth);
|
||||||
const { isFetchingQuery } = useAppSelector((state) => state.openAi);
|
const { isFetchingQuery } = useAppSelector((state) => state.openAi);
|
||||||
|
|
||||||
@ -98,24 +94,12 @@ const Dashboard = () => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getWidgets(roleId) {
|
|
||||||
await dispatch(fetchWidgets(roleId));
|
|
||||||
}
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
if (!currentUser) return;
|
if (!currentUser) return;
|
||||||
loadData().then();
|
loadData().then();
|
||||||
setWidgetsRole({
|
|
||||||
role: {
|
|
||||||
value: currentUser?.app_role?.id,
|
|
||||||
label: currentUser?.app_role?.name,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}, [currentUser]);
|
}, [currentUser]);
|
||||||
|
|
||||||
React.useEffect(() => {
|
|
||||||
if (!currentUser || !widgetsRole?.role?.value) return;
|
|
||||||
getWidgets(widgetsRole?.role?.value || '').then();
|
|
||||||
}, [widgetsRole?.role?.value]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@ -131,52 +115,10 @@ const Dashboard = () => {
|
|||||||
{''}
|
{''}
|
||||||
</SectionTitleLineWithButton>
|
</SectionTitleLineWithButton>
|
||||||
|
|
||||||
{hasPermission(currentUser, 'CREATE_ROLES') && (
|
|
||||||
<WidgetCreator
|
|
||||||
currentUser={currentUser}
|
|
||||||
isFetchingQuery={isFetchingQuery}
|
|
||||||
setWidgetsRole={setWidgetsRole}
|
|
||||||
widgetsRole={widgetsRole}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
{!!rolesWidgets.length &&
|
|
||||||
hasPermission(currentUser, 'CREATE_ROLES') && (
|
|
||||||
<p className=' text-gray-500 dark:text-gray-400 mb-4'>
|
|
||||||
{`${widgetsRole?.role?.label || 'Users'}'s widgets`}
|
|
||||||
</p>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<div className='grid grid-cols-1 gap-6 lg:grid-cols-4 mb-6 grid-flow-dense'>
|
<div className='grid grid-cols-1 gap-6 lg:grid-cols-4 mb-6 grid-flow-dense'>
|
||||||
{(isFetchingQuery || loading) && (
|
|
||||||
<div
|
|
||||||
className={` ${
|
|
||||||
corners !== 'rounded-full' ? corners : 'rounded-3xl'
|
|
||||||
} dark:bg-dark-900 text-lg leading-tight text-gray-500 flex items-center ${cardsStyle} dark:border-dark-700 p-6`}
|
|
||||||
>
|
|
||||||
<BaseIcon
|
|
||||||
className={`${iconsColor} animate-spin mr-5`}
|
|
||||||
w='w-16'
|
|
||||||
h='h-16'
|
|
||||||
size={48}
|
|
||||||
path={icon.mdiLoading}
|
|
||||||
/>{' '}
|
|
||||||
Loading widgets...
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{rolesWidgets &&
|
|
||||||
rolesWidgets.map((widget) => (
|
|
||||||
<SmartWidget
|
|
||||||
key={widget.id}
|
|
||||||
userId={currentUser?.id}
|
|
||||||
widget={widget}
|
|
||||||
roleId={widgetsRole?.role?.value || ''}
|
|
||||||
admin={hasPermission(currentUser, 'CREATE_ROLES')}
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{!!rolesWidgets.length && <hr className='my-6 ' />}
|
|
||||||
|
|
||||||
<div
|
<div
|
||||||
id='dashboard'
|
id='dashboard'
|
||||||
|
|||||||
548
frontend/src/pages/dashboard.tsx.temp
Normal file
548
frontend/src/pages/dashboard.tsx.temp
Normal file
@ -0,0 +1,548 @@
|
|||||||
|
import * as icon from '@mdi/js';
|
||||||
|
import Head from 'next/head';
|
||||||
|
import React from 'react';
|
||||||
|
import axios from 'axios';
|
||||||
|
import type { ReactElement } from 'react';
|
||||||
|
import LayoutAuthenticated from '../layouts/Authenticated';
|
||||||
|
import SectionMain from '../components/SectionMain';
|
||||||
|
import SectionTitleLineWithButton from '../components/SectionTitleLineWithButton';
|
||||||
|
import BaseIcon from '../components/BaseIcon';
|
||||||
|
import { getPageTitle } from '../config';
|
||||||
|
import Link from 'next/link';
|
||||||
|
|
||||||
|
import { hasPermission } from '../helpers/userPermissions';
|
||||||
|
import { fetchWidgets } from '../stores/roles/rolesSlice';
|
||||||
|
import { WidgetCreator } from '../components/WidgetCreator/WidgetCreator';
|
||||||
|
|
||||||
|
import { useAppDispatch, useAppSelector } from '../stores/hooks';
|
||||||
|
const Dashboard = () => {
|
||||||
|
const dispatch = useAppDispatch();
|
||||||
|
const iconsColor = useAppSelector((state) => state.style.iconsColor);
|
||||||
|
const corners = useAppSelector((state) => state.style.corners);
|
||||||
|
const cardsStyle = useAppSelector((state) => state.style.cardsStyle);
|
||||||
|
|
||||||
|
const [users, setUsers] = React.useState('Loading...');
|
||||||
|
const [employees, setEmployees] = React.useState('Loading...');
|
||||||
|
const [inventory, setInventory] = React.useState('Loading...');
|
||||||
|
const [machinery, setMachinery] = React.useState('Loading...');
|
||||||
|
const [quality_controls, setQuality_controls] = React.useState('Loading...');
|
||||||
|
const [raw_materials, setRaw_materials] = React.useState('Loading...');
|
||||||
|
const [suppliers, setSuppliers] = React.useState('Loading...');
|
||||||
|
const [work_orders, setWork_orders] = React.useState('Loading...');
|
||||||
|
const [roles, setRoles] = React.useState('Loading...');
|
||||||
|
const [permissions, setPermissions] = React.useState('Loading...');
|
||||||
|
const [companies, setCompanies] = React.useState('Loading...');
|
||||||
|
const [staff, setStaff] = React.useState('Loading...');
|
||||||
|
const [clients, setClients] = React.useState('Loading...');
|
||||||
|
|
||||||
|
const { currentUser } = useAppSelector((state) => state.auth);
|
||||||
|
const { isFetchingQuery } = useAppSelector((state) => state.openAi);
|
||||||
|
|
||||||
|
const { rolesWidgets, loading } = useAppSelector((state) => state.roles);
|
||||||
|
|
||||||
|
const organizationId = currentUser?.companies?.id;
|
||||||
|
|
||||||
|
async function loadData() {
|
||||||
|
const entities = [
|
||||||
|
'users',
|
||||||
|
'employees',
|
||||||
|
'inventory',
|
||||||
|
'machinery',
|
||||||
|
'quality_controls',
|
||||||
|
'raw_materials',
|
||||||
|
'suppliers',
|
||||||
|
'work_orders',
|
||||||
|
'roles',
|
||||||
|
'permissions',
|
||||||
|
'companies',
|
||||||
|
'staff',
|
||||||
|
'clients',
|
||||||
|
];
|
||||||
|
const fns = [
|
||||||
|
setUsers,
|
||||||
|
setEmployees,
|
||||||
|
setInventory,
|
||||||
|
setMachinery,
|
||||||
|
setQuality_controls,
|
||||||
|
setRaw_materials,
|
||||||
|
setSuppliers,
|
||||||
|
setWork_orders,
|
||||||
|
setRoles,
|
||||||
|
setPermissions,
|
||||||
|
setCompanies,
|
||||||
|
setStaff,
|
||||||
|
setClients,
|
||||||
|
];
|
||||||
|
|
||||||
|
const requests = entities.map((entity, index) => {
|
||||||
|
if (hasPermission(currentUser, `READ_${entity.toUpperCase()}`)) {
|
||||||
|
return axios.get(`/${entity.toLowerCase()}/count`);
|
||||||
|
} else {
|
||||||
|
fns[index](null);
|
||||||
|
return Promise.resolve({ data: { count: null } });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Promise.allSettled(requests).then((results) => {
|
||||||
|
results.forEach((result, i) => {
|
||||||
|
if (result.status === 'fulfilled') {
|
||||||
|
fns[i](result.value.data.count);
|
||||||
|
} else {
|
||||||
|
fns[i](result.reason.message);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
if (!currentUser) return;
|
||||||
|
loadData().then();
|
||||||
|
<Head>
|
||||||
|
<title>{getPageTitle('Dashboard')}</title>
|
||||||
|
</Head>
|
||||||
|
<SectionMain>
|
||||||
|
<SectionTitleLineWithButton
|
||||||
|
icon={icon.mdiChartTimelineVariant}
|
||||||
|
title='Overview'
|
||||||
|
main
|
||||||
|
>
|
||||||
|
{''}
|
||||||
|
</SectionTitleLineWithButton>
|
||||||
|
|
||||||
|
|
||||||
|
<div className='grid grid-cols-1 gap-6 lg:grid-cols-4 mb-6 grid-flow-dense'>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div
|
||||||
|
id='dashboard'
|
||||||
|
className='grid grid-cols-1 gap-6 lg:grid-cols-3 mb-6'
|
||||||
|
>
|
||||||
|
{hasPermission(currentUser, 'READ_USERS') && (
|
||||||
|
<Link href={'/users/users-list'}>
|
||||||
|
<div
|
||||||
|
className={`${
|
||||||
|
corners !== 'rounded-full' ? corners : 'rounded-3xl'
|
||||||
|
} dark:bg-dark-900 ${cardsStyle} dark:border-dark-700 p-6`}
|
||||||
|
>
|
||||||
|
<div className='flex justify-between align-center'>
|
||||||
|
<div>
|
||||||
|
<div className='text-lg leading-tight text-gray-500 dark:text-gray-400'>
|
||||||
|
Users
|
||||||
|
</div>
|
||||||
|
<div className='text-3xl leading-tight font-semibold'>
|
||||||
|
{users}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<BaseIcon
|
||||||
|
className={`${iconsColor}`}
|
||||||
|
w='w-16'
|
||||||
|
h='h-16'
|
||||||
|
size={48}
|
||||||
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
|
// @ts-ignore
|
||||||
|
path={icon.mdiAccountGroup || icon.mdiTable}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Link>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{hasPermission(currentUser, 'READ_EMPLOYEES') && (
|
||||||
|
<Link href={'/employees/employees-list'}>
|
||||||
|
<div
|
||||||
|
className={`${
|
||||||
|
corners !== 'rounded-full' ? corners : 'rounded-3xl'
|
||||||
|
} dark:bg-dark-900 ${cardsStyle} dark:border-dark-700 p-6`}
|
||||||
|
>
|
||||||
|
<div className='flex justify-between align-center'>
|
||||||
|
<div>
|
||||||
|
<div className='text-lg leading-tight text-gray-500 dark:text-gray-400'>
|
||||||
|
Employees
|
||||||
|
</div>
|
||||||
|
<div className='text-3xl leading-tight font-semibold'>
|
||||||
|
{employees}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<BaseIcon
|
||||||
|
className={`${iconsColor}`}
|
||||||
|
w='w-16'
|
||||||
|
h='h-16'
|
||||||
|
size={48}
|
||||||
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
|
// @ts-ignore
|
||||||
|
path={icon.mdiAccountGroup || icon.mdiTable}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Link>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{hasPermission(currentUser, 'READ_INVENTORY') && (
|
||||||
|
<Link href={'/inventory/inventory-list'}>
|
||||||
|
<div
|
||||||
|
className={`${
|
||||||
|
corners !== 'rounded-full' ? corners : 'rounded-3xl'
|
||||||
|
} dark:bg-dark-900 ${cardsStyle} dark:border-dark-700 p-6`}
|
||||||
|
>
|
||||||
|
<div className='flex justify-between align-center'>
|
||||||
|
<div>
|
||||||
|
<div className='text-lg leading-tight text-gray-500 dark:text-gray-400'>
|
||||||
|
Inventory
|
||||||
|
</div>
|
||||||
|
<div className='text-3xl leading-tight font-semibold'>
|
||||||
|
{inventory}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<BaseIcon
|
||||||
|
className={`${iconsColor}`}
|
||||||
|
w='w-16'
|
||||||
|
h='h-16'
|
||||||
|
size={48}
|
||||||
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
|
// @ts-ignore
|
||||||
|
path={icon.mdiWarehouse || icon.mdiTable}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Link>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{hasPermission(currentUser, 'READ_MACHINERY') && (
|
||||||
|
<Link href={'/machinery/machinery-list'}>
|
||||||
|
<div
|
||||||
|
className={`${
|
||||||
|
corners !== 'rounded-full' ? corners : 'rounded-3xl'
|
||||||
|
} dark:bg-dark-900 ${cardsStyle} dark:border-dark-700 p-6`}
|
||||||
|
>
|
||||||
|
<div className='flex justify-between align-center'>
|
||||||
|
<div>
|
||||||
|
<div className='text-lg leading-tight text-gray-500 dark:text-gray-400'>
|
||||||
|
Machinery
|
||||||
|
</div>
|
||||||
|
<div className='text-3xl leading-tight font-semibold'>
|
||||||
|
{machinery}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<BaseIcon
|
||||||
|
className={`${iconsColor}`}
|
||||||
|
w='w-16'
|
||||||
|
h='h-16'
|
||||||
|
size={48}
|
||||||
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
|
// @ts-ignore
|
||||||
|
path={icon.mdiFactory || icon.mdiTable}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Link>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{hasPermission(currentUser, 'READ_QUALITY_CONTROLS') && (
|
||||||
|
<Link href={'/quality_controls/quality_controls-list'}>
|
||||||
|
<div
|
||||||
|
className={`${
|
||||||
|
corners !== 'rounded-full' ? corners : 'rounded-3xl'
|
||||||
|
} dark:bg-dark-900 ${cardsStyle} dark:border-dark-700 p-6`}
|
||||||
|
>
|
||||||
|
<div className='flex justify-between align-center'>
|
||||||
|
<div>
|
||||||
|
<div className='text-lg leading-tight text-gray-500 dark:text-gray-400'>
|
||||||
|
Quality controls
|
||||||
|
</div>
|
||||||
|
<div className='text-3xl leading-tight font-semibold'>
|
||||||
|
{quality_controls}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<BaseIcon
|
||||||
|
className={`${iconsColor}`}
|
||||||
|
w='w-16'
|
||||||
|
h='h-16'
|
||||||
|
size={48}
|
||||||
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
|
// @ts-ignore
|
||||||
|
path={icon.mdiCheckCircle || icon.mdiTable}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Link>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{hasPermission(currentUser, 'READ_RAW_MATERIALS') && (
|
||||||
|
<Link href={'/raw_materials/raw_materials-list'}>
|
||||||
|
<div
|
||||||
|
className={`${
|
||||||
|
corners !== 'rounded-full' ? corners : 'rounded-3xl'
|
||||||
|
} dark:bg-dark-900 ${cardsStyle} dark:border-dark-700 p-6`}
|
||||||
|
>
|
||||||
|
<div className='flex justify-between align-center'>
|
||||||
|
<div>
|
||||||
|
<div className='text-lg leading-tight text-gray-500 dark:text-gray-400'>
|
||||||
|
Raw materials
|
||||||
|
</div>
|
||||||
|
<div className='text-3xl leading-tight font-semibold'>
|
||||||
|
{raw_materials}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<BaseIcon
|
||||||
|
className={`${iconsColor}`}
|
||||||
|
w='w-16'
|
||||||
|
h='h-16'
|
||||||
|
size={48}
|
||||||
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
|
// @ts-ignore
|
||||||
|
path={icon.mdiPackageVariant || icon.mdiTable}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Link>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{hasPermission(currentUser, 'READ_SUPPLIERS') && (
|
||||||
|
<Link href={'/suppliers/suppliers-list'}>
|
||||||
|
<div
|
||||||
|
className={`${
|
||||||
|
corners !== 'rounded-full' ? corners : 'rounded-3xl'
|
||||||
|
} dark:bg-dark-900 ${cardsStyle} dark:border-dark-700 p-6`}
|
||||||
|
>
|
||||||
|
<div className='flex justify-between align-center'>
|
||||||
|
<div>
|
||||||
|
<div className='text-lg leading-tight text-gray-500 dark:text-gray-400'>
|
||||||
|
Suppliers
|
||||||
|
</div>
|
||||||
|
<div className='text-3xl leading-tight font-semibold'>
|
||||||
|
{suppliers}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<BaseIcon
|
||||||
|
className={`${iconsColor}`}
|
||||||
|
w='w-16'
|
||||||
|
h='h-16'
|
||||||
|
size={48}
|
||||||
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
|
// @ts-ignore
|
||||||
|
path={icon.mdiTruck || icon.mdiTable}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Link>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{hasPermission(currentUser, 'READ_WORK_ORDERS') && (
|
||||||
|
<Link href={'/work_orders/work_orders-list'}>
|
||||||
|
<div
|
||||||
|
className={`${
|
||||||
|
corners !== 'rounded-full' ? corners : 'rounded-3xl'
|
||||||
|
} dark:bg-dark-900 ${cardsStyle} dark:border-dark-700 p-6`}
|
||||||
|
>
|
||||||
|
<div className='flex justify-between align-center'>
|
||||||
|
<div>
|
||||||
|
<div className='text-lg leading-tight text-gray-500 dark:text-gray-400'>
|
||||||
|
Work orders
|
||||||
|
</div>
|
||||||
|
<div className='text-3xl leading-tight font-semibold'>
|
||||||
|
{work_orders}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<BaseIcon
|
||||||
|
className={`${iconsColor}`}
|
||||||
|
w='w-16'
|
||||||
|
h='h-16'
|
||||||
|
size={48}
|
||||||
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
|
// @ts-ignore
|
||||||
|
path={icon.mdiClipboardList || icon.mdiTable}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Link>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{hasPermission(currentUser, 'READ_ROLES') && (
|
||||||
|
<Link href={'/roles/roles-list'}>
|
||||||
|
<div
|
||||||
|
className={`${
|
||||||
|
corners !== 'rounded-full' ? corners : 'rounded-3xl'
|
||||||
|
} dark:bg-dark-900 ${cardsStyle} dark:border-dark-700 p-6`}
|
||||||
|
>
|
||||||
|
<div className='flex justify-between align-center'>
|
||||||
|
<div>
|
||||||
|
<div className='text-lg leading-tight text-gray-500 dark:text-gray-400'>
|
||||||
|
Roles
|
||||||
|
</div>
|
||||||
|
<div className='text-3xl leading-tight font-semibold'>
|
||||||
|
{roles}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<BaseIcon
|
||||||
|
className={`${iconsColor}`}
|
||||||
|
w='w-16'
|
||||||
|
h='h-16'
|
||||||
|
size={48}
|
||||||
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
|
// @ts-ignore
|
||||||
|
path={
|
||||||
|
icon.mdiShieldAccountVariantOutline || icon.mdiTable
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Link>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{hasPermission(currentUser, 'READ_PERMISSIONS') && (
|
||||||
|
<Link href={'/permissions/permissions-list'}>
|
||||||
|
<div
|
||||||
|
className={`${
|
||||||
|
corners !== 'rounded-full' ? corners : 'rounded-3xl'
|
||||||
|
} dark:bg-dark-900 ${cardsStyle} dark:border-dark-700 p-6`}
|
||||||
|
>
|
||||||
|
<div className='flex justify-between align-center'>
|
||||||
|
<div>
|
||||||
|
<div className='text-lg leading-tight text-gray-500 dark:text-gray-400'>
|
||||||
|
Permissions
|
||||||
|
</div>
|
||||||
|
<div className='text-3xl leading-tight font-semibold'>
|
||||||
|
{permissions}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<BaseIcon
|
||||||
|
className={`${iconsColor}`}
|
||||||
|
w='w-16'
|
||||||
|
h='h-16'
|
||||||
|
size={48}
|
||||||
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
|
// @ts-ignore
|
||||||
|
path={icon.mdiShieldAccountOutline || icon.mdiTable}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Link>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{hasPermission(currentUser, 'READ_COMPANIES') && (
|
||||||
|
<Link href={'/companies/companies-list'}>
|
||||||
|
<div
|
||||||
|
className={`${
|
||||||
|
corners !== 'rounded-full' ? corners : 'rounded-3xl'
|
||||||
|
} dark:bg-dark-900 ${cardsStyle} dark:border-dark-700 p-6`}
|
||||||
|
>
|
||||||
|
<div className='flex justify-between align-center'>
|
||||||
|
<div>
|
||||||
|
<div className='text-lg leading-tight text-gray-500 dark:text-gray-400'>
|
||||||
|
Companies
|
||||||
|
</div>
|
||||||
|
<div className='text-3xl leading-tight font-semibold'>
|
||||||
|
{companies}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<BaseIcon
|
||||||
|
className={`${iconsColor}`}
|
||||||
|
w='w-16'
|
||||||
|
h='h-16'
|
||||||
|
size={48}
|
||||||
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
|
// @ts-ignore
|
||||||
|
path={icon.mdiTable || icon.mdiTable}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Link>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{hasPermission(currentUser, 'READ_STAFF') && (
|
||||||
|
<Link href={'/staff/staff-list'}>
|
||||||
|
<div
|
||||||
|
className={`${
|
||||||
|
corners !== 'rounded-full' ? corners : 'rounded-3xl'
|
||||||
|
} dark:bg-dark-900 ${cardsStyle} dark:border-dark-700 p-6`}
|
||||||
|
>
|
||||||
|
<div className='flex justify-between align-center'>
|
||||||
|
<div>
|
||||||
|
<div className='text-lg leading-tight text-gray-500 dark:text-gray-400'>
|
||||||
|
Staff
|
||||||
|
</div>
|
||||||
|
<div className='text-3xl leading-tight font-semibold'>
|
||||||
|
{staff}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<BaseIcon
|
||||||
|
className={`${iconsColor}`}
|
||||||
|
w='w-16'
|
||||||
|
h='h-16'
|
||||||
|
size={48}
|
||||||
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
|
// @ts-ignore
|
||||||
|
path={icon.mdiTable || icon.mdiTable}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Link>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{hasPermission(currentUser, 'READ_CLIENTS') && (
|
||||||
|
<Link href={'/clients/clients-list'}>
|
||||||
|
<div
|
||||||
|
className={`${
|
||||||
|
corners !== 'rounded-full' ? corners : 'rounded-3xl'
|
||||||
|
} dark:bg-dark-900 ${cardsStyle} dark:border-dark-700 p-6`}
|
||||||
|
>
|
||||||
|
<div className='flex justify-between align-center'>
|
||||||
|
<div>
|
||||||
|
<div className='text-lg leading-tight text-gray-500 dark:text-gray-400'>
|
||||||
|
Clients
|
||||||
|
</div>
|
||||||
|
<div className='text-3xl leading-tight font-semibold'>
|
||||||
|
{clients}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<BaseIcon
|
||||||
|
className={`${iconsColor}`}
|
||||||
|
w='w-16'
|
||||||
|
h='h-16'
|
||||||
|
size={48}
|
||||||
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
|
// @ts-ignore
|
||||||
|
path={icon.mdiTable || icon.mdiTable}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Link>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</SectionMain>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
Dashboard.getLayout = function getLayout(page: ReactElement) {
|
||||||
|
return <LayoutAuthenticated>{page}</LayoutAuthenticated>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Dashboard;
|
||||||
Loading…
x
Reference in New Issue
Block a user