This commit is contained in:
2025-12-24 14:48:49 +01:00
parent c6793e2473
commit 9beb6e1b43
20 changed files with 1777 additions and 508 deletions
@@ -0,0 +1,20 @@
<?php
header('Content-Type: application/json');
require __DIR__ . '/../includes/db.php';
try {
$stmt = $pdo->query("SELECT id, event_date AS date, event_type AS type, person_id, duration FROM pf_events ORDER BY event_date");
$events = $stmt->fetchAll(PDO::FETCH_ASSOC);
echo json_encode([
'status' => 'success',
'events' => $events,
]);
} catch (Exception $e) {
http_response_code(500);
echo json_encode([
'status' => 'error',
'message' => 'Erreur lors de la récupération des événements : ' . $e->getMessage(),
]);
}
@@ -0,0 +1,31 @@
<?php
// api/get-leaves.php
header('Content-Type: application/json');
require __DIR__ . '/../includes/db.php';
try {
$stmt = $pdo->query("
SELECT
l.id,
l.person_id,
p.name AS person_name,
l.leave_type,
l.leave_date,
l.duration
FROM pf_leaves l
JOIN pf_people p ON p.id = l.person_id
ORDER BY l.leave_date, l.person_id
");
$leaves = $stmt->fetchAll(PDO::FETCH_ASSOC);
echo json_encode([
'status' => 'success',
'leaves' => $leaves,
]);
} catch (PDOException $e) {
http_response_code(500);
echo json_encode(['status' => 'error', 'message' => $e->getMessage()]);
}
@@ -0,0 +1,103 @@
<?php
header('Content-Type: application/json');
require __DIR__ . '/../includes/db.php';
$input = json_decode(file_get_contents('php://input'), true);
if (!isset($input['action'])) {
http_response_code(400);
echo json_encode(['status' => 'error', 'message' => 'Action manquante.']);
exit;
}
$action = $input['action'];
try {
if ($action === 'delete') {
// Suppression d'un seul événement
if (!isset($input['event_id'])) {
http_response_code(400);
echo json_encode(['status' => 'error', 'message' => 'ID manquant pour la suppression.']);
exit;
}
$eventId = (int)$input['event_id'];
$stmt = $pdo->prepare("DELETE FROM pf_events WHERE id = ?");
$stmt->execute([$eventId]);
echo json_encode(['status' => 'success', 'message' => 'Événement supprimé.']);
} elseif ($action === 'update') {
// Mise à jour d'un seul événement
if (!isset($input['event_id'], $input['new_type'])) {
http_response_code(400);
echo json_encode(['status' => 'error', 'message' => 'ID ou nouveau type manquant pour la mise à jour.']);
exit;
}
$eventId = (int)$input['event_id'];
$newType = $input['new_type'];
$stmt = $pdo->prepare("UPDATE pf_events SET event_type = ? WHERE id = ?");
$stmt->execute([$newType, $eventId]);
echo json_encode(['status' => 'success', 'message' => 'Événement mis à jour.']);
} elseif ($action === 'bulk_delete') {
// Suppression en masse
if (empty($input['event_ids']) || !is_array($input['event_ids'])) {
http_response_code(400);
echo json_encode(['status' => 'error', 'message' => 'Liste event_ids manquante pour bulk_delete.']);
exit;
}
$eventIds = array_map('intval', $input['event_ids']);
$eventIds = array_filter($eventIds, fn($id) => $id > 0);
if (empty($eventIds)) {
http_response_code(400);
echo json_encode(['status' => 'error', 'message' => 'Aucun ID valide pour bulk_delete.']);
exit;
}
$placeholders = implode(',', array_fill(0, count($eventIds), '?'));
$stmt = $pdo->prepare("DELETE FROM pf_events WHERE id IN ($placeholders)");
$stmt->execute($eventIds);
echo json_encode(['status' => 'success', 'message' => 'Événements supprimés en masse.']);
} elseif ($action === 'bulk_update') {
// Mise à jour en masse
if (empty($input['event_ids']) || !is_array($input['event_ids']) || !isset($input['new_type'])) {
http_response_code(400);
echo json_encode(['status' => 'error', 'message' => 'event_ids ou new_type manquant pour bulk_update.']);
exit;
}
$eventIds = array_map('intval', $input['event_ids']);
$eventIds = array_filter($eventIds, fn($id) => $id > 0);
$newType = $input['new_type'];
if (empty($eventIds)) {
http_response_code(400);
echo json_encode(['status' => 'error', 'message' => 'Aucun ID valide pour bulk_update.']);
exit;
}
$placeholders = implode(',', array_fill(0, count($eventIds), '?'));
$params = array_merge([$newType], $eventIds);
$stmt = $pdo->prepare("UPDATE pf_events SET event_type = ? WHERE id IN ($placeholders)");
$stmt->execute($params);
echo json_encode(['status' => 'success', 'message' => 'Événements mis à jour en masse.']);
} else {
http_response_code(400);
echo json_encode(['status' => 'error', 'message' => 'Action non valide.']);
}
} catch (PDOException $e) {
http_response_code(500);
echo json_encode(['status' => 'error', 'message' => $e->getMessage()]);
}
@@ -0,0 +1,45 @@
<?php
// api/manage-leaf.php
header('Content-Type: application/json');
require __DIR__ . '/../includes/db.php';
$input = json_decode(file_get_contents('php://input'), true);
if (!isset($input['action'])) {
http_response_code(400);
echo json_encode(['status' => 'error', 'message' => 'Action manquante.']);
exit;
}
$action = $input['action'];
try {
if ($action === 'delete_day') {
if (empty($input['date'])) {
http_response_code(400);
echo json_encode(['status' => 'error', 'message' => 'Date manquante pour delete_day.']);
exit;
}
$dateObj = date_create($input['date']);
if (!$dateObj) {
http_response_code(400);
echo json_encode(['status' => 'error', 'message' => 'Date invalide.']);
exit;
}
$leaveDate = $dateObj->format('Y-m-d');
$stmt = $pdo->prepare("DELETE FROM pf_leaves WHERE leave_date = ?");
$stmt->execute([$leaveDate]);
echo json_encode(['status' => 'success', 'message' => 'Congés supprimés pour ce jour.']);
} else {
http_response_code(400);
echo json_encode(['status' => 'error', 'message' => 'Action non valide.']);
}
} catch (PDOException $e) {
http_response_code(500);
echo json_encode(['status' => 'error', 'message' => $e->getMessage()]);
}
@@ -0,0 +1,62 @@
<?php
header('Content-Type: application/json');
require __DIR__ . '/../includes/db.php';
$eventsToSave = json_decode(file_get_contents('php://input'), true);
if (empty($eventsToSave) || !is_array($eventsToSave)) {
http_response_code(400);
echo json_encode(['status' => 'error', 'message' => 'Aucune donnée d\'événement reçue.']);
exit;
}
$inserted = [];
try {
$pdo->beginTransaction();
$sql = "INSERT INTO pf_events (event_date, event_type, person_id, duration)
VALUES (:event_date, :event_type, :person_id, :duration)";
$stmt = $pdo->prepare($sql);
foreach ($eventsToSave as $event) {
$person_id = null;
// Si un nom de personne est fourni
if (!empty($event['person'])) {
$personStmt = $pdo->prepare("SELECT id FROM pf_people WHERE name = ?");
$personStmt->execute([$event['person']]);
$personRow = $personStmt->fetch();
if ($personRow) {
$person_id = $personRow['id'];
}
}
$stmt->execute([
':event_date' => $event['date'],
':event_type' => $event['type'],
':person_id' => $person_id,
':duration' => $event['duration'] ?? 1.0,
]);
$inserted[] = [
'id' => $pdo->lastInsertId(),
'date' => $event['date'],
'type' => $event['type'],
'duration' => $event['duration'] ?? 1.0,
'person_id' => $person_id,
];
}
$pdo->commit();
echo json_encode([
'status' => 'success',
'inserted' => $inserted,
]);
} catch (Exception $e) {
$pdo->rollBack();
http_response_code(500);
echo json_encode(['status' => 'error', 'message' => 'Erreur lors de la sauvegarde : ' . $e->getMessage()]);
}
@@ -0,0 +1,68 @@
<?php
// api/save-leaves.php
header('Content-Type: application/json');
require __DIR__ . '/../includes/db.php';
$input = json_decode(file_get_contents('php://input'), true);
if (!is_array($input) || empty($input)) {
http_response_code(400);
echo json_encode(['status' => 'error', 'message' => 'Données invalides (attendu tableau JSON).']);
exit;
}
// Exemple d'élément attendu :
// { date: '2025-09-01', person_id: 2, leave_type: 'CP', duration: 1.0 }
$validLeaveTypes = ['CP', 'JRA', 'JA'];
try {
$pdo->beginTransaction();
$stmtInsert = $pdo->prepare("
INSERT INTO pf_leaves (person_id, leave_type, leave_date, duration)
VALUES (:person_id, :leave_type, :leave_date, :duration)
");
foreach ($input as $item) {
$date = $item['date'] ?? null;
$personId = $item['person_id'] ?? null;
$leaveType = $item['leave_type'] ?? null;
$duration = isset($item['duration']) ? (float)$item['duration'] : 1.0;
if (!$date || !$personId || !$leaveType) {
continue; // on ignore les lignes incomplètes
}
if (!in_array($leaveType, $validLeaveTypes, true)) {
continue; // leave_type invalide
}
// Normalisation de la date
$dateObj = date_create($date);
if (!$dateObj) {
continue;
}
$leaveDate = $dateObj->format('Y-m-d');
$stmtInsert->execute([
':person_id' => (int)$personId,
':leave_type' => $leaveType,
':leave_date' => $leaveDate,
':duration' => $duration,
]);
}
$pdo->commit();
echo json_encode([
'status' => 'success',
'message' => 'Congés enregistrés.',
]);
} catch (PDOException $e) {
$pdo->rollBack();
http_response_code(500);
echo json_encode(['status' => 'error', 'message' => $e->getMessage()]);
}
+726
View File
@@ -0,0 +1,726 @@
/* === TABLES SPÉCIFIQUES AU FAMILY CALENDAR === */
/* Tableau des vacances scolaires */
#schoolHolidaysTable {
width: auto;
table-layout: auto;
border-collapse: collapse;
}
.pf-card.pf-card--wide .pf-table-wrapper {
width: 100%;
overflow-x: auto;
}
/* En-têtes et cellules sans retour à la ligne */
#schoolHolidaysTable th,
#schoolHolidaysTable td {
white-space: nowrap;
overflow: visible;
padding: 4px 8px;
text-align: center;
}
/* Planning hebdomadaire principal */
#planningTable {
table-layout: fixed;
width: 100%;
}
#planningTable th,
#planningTable td {
text-align: center;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
/* Colonnes "Mois" et "Semaine" plus étroites */
#planningTable th:nth-child(1),
#planningTable td:nth-child(1),
#planningTable th:nth-child(2),
#planningTable td:nth-child(2) {
width: 2%;
}
/* Colonnes jours (Lundi à Vendredi) */
#planningTable th:nth-child(3),
#planningTable td:nth-child(3),
#planningTable th:nth-child(4),
#planningTable td:nth-child(4),
#planningTable th:nth-child(5),
#planningTable td:nth-child(5),
#planningTable th:nth-child(6),
#planningTable td:nth-child(6),
#planningTable th:nth-child(7),
#planningTable td:nth-child(7) {
width: 2%;
}
/* Colonnes de totaux */
#planningTable th:nth-child(8),
#planningTable td:nth-child(8),
#planningTable th:nth-child(9),
#planningTable td:nth-child(9),
#planningTable th:nth-child(10),
#planningTable td:nth-child(10),
#planningTable th:nth-child(11),
#planningTable td:nth-child(11) {
width: 4%;
}
/* === COLOR CODING / LÉGENDE === */
.fc-row--carole-off {
background: #ffe0e0;
}
.fc-row--bank-holiday {
background: #d9f7be;
}
/* Tableau recap vacances scolaires */
.fc-holidays-table {
width: 100%;
border-collapse: collapse;
font-size: 12px;
margin-top: 8px;
}
.fc-holidays-table th,
.fc-holidays-table td {
border: none;
padding: 4px 4px;
}
.fc-holidays-table thead th {
background: none;
font-weight: 600;
color: #243b53;
padding-bottom: 4px;
border-bottom: 1px solid #d9e2ec;
}
.fc-holidays-table tbody tr:nth-child(odd) td {
background: #f8fafc;
}
.fc-holidays-table tbody tr:nth-child(even) td {
background: transparent;
}
/* Cellule de jour sélectionnée dans le calendrier */
.fc-day--selected {
background-color: #bde4ff !important;
cursor: pointer;
}
/* Le menu contextuel flottant */
.fc-selection-menu {
display: none;
position: absolute;
z-index: 100;
background-color: white;
border: 1px solid #ccc;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
border-radius: 6px;
padding: 8px;
font-size: 12px;
}
.fc-selection-menu .fc-menu-section {
margin-bottom: 8px;
}
.fc-selection-menu .fc-menu-section:last-child {
margin-bottom: 0;
}
.fc-selection-menu strong {
display: block;
margin-bottom: 4px;
font-weight: 600;
}
.fc-selection-menu button {
display: block;
width: 100%;
background: none;
border: 1px solid #ddd;
border-radius: 4px;
padding: 4px 8px;
margin-top: 4px;
text-align: left;
cursor: pointer;
}
.fc-selection-menu button:hover {
background-color: #f0f4f8;
border-color: #b0c4de;
}
/* --- Couleurs de base pour la légende et les jours --- */
.fc-day--school-holiday {
background-color: #e5d9f2;
}
.fc-day--public-holiday {
background-color: #e0e0e0;
}
.fc-day--off-carole {
background-color: #ffe9a7;
}
.fc-day--extra-off-carole {
background-color: #ffd59b;
}
.fc-day--has-guard {
box-sizing: border-box;
}
/* Picto pour Centre */
.fc-day--has-guard.fc-day--centre {
position: relative;
}
.fc-day--has-guard.fc-day--centre::after {
content: "🏫";
position: absolute;
top: 2px;
right: 2px;
font-size: 14px;
line-height: 1;
z-index: 2;
}
/* Combinaisons avec dégradés */
.fc-day--school-holiday.fc-day--off-carole {
background-image: linear-gradient(45deg, #e5d9f2 49%, #ffe9a7 51%);
}
.fc-day--school-holiday.fc-day--extra-off-carole {
background-image: linear-gradient(45deg, #e5d9f2 49%, #ffd59b 51%);
}
/* Légende */
.pf-legend-item {
display: flex;
align-items: center;
margin-bottom: 5px;
}
.pf-legend-color {
width: 18px;
height: 18px;
border-radius: 4px;
border: 1px solid #d9e2ec;
margin-right: 8px;
}
.pf-legend-item span {
font-size: 12px;
color: #334e68;
}
.fc-legend-school-holiday {
background-color: #e5d9f2;
}
.fc-legend-public-holiday {
background-color: #e0e0e0;
}
.fc-legend-off-carole {
background-color: #ffe9a7;
}
.fc-legend-extra-off-carole {
background-color: #ffd59b;
}
.fc-legend-centre {
display: flex;
justify-content: center;
align-items: center;
font-size: 16px;
background: none;
border: none;
}
.fc-legend-centre::before {
content: "🏫";
}
/* Avis indicateur */
.fc-legend-avis {
border-radius: 2px;
width: 24px;
height: 16px;
background: linear-gradient(
to bottom,
#ffcc00 0%,
#ffcc00 11%,
#c8102e 11%,
#c8102e 22%,
#ffcc00 22%,
#ffcc00 33%,
#c8102e 33%,
#c8102e 44%,
#ffcc00 44%,
#ffcc00 55%,
#c8102e 55%,
#c8102e 66%,
#ffcc00 66%,
#ffcc00 77%,
#c8102e 77%,
#c8102e 88%,
#ffcc00 88%,
#ffcc00 100%
);
box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.2);
}
/* === CALENDRIER MENSUEL === */
.fc-day--has-guard.fc-day--avis {
position: relative;
}
.fc-day--has-guard.fc-day--avis::after {
content: "";
position: absolute;
top: 2px;
right: 2px;
width: 14px;
height: 8px;
border-radius: 2px;
background: linear-gradient(
to bottom,
#ffcc00 0%,
#ffcc00 11%,
#c8102e 11%,
#c8102e 22%,
#ffcc00 22%,
#ffcc00 33%,
#c8102e 33%,
#c8102e 44%,
#ffcc00 44%,
#ffcc00 55%,
#c8102e 55%,
#c8102e 66%,
#ffcc00 66%,
#ffcc00 77%,
#c8102e 77%,
#c8102e 88%,
#ffcc00 88%,
#ffcc00 100%
);
box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.2);
z-index: 2;
}
.fc-month-calendar-wrapper {
background: #fff;
border-radius: 8px;
padding: 16px;
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.08);
border: 1px solid #d9e2ec;
}
.fc-calendar-and-summary {
display: block;
}
.fc-month-header {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 16px;
padding-bottom: 12px;
border-bottom: 2px solid #d9e2ec;
flex-wrap: wrap;
gap: 12px;
}
.fc-view-controls {
display: flex;
gap: 8px;
}
.fc-view-button {
background: #f0f4f8;
border: 1px solid #d9e2ec;
border-radius: 4px;
padding: 6px 12px;
font-size: 13px;
cursor: pointer;
color: #243b53;
transition: all 0.2s;
}
.fc-view-button:hover {
background: #d9e2ec;
border-color: #bcccdc;
}
.fc-view-button--active {
background: #243b53;
color: #fff;
border-color: #243b53;
}
.fc-view-button--active:hover {
background: #102a43;
border-color: #102a43;
}
.fc-nav-controls {
display: flex;
align-items: center;
gap: 12px;
}
.fc-month-header h3 {
margin: 0;
font-size: 18px;
font-weight: 600;
color: #243b53;
min-width: 200px;
text-align: center;
}
.fc-nav-button {
background: #f0f4f8;
border: 1px solid #d9e2ec;
border-radius: 4px;
padding: 6px 12px;
font-size: 18px;
cursor: pointer;
color: #243b53;
transition: all 0.2s;
}
.fc-nav-button:hover {
background: #d9e2ec;
border-color: #bcccdc;
}
.fc-month-calendar {
width: 100%;
}
.fc-month-table {
width: 100%;
border-collapse: collapse;
font-size: 13px;
}
.fc-month-table thead th {
background: #f0f4f8;
padding: 8px 4px;
text-align: center;
font-weight: 600;
color: #243b53;
border: 1px solid #d9e2ec;
}
.fc-month-table tbody td {
border: 1px solid #d9e2ec;
padding: 8px 4px;
text-align: center;
vertical-align: top;
min-height: 60px;
height: 60px;
position: relative;
cursor: pointer;
transition: background-color 0.2s;
}
.fc-month-summary-inline {
margin-top: 8px;
background: #f8fafc;
border-radius: 6px;
border: 1px solid #d9e2ec;
font-size: 12px;
padding: 6px 8px;
}
.fc-month-summary-inline table {
width: 100%;
border-collapse: collapse;
}
.fc-month-summary-inline th,
.fc-month-summary-inline td {
padding: 4px 6px;
text-align: center;
}
.fc-month-summary-inline th {
font-weight: 600;
color: #243b53;
border-bottom: 1px solid #d9e2ec;
}
.fc-month-summary-inline td:first-child {
text-align: left;
}
.fc-month-day {
background: #fff;
}
.fc-month-day:hover {
background: #f8fafc !important;
}
.fc-day--other-month {
background: #f0f4f8;
color: #9fb3c8;
box-shadow: none;
}
.fc-day--weekend {
background: #f8fafc;
}
.fc-day--weekend.fc-day--school-holiday,
.fc-day--weekend.fc-day--public-holiday,
.fc-day--weekend.fc-day--off-carole,
.fc-day--weekend.fc-day--extra-off-carole {
background: inherit;
}
/* Application des couleurs existantes au calendrier mensuel */
.fc-month-table .fc-day--school-holiday {
background-color: #e5d9f2;
}
.fc-month-table .fc-day--public-holiday {
background-color: #e0e0e0;
}
.fc-month-table .fc-day--off-carole {
background-color: #ffe9a7;
}
.fc-month-table .fc-day--extra-off-carole {
background-color: #ffd59b;
}
.fc-month-table .fc-day--has-guard {
box-sizing: border-box;
}
.fc-month-table .fc-day--has-guard.fc-day--centre {
position: relative;
}
.fc-month-table .fc-day--has-guard.fc-day--centre::after {
content: "🏫";
position: absolute;
top: 2px;
right: 2px;
font-size: 12px;
line-height: 1;
z-index: 2;
}
.fc-month-table .fc-day--has-guard.fc-day--avis {
position: relative;
}
.fc-month-table .fc-day--has-guard.fc-day--avis::after {
content: "";
position: absolute;
top: 2px;
right: 2px;
width: 12px;
height: 7px;
border-radius: 2px;
background: linear-gradient(
to bottom,
#ffcc00 0%,
#ffcc00 11%,
#c8102e 11%,
#c8102e 22%,
#ffcc00 22%,
#ffcc00 33%,
#c8102e 33%,
#c8102e 44%,
#ffcc00 44%,
#ffcc00 55%,
#c8102e 55%,
#c8102e 66%,
#ffcc00 66%,
#ffcc00 77%,
#c8102e 77%,
#c8102e 88%,
#ffcc00 88%,
#ffcc00 100%
);
box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.2);
z-index: 2;
}
.fc-month-table .fc-day--selected {
background-color: #bde4ff !important;
cursor: pointer;
}
.fc-leaves-label-container {
position: absolute;
top: 1px;
left: 2px;
display: flex;
flex-direction: column;
gap: 0;
z-index: 2;
}
.fc-leaves-label {
font-size: 8px;
font-weight: 600;
color: #1f2933;
line-height: 1;
}
/* === TABLEAU RÉCAPITULATIF === */
.fc-month-summary {
min-width: 300px;
}
.fc-summary-table-wrapper {
background: #f8fafc;
border-radius: 10px;
padding: 10px 10px 12px;
border: 1px solid #d9e2ec;
box-shadow: 0 4px 10px rgba(15, 23, 42, 0.06);
}
.fc-summary-table {
font-size: 12px;
}
.fc-summary-table thead th {
background: transparent;
border-bottom: 1px solid #d9e2ec;
}
.fc-summary-table tbody td {
border: none;
border-bottom: 1px solid #edf2f7;
}
.fc-summary-table tbody tr:last-child td {
border-bottom: none;
}
.fc-summary-total-row {
background: #f0f4f8 !important;
border-top: 2px solid #243b53;
}
.fc-summary-total-row td {
background: #f0f4f8 !important;
font-weight: 600;
color: #243b53;
}
/* Responsive pour le calendrier et le récapitulatif */
@media (max-width: 1200px) {
.fc-calendar-and-summary {
grid-template-columns: 1fr;
}
.fc-month-summary {
min-width: 100%;
}
}
/* === VUE 2 MOIS === */
.fc-two-months-container {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 24px;
}
.fc-month-container {
width: 100%;
}
.fc-month-title {
font-weight: 600;
font-size: 15px;
color: #243b53;
margin-bottom: 12px;
text-align: center;
padding-bottom: 8px;
border-bottom: 1px solid #d9e2ec;
}
/* === VUE ANNÉE === */
.fc-year-container {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 20px;
}
.fc-year-month {
background: #f8fafc;
border: 1px solid #d9e2ec;
border-radius: 6px;
padding: 12px;
}
.fc-year-month-title {
font-weight: 600;
font-size: 14px;
color: #243b53;
margin-bottom: 8px;
text-align: center;
padding-bottom: 8px;
border-bottom: 1px solid #d9e2ec;
}
.fc-year-month .fc-month-table {
font-size: 11px;
}
.fc-year-month .fc-month-table thead th {
padding: 4px 2px;
font-size: 10px;
}
.fc-year-month .fc-month-table tbody td {
padding: 4px 2px;
height: 32px;
font-size: 11px;
}
/* Responsive pour la vue année */
@media (max-width: 1200px) {
.fc-year-container {
grid-template-columns: repeat(2, 1fr);
}
}
@media (max-width: 768px) {
.fc-two-months-container {
grid-template-columns: 1fr;
}
.fc-year-container {
grid-template-columns: 1fr;
}
.fc-month-header {
flex-direction: column;
align-items: stretch;
}
.fc-view-controls {
justify-content: center;
}
.fc-nav-controls {
justify-content: center;
}
}
File diff suppressed because it is too large Load Diff