Added more Responsive to Mobile Device
This commit is contained in:
@@ -2,6 +2,159 @@ import { NextRequest, NextResponse } from 'next/server';
|
||||
import { prisma } from '@/lib/prisma';
|
||||
import { getCurrentUser } from '@/lib/auth';
|
||||
|
||||
// Types de période: day | 7days | 30days | month | quarter | year
|
||||
// Ou plage personnalisée via from & to (format ISO)
|
||||
function getDateRange(period: string | null, from: string | null, to: string | null): {
|
||||
start: Date;
|
||||
end: Date;
|
||||
prevStart: Date;
|
||||
prevEnd: Date;
|
||||
periodLabel: string;
|
||||
} {
|
||||
const now = new Date();
|
||||
const endOfDay = (d: Date) => new Date(d.getFullYear(), d.getMonth(), d.getDate(), 23, 59, 59, 999);
|
||||
const startOfDay = (d: Date) => new Date(d.getFullYear(), d.getMonth(), d.getDate());
|
||||
|
||||
if (from && to) {
|
||||
const start = new Date(from);
|
||||
const end = endOfDay(new Date(to));
|
||||
const diff = end.getTime() - start.getTime();
|
||||
const prevEnd = new Date(start.getTime() - 1);
|
||||
const prevStart = new Date(prevEnd.getTime() - diff);
|
||||
return {
|
||||
start: startOfDay(start),
|
||||
end,
|
||||
prevStart: startOfDay(prevStart),
|
||||
prevEnd: endOfDay(prevEnd),
|
||||
periodLabel: `${start.toLocaleDateString('fr-FR')} - ${new Date(to).toLocaleDateString('fr-FR')}`,
|
||||
};
|
||||
}
|
||||
|
||||
switch (period) {
|
||||
case 'day': {
|
||||
const start = startOfDay(now);
|
||||
const end = endOfDay(now);
|
||||
const yesterday = new Date(now);
|
||||
yesterday.setDate(yesterday.getDate() - 1);
|
||||
return {
|
||||
start,
|
||||
end,
|
||||
prevStart: startOfDay(yesterday),
|
||||
prevEnd: endOfDay(yesterday),
|
||||
periodLabel: "Aujourd'hui",
|
||||
};
|
||||
}
|
||||
case 'yesterday': {
|
||||
const yesterday = new Date(now);
|
||||
yesterday.setDate(yesterday.getDate() - 1);
|
||||
const start = startOfDay(yesterday);
|
||||
const end = endOfDay(yesterday);
|
||||
const dayBefore = new Date(yesterday);
|
||||
dayBefore.setDate(dayBefore.getDate() - 1);
|
||||
return {
|
||||
start,
|
||||
end,
|
||||
prevStart: startOfDay(dayBefore),
|
||||
prevEnd: endOfDay(dayBefore),
|
||||
periodLabel: 'Hier',
|
||||
};
|
||||
}
|
||||
case 'week': {
|
||||
// Cette semaine : lundi à aujourd'hui (ISO week, lundi = 1)
|
||||
const dayOfWeek = now.getDay();
|
||||
const mondayOffset = dayOfWeek === 0 ? -6 : 1 - dayOfWeek;
|
||||
const startOfWeek = new Date(now);
|
||||
startOfWeek.setDate(startOfWeek.getDate() + mondayOffset);
|
||||
const start = startOfDay(startOfWeek);
|
||||
const end = endOfDay(now);
|
||||
const prevWeekStart = new Date(start);
|
||||
prevWeekStart.setDate(prevWeekStart.getDate() - 7);
|
||||
const prevWeekEnd = new Date(start);
|
||||
prevWeekEnd.setDate(prevWeekEnd.getDate() - 1);
|
||||
return {
|
||||
start,
|
||||
end,
|
||||
prevStart: startOfDay(prevWeekStart),
|
||||
prevEnd: endOfDay(prevWeekEnd),
|
||||
periodLabel: 'Cette semaine',
|
||||
};
|
||||
}
|
||||
case '7days': {
|
||||
const start = new Date(now);
|
||||
start.setDate(start.getDate() - 6);
|
||||
const end = endOfDay(now);
|
||||
const prevEnd = new Date(start.getTime() - 1);
|
||||
const prevStart = new Date(prevEnd);
|
||||
prevStart.setDate(prevStart.getDate() - 6);
|
||||
return {
|
||||
start: startOfDay(start),
|
||||
end,
|
||||
prevStart: startOfDay(prevStart),
|
||||
prevEnd: endOfDay(prevEnd),
|
||||
periodLabel: '7 derniers jours',
|
||||
};
|
||||
}
|
||||
case '30days': {
|
||||
const start = new Date(now);
|
||||
start.setDate(start.getDate() - 29);
|
||||
const end = endOfDay(now);
|
||||
const prevEnd = new Date(start.getTime() - 1);
|
||||
const prevStart = new Date(prevEnd);
|
||||
prevStart.setDate(prevStart.getDate() - 29);
|
||||
return {
|
||||
start: startOfDay(start),
|
||||
end,
|
||||
prevStart: startOfDay(prevStart),
|
||||
prevEnd: endOfDay(prevEnd),
|
||||
periodLabel: '30 derniers jours',
|
||||
};
|
||||
}
|
||||
case 'quarter': {
|
||||
const q = Math.floor(now.getMonth() / 3) + 1;
|
||||
const startOfQuarter = new Date(now.getFullYear(), (q - 1) * 3, 1);
|
||||
const endOfQuarter = new Date(now.getFullYear(), q * 3, 0, 23, 59, 59, 999);
|
||||
const prevQuarter = q === 1 ? 4 : q - 1;
|
||||
const prevYear = q === 1 ? now.getFullYear() - 1 : now.getFullYear();
|
||||
const prevStart = new Date(prevYear, (prevQuarter - 1) * 3, 1);
|
||||
const prevEnd = new Date(prevYear, prevQuarter * 3, 0, 23, 59, 59, 999);
|
||||
return {
|
||||
start: startOfQuarter,
|
||||
end: endOfQuarter,
|
||||
prevStart: prevStart,
|
||||
prevEnd: prevEnd,
|
||||
periodLabel: `T${q} ${now.getFullYear()}`,
|
||||
};
|
||||
}
|
||||
case 'year': {
|
||||
const startOfYear = new Date(now.getFullYear(), 0, 1);
|
||||
const endOfYear = new Date(now.getFullYear(), 11, 31, 23, 59, 59, 999);
|
||||
const prevStart = new Date(now.getFullYear() - 1, 0, 1);
|
||||
const prevEnd = new Date(now.getFullYear() - 1, 11, 31, 23, 59, 59, 999);
|
||||
return {
|
||||
start: startOfYear,
|
||||
end: endOfYear,
|
||||
prevStart: prevStart,
|
||||
prevEnd: prevEnd,
|
||||
periodLabel: `Année ${now.getFullYear()}`,
|
||||
};
|
||||
}
|
||||
case 'month':
|
||||
default: {
|
||||
const startOfMonth = new Date(now.getFullYear(), now.getMonth(), 1);
|
||||
const endOfMonth = new Date(now.getFullYear(), now.getMonth() + 1, 0, 23, 59, 59, 999);
|
||||
const startOfLastMonth = new Date(now.getFullYear(), now.getMonth() - 1, 1);
|
||||
const endOfLastMonth = new Date(now.getFullYear(), now.getMonth(), 0, 23, 59, 59, 999);
|
||||
return {
|
||||
start: startOfMonth,
|
||||
end: endOfMonth,
|
||||
prevStart: startOfLastMonth,
|
||||
prevEnd: endOfLastMonth,
|
||||
periodLabel: 'Mois en cours',
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// GET - Récupérer les statistiques du dashboard
|
||||
export async function GET(request: NextRequest) {
|
||||
try {
|
||||
@@ -10,26 +163,20 @@ export async function GET(request: NextRequest) {
|
||||
return NextResponse.json({ error: 'Non autorisé' }, { status: 401 });
|
||||
}
|
||||
|
||||
const now = new Date();
|
||||
const startOfToday = new Date(now.getFullYear(), now.getMonth(), now.getDate());
|
||||
const endOfToday = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 23, 59, 59, 999);
|
||||
|
||||
const startOfMonth = new Date(now.getFullYear(), now.getMonth(), 1);
|
||||
const endOfMonth = new Date(now.getFullYear(), now.getMonth() + 1, 0, 23, 59, 59, 999);
|
||||
|
||||
const startOfLastMonth = new Date(now.getFullYear(), now.getMonth() - 1, 1);
|
||||
const endOfLastMonth = new Date(now.getFullYear(), now.getMonth(), 0, 23, 59, 59, 999);
|
||||
|
||||
const startOfYesterday = new Date(now.getFullYear(), now.getMonth(), now.getDate() - 1);
|
||||
const endOfYesterday = new Date(now.getFullYear(), now.getMonth(), now.getDate() - 1, 23, 59, 59, 999);
|
||||
const { searchParams } = new URL(request.url);
|
||||
const period = searchParams.get('period') || 'month';
|
||||
const from = searchParams.get('from');
|
||||
const to = searchParams.get('to');
|
||||
|
||||
// 1. Participations du mois (trajets validés/terminés ce mois)
|
||||
const { start, end, prevStart, prevEnd, periodLabel } = getDateRange(period, from, to);
|
||||
|
||||
// 1. Participations sur la période (trajets validés/terminés)
|
||||
const participationsMoisData = await prisma.participationFinanciere.findMany({
|
||||
where: {
|
||||
trajet: {
|
||||
date: {
|
||||
gte: startOfMonth,
|
||||
lte: endOfMonth,
|
||||
gte: start,
|
||||
lte: end,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -44,57 +191,57 @@ export async function GET(request: NextRequest) {
|
||||
);
|
||||
const nombreFactures = participationsCeMois.length;
|
||||
|
||||
// 2. Trajets aujourd'hui
|
||||
const trajetsAujourdhui = await prisma.trajet.count({
|
||||
// 2. Trajets sur la période
|
||||
const trajetsPeriode = await prisma.trajet.count({
|
||||
where: {
|
||||
archived: false,
|
||||
date: {
|
||||
gte: startOfToday,
|
||||
lte: endOfToday,
|
||||
gte: start,
|
||||
lte: end,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
// Trajets hier pour comparaison
|
||||
const trajetsHier = await prisma.trajet.count({
|
||||
// Trajets période précédente pour comparaison
|
||||
const trajetsPeriodePrecedente = await prisma.trajet.count({
|
||||
where: {
|
||||
archived: false,
|
||||
date: {
|
||||
gte: startOfYesterday,
|
||||
lte: endOfYesterday,
|
||||
gte: prevStart,
|
||||
lte: prevEnd,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const differenceAujourdhui = trajetsAujourdhui - trajetsHier;
|
||||
const differenceTrajets = trajetsPeriode - trajetsPeriodePrecedente;
|
||||
|
||||
// 3. Trajets réalisés ce mois (terminés)
|
||||
const trajetsRealisesMois = await prisma.trajet.count({
|
||||
// 3. Trajets réalisés sur la période (terminés)
|
||||
const trajetsRealisesPeriode = await prisma.trajet.count({
|
||||
where: {
|
||||
archived: false,
|
||||
statut: 'Terminé',
|
||||
date: {
|
||||
gte: startOfMonth,
|
||||
lte: endOfMonth,
|
||||
gte: start,
|
||||
lte: end,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
// Trajets réalisés le mois dernier pour comparaison
|
||||
const trajetsRealisesMoisDernier = await prisma.trajet.count({
|
||||
// Trajets réalisés période précédente pour comparaison
|
||||
const trajetsRealisesPeriodePrecedente = await prisma.trajet.count({
|
||||
where: {
|
||||
archived: false,
|
||||
statut: 'Terminé',
|
||||
date: {
|
||||
gte: startOfLastMonth,
|
||||
lte: endOfLastMonth,
|
||||
gte: prevStart,
|
||||
lte: prevEnd,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const pourcentageEvolution = trajetsRealisesMoisDernier > 0
|
||||
? Math.round(((trajetsRealisesMois - trajetsRealisesMoisDernier) / trajetsRealisesMoisDernier) * 100)
|
||||
: trajetsRealisesMois > 0 ? 100 : 0;
|
||||
const pourcentageEvolution = trajetsRealisesPeriodePrecedente > 0
|
||||
? Math.round(((trajetsRealisesPeriode - trajetsRealisesPeriodePrecedente) / trajetsRealisesPeriodePrecedente) * 100)
|
||||
: trajetsRealisesPeriode > 0 ? 100 : 0;
|
||||
|
||||
// 4. Chauffeurs actifs (disponibles)
|
||||
const totalChauffeurs = await prisma.chauffeur.count();
|
||||
@@ -105,16 +252,17 @@ export async function GET(request: NextRequest) {
|
||||
});
|
||||
|
||||
return NextResponse.json({
|
||||
periodLabel,
|
||||
participationsMois: {
|
||||
montant: participationsMois,
|
||||
nombreFactures: nombreFactures,
|
||||
},
|
||||
trajetsAujourdhui: {
|
||||
nombre: trajetsAujourdhui,
|
||||
difference: differenceAujourdhui,
|
||||
nombre: trajetsPeriode,
|
||||
difference: differenceTrajets,
|
||||
},
|
||||
trajetsRealisesMois: {
|
||||
nombre: trajetsRealisesMois,
|
||||
nombre: trajetsRealisesPeriode,
|
||||
pourcentageEvolution: pourcentageEvolution,
|
||||
},
|
||||
chauffeursActifs: {
|
||||
|
||||
@@ -18,7 +18,7 @@ export default async function CalendrierPage() {
|
||||
|
||||
return (
|
||||
<DashboardLayout user={user}>
|
||||
<div className="p-4 sm:p-6 lg:p-8">
|
||||
<div className="px-3 py-4 sm:p-6 lg:p-8 min-w-0 overflow-x-hidden">
|
||||
<CalendrierPageContent />
|
||||
</div>
|
||||
</DashboardLayout>
|
||||
|
||||
@@ -12,8 +12,8 @@ const poppins = Poppins({
|
||||
});
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "Platform SaaS",
|
||||
description: "Plateforme SaaS",
|
||||
title: "MAD - BackOffice",
|
||||
description: "MAD",
|
||||
icons: {
|
||||
icon: "/logo.svg",
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user