seating chart edit
This commit is contained in:
BIN
app/.DS_Store
vendored
BIN
app/.DS_Store
vendored
Binary file not shown.
@@ -1,16 +1,16 @@
|
||||
{
|
||||
"files": {
|
||||
"main.css": "/static/css/main.57cff37a.css",
|
||||
"main.js": "/static/js/main.68aeca0a.js",
|
||||
"main.css": "/static/css/main.6616f3cb.css",
|
||||
"main.js": "/static/js/main.0e292118.js",
|
||||
"static/js/787.c4e7f8f9.chunk.js": "/static/js/787.c4e7f8f9.chunk.js",
|
||||
"static/media/landing.png": "/static/media/landing.d4c6072db7a67dff6a78.png",
|
||||
"index.html": "/index.html",
|
||||
"main.57cff37a.css.map": "/static/css/main.57cff37a.css.map",
|
||||
"main.68aeca0a.js.map": "/static/js/main.68aeca0a.js.map",
|
||||
"main.6616f3cb.css.map": "/static/css/main.6616f3cb.css.map",
|
||||
"main.0e292118.js.map": "/static/js/main.0e292118.js.map",
|
||||
"787.c4e7f8f9.chunk.js.map": "/static/js/787.c4e7f8f9.chunk.js.map"
|
||||
},
|
||||
"entrypoints": [
|
||||
"static/css/main.57cff37a.css",
|
||||
"static/js/main.68aeca0a.js"
|
||||
"static/css/main.6616f3cb.css",
|
||||
"static/js/main.0e292118.js"
|
||||
]
|
||||
}
|
||||
@@ -1 +1 @@
|
||||
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="/favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="Web site created using create-react-app"/><link rel="apple-touch-icon" href="/logo192.png"/><script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script><link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css"><link rel="manifest" href="/manifest.json"/><title>Worldshine Transportation</title><script defer="defer" src="/static/js/main.68aeca0a.js"></script><link href="/static/css/main.57cff37a.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>
|
||||
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="/favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="Web site created using create-react-app"/><link rel="apple-touch-icon" href="/logo192.png"/><script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script><link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css"><link rel="manifest" href="/manifest.json"/><title>Worldshine Transportation</title><script defer="defer" src="/static/js/main.0e292118.js"></script><link href="/static/css/main.6616f3cb.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
app/views/static/css/main.6616f3cb.css.map
Normal file
1
app/views/static/css/main.6616f3cb.css.map
Normal file
File diff suppressed because one or more lines are too long
3
app/views/static/js/main.0e292118.js
Normal file
3
app/views/static/js/main.0e292118.js
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
BIN
client/.DS_Store
vendored
BIN
client/.DS_Store
vendored
Binary file not shown.
@@ -1651,11 +1651,11 @@ input[type="checkbox"] {
|
||||
.label-delete-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
font-size: 13px;
|
||||
border: 1px solid #ccc;
|
||||
padding: 8px;
|
||||
padding: 8px 12px;
|
||||
border-radius: 8px;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.btn-custom-label {
|
||||
@@ -1732,14 +1732,15 @@ input[type="checkbox"] {
|
||||
|
||||
.manage-seating-chart-container {
|
||||
background: #D0E1F8;
|
||||
/* right: -250px; */
|
||||
/* top: 0; */
|
||||
height: 100vh;
|
||||
width: 300px;
|
||||
min-width: 300px;
|
||||
flex-shrink: 0;
|
||||
padding: 16px;
|
||||
overflow: auto;
|
||||
margin-top: -40px;
|
||||
margin-left: 40px;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
margin-left: 24px;
|
||||
}
|
||||
|
||||
.manage-seating-chart-title-container {
|
||||
@@ -1768,6 +1769,11 @@ input[type="checkbox"] {
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.seating-page-container > .list.row {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.table-config-container {
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
@@ -121,6 +121,9 @@ const EventsCalendar = () => {
|
||||
const [editRepeatEndDate, setEditRepeatEndDate] = useState(null);
|
||||
const [editIndefiniteRepeat, setEditIndefiniteRepeat] = useState(false);
|
||||
const [editingRecurId, setEditingRecurId] = useState(null); // tracks if editing a recurrence rule
|
||||
// Delete confirmation modal
|
||||
const [showDeleteConfirm, setShowDeleteConfirm] = useState(false);
|
||||
const [deleteTargetId, setDeleteTargetId] = useState(null);
|
||||
|
||||
// Helper function to format name from "lastname, firstname" to "firstname lastname"
|
||||
const formatFullName = (name) => {
|
||||
@@ -818,12 +821,12 @@ const EventsCalendar = () => {
|
||||
style={{ cursor: 'pointer' }}
|
||||
title="Edit"
|
||||
/>
|
||||
<Archive
|
||||
size={16}
|
||||
onClick={() => disableEvent(calendarEvent?.id)}
|
||||
style={{ cursor: 'pointer' }}
|
||||
title="Delete"
|
||||
/>
|
||||
<Archive
|
||||
size={16}
|
||||
onClick={() => { setDeleteTargetId(calendarEvent?.id); setShowDeleteConfirm(true); }}
|
||||
style={{ cursor: 'pointer' }}
|
||||
title="Delete"
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
}
|
||||
@@ -2088,6 +2091,24 @@ const getReminderTitleLabel = (value) => {
|
||||
</Button>
|
||||
</Modal.Footer>
|
||||
</Modal>
|
||||
|
||||
{/* Delete Confirmation Modal */}
|
||||
<Modal show={showDeleteConfirm} onHide={() => { setShowDeleteConfirm(false); setDeleteTargetId(null); }} size="sm" centered>
|
||||
<Modal.Header closeButton>
|
||||
<Modal.Title>Confirm Delete</Modal.Title>
|
||||
</Modal.Header>
|
||||
<Modal.Body>
|
||||
Are you sure you want to delete this event?
|
||||
</Modal.Body>
|
||||
<Modal.Footer>
|
||||
<Button variant="secondary" size="sm" onClick={() => { setShowDeleteConfirm(false); setDeleteTargetId(null); }}>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button variant="danger" size="sm" onClick={() => { disableEvent(deleteTargetId); setShowDeleteConfirm(false); setDeleteTargetId(null); }}>
|
||||
Delete
|
||||
</Button>
|
||||
</Modal.Footer>
|
||||
</Modal>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
|
||||
@@ -98,6 +98,8 @@ const Seating = () => {
|
||||
|
||||
const [startAddLabel, setStartAddLabel] = useState(false);
|
||||
const [deletedItems, setDeletedItems] = useState([]);
|
||||
const [editingLabelId, setEditingLabelId] = useState(null);
|
||||
const [editingLabelName, setEditingLabelName] = useState('');
|
||||
|
||||
const [selectedCustomer, setSelectedCustomer] = useState(undefined);
|
||||
const [selectedCustomerLabel, setSelectedCustomerLabel] = useState(undefined);
|
||||
@@ -550,6 +552,8 @@ const Seating = () => {
|
||||
setCurrentLabels(originalLabelsList);
|
||||
setShowLabelConfig(false);
|
||||
setStartAddLabel(false);
|
||||
setEditingLabelId(null);
|
||||
setEditingLabelName('');
|
||||
}
|
||||
|
||||
const onDeleteLabel = (item) => {
|
||||
@@ -562,6 +566,28 @@ const Seating = () => {
|
||||
]))
|
||||
}
|
||||
|
||||
const startEditingLabel = (item) => {
|
||||
setEditingLabelId(item.id);
|
||||
setEditingLabelName(item.label_name);
|
||||
}
|
||||
|
||||
const saveEditingLabel = () => {
|
||||
if (!editingLabelId || !editingLabelName.trim()) return;
|
||||
LabelService.updateLabel(editingLabelId, { label_name: editingLabelName.trim() }).then(() => {
|
||||
LabelService.getAll('active').then(data => {
|
||||
setCurrentLabels(data?.data);
|
||||
setOriginalLabelsList(data?.data);
|
||||
});
|
||||
});
|
||||
setEditingLabelId(null);
|
||||
setEditingLabelName('');
|
||||
}
|
||||
|
||||
const cancelEditingLabel = () => {
|
||||
setEditingLabelId(null);
|
||||
setEditingLabelName('');
|
||||
}
|
||||
|
||||
const handleFullScreen = () => {
|
||||
setIsFullScreen(true);
|
||||
}
|
||||
@@ -997,7 +1023,29 @@ const Seating = () => {
|
||||
<h6>Customer Labels</h6>
|
||||
<div className="mb-4">
|
||||
{
|
||||
currentLabels.map((item) => <div className="label-delete-item"><span style={{width: '16px', height: '16px', borderRadius: '16px', background: item.label_color }}></span>{item.label_name} <FileX size={16} onClick={(item) => onDeleteLabel(item)}></FileX></div>)
|
||||
currentLabels.map((item) => <div className="label-delete-item" key={item.id}>
|
||||
<span style={{width: '16px', height: '16px', borderRadius: '16px', background: item.label_color, flexShrink: 0 }}></span>
|
||||
{editingLabelId === item.id ? (
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: '4px', flex: 1, marginLeft: '8px' }}>
|
||||
<input
|
||||
type="text"
|
||||
value={editingLabelName}
|
||||
onChange={(e) => setEditingLabelName(e.target.value)}
|
||||
onKeyDown={(e) => { if (e.key === 'Enter') saveEditingLabel(); if (e.key === 'Escape') cancelEditingLabel(); }}
|
||||
style={{ flex: 1, fontSize: '13px', padding: '2px 6px', border: '1px solid #aaa', borderRadius: '4px' }}
|
||||
autoFocus
|
||||
/>
|
||||
<button className="btn btn-primary btn-sm" style={{ padding: '1px 8px', fontSize: '12px' }} onClick={saveEditingLabel}>OK</button>
|
||||
<button className="btn btn-default btn-sm" style={{ padding: '1px 8px', fontSize: '12px' }} onClick={cancelEditingLabel}>X</button>
|
||||
</div>
|
||||
) : (
|
||||
<>
|
||||
<span style={{ flex: 1, marginLeft: '8px' }}>{item.label_name}</span>
|
||||
<PencilSquare size={14} color="#777" style={{ cursor: 'pointer', marginRight: '8px' }} onClick={() => startEditingLabel(item)} />
|
||||
<FileX size={16} style={{ cursor: 'pointer' }} onClick={() => onDeleteLabel(item)} />
|
||||
</>
|
||||
)}
|
||||
</div>)
|
||||
}
|
||||
</div>
|
||||
{!startAddLabel && <button className="btn btn-tertiary btn-custom-label btn-sm mb-4" onClick={() => setStartAddLabel(true)}>+ Add New Label</button>}
|
||||
|
||||
@@ -1,22 +1,19 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { TransRoutesService } from "../../services";
|
||||
import { useDispatch } from "react-redux";
|
||||
import { transRoutesSlice, selectBreakfastsLoaded } from "./../../store";
|
||||
import moment from 'moment';
|
||||
|
||||
|
||||
const BreakfastSection = ({transRoutes, breakfastRecords, sectionName, confimHasBreakfast, removeBreakfastRecord}) => {
|
||||
const BreakfastSection = ({transRoutes, breakfastRecords, sectionName, confimHasBreakfast, removeBreakfastRecord, selectedDate, refreshRecords}) => {
|
||||
const [customers, setCustomers] = useState([]);
|
||||
const dispatch = useDispatch();
|
||||
const { fetchAllBreakfastRecords } = transRoutesSlice.actions;
|
||||
|
||||
const createBreakfastForAll = async () => {
|
||||
const dateStr = moment(selectedDate || new Date()).format('MM/DD/YYYY');
|
||||
for (const c of customers) {
|
||||
await TransRoutesService.createBreakfastRecords({
|
||||
customer_id: c?.customer_id,
|
||||
customer_name: c?.customer_name,
|
||||
has_breakfast: true,
|
||||
date: moment(new Date()).format('MM/DD/YYYY'),
|
||||
date: dateStr,
|
||||
create_by: localStorage.getItem('user') && JSON.parse(localStorage.getItem('user'))?.name,
|
||||
create_date: new Date(),
|
||||
edit_history: [{
|
||||
@@ -25,7 +22,7 @@ const BreakfastSection = ({transRoutes, breakfastRecords, sectionName, confimHas
|
||||
}]
|
||||
})
|
||||
};
|
||||
dispatch(fetchAllBreakfastRecords());
|
||||
if (refreshRecords) refreshRecords();
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
@@ -1,22 +1,19 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { TransRoutesService } from "../../services";
|
||||
import { useDispatch } from "react-redux";
|
||||
import { transRoutesSlice } from "./../../store";
|
||||
import moment from 'moment';
|
||||
|
||||
|
||||
const LunchSection = ({transRoutes, lunchRecords, sectionName, confirmHasLunch, removeLunchRecord}) => {
|
||||
const LunchSection = ({transRoutes, lunchRecords, sectionName, confirmHasLunch, removeLunchRecord, selectedDate, refreshRecords}) => {
|
||||
const [customers, setCustomers] = useState([]);
|
||||
const dispatch = useDispatch();
|
||||
const { fetchAllLunchRecords } = transRoutesSlice.actions;
|
||||
|
||||
const createLunchForAll = async () => {
|
||||
const dateStr = moment(selectedDate || new Date()).format('MM/DD/YYYY');
|
||||
for (const c of customers) {
|
||||
await TransRoutesService.createLunchRecords({
|
||||
customer_id: c?.customer_id,
|
||||
customer_name: c?.customer_name,
|
||||
has_lunch: true,
|
||||
date: moment(new Date()).format('MM/DD/YYYY'),
|
||||
date: dateStr,
|
||||
create_by: localStorage.getItem('user') && JSON.parse(localStorage.getItem('user'))?.name,
|
||||
create_date: new Date(),
|
||||
edit_history: [{
|
||||
@@ -25,7 +22,7 @@ const LunchSection = ({transRoutes, lunchRecords, sectionName, confirmHasLunch,
|
||||
}]
|
||||
})
|
||||
};
|
||||
dispatch(fetchAllLunchRecords());
|
||||
if (refreshRecords) refreshRecords();
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
import React, { useEffect } from "react";
|
||||
import { useSelector, useDispatch } from "react-redux";
|
||||
import { selectAllRoutes, selectAllBreakfastRecords, selectAllLunchRecords, selectAllSnackRecords, transRoutesSlice } from "./../../store";
|
||||
import React, { useEffect, useState, useCallback } from "react";
|
||||
import { TransRoutesService } from "../../services";
|
||||
import BreakfastSection from './BreakfastSection';
|
||||
import LunchSection from "./LunchSection";
|
||||
@@ -9,26 +7,62 @@ import { Breadcrumb } from "react-bootstrap";
|
||||
import moment from 'moment';
|
||||
|
||||
const MealStatus = () => {
|
||||
const dispatch = useDispatch();
|
||||
const { fetchAllRoutes, fetchAllBreakfastRecords, fetchAllLunchRecords, fetchAllSnackRecords } = transRoutesSlice.actions;
|
||||
const allRoutes = useSelector(selectAllRoutes);
|
||||
const breakfastRecords = useSelector(selectAllBreakfastRecords);
|
||||
const lunchRecords = useSelector(selectAllLunchRecords);
|
||||
const snackRecords = useSelector(selectAllSnackRecords);
|
||||
const [selectedDate, setSelectedDate] = useState(new Date());
|
||||
const [allRoutes, setAllRoutes] = useState([]);
|
||||
const [breakfastRecords, setBreakfastRecords] = useState([]);
|
||||
const [lunchRecords, setLunchRecords] = useState([]);
|
||||
const [snackRecords, setSnackRecords] = useState([]);
|
||||
|
||||
const dateText = moment(selectedDate).format('MM/DD/YYYY');
|
||||
|
||||
const fetchAllData = useCallback(() => {
|
||||
const formattedDate = moment(selectedDate).format('MM/DD/YYYY');
|
||||
TransRoutesService.getAll(formattedDate).then(res => {
|
||||
setAllRoutes(res?.data || []);
|
||||
}).catch(() => setAllRoutes([]));
|
||||
TransRoutesService.getAllBreakfastRecords(formattedDate).then(res => {
|
||||
setBreakfastRecords(res?.data || []);
|
||||
}).catch(() => setBreakfastRecords([]));
|
||||
TransRoutesService.getAllLunchRecords(formattedDate).then(res => {
|
||||
setLunchRecords(res?.data || []);
|
||||
}).catch(() => setLunchRecords([]));
|
||||
TransRoutesService.getAllSnackRecords(formattedDate).then(res => {
|
||||
setSnackRecords(res?.data || []);
|
||||
}).catch(() => setSnackRecords([]));
|
||||
}, [selectedDate]);
|
||||
|
||||
useEffect(() => {
|
||||
dispatch(fetchAllRoutes());
|
||||
dispatch(fetchAllBreakfastRecords());
|
||||
dispatch(fetchAllLunchRecords());
|
||||
dispatch(fetchAllSnackRecords());
|
||||
}, []);
|
||||
fetchAllData();
|
||||
}, [fetchAllData]);
|
||||
|
||||
const goToPreviousDay = () => {
|
||||
setSelectedDate(prev => {
|
||||
const d = new Date(prev);
|
||||
d.setDate(d.getDate() - 1);
|
||||
return d;
|
||||
});
|
||||
};
|
||||
|
||||
const goToNextDay = () => {
|
||||
setSelectedDate(prev => {
|
||||
const d = new Date(prev);
|
||||
d.setDate(d.getDate() + 1);
|
||||
return d;
|
||||
});
|
||||
};
|
||||
|
||||
const goToToday = () => {
|
||||
setSelectedDate(new Date());
|
||||
};
|
||||
|
||||
const isToday = moment(selectedDate).isSame(moment(), 'day');
|
||||
|
||||
const confimHasBreakfast = (customer) => {
|
||||
TransRoutesService.createBreakfastRecords({
|
||||
customer_id: customer?.customer_id,
|
||||
customer_name: customer?.customer_name,
|
||||
has_breakfast: true,
|
||||
date: moment(new Date()).format('MM/DD/YYYY'),
|
||||
date: dateText,
|
||||
create_by: localStorage.getItem('user') && JSON.parse(localStorage.getItem('user'))?.name,
|
||||
create_date: new Date(),
|
||||
edit_history: [{
|
||||
@@ -36,7 +70,7 @@ const MealStatus = () => {
|
||||
date: new Date()
|
||||
}]
|
||||
}).then(() => {
|
||||
dispatch(fetchAllBreakfastRecords());
|
||||
fetchAllData();
|
||||
})
|
||||
}
|
||||
|
||||
@@ -45,7 +79,7 @@ const MealStatus = () => {
|
||||
customer_id: customer?.customer_id,
|
||||
customer_name: customer?.customer_name,
|
||||
has_lunch: true,
|
||||
date: moment(new Date()).format('MM/DD/YYYY'),
|
||||
date: dateText,
|
||||
create_by: localStorage.getItem('user') && JSON.parse(localStorage.getItem('user'))?.name,
|
||||
create_date: new Date(),
|
||||
edit_history: [{
|
||||
@@ -53,7 +87,7 @@ const MealStatus = () => {
|
||||
date: new Date()
|
||||
}]
|
||||
}).then(() => {
|
||||
dispatch(fetchAllLunchRecords());
|
||||
fetchAllData();
|
||||
})
|
||||
}
|
||||
|
||||
@@ -62,7 +96,7 @@ const MealStatus = () => {
|
||||
customer_id: customer?.customer_id,
|
||||
customer_name: customer?.customer_name,
|
||||
has_snack: true,
|
||||
date: moment(new Date()).format('MM/DD/YYYY'),
|
||||
date: dateText,
|
||||
create_by: localStorage.getItem('user') && JSON.parse(localStorage.getItem('user'))?.name,
|
||||
create_date: new Date(),
|
||||
edit_history: [{
|
||||
@@ -70,28 +104,28 @@ const MealStatus = () => {
|
||||
date: new Date()
|
||||
}]
|
||||
}).then(() => {
|
||||
dispatch(fetchAllSnackRecords());
|
||||
fetchAllData();
|
||||
})
|
||||
}
|
||||
|
||||
const removeBreakfastRecord = (customer_id) => {
|
||||
const breakfast = breakfastRecords.find(b => b.customer_id === customer_id)?.id;
|
||||
TransRoutesService.deleteBreakfastRecords(breakfast).then(() => {
|
||||
dispatch(fetchAllBreakfastRecords());
|
||||
fetchAllData();
|
||||
})
|
||||
}
|
||||
|
||||
const removeLunchRecord = (customer_id) => {
|
||||
const lunch = lunchRecords.find(b => b.customer_id === customer_id)?.id;
|
||||
TransRoutesService.deleteLunchRecords(lunch).then(() => {
|
||||
dispatch(fetchAllLunchRecords());
|
||||
fetchAllData();
|
||||
})
|
||||
}
|
||||
|
||||
const removeSnackRecord = (customer_id) => {
|
||||
const snack = snackRecords.find(b => b.customer_id === customer_id)?.id;
|
||||
TransRoutesService.deleteSnackRecords(snack).then(() => {
|
||||
dispatch(fetchAllSnackRecords());
|
||||
fetchAllData();
|
||||
})
|
||||
}
|
||||
|
||||
@@ -107,9 +141,27 @@ const MealStatus = () => {
|
||||
<div className="col-md-12 text-primary">
|
||||
<h4>Meal Status</h4>
|
||||
</div>
|
||||
<div className="col-md-12 d-flex align-items-center" style={{ marginTop: '8px' }}>
|
||||
<div className="d-flex align-items-center" style={{ gap: '12px' }}>
|
||||
<button className="btn btn-outline-secondary btn-sm" onClick={goToPreviousDay} title="Previous day">
|
||||
<span style={{ fontSize: '18px', lineHeight: 1 }}>‹</span>
|
||||
</button>
|
||||
<span style={{ fontWeight: 600, fontSize: '16px', minWidth: '160px', textAlign: 'center' }}>
|
||||
{moment(selectedDate).format('ddd, MMM D, YYYY')}
|
||||
</span>
|
||||
<button className="btn btn-outline-secondary btn-sm" onClick={goToNextDay} title="Next day">
|
||||
<span style={{ fontSize: '18px', lineHeight: 1 }}>›</span>
|
||||
</button>
|
||||
{!isToday && (
|
||||
<button className="btn btn-outline-primary btn-sm" onClick={goToToday}>
|
||||
Today
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="app-main-content-list-container">
|
||||
<div className="app-main-content-list-container" style={{ marginTop: '16px' }}>
|
||||
<div className="list row">
|
||||
<div className="col-md-4 col-sm-12 mb-4">
|
||||
<BreakfastSection
|
||||
@@ -118,6 +170,8 @@ const MealStatus = () => {
|
||||
confimHasBreakfast={confimHasBreakfast}
|
||||
removeBreakfastRecord={removeBreakfastRecord}
|
||||
sectionName={'Breakfast Info'}
|
||||
selectedDate={selectedDate}
|
||||
refreshRecords={fetchAllData}
|
||||
/>
|
||||
</div>
|
||||
<div className="col-md-4 col-sm-12 mb-4">
|
||||
@@ -127,6 +181,8 @@ const MealStatus = () => {
|
||||
confirmHasLunch={confirmHasLunch}
|
||||
removeLunchRecord={removeLunchRecord}
|
||||
sectionName={'Lunch Info'}
|
||||
selectedDate={selectedDate}
|
||||
refreshRecords={fetchAllData}
|
||||
/>
|
||||
</div>
|
||||
<div className="col-md-4 col-sm-12 mb-4">
|
||||
@@ -136,6 +192,8 @@ const MealStatus = () => {
|
||||
confirmHasSnack={confirmHasSnack}
|
||||
removeSnackRecord={removeSnackRecord}
|
||||
sectionName={'Snack Info'}
|
||||
selectedDate={selectedDate}
|
||||
refreshRecords={fetchAllData}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -405,14 +405,16 @@ const RouteCustomerEditor = ({currentRoute, setNewCustomerList = (a) => {}, view
|
||||
|
||||
// Only initialize customers from currentRoute when the route ID changes
|
||||
// Don't reset when currentRoute object reference changes (which happens on every render)
|
||||
// Note: template sub-document routes use _id instead of id
|
||||
const currentRouteId = currentRoute?.id || currentRoute?._id;
|
||||
useEffect(() => {
|
||||
if (currentRoute?.id && currentRoute.id !== initializedRouteId) {
|
||||
if (currentRouteId && currentRouteId !== initializedRouteId) {
|
||||
setCustomers(getRouteCustomersWithGroups());
|
||||
setInitializedRouteId(currentRoute.id);
|
||||
setInitializedRouteId(currentRouteId);
|
||||
}
|
||||
}, [currentRoute?.id, initializedRouteId])
|
||||
}, [currentRouteId, initializedRouteId])
|
||||
const getRouteCustomersWithGroups = () => {
|
||||
const customerList = currentRoute?.route_customer_list?.map(item => Object.assign({}, item, {routeType: currentRoute.type, routeId: currentRoute.id}));
|
||||
const customerList = currentRoute?.route_customer_list?.map(item => Object.assign({}, item, {routeType: currentRoute.type, routeId: currentRoute.id || currentRoute._id}));
|
||||
const result = {};
|
||||
if (customerList) {
|
||||
for (const customer of customerList) {
|
||||
|
||||
@@ -1,22 +1,19 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { TransRoutesService } from "../../services";
|
||||
import { useDispatch } from "react-redux";
|
||||
import { transRoutesSlice } from "./../../store";
|
||||
import moment from 'moment';
|
||||
|
||||
|
||||
const SnackSection = ({transRoutes, snackRecords, sectionName, confirmHasSnack, removeSnackRecord}) => {
|
||||
const SnackSection = ({transRoutes, snackRecords, sectionName, confirmHasSnack, removeSnackRecord, selectedDate, refreshRecords}) => {
|
||||
const [customers, setCustomers] = useState([]);
|
||||
const dispatch = useDispatch();
|
||||
const { fetchAllSnackRecords } = transRoutesSlice.actions;
|
||||
|
||||
const createSnackForAll = async () => {
|
||||
const dateStr = moment(selectedDate || new Date()).format('MM/DD/YYYY');
|
||||
for (const c of customers) {
|
||||
await TransRoutesService.createSnackRecords({
|
||||
customer_id: c?.customer_id,
|
||||
customer_name: c?.customer_name,
|
||||
has_snack: true,
|
||||
date: moment(new Date()).format('MM/DD/YYYY'),
|
||||
date: dateStr,
|
||||
create_by: localStorage.getItem('user') && JSON.parse(localStorage.getItem('user'))?.name,
|
||||
create_date: new Date(),
|
||||
edit_history: [{
|
||||
@@ -25,7 +22,7 @@ const SnackSection = ({transRoutes, snackRecords, sectionName, confirmHasSnack,
|
||||
}]
|
||||
})
|
||||
};
|
||||
dispatch(fetchAllSnackRecords());
|
||||
if (refreshRecords) refreshRecords();
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
Reference in New Issue
Block a user