upgrade stats page

This commit is contained in:
Dobromir Popov
2024-04-13 20:29:47 +03:00
parent 7eeb55af88
commit f510090323
2 changed files with 129 additions and 24 deletions

View File

@ -1,7 +1,7 @@
import { useState } from 'react';
import Layout from "../../../components/layout";
import ProtectedRoute from '../../../components/protectedRoute';
import { UserRole } from '@prisma/client';
import { Prisma, UserRole } from '@prisma/client';
import axiosServer from '../../../src/axiosServer';
import common from '../../../src/helpers/common';
// import { filterPublishers, /* other functions */ } from '../../api/index';
@ -9,10 +9,10 @@ import data from '../../../src/helpers/data';
// const data = require('../../src/helpers/data');
function ContactsPage({ publishers }) {
function ContactsPage({ publishers, allPublishers }) {
const [searchQuery, setSearchQuery] = useState('');
const filteredPublishers = publishers.filter((publisher) =>
const filteredPublishers = allPublishers.filter((publisher) =>
publisher.firstName.toLowerCase().includes(searchQuery.toLowerCase()) ||
publisher.lastName.toLowerCase().includes(searchQuery.toLowerCase()) ||
publisher.email.toLowerCase().includes(searchQuery.toLowerCase()) ||
@ -24,7 +24,7 @@ function ContactsPage({ publishers }) {
<ProtectedRoute allowedRoles={[UserRole.ADMIN, UserRole.POWERUSER, UserRole.USER]}>
<div className="container mx-auto p-4">
<h1 className="text-xl font-semibold mb-4">Статистика </h1>
<h5 className="text-lg font-semibold mb-4">{publishers.length} участника с предпочитания</h5>
<h5 className="text-lg font-semibold mb-4">{publishers.length} участника с предпочитания (от {allPublishers.length} )</h5>
<input
type="text"
placeholder="Търси по име, имейл или телефон..."
@ -42,26 +42,55 @@ function ContactsPage({ publishers }) {
</tr>
</thead>
<tbody>
{filteredPublishers.map((pub) => (
<tr key={pub.id}>
<td className="border-b p-4 pl-8" title={pub.lastUpdate}>{pub.firstName} {pub.lastName}</td>
<td className="border-b p-4">
<span title="Възможност: часове | дни" className={`badge py-1 px-2 rounded-md text-xs ${pub.currentMonthAvailabilityHoursCount || pub.currentMonthAvailabilityDaysCount ? 'bg-teal-500 text-white' : 'bg-teal-200 text-gray-300'} hover:underline`} >
{pub.currentMonthAvailabilityDaysCount || 0} | {pub.currentMonthAvailabilityHoursCount || 0}
</span>
</td>
<td className="border-b p-4">
<div className="flex items-center justify-between">
<div className="flex items-center">
<span title="участия тази седмица" className={`badge py-1 px-2 rounded-full text-xs ${pub.currentWeekAssignments ? 'bg-yellow-500 text-white' : 'bg-yellow-200 text-gray-400'}`}>{pub.currentWeekAssignments || 0}</span>
<span title="участия този месец" className={`badge py-1 px-2 rounded-full text-xs ${pub.currentMonthAssignments ? 'bg-green-500 text-white' : 'bg-green-200 text-gray-400'}`}>{pub.currentMonthAssignments || 0}</span>
<span tooltip="участия миналия месец" title="участия миналия месец" className={`badge py-1 px-2 rounded-full text-xs ${pub.previousMonthAssignments ? 'bg-blue-500 text-white' : 'bg-blue-200 text-gray-400'}`}>{pub.previousMonthAssignments || 0}</span>
<button tooltip="желани участия този месец" title="желани участия" className={`badge py-1 px-2 rounded-md text-xs ${pub.desiredShiftsPerMonth ? 'bg-purple-500 text-white' : 'bg-purple-200 text-gray-400'}`}>{pub.desiredShiftsPerMonth || 0}</button>
</div>
</div>
</td>
</tr>
))}
{filteredPublishers.map((allPub) => {
// Find the publisher in the publishers collection to access statistics
const pub = publishers.find(publisher => publisher.id === allPub.id);
return (
<tr key={allPub.id}>
<td className="border-b p-4 pl-8" title={allPub.lastUpdate}>{allPub.firstName} {allPub.lastName}</td>
{/* Display statistics if publisher is found */}
{pub ? (
<>
<td className="border-b p-4">
<span title="Възможност: часове | дни" className={`badge py-1 px-2 rounded-md text-xs ${pub.currentMonthAvailabilityHoursCount || pub.currentMonthAvailabilityDaysCount ? 'bg-teal-500 text-white' : 'bg-teal-200 text-gray-300'} hover:underline`}>
{pub.currentMonthAvailabilityDaysCount || 0} | {pub.currentMonthAvailabilityHoursCount || 0}
</span>
</td>
<td className="border-b p-4">
<div className="flex items-center justify-between">
<div className="flex items-center">
<span title="участия тази седмица" className={`badge py-1 px-2 rounded-full text-xs ${pub.currentWeekAssignments ? 'bg-yellow-500 text-white' : 'bg-yellow-200 text-gray-400'}`}>{pub.currentWeekAssignments || 0}</span>
<span title="участия този месец" className={`badge py-1 px-2 rounded-full text-xs ${pub.currentMonthAssignments ? 'bg-green-500 text-white' : 'bg-green-200 text-gray-400'}`}>{pub.currentMonthAssignments || 0}</span>
<span title="участия миналия месец" className={`badge py-1 px-2 rounded-full text-xs ${pub.previousMonthAssignments ? 'bg-blue-500 text-white' : 'bg-blue-200 text-gray-400'}`}>{pub.previousMonthAssignments || 0}</span>
<button title="желани участия" className={`badge py-1 px-2 rounded-md text-xs ${pub.desiredShiftsPerMonth ? 'bg-purple-500 text-white' : 'bg-purple-200 text-gray-400'}`}>{pub.desiredShiftsPerMonth || 0}</button>
</div>
</div>
</td>
</>
) : (
<>
<td className="border-b p-4">
</td>
<td className="border-b p-4">
<div className="flex items-center justify-between">
<div className="flex items-center">
<span className="badge py-1 px-2 rounded-md text-xs bg-gray-300 text-gray-500" title="участия този месец">
{allPub.currentMonthAssignments || 0}
</span>
<span className="badge py-1 px-2 rounded-md text-xs bg-gray-300 text-gray-500" title="участия миналия месец">
{allPub.previousMonthAssignments || 0}
</span>
</div>
</div>
</td>
<td className="border-b p-4"></td> {/* Empty cell for alignment */}
</>
)}
</tr>
);
})}
</tbody>
</table>
</div>
@ -74,7 +103,26 @@ function ContactsPage({ publishers }) {
export default ContactsPage;
// Helper functions ToDo: move them to common and replace all implementations with the common ones
function countAssignments(assignments, startTime, endTime) {
return assignments.filter(assignment =>
assignment.shift.startTime >= startTime && assignment.shift.startTime <= endTime
).length;
}
function convertShiftDates(assignments) {
assignments.forEach(assignment => {
if (assignment.shift && assignment.shift.startTime) {
assignment.shift.startTime = new Date(assignment.shift.startTime).toISOString();
assignment.shift.endTime = new Date(assignment.shift.endTime).toISOString();
}
});
}
export const getServerSideProps = async (context) => {
const prisma = common.getPrismaClient();
const dateStr = new Date().toISOString().split('T')[0];
let publishers = await data.filterPublishersNew('id,firstName,lastName,email,isActive,desiredShiftsPerMonth', dateStr, false, true, true);
@ -118,9 +166,65 @@ export const getServerSideProps = async (context) => {
//remove publishers without availabilities
publishers = publishers.filter(publisher => publisher.availabilities.length > 0);
let allPublishers = await prisma.publisher.findMany({
select: {
id: true,
firstName: true,
lastName: true,
email: true,
phone: true,
isActive: true,
desiredShiftsPerMonth: true,
assignments: {
select: {
id: true,
shift: {
select: {
startTime: true,
endTime: true,
},
},
},
},
},
});
let monthInfo,
currentMonthStart, currentMonthEnd,
previousMonthStart, previousMonthEnd;
monthInfo = common.getMonthDatesInfo(new Date());
currentMonthStart = monthInfo.firstMonday;
currentMonthEnd = monthInfo.lastSunday;
let prevMnt = new Date();
prevMnt.setMonth(prevMnt.getMonth() - 1);
monthInfo = common.getMonthDatesInfo(prevMnt);
previousMonthStart = monthInfo.firstMonday;
previousMonthEnd = monthInfo.lastSunday;
allPublishers.forEach(publisher => {
// Use helper functions to calculate and assign assignment counts
publisher.currentMonthAssignments = countAssignments(publisher.assignments, currentMonthStart, currentMonthEnd);
publisher.previousMonthAssignments = countAssignments(publisher.assignments, previousMonthStart, previousMonthEnd);
// Convert date formats within the same iteration
convertShiftDates(publisher.assignments);
});
// Optionally, if you need a transformed list or additional properties, map the publishers
allPublishers = allPublishers.map(publisher => ({
...publisher,
// Potentially add more computed properties or transformations here if needed
}));
return {
props: {
publishers,
allPublishers,
},
};
};

View File

@ -482,6 +482,7 @@ async function filterPublishersNew(selectFields, filterDate, isExactTime = false
}
function matchesAvailability(avail, filterDate) {
// Setting the start and end time of the filterDate
filterDate.setHours(0, 0, 0, 0);