add date filter to assignments

This commit is contained in:
Dobromir Popov
2024-12-28 17:15:47 +02:00
parent 25b53222d4
commit c290b1a37b
4 changed files with 83 additions and 6 deletions

1
.gitignore vendored
View File

@ -37,3 +37,4 @@ public/content/output/shifts 2024.1.json
!public/content/uploads/*
.aider*
/shift_generate_log_*.txt
.env

View File

@ -95,6 +95,7 @@ export default function ReportForm({ shiftId, existingItem, onDone }) {
delete item.shift;
} else {
item.shift = { connect: { id: parseInt(item.shiftId) } };
// item.shift = { connect: { id: item.shiftId.toString() } };
}
delete item.shiftId;
item.date = new Date(item.date);

View File

@ -2,6 +2,7 @@ import { NextApiRequest, NextApiResponse } from 'next';
import { PrismaClient } from '@prisma/client';
import { getServerSession } from "next-auth/next";
import { authOptions } from "../../auth/[...nextauth]";
import e from 'express';
const common = require('../../../../src/helpers/common');
@ -71,10 +72,15 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
if (req.method === 'POST' && req.headers['content-type']?.includes('application/json')) {
// Handle POST request
queryOptions = req.body;
} else {
} else if (req.method === 'GET') {
// Handle GET request
queryOptions = parseQueryParams(req.query);
}
else if (req.method === 'DELETE') {
// Handle DELETE request
queryOptions = req.body;
}
try {
if (!modelArray || modelArray.length === 0) {
@ -84,6 +90,20 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
if (!prisma[modelName]) {
throw new Error(`Model ${modelName} not found in Prisma client.`);
}
if (req.method === 'POST') {
// Create a new record
const result = await prisma[modelName].create({ data: queryOptions });
res.status(201).json(result);
return;
} else if (req.method === 'DELETE') {
// Delete a record
const result = await prisma[modelName].delete({ where: queryOptions });
res.status(200).json(result);
return;
}
// Fetch records
const result = await prisma[modelName].findMany(queryOptions);
if (req.query.format === 'sql') {
// Generate SQL if requested via query parameter

View File

@ -1,6 +1,12 @@
// Next.js page to show all locations in the database with a link to the location page
import { useSession } from "next-auth/react";
import { useEffect, useState, useRef, use } from "react";
import { DatePicker } from '@mui/x-date-pickers/DatePicker';
import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
import { DesktopDatePicker } from '@mui/x-date-pickers/DesktopDatePicker';
import dayjs from 'dayjs';
// import { getSession } from 'next-auth/client'
// import { NextAuth } from 'next-auth/client'
import { Publisher, UserRole } from "@prisma/client";
@ -26,6 +32,7 @@ function PublishersPage({ publishers = [] }: IProps) {
const [filter, setFilter] = useState("");
const [showZeroShiftsOnly, setShowZeroShiftsOnly] = useState(false);
const [selectedDate, setSelectedDate] = useState<dayjs.Dayjs | null>(null);
const [filterIsImported, setFilterIsImported] = useState({
checked: false,
indeterminate: true,
@ -113,10 +120,22 @@ function PublishersPage({ publishers = [] }: IProps) {
// Combine name and email filters, removing duplicates
let filteredPublishers = [...new Set([...filteredPublishersByName, ...filteredPublishersByEmail])];
// inactive publishers filter
filteredPublishers = showZeroShiftsOnly
? filteredPublishers.filter(p => p.assignments.length === 0)
: filteredPublishers;
// Zero shifts (inactive) and date filter
if (showZeroShiftsOnly && selectedDate) {
filteredPublishers = publishers.filter(publisher => {
// If no assignments at all, include in results
if (publisher.assignments.length === 0) return true;
// Only include publishers who don't have any assignments after the selected date
return !publisher.assignments.some(assignment => {
const shiftDate = dayjs(assignment.shift.startTime);
return shiftDate.isAfter(selectedDate);
});
});
} else if (showZeroShiftsOnly) {
// If checkbox is checked but no date selected, show publishers with no assignments
filteredPublishers = publishers.filter(publisher => publisher.assignments.length === 0);
}
// trained filter
if (flterNoTraining) {
@ -124,9 +143,15 @@ function PublishersPage({ publishers = [] }: IProps) {
}
setShownPubs(filteredPublishers);
}, [filter, showZeroShiftsOnly, flterNoTraining]);
}, [filter, showZeroShiftsOnly, selectedDate, flterNoTraining]);
// Separate effect to handle date reset when checkbox is unchecked
useEffect(() => {
if (!showZeroShiftsOnly) {
setSelectedDate(null);
}
}, [showZeroShiftsOnly]);
const renderPublishers = () => {
if (shownPubs.length === 0) {
@ -239,6 +264,36 @@ function PublishersPage({ publishers = [] }: IProps) {
/>
<span className="ml-2">само без смени</span>
</label>
{showZeroShiftsOnly && (
<div className="flex items-center space-x-2 ml-2">
<span className="whitespace-nowrap">след:</span>
<DatePicker
value={selectedDate}
onChange={(newDate) => setSelectedDate(newDate)}
slotProps={{
textField: {
size: "small",
sx: {
width: '140px',
'& .MuiInputBase-input': {
padding: '4px 8px',
fontSize: '0.875rem'
}
}
},
mobileWrapper: {
sx: {
'& .MuiPickersLayout-root': {
minWidth: 'unset'
}
}
}
}}
format="DD.MM.YYYY"
className="min-w-[120px]"
/>
</div>
)}
<label htmlFor="filterTrained" className="ml-4 inline-flex items-center">
<input type="checkbox" id="filterTrained" name="filterTrained"