amélioration de planning

This commit is contained in:
2025-12-11 17:37:52 +01:00
parent db4a851a81
commit 619a2b240a
3 changed files with 167 additions and 163 deletions

View File

@@ -7,20 +7,52 @@
} }
.planning { .planning {
height: 100%; display: flex;
display: grid; flex-direction: row; /* au lieu de column */
grid-template-columns: 280px 1fr 240px;
gap: 15px; gap: 15px;
height: 100%;
max-width: 100%; max-width: 100%;
margin: 0 auto; margin: 0 auto;
} }
/* Section Calendrier (gauche) */
.left {
width: 70%;
height: 100%;
display: flex;
flex-direction: column;
gap: 15px;
}
.right {
width: 30%;
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
}
/* Section Calendrier */
.calendar-section { .calendar-section {
width: 90%;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 12px; gap: 12px;
overflow: hidden; overflow-y: auto;
}
.calendar-section::-webkit-scrollbar {
width: 6px;
}
.calendar-section::-webkit-scrollbar-track {
background: #f0f0f0;
border-radius: 10px;
}
.calendar-section::-webkit-scrollbar-thumb {
background: var(--ugly-yellow);
border-radius: 10px;
} }
.calendar-title { .calendar-title {
@@ -89,12 +121,13 @@
} }
.card { .card {
width: 100%;
height: 100%;
background: white; background: white;
border: 2px solid var(--ugly-yellow); border: 2px solid var(--ugly-yellow);
border-radius: 16px; border-radius: 16px;
padding: 16px; padding: 16px;
box-shadow: 0 3px 12px rgba(212, 165, 116, 0.15); box-shadow: 0 3px 12px rgba(212, 165, 116, 0.15);
flex: 1;
overflow: hidden; overflow: hidden;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
@@ -136,7 +169,6 @@
/* Styles pour le calendrier NG-ZORRO */ /* Styles pour le calendrier NG-ZORRO */
::ng-deep .card nz-calendar { ::ng-deep .card nz-calendar {
background: transparent; background: transparent;
flex: 1;
overflow: hidden; overflow: hidden;
} }
@@ -203,12 +235,13 @@
height: 36px; height: 36px;
} }
/* Section Planning (centre) */ /* Section Planning */
.week-section { .week-section {
background: white; background: white;
border-radius: 16px; border-radius: 16px;
box-shadow: 0 3px 16px rgba(0, 0, 0, 0.08); box-shadow: 0 3px 16px rgba(0, 0, 0, 0.08);
padding: 18px; padding: 18px;
height: 100%;
overflow: hidden; overflow: hidden;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
@@ -325,7 +358,11 @@
grid-template-columns: 50px repeat(7, 1fr); grid-template-columns: 50px repeat(7, 1fr);
gap: 0; gap: 0;
height: 100%; height: 100%;
overflow: hidden; overflow-y: scroll;
}
.week-grid::-webkit-scrollbar {
display: none;
} }
.time-column { .time-column {
@@ -338,7 +375,7 @@
} }
.time-slot { .time-slot {
height: 60px; height: 40px;
display: flex; display: flex;
align-items: flex-start; align-items: flex-start;
justify-content: center; justify-content: center;
@@ -397,7 +434,7 @@
} }
.hour-slot { .hour-slot {
height: 60px; height: 40px;
border-bottom: 1px solid #f5f5f5; border-bottom: 1px solid #f5f5f5;
padding: 3px; padding: 3px;
position: relative; position: relative;
@@ -414,12 +451,12 @@
.hour-slot.selected { .hour-slot.selected {
background: rgba(212, 165, 116, 0.2); background: rgba(212, 165, 116, 0.2);
border-left: 3px solid var(--ugly-yellow); border-bottom: 3px solid var(--ugly-yellow);
} }
.slot-indicator { .slot-indicator {
width: 10px; width: 8px;
height: 10px; height: 8px;
background: var(--ugly-yellow); background: var(--ugly-yellow);
border-radius: 50%; border-radius: 50%;
box-shadow: 0 2px 6px rgba(212, 165, 116, 0.4); box-shadow: 0 2px 6px rgba(212, 165, 116, 0.4);
@@ -437,14 +474,17 @@
} }
} }
/* Sidebar (droite) */ /* Sidebar */
.sidebar-section { .details {
margin-top: 14px;
width: 90%;
background: white; background: white;
border-radius: 16px; border-radius: 16px;
box-shadow: 0 3px 16px rgba(0, 0, 0, 0.08); box-shadow: 0 3px 16px rgba(0, 0, 0, 0.08);
padding: 18px; padding: 18px;
overflow-y: auto; overflow-y: auto;
max-height: 100%; display: flex;
flex-direction: column;
} }
.sidebar-section::-webkit-scrollbar { .sidebar-section::-webkit-scrollbar {

View File

@@ -1,30 +1,102 @@
<div class="background"> <div class="background">
<div class="planning"> <div class="planning">
<!-- Calendrier à gauche --> <div class="left">
<div class="calendar-section"> <!-- Planning de la semaine au centre -->
<div class="calendar-title">CALENDRIER</div> <div class="week-section" *ngIf="selectedDates.length > 0">
<div class="calendar-date-info"> <div class="week-toolbar">
<div class="date-badge"> <div class="week-actions">
<div class="month-abbr">{{ getCurrentMonth() }}</div> <button [class]="isCamionFilterActive ? 'action-btn active' : 'action-btn'"
<div class="day-number">{{ getCurrentDay() }}</div> (click)="camionFilter()">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor">
<rect x="1" y="3" width="15" height="13" rx="2" ry="2" stroke-width="2"/>
<path d="M16 8h5l3 3v5h-4" stroke-width="2"/>
<circle cx="5.5" cy="18.5" r="2.5" stroke-width="2"/>
<circle cx="18.5" cy="18.5" r="2.5" stroke-width="2"/>
</svg>
Camion
</button>
<button [class]="isShowFilterActive ? 'action-btn active' : 'action-btn'" (click)="showFilter()">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor">
<circle cx="11" cy="11" r="8" stroke-width="2"/>
<path d="M21 21l-4.35-4.35" stroke-width="2" stroke-linecap="round"/>
</svg>
Show
</button>
</div>
<div class="week-nav">
<button class="nav-button-week" (click)="previousWeek()">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none">
<path d="M15 18L9 12L15 6" stroke="#666" stroke-width="2" stroke-linecap="round"
stroke-linejoin="round"/>
</svg>
</button>
<button class="today-btn" (click)="goToToday()">
Aujourd'hui
</button>
<button class="nav-button-week" (click)="nextWeek()">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none">
<path d="M9 18L15 12L9 6" stroke="#666" stroke-width="2" stroke-linecap="round"
stroke-linejoin="round"/>
</svg>
</button>
</div>
</div> </div>
<div class="date-full">
<div class="date-text">{{ getCurrentDate() }}</div> <div class="week-calendar">
<div class="day-text">{{ getDayWeek() }}</div> <div class="week-grid">
<!-- Colonne des heures -->
<div class="time-column">
<div class="time-header"></div>
<div class="time-slot" *ngFor="let hour of getHours()">
{{ hour }}
</div>
</div>
<!-- Colonnes des jours -->
<div class="day-column" *ngFor="let date of selectedDates">
<div class="day-header" [class.today]="isToday(date)">
<div class="day-name">{{ getDayName(date) }}</div>
<div class="day-date">{{ date.getDate() }}</div>
</div>
<div class="day-slots">
<div class="hour-slot"
*ngFor="let hour of getHours()"
(click)="selectSlot(date, hour)"
[class.selected]="isSlotSelected(date, hour)">
<div class="slot-indicator" *ngIf="isSlotSelected(date, hour)"></div>
</div>
</div>
</div>
</div>
</div> </div>
</div> </div>
<!-- Message si aucune semaine sélectionnée -->
<div *ngIf="selectedDates.length === 0" class="week-section empty-state">
<div class="empty-message">
<p>Sélectionnez une date dans le calendrier</p>
</div>
</div>
</div>
<div class="right">
<div class="calendar-section">
<div class="calendar-title">CALENDRIER</div>
<div class="card"> <div class="card">
<div class="calendar-header"> <div class="calendar-header">
<button class="nav-button" (click)="previousMonth()"> <button class="nav-button" (click)="previousMonth()">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none"> <svg width="20" height="20" viewBox="0 0 24 24" fill="none">
<path d="M15 18L9 12L15 6" stroke="#d4a574" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> <path d="M15 18L9 12L15 6" stroke="#d4a574" stroke-width="2" stroke-linecap="round"
stroke-linejoin="round"/>
</svg> </svg>
</button> </button>
<h2 class="month-title">{{ currentMonthYear }}</h2> <h2 class="month-title">{{ currentMonthYear }}</h2>
<button class="nav-button" (click)="nextMonth()"> <button class="nav-button" (click)="nextMonth()">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none"> <svg width="20" height="20" viewBox="0 0 24 24" fill="none">
<path d="M9 18L15 12L9 6" stroke="#d4a574" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> <path d="M9 18L15 12L9 6" stroke="#d4a574" stroke-width="2" stroke-linecap="round"
stroke-linejoin="round"/>
</svg> </svg>
</button> </button>
</div> </div>
@@ -43,82 +115,8 @@
</div> </div>
</div> </div>
<!-- Planning de la semaine au centre -->
<div class="week-section" *ngIf="selectedDates.length > 0">
<div class="week-toolbar">
<div class="week-actions">
<button [class]="isCamionFilterActive ? 'action-btn active' : 'action-btn'" (click)="camionFilter()">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor">
<rect x="1" y="3" width="15" height="13" rx="2" ry="2" stroke-width="2"/>
<path d="M16 8h5l3 3v5h-4" stroke-width="2"/>
<circle cx="5.5" cy="18.5" r="2.5" stroke-width="2"/>
<circle cx="18.5" cy="18.5" r="2.5" stroke-width="2"/>
</svg>
Camion
</button>
<button [class]="isShowFilterActive ? 'action-btn active' : 'action-btn'" (click)="showFilter()">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor">
<circle cx="11" cy="11" r="8" stroke-width="2"/>
<path d="M21 21l-4.35-4.35" stroke-width="2" stroke-linecap="round"/>
</svg>
Show
</button>
</div>
<div class="week-nav">
<button class="nav-button-week" (click)="previousWeek()">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none">
<path d="M15 18L9 12L15 6" stroke="#666" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
</button>
<button class="today-btn" (click)="goToToday()">
Aujourd'hui
</button>
<button class="nav-button-week" (click)="nextWeek()">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none">
<path d="M9 18L15 12L9 6" stroke="#666" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
</button>
</div>
</div>
<div class="week-calendar">
<div class="week-grid">
<!-- Colonne des heures -->
<div class="time-column">
<div class="time-header"></div>
<div class="time-slot" *ngFor="let hour of getHours()">
{{ hour }}
</div>
</div>
<!-- Colonnes des jours -->
<div class="day-column" *ngFor="let date of selectedDates">
<div class="day-header" [class.today]="isToday(date)">
<div class="day-name">{{ getDayName(date) }}</div>
<div class="day-date">{{ date.getDate() }}</div>
</div>
<div class="day-slots">
<div class="hour-slot"
*ngFor="let hour of getHours()"
(click)="selectSlot(date, hour)"
[class.selected]="isSlotSelected(date, hour)">
<div class="slot-indicator" *ngIf="isSlotSelected(date, hour)"></div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Message si aucune semaine sélectionnée -->
<div class="week-section empty-state" *ngIf="selectedDates.length === 0">
<div class="empty-message">
<p>Sélectionnez une date dans le calendrier</p>
</div>
</div>
<!-- Sidebar à droite --> <!-- Sidebar à droite -->
<div class="sidebar-section"> <div class="details">
<div class="sidebar-header"> <div class="sidebar-header">
<h3 class="sidebar-title">Détails</h3> <h3 class="sidebar-title">Détails</h3>
</div> </div>
@@ -133,33 +131,14 @@
</h4> </h4>
<div class="slot-info"> <div class="slot-info">
@for (show of shows(); track show.id) { @for (show of shows(); track show.id) {
<p><strong>{{ show.name }}</strong></p> <p><strong>{{ show.name }}</strong></p>
<p>{{ show.place }}</p> <p>{{ show.place }}</p>
<p>{{ show.date }}</p> <p>{{ show.date }}</p>
<p>{{ show.description }}</p> <p>{{ show.description }}</p>
} }
</div> </div>
</div> </div>
<div class="sidebar-block">
<h4>
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor">
<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4M7 10l5 5 5-5M12 15V3" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
Statistiques
</h4>
<div class="stats-grid">
<div class="stat-item">
<div class="stat-value">{{ getTotalEvents() }}</div>
<div class="stat-label">Événements</div>
</div>
<div class="stat-item">
<div class="stat-value">S{{ getWeekNumber() }}</div>
<div class="stat-label">Semaine</div>
</div>
</div>
</div>
<div class="sidebar-block"> <div class="sidebar-block">
<h4> <h4>
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor"> <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor">
@@ -172,19 +151,14 @@
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor"> <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor">
<path d="M12 5v14M5 12h14" stroke-width="2" stroke-linecap="round"/> <path d="M12 5v14M5 12h14" stroke-width="2" stroke-linecap="round"/>
</svg> </svg>
<span>Créer événement</span> <span>Créer un spectacle</span>
</button> </button>
<nz-modal <nz-modal (nzOnCancel)="handleCancel()"
(nzOnCancel)="handleCancel()" (nzOnOk)="handleOk()"
(nzOnOk)="handleOk()" [(nzVisible)]="isVisible"
[(nzVisible)]="isVisible" nzTitle="Création d'évènement">
nzCentered
nzDraggable
nzTitle="Création d'évènement"
>
<ng-container *nzModalContent> <ng-container *nzModalContent>
<p>Just don't learn physics at school and your life will be full of magic and miracles.</p>
<p>Day before yesterday I saw a rabbit, and yesterday a deer, and today, you.</p> <p>Day before yesterday I saw a rabbit, and yesterday a deer, and today, you.</p>
</ng-container> </ng-container>
</nz-modal> </nz-modal>
@@ -199,4 +173,5 @@
</div> </div>
</div> </div>
</div> </div>
</div>
</div> </div>

View File

@@ -1,25 +1,24 @@
import {Component, inject, OnInit, signal} from '@angular/core'; import {Component, inject, OnInit, signal} from '@angular/core';
import { NzCalendarMode, NzCalendarModule } from 'ng-zorro-antd/calendar'; import {NzCalendarMode, NzCalendarModule} from 'ng-zorro-antd/calendar';
import { CommonModule } from '@angular/common'; import {CommonModule} from '@angular/common';
import { FormsModule } from '@angular/forms'; import {FormsModule} from '@angular/forms';
import {ReadShowDto, ShowsService} from "../../../services/api"; import {ReadShowDto, ShowsService} from "../../../services/api";
import {firstValueFrom} from "rxjs"; import {firstValueFrom} from "rxjs";
import {NzTableComponent} from "ng-zorro-antd/table";
import {NzModalComponent, NzModalModule} from "ng-zorro-antd/modal"; import {NzModalComponent, NzModalModule} from "ng-zorro-antd/modal";
import {NzButtonModule} from "ng-zorro-antd/button"; import {NzButtonModule} from "ng-zorro-antd/button";
@Component({ @Component({
selector: 'app-planning', selector: 'app-planning',
imports: [NzCalendarModule, CommonModule, FormsModule, NzModalComponent, NzButtonModule, NzModalModule], imports: [NzCalendarModule, CommonModule, FormsModule, NzButtonModule, NzModalModule],
templateUrl: './planning.html', templateUrl: './planning.html',
styleUrl: './planning.css', styleUrl: './planning.css',
}) })
export class Planning implements OnInit{ export class Planning implements OnInit {
private showsServices = inject(ShowsService) private showsServices = inject(ShowsService)
shows = signal<ReadShowDto[]>([]); shows = signal<ReadShowDto[]>([]);
async ngOnInit(){ async ngOnInit() {
await this.fetchShows(); await this.fetchShows();
} }
@@ -28,44 +27,34 @@ export class Planning implements OnInit{
this.shows.set(shows); this.shows.set(shows);
} }
isVisible = false; isVisible = signal<boolean>(false);
showModal(): void { showModal(): void {
if (!this.isVisible) { if (!this.isVisible()) {
this.isVisible = true; this.isVisible.set(true);
} } else {
else { this.isVisible.set(false);
this.isVisible = false;
} }
} }
handleOk(): void { handleOk(): void {
console.log('Button ok clicked!'); console.log('Button ok clicked!');
this.isVisible = false; this.isVisible.set(false);
} }
handleCancel(): void { handleCancel(): void {
console.log('Button cancel clicked!'); console.log('Button cancel clicked!');
this.isVisible = false; this.isVisible.set(false);
} }
selectSlot(date: Date, hour: string): void { selectSlot(date: Date, hour: string): void {
this.selectedSlot = { date, hour }; this.selectedSlot = {date, hour};
console.log('Slot sélectionné:', date, hour); console.log('Slot sélectionné:', date, hour);
} }
currentDate: Date = new Date(); currentDate: Date = new Date();
selectedDates: Date[] = []; selectedDates: Date[] = [];
monthNames = ['Janvier', 'Février', 'Mars', 'Avril', 'Mai', 'Juin', monthNames = ['Janvier', 'Février', 'Mars', 'Avril', 'Mai', 'Juin',
@@ -179,7 +168,7 @@ export class Planning implements OnInit{
} }
getHours(): string[] { getHours(): string[] {
return ['8h', '10h', '11h', '12h', '14h', '16h', '18h', '20h', '22h']; return ['', '1h', '2h', '3h', '4h', '5h', '6h', '7h', '8h', '9h', '10h', '11h', '12h', '13h', '14h', '15h', '16h', '17h', '18h', '19h', '20h', '21h', '22h', '23h'];
} }
// Filtres // Filtres