use material icon for transport;
transport icon on all available pubs for transport
This commit is contained in:
@ -2,7 +2,7 @@ import React, { useState, useEffect } from 'react';
|
|||||||
import axiosInstance from '../../src/axiosSecure';
|
import axiosInstance from '../../src/axiosSecure';
|
||||||
import PublisherSearchBox from '../publisher/PublisherSearchBox'; // Update the path
|
import PublisherSearchBox from '../publisher/PublisherSearchBox'; // Update the path
|
||||||
|
|
||||||
import { DirectionsBus } from '@mui/material'; // Import MUI CircularProgress for loading indicator
|
import LocalShippingIcon from '@mui/icons-material/LocalShipping';
|
||||||
|
|
||||||
const common = require('src/helpers/common');
|
const common = require('src/helpers/common');
|
||||||
|
|
||||||
@ -138,9 +138,6 @@ function ShiftComponent({ shift, onShiftSelect, isSelected, onPublisherSelect, a
|
|||||||
} catch (error) { }
|
} catch (error) { }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={`flow w-full p-4 py-2 border-2 border-gray-300 rounded-md my-1 ${isSelected ? 'bg-gray-200' : ''}`}
|
<div className={`flow w-full p-4 py-2 border-2 border-gray-300 rounded-md my-1 ${isSelected ? 'bg-gray-200' : ''}`}
|
||||||
onClick={handleShiftClick} onDoubleClick={copyAllPublisherNames}>
|
onClick={handleShiftClick} onDoubleClick={copyAllPublisherNames}>
|
||||||
@ -148,6 +145,7 @@ function ShiftComponent({ shift, onShiftSelect, isSelected, onPublisherSelect, a
|
|||||||
<div className="flex justify-between items-center mb-2 border-b pb-1">
|
<div className="flex justify-between items-center mb-2 border-b pb-1">
|
||||||
<span className="text-lg font-semibold">
|
<span className="text-lg font-semibold">
|
||||||
{`${common.getTimeRange(new Date(shift.startTime), new Date(shift.endTime))}`}
|
{`${common.getTimeRange(new Date(shift.startTime), new Date(shift.endTime))}`}
|
||||||
|
{/* {shift.requiresTransport && (<LocalShippingIcon />)} */}
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
{/* Copy All Names Button */}
|
{/* Copy All Names Button */}
|
||||||
@ -162,7 +160,6 @@ function ShiftComponent({ shift, onShiftSelect, isSelected, onPublisherSelect, a
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
{/* Assignments */}
|
{/* Assignments */}
|
||||||
{assignments.map((ass, index) => {
|
{assignments.map((ass, index) => {
|
||||||
const publisherInfo = allPublishersInfo.find(info => info?.id === ass.publisher.id) || ass.publisher;
|
const publisherInfo = allPublishersInfo.find(info => info?.id === ass.publisher.id) || ass.publisher;
|
||||||
@ -222,9 +219,9 @@ function ShiftComponent({ shift, onShiftSelect, isSelected, onPublisherSelect, a
|
|||||||
{shift.requiresTransport && (
|
{shift.requiresTransport && (
|
||||||
<span
|
<span
|
||||||
onClick={ass.canTransport ? () => toggleTransport(ass) : undefined}
|
onClick={ass.canTransport ? () => toggleTransport(ass) : undefined}
|
||||||
className={`material-icons ${ass.isWithTransport || ass.canTransport ? 'text-green-500 font-bold' : (transportProvided ? 'text-gray-400 ' : 'text-orange-400 font-bold')} ${ass.canTransport ? ' cursor-pointer' : 'cursor-not-allowed'} px-3 py-1 ml-2 rounded-md`}
|
className={`material-icons ${ass.isWithTransport ? 'text-green-500 font-bold' : (transportProvided ? 'text-gray-400 ' : 'text-orange-400 font-bold')} ${ass.canTransport ? ' cursor-pointer' : 'cursor-not-allowed'} px-3 py-1 ml-2 rounded-md`}
|
||||||
>
|
>
|
||||||
{ass.isWithTransport ? "транспорт" : ass.canTransport ? "може транспорт" : "без транспорт"}
|
{ass.isWithTransport ? "транспорт" : ass.canTransport ? "може транспорт" : "без транспорт"} <LocalShippingIcon />
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
<button onClick={() => removeAssignment(ass.id)} className="text-white bg-red-500 hover:bg-red-600 px-3 py-1 ml-2 rounded-md" >
|
<button onClick={() => removeAssignment(ass.id)} className="text-white bg-red-500 hover:bg-red-600 px-3 py-1 ml-2 rounded-md" >
|
||||||
|
@ -14,8 +14,12 @@ const common = require('src/helpers/common');
|
|||||||
import { toast } from 'react-toastify';
|
import { toast } from 'react-toastify';
|
||||||
import ProtectedRoute from '../../../components/protectedRoute';
|
import ProtectedRoute from '../../../components/protectedRoute';
|
||||||
import ConfirmationModal from '../../../components/ConfirmationModal';
|
import ConfirmationModal from '../../../components/ConfirmationModal';
|
||||||
|
import axiosServer from '../../../src/axiosServer';
|
||||||
|
|
||||||
|
|
||||||
// import { FaPlus, FaCogs, FaTrashAlt, FaSpinner } from 'react-icons/fa'; // Import FontAwesome icons
|
// import { FaPlus, FaCogs, FaTrashAlt, FaSpinner } from 'react-icons/fa'; // Import FontAwesome icons
|
||||||
|
import LocalShippingIcon from '@mui/icons-material/LocalShipping';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -108,6 +112,12 @@ export default function CalendarPage({ initialEvents, initialShifts }) {
|
|||||||
const { data: shiftsForDate } = await axiosInstance.get(`/api/?action=getShiftsForDay&date=${dateStr}`);
|
const { data: shiftsForDate } = await axiosInstance.get(`/api/?action=getShiftsForDay&date=${dateStr}`);
|
||||||
setShifts(shiftsForDate);
|
setShifts(shiftsForDate);
|
||||||
let { data: availablePubsForDate } = await axiosInstance.get(`/api/?action=filterPublishers&assignments=true&availabilities=true&date=${dateStr}&select=id,firstName,lastName,isactive,desiredShiftsPerMonth`);
|
let { data: availablePubsForDate } = await axiosInstance.get(`/api/?action=filterPublishers&assignments=true&availabilities=true&date=${dateStr}&select=id,firstName,lastName,isactive,desiredShiftsPerMonth`);
|
||||||
|
availablePubsForDate.forEach(pub => {
|
||||||
|
pub.canTransport = pub.availabilities.some(av =>
|
||||||
|
av.isWithTransportIn || av.isWithTransportOut
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
//remove availabilities that are isFromPreviousAssignment or from previous month for each publisher
|
//remove availabilities that are isFromPreviousAssignment or from previous month for each publisher
|
||||||
// availablePubsForDate = availablePubsForDate.map(pub => {
|
// availablePubsForDate = availablePubsForDate.map(pub => {
|
||||||
// pub.availabilities = pub.availabilities.filter(avail => avail.isFromPreviousAssignment == false);
|
// pub.availabilities = pub.availabilities.filter(avail => avail.isFromPreviousAssignment == false);
|
||||||
@ -134,22 +144,30 @@ export default function CalendarPage({ initialEvents, initialShifts }) {
|
|||||||
const handleShiftSelection = (selectedShift) => {
|
const handleShiftSelection = (selectedShift) => {
|
||||||
setSelectedShiftId(selectedShift.id);
|
setSelectedShiftId(selectedShift.id);
|
||||||
const updatedPubs = availablePubs.map(pub => {
|
const updatedPubs = availablePubs.map(pub => {
|
||||||
const isAvailableForShift = pub.availabilities.some(avail =>
|
const av = pub.availabilities?.find(avail =>
|
||||||
avail.startTime <= selectedShift.startTime
|
avail.startTime <= selectedShift.startTime
|
||||||
&& avail.endTime >= selectedShift.endTime
|
&& avail.endTime >= selectedShift.endTime
|
||||||
&& avail.isFromPreviousAssignment == false
|
|
||||||
);
|
);
|
||||||
|
if (av) {
|
||||||
|
pub.isAvailableForShift = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// const isAvailableForShift = pub.availabilities.some(avail =>
|
||||||
|
// avail.startTime <= selectedShift.startTime
|
||||||
|
// && avail.endTime >= selectedShift.endTime
|
||||||
|
// && avail.isFromPreviousAssignment == false
|
||||||
|
// );
|
||||||
const isAvailableForShiftWithPrevious = pub.availabilities.some(avail =>
|
const isAvailableForShiftWithPrevious = pub.availabilities.some(avail =>
|
||||||
avail.startTime <= selectedShift.startTime
|
avail.startTime <= selectedShift.startTime
|
||||||
&& avail.endTime >= selectedShift.endTime
|
&& avail.endTime >= selectedShift.endTime
|
||||||
);
|
);
|
||||||
//! console.log(`Publisher ${pub.firstName} ${pub.lastName} is available for shift ${selectedShift.id}: ${isAvailableForShift}`);
|
// //! console.log(`Publisher ${pub.firstName} ${pub.lastName} is available for shift ${selectedShift.id}: ${isAvailableForShift}`);
|
||||||
//// console.log(`Publisher ${pub.firstName} ${pub.lastName} has ${pub.availabilities.length} availabilities :` + pub.availabilities.map(avail => avail.startTime + " - " + avail.endTime));
|
// //// console.log(`Publisher ${pub.firstName} ${pub.lastName} has ${pub.availabilities.length} availabilities :` + pub.availabilities.map(avail => avail.startTime + " - " + avail.endTime));
|
||||||
//// console.log(`Publisher ${pub.firstName} ${pub.lastName} has ${pub.availabilities.length} availabilities :` + stringify.join(', 'pub.availabilities.map(avail => avail.id)));
|
// //// console.log(`Publisher ${pub.firstName} ${pub.lastName} has ${pub.availabilities.length} availabilities :` + stringify.join(', 'pub.availabilities.map(avail => avail.id)));
|
||||||
|
|
||||||
const availabilitiesIds = pub.availabilities.map(avail => avail.id).join(', ');
|
// const availabilitiesIds = pub.availabilities.map(avail => avail.id).join(', ');
|
||||||
//! console.log(`Publisher ${pub.firstName} ${pub.lastName} has ${pub.availabilities.length} availabilities with IDs: ${availabilitiesIds}`);
|
// //! console.log(`Publisher ${pub.firstName} ${pub.lastName} has ${pub.availabilities.length} availabilities with IDs: ${availabilitiesIds}`);
|
||||||
return { ...pub, isAvailableForShift, isAvailableForShiftWithPrevious, isSelected: pub.id === selectedShift.selectedPublisher?.id };
|
return { ...pub, isAvailableForShiftWithPrevious, isSelected: pub.id === selectedShift.selectedPublisher?.id };
|
||||||
});
|
});
|
||||||
|
|
||||||
// Sort publishers based on their availability state. use currentDayAssignments, currentWeekAssignments,
|
// Sort publishers based on their availability state. use currentDayAssignments, currentWeekAssignments,
|
||||||
@ -317,7 +335,7 @@ export default function CalendarPage({ initialEvents, initialShifts }) {
|
|||||||
var classname = "";
|
var classname = "";
|
||||||
|
|
||||||
if (events == null) {
|
if (events == null) {
|
||||||
return <div>{" "}</div>;
|
return <div>{" - "}</div>;
|
||||||
}
|
}
|
||||||
|
|
||||||
const event = events.find((event) => {
|
const event = events.find((event) => {
|
||||||
@ -664,6 +682,7 @@ export default function CalendarPage({ initialEvents, initialShifts }) {
|
|||||||
>
|
>
|
||||||
<span className={`text-gray-700 ${pub.isAvailableForShift ? 'font-bold' : 'font-medium'} `}>
|
<span className={`text-gray-700 ${pub.isAvailableForShift ? 'font-bold' : 'font-medium'} `}>
|
||||||
{pub.firstName} {pub.lastName}
|
{pub.firstName} {pub.lastName}
|
||||||
|
{pub.canTransport && (<LocalShippingIcon className="mx-1 text-gray-500" />)}
|
||||||
</span>
|
</span>
|
||||||
<div className="flex space-x-1 overflow-hidden">
|
<div className="flex space-x-1 overflow-hidden">
|
||||||
<span title="Възможност: часове | дни" className={`badge py-1 px-2 rounded-md text-xs ${pub.currentMonthAvailabilityHoursCount || pub.currentMonthAvailabilityDaysCount ? 'bg-teal-500 text-white' : 'bg-teal-200 text-gray-300'} hover:underline`} >
|
<span title="Възможност: часове | дни" className={`badge py-1 px-2 rounded-md text-xs ${pub.currentMonthAvailabilityHoursCount || pub.currentMonthAvailabilityDaysCount ? 'bg-teal-500 text-white' : 'bg-teal-200 text-gray-300'} hover:underline`} >
|
||||||
@ -694,10 +713,6 @@ export default function CalendarPage({ initialEvents, initialShifts }) {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
|
||||||
{/* <CustomCalendar date={value} shifts={shifts} /> */}
|
|
||||||
</div>
|
|
||||||
{isModalOpen && <PublisherShiftsModal publisher={modalPub} shifts={allShifts} onClose={() => setIsModalOpen(false)} />}
|
{isModalOpen && <PublisherShiftsModal publisher={modalPub} shifts={allShifts} onClose={() => setIsModalOpen(false)} />}
|
||||||
</ProtectedRoute >
|
</ProtectedRoute >
|
||||||
</Layout >
|
</Layout >
|
||||||
@ -844,69 +859,3 @@ export default function CalendarPage({ initialEvents, initialShifts }) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
import axiosServer from '../../../src/axiosServer';
|
|
||||||
import { start } from 'repl';
|
|
||||||
export const getServerSideProps = async (context) => {
|
|
||||||
const axios = await axiosServer(context);
|
|
||||||
const baseUrl = common.getBaseUrl();
|
|
||||||
console.log('runtime BaseUrl: ' + baseUrl);
|
|
||||||
console.log('runtime NEXTAUTH_URL: ' + process.env.NEXTAUTH_URL);
|
|
||||||
console.log('Runtime Axios Base URL:', axios.defaults.baseURL);
|
|
||||||
|
|
||||||
const currentDate = new Date();
|
|
||||||
const firstDayOfMonth = new Date(currentDate.getFullYear(), currentDate.getMonth() - 3, 1);
|
|
||||||
const lastDayOfMonth = new Date(currentDate.getFullYear(), currentDate.getMonth() + 1, 0); // 0th day of the next month gives the last day of the current month
|
|
||||||
|
|
||||||
const url = `/api/data/shifts?where={"startTime":{"$and":[{"$gte":"${common.getISODateOnly(firstDayOfMonth)}","$lt":"${common.getISODateOnly(lastDayOfMonth)}"}]}}`;
|
|
||||||
|
|
||||||
const prismaClient = common.getPrismaClient();
|
|
||||||
// let events = await prismaClient.cartEvent.findMany({ where: { isactive: true } });
|
|
||||||
// events = events.map(event => ({
|
|
||||||
// ...event,
|
|
||||||
// // Convert Date objects to ISO strings
|
|
||||||
// startTime: event.startTime.toISOString(),
|
|
||||||
// endTime: event.endTime.toISOString(),
|
|
||||||
// }));
|
|
||||||
const { data: events } = await axios.get(`/api/data/cartevents?where={"isactive":true}`);
|
|
||||||
//const { data: shifts } = await axios.get(url);
|
|
||||||
|
|
||||||
// get all shifts for the month, including assigments
|
|
||||||
let shifts = await prismaClient.shift.findMany({
|
|
||||||
where: {
|
|
||||||
isactive: true,
|
|
||||||
startTime: {
|
|
||||||
gte: firstDayOfMonth,
|
|
||||||
//lt: lastDayOfMonth
|
|
||||||
}
|
|
||||||
},
|
|
||||||
include: {
|
|
||||||
assignments: {
|
|
||||||
include: {
|
|
||||||
publisher: {
|
|
||||||
select: {
|
|
||||||
id: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
//calculate assCount for each shift
|
|
||||||
shifts = shifts.map(shift => ({
|
|
||||||
...shift,
|
|
||||||
assignedCount: shift.assignments.length,
|
|
||||||
startTime: shift.startTime.toISOString(),
|
|
||||||
endTime: shift.endTime.toISOString(),
|
|
||||||
}));
|
|
||||||
|
|
||||||
|
|
||||||
return {
|
|
||||||
props: {
|
|
||||||
initialEvents: events,
|
|
||||||
initialShifts: shifts,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
Reference in New Issue
Block a user