Merge commit '53729a5926cef1f5d155bc3aff90ccaee1b96c86'
This commit is contained in:
6
.gitignore
vendored
6
.gitignore
vendored
@ -35,7 +35,5 @@ content/output/*
|
|||||||
public/content/output/*
|
public/content/output/*
|
||||||
public/content/output/shifts 2024.1.json
|
public/content/output/shifts 2024.1.json
|
||||||
!public/content/uploads/*
|
!public/content/uploads/*
|
||||||
shift_generate_log_*.txt
|
.aider*
|
||||||
.aider.input.history
|
/shift_generate_log_*.txt
|
||||||
.aider.chat.history.md
|
|
||||||
.aider.tags.cache.v3/*
|
|
||||||
|
@ -39,6 +39,8 @@ if [ "$UPDATE_CODE_FROM_GIT" = "true" ]; then
|
|||||||
rsync -av --itemize-changes \
|
rsync -av --itemize-changes \
|
||||||
--exclude='package.json' \
|
--exclude='package.json' \
|
||||||
--exclude='package-lock.json' \
|
--exclude='package-lock.json' \
|
||||||
|
--exclude='/public/content/permits' \
|
||||||
|
--exclude='/public/content/uploads' \
|
||||||
/tmp/clone/ /app/ >> /app/logs/deploy.txt 2>&1
|
/tmp/clone/ /app/ >> /app/logs/deploy.txt 2>&1
|
||||||
|
|
||||||
# Check rsync exit status
|
# Check rsync exit status
|
||||||
|
@ -118,6 +118,11 @@ next start
|
|||||||
export OPENAI_API_KEY=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 # personal
|
export OPENAI_API_KEY=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 # personal
|
||||||
export OPENAI_API_KEY=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 # dev-bro
|
export OPENAI_API_KEY=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 # dev-bro
|
||||||
|
|
||||||
|
aider --openai-api-key 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 --no-auto-commits --
|
||||||
|
|
||||||
|
## build - prod
|
||||||
|
npx run build
|
||||||
|
npm run prod
|
||||||
# ----------------------------------------------update PRISMA schema/sync database ----------------------------------------------- #
|
# ----------------------------------------------update PRISMA schema/sync database ----------------------------------------------- #
|
||||||
# prisma migrate dev --create-only
|
# prisma migrate dev --create-only
|
||||||
NODE_ENV=production npx prisma migrate deploy
|
NODE_ENV=production npx prisma migrate deploy
|
||||||
|
@ -51,10 +51,15 @@ const messages = {
|
|||||||
const AvCalendar = ({ publisherId, events, selectedDate, cartEvents, lastPublishedDate }) => {
|
const AvCalendar = ({ publisherId, events, selectedDate, cartEvents, lastPublishedDate }) => {
|
||||||
const [editLockedBefore, setEditLockedBefore] = useState(new Date(lastPublishedDate));
|
const [editLockedBefore, setEditLockedBefore] = useState(new Date(lastPublishedDate));
|
||||||
const [isAdmin, setIsAdmin] = useState(false);
|
const [isAdmin, setIsAdmin] = useState(false);
|
||||||
|
// const [isPowerUser, setIsPowerUser] = useState(false);
|
||||||
|
// const [currentUserId, setCurrentUserId] = useState(null);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
(async () => {
|
(async () => {
|
||||||
try {
|
try {
|
||||||
setIsAdmin(await ProtectedRoute.IsInRole(UserRole.ADMIN));
|
setIsAdmin(await ProtectedRoute.IsInRole(UserRole.ADMIN));
|
||||||
|
// setIsPowerUser(await ProtectedRoute.IsInRole(UserRole.POWERUSER));
|
||||||
|
// // Assuming you have a way to get the current user's ID
|
||||||
|
// setCurrentUserId(await ProtectedRoute.GetCurrentUserId());
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Failed to check admin role:", error);
|
console.error("Failed to check admin role:", error);
|
||||||
}
|
}
|
||||||
@ -256,7 +261,9 @@ const AvCalendar = ({ publisherId, events, selectedDate, cartEvents, lastPublish
|
|||||||
const enddate = common.setTimezone(end);
|
const enddate = common.setTimezone(end);
|
||||||
|
|
||||||
if (!start || !end) return;
|
if (!start || !end) return;
|
||||||
//readonly for past dates (ToDo: if not admin)
|
//readonly for past dates (ToDo: if not admin or current user)
|
||||||
|
//const isCurrentUser = selectedEvents.some(event => event.userId === currentUserId);
|
||||||
|
|
||||||
if (!isAdmin) {
|
if (!isAdmin) {
|
||||||
if (startdate < new Date() || end < new Date() || startdate > end) return;
|
if (startdate < new Date() || end < new Date() || startdate > end) return;
|
||||||
//or if schedule is published (lastPublishedDate)
|
//or if schedule is published (lastPublishedDate)
|
||||||
|
@ -85,5 +85,10 @@ export async function serverSideAuth({ req, allowedRoles }) {
|
|||||||
// Static method to check if the user has a specific role
|
// Static method to check if the user has a specific role
|
||||||
ProtectedRoute.IsInRole = async (roleName) => {
|
ProtectedRoute.IsInRole = async (roleName) => {
|
||||||
const session = await getSession();
|
const session = await getSession();
|
||||||
return session && session.user && session.user.role === roleName;
|
return (session && session.user && session.user.role === roleName) || false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ProtectedRoute.GetCurrentUserId = async () => {
|
||||||
|
const session = await getSession();
|
||||||
|
return session && session.user && session.user.id;
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { Publisher } from "@prisma/client"
|
import { Publisher, UserRole } from "@prisma/client"
|
||||||
// import {IsDateXMonthsAgo} from "../../helpers/const"
|
// import {IsDateXMonthsAgo} from "../../helpers/const"
|
||||||
import { useEffect, useState } from 'react'
|
import { useEffect, useState } from 'react'
|
||||||
import toast from "react-hot-toast";
|
import toast from "react-hot-toast";
|
||||||
@ -97,26 +97,27 @@ export default function PublisherCard({ publisher }) {
|
|||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
<div className="absolute bottom-2 right-2">
|
<div className="absolute bottom-2 right-2">
|
||||||
<button onClick={() => { setIsModalOpen(true) }} aria-label="Изтрий Publisher">
|
<ProtectedRoute allowedRoles={[UserRole.ADMIN]} deniedMessage=" ">
|
||||||
<svg className="w-5 h-6 text-red-500 hover:text-red-700" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
|
<button onClick={() => { setIsModalOpen(true) }} aria-label="Изтрий Publisher">
|
||||||
<path d="M10 11V17" stroke="#000000" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
|
<svg className="w-5 h-6 text-red-500 hover:text-red-700" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
|
||||||
<path d="M14 11V17" stroke="#000000" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
|
<path d="M10 11V17" stroke="#000000" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
|
||||||
<path d="M4 7H20" stroke="#000000" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
|
<path d="M14 11V17" stroke="#000000" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
|
||||||
<path d="M6 7H12H18V18C18 19.6569 16.6569 21 15 21H9C7.34315 21 6 19.6569 6 18V7Z" stroke="#000000" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
|
<path d="M4 7H20" stroke="#000000" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
|
||||||
<path d="M9 5C9 3.89543 9.89543 3 11 3H13C14.1046 3 15 3.89543 15 5V7H9V5Z" stroke="#000000" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
|
<path d="M6 7H12H18V18C18 19.6569 16.6569 21 15 21H9C7.34315 21 6 19.6569 6 18V7Z" stroke="#000000" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
|
||||||
|
<path d="M9 5C9 3.89543 9.89543 3 11 3H13C14.1046 3 15 3.89543 15 5V7H9V5Z" stroke="#000000" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
|
||||||
|
|
||||||
{/* <path d="M8 9a1 1 0 000 2h4a1 1 0 100-2H8z" />
|
{/* <path d="M8 9a1 1 0 000 2h4a1 1 0 100-2H8z" />
|
||||||
<path fillRule="evenodd" d="M4.293 4.293A1 1 0 015.707 3.707L10 8l4.293-4.293a1 1 0 111.414 1.414L11.414 9l4.293 4.293a1 1 0 01-1.414 1.414L10 10.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 9 4.293 4.707a1 1 0 010-1.414z" clipRule="evenodd" /> */}
|
<path fillRule="evenodd" d="M4.293 4.293A1 1 0 015.707 3.707L10 8l4.293-4.293a1 1 0 111.414 1.414L11.414 9l4.293 4.293a1 1 0 01-1.414 1.414L10 10.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 9 4.293 4.707a1 1 0 010-1.414z" clipRule="evenodd" /> */}
|
||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
<ConfirmationModal
|
<ConfirmationModal
|
||||||
isOpen={isModalOpen}
|
isOpen={isModalOpen}
|
||||||
onClose={() => setIsModalOpen(false)}
|
onClose={() => setIsModalOpen(false)}
|
||||||
onConfirm={() => handleDelete(publisher.id)}
|
onConfirm={() => handleDelete(publisher.id)}
|
||||||
message="Сигурни ли сте, че искате да изтриете този профил? Това действие не може да бъде отменено."
|
message="Сигурни ли сте, че искате да изтриете този профил? Това действие не може да бъде отменено."
|
||||||
/>
|
/>
|
||||||
<ProtectedRoute>
|
</ProtectedRoute>
|
||||||
|
<ProtectedRoute allowedRoles={[UserRole.ADMIN, UserRole.POWERUSER]} deniedMessage=" ">
|
||||||
<button onClick={() => handleLoginAs(publisher.id)}>Login as</button>
|
<button onClick={() => handleLoginAs(publisher.id)}>Login as</button>
|
||||||
</ProtectedRoute>
|
</ProtectedRoute>
|
||||||
</div>
|
</div>
|
||||||
|
@ -317,7 +317,7 @@ export default function PublisherForm({ item, me }) {
|
|||||||
|
|
||||||
|
|
||||||
{/* ADMINISTRATORS ONLY */}
|
{/* ADMINISTRATORS ONLY */}
|
||||||
<ProtectedRoute allowedRoles={[UserRole.ADMIN]} deniedMessage=" " className="">
|
<ProtectedRoute allowedRoles={[UserRole.ADMIN, UserRole.POWERUSER]} deniedMessage=" " className="">
|
||||||
<div className="border border-blue-500 border-solid p-2">
|
<div className="border border-blue-500 border-solid p-2">
|
||||||
{/* prompt to install PWA */}
|
{/* prompt to install PWA */}
|
||||||
<div className="mb-4">
|
<div className="mb-4">
|
||||||
@ -341,12 +341,16 @@ export default function PublisherForm({ item, me }) {
|
|||||||
</div>
|
</div>
|
||||||
<div className="mb-4">
|
<div className="mb-4">
|
||||||
<div className="form-check">
|
<div className="form-check">
|
||||||
|
|
||||||
|
<ProtectedRoute allowedRoles={[UserRole.ADMIN]} deniedMessage=" ">
|
||||||
|
<input className="checkbox disabled" type="checkbox" id="isImported" name="isImported" onChange={handleChange} checked={publisher.isImported} autoComplete="off" />
|
||||||
|
<label className="label " htmlFor="isImported">Импортиран от график</label>
|
||||||
|
</ProtectedRoute>
|
||||||
<input className="checkbox" type="checkbox" id="isActive" name="isActive" onChange={handleChange} checked={publisher.isActive} autoComplete="off" />
|
<input className="checkbox" type="checkbox" id="isActive" name="isActive" onChange={handleChange} checked={publisher.isActive} autoComplete="off" />
|
||||||
<label className="label" htmlFor="isActive">Активен</label>
|
<label className="label" htmlFor="isActive">Активен</label>
|
||||||
<input className="checkbox" type="checkbox" id="isTrained" name="isTrained" onChange={handleChange} checked={publisher.isTrained} autoComplete="off" />
|
<input className="checkbox" type="checkbox" id="isTrained" name="isTrained" onChange={handleChange} checked={publisher.isTrained} autoComplete="off" />
|
||||||
<label className="label" htmlFor="isTrained">Получил обучение</label>
|
<label className="label" htmlFor="isTrained">Получил обучение</label>
|
||||||
<input className="checkbox disabled" type="checkbox" id="isImported" name="isImported" onChange={handleChange} checked={publisher.isImported} autoComplete="off" />
|
|
||||||
<label className="label " htmlFor="isImported">Импортиран от график</label>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="mb-4">
|
<div className="mb-4">
|
||||||
@ -356,7 +360,9 @@ export default function PublisherForm({ item, me }) {
|
|||||||
<option value={`${UserRole.USER}`}>Потребител</option>
|
<option value={`${UserRole.USER}`}>Потребител</option>
|
||||||
<option value={`${UserRole.EXTERNAL}`}>Външен</option>
|
<option value={`${UserRole.EXTERNAL}`}>Външен</option>
|
||||||
<option value={`${UserRole.POWERUSER}`}>Организатор</option>
|
<option value={`${UserRole.POWERUSER}`}>Организатор</option>
|
||||||
<option value={`${UserRole.ADMIN}`}>Администратор</option>
|
<ProtectedRoute allowedRoles={[UserRole.ADMIN]} deniedMessage=" ">
|
||||||
|
<option value={`${UserRole.ADMIN}`}>Администратор</option>
|
||||||
|
</ProtectedRoute>
|
||||||
{/* Add other roles as needed */}
|
{/* Add other roles as needed */}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,17 +1,22 @@
|
|||||||
import React, { useEffect } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import common from 'src/helpers/common';
|
import common from 'src/helpers/common';
|
||||||
import axiosInstance from 'src/axiosSecure';
|
import axiosInstance from 'src/axiosSecure';
|
||||||
|
|
||||||
const PublisherShiftsModal = ({ publisher, _shifts, onClose, date, onAssignmentChange }) => {
|
const PublisherShiftsModal = ({ publisher, _shifts, onClose, date, onAssignmentChange }) => {
|
||||||
|
|
||||||
const [shifts, setShifts] = React.useState([..._shifts]);
|
const [shifts, setShifts] = useState([..._shifts]);
|
||||||
|
const [assignments, setAssignments] = useState(publisher.assignments || []);
|
||||||
//Refactor ToDo: show the whole month instead of just the current week by showing the shift start time in front of the rows, and show all shifts in the month from the first to the last week in the cell where we show one shift now
|
//Refactor ToDo: show the whole month instead of just the current week by showing the shift start time in front of the rows, and show all shifts in the month from the first to the last week in the cell where we show one shift now
|
||||||
|
|
||||||
const monthInfo = common.getMonthDatesInfo(new Date(date));
|
let monthInfo = common.getMonthDatesInfo(new Date(date));
|
||||||
|
//if date is before monthInfo.firstMonday, get the previous month indexOf
|
||||||
|
if (date < monthInfo.firstMonday) {
|
||||||
|
monthInfo = common.getMonthDatesInfo(new Date(date.getFullYear(), date.getMonth() - 1, 1));
|
||||||
|
}
|
||||||
const monthShifts = shifts.filter(shift => {
|
const monthShifts = shifts.filter(shift => {
|
||||||
const shiftDate = new Date(shift.startTime);
|
const shiftDate = new Date(shift.startTime);
|
||||||
return shiftDate > monthInfo.firstDay && shiftDate < monthInfo.lastDay;
|
return shiftDate > monthInfo.firstDay && shiftDate < monthInfo.lastSunday;
|
||||||
});
|
});
|
||||||
const weekShifts = monthShifts.filter(shift => {
|
const weekShifts = monthShifts.filter(shift => {
|
||||||
const shiftDate = new Date(shift.startTime);
|
const shiftDate = new Date(shift.startTime);
|
||||||
@ -38,11 +43,13 @@ const PublisherShiftsModal = ({ publisher, _shifts, onClose, date, onAssignmentC
|
|||||||
console.log("dayShifts:", dayShifts);
|
console.log("dayShifts:", dayShifts);
|
||||||
|
|
||||||
const hasAssignment = (shiftId) => {
|
const hasAssignment = (shiftId) => {
|
||||||
// return publisher.assignments.some(ass => ass.shift.id == shiftId);
|
|
||||||
return publisher.assignments?.some(ass => {
|
return assignments.some(ass => ass.shift.id === shiftId);
|
||||||
//console.log(`Comparing: ${ass.shift.id} to ${shiftId}: ${ass.shift.id === shiftId}`);
|
// // return publisher.assignments.some(ass => ass.shift.id == shiftId);
|
||||||
return ass.shift.id === shiftId;
|
// return publisher.assignments?.some(ass => {
|
||||||
});
|
// //console.log(`Comparing: ${ass.shift.id} to ${shiftId}: ${ass.shift.id === shiftId}`);
|
||||||
|
// return ass.shift.id === shiftId;
|
||||||
|
// });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -63,6 +70,61 @@ const PublisherShiftsModal = ({ publisher, _shifts, onClose, date, onAssignmentC
|
|||||||
};
|
};
|
||||||
}, [onClose]); // Include onClose in the dependency array
|
}, [onClose]); // Include onClose in the dependency array
|
||||||
|
|
||||||
|
function getColorForShift(shift) {
|
||||||
|
const assignedCount = shift.assignedCount || 0; // Assuming each shift has an assignedCount property
|
||||||
|
switch (assignedCount) {
|
||||||
|
case 0: return 'bg-blue-300';
|
||||||
|
case 1: return 'bg-green-300';
|
||||||
|
case 2: return 'bg-yellow-300';
|
||||||
|
case 3: return 'bg-orange-300';
|
||||||
|
case 4: return 'bg-red-200';
|
||||||
|
default: return 'bg-gray-300';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//ToDo: DRY - move to common
|
||||||
|
const addAssignment = async (publisher, shiftId) => {
|
||||||
|
try {
|
||||||
|
console.log(`calendar.idx: new assignment for publisher ${publisher.id} - ${publisher.firstName} ${publisher.lastName}`);
|
||||||
|
const newAssignment = {
|
||||||
|
publisher: { connect: { id: publisher.id } },
|
||||||
|
shift: { connect: { id: shiftId } },
|
||||||
|
isConfirmed: true
|
||||||
|
};
|
||||||
|
const { data } = await axiosInstance.post("/api/data/assignments", newAssignment);
|
||||||
|
|
||||||
|
// Update the 'publisher' property of the returned data with the full publisher object
|
||||||
|
data.publisher = publisher;
|
||||||
|
data.shift = shifts.find(shift => shift.id === shiftId);
|
||||||
|
publisher.assignments = [...publisher.assignments, data];
|
||||||
|
// handleAssignmentChange(publisher.id, 'add');
|
||||||
|
|
||||||
|
setAssignments(prevAssignments => [...prevAssignments, data]);
|
||||||
|
if (onAssignmentChange) { onAssignmentChange(publisher.id, 'add'); }
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error adding assignment:", error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const removeAssignment = async (publisher, shiftId) => {
|
||||||
|
try {
|
||||||
|
const assignment = publisher.assignments.find(ass => ass.shift.id === shiftId);
|
||||||
|
console.log(`calendar.idx: remove assignment for shift ${shiftId}`);
|
||||||
|
const { data } = await axiosInstance.delete(`/api/data/assignments/${assignment.id}`);
|
||||||
|
//remove from local assignments:
|
||||||
|
publisher.assignments = publisher.assignments.filter(a => a.id !== assignment.id)
|
||||||
|
// Update local state
|
||||||
|
setAssignments(prevAssignments => prevAssignments.filter(a => a.id !== assignment.id));
|
||||||
|
|
||||||
|
//
|
||||||
|
// handleAssignmentChange(publisher.id, 'remove')
|
||||||
|
if (onAssignmentChange) {
|
||||||
|
onAssignmentChange(publisher.id, 'remove')
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error removing assignment:", error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="fixed top-0 left-0 w-full h-full flex items-center justify-center bg-black bg-opacity-50 z-50">
|
<div className="fixed top-0 left-0 w-full h-full flex items-center justify-center bg-black bg-opacity-50 z-50">
|
||||||
<div className="relative bg-white p-8 rounded-lg shadow-xl max-w-xl w-full h-auto overflow-y-auto">
|
<div className="relative bg-white p-8 rounded-lg shadow-xl max-w-xl w-full h-auto overflow-y-auto">
|
||||||
@ -91,24 +153,23 @@ const PublisherShiftsModal = ({ publisher, _shifts, onClose, date, onAssignmentC
|
|||||||
>
|
>
|
||||||
{common.getTimeRange(shift.startTime, shift.endTime)} {shift.id}
|
{common.getTimeRange(shift.startTime, shift.endTime)} {shift.id}
|
||||||
|
|
||||||
{!assignmentExists && shift.isAvailable && (
|
{shift.isAvailable && (
|
||||||
<button onClick={() => { addAssignment(publisher, shift.id); }}
|
<button
|
||||||
className="mt-2 bg-green-500 text-white p-1 rounded hover:bg-green-600 active:bg-green-700 focus:outline-none"
|
onClick={() => {
|
||||||
|
if (assignmentExists) {
|
||||||
|
removeAssignment(publisher, shift.id);
|
||||||
|
} else {
|
||||||
|
addAssignment(publisher, shift.id);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
className={`mt-2 ${assignmentExists ? 'bg-red-500 hover:bg-red-600 active:bg-red-700' : 'bg-green-500 hover:bg-green-600 active:bg-green-700'} text-white p-1 rounded focus:outline-none`}
|
||||||
>
|
>
|
||||||
добави
|
{assignmentExists ? 'махни' : 'добави'}
|
||||||
</button>
|
|
||||||
)}
|
|
||||||
{assignmentExists && (
|
|
||||||
<button onClick={() => { removeAssignment(publisher, shift.id) }} // Implement the removeAssignment function
|
|
||||||
className="mt-2 bg-red-500 text-white p-1 rounded hover:bg-red-600 active:bg-red-700 focus:outline-none"
|
|
||||||
>
|
|
||||||
махни
|
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
})}
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
@ -133,57 +194,10 @@ const PublisherShiftsModal = ({ publisher, _shifts, onClose, date, onAssignmentC
|
|||||||
</div>
|
</div>
|
||||||
</div >
|
</div >
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getColorForShift(shift) {
|
|
||||||
const assignedCount = shift.assignedCount || 0; // Assuming each shift has an assignedCount property
|
|
||||||
switch (assignedCount) {
|
|
||||||
case 0: return 'bg-blue-300';
|
|
||||||
case 1: return 'bg-green-300';
|
|
||||||
case 2: return 'bg-yellow-300';
|
|
||||||
case 3: return 'bg-orange-300';
|
|
||||||
case 4: return 'bg-red-200';
|
|
||||||
default: return 'bg-gray-300';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//ToDo: DRY - move to common
|
|
||||||
const addAssignment = async (publisher, shiftId) => {
|
|
||||||
try {
|
|
||||||
console.log(`calendar.idx: new assignment for publisher ${publisher.id} - ${publisher.firstName} ${publisher.lastName}`);
|
|
||||||
const newAssignment = {
|
|
||||||
publisher: { connect: { id: publisher.id } },
|
|
||||||
shift: { connect: { id: shiftId } },
|
|
||||||
isConfirmed: true
|
|
||||||
};
|
|
||||||
const { data } = await axiosInstance.post("/api/data/assignments", newAssignment);
|
|
||||||
|
|
||||||
// Update the 'publisher' property of the returned data with the full publisher object
|
|
||||||
data.publisher = publisher;
|
|
||||||
data.shift = shifts.find(shift => shift.id === shiftId);
|
|
||||||
publisher.assignments = [...publisher.assignments, data];
|
|
||||||
// handleAssignmentChange(publisher.id, 'add');
|
|
||||||
if (onAssignmentChange) { onAssignmentChange(publisher.id, 'add'); }
|
|
||||||
} catch (error) {
|
|
||||||
console.error("Error adding assignment:", error);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const removeAssignment = async (publisher, shiftId) => {
|
|
||||||
try {
|
|
||||||
const assignment = publisher.assignments.find(ass => ass.shift.id === shiftId);
|
|
||||||
console.log(`calendar.idx: remove assignment for shift ${shiftId}`);
|
|
||||||
const { data } = await axiosInstance.delete(`/api/data/assignments/${assignment.id}`);
|
|
||||||
//remove from local assignments:
|
|
||||||
publisher.assignments = publisher.assignments.filter(a => a.id !== assignment.id)
|
|
||||||
//
|
|
||||||
// handleAssignmentChange(publisher.id, 'remove')
|
|
||||||
if (onAssignmentChange) {
|
|
||||||
onAssignmentChange(publisher.id, 'remove')
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error("Error removing assignment:", error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
export default PublisherShiftsModal;
|
export default PublisherShiftsModal;
|
689
package-lock.json
generated
689
package-lock.json
generated
@ -100,6 +100,7 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"cross-env": "^7.0.3",
|
"cross-env": "^7.0.3",
|
||||||
"depcheck": "^1.4.7",
|
"depcheck": "^1.4.7",
|
||||||
|
"eslint-plugin-no-unsanitized": "^4.1.0",
|
||||||
"prisma": "^5.19.1"
|
"prisma": "^5.19.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -2128,6 +2129,200 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.1.tgz",
|
||||||
"integrity": "sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww=="
|
"integrity": "sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww=="
|
||||||
},
|
},
|
||||||
|
"node_modules/@eslint-community/eslint-utils": {
|
||||||
|
"version": "4.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz",
|
||||||
|
"integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==",
|
||||||
|
"dev": true,
|
||||||
|
"peer": true,
|
||||||
|
"dependencies": {
|
||||||
|
"eslint-visitor-keys": "^3.3.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"eslint": "^6.0.0 || ^7.0.0 || >=8.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": {
|
||||||
|
"version": "3.4.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
|
||||||
|
"integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
|
||||||
|
"dev": true,
|
||||||
|
"peer": true,
|
||||||
|
"engines": {
|
||||||
|
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://opencollective.com/eslint"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@eslint-community/regexpp": {
|
||||||
|
"version": "4.11.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.1.tgz",
|
||||||
|
"integrity": "sha512-m4DVN9ZqskZoLU5GlWZadwDnYo3vAEydiUayB9widCl9ffWx2IvPnp6n3on5rJmziJSw9Bv+Z3ChDVdMwXCY8Q==",
|
||||||
|
"dev": true,
|
||||||
|
"peer": true,
|
||||||
|
"engines": {
|
||||||
|
"node": "^12.0.0 || ^14.0.0 || >=16.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@eslint/config-array": {
|
||||||
|
"version": "0.18.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.18.0.tgz",
|
||||||
|
"integrity": "sha512-fTxvnS1sRMu3+JjXwJG0j/i4RT9u4qJ+lqS/yCGap4lH4zZGzQ7tu+xZqQmcMZq5OBZDL4QRxQzRjkWcGt8IVw==",
|
||||||
|
"dev": true,
|
||||||
|
"peer": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@eslint/object-schema": "^2.1.4",
|
||||||
|
"debug": "^4.3.1",
|
||||||
|
"minimatch": "^3.1.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@eslint/config-array/node_modules/debug": {
|
||||||
|
"version": "4.3.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
|
||||||
|
"integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
|
||||||
|
"dev": true,
|
||||||
|
"peer": true,
|
||||||
|
"dependencies": {
|
||||||
|
"ms": "^2.1.3"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"supports-color": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@eslint/config-array/node_modules/ms": {
|
||||||
|
"version": "2.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||||
|
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
|
||||||
|
"dev": true,
|
||||||
|
"peer": true
|
||||||
|
},
|
||||||
|
"node_modules/@eslint/eslintrc": {
|
||||||
|
"version": "3.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.1.0.tgz",
|
||||||
|
"integrity": "sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==",
|
||||||
|
"dev": true,
|
||||||
|
"peer": true,
|
||||||
|
"dependencies": {
|
||||||
|
"ajv": "^6.12.4",
|
||||||
|
"debug": "^4.3.2",
|
||||||
|
"espree": "^10.0.1",
|
||||||
|
"globals": "^14.0.0",
|
||||||
|
"ignore": "^5.2.0",
|
||||||
|
"import-fresh": "^3.2.1",
|
||||||
|
"js-yaml": "^4.1.0",
|
||||||
|
"minimatch": "^3.1.2",
|
||||||
|
"strip-json-comments": "^3.1.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://opencollective.com/eslint"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@eslint/eslintrc/node_modules/argparse": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
|
||||||
|
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
|
||||||
|
"dev": true,
|
||||||
|
"peer": true
|
||||||
|
},
|
||||||
|
"node_modules/@eslint/eslintrc/node_modules/debug": {
|
||||||
|
"version": "4.3.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
|
||||||
|
"integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
|
||||||
|
"dev": true,
|
||||||
|
"peer": true,
|
||||||
|
"dependencies": {
|
||||||
|
"ms": "^2.1.3"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"supports-color": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@eslint/eslintrc/node_modules/globals": {
|
||||||
|
"version": "14.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz",
|
||||||
|
"integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==",
|
||||||
|
"dev": true,
|
||||||
|
"peer": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@eslint/eslintrc/node_modules/js-yaml": {
|
||||||
|
"version": "4.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
|
||||||
|
"integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
|
||||||
|
"dev": true,
|
||||||
|
"peer": true,
|
||||||
|
"dependencies": {
|
||||||
|
"argparse": "^2.0.1"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"js-yaml": "bin/js-yaml.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@eslint/eslintrc/node_modules/ms": {
|
||||||
|
"version": "2.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||||
|
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
|
||||||
|
"dev": true,
|
||||||
|
"peer": true
|
||||||
|
},
|
||||||
|
"node_modules/@eslint/js": {
|
||||||
|
"version": "9.10.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.10.0.tgz",
|
||||||
|
"integrity": "sha512-fuXtbiP5GWIn8Fz+LWoOMVf/Jxm+aajZYkhi6CuEm4SxymFM+eUWzbO9qXT+L0iCkL5+KGYMCSGxo686H19S1g==",
|
||||||
|
"dev": true,
|
||||||
|
"peer": true,
|
||||||
|
"engines": {
|
||||||
|
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@eslint/object-schema": {
|
||||||
|
"version": "2.1.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.4.tgz",
|
||||||
|
"integrity": "sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==",
|
||||||
|
"dev": true,
|
||||||
|
"peer": true,
|
||||||
|
"engines": {
|
||||||
|
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@eslint/plugin-kit": {
|
||||||
|
"version": "0.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.1.0.tgz",
|
||||||
|
"integrity": "sha512-autAXT203ixhqei9xt+qkYOvY8l6LAFIdT2UXc/RPNeUVfqRF1BV94GTJyVPFKT8nFM6MyVJhjLj9E8JWvf5zQ==",
|
||||||
|
"dev": true,
|
||||||
|
"peer": true,
|
||||||
|
"dependencies": {
|
||||||
|
"levn": "^0.4.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@fast-csv/format": {
|
"node_modules/@fast-csv/format": {
|
||||||
"version": "4.3.5",
|
"version": "4.3.5",
|
||||||
"resolved": "https://registry.npmjs.org/@fast-csv/format/-/format-4.3.5.tgz",
|
"resolved": "https://registry.npmjs.org/@fast-csv/format/-/format-4.3.5.tgz",
|
||||||
@ -2293,6 +2488,34 @@
|
|||||||
"react": ">= 16"
|
"react": ">= 16"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@humanwhocodes/module-importer": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==",
|
||||||
|
"dev": true,
|
||||||
|
"peer": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12.22"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/nzakas"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@humanwhocodes/retry": {
|
||||||
|
"version": "0.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.0.tgz",
|
||||||
|
"integrity": "sha512-d2CGZR2o7fS6sWB7DG/3a95bGKQyHMACZ5aW8qGkkqQpUoZV6C0X7Pc7l4ZNMZkfNBf4VWNe9E1jRsf0G146Ew==",
|
||||||
|
"dev": true,
|
||||||
|
"peer": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18.18"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/nzakas"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@img/sharp-darwin-arm64": {
|
"node_modules/@img/sharp-darwin-arm64": {
|
||||||
"version": "0.33.2",
|
"version": "0.33.2",
|
||||||
"resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.33.2.tgz",
|
"resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.33.2.tgz",
|
||||||
@ -4914,9 +5137,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/acorn": {
|
"node_modules/acorn": {
|
||||||
"version": "8.11.3",
|
"version": "8.12.1",
|
||||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz",
|
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz",
|
||||||
"integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==",
|
"integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==",
|
||||||
"bin": {
|
"bin": {
|
||||||
"acorn": "bin/acorn"
|
"acorn": "bin/acorn"
|
||||||
},
|
},
|
||||||
@ -4933,6 +5156,16 @@
|
|||||||
"acorn": "^8"
|
"acorn": "^8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/acorn-jsx": {
|
||||||
|
"version": "5.3.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
|
||||||
|
"integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
|
||||||
|
"dev": true,
|
||||||
|
"peer": true,
|
||||||
|
"peerDependencies": {
|
||||||
|
"acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/acorn-walk": {
|
"node_modules/acorn-walk": {
|
||||||
"version": "8.3.2",
|
"version": "8.3.2",
|
||||||
"resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz",
|
"resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz",
|
||||||
@ -6616,6 +6849,13 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/deep-is": {
|
||||||
|
"version": "0.1.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
|
||||||
|
"integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
|
||||||
|
"dev": true,
|
||||||
|
"peer": true
|
||||||
|
},
|
||||||
"node_modules/deepmerge": {
|
"node_modules/deepmerge": {
|
||||||
"version": "4.3.1",
|
"version": "4.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz",
|
||||||
@ -7499,6 +7739,75 @@
|
|||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/eslint": {
|
||||||
|
"version": "9.10.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/eslint/-/eslint-9.10.0.tgz",
|
||||||
|
"integrity": "sha512-Y4D0IgtBZfOcOUAIQTSXBKoNGfY0REGqHJG6+Q81vNippW5YlKjHFj4soMxamKK1NXHUWuBZTLdU3Km+L/pcHw==",
|
||||||
|
"dev": true,
|
||||||
|
"peer": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@eslint-community/eslint-utils": "^4.2.0",
|
||||||
|
"@eslint-community/regexpp": "^4.11.0",
|
||||||
|
"@eslint/config-array": "^0.18.0",
|
||||||
|
"@eslint/eslintrc": "^3.1.0",
|
||||||
|
"@eslint/js": "9.10.0",
|
||||||
|
"@eslint/plugin-kit": "^0.1.0",
|
||||||
|
"@humanwhocodes/module-importer": "^1.0.1",
|
||||||
|
"@humanwhocodes/retry": "^0.3.0",
|
||||||
|
"@nodelib/fs.walk": "^1.2.8",
|
||||||
|
"ajv": "^6.12.4",
|
||||||
|
"chalk": "^4.0.0",
|
||||||
|
"cross-spawn": "^7.0.2",
|
||||||
|
"debug": "^4.3.2",
|
||||||
|
"escape-string-regexp": "^4.0.0",
|
||||||
|
"eslint-scope": "^8.0.2",
|
||||||
|
"eslint-visitor-keys": "^4.0.0",
|
||||||
|
"espree": "^10.1.0",
|
||||||
|
"esquery": "^1.5.0",
|
||||||
|
"esutils": "^2.0.2",
|
||||||
|
"fast-deep-equal": "^3.1.3",
|
||||||
|
"file-entry-cache": "^8.0.0",
|
||||||
|
"find-up": "^5.0.0",
|
||||||
|
"glob-parent": "^6.0.2",
|
||||||
|
"ignore": "^5.2.0",
|
||||||
|
"imurmurhash": "^0.1.4",
|
||||||
|
"is-glob": "^4.0.0",
|
||||||
|
"is-path-inside": "^3.0.3",
|
||||||
|
"json-stable-stringify-without-jsonify": "^1.0.1",
|
||||||
|
"lodash.merge": "^4.6.2",
|
||||||
|
"minimatch": "^3.1.2",
|
||||||
|
"natural-compare": "^1.4.0",
|
||||||
|
"optionator": "^0.9.3",
|
||||||
|
"strip-ansi": "^6.0.1",
|
||||||
|
"text-table": "^0.2.0"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"eslint": "bin/eslint.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://eslint.org/donate"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"jiti": "*"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"jiti": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/eslint-plugin-no-unsanitized": {
|
||||||
|
"version": "4.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/eslint-plugin-no-unsanitized/-/eslint-plugin-no-unsanitized-4.1.0.tgz",
|
||||||
|
"integrity": "sha512-9A8Yrbkkex8e56ivxJ2f5dXN2Js2BmKC8QgmeYZjadyiGUngo3KLXDlq6ZzalmCHyLwLF5MoQLPR6FWlNc+Qbw==",
|
||||||
|
"dev": true,
|
||||||
|
"peerDependencies": {
|
||||||
|
"eslint": "^8 || ^9"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/eslint-scope": {
|
"node_modules/eslint-scope": {
|
||||||
"version": "5.1.1",
|
"version": "5.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
|
||||||
@ -7512,6 +7821,178 @@
|
|||||||
"node": ">=8.0.0"
|
"node": ">=8.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/eslint-visitor-keys": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz",
|
||||||
|
"integrity": "sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==",
|
||||||
|
"dev": true,
|
||||||
|
"peer": true,
|
||||||
|
"engines": {
|
||||||
|
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://opencollective.com/eslint"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/eslint/node_modules/ansi-styles": {
|
||||||
|
"version": "4.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
|
||||||
|
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
|
||||||
|
"dev": true,
|
||||||
|
"peer": true,
|
||||||
|
"dependencies": {
|
||||||
|
"color-convert": "^2.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/eslint/node_modules/chalk": {
|
||||||
|
"version": "4.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
|
||||||
|
"integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
|
||||||
|
"dev": true,
|
||||||
|
"peer": true,
|
||||||
|
"dependencies": {
|
||||||
|
"ansi-styles": "^4.1.0",
|
||||||
|
"supports-color": "^7.1.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/chalk/chalk?sponsor=1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/eslint/node_modules/color-convert": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||||
|
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
|
||||||
|
"dev": true,
|
||||||
|
"peer": true,
|
||||||
|
"dependencies": {
|
||||||
|
"color-name": "~1.1.4"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=7.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/eslint/node_modules/debug": {
|
||||||
|
"version": "4.3.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
|
||||||
|
"integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
|
||||||
|
"dev": true,
|
||||||
|
"peer": true,
|
||||||
|
"dependencies": {
|
||||||
|
"ms": "^2.1.3"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"supports-color": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/eslint/node_modules/eslint-scope": {
|
||||||
|
"version": "8.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.0.2.tgz",
|
||||||
|
"integrity": "sha512-6E4xmrTw5wtxnLA5wYL3WDfhZ/1bUBGOXV0zQvVRDOtrR8D0p6W7fs3JweNYhwRYeGvd/1CKX2se0/2s7Q/nJA==",
|
||||||
|
"dev": true,
|
||||||
|
"peer": true,
|
||||||
|
"dependencies": {
|
||||||
|
"esrecurse": "^4.3.0",
|
||||||
|
"estraverse": "^5.2.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://opencollective.com/eslint"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/eslint/node_modules/estraverse": {
|
||||||
|
"version": "5.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
|
||||||
|
"integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
|
||||||
|
"dev": true,
|
||||||
|
"peer": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/eslint/node_modules/glob-parent": {
|
||||||
|
"version": "6.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
|
||||||
|
"integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
|
||||||
|
"dev": true,
|
||||||
|
"peer": true,
|
||||||
|
"dependencies": {
|
||||||
|
"is-glob": "^4.0.3"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10.13.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/eslint/node_modules/has-flag": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
|
||||||
|
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
|
||||||
|
"dev": true,
|
||||||
|
"peer": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/eslint/node_modules/lodash.merge": {
|
||||||
|
"version": "4.6.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
|
||||||
|
"integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
|
||||||
|
"dev": true,
|
||||||
|
"peer": true
|
||||||
|
},
|
||||||
|
"node_modules/eslint/node_modules/ms": {
|
||||||
|
"version": "2.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||||
|
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
|
||||||
|
"dev": true,
|
||||||
|
"peer": true
|
||||||
|
},
|
||||||
|
"node_modules/eslint/node_modules/supports-color": {
|
||||||
|
"version": "7.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
|
||||||
|
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
|
||||||
|
"dev": true,
|
||||||
|
"peer": true,
|
||||||
|
"dependencies": {
|
||||||
|
"has-flag": "^4.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/espree": {
|
||||||
|
"version": "10.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/espree/-/espree-10.1.0.tgz",
|
||||||
|
"integrity": "sha512-M1M6CpiE6ffoigIOWYO9UDP8TMUw9kqb21tf+08IgDYjCsOvCuDt4jQcZmoYxx+w7zlKw9/N0KXfto+I8/FrXA==",
|
||||||
|
"dev": true,
|
||||||
|
"peer": true,
|
||||||
|
"dependencies": {
|
||||||
|
"acorn": "^8.12.0",
|
||||||
|
"acorn-jsx": "^5.3.2",
|
||||||
|
"eslint-visitor-keys": "^4.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://opencollective.com/eslint"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/esprima": {
|
"node_modules/esprima": {
|
||||||
"version": "4.0.1",
|
"version": "4.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
|
||||||
@ -7525,6 +8006,29 @@
|
|||||||
"node": ">=4"
|
"node": ">=4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/esquery": {
|
||||||
|
"version": "1.6.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz",
|
||||||
|
"integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==",
|
||||||
|
"dev": true,
|
||||||
|
"peer": true,
|
||||||
|
"dependencies": {
|
||||||
|
"estraverse": "^5.1.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/esquery/node_modules/estraverse": {
|
||||||
|
"version": "5.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
|
||||||
|
"integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
|
||||||
|
"dev": true,
|
||||||
|
"peer": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/esrecurse": {
|
"node_modules/esrecurse": {
|
||||||
"version": "4.3.0",
|
"version": "4.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
|
||||||
@ -7807,6 +8311,13 @@
|
|||||||
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
|
||||||
"integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="
|
"integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="
|
||||||
},
|
},
|
||||||
|
"node_modules/fast-levenshtein": {
|
||||||
|
"version": "2.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
|
||||||
|
"integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
|
||||||
|
"dev": true,
|
||||||
|
"peer": true
|
||||||
|
},
|
||||||
"node_modules/fast-write-atomic": {
|
"node_modules/fast-write-atomic": {
|
||||||
"version": "0.2.1",
|
"version": "0.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/fast-write-atomic/-/fast-write-atomic-0.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/fast-write-atomic/-/fast-write-atomic-0.2.1.tgz",
|
||||||
@ -7839,6 +8350,19 @@
|
|||||||
"resolved": "https://registry.npmjs.org/fflate/-/fflate-0.3.11.tgz",
|
"resolved": "https://registry.npmjs.org/fflate/-/fflate-0.3.11.tgz",
|
||||||
"integrity": "sha512-Rr5QlUeGN1mbOHlaqcSYMKVpPbgLy0AWT/W0EHxA6NGI12yO1jpoui2zBBvU2G824ltM6Ut8BFgfHSBGfkmS0A=="
|
"integrity": "sha512-Rr5QlUeGN1mbOHlaqcSYMKVpPbgLy0AWT/W0EHxA6NGI12yO1jpoui2zBBvU2G824ltM6Ut8BFgfHSBGfkmS0A=="
|
||||||
},
|
},
|
||||||
|
"node_modules/file-entry-cache": {
|
||||||
|
"version": "8.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz",
|
||||||
|
"integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==",
|
||||||
|
"dev": true,
|
||||||
|
"peer": true,
|
||||||
|
"dependencies": {
|
||||||
|
"flat-cache": "^4.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=16.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/file-stream-rotator": {
|
"node_modules/file-stream-rotator": {
|
||||||
"version": "0.6.1",
|
"version": "0.6.1",
|
||||||
"resolved": "https://registry.npmjs.org/file-stream-rotator/-/file-stream-rotator-0.6.1.tgz",
|
"resolved": "https://registry.npmjs.org/file-stream-rotator/-/file-stream-rotator-0.6.1.tgz",
|
||||||
@ -7935,7 +8459,7 @@
|
|||||||
"version": "5.0.0",
|
"version": "5.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
|
||||||
"integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
|
"integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
|
||||||
"optional": true,
|
"devOptional": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"locate-path": "^6.0.0",
|
"locate-path": "^6.0.0",
|
||||||
"path-exists": "^4.0.0"
|
"path-exists": "^4.0.0"
|
||||||
@ -7962,6 +8486,27 @@
|
|||||||
"node": ">= 10.13.0"
|
"node": ">= 10.13.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/flat-cache": {
|
||||||
|
"version": "4.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz",
|
||||||
|
"integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==",
|
||||||
|
"dev": true,
|
||||||
|
"peer": true,
|
||||||
|
"dependencies": {
|
||||||
|
"flatted": "^3.2.9",
|
||||||
|
"keyv": "^4.5.4"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=16"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/flatted": {
|
||||||
|
"version": "3.3.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz",
|
||||||
|
"integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==",
|
||||||
|
"dev": true,
|
||||||
|
"peer": true
|
||||||
|
},
|
||||||
"node_modules/fn.name": {
|
"node_modules/fn.name": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz",
|
||||||
@ -9157,6 +9702,16 @@
|
|||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/imurmurhash": {
|
||||||
|
"version": "0.1.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
|
||||||
|
"integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
|
||||||
|
"dev": true,
|
||||||
|
"peer": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.8.19"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/indent-string": {
|
"node_modules/indent-string": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz",
|
||||||
@ -9533,7 +10088,7 @@
|
|||||||
"version": "3.0.3",
|
"version": "3.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz",
|
||||||
"integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==",
|
"integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==",
|
||||||
"optional": true,
|
"devOptional": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
@ -9881,6 +10436,13 @@
|
|||||||
"bignumber.js": "^9.0.0"
|
"bignumber.js": "^9.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/json-buffer": {
|
||||||
|
"version": "3.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
|
||||||
|
"integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==",
|
||||||
|
"dev": true,
|
||||||
|
"peer": true
|
||||||
|
},
|
||||||
"node_modules/json-parse-even-better-errors": {
|
"node_modules/json-parse-even-better-errors": {
|
||||||
"version": "2.3.1",
|
"version": "2.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
|
||||||
@ -9896,6 +10458,13 @@
|
|||||||
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
|
||||||
"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="
|
"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="
|
||||||
},
|
},
|
||||||
|
"node_modules/json-stable-stringify-without-jsonify": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==",
|
||||||
|
"dev": true,
|
||||||
|
"peer": true
|
||||||
|
},
|
||||||
"node_modules/json-stringify-safe": {
|
"node_modules/json-stringify-safe": {
|
||||||
"version": "5.0.1",
|
"version": "5.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
|
||||||
@ -10052,6 +10621,16 @@
|
|||||||
"resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-3.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-3.1.2.tgz",
|
||||||
"integrity": "sha512-UfpWE/VZn0iP50d8cz9NrZLM9lSWhcJ+0Gt/nm4by88UL+J1SiKN8/5dkjMmbEzwL2CAe+67GsegCbIKtbp75A=="
|
"integrity": "sha512-UfpWE/VZn0iP50d8cz9NrZLM9lSWhcJ+0Gt/nm4by88UL+J1SiKN8/5dkjMmbEzwL2CAe+67GsegCbIKtbp75A=="
|
||||||
},
|
},
|
||||||
|
"node_modules/keyv": {
|
||||||
|
"version": "4.5.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
|
||||||
|
"integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==",
|
||||||
|
"dev": true,
|
||||||
|
"peer": true,
|
||||||
|
"dependencies": {
|
||||||
|
"json-buffer": "3.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/kleur": {
|
"node_modules/kleur": {
|
||||||
"version": "4.1.5",
|
"version": "4.1.5",
|
||||||
"resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz",
|
"resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz",
|
||||||
@ -10133,6 +10712,20 @@
|
|||||||
"url": "https://github.com/sponsors/wooorm"
|
"url": "https://github.com/sponsors/wooorm"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/levn": {
|
||||||
|
"version": "0.4.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
|
||||||
|
"integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
|
||||||
|
"dev": true,
|
||||||
|
"peer": true,
|
||||||
|
"dependencies": {
|
||||||
|
"prelude-ls": "^1.2.1",
|
||||||
|
"type-check": "~0.4.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/lie": {
|
"node_modules/lie": {
|
||||||
"version": "3.3.0",
|
"version": "3.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz",
|
||||||
@ -10185,7 +10778,7 @@
|
|||||||
"version": "6.0.0",
|
"version": "6.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
|
||||||
"integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
|
"integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
|
||||||
"optional": true,
|
"devOptional": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"p-locate": "^5.0.0"
|
"p-locate": "^5.0.0"
|
||||||
},
|
},
|
||||||
@ -10887,6 +11480,13 @@
|
|||||||
"node": "^18 || >=20"
|
"node": "^18 || >=20"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/natural-compare": {
|
||||||
|
"version": "1.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
|
||||||
|
"integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
|
||||||
|
"dev": true,
|
||||||
|
"peer": true
|
||||||
|
},
|
||||||
"node_modules/negotiator": {
|
"node_modules/negotiator": {
|
||||||
"version": "0.6.3",
|
"version": "0.6.3",
|
||||||
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
|
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
|
||||||
@ -14560,6 +15160,24 @@
|
|||||||
"url": "https://github.com/sponsors/panva"
|
"url": "https://github.com/sponsors/panva"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/optionator": {
|
||||||
|
"version": "0.9.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz",
|
||||||
|
"integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==",
|
||||||
|
"dev": true,
|
||||||
|
"peer": true,
|
||||||
|
"dependencies": {
|
||||||
|
"deep-is": "^0.1.3",
|
||||||
|
"fast-levenshtein": "^2.0.6",
|
||||||
|
"levn": "^0.4.1",
|
||||||
|
"prelude-ls": "^1.2.1",
|
||||||
|
"type-check": "^0.4.0",
|
||||||
|
"word-wrap": "^1.2.5"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/p-filter": {
|
"node_modules/p-filter": {
|
||||||
"version": "2.1.0",
|
"version": "2.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/p-filter/-/p-filter-2.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/p-filter/-/p-filter-2.1.0.tgz",
|
||||||
@ -14585,7 +15203,7 @@
|
|||||||
"version": "3.1.0",
|
"version": "3.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
|
||||||
"integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
|
"integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
|
||||||
"optional": true,
|
"devOptional": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"yocto-queue": "^0.1.0"
|
"yocto-queue": "^0.1.0"
|
||||||
},
|
},
|
||||||
@ -14600,7 +15218,7 @@
|
|||||||
"version": "5.0.0",
|
"version": "5.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
|
||||||
"integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
|
"integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
|
||||||
"optional": true,
|
"devOptional": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"p-limit": "^3.0.2"
|
"p-limit": "^3.0.2"
|
||||||
},
|
},
|
||||||
@ -15072,6 +15690,16 @@
|
|||||||
"preact": ">=10"
|
"preact": ">=10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/prelude-ls": {
|
||||||
|
"version": "1.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
|
||||||
|
"integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
|
||||||
|
"dev": true,
|
||||||
|
"peer": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/pretty-bytes": {
|
"node_modules/pretty-bytes": {
|
||||||
"version": "5.6.0",
|
"version": "5.6.0",
|
||||||
"resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz",
|
"resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz",
|
||||||
@ -16934,6 +17562,19 @@
|
|||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/strip-json-comments": {
|
||||||
|
"version": "3.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
|
||||||
|
"integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
|
||||||
|
"dev": true,
|
||||||
|
"peer": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/styled-jsx": {
|
"node_modules/styled-jsx": {
|
||||||
"version": "5.1.1",
|
"version": "5.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.1.tgz",
|
||||||
@ -17491,6 +18132,13 @@
|
|||||||
"resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz",
|
||||||
"integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg=="
|
"integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg=="
|
||||||
},
|
},
|
||||||
|
"node_modules/text-table": {
|
||||||
|
"version": "0.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
|
||||||
|
"integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==",
|
||||||
|
"dev": true,
|
||||||
|
"peer": true
|
||||||
|
},
|
||||||
"node_modules/thenify": {
|
"node_modules/thenify": {
|
||||||
"version": "3.3.1",
|
"version": "3.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz",
|
||||||
@ -17862,6 +18510,19 @@
|
|||||||
"resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
|
"resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
|
||||||
"integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA=="
|
"integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA=="
|
||||||
},
|
},
|
||||||
|
"node_modules/type-check": {
|
||||||
|
"version": "0.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
|
||||||
|
"integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
|
||||||
|
"dev": true,
|
||||||
|
"peer": true,
|
||||||
|
"dependencies": {
|
||||||
|
"prelude-ls": "^1.2.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/type-fest": {
|
"node_modules/type-fest": {
|
||||||
"version": "0.8.1",
|
"version": "0.8.1",
|
||||||
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
|
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
|
||||||
@ -18631,6 +19292,16 @@
|
|||||||
"node": ">=0.8"
|
"node": ">=0.8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/word-wrap": {
|
||||||
|
"version": "1.2.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz",
|
||||||
|
"integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==",
|
||||||
|
"dev": true,
|
||||||
|
"peer": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/wordwrap": {
|
"node_modules/wordwrap": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
|
||||||
@ -19352,7 +20023,7 @@
|
|||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
|
||||||
"integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
|
"integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
|
||||||
"optional": true,
|
"devOptional": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=10"
|
"node": ">=10"
|
||||||
},
|
},
|
||||||
|
@ -118,6 +118,7 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"cross-env": "^7.0.3",
|
"cross-env": "^7.0.3",
|
||||||
"depcheck": "^1.4.7",
|
"depcheck": "^1.4.7",
|
||||||
|
"eslint-plugin-no-unsanitized": "^4.1.0",
|
||||||
"prisma": "^5.19.1"
|
"prisma": "^5.19.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ import fs from 'fs';
|
|||||||
import path from 'path';
|
import path from 'path';
|
||||||
import { all } from "axios";
|
import { all } from "axios";
|
||||||
import { logger } from "src/helpers/common";
|
import { logger } from "src/helpers/common";
|
||||||
import { excel } from "src/helpers/excel";
|
import { ExportPublishersToExcel } from "src/helpers/excel";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@ -435,7 +435,7 @@ export default async function handler(req, res) {
|
|||||||
res.status(200).json(await dataHelper.getAllPublishersWithStatisticsMonth(day, noEndDate));
|
res.status(200).json(await dataHelper.getAllPublishersWithStatisticsMonth(day, noEndDate));
|
||||||
case "exportPublishersExcel":
|
case "exportPublishersExcel":
|
||||||
try {
|
try {
|
||||||
await excel.ExportPublishersToExcel(req, res);
|
await ExportPublishersToExcel(req, res);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(JSON.stringify(error));
|
console.error(JSON.stringify(error));
|
||||||
}
|
}
|
||||||
|
@ -143,7 +143,7 @@ function flattenRegistry(dayKey) {
|
|||||||
return Object.values(weekEntries).flat();
|
return Object.values(weekEntries).flat();
|
||||||
}
|
}
|
||||||
|
|
||||||
async function GenerateSchedule(axios, date, copyFromPreviousMonth = false, autoFill = false, forDay, algType = 0) {
|
async function GenerateSchedule(axios, date, copyFromPreviousMonth = false, autoFill = false, forDay, algType = 0, until) {
|
||||||
|
|
||||||
let missingPublishers = [];
|
let missingPublishers = [];
|
||||||
let publishersWithChangedPref = [];
|
let publishersWithChangedPref = [];
|
||||||
@ -176,7 +176,14 @@ async function GenerateSchedule(axios, date, copyFromPreviousMonth = false, auto
|
|||||||
|
|
||||||
if (forDay) {
|
if (forDay) {
|
||||||
day = monthInfo.date;
|
day = monthInfo.date;
|
||||||
endDate.setDate(monthInfo.date.getDate() + 1);
|
if (until === undefined) {
|
||||||
|
const oneDayInMs = 24 * 60 * 60 * 1000;
|
||||||
|
endDate = new Date(monthInfo.date.getTime() + oneDayInMs);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
endDate = new Date(until);
|
||||||
|
}
|
||||||
|
|
||||||
dayNr = monthInfo.date.getDate();
|
dayNr = monthInfo.date.getDate();
|
||||||
weekNr = common.getWeekNumber(monthInfo.date);
|
weekNr = common.getWeekNumber(monthInfo.date);
|
||||||
}
|
}
|
||||||
@ -184,7 +191,7 @@ async function GenerateSchedule(axios, date, copyFromPreviousMonth = false, auto
|
|||||||
let publishersThisWeek = [];
|
let publishersThisWeek = [];
|
||||||
|
|
||||||
|
|
||||||
|
// # # # # # # # # # # #
|
||||||
// 0. generate shifts and assign publishers from the previous month if still available
|
// 0. generate shifts and assign publishers from the previous month if still available
|
||||||
while (day < endDate) {
|
while (day < endDate) {
|
||||||
let availablePubsForTheDay = await data.filterPublishersNew('id,firstName,lastName,email,isActive,desiredShiftsPerMonth,lastLogin,type', day, false, false, false, true, false);
|
let availablePubsForTheDay = await data.filterPublishersNew('id,firstName,lastName,email,isActive,desiredShiftsPerMonth,lastLogin,type', day, false, false, false, true, false);
|
||||||
@ -262,7 +269,7 @@ async function GenerateSchedule(axios, date, copyFromPreviousMonth = false, auto
|
|||||||
//ToDo: check if getAvailablePublishersForShift is working correctly. It seems not to!
|
//ToDo: check if getAvailablePublishersForShift is working correctly. It seems not to!
|
||||||
let availablePublishers = await getAvailablePublishersForShiftNew(shiftStart, shiftEnd, availablePubsForTheDay, publishersThisWeek);
|
let availablePublishers = await getAvailablePublishersForShiftNew(shiftStart, shiftEnd, availablePubsForTheDay, publishersThisWeek);
|
||||||
|
|
||||||
console.log("shift " + __shiftName + " needs " + publishersNeeded + " publishers, available: " + availablePublishers.length + " for the day: " + availablePubsForTheDay.length);
|
console.log("shift " + __shiftName + " needs " + publishersNeeded + " publishers, available: " + availablePublishers.length + ", for the day: " + availablePubsForTheDay.length);
|
||||||
|
|
||||||
const createdShift = await prisma.shift.create({
|
const createdShift = await prisma.shift.create({
|
||||||
data: {
|
data: {
|
||||||
@ -294,21 +301,31 @@ async function GenerateSchedule(axios, date, copyFromPreviousMonth = false, auto
|
|||||||
shiftEnd.setMinutes(shiftStart.getMinutes() + event.shiftDuration);
|
shiftEnd.setMinutes(shiftStart.getMinutes() + event.shiftDuration);
|
||||||
}
|
}
|
||||||
|
|
||||||
day.setDate(day.getDate() + 1);
|
|
||||||
dayNr++;
|
if (forDay) { break; }
|
||||||
if (common.DaysOfWeekArray[day.getDayEuropean()] === DayOfWeek.Sunday) {
|
else {
|
||||||
weekNr++;
|
day.setDate(day.getDate() + 1);
|
||||||
publishersThisWeek = [];
|
dayNr++;
|
||||||
publishers.forEach(p => p.currentWeekAssignments = 0);
|
if (common.DaysOfWeekArray[day.getDayEuropean()] === DayOfWeek.Sunday) {
|
||||||
|
weekNr++;
|
||||||
|
publishersThisWeek = [];
|
||||||
|
publishers.forEach(p => p.currentWeekAssignments = 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (forDay) break;
|
}
|
||||||
|
|
||||||
|
|
||||||
|
let from = monthInfo.firstMonday, to = monthInfo.lastSunday;
|
||||||
|
if (forDay) {
|
||||||
|
from = day;
|
||||||
|
to = endDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
let allShifts = await prisma.shift.findMany({
|
let allShifts = await prisma.shift.findMany({
|
||||||
where: {
|
where: {
|
||||||
startTime: {
|
startTime: {
|
||||||
gte: monthInfo.firstMonday,
|
gte: from,
|
||||||
lt: monthInfo.lastSunday,
|
lt: to,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
include: {
|
include: {
|
||||||
@ -320,17 +337,23 @@ async function GenerateSchedule(axios, date, copyFromPreviousMonth = false, auto
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
let publishersToday = [];
|
let publishersToday = [];
|
||||||
let rankedPublishers = [];
|
let rankedPublishers = [];
|
||||||
|
|
||||||
|
// # # # # # # # # # # #
|
||||||
// Second pass - prioritize shifts with transport where it is needed
|
// Second pass - prioritize shifts with transport where it is needed
|
||||||
|
if (forDay) { }
|
||||||
|
else {
|
||||||
|
day = new Date(monthInfo.firstMonday);
|
||||||
|
dayNr = 1;
|
||||||
|
weekNr = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
console.log("\r\n\r\n\r\n" + "# ".repeat(50));
|
console.log("\r\n\r\n\r\n" + "# ".repeat(50));
|
||||||
console.log("Second pass - fix transports " + monthInfo.monthName + " " + monthInfo.year);
|
console.log("Second pass - fix transports " + day.toLocaleDateString());
|
||||||
|
|
||||||
day = new Date(monthInfo.firstMonday);
|
|
||||||
dayNr = 1;
|
|
||||||
weekNr = 1;
|
|
||||||
while (day < endDate) {
|
while (day < endDate) {
|
||||||
let dayOfWeekEnum = common.getDayOfWeekNameEnEnumForDate(day);
|
let dayOfWeekEnum = common.getDayOfWeekNameEnEnumForDate(day);
|
||||||
let event = events.find((event) => event.dayofweek == common.DaysOfWeekArray[day.getDayEuropean()]);
|
let event = events.find((event) => event.dayofweek == common.DaysOfWeekArray[day.getDayEuropean()]);
|
||||||
@ -371,7 +394,7 @@ async function GenerateSchedule(axios, date, copyFromPreviousMonth = false, auto
|
|||||||
else if (publishersNeeded > 0) {
|
else if (publishersNeeded > 0) {
|
||||||
console.log("shift " + shift.name + " requires transport (" + transportCapable.length + " transport capable)");
|
console.log("shift " + shift.name + " requires transport (" + transportCapable.length + " transport capable)");
|
||||||
|
|
||||||
let availablePubsForTheShift = await data.filterPublishersNew('id,firstName,lastName,email,isActive,desiredShiftsPerMonth,lastLogin,type', shift.startTime, true, false, false, true, false);
|
let availablePubsForTheShift = await data.filterPublishersNew('id,firstName,lastName,email,isActive,desiredShiftsPerMonth,lastLogin,type,familyHeadId', shift.startTime, true, false, false, true, false);
|
||||||
|
|
||||||
let availablePublishers = availablePubsForTheShift.filter(p => {
|
let availablePublishers = availablePubsForTheShift.filter(p => {
|
||||||
const hasTransportInAvailability = shift.transportIn && p.availabilities.some(avail => avail.isWithTransportIn);
|
const hasTransportInAvailability = shift.transportIn && p.availabilities.some(avail => avail.isWithTransportIn);
|
||||||
@ -386,45 +409,35 @@ async function GenerateSchedule(axios, date, copyFromPreviousMonth = false, auto
|
|||||||
} else if (algType == 1) {
|
} else if (algType == 1) {
|
||||||
rankedPublishers = await RankPublishersForShiftWeighted([...availablePublishers], scheduledPubsPerDayAndWeek, day, weekNr);
|
rankedPublishers = await RankPublishersForShiftWeighted([...availablePublishers], scheduledPubsPerDayAndWeek, day, weekNr);
|
||||||
}
|
}
|
||||||
// if (rankedPublishers.length > 0) {
|
|
||||||
// const newAssignment = await prisma.assignment.create({
|
|
||||||
// data: {
|
|
||||||
// shift: {
|
|
||||||
// connect: {
|
|
||||||
// id: shift.id,
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
// publisher: {
|
|
||||||
// connect: {
|
|
||||||
// id: rankedPublishers[0].id,
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
// isWithTransport: true,
|
|
||||||
// isConfirmed: true,
|
|
||||||
// isBySystem: false,
|
|
||||||
// },
|
|
||||||
// });
|
|
||||||
|
|
||||||
// shift.assignments.push(newAssignment);
|
|
||||||
// publishersToday.push(rankedPublishers[0].id);
|
|
||||||
// updateRegistry(rankedPublishers[0].id, day, weekNr);
|
|
||||||
// }
|
|
||||||
AddPublisherAssignment(prisma, event, shift, availablePublishers, rankedPublishers, publishersToday, day, weekNr);
|
AddPublisherAssignment(prisma, event, shift, availablePublishers, rankedPublishers, publishersToday, day, weekNr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
day.setDate(day.getDate() + 1);
|
if (forDay) { break; }
|
||||||
|
else {
|
||||||
|
day.setDate(day.getDate() + 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fill the rest of the shifts
|
|
||||||
|
// # # # # # # # # # # #
|
||||||
|
// 3. Fill the rest of the shifts
|
||||||
let goal = 1;
|
let goal = 1;
|
||||||
while (goal <= 4) {
|
while (goal <= 4) {
|
||||||
console.log("\r\n\r\n\r\n" + "# ".repeat(50));
|
|
||||||
console.log("Filling shifts with " + goal + " publishers " + monthInfo.monthName + " " + monthInfo.year);
|
if (forDay) {
|
||||||
day = new Date(monthInfo.firstMonday);
|
}
|
||||||
dayNr = 1;
|
else {
|
||||||
weekNr = 1;
|
day = new Date(monthInfo.firstMonday);
|
||||||
|
dayNr = 1;
|
||||||
|
weekNr = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("\r\n\r\n" + "# ".repeat(50));
|
||||||
|
console.log("Filling shifts with " + goal + " publishers | " + day.toLocaleDateString());
|
||||||
|
|
||||||
while (day < endDate) {
|
while (day < endDate) {
|
||||||
let dayOfWeekEnum = common.getDayOfWeekNameEnEnumForDate(day);
|
let dayOfWeekEnum = common.getDayOfWeekNameEnEnumForDate(day);
|
||||||
let event = events.find((event) => event.dayofweek == common.DaysOfWeekArray[day.getDayEuropean()]);
|
let event = events.find((event) => event.dayofweek == common.DaysOfWeekArray[day.getDayEuropean()]);
|
||||||
@ -452,7 +465,7 @@ async function GenerateSchedule(axios, date, copyFromPreviousMonth = false, auto
|
|||||||
console.log("Filling shift " + shift.name + " with " + goal + " publishers");
|
console.log("Filling shift " + shift.name + " with " + goal + " publishers");
|
||||||
let publishersNeeded = event.numberOfPublishers - shift.assignments.length;
|
let publishersNeeded = event.numberOfPublishers - shift.assignments.length;
|
||||||
if (publishersNeeded > 0 && shift.assignments.length < goal) {
|
if (publishersNeeded > 0 && shift.assignments.length < goal) {
|
||||||
let availablePubsForTheShift = await data.filterPublishersNew('id,firstName,lastName,email,isActive,desiredShiftsPerMonth,lastLogin,type', shift.startTime, true, false, false, true, false);
|
let availablePubsForTheShift = await data.filterPublishersNew('id,firstName,lastName,email,isActive,desiredShiftsPerMonth,lastLogin,type,familyHeadId', shift.startTime, true, false, false, true, false);
|
||||||
|
|
||||||
let availablePublishers = await FilterInappropriatePublishers([...availablePubsForTheShift], publishersToday, shift);
|
let availablePublishers = await FilterInappropriatePublishers([...availablePubsForTheShift], publishersToday, shift);
|
||||||
if (algType == 0) {
|
if (algType == 0) {
|
||||||
@ -461,12 +474,17 @@ async function GenerateSchedule(axios, date, copyFromPreviousMonth = false, auto
|
|||||||
rankedPublishers = await RankPublishersForShiftWeighted([...availablePublishers], scheduledPubsPerDayAndWeek, day, weekNr);
|
rankedPublishers = await RankPublishersForShiftWeighted([...availablePublishers], scheduledPubsPerDayAndWeek, day, weekNr);
|
||||||
}
|
}
|
||||||
|
|
||||||
AddPublisherAssignment(prisma, event, shift, availablePublishers, rankedPublishers, publishersToday, day, weekNr);
|
await AddPublisherAssignment(prisma, event, shift, availablePublishers, rankedPublishers, publishersToday, day, weekNr);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
day.setDate(day.getDate() + 1);
|
if (forDay) { break; }
|
||||||
|
else {
|
||||||
|
day.setDate(day.getDate() + 1);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
goal += 1;
|
goal += 1;
|
||||||
}
|
}
|
||||||
@ -486,14 +504,18 @@ async function GenerateSchedule(axios, date, copyFromPreviousMonth = false, auto
|
|||||||
|
|
||||||
async function AddPublisherAssignment(prisma, event, shift, availablePubsForTheShift, rankedPublishers, publishersToday, day, weekNr) {
|
async function AddPublisherAssignment(prisma, event, shift, availablePubsForTheShift, rankedPublishers, publishersToday, day, weekNr) {
|
||||||
if (rankedPublishers.length == 0) {
|
if (rankedPublishers.length == 0) {
|
||||||
console.log("No available publishers for shift " + shift.name);
|
console.log("! ! ! No available publishers for shift " + shift.name + " ! ! !");
|
||||||
} else {
|
} else {
|
||||||
for (let i = 0; i < rankedPublishers.length; i++) {
|
for (let i = 0; i < rankedPublishers.length; i++) {
|
||||||
let mainPublisher = rankedPublishers[i];
|
let mainPublisher = rankedPublishers[i];
|
||||||
let familyMembers = availablePubsForTheShift.filter(p => (p.familyHeadId && p.familyHeadId === mainPublisher.familyHeadId) || (p.familyHeadId === mainPublisher.id));
|
let familyMembers = availablePubsForTheShift.filter(p => (p.id !== mainPublisher.id && (p.id === mainPublisher.familyHeadId) || (p.familyHeadId === mainPublisher.id)));
|
||||||
|
|
||||||
if (familyMembers.length > 0 && (shift.assignments.length + familyMembers.length + 1) <= event.numberOfPublishers) {
|
if (familyMembers.length > 0 && (shift.assignments.length + familyMembers.length + 1) <= event.numberOfPublishers) {
|
||||||
console.log("Assigning " + mainPublisher.firstName + " " + mainPublisher.lastName + " and family members to " + new Date(shift.startTime).getDate() + " " + shift.name);
|
console.log("Assigning " + mainPublisher.firstName + " " + mainPublisher.lastName + " and " + familyMembers.length + " available family members to " + new Date(shift.startTime).getDate() + " " + shift.name);
|
||||||
|
|
||||||
|
const hasTransportInAvailability = shift.transportIn && mainPublisher.availabilities.some(avail => avail.isWithTransportIn);
|
||||||
|
const hasTransportOutAvailability = shift.transportOut && mainPublisher.availabilities.some(avail => avail.isWithTransportOut);
|
||||||
|
|
||||||
const newAssignment = await prisma.assignment.create({
|
const newAssignment = await prisma.assignment.create({
|
||||||
data: {
|
data: {
|
||||||
shift: {
|
shift: {
|
||||||
@ -508,7 +530,7 @@ async function AddPublisherAssignment(prisma, event, shift, availablePubsForTheS
|
|||||||
},
|
},
|
||||||
isConfirmed: false,
|
isConfirmed: false,
|
||||||
isBySystem: false,
|
isBySystem: false,
|
||||||
isWithTransport: shift.requiresTransport,
|
isWithTransport: (hasTransportInAvailability || hasTransportOutAvailability),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
shift.assignments.push(newAssignment);
|
shift.assignments.push(newAssignment);
|
||||||
@ -540,6 +562,10 @@ async function AddPublisherAssignment(prisma, event, shift, availablePubsForTheS
|
|||||||
break;
|
break;
|
||||||
} else if (familyMembers.length == 0) {
|
} else if (familyMembers.length == 0) {
|
||||||
console.log("Assigning " + mainPublisher.firstName + " " + mainPublisher.lastName + " to " + new Date(shift.startTime).getDate() + " " + shift.name);
|
console.log("Assigning " + mainPublisher.firstName + " " + mainPublisher.lastName + " to " + new Date(shift.startTime).getDate() + " " + shift.name);
|
||||||
|
|
||||||
|
const hasTransportInAvailability = shift.transportIn && mainPublisher.availabilities.some(avail => avail.isWithTransportIn);
|
||||||
|
const hasTransportOutAvailability = shift.transportOut && mainPublisher.availabilities.some(avail => avail.isWithTransportOut);
|
||||||
|
|
||||||
const newAssignment = await prisma.assignment.create({
|
const newAssignment = await prisma.assignment.create({
|
||||||
data: {
|
data: {
|
||||||
shift: {
|
shift: {
|
||||||
@ -554,7 +580,7 @@ async function AddPublisherAssignment(prisma, event, shift, availablePubsForTheS
|
|||||||
},
|
},
|
||||||
isConfirmed: false,
|
isConfirmed: false,
|
||||||
isBySystem: false,
|
isBySystem: false,
|
||||||
isWithTransport: shift.requiresTransport,
|
isWithTransport: (hasTransportInAvailability || hasTransportOutAvailability),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
shift.assignments.push(newAssignment);
|
shift.assignments.push(newAssignment);
|
||||||
@ -564,17 +590,16 @@ async function AddPublisherAssignment(prisma, event, shift, availablePubsForTheS
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function FilterInappropriatePublishers(availablePublishers, pubsToExclude, shift) {
|
async function FilterInappropriatePublishers(availablePublishers, pubsToExclude, shift, maxShifts = 0) {
|
||||||
//ToDo: Optimization: store number of publishers, so we process the shifts from least to most available publishers later.
|
//ToDo: Optimization: store number of publishers, so we process the shifts from least to most available publishers later.
|
||||||
let goodPublishers = availablePublishers.filter(p => {
|
let goodPublishers = availablePublishers.filter(p => {
|
||||||
const isNotAssigned = !shift.assignments.some(a => a.publisher?.id === p.id);
|
const isNotAssigned = !shift.assignments.some(a => a.publisher?.id === p.id);
|
||||||
const isNotAssignedToday = !pubsToExclude.includes(p.id);
|
const isNotAssignedToday = !pubsToExclude.includes(p.id);
|
||||||
const isAssignedEnough = p.currentMonthAssignments >= p.desiredShiftsPerMonth
|
const isAssignedEnough = p.currentMonthAssignments >= p.desiredShiftsPerMonth
|
||||||
|| p.currentMonthAssignments >= 6; // overwrite the desiredShiftsPerMonth to max 6 shifts per month
|
|| p.currentMonthAssignments >= maxShifts; // overwrite the desiredShiftsPerMonth to max 10 shifts per month
|
||||||
return isNotAssigned && isNotAssignedToday && !isAssignedEnough;
|
return isNotAssigned && isNotAssignedToday && (!isAssignedEnough || maxShifts == 0);
|
||||||
});
|
});
|
||||||
return goodPublishers;
|
return goodPublishers;
|
||||||
}
|
}
|
||||||
@ -696,10 +721,17 @@ async function RankPublishersForShiftWeighted(publishers, scheduledPubsPerDayAnd
|
|||||||
const result = calculateScoreAndPenalties(p);
|
const result = calculateScoreAndPenalties(p);
|
||||||
p.score = result.score;
|
p.score = result.score;
|
||||||
p.penalties = result.penalties;
|
p.penalties = result.penalties;
|
||||||
|
|
||||||
|
p.finalScore = p.score;
|
||||||
|
if (p.finalScore > 0) {
|
||||||
|
p.penalties.forEach(penalty => {
|
||||||
|
p.finalScore *= penalty.penalty;
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Sort publishers based on score
|
// Sort publishers based on score
|
||||||
let ranked = publishers.sort((a, b) => b.score - a.score);
|
let ranked = publishers.sort((a, b) => b.finalScore - a.finalScore);
|
||||||
|
|
||||||
// Log the scores and penalties of the top publisher
|
// Log the scores and penalties of the top publisher
|
||||||
if (ranked.length > 0) {
|
if (ranked.length > 0) {
|
||||||
|
@ -625,7 +625,7 @@ export default function CalendarPage({ initialEvents, initialShifts }) {
|
|||||||
async function setAvailabilityBlockDate(AvailabilityBlockDate: Date): Promise<void> {
|
async function setAvailabilityBlockDate(AvailabilityBlockDate: Date): Promise<void> {
|
||||||
// set AvailabilityBlockDate to the selected date
|
// set AvailabilityBlockDate to the selected date
|
||||||
let monthInfo = common.getMonthInfo(value);
|
let monthInfo = common.getMonthInfo(value);
|
||||||
await axiosInstance.put(`/api/?action=settings&key=AvailabilityBlockDate&value=${common.getISODateOnly(monthInfo.lastSunday)}`)
|
await axiosInstance.put(`/api/?action=settings&key=AvailabilityBlockDate&value=${common.getISODateOnly(value)}`)
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
console.log("AvailabilityBlockDate set to:", response.data);
|
console.log("AvailabilityBlockDate set to:", response.data);
|
||||||
// setShifts([...shifts, response.data]);
|
// setShifts([...shifts, response.data]);
|
||||||
@ -703,9 +703,11 @@ export default function CalendarPage({ initialEvents, initialShifts }) {
|
|||||||
<button className="block w-full px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 flex items-center" onClick={() => generateShifts("genEmptyDay", false, false, true)}>
|
<button className="block w-full px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 flex items-center" onClick={() => generateShifts("genEmptyDay", false, false, true)}>
|
||||||
{isLoading('genEmptyDay') ? (<i className="fas fa-sync-alt fa-spin mr-2"></i>) : (<i className="fas fa-plus mr-2"></i>)}
|
{isLoading('genEmptyDay') ? (<i className="fas fa-sync-alt fa-spin mr-2"></i>) : (<i className="fas fa-plus mr-2"></i>)}
|
||||||
създай празни ({value.getDate()}-ти) </button>
|
създай празни ({value.getDate()}-ти) </button>
|
||||||
<button className="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100" onClick={() => generateShifts("genDay", false, true, true)}>
|
|
||||||
|
<button className="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100" onClick={() => generateShifts("genDay", false, true, true, 1)}>
|
||||||
{isLoading('genDay') ? (<i className="fas fa-sync-alt fa-spin mr-2"></i>) : (<i className="fas fa-cogs mr-2"></i>)}
|
{isLoading('genDay') ? (<i className="fas fa-sync-alt fa-spin mr-2"></i>) : (<i className="fas fa-cogs mr-2"></i>)}
|
||||||
Генерирай смени ({value.getDate()}-ти) </button>
|
Генерирай смени ({value.getDate()}-ти) </button>
|
||||||
|
|
||||||
<button className="block px-4 py-2 text-sm text-red-500 hover:bg-gray-100"
|
<button className="block px-4 py-2 text-sm text-red-500 hover:bg-gray-100"
|
||||||
onClick={() => openConfirmModal(
|
onClick={() => openConfirmModal(
|
||||||
'Сигурни ли сте че искате да изтриете смените и назначения на този ден?',
|
'Сигурни ли сте че искате да изтриете смените и назначения на този ден?',
|
||||||
@ -749,7 +751,7 @@ export default function CalendarPage({ initialEvents, initialShifts }) {
|
|||||||
{isLoading('fetchShifts') ? (<i className="fas fa-sync-alt fa-spin mr-2"></i>) : (<i className="fas fa-sync-alt mr-2"></i>)} презареди</button>
|
{isLoading('fetchShifts') ? (<i className="fas fa-sync-alt fa-spin mr-2"></i>) : (<i className="fas fa-sync-alt mr-2"></i>)} презареди</button>
|
||||||
{/* <button className="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100" onClick={generateMonthlyStatistics}><i className="fas fa-chart-bar mr-2"></i> Генерирай статистика</button>
|
{/* <button className="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100" onClick={generateMonthlyStatistics}><i className="fas fa-chart-bar mr-2"></i> Генерирай статистика</button>
|
||||||
<button className="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100" onClick={copyOldAvailabilities}><i className="fas fa-copy mr-2"></i> Прехвърли предпочитанията</button> */}
|
<button className="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100" onClick={copyOldAvailabilities}><i className="fas fa-copy mr-2"></i> Прехвърли предпочитанията</button> */}
|
||||||
<button className="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100" onClick={setAvailabilityBlockDate}><i className="fas fa-copy mr-2"></i> Блокирай предпочитанията до края на {selectedMonth + 1} м.</button>
|
<button className="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100" onClick={setAvailabilityBlockDate}><i className="fas fa-copy mr-2"></i> Блокирай предпочитанията до {value.getDate()}-ти</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
@ -219,7 +219,7 @@ export default function DashboardPage({ initialItems, initialUserId, cartEvents,
|
|||||||
<Layout>
|
<Layout>
|
||||||
<ProtectedRoute allowedRoles={[UserRole.ADMIN, UserRole.POWERUSER, UserRole.USER, UserRole.EXTERNAL]} deniedMessage="">
|
<ProtectedRoute allowedRoles={[UserRole.ADMIN, UserRole.POWERUSER, UserRole.USER, UserRole.EXTERNAL]} deniedMessage="">
|
||||||
<h1 className="pt-2 pb-1 text-xl font-bold text-center">Графика на {userName}</h1>
|
<h1 className="pt-2 pb-1 text-xl font-bold text-center">Графика на {userName}</h1>
|
||||||
<ProtectedRoute allowedRoles={[UserRole.ADMIN]} deniedMessage="">
|
<ProtectedRoute allowedRoles={[UserRole.ADMIN, UserRole.POWERUSER]} deniedMessage="">
|
||||||
<PublisherSearchBox selectedId={userId} infoText="" onChange={handleUserSelection} />
|
<PublisherSearchBox selectedId={userId} infoText="" onChange={handleUserSelection} />
|
||||||
</ProtectedRoute>
|
</ProtectedRoute>
|
||||||
<div className="flex flex-row md:flex-row mt-4 xs:mt-1 space-y-4 md:space-y-0 md:space-x-4 h-[calc(100vh-10rem)]">
|
<div className="flex flex-row md:flex-row mt-4 xs:mt-1 space-y-4 md:space-y-0 md:space-x-4 h-[calc(100vh-10rem)]">
|
||||||
@ -318,7 +318,7 @@ export const getServerSideProps = async (context) => {
|
|||||||
|
|
||||||
if (blockedDate) {
|
if (blockedDate) {
|
||||||
blockedDate.value = new Date(blockedDate.value);
|
blockedDate.value = new Date(blockedDate.value);
|
||||||
lastPublishedDate = lastPublishedDate > blockedDate.value ? lastPublishedDate : blockedDate.value;
|
lastPublishedDate = blockedDate.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
let messages = await prisma.message.findMany({
|
let messages = await prisma.message.findMany({
|
||||||
@ -333,8 +333,9 @@ export const getServerSideProps = async (context) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
messages = messages.filter((message) => {
|
messages = messages.filter((message) => {
|
||||||
return (!message.Survey.publicFrom || message.Survey.publicFrom >= common.getStartOfDay(new Date()))
|
let now = new Date();
|
||||||
&& (!message.Survey.publicUntil || message.Survey.publicUntil <= common.getEndOfDay(new Date()))
|
return (!message.Survey.publicFrom || message.Survey.publicFrom <= common.getStartOfDay(now))
|
||||||
|
&& (!message.Survey.publicUntil || message.Survey.publicUntil >= common.getEndOfDay(now))
|
||||||
});
|
});
|
||||||
messages = common.convertDatesToISOStrings(messages);
|
messages = common.convertDatesToISOStrings(messages);
|
||||||
messages = messages.map(message => {
|
messages = messages.map(message => {
|
||||||
|
@ -49,7 +49,7 @@ const PDFViewerPage = ({ pdfFiles }) => {
|
|||||||
return (
|
return (
|
||||||
<Layout>
|
<Layout>
|
||||||
<h1 className="text-3xl font-bold p-4 pt-8">Разрешителни</h1>
|
<h1 className="text-3xl font-bold p-4 pt-8">Разрешителни</h1>
|
||||||
<ProtectedRoute allowedRoles={[UserRole.ADMIN]} deniedMessage="">
|
<ProtectedRoute allowedRoles={[UserRole.ADMIN, UserRole.POWERUSER]} deniedMessage="">
|
||||||
<div className="border border-blue-500 p-4 rounded shadow-md">
|
<div className="border border-blue-500 p-4 rounded shadow-md">
|
||||||
<div className="mb-6">
|
<div className="mb-6">
|
||||||
<p className="text-lg mb-2">За да качите файл кликнете на бутона по-долу и изберете файл от вашия компютър.</p>
|
<p className="text-lg mb-2">За да качите файл кликнете на бутона по-долу и изберете файл от вашия компютър.</p>
|
||||||
|
BIN
public/content/permits/9- Разрешително за Септември 24г..pdf
Normal file
BIN
public/content/permits/9- Разрешително за Септември 24г..pdf
Normal file
Binary file not shown.
@ -17,7 +17,7 @@ const CREDENTIALS_PATH = path.join(
|
|||||||
);
|
);
|
||||||
|
|
||||||
//generates iCalendar file for a single shift
|
//generates iCalendar file for a single shift
|
||||||
GenerateICS = function (shifts) {
|
const GenerateICS = function (shifts) {
|
||||||
// https://stackoverflow.com/questions/3665115/create-a-file-in-memory-for-user-to-download-not-through-server
|
// https://stackoverflow.com/questions/3665115/create-a-file-in-memory-for-user-to-download-not-through-server
|
||||||
|
|
||||||
var content = "BEGIN:VCALENDAR\n";
|
var content = "BEGIN:VCALENDAR\n";
|
||||||
@ -174,76 +174,76 @@ GenerateICS = function (shifts) {
|
|||||||
// const TOKEN_PATH = path.join(process.cwd(), 'content/token.json');
|
// const TOKEN_PATH = path.join(process.cwd(), 'content/token.json');
|
||||||
// const CREDENTIALS_PATH = path.join(process.cwd(), 'content/client_secret_926212607479-d3m8hm8f8esp3rf1639prskn445sa01v.apps.googleusercontent.com.json');
|
// const CREDENTIALS_PATH = path.join(process.cwd(), 'content/client_secret_926212607479-d3m8hm8f8esp3rf1639prskn445sa01v.apps.googleusercontent.com.json');
|
||||||
|
|
||||||
createEvent = async function createEvent(id) {
|
// const createEvent = async function createEvent(id) {
|
||||||
// var eventTest2 = {
|
// // var eventTest2 = {
|
||||||
// 'summary': 'Google I/O 2015',
|
// // 'summary': 'Google I/O 2015',
|
||||||
// 'location': '800 Howard St., San Francisco, CA 94103',
|
// // 'location': '800 Howard St., San Francisco, CA 94103',
|
||||||
// 'description': 'A chance to hear more about Google\'s developer products.',
|
// // 'description': 'A chance to hear more about Google\'s developer products.',
|
||||||
// 'start': {
|
// // 'start': {
|
||||||
// 'dateTime': '2015-05-28T09:00:00-07:00',
|
// // 'dateTime': '2015-05-28T09:00:00-07:00',
|
||||||
// 'timeZone': 'America/Los_Angeles',
|
// // 'timeZone': 'America/Los_Angeles',
|
||||||
// },
|
// // },
|
||||||
// 'end': {
|
// // 'end': {
|
||||||
// 'dateTime': '2015-05-28T17:00:00-07:00',
|
// // 'dateTime': '2015-05-28T17:00:00-07:00',
|
||||||
// 'timeZone': 'America/Los_Angeles',
|
// // 'timeZone': 'America/Los_Angeles',
|
||||||
// },
|
// // },
|
||||||
// 'recurrence': [
|
// // 'recurrence': [
|
||||||
// 'RRULE:FREQ=DAILY;COUNT=2'
|
// // 'RRULE:FREQ=DAILY;COUNT=2'
|
||||||
// ],
|
// // ],
|
||||||
// 'attendees': [
|
// // 'attendees': [
|
||||||
// { 'email': '' },
|
// // { 'email': '' },
|
||||||
|
|
||||||
// ],
|
// // ],
|
||||||
// 'reminders': {
|
// // 'reminders': {
|
||||||
// 'useDefault': false,
|
// // 'useDefault': false,
|
||||||
// 'overrides': [
|
// // 'overrides': [
|
||||||
// { 'method': 'email', 'minutes': 24 * 60 },
|
// // { 'method': 'email', 'minutes': 24 * 60 },
|
||||||
// { 'method': 'popup', 'minutes': 10 },
|
// // { 'method': 'popup', 'minutes': 10 },
|
||||||
// ],
|
// // ],
|
||||||
// },
|
// // },
|
||||||
// };
|
// // };
|
||||||
// var errors;
|
// // var errors;
|
||||||
// var auth = await exports.authorize().then((auth) => {
|
// // var auth = await exports.authorize().then((auth) => {
|
||||||
|
|
||||||
// const calendar = google.calendar({ version: 'v3', auth });
|
// // const calendar = google.calendar({ version: 'v3', auth });
|
||||||
// const res = calendar.events.insert({
|
// // const res = calendar.events.insert({
|
||||||
// calendarId: 'primary',
|
// // calendarId: 'primary',
|
||||||
// resource: eventTest,
|
// // resource: eventTest,
|
||||||
|
|
||||||
// }, (err, event) => {
|
// // }, (err, event) => {
|
||||||
// if (err) {
|
// // if (err) {
|
||||||
// console.log(`There was an error creating the event: ${err}`);
|
// // console.log(`There was an error creating the event: ${err}`);
|
||||||
// return;
|
// // return;
|
||||||
// }
|
// // }
|
||||||
// console.log(`Event created: ${event.data.htmlLink}`);
|
// // console.log(`Event created: ${event.data.htmlLink}`);
|
||||||
// });
|
// // });
|
||||||
// }).catch(console.error).then((err) => {
|
// // }).catch(console.error).then((err) => {
|
||||||
// errors = err;
|
// // errors = err;
|
||||||
// });
|
// // });
|
||||||
// return errors;
|
// // return errors;
|
||||||
// }
|
// // }
|
||||||
|
|
||||||
// authorizeNew = async function authorizeNew() {
|
// // authorizeNew = async function authorizeNew() {
|
||||||
// let client = await loadSavedCredentialsIfExist();
|
// // let client = await loadSavedCredentialsIfExist();
|
||||||
// if (client) {
|
// // if (client) {
|
||||||
// return client;
|
// // return client;
|
||||||
// }
|
// // }
|
||||||
// // Set up the Google Calendar API client
|
// // // Set up the Google Calendar API client
|
||||||
// const calendar = google.calendar({ version: 'v3', auth });
|
// // const calendar = google.calendar({ version: 'v3', auth });
|
||||||
|
|
||||||
// // Load the client secrets from a JSON file
|
// // // Load the client secrets from a JSON file
|
||||||
|
|
||||||
fs.readFile("./path/to/client_secret.json", (err, content) => {
|
// fs.readFile("./path/to/client_secret.json", (err, content) => {
|
||||||
if (err) return console.error("Error loading client secret file:", err);
|
// if (err) return console.error("Error loading client secret file:", err);
|
||||||
|
|
||||||
// Authorize a client with the loaded credentials
|
// // Authorize a client with the loaded credentials
|
||||||
authorizeOA(JSON.parse(content), calendar.calendarList.list);
|
// authorizeOA(JSON.parse(content), calendar.calendarList.list);
|
||||||
});
|
// });
|
||||||
if (client.credentials) {
|
// if (client.credentials) {
|
||||||
await saveCredentials(client);
|
// await saveCredentials(client);
|
||||||
}
|
// }
|
||||||
return client;
|
// return client;
|
||||||
};
|
// };
|
||||||
|
|
||||||
// var googletoken = axiosInstance.get("/content/google_token.json");
|
// var googletoken = axiosInstance.get("/content/google_token.json");
|
||||||
// console.log("googletoken: " + googletoken);
|
// console.log("googletoken: " + googletoken);
|
||||||
@ -372,7 +372,7 @@ async function importModules() {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
createEvent = async (event) => {
|
const createEvent = async (event) => {
|
||||||
|
|
||||||
const { open, getPort } = await importModules();
|
const { open, getPort } = await importModules();
|
||||||
|
|
||||||
@ -474,7 +474,7 @@ createEvent = async (event) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
SaveEventsInGoogleCalendar = async function SaveEventsInGoogleCalendar(events) {
|
const SaveEventsInGoogleCalendar = async function SaveEventsInGoogleCalendar(events) {
|
||||||
// Load client secrets from a local file.
|
// Load client secrets from a local file.
|
||||||
try {
|
try {
|
||||||
const content = await fs.readFile(CREDENTIALS_PATH);
|
const content = await fs.readFile(CREDENTIALS_PATH);
|
||||||
|
@ -5,7 +5,7 @@ const path = require('path');
|
|||||||
const { MailtrapClient } = require("mailtrap");
|
const { MailtrapClient } = require("mailtrap");
|
||||||
const nodemailer = require("nodemailer");
|
const nodemailer = require("nodemailer");
|
||||||
const CON = require("./const");
|
const CON = require("./const");
|
||||||
const CAL = require("./calendar");
|
const { GenerateICS } = require("./calendar");
|
||||||
const common = require("./common");
|
const common = require("./common");
|
||||||
const Handlebars = require('handlebars');
|
const Handlebars = require('handlebars');
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user