Forced merge: merge ai-dev into master

This commit is contained in:
Flatlogic Bot 2026-01-15 09:06:57 +00:00
commit 26a02431a3
5 changed files with 139 additions and 11 deletions

View File

@ -7,6 +7,11 @@ const menuAside: MenuAsideItem[] = [
icon: icon.mdiViewDashboardOutline,
label: 'Dashboard',
},
{
href: '/tables',
label: 'Table Management',
icon: icon.mdiTableChair,
},
{
href: '/users/users-list',
@ -50,7 +55,7 @@ const menuAside: MenuAsideItem[] = [
},
{
href: '/tables/tables-list',
label: 'Tables',
label: 'Table List',
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
icon: 'mdiSeat' in icon ? icon['mdiSeat' as keyof typeof icon] : icon.mdiTable ?? icon.mdiTable,

View File

@ -184,7 +184,7 @@ const ReservationsNew = () => {
// get from url params
const { dateRangeStart, dateRangeEnd } = router.query
const { dateRangeStart, dateRangeEnd, tableId } = router.query
const handleSubmit = async (data) => {
@ -206,11 +206,12 @@ const ReservationsNew = () => {
dateRangeStart && dateRangeEnd ?
(dateRangeStart && dateRangeEnd) || tableId ?
{
...initialValues,
start_at: moment(dateRangeStart).format('YYYY-MM-DDTHH:mm'),
end_at: moment(dateRangeEnd).format('YYYY-MM-DDTHH:mm'),
table: tableId,
} : initialValues
}

View File

@ -0,0 +1,122 @@
import { useState, useEffect } from 'react'
import { useDispatch, useSelector } from 'react-redux'
import type { ReactElement } from 'react'
import { useRouter } from 'next/router'
import Link from 'next/link'
import Head from 'next/head'
import { mdiTable } from '@mdi/js'
import CardBox from '../../components/CardBox'
import LayoutAuthenticated from '../../layouts/Authenticated'
import SectionMain from '../../components/SectionMain'
import SectionTitleLineWithButton from '../../components/SectionTitleLineWithButton'
import { getPageTitle } from '../../config'
import { fetchTables } from '../../stores/tables/tablesSlice'
import { fetchReservations } from '../../stores/reservations/reservationsSlice'
const TableStatus = {
Available: 'Available',
Reserved: 'Reserved',
Occupied: 'Occupied',
}
const TableCard = ({ table, status }) => {
const router = useRouter()
const getStatusColor = () => {
switch (status) {
case TableStatus.Available:
return 'bg-green-500'
case TableStatus.Reserved:
return 'bg-orange-500'
case TableStatus.Occupied:
return 'bg-red-500'
default:
return 'bg-gray-400'
}
}
const handleTableClick = () => {
if (status === TableStatus.Available) {
router.push(`/reservations/reservations-new?tableId=${table.id}`)
} else {
// Find reservation and show details, for now just log
console.log(`Table ${table.number} is ${status}`)
}
}
return (
<div
className={`p-4 rounded-lg text-white cursor-pointer transform hover:scale-105 transition-transform ${getStatusColor()}`}
onClick={handleTableClick}
>
<div className="text-lg font-bold">Table {table.number}</div>
<div>{table.capacity} Seats</div>
<div className="mt-2">{status}</div>
</div>
)
}
const TablesPage = () => {
const dispatch = useDispatch()
const router = useRouter()
const tables = useSelector((state) => state.tables.tables)
const reservations = useSelector((state) => state.reservations.reservations)
const [tableStatuses, setTableStatuses] = useState({})
useEffect(() => {
dispatch(fetchTables())
dispatch(fetchReservations())
}, [dispatch])
useEffect(() => {
const statuses = {}
const now = new Date()
tables.forEach((table) => {
const currentReservation = reservations.find(
(r) =>
r.tableId === table.id &&
new Date(r.startTime) <= now &&
new Date(r.endTime) > now,
)
if (currentReservation) {
if (currentReservation.status === 'Confirmed') {
statuses[table.id] = TableStatus.Occupied
} else {
statuses[table.id] = TableStatus.Reserved
}
} else {
statuses[table.id] = TableStatus.Available
}
})
setTableStatuses(statuses)
}, [tables, reservations])
return (
<>
<Head>
<title>{getPageTitle('Tables')}</title>
</Head>
<SectionMain>
<SectionTitleLineWithButton icon={mdiTable} title="Tables" main />
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5 gap-6">
{tables.map((table) => (
<TableCard key={table.id} table={table} status={tableStatuses[table.id]} />
))}
</div>
</SectionMain>
</>
)
}
TablesPage.getLayout = function getLayout(page: ReactElement) {
return <LayoutAuthenticated>{page}</LayoutAuthenticated>
}
export default TablesPage

View File

@ -28,7 +28,7 @@ const initialState: MainState = {
},
}
export const fetch = createAsyncThunk('reservations/fetch', async (data: any) => {
export const fetchReservations = createAsyncThunk('reservations/fetch', async (data: any = {}) => {
const { id, query } = data
const result = await axios.get(
`reservations${
@ -132,16 +132,16 @@ export const reservationsSlice = createSlice({
},
},
extraReducers: (builder) => {
builder.addCase(fetch.pending, (state) => {
builder.addCase(fetchReservations.pending, (state) => {
state.loading = true
resetNotify(state);
})
builder.addCase(fetch.rejected, (state, action) => {
builder.addCase(fetchReservations.rejected, (state, action) => {
state.loading = false
rejectNotify(state, action);
})
builder.addCase(fetch.fulfilled, (state, action) => {
builder.addCase(fetchReservations.fulfilled, (state, action) => {
if (action.payload.rows && action.payload.count >= 0) {
state.reservations = action.payload.rows;
state.count = action.payload.count;

View File

@ -28,7 +28,7 @@ const initialState: MainState = {
},
}
export const fetch = createAsyncThunk('tables/fetch', async (data: any) => {
export const fetchTables = createAsyncThunk('tables/fetch', async (data: any = {}) => {
const { id, query } = data
const result = await axios.get(
`tables${
@ -132,16 +132,16 @@ export const tablesSlice = createSlice({
},
},
extraReducers: (builder) => {
builder.addCase(fetch.pending, (state) => {
builder.addCase(fetchTables.pending, (state) => {
state.loading = true
resetNotify(state);
})
builder.addCase(fetch.rejected, (state, action) => {
builder.addCase(fetchTables.rejected, (state, action) => {
state.loading = false
rejectNotify(state, action);
})
builder.addCase(fetch.fulfilled, (state, action) => {
builder.addCase(fetchTables.fulfilled, (state, action) => {
if (action.payload.rows && action.payload.count >= 0) {
state.tables = action.payload.rows;
state.count = action.payload.count;