Merge pull request 'truong-sprint-1' (#8) from truong-sprint-1 into master
Reviewed-on: #8
This commit is contained in:
commit
571ebb6a09
|
|
@ -49,6 +49,21 @@ class TicketController extends Controller
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
$this->searchRequest(
|
||||||
|
builder: $tickets,
|
||||||
|
value: $request->get('search'),
|
||||||
|
fields: [
|
||||||
|
'users.name',
|
||||||
|
"start_date",
|
||||||
|
"startPeriod.c_name",
|
||||||
|
"end_date",
|
||||||
|
"endPeriod.c_name",
|
||||||
|
"typeReason.c_name",
|
||||||
|
'status',
|
||||||
|
"reason",
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
$responseData = array_merge(
|
$responseData = array_merge(
|
||||||
$tickets
|
$tickets
|
||||||
->join('users', 'tickets.user_id', '=', 'users.id')
|
->join('users', 'tickets.user_id', '=', 'users.id')
|
||||||
|
|
@ -111,8 +126,58 @@ class TicketController extends Controller
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
$this->searchRequest(
|
||||||
|
builder: $tickets,
|
||||||
|
value: $request->get('search'),
|
||||||
|
fields: [
|
||||||
|
'users.name',
|
||||||
|
"start_date",
|
||||||
|
"startPeriod.c_name",
|
||||||
|
"end_date",
|
||||||
|
"endPeriod.c_name",
|
||||||
|
"typeReason.c_name",
|
||||||
|
'status',
|
||||||
|
"reason",
|
||||||
|
"admin_note"
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
if ($request->typeReason != '') {
|
||||||
|
$tickets = $tickets->where('tickets.type', '=', $request->typeReason);
|
||||||
|
}
|
||||||
|
if ($request->statusFilter != '') {
|
||||||
|
$tickets = $tickets->where('tickets.status', '=', $request->statusFilter);
|
||||||
|
}
|
||||||
|
|
||||||
$responseData = array_merge(
|
$responseData = array_merge(
|
||||||
$tickets->orderBy('created_at', 'desc')->paginate($request->get('per_page'))->toArray(),
|
$tickets
|
||||||
|
->join('users', 'tickets.user_id', '=', 'users.id')
|
||||||
|
->leftJoin("categories as startPeriod", function ($join) {
|
||||||
|
$join->on('start_period', '=', 'startPeriod.c_code');
|
||||||
|
$join->on('startPeriod.c_type', DB::raw("CONCAT('TIME_TYPE')"));
|
||||||
|
})
|
||||||
|
->leftJoin("categories as endPeriod", function ($join) {
|
||||||
|
$join->on('end_period', '=', 'endPeriod.c_code');
|
||||||
|
$join->on('endPeriod.c_type', DB::raw("CONCAT('TIME_TYPE')"));
|
||||||
|
})
|
||||||
|
->leftJoin("categories as typeReason", function ($join) {
|
||||||
|
$join->on('type', '=', 'typeReason.c_code');
|
||||||
|
$join->on('typeReason.c_type', DB::raw("CONCAT('REASON')"));
|
||||||
|
})
|
||||||
|
->leftJoin("categories as statusTickets", function ($join) {
|
||||||
|
$join->on('status', '=', 'statusTickets.c_code');
|
||||||
|
$join->on('statusTickets.c_type', DB::raw("CONCAT('STATUS_TICKETS')"));
|
||||||
|
})
|
||||||
|
->select(
|
||||||
|
'users.name as user_name',
|
||||||
|
'users.email',
|
||||||
|
'tickets.*',
|
||||||
|
'startPeriod.c_name as startPeriodName',
|
||||||
|
'endPeriod.c_name as endPeriodName',
|
||||||
|
'typeReason.c_name as typeReasonName',
|
||||||
|
'statusTickets.c_name as statusTicketsName',
|
||||||
|
)
|
||||||
|
->orderBy('tickets.created_at', 'desc')->paginate($request->get('per_page'))->toArray(),
|
||||||
['status' => true]
|
['status' => true]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -210,7 +275,7 @@ class TicketController extends Controller
|
||||||
return response()->json(['message' => "Ticket not found", 'status' => false]);
|
return response()->json(['message' => "Ticket not found", 'status' => false]);
|
||||||
}
|
}
|
||||||
$results = $this->getAllPeriod($ticket->start_date, $ticket->start_period, $ticket->end_date, $ticket->end_period);
|
$results = $this->getAllPeriod($ticket->start_date, $ticket->start_period, $ticket->end_date, $ticket->end_period);
|
||||||
|
|
||||||
// $admin->id != user_id of ticket ---> continue
|
// $admin->id != user_id of ticket ---> continue
|
||||||
// Confirm
|
// Confirm
|
||||||
// Add records to the notes table like function Timekeeping.addNoteForUser() based on the $results array
|
// Add records to the notes table like function Timekeeping.addNoteForUser() based on the $results array
|
||||||
|
|
@ -251,6 +316,7 @@ class TicketController extends Controller
|
||||||
$ticket['updated_by'] = $admin->name;
|
$ticket['updated_by'] = $admin->name;
|
||||||
$ticket['admin_note'] = $admin_note;
|
$ticket['admin_note'] = $admin_note;
|
||||||
$ticket['status'] = 'REFUSED';
|
$ticket['status'] = 'REFUSED';
|
||||||
|
$ticket->save();
|
||||||
return response()->json(['message' => "refused", 'status' => true]);
|
return response()->json(['message' => "refused", 'status' => true]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -78,6 +78,8 @@ export const getLeaveManagement = API_URL + 'v1/admin/leave-management'
|
||||||
export const updateNoteLeave = API_URL + 'v1/admin/leave-management/saveNoteLeave'
|
export const updateNoteLeave = API_URL + 'v1/admin/leave-management/saveNoteLeave'
|
||||||
|
|
||||||
//Tickets
|
//Tickets
|
||||||
|
export const getTickets = API_URL + 'v1/admin/ticket/all'
|
||||||
export const getTicketsOfUser = API_URL + 'v1/admin/ticket/getByUserId'
|
export const getTicketsOfUser = API_URL + 'v1/admin/ticket/getByUserId'
|
||||||
export const deleteTicket = API_URL + 'v1/admin/ticket/delete'
|
export const deleteTicket = API_URL + 'v1/admin/ticket/delete'
|
||||||
export const addTicket = API_URL + 'v1/admin/ticket/create'
|
export const addTicket = API_URL + 'v1/admin/ticket/create'
|
||||||
|
export const handleTicket = API_URL + 'v1/admin/ticket/handle-ticket'
|
||||||
|
|
@ -47,7 +47,11 @@ const data = [
|
||||||
icon: IconCalendarClock,
|
icon: IconCalendarClock,
|
||||||
},
|
},
|
||||||
{ link: '/tickets', label: 'Tickets', icon: IconTicket },
|
{ link: '/tickets', label: 'Tickets', icon: IconTicket },
|
||||||
{ link: '/tickets-management', label: 'Tickets Management', icon: IconDevices },
|
{
|
||||||
|
link: '/tickets-management',
|
||||||
|
label: 'Tickets Management',
|
||||||
|
icon: IconDevices,
|
||||||
|
},
|
||||||
// { link: '/jira', label: 'Jira', icon: IconSubtask },
|
// { link: '/jira', label: 'Jira', icon: IconSubtask },
|
||||||
// { link: '/custom-theme', label: 'Custom Theme', icon: IconBrush },
|
// { link: '/custom-theme', label: 'Custom Theme', icon: IconBrush },
|
||||||
// { link: '/general-setting', label: 'General Setting', icon: IconSettings },
|
// { link: '/general-setting', label: 'General Setting', icon: IconSettings },
|
||||||
|
|
@ -102,29 +106,33 @@ const Navbar = ({
|
||||||
getInitialValueInEffect: true,
|
getInitialValueInEffect: true,
|
||||||
})
|
})
|
||||||
|
|
||||||
const links = data.map((item) => (
|
const links = data.map((item) => {
|
||||||
<a
|
if (user?.user?.permission !== 'admin' && item.link === '/tickets-management')
|
||||||
className={classes.link}
|
return null
|
||||||
data-active={item.label === active || undefined}
|
return (
|
||||||
key={item.label}
|
<a
|
||||||
onClick={() => {
|
className={classes.link}
|
||||||
// setHeader(item.label);
|
data-active={item.label === active || undefined}
|
||||||
setActive(active)
|
key={item.label}
|
||||||
if (active !== item.label) {
|
onClick={() => {
|
||||||
navigate(item.link)
|
// setHeader(item.label);
|
||||||
}
|
setActive(active)
|
||||||
}}
|
if (active !== item.label) {
|
||||||
>
|
navigate(item.link)
|
||||||
<item.icon className={classes.linkIcon} stroke={1.5} />
|
}
|
||||||
<span
|
}}
|
||||||
className={`${classes.itemLabel} ${
|
|
||||||
isCompactMenu ? classes.labelCompactMenu : ''
|
|
||||||
} `}
|
|
||||||
>
|
>
|
||||||
{item.label}
|
<item.icon className={classes.linkIcon} stroke={1.5} />
|
||||||
</span>
|
<span
|
||||||
</a>
|
className={`${classes.itemLabel} ${
|
||||||
))
|
isCompactMenu ? classes.labelCompactMenu : ''
|
||||||
|
} `}
|
||||||
|
>
|
||||||
|
{item.label}
|
||||||
|
</span>
|
||||||
|
</a>
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
const handleLogout = useCallback(() => {
|
const handleLogout = useCallback(() => {
|
||||||
dispatch(logout(navigate))
|
dispatch(logout(navigate))
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,9 @@
|
||||||
import { useAppSelector } from '@/rtk/hooks'
|
import { useAppSelector } from '@/rtk/hooks'
|
||||||
import { checkExpToken, removeTokens } from '@/rtk/localStorage'
|
import {
|
||||||
|
checkExpToken,
|
||||||
|
checkPermissionAdmin,
|
||||||
|
removeTokens,
|
||||||
|
} from '@/rtk/localStorage'
|
||||||
import { selectAuthentication } from '@/rtk/slices/auth'
|
import { selectAuthentication } from '@/rtk/slices/auth'
|
||||||
import type { ReactNode } from 'react'
|
import type { ReactNode } from 'react'
|
||||||
import { Navigate } from 'react-router-dom'
|
import { Navigate } from 'react-router-dom'
|
||||||
|
|
@ -7,16 +11,31 @@ import { Navigate } from 'react-router-dom'
|
||||||
interface ProtectedRouteProps {
|
interface ProtectedRouteProps {
|
||||||
children: ReactNode
|
children: ReactNode
|
||||||
mode: string
|
mode: string
|
||||||
|
permission: string
|
||||||
}
|
}
|
||||||
|
|
||||||
const ProtectedRoute: React.FC<ProtectedRouteProps> = ({ children, mode }) => {
|
const ProtectedRoute: React.FC<ProtectedRouteProps> = ({
|
||||||
|
children,
|
||||||
|
mode,
|
||||||
|
permission = 'staff',
|
||||||
|
}) => {
|
||||||
const auth = useAppSelector(selectAuthentication)
|
const auth = useAppSelector(selectAuthentication)
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case 'login':
|
case 'login':
|
||||||
return checkExpToken() ? <Navigate to="/" /> : <>{children}</>
|
return checkExpToken() ? <Navigate to="/" /> : <>{children}</>
|
||||||
|
|
||||||
case 'route':
|
case 'route':
|
||||||
return !auth.user ? <Navigate to="/login" /> : <>{children}</>
|
return !auth.user ? (
|
||||||
|
<Navigate to="/login" />
|
||||||
|
) : permission == 'admin' ? (
|
||||||
|
checkPermissionAdmin() ? (
|
||||||
|
<>{children}</>
|
||||||
|
) : (
|
||||||
|
<Navigate to="/" />
|
||||||
|
)
|
||||||
|
) : (
|
||||||
|
<>{children}</>
|
||||||
|
)
|
||||||
|
|
||||||
case 'home':
|
case 'home':
|
||||||
if (checkExpToken()) {
|
if (checkExpToken()) {
|
||||||
|
|
|
||||||
|
|
@ -64,6 +64,12 @@ interface DataTimeType {
|
||||||
c_name: string
|
c_name: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface FilterInfo {
|
||||||
|
key: string
|
||||||
|
name: string
|
||||||
|
type: string
|
||||||
|
}
|
||||||
|
|
||||||
const Tickets = () => {
|
const Tickets = () => {
|
||||||
const [listTickets, setListTiskets] = useState<TListTickets>({
|
const [listTickets, setListTiskets] = useState<TListTickets>({
|
||||||
data: [],
|
data: [],
|
||||||
|
|
@ -127,7 +133,7 @@ const Tickets = () => {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'start_date',
|
name: 'start_date',
|
||||||
size: '11%',
|
size: '8%',
|
||||||
header: 'From Date',
|
header: 'From Date',
|
||||||
render: (row: any) => {
|
render: (row: any) => {
|
||||||
return moment(row.start_date).format('DD/MM/YYYY')
|
return moment(row.start_date).format('DD/MM/YYYY')
|
||||||
|
|
@ -140,7 +146,7 @@ const Tickets = () => {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'end_date',
|
name: 'end_date',
|
||||||
size: '10%',
|
size: '8%',
|
||||||
header: 'End Date',
|
header: 'End Date',
|
||||||
render: (row: any) => {
|
render: (row: any) => {
|
||||||
return moment(row.end_date).format('DD/MM/YYYY')
|
return moment(row.end_date).format('DD/MM/YYYY')
|
||||||
|
|
@ -153,7 +159,7 @@ const Tickets = () => {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'reason',
|
name: 'reason',
|
||||||
size: '20%',
|
size: '15%',
|
||||||
header: 'Notes',
|
header: 'Notes',
|
||||||
render: (row: any) => {
|
render: (row: any) => {
|
||||||
return (
|
return (
|
||||||
|
|
@ -178,7 +184,7 @@ const Tickets = () => {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'status',
|
name: 'status',
|
||||||
size: '8%',
|
size: '5%',
|
||||||
header: 'Status',
|
header: 'Status',
|
||||||
render: (row: any) => {
|
render: (row: any) => {
|
||||||
switch (row.status) {
|
switch (row.status) {
|
||||||
|
|
@ -193,6 +199,31 @@ const Tickets = () => {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'admin_note',
|
||||||
|
size: '15%',
|
||||||
|
header: 'Admin Notes',
|
||||||
|
render: (row: any) => {
|
||||||
|
return (
|
||||||
|
<HoverCard width={280} shadow="md">
|
||||||
|
<HoverCard.Target>
|
||||||
|
<Text fz={'sm'}>
|
||||||
|
{row.admin_note !== null &&
|
||||||
|
row.admin_note !== '' &&
|
||||||
|
row.admin_note.length > 25
|
||||||
|
? row.admin_note.slice(0, 25) + '...'
|
||||||
|
: row.admin_note}
|
||||||
|
</Text>
|
||||||
|
</HoverCard.Target>
|
||||||
|
<HoverCard.Dropdown>
|
||||||
|
<Textarea size="sm" autosize>
|
||||||
|
{row.admin_note}
|
||||||
|
</Textarea>
|
||||||
|
</HoverCard.Dropdown>
|
||||||
|
</HoverCard>
|
||||||
|
)
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: '#',
|
name: '#',
|
||||||
size: '5%',
|
size: '5%',
|
||||||
|
|
@ -215,23 +246,7 @@ const Tickets = () => {
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
const filterInfo = [
|
const filterInfo: FilterInfo[] = []
|
||||||
{
|
|
||||||
key: 'reason',
|
|
||||||
name: 'Notes',
|
|
||||||
type: 'text',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'start_date',
|
|
||||||
name: 'From Date',
|
|
||||||
type: 'date',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'end_date',
|
|
||||||
name: 'End Date',
|
|
||||||
type: 'date',
|
|
||||||
},
|
|
||||||
]
|
|
||||||
|
|
||||||
const getAllTickets = async () => {
|
const getAllTickets = async () => {
|
||||||
try {
|
try {
|
||||||
|
|
@ -330,7 +345,7 @@ const Tickets = () => {
|
||||||
filterInfo={filterInfo}
|
filterInfo={filterInfo}
|
||||||
data={listTickets}
|
data={listTickets}
|
||||||
columns={columns}
|
columns={columns}
|
||||||
// searchInput
|
searchInput
|
||||||
size=""
|
size=""
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
|
||||||
|
|
@ -1,38 +1,28 @@
|
||||||
import {
|
import { getListMaster, getTickets, handleTicket } from '@/api/Admin'
|
||||||
addTicket,
|
|
||||||
deleteTicket,
|
|
||||||
getListMaster,
|
|
||||||
getTicketsOfUser
|
|
||||||
} from '@/api/Admin'
|
|
||||||
import { DataTablePagination } from '@/components/DataTable/DataTable'
|
import { DataTablePagination } from '@/components/DataTable/DataTable'
|
||||||
import { Xdelete, create } from '@/rtk/helpers/CRUD'
|
import { create } from '@/rtk/helpers/CRUD'
|
||||||
import { get } from '@/rtk/helpers/apiService'
|
import { get } from '@/rtk/helpers/apiService'
|
||||||
import {
|
import {
|
||||||
|
Badge,
|
||||||
Box,
|
Box,
|
||||||
Button,
|
Button,
|
||||||
Dialog,
|
HoverCard,
|
||||||
Group,
|
|
||||||
Modal,
|
Modal,
|
||||||
Select,
|
Select,
|
||||||
Text,
|
Text,
|
||||||
Textarea,
|
Textarea,
|
||||||
} from '@mantine/core'
|
} from '@mantine/core'
|
||||||
import { DateInput } from '@mantine/dates'
|
|
||||||
import { useForm } from '@mantine/form'
|
import { useForm } from '@mantine/form'
|
||||||
import { notifications } from '@mantine/notifications'
|
import { notifications } from '@mantine/notifications'
|
||||||
import { IconTrash } from '@tabler/icons-react'
|
import { IconCheckbox, IconSquareXFilled } from '@tabler/icons-react'
|
||||||
import moment from 'moment'
|
import moment from 'moment'
|
||||||
import { useEffect, useState } from 'react'
|
import { useEffect, useState } from 'react'
|
||||||
import classes from './TicketsManagement.module.css'
|
import classes from './TicketsManagement.module.css'
|
||||||
|
|
||||||
type TTickets = {
|
type TTickets = {
|
||||||
id: number
|
ticket_id: number
|
||||||
start_period: string
|
admin_note: string
|
||||||
end_period: string
|
action: string
|
||||||
type: string
|
|
||||||
start_date: Date
|
|
||||||
end_date: Date
|
|
||||||
reason: string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type TListTickets = {
|
type TListTickets = {
|
||||||
|
|
@ -50,13 +40,13 @@ interface User {
|
||||||
updated_at: string | null
|
updated_at: string | null
|
||||||
}
|
}
|
||||||
|
|
||||||
interface DataReason {
|
interface FilterInfo {
|
||||||
id: number
|
key: string
|
||||||
c_code: string
|
name: string
|
||||||
c_name: string
|
type: string
|
||||||
}
|
}
|
||||||
|
|
||||||
interface DataTimeType {
|
interface DataReason {
|
||||||
id: number
|
id: number
|
||||||
c_code: string
|
c_code: string
|
||||||
c_name: string
|
c_name: string
|
||||||
|
|
@ -68,10 +58,11 @@ const TicketsManagement = () => {
|
||||||
})
|
})
|
||||||
const [action, setAction] = useState('')
|
const [action, setAction] = useState('')
|
||||||
const [item, setItem] = useState({ id: 0 })
|
const [item, setItem] = useState({ id: 0 })
|
||||||
const [activeBtn, setActiveBtn] = useState(false)
|
|
||||||
const [disableBtn, setDisableBtn] = useState(false)
|
const [disableBtn, setDisableBtn] = useState(false)
|
||||||
|
const [filter, setFilter] = useState({
|
||||||
const [dataTimeType, setDataTimeType] = useState<DataTimeType[]>([])
|
typeReason: '',
|
||||||
|
statusFilter: '',
|
||||||
|
})
|
||||||
const [dataReason, setDataReason] = useState<DataReason[]>([])
|
const [dataReason, setDataReason] = useState<DataReason[]>([])
|
||||||
|
|
||||||
const getListMasterByType = async (type: string) => {
|
const getListMasterByType = async (type: string) => {
|
||||||
|
|
@ -95,11 +86,6 @@ const TicketsManagement = () => {
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const fetchData = async () => {
|
const fetchData = async () => {
|
||||||
const resultTimeType = await getListMasterByType('TIME_TYPE')
|
|
||||||
setDataTimeType(
|
|
||||||
resultTimeType.filter((item: DataTimeType) => item.c_code !== 'ALL'),
|
|
||||||
)
|
|
||||||
|
|
||||||
const resultReason = await getListMasterByType('REASON')
|
const resultReason = await getListMasterByType('REASON')
|
||||||
setDataReason(resultReason)
|
setDataReason(resultReason)
|
||||||
}
|
}
|
||||||
|
|
@ -125,7 +111,7 @@ const TicketsManagement = () => {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'start_date',
|
name: 'start_date',
|
||||||
size: '11%',
|
size: '8%',
|
||||||
header: 'From Date',
|
header: 'From Date',
|
||||||
render: (row: any) => {
|
render: (row: any) => {
|
||||||
return moment(row.start_date).format('DD/MM/YYYY')
|
return moment(row.start_date).format('DD/MM/YYYY')
|
||||||
|
|
@ -138,7 +124,7 @@ const TicketsManagement = () => {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'end_date',
|
name: 'end_date',
|
||||||
size: '10%',
|
size: '8%',
|
||||||
header: 'End Date',
|
header: 'End Date',
|
||||||
render: (row: any) => {
|
render: (row: any) => {
|
||||||
return moment(row.end_date).format('DD/MM/YYYY')
|
return moment(row.end_date).format('DD/MM/YYYY')
|
||||||
|
|
@ -151,58 +137,150 @@ const TicketsManagement = () => {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'reason',
|
name: 'reason',
|
||||||
size: '20%',
|
size: '15%',
|
||||||
header: 'Notes',
|
header: 'Notes',
|
||||||
|
render: (row: any) => {
|
||||||
|
return (
|
||||||
|
<HoverCard width={280} shadow="md">
|
||||||
|
<HoverCard.Target>
|
||||||
|
<Text fz={'sm'}>
|
||||||
|
{row.reason !== null &&
|
||||||
|
row.reason !== '' &&
|
||||||
|
row.reason.length > 25
|
||||||
|
? row.reason.slice(0, 25) + '...'
|
||||||
|
: row.reason}
|
||||||
|
</Text>
|
||||||
|
</HoverCard.Target>
|
||||||
|
<HoverCard.Dropdown>
|
||||||
|
<Textarea size="sm" autosize>
|
||||||
|
{row.reason}
|
||||||
|
</Textarea>
|
||||||
|
</HoverCard.Dropdown>
|
||||||
|
</HoverCard>
|
||||||
|
)
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'status',
|
name: 'status',
|
||||||
size: '8%',
|
size: '5%',
|
||||||
header: 'Status',
|
header: 'Status',
|
||||||
|
render: (row: any) => {
|
||||||
|
switch (row.status) {
|
||||||
|
case 'WAITING':
|
||||||
|
return <Badge color="blue">Waiting</Badge>
|
||||||
|
case 'CONFIRMED':
|
||||||
|
return <Badge color="green">Confirmed</Badge>
|
||||||
|
case 'REFUSED':
|
||||||
|
return <Badge color="red">Refused</Badge>
|
||||||
|
default:
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'admin_note',
|
||||||
|
size: '15%',
|
||||||
|
header: 'Admin Notes',
|
||||||
|
render: (row: any) => {
|
||||||
|
return (
|
||||||
|
<HoverCard width={280} shadow="md">
|
||||||
|
<HoverCard.Target>
|
||||||
|
<Text fz={'sm'}>
|
||||||
|
{row.admin_note !== null &&
|
||||||
|
row.admin_note !== '' &&
|
||||||
|
row.admin_note.length > 25
|
||||||
|
? row.admin_note.slice(0, 25) + '...'
|
||||||
|
: row.admin_note}
|
||||||
|
</Text>
|
||||||
|
</HoverCard.Target>
|
||||||
|
<HoverCard.Dropdown>
|
||||||
|
<Textarea size="sm" autosize>
|
||||||
|
{row.admin_note}
|
||||||
|
</Textarea>
|
||||||
|
</HoverCard.Dropdown>
|
||||||
|
</HoverCard>
|
||||||
|
)
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '#',
|
name: '#',
|
||||||
size: '5%',
|
size: '5%',
|
||||||
header: 'Action',
|
header: 'Action',
|
||||||
render: (row: any) => {
|
render: (row: any) => {
|
||||||
return (
|
return row.status === 'WAITING' ? (
|
||||||
<Box className={classes.optionIcon}>
|
<Box className={classes.optionIcon}>
|
||||||
<IconTrash
|
<IconCheckbox
|
||||||
|
className={classes.editIcon}
|
||||||
|
onClick={() => {
|
||||||
|
setAction('confirm')
|
||||||
|
setItem(row)
|
||||||
|
form.reset()
|
||||||
|
}}
|
||||||
|
width={20}
|
||||||
|
height={20}
|
||||||
|
/>
|
||||||
|
<IconSquareXFilled
|
||||||
className={classes.deleteIcon}
|
className={classes.deleteIcon}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setAction('delete')
|
setAction('refuse')
|
||||||
setItem(row)
|
setItem(row)
|
||||||
|
form.reset()
|
||||||
}}
|
}}
|
||||||
width={20}
|
width={20}
|
||||||
height={20}
|
height={20}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
)
|
) : null
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
const filterInfo = [
|
const filterInfo: FilterInfo[] = [
|
||||||
{
|
// {
|
||||||
key: 'reason',
|
// key: 'users.name',
|
||||||
name: 'Notes',
|
// name: 'User',
|
||||||
type: 'text',
|
// type: 'text',
|
||||||
},
|
// },
|
||||||
{
|
// {
|
||||||
key: 'start_date',
|
// key: 'start_date',
|
||||||
name: 'From Date',
|
// name: 'From Date',
|
||||||
type: 'date',
|
// type: 'date',
|
||||||
},
|
// },
|
||||||
{
|
// {
|
||||||
key: 'end_date',
|
// key: 'startPeriod.c_name',
|
||||||
name: 'End Date',
|
// name: 'Start Period',
|
||||||
type: 'date',
|
// type: 'text',
|
||||||
},
|
// },
|
||||||
|
// {
|
||||||
|
// key: 'end_date',
|
||||||
|
// name: 'End Date',
|
||||||
|
// type: 'date',
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// key: 'endPeriod.c_name',
|
||||||
|
// name: 'End Period',
|
||||||
|
// type: 'text',
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// key: 'typeReason.c_name',
|
||||||
|
// name: 'Reason',
|
||||||
|
// type: 'text',
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// key: 'status',
|
||||||
|
// name: 'Status',
|
||||||
|
// type: 'text',
|
||||||
|
// }
|
||||||
]
|
]
|
||||||
|
|
||||||
const getAllTickets = async () => {
|
const getAllTickets = async () => {
|
||||||
try {
|
try {
|
||||||
const searchParams = new URLSearchParams(window.location.search)
|
const searchParams = new URLSearchParams(window.location.search)
|
||||||
const params = {}
|
|
||||||
|
const params = {
|
||||||
|
typeReason: filter.typeReason,
|
||||||
|
statusFilter: filter.statusFilter,
|
||||||
|
}
|
||||||
|
|
||||||
for (const [key, value] of searchParams.entries()) {
|
for (const [key, value] of searchParams.entries()) {
|
||||||
if (key === 'page' && value === '') {
|
if (key === 'page' && value === '') {
|
||||||
|
|
@ -212,7 +290,7 @@ const TicketsManagement = () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const res = await get(getTicketsOfUser, params)
|
const res = await get(getTickets, params)
|
||||||
if (res.status) {
|
if (res.status) {
|
||||||
setListTiskets(res)
|
setListTiskets(res)
|
||||||
}
|
}
|
||||||
|
|
@ -225,18 +303,14 @@ const TicketsManagement = () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleCreate = async (values: TTickets) => {
|
const handleSave = async (values: TTickets) => {
|
||||||
try {
|
try {
|
||||||
const res = await create(
|
const res = await create(
|
||||||
addTicket,
|
handleTicket,
|
||||||
{
|
{
|
||||||
// time_string: moment(values.time_string).format('YYYY-MM-DD HH:mm:ss'),
|
ticket_id: item.id,
|
||||||
start_date: moment(values.start_date).format('YYYY-MM-DD'),
|
action: action,
|
||||||
start_period: values.start_period,
|
admin_note: values.admin_note,
|
||||||
end_date: moment(values.end_date).format('YYYY-MM-DD'),
|
|
||||||
end_period: values.end_period,
|
|
||||||
type: values.type,
|
|
||||||
reason: values.reason,
|
|
||||||
},
|
},
|
||||||
getAllTickets,
|
getAllTickets,
|
||||||
)
|
)
|
||||||
|
|
@ -249,27 +323,15 @@ const TicketsManagement = () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleDelete = async (id: number) => {
|
|
||||||
try {
|
|
||||||
await Xdelete(deleteTicket, { ticket_id: id }, getAllTickets)
|
|
||||||
} catch (error) {
|
|
||||||
console.log(error)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
getAllTickets()
|
getAllTickets()
|
||||||
}, [])
|
}, [filter])
|
||||||
|
|
||||||
const form = useForm({
|
const form = useForm({
|
||||||
initialValues: {
|
initialValues: {
|
||||||
id: 0,
|
ticket_id: 0,
|
||||||
start_date: new Date(),
|
action: '',
|
||||||
start_period: '',
|
admin_note: '',
|
||||||
end_date: new Date(),
|
|
||||||
end_period: '',
|
|
||||||
type: '',
|
|
||||||
reason: '',
|
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
@ -280,172 +342,94 @@ const TicketsManagement = () => {
|
||||||
<Text>Admin/</Text>
|
<Text>Admin/</Text>
|
||||||
Tickets Management
|
Tickets Management
|
||||||
</h3>
|
</h3>
|
||||||
<Button
|
|
||||||
m={5}
|
|
||||||
onClick={() => {
|
|
||||||
setAction('add')
|
|
||||||
form.reset()
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
+ Add
|
|
||||||
</Button>
|
|
||||||
</div>
|
</div>
|
||||||
<Box p={20}>
|
<Box display={'flex'} p={15}>
|
||||||
|
<Box style={{ display: 'flex', flexFlow: 'column' }} w={'40%'}>
|
||||||
|
<Box w="100%" display={'flex'}>
|
||||||
|
<Select
|
||||||
|
clearable
|
||||||
|
w="50%"
|
||||||
|
value={filter.typeReason}
|
||||||
|
size="xs"
|
||||||
|
label="Reason"
|
||||||
|
data={dataReason.map((user) => ({
|
||||||
|
value: user.c_code.toString(),
|
||||||
|
label: user.c_name,
|
||||||
|
}))}
|
||||||
|
onChange={(e) => {
|
||||||
|
setFilter({ ...filter, typeReason: e! })
|
||||||
|
}}
|
||||||
|
></Select>
|
||||||
|
<Select
|
||||||
|
clearable
|
||||||
|
w="50%"
|
||||||
|
value={filter.statusFilter}
|
||||||
|
size="xs"
|
||||||
|
ml={'sm'}
|
||||||
|
label="Status"
|
||||||
|
data={[
|
||||||
|
{ value: 'WAITING', label: 'WAITING' },
|
||||||
|
{ value: 'CONFIRM', label: 'CONFIRM' },
|
||||||
|
{ value: 'REFUSED', label: 'REFUSED' },
|
||||||
|
]}
|
||||||
|
onChange={(e) => {
|
||||||
|
setFilter({ ...filter, statusFilter: e! })
|
||||||
|
}}
|
||||||
|
></Select>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
<Box>
|
||||||
{listTickets.data.length > 0 && (
|
{listTickets.data.length > 0 && (
|
||||||
<DataTablePagination
|
<DataTablePagination
|
||||||
filterInfo={filterInfo}
|
filterInfo={filterInfo}
|
||||||
data={listTickets}
|
data={listTickets}
|
||||||
columns={columns}
|
columns={columns}
|
||||||
// searchInput
|
searchInput
|
||||||
size=""
|
size=""
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
{/* Add/Edit User modal */}
|
|
||||||
<Modal
|
<Modal
|
||||||
opened={action === 'add' || action === 'edit'}
|
opened={action === 'confirm' || action === 'refuse'}
|
||||||
onClose={() => {
|
onClose={() => {
|
||||||
setAction('')
|
setAction('')
|
||||||
form.reset()
|
form.reset()
|
||||||
}}
|
}}
|
||||||
title={
|
title={
|
||||||
<Text pl={'sm'} fw={700} fz={'lg'}>
|
<Text pl={'sm'} fw={700} fz={'lg'}>
|
||||||
{action === 'add' && 'Add Ticket'}
|
{action === 'confirm' ? 'Confirm Ticket' : 'Refuse Ticket'}
|
||||||
</Text>
|
</Text>
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<form
|
<form
|
||||||
onSubmit={form.onSubmit(async (values) => {
|
onSubmit={form.onSubmit(async (values) => {
|
||||||
setDisableBtn(true)
|
setDisableBtn(true)
|
||||||
action === 'add' && (await handleCreate(values))
|
await handleSave(values)
|
||||||
setDisableBtn(false)
|
setDisableBtn(false)
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
<Box pl={'md'} pr={'md'}>
|
<Box pl={'md'} pr={'md'}>
|
||||||
<Box display={'flex'}>
|
|
||||||
<Box style={{ display: 'flex', flexFlow: 'column' }} w={'40%'}>
|
|
||||||
<DateInput
|
|
||||||
required
|
|
||||||
mb={'md'}
|
|
||||||
label={'From Date'}
|
|
||||||
value={new Date(form.values.start_date)}
|
|
||||||
valueFormat="DD/MM/YYYY"
|
|
||||||
onChange={(e) => form.setFieldValue('start_date', e!)}
|
|
||||||
></DateInput>
|
|
||||||
|
|
||||||
<Select
|
|
||||||
required
|
|
||||||
mb={'md'}
|
|
||||||
label={'Start Period'}
|
|
||||||
data={dataTimeType.map((item) => {
|
|
||||||
return { value: item.c_code.toString(), label: item.c_name }
|
|
||||||
})}
|
|
||||||
value={form.values.start_period}
|
|
||||||
error={form.errors.start_period}
|
|
||||||
onChange={(e) => form.setFieldValue('start_period', e!)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<Select
|
|
||||||
required
|
|
||||||
mb={'md'}
|
|
||||||
searchable
|
|
||||||
label="Type"
|
|
||||||
data={dataReason.map((user) => ({
|
|
||||||
value: user.c_code.toString(),
|
|
||||||
label: user.c_name,
|
|
||||||
}))}
|
|
||||||
value={form.values.type}
|
|
||||||
error={form.errors.type}
|
|
||||||
onChange={(e) => form.setFieldValue('type', e!)}
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
<Box
|
|
||||||
style={{ display: 'flex', flexFlow: 'column' }}
|
|
||||||
w={'20%'}
|
|
||||||
></Box>
|
|
||||||
<Box style={{ display: 'flex', flexFlow: 'column' }} w={'40%'}>
|
|
||||||
<DateInput
|
|
||||||
required
|
|
||||||
mb={'md'}
|
|
||||||
label={'End Date'}
|
|
||||||
value={new Date(form.values.end_date)}
|
|
||||||
valueFormat="DD/MM/YYYY"
|
|
||||||
onChange={(e) => form.setFieldValue('end_date', e!)}
|
|
||||||
></DateInput>
|
|
||||||
<Select
|
|
||||||
required
|
|
||||||
mb={'md'}
|
|
||||||
label={'End Period'}
|
|
||||||
data={dataTimeType.map((item) => {
|
|
||||||
return { value: item.c_code.toString(), label: item.c_name }
|
|
||||||
})}
|
|
||||||
value={form.values.end_period}
|
|
||||||
error={form.errors.end_period}
|
|
||||||
onChange={(e) => form.setFieldValue('end_period', e!)}
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
</Box>
|
|
||||||
|
|
||||||
<Textarea
|
<Textarea
|
||||||
label="Reason"
|
label="Admin Notes"
|
||||||
required
|
required
|
||||||
value={form.values.reason}
|
value={form.values.admin_note}
|
||||||
onChange={(e) => form.setFieldValue('reason', e.target.value)}
|
onChange={(e) => form.setFieldValue('admin_note', e.target.value)}
|
||||||
/>
|
/>
|
||||||
<Box ta={'center'}>
|
<Box ta={'center'}>
|
||||||
{action === 'add' && (
|
<Button
|
||||||
<Button
|
mt={'lg'}
|
||||||
mt={'lg'}
|
bg={'green'}
|
||||||
bg={'green'}
|
type="submit"
|
||||||
type="submit"
|
disabled={disableBtn}
|
||||||
disabled={disableBtn}
|
>
|
||||||
>
|
Save
|
||||||
Create
|
</Button>
|
||||||
</Button>
|
|
||||||
)}
|
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
</form>
|
</form>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
|
||||||
<Dialog
|
|
||||||
className={classes.dialog}
|
|
||||||
opened={action === 'delete'}
|
|
||||||
withCloseButton
|
|
||||||
onClose={() => setAction('')}
|
|
||||||
size="lg"
|
|
||||||
radius="md"
|
|
||||||
position={{ top: 30, right: 10 }}
|
|
||||||
>
|
|
||||||
<Text className={classes.dialogText} size="sm" mb="xs" fw={500}>
|
|
||||||
Do you want to delete this record?
|
|
||||||
<Group justify="center" m={10}>
|
|
||||||
<Button
|
|
||||||
disabled={activeBtn}
|
|
||||||
fw={700}
|
|
||||||
size="xs"
|
|
||||||
variant="light"
|
|
||||||
onClick={async () => {
|
|
||||||
setActiveBtn(true)
|
|
||||||
await handleDelete(item.id)
|
|
||||||
setActiveBtn(false)
|
|
||||||
setAction('')
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Yes
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
fw={700}
|
|
||||||
size="xs"
|
|
||||||
variant="light"
|
|
||||||
onClick={() => setAction('')}
|
|
||||||
>
|
|
||||||
Cancel
|
|
||||||
</Button>
|
|
||||||
</Group>
|
|
||||||
</Text>
|
|
||||||
</Dialog>
|
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ const mainRoutes = [
|
||||||
path: '/',
|
path: '/',
|
||||||
// element: <ProtectedRoute mode="home"><PageHome /></ProtectedRoute>,
|
// element: <ProtectedRoute mode="home"><PageHome /></ProtectedRoute>,
|
||||||
element: (
|
element: (
|
||||||
<ProtectedRoute mode="home">
|
<ProtectedRoute mode="home" permission="staff">
|
||||||
<Navigate to="/timekeeping"></Navigate>
|
<Navigate to="/timekeeping"></Navigate>
|
||||||
</ProtectedRoute>
|
</ProtectedRoute>
|
||||||
),
|
),
|
||||||
|
|
@ -29,7 +29,7 @@ const mainRoutes = [
|
||||||
{
|
{
|
||||||
path: '/welcome',
|
path: '/welcome',
|
||||||
element: (
|
element: (
|
||||||
<ProtectedRoute mode="route">
|
<ProtectedRoute mode="route" permission="staff">
|
||||||
<PageWelcome />
|
<PageWelcome />
|
||||||
</ProtectedRoute>
|
</ProtectedRoute>
|
||||||
),
|
),
|
||||||
|
|
@ -37,7 +37,7 @@ const mainRoutes = [
|
||||||
{
|
{
|
||||||
path: '/dashboard',
|
path: '/dashboard',
|
||||||
element: (
|
element: (
|
||||||
<ProtectedRoute mode="route">
|
<ProtectedRoute mode="route" permission="staff">
|
||||||
<BasePage
|
<BasePage
|
||||||
main={
|
main={
|
||||||
<>
|
<>
|
||||||
|
|
@ -51,7 +51,7 @@ const mainRoutes = [
|
||||||
{
|
{
|
||||||
path: '/general-setting',
|
path: '/general-setting',
|
||||||
element: (
|
element: (
|
||||||
<ProtectedRoute mode="route">
|
<ProtectedRoute mode="home" permission="staff">
|
||||||
<BasePage
|
<BasePage
|
||||||
main={
|
main={
|
||||||
<>
|
<>
|
||||||
|
|
@ -65,7 +65,7 @@ const mainRoutes = [
|
||||||
{
|
{
|
||||||
path: '/custom-theme',
|
path: '/custom-theme',
|
||||||
element: (
|
element: (
|
||||||
<ProtectedRoute mode="route">
|
<ProtectedRoute mode="home" permission="staff">
|
||||||
<BasePage
|
<BasePage
|
||||||
main={
|
main={
|
||||||
<>
|
<>
|
||||||
|
|
@ -79,7 +79,7 @@ const mainRoutes = [
|
||||||
{
|
{
|
||||||
path: '/tracking',
|
path: '/tracking',
|
||||||
element: (
|
element: (
|
||||||
<ProtectedRoute mode="route">
|
<ProtectedRoute mode="home" permission="staff">
|
||||||
<BasePage
|
<BasePage
|
||||||
main={
|
main={
|
||||||
<>
|
<>
|
||||||
|
|
@ -93,7 +93,7 @@ const mainRoutes = [
|
||||||
// {
|
// {
|
||||||
// path: '/jira',
|
// path: '/jira',
|
||||||
// element: (
|
// element: (
|
||||||
// <ProtectedRoute mode="route">
|
// <ProtectedRoute mode="home" permission="staff">
|
||||||
// <BasePage
|
// <BasePage
|
||||||
// main={
|
// main={
|
||||||
// <>
|
// <>
|
||||||
|
|
@ -107,7 +107,7 @@ const mainRoutes = [
|
||||||
{
|
{
|
||||||
path: '/worklogs',
|
path: '/worklogs',
|
||||||
element: (
|
element: (
|
||||||
<ProtectedRoute mode="route">
|
<ProtectedRoute mode="home" permission="staff">
|
||||||
<BasePage
|
<BasePage
|
||||||
main={
|
main={
|
||||||
<>
|
<>
|
||||||
|
|
@ -121,7 +121,7 @@ const mainRoutes = [
|
||||||
{
|
{
|
||||||
path: '/timekeeping',
|
path: '/timekeeping',
|
||||||
element: (
|
element: (
|
||||||
<ProtectedRoute mode="route">
|
<ProtectedRoute mode="home" permission="staff">
|
||||||
<BasePage
|
<BasePage
|
||||||
main={
|
main={
|
||||||
<>
|
<>
|
||||||
|
|
@ -135,7 +135,7 @@ const mainRoutes = [
|
||||||
{
|
{
|
||||||
path: '/leave-management',
|
path: '/leave-management',
|
||||||
element: (
|
element: (
|
||||||
<ProtectedRoute mode="route">
|
<ProtectedRoute mode="home" permission="staff">
|
||||||
<BasePage
|
<BasePage
|
||||||
main={
|
main={
|
||||||
<>
|
<>
|
||||||
|
|
@ -149,7 +149,7 @@ const mainRoutes = [
|
||||||
{
|
{
|
||||||
path: '/tickets',
|
path: '/tickets',
|
||||||
element: (
|
element: (
|
||||||
<ProtectedRoute mode="route">
|
<ProtectedRoute mode="route" permission="staff">
|
||||||
<BasePage
|
<BasePage
|
||||||
main={
|
main={
|
||||||
<>
|
<>
|
||||||
|
|
@ -163,7 +163,7 @@ const mainRoutes = [
|
||||||
{
|
{
|
||||||
path: '/tickets-management',
|
path: '/tickets-management',
|
||||||
element: (
|
element: (
|
||||||
<ProtectedRoute mode="route">
|
<ProtectedRoute mode="route" permission="admin">
|
||||||
<BasePage
|
<BasePage
|
||||||
main={
|
main={
|
||||||
<>
|
<>
|
||||||
|
|
@ -177,7 +177,7 @@ const mainRoutes = [
|
||||||
// {
|
// {
|
||||||
// path: '/packages',
|
// path: '/packages',
|
||||||
// element: (
|
// element: (
|
||||||
// <ProtectedRoute mode="route">
|
// <ProtectedRoute mode="home" permission="staff">
|
||||||
// <BasePage
|
// <BasePage
|
||||||
// main={
|
// main={
|
||||||
// <>
|
// <>
|
||||||
|
|
@ -191,7 +191,7 @@ const mainRoutes = [
|
||||||
// {
|
// {
|
||||||
// path: '/discounts',
|
// path: '/discounts',
|
||||||
// element: (
|
// element: (
|
||||||
// <ProtectedRoute mode="route">
|
// <ProtectedRoute mode="home" permission="staff">
|
||||||
// <BasePage
|
// <BasePage
|
||||||
// main={
|
// main={
|
||||||
// <>
|
// <>
|
||||||
|
|
@ -205,7 +205,7 @@ const mainRoutes = [
|
||||||
// {
|
// {
|
||||||
// path: '/client',
|
// path: '/client',
|
||||||
// element: (
|
// element: (
|
||||||
// <ProtectedRoute mode="route">
|
// <ProtectedRoute mode="home" permission="staff">
|
||||||
// <BasePage
|
// <BasePage
|
||||||
// main={
|
// main={
|
||||||
// <>
|
// <>
|
||||||
|
|
@ -219,7 +219,7 @@ const mainRoutes = [
|
||||||
// {
|
// {
|
||||||
// path: '/banner',
|
// path: '/banner',
|
||||||
// element: (
|
// element: (
|
||||||
// <ProtectedRoute mode="route">
|
// <ProtectedRoute mode="home" permission="staff">
|
||||||
// <BasePage
|
// <BasePage
|
||||||
// main={
|
// main={
|
||||||
// <>
|
// <>
|
||||||
|
|
@ -233,7 +233,7 @@ const mainRoutes = [
|
||||||
// {
|
// {
|
||||||
// path: '/order',
|
// path: '/order',
|
||||||
// element: (
|
// element: (
|
||||||
// <ProtectedRoute mode="route">
|
// <ProtectedRoute mode="home" permission="staff">
|
||||||
// <BasePage
|
// <BasePage
|
||||||
// main={
|
// main={
|
||||||
// <>
|
// <>
|
||||||
|
|
@ -247,7 +247,7 @@ const mainRoutes = [
|
||||||
// {
|
// {
|
||||||
// path: '/sn-check-history',
|
// path: '/sn-check-history',
|
||||||
// element: (
|
// element: (
|
||||||
// <ProtectedRoute mode="route">
|
// <ProtectedRoute mode="home" permission="staff">
|
||||||
// <BasePage
|
// <BasePage
|
||||||
// main={
|
// main={
|
||||||
// <>
|
// <>
|
||||||
|
|
@ -261,7 +261,7 @@ const mainRoutes = [
|
||||||
// {
|
// {
|
||||||
// path: '/contacts',
|
// path: '/contacts',
|
||||||
// element: (
|
// element: (
|
||||||
// <ProtectedRoute mode="route">
|
// <ProtectedRoute mode="home" permission="staff">
|
||||||
// <BasePage
|
// <BasePage
|
||||||
// main={
|
// main={
|
||||||
// <>
|
// <>
|
||||||
|
|
@ -275,7 +275,7 @@ const mainRoutes = [
|
||||||
{
|
{
|
||||||
path: '/login',
|
path: '/login',
|
||||||
element: (
|
element: (
|
||||||
<ProtectedRoute mode="login">
|
<ProtectedRoute mode="login" permission="staff">
|
||||||
<PageLogin />
|
<PageLogin />
|
||||||
</ProtectedRoute>
|
</ProtectedRoute>
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,21 @@ export const checkExpToken = () => {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const checkPermissionAdmin = () => {
|
||||||
|
const user = localStorage.getItem('user')
|
||||||
|
if (user) {
|
||||||
|
const parsedUser = JSON.parse(user)
|
||||||
|
if (parsedUser.user.permission == 'admin') {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export const getUser = () => localStorage.getItem('user') as string
|
export const getUser = () => localStorage.getItem('user') as string
|
||||||
export const getAccessToken = () =>
|
export const getAccessToken = () =>
|
||||||
localStorage.getItem('token')?.slice(1, -1) as string
|
localStorage.getItem('token')?.slice(1, -1) as string
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue