upgrade stats page
This commit is contained in:
@ -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,
|
||||
},
|
||||
};
|
||||
};
|
||||
|
@ -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);
|
||||
|
Reference in New Issue
Block a user