import React, { useState, useEffect } from 'react'; import CircularTable from './CircularTable'; import { Breadcrumb, Tabs, Tab, Dropdown } from "react-bootstrap"; import { Columns, Download, Filter, PencilSquare, ArrowBarRight, ChevronDown, ChevronRight, FileX } from "react-bootstrap-icons"; import { CustomerService, LabelService, SeatingService } from '../../services'; import moment from 'moment'; import Select from 'react-select'; const Seating = () => { const initialValue = { rows: [{ id: 1, tables: 1 }], tables: { 'table-1': { id: 1, tableId: 'table-1', seats: [ { id: '1-A', name: 'A', customerId: '', customerName: '', label: {}, rowIndex: 1 }, { id: '1-B', name: 'B', customerId: '', customerName: '', label: {}, rowIndex: 1 }, { id: '1-C', name: 'C', customerId: '', customerName: '', label: {}, rowIndex: 1 }, { id: '1-D', name: 'D', customerId: '', customerName: '', label: {}, rowIndex: 1 }, { id: '1-E', name: 'E', customerId: '', customerName: '', label: {}, rowIndex: 1 }, { id: '1-F', name: 'F', customerId: '', customerName: '', label: {}, rowIndex: 1 }, { id: '1-G', name: 'G', customerId: '', customerName: '', label: {}, rowIndex: 1 }, { id: '1-H', name: 'H', customerId: '', customerName: '', label: {}, rowIndex: 1 } ], expanded: false, rowIndex: 1 } } }; const [tableLayout, setTableLayout] = useState({ rows: [], tables: {} } // rows: [ // { // itemsLength: 5, // id: 'row-1' // }, { // itemsLength: 5, // id: 'row-2' // }, { // itemsLength: 5, // id: 'row-3' // } // ], // tables: ); const [rowCount, setRowCount] = useState(1); const [currentDateRecord, setCurrentDateRecord] = useState(null); const [tableCountsPerRow, setTableCountsPerRow] = useState([1]); const [editingSeat, setEditingSeat] = useState(null); const [showTableLayoutConfig, setShowTableLayoutConfig] = useState(false); const [currentLabels, setCurrentLabels] = useState([]); const [newLabel, setNewLabel] = useState({ label_name: undefined, label_color: undefined}); const [customers, setCustomers] = useState([]); const [showLabelConfig, setShowLabelConfig] = useState(false); const [originalLabelsList, setOriginalLabelsList] = useState([]); const [startAddLabel, setStartAddLabel] = useState(false); const [deletedItems, setDeletedItems] = useState([]); const [selectedCustomer, setSelectedCustomer] = useState(undefined); const [selectedCustomerLabel, setSelectedCustomerLabel] = useState(undefined); const [selectedLabelColor, setSelectedLabelColor] = useState(undefined); const colorsList = ['#AD967A', '#BD816E', '#2B76E5', '#66CCFF', '#0A7E22', '#00C875', '#9CD326', '#FFCB00', '#FF642E', '#FD314D', '#BB3354', '#FF158A', '#9B51E0', '#BDA8F9']; useEffect(() => { CustomerService.getAllActiveCustomers().then(data => setCustomers(data?.data)); LabelService.getAll('active').then((data) => {setCurrentLabels(data?.data); setOriginalLabelsList(data?.data)}); SeatingService.getAll(moment().format('MM/DD/YYYY')).then(data => { const result = data?.data; if (result?.length > 0) { setTableLayout(result[0]?.seating_assignment); setCurrentDateRecord(result[0]); setRowCount(result[0]?.seating_assignment?.rows?.length); setTableCountsPerRow(result[0]?.seating_assignment?.rows?.map(item => item.tables)); } }); }, []) useEffect(() => { const newRows = Array.from({length: rowCount}, (_, index) => ({ id: index+1, tables: tableCountsPerRow[index] || 0 })); if (rowCount !== tableLayout.rows?.length) { setTableLayout(prevLayout => ({ ...prevLayout, rows: newRows })); if (tableCountsPerRow.length !== rowCount) { setTableCountsPerRow(prev => { const newCounts = [...prev]; while(newCounts.length < newCounts) { newCounts.push(0); } return newCounts.slice(0, rowCount); }) } } }, [rowCount]); useEffect(() => { const newTables = {}; let tableNumber = 1; let startUpdate = false; if (tableCountsPerRow.length !== tableLayout.rows.length) { startUpdate = true; } else { for (let i = 0; i { const tableCount = tableCountsPerRow[rowIndex] || 0; row.tables = tableCount; for (let tableIndex = 0; tableIndex < tableCount; tableIndex++) { const tableId = `table-${tableNumber}` if (!newTables[tableId]) { const seats = Array.from({length: 8}, (_, seatIndex) => { const seatLetter = String.fromCharCode(65 + seatIndex); return { id: `${tableNumber}-${seatLetter}`, name: seatLetter, customerName: '', customerId: '', rowIndex: rowIndex + 1, label: {label_name: undefined, label_color: undefined} } }); newTables[tableId] = { id: tableNumber, tableId: tableId, seats, expanded: false, rowIndex: rowIndex + 1 } } else { newTables[tableId] = tableLayout.tables[tableId]; } tableNumber++; } }) setTableLayout(prevLayout => ({ ...prevLayout, rows: prevLayout.rows.map((item, index) => ({...item, tables: tableCountsPerRow[index]}) ), tables: newTables })); } }, [tableCountsPerRow, tableLayout.rows]); const handleRowCountChange = (e) => { const count = parseInt(e.target.value) || 0; setRowCount(count); } const handleTableCountChange = (rowIndex, count) => { setTableCountsPerRow(prev => { const newCounts = [...prev]; newCounts[rowIndex] = parseInt(count) || 0; return newCounts; }) } const toggleTableExpansion = (tableId) => { setTableLayout(prevLayout => ({ ...prevLayout, tables: { ...prevLayout.tables, [tableId]: { ...prevLayout.tables[tableId], expanded: !prevLayout.tables[tableId].expanded } } })); } const cleanAndClose = () => { setTableLayout(currentDateRecord?.seat_assignment || initialValue); setRowCount(currentDateRecord?.seat_assignment?.rows?.length || 1); setTableCountsPerRow(currentDateRecord?.seat_assignment?.rows?.map(item => item.tables)); setShowTableLayoutConfig(false); setSelectedCustomer(undefined); setSelectedCustomerLabel(undefined); } const saveAndClose = () => { if (currentDateRecord) { SeatingService.updateSeating(currentDateRecord?.id, { seating_assignment: tableLayout, update_by: localStorage.getItem('user') && JSON.parse(localStorage.getItem('user'))?.name, update_date: new Date() }) } else { SeatingService.createNewSeating({ date: moment().format('MM/DD/YYYY'), seating_assignment: tableLayout, create_by: localStorage.getItem('user') && JSON.parse(localStorage.getItem('user'))?.name, update_by: localStorage.getItem('user') && JSON.parse(localStorage.getItem('user'))?.name, create_date: new Date(), update_date: new Date() }).then((data) => { const result = data?.data; setCurrentDateRecord(result); }) } setShowTableLayoutConfig(false); setSelectedCustomer(undefined); setSelectedCustomerLabel(undefined); } const [keyword, setKeyword] = useState(''); const getTotalTableNumber = () => tableCountsPerRow.reduce((acc, curr) => acc + curr, 0); const tablesByRow = () => tableLayout.rows.map((row, rowIndex) => { const rowTables = Object.values(tableLayout.tables).filter(table => table.rowIndex === rowIndex + 1).sort((a,b) => a.id - b.id); return { rowId: row.id, tables: rowTables } }) const startEditingSeat = (tableId, seatId) => { const seat = tableLayout.tables[tableId].seats.find(seat => seat.id === seatId); setEditingSeat({ tableId, seatId, customerId: seat?.customerId, label: seat?.label, customerName: seat?.customerName }); setSelectedCustomer({value: seat?.customerId, label: seat?.customerName}); setSelectedCustomerLabel({value: seat?.label?.id, label: seat?.label?.label_name}); }; const onCustomerChange = (selectedCustomer) => { setEditingSeat({ ...editingSeat, customerId: selectedCustomer.value, customerName: selectedCustomer.label }); setSelectedCustomer(selectedCustomer) } const handleLabelChange = (selectedLabel) => { setEditingSeat({ ...editingSeat, label: { label_name: selectedLabel.label, id: selectedLabel.value, label_color: currentLabels.find(item => item.id === selectedLabel.value)?.label_color } }) setSelectedCustomerLabel(selectedLabel); } const handleNewLabelNameChange = (e) => { setNewLabel(prevLabel => ({ ...prevLabel, label_name: e.target.value })) } const handleNewLabelColorChange = (selectedColor) => { setSelectedLabelColor(selectedColor); setNewLabel(prevLabel => ({ ...prevLabel, label_color: selectedColor.value })) } const saveSeatEdit = () =>{ if (!editingSeat) return; const {tableId, seatId, customerName, customerId, label} = editingSeat; setTableLayout(prevLayout => { const updatedSeats = prevLayout.tables[tableId].seats.map(seat => seat.id === seatId ? {...seat, customerName, customerId, label} : seat); const finalResult = { ...prevLayout, tables: { ...prevLayout.tables, [tableId]: { ...prevLayout.tables[tableId], seats: updatedSeats } } }; SeatingService.updateSeating(currentDateRecord?.id, { seating_assignment: finalResult, update_by: localStorage.getItem('user') && JSON.parse(localStorage.getItem('user'))?.name, update_date: new Date()}); CustomerService.updateCustomer(customerId, { table_id: tableId, seating: seatId, tags:[...customers.find(item => item.id === customerId)?.tags, label?.label_name], edit_by: localStorage.getItem('user') && JSON.parse(localStorage.getItem('user'))?.name, edit_date: new Date()}) return finalResult; }); setEditingSeat(null); } const cancelSeatEdit = () => { setEditingSeat(null); } const saveLabelAndClose = () => { if (newLabel.label_color && newLabel.label_name) { LabelService.createNewLabel(newLabel).then(() => { LabelService.getAll('active').then(data => { setCurrentLabels(data?.data); setOriginalLabelsList(data?.data); setShowLabelConfig(false); setStartAddLabel(false); setNewLabel({ label_color: undefined, label_name: undefined}) }); }); } if (deletedItems.length > 0) { Promise.all(deletedItems.map(item => LabelService.updateLabel(item.id, {status: 'inactive'}))).then(() => setDeletedItems([])); } } const cleanLabelAndClose = () => { setCurrentLabels(originalLabelsList); setShowLabelConfig(false); setStartAddLabel(false); } const onDeleteLabel = (item) => { setCurrentLabels(prevLabels => ({ ...prevLabels.filter(lb => lb.id !== item.id) })) setDeletedItems(prevLabels => ([ ...prevLabels, item ])) } return (
Lobby Seating Chart

Seating Chart

Stage
{ tablesByRow().map((rowItem, rowIndex) => { return (
{ rowItem?.tables?.map((item, itemIndex) => ) }
) }) }
{ currentLabels.map((item) =>
{item.label_name}
) }
setKeyword(e.currentTarget.value)} /> {/* */}
Manage Seating Chart
{/* */}
Table Layout setShowTableLayoutConfig(true)}/> { showTableLayoutConfig &&
Manage Table Layout
Number of Rows
{ rowCount>0 && Array.from({length: rowCount}).map((_, rowIndex) => (
{`Row ${rowIndex + 1}`}
handleTableCountChange(rowIndex, e.target.value)}/>
)) }
}
{ Object.keys(tableLayout.tables).map((tableId) => (
{!tableLayout.tables[tableId]?.expanded && toggleTableExpansion(tableId)} />} {tableLayout.tables[tableId]?.expanded && toggleTableExpansion(tableId)} />} {tableId.replace('-', ' ')}
{tableLayout.tables[tableId]?.expanded && tableLayout.tables[tableId]?.seats.map(seat =>
{`${seat.name}. ${seat.customerName}`} startEditingSeat(tableId, seat.id)} /> { editingSeat && editingSeat.tableId === tableId && editingSeat.seatId === seat.id &&
Seat Assignment
Customer Name
Customer Label
}
)}
)) }
Customer Label setShowLabelConfig(true)}/> { showLabelConfig &&
Customer Labels
{ currentLabels.map((item) =>
{item.label_name} onDeleteLabel(item)}>
) }
{!startAddLabel && } {startAddLabel && <>
Label Name
Label Color
{/* */}
}
}
{ currentLabels.map((item) =>
{item.label_name}
) }
) } export default Seating;