avancement planning

This commit is contained in:
2025-12-04 17:54:16 +01:00
parent 53abb68514
commit eb403c3aac
15 changed files with 4156 additions and 598 deletions

View File

@@ -1,14 +1,17 @@
.background {
padding: 20px;
min-height: 100vh;
background: #f5f5f0;
height: 100vh;
overflow: hidden;
background: linear-gradient(135deg, #f5f5f0 0%, #faf8f5 100%);
padding: 15px;
box-sizing: border-box;
}
.planning-container {
.planning {
height: 100%;
display: grid;
grid-template-columns: 300px 1fr;
gap: 20px;
max-width: 1400px;
grid-template-columns: 280px 1fr 240px;
gap: 15px;
max-width: 100%;
margin: 0 auto;
}
@@ -16,80 +19,98 @@
.calendar-section {
display: flex;
flex-direction: column;
gap: 15px;
gap: 12px;
overflow: hidden;
}
.calendar-title {
font-size: 18px;
font-weight: 600;
font-size: 16px;
font-weight: 700;
color: #333;
letter-spacing: 1px;
letter-spacing: 1.5px;
padding-left: 5px;
}
.calendar-date-info {
display: flex;
align-items: center;
gap: 15px;
padding: 15px;
gap: 12px;
padding: 14px;
background: white;
border-radius: 12px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
border-radius: 14px;
box-shadow: 0 3px 10px rgba(0, 0, 0, 0.06);
transition: transform 0.2s ease;
}
.calendar-date-info:hover {
transform: translateY(-2px);
}
.date-badge {
background: #8b7b8b;
background: linear-gradient(135deg, var(--mauve) 0%, #8b7ba8 100%);
color: white;
padding: 10px;
border-radius: 8px;
border-radius: 10px;
text-align: center;
min-width: 60px;
min-width: 55px;
box-shadow: 0 3px 10px rgba(106, 90, 139, 0.3);
}
.month-abbr {
font-size: 12px;
font-size: 11px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.5px;
}
.day-number {
font-size: 24px;
font-weight: 700;
line-height: 1;
margin-top: 2px;
}
.date-full {
display: flex;
flex-direction: column;
gap: 2px;
}
.date-text {
font-size: 14px;
font-size: 13px;
font-weight: 600;
color: #333;
}
.day-text {
font-size: 13px;
font-size: 12px;
color: #999;
font-weight: 500;
}
.card {
background: #fefdfb;
border: 2px solid #d4a574;
border-radius: 20px;
padding: 15px;
box-shadow: 0 4px 12px rgba(212, 165, 116, 0.1);
background: white;
border: 2px solid var(--ugly-yellow);
border-radius: 16px;
padding: 16px;
box-shadow: 0 3px 12px rgba(212, 165, 116, 0.15);
flex: 1;
overflow: hidden;
display: flex;
flex-direction: column;
}
.calendar-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 5px 0 15px;
padding: 0 0 14px;
}
.month-title {
font-size: 18px;
font-weight: 600;
color: #d4a574;
font-size: 16px;
font-weight: 700;
color: var(--ugly-yellow);
margin: 0;
}
@@ -103,16 +124,20 @@
justify-content: center;
transition: all 0.2s ease;
opacity: 0.7;
border-radius: 6px;
}
.nav-button:hover {
opacity: 1;
background: rgba(212, 165, 116, 0.1);
transform: scale(1.1);
}
/* Styles pour le calendrier NG-ZORRO */
::ng-deep .card nz-calendar {
background: transparent;
flex: 1;
overflow: hidden;
}
::ng-deep .card .ant-picker-calendar {
@@ -134,43 +159,40 @@
::ng-deep .card thead th {
color: #8b6f47;
font-weight: 600;
font-size: 11px;
font-size: 10px;
padding: 8px 0;
text-align: center;
border-bottom: none;
text-transform: uppercase;
}
::ng-deep .card .ant-picker-cell {
padding: 4px 0;
padding: 2px 0;
text-align: center;
}
::ng-deep .card .ant-picker-cell-inner {
width: 32px;
height: 32px;
line-height: 32px;
width: 30px;
height: 30px;
line-height: 30px;
border-radius: 8px;
margin: 0 auto;
color: #d4a574;
font-size: 13px;
font-weight: 500;
color: var(--ugly-yellow);
font-size: 12px;
font-weight: 600;
transition: all 0.2s ease;
background: transparent;
}
::ng-deep .card .ant-picker-cell:hover .ant-picker-cell-inner {
background: #f9f3ec;
background: rgba(212, 165, 116, 0.15);
transform: scale(1.05);
}
::ng-deep .card .ant-picker-cell-inner.in-selection {
background: #d4a574 !important;
background: linear-gradient(135deg, var(--ugly-yellow) 0%, #c49563 100%) !important;
color: white !important;
box-shadow: 0 2px 8px rgba(212, 165, 116, 0.3);
}
::ng-deep .card .ant-picker-cell-inner.in-selection:hover {
background: #c49563 !important;
box-shadow: 0 2px 8px rgba(212, 165, 116, 0.4);
}
::ng-deep .card .ant-picker-cell-disabled .ant-picker-cell-inner {
@@ -178,127 +200,107 @@
}
::ng-deep .card tbody tr {
height: 40px;
height: 36px;
}
/* Section Planning (droite) */
/* Section Planning (centre) */
.week-section {
background: white;
border-radius: 20px;
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);
padding: 20px;
border-radius: 16px;
box-shadow: 0 3px 16px rgba(0, 0, 0, 0.08);
padding: 18px;
overflow: hidden;
display: flex;
flex-direction: column;
}
.empty-state {
display: flex;
align-items: center;
justify-content: center;
min-height: 500px;
}
.empty-message {
text-align: center;
color: #999;
font-size: 14px;
display: flex;
flex-direction: column;
align-items: center;
gap: 12px;
}
.week-toolbar {
display: flex;
justify-content: space-between;
align-items: center;
padding-bottom: 20px;
padding-bottom: 14px;
border-bottom: 2px solid #f0f0f0;
margin-bottom: 15px;
margin-bottom: 14px;
}
.week-actions {
display: flex;
gap: 10px;
gap: 8px;
}
.action-btn {
padding: 8px 16px;
border: 1px solid #d9d9d9;
display: flex;
align-items: center;
gap: 6px;
padding: 8px 14px;
border: 2px solid #e0e0e0;
background: white;
border-radius: 6px;
border-radius: 8px;
cursor: pointer;
font-size: 13px;
font-size: 12px;
font-weight: 600;
transition: all 0.2s ease;
color: #666;
}
.action-btn:hover {
border-color: #d4a574;
border-color: var(--ugly-yellow);
background: rgba(212, 165, 116, 0.05);
transform: translateY(-1px);
}
.action-btn.active {
background: #d4a574;
background: linear-gradient(135deg, var(--ugly-yellow) 0%, #c49563 100%);
color: white;
border-color: #d4a574;
border-color: var(--ugly-yellow);
box-shadow: 0 3px 10px rgba(212, 165, 116, 0.3);
}
.week-nav {
display: flex;
align-items: center;
gap: 15px;
}
.today-label {
font-weight: 600;
color: #999;
font-size: 14px;
gap: 10px;
}
.today-btn {
padding: 8px 16px;
padding: 8px 14px;
background: white;
border: 1px solid #d9d9d9;
border-radius: 6px;
border: 2px solid #e0e0e0;
border-radius: 8px;
cursor: pointer;
font-size: 13px;
font-size: 12px;
font-weight: 600;
transition: all 0.2s ease;
color: #666;
}
.today-btn:hover {
border-color: #8b7b8b;
}
.new-project-btn {
padding: 8px 20px;
background: #8b7b8b;
color: white;
border: none;
border-radius: 6px;
cursor: pointer;
font-weight: 600;
font-size: 13px;
transition: all 0.2s ease;
}
.new-project-btn:hover {
background: #7a6a7a;
border-color: var(--mauve);
background: rgba(106, 90, 139, 0.05);
transform: translateY(-1px);
}
.week-calendar {
overflow-x: auto;
position: relative;
}
.week-nav-header {
position: absolute;
top: 8px;
right: 20px;
display: flex;
gap: 8px;
z-index: 10;
}
.nav-button-week {
background: white;
border: 1px solid #e0e0e0;
border-radius: 4px;
padding: 4px 8px;
border: 2px solid #e0e0e0;
border-radius: 6px;
padding: 6px 8px;
cursor: pointer;
display: flex;
align-items: center;
@@ -308,37 +310,47 @@
.nav-button-week:hover {
border-color: #999;
background: #f9f9f9;
transform: scale(1.05);
}
.week-calendar {
flex: 1;
overflow: hidden;
display: flex;
flex-direction: column;
}
.week-grid {
display: grid;
grid-template-columns: 70px repeat(7, 1fr);
grid-template-columns: 50px repeat(7, 1fr);
gap: 0;
min-width: 900px;
height: 100%;
overflow: hidden;
}
.time-column {
border-right: 1px solid #e8e8e8;
border-right: 2px solid #f0f0f0;
}
.time-header {
height: 70px;
height: 50px;
border-bottom: 2px solid #e8e8e8;
}
.time-slot {
height: 70px;
height: 60px;
display: flex;
align-items: flex-start;
justify-content: center;
padding-top: 5px;
font-size: 11px;
font-size: 10px;
color: #999;
border-bottom: 1px solid #f0f0f0;
font-weight: 600;
border-bottom: 1px solid #f5f5f5;
}
.day-column {
border-right: 1px solid #e8e8e8;
border-right: 1px solid #f0f0f0;
}
.day-column:last-child {
@@ -346,34 +358,37 @@
}
.day-header {
height: 70px;
height: 50px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
border-bottom: 2px solid #e8e8e8;
background: #fafafa;
transition: all 0.2s ease;
transition: all 0.3s ease;
gap: 2px;
}
.day-header.today {
background: #8b7b8b;
background: linear-gradient(135deg, var(--mauve) 0%, #8b7ba8 100%);
color: white;
box-shadow: 0 3px 10px rgba(106, 90, 139, 0.3);
}
.day-name {
font-size: 13px;
font-weight: 600;
margin-bottom: 3px;
font-size: 11px;
font-weight: 700;
letter-spacing: 0.5px;
}
.day-date {
font-size: 11px;
color: #999;
font-size: 16px;
font-weight: 700;
color: var(--ugly-yellow);
}
.day-header.today .day-date {
color: rgba(255, 255, 255, 0.8);
color: white;
}
.day-slots {
@@ -382,14 +397,203 @@
}
.hour-slot {
height: 70px;
border-bottom: 1px solid #f0f0f0;
height: 60px;
border-bottom: 1px solid #f5f5f5;
padding: 3px;
position: relative;
transition: background 0.2s ease;
transition: all 0.2s ease;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
}
.hour-slot:hover {
background: #f9f9f9;
cursor: pointer;
background: rgba(212, 165, 116, 0.08);
}
.hour-slot.selected {
background: rgba(212, 165, 116, 0.2);
border-left: 3px solid var(--ugly-yellow);
}
.slot-indicator {
width: 10px;
height: 10px;
background: var(--ugly-yellow);
border-radius: 50%;
box-shadow: 0 2px 6px rgba(212, 165, 116, 0.4);
animation: pulse 2s infinite;
}
@keyframes pulse {
0%, 100% {
transform: scale(1);
opacity: 1;
}
50% {
transform: scale(1.2);
opacity: 0.8;
}
}
/* Sidebar (droite) */
.sidebar-section {
background: white;
border-radius: 16px;
box-shadow: 0 3px 16px rgba(0, 0, 0, 0.08);
padding: 18px;
overflow-y: auto;
max-height: 100%;
}
.sidebar-section::-webkit-scrollbar {
width: 6px;
}
.sidebar-section::-webkit-scrollbar-track {
background: #f0f0f0;
border-radius: 10px;
}
.sidebar-section::-webkit-scrollbar-thumb {
background: var(--ugly-yellow);
border-radius: 10px;
}
.sidebar-header {
padding-bottom: 14px;
border-bottom: 2px solid #f0f0f0;
margin-bottom: 14px;
}
.sidebar-title {
font-size: 16px;
font-weight: 700;
color: #333;
margin: 0;
}
.sidebar-content {
display: flex;
flex-direction: column;
gap: 14px;
}
.sidebar-block {
padding: 14px;
background: linear-gradient(135deg, #fafafa 0%, #f5f5f5 100%);
border-radius: 12px;
border-left: 3px solid var(--ugly-yellow);
transition: all 0.2s ease;
}
.sidebar-block:hover {
transform: translateX(3px);
box-shadow: 0 3px 10px rgba(0, 0, 0, 0.06);
}
.sidebar-block h4 {
font-size: 12px;
font-weight: 700;
color: #333;
margin: 0 0 10px 0;
display: flex;
align-items: center;
gap: 6px;
}
.sidebar-block p {
font-size: 12px;
color: #666;
margin: 0;
line-height: 1.4;
}
.slot-info {
display: flex;
flex-direction: column;
gap: 6px;
margin-bottom: 10px;
}
.slot-info p {
padding: 8px 10px;
background: white;
border-radius: 6px;
border-left: 3px solid var(--ugly-yellow);
}
.sidebar-btn {
display: flex;
align-items: center;
gap: 6px;
width: 100%;
padding: 10px 12px;
margin-bottom: 8px;
background: white;
border: 2px solid #e0e0e0;
border-radius: 8px;
cursor: pointer;
font-size: 11px;
font-weight: 600;
transition: all 0.2s ease;
color: #666;
}
.sidebar-btn:hover {
background: rgba(212, 165, 116, 0.05);
border-color: var(--ugly-yellow);
transform: translateY(-1px);
}
.sidebar-btn.primary {
background: linear-gradient(135deg, var(--ugly-yellow) 0%, #c49563 100%);
color: white;
border-color: var(--ugly-yellow);
box-shadow: 0 3px 10px rgba(212, 165, 116, 0.3);
}
.sidebar-btn.primary:hover {
box-shadow: 0 4px 12px rgba(212, 165, 116, 0.4);
}
.sidebar-btn:last-child {
margin-bottom: 0;
}
.stats-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 8px;
margin-top: 10px;
}
.stat-item {
background: white;
padding: 12px;
border-radius: 8px;
text-align: center;
border: 2px solid #f0f0f0;
transition: all 0.2s ease;
}
.stat-item:hover {
border-color: var(--ugly-yellow);
transform: translateY(-1px);
}
.stat-value {
font-size: 20px;
font-weight: 700;
color: var(--ugly-yellow);
margin-bottom: 3px;
}
.stat-label {
font-size: 9px;
color: #999;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.5px;
}

View File

@@ -1,41 +1,40 @@
<div class="background">
<div class="planning-container">
<div class="planning">
<!-- Calendrier à gauche -->
<div class="calendar-section">
<div class="calendar-title">CALENDAR</div>
<div class="calendar-title">CALENDRIER</div>
<div class="calendar-date-info">
<div class="date-badge">
<div class="month-abbr">JAN</div>
<div class="day-number">21</div>
<div class="month-abbr">{{ getCurrentMonth() }}</div>
<div class="day-number">{{ getCurrentDay() }}</div>
</div>
<div class="date-full">
<div class="date-text">21 janvier 2026</div>
<div class="day-text">Mercredi</div>
<div class="date-text">{{ getCurrentDate() }}</div>
<div class="day-text">{{ getDayWeek() }}</div>
</div>
</div>
<div class="card">
<div class="calendar-header">
<button class="nav-button" (click)="previousMonth()">
<svg width="24" height="24" 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"/>
</svg>
</button>
<h2 class="month-title">{{ currentMonthYear }}</h2>
<button class="nav-button" (click)="nextMonth()">
<svg width="24" height="24" 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"/>
</svg>
</button>
</div>
<nz-calendar
[nzFullscreen]="false"
[ngModel]="currentDate"
(nzSelectChange)="onValueChange($event)"
(nzPanelChange)="onPanelChange($event)"
[nzDateFullCell]="dateCellTemplate"
[nzFullscreen]="false"
[ngModel]="currentDate"
(nzSelectChange)="onValueChange($event)"
(nzPanelChange)="onPanelChange($event)"
[nzDateFullCell]="dateCellTemplate"
></nz-calendar>
<ng-template #dateCellTemplate let-date>
<div class="ant-picker-cell-inner" [class.in-selection]="isDateSelected(date)">
{{ date.getDate() }}
@@ -44,37 +43,45 @@
</div>
</div>
<!-- Planning de la semaine à droite -->
<!-- Planning de la semaine au centre -->
<div class="week-section" *ngIf="selectedDates.length > 0">
<div class="week-toolbar">
<div class="week-actions">
<button class="action-btn">Lorem</button>
<button class="action-btn active">Camion</button>
<button class="action-btn">Show</button>
<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">
<span class="today-label">LOREM</span>
<button class="today-btn" (click)="goToToday()">
< TODAY >
<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>
<button class="new-project-btn">NEW PROJECT</button>
</div>
</div>
<div class="week-calendar">
<div class="week-nav-header">
<button class="nav-button-week" (click)="previousWeek()">
<svg width="24" height="24" viewBox="0 0 24 24" fill="none">
<path d="M15 18L9 12L15 6" stroke="#999" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
</button>
<button class="nav-button-week" (click)="nextWeek()">
<svg width="24" height="24" viewBox="0 0 24 24" fill="none">
<path d="M9 18L15 12L9 6" stroke="#999" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
</button>
</div>
<div class="week-grid">
<!-- Colonne des heures -->
<div class="time-column">
@@ -88,11 +95,14 @@
<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">{{ formatDate(date) }}</div>
<div class="day-date">{{ date.getDate() }}</div>
</div>
<div class="day-slots">
<div class="hour-slot" *ngFor="let hour of getHours()">
<!-- Ici on peut ajouter des événements plus tard -->
<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>
@@ -103,8 +113,90 @@
<!-- 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 pour voir le planning de la semaine</p>
<p>Sélectionnez une date dans le calendrier</p>
</div>
</div>
<!-- Sidebar à droite -->
<div class="sidebar-section">
<div class="sidebar-header">
<h3 class="sidebar-title">Détails</h3>
</div>
<div class="sidebar-content">
<div class="sidebar-block" *ngIf="selectedSlot">
<h4>
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor">
<circle cx="12" cy="12" r="10" stroke-width="2"/>
<polyline points="12 6 12 12 16 14" stroke-width="2" stroke-linecap="round"/>
</svg>
Spéctacle sélectionné :
</h4>
<div class="slot-info">
@for (show of shows(); track show.id) {
<p><strong>{{ show.name }}</strong></p>
<p>{{ show.place }}</p>
<p>{{ show.date }}</p>
<p>{{ show.description }}</p>
}
</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">
<h4>
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor">
<circle cx="12" cy="12" r="3" stroke-width="2"/>
<path d="M12 1v6m0 6v6M1 12h6m6 0h6" stroke-width="2" stroke-linecap="round"/>
</svg>
Actions rapides
</h4>
<button class="sidebar-btn" nzType="default" (click)="showModal()">
<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"/>
</svg>
<span>Créer événement</span>
</button>
<nz-modal
(nzOnCancel)="handleCancel()"
(nzOnOk)="handleOk()"
[(nzVisible)]="isVisible"
nzCentered
nzDraggable
nzTitle="Création d'évènement"
>
<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>
</ng-container>
</nz-modal>
<button class="sidebar-btn">
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor">
<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" stroke-width="2"/>
<polyline points="14 2 14 8 20 8" stroke-width="2"/>
</svg>
Voir rapports
</button>
</div>
</div>
</div>
</div>
</div>
</div>

View File

@@ -1,106 +1,234 @@
import { Component } from '@angular/core';
import {Component, inject, OnInit, signal} from '@angular/core';
import { NzCalendarMode, NzCalendarModule } from 'ng-zorro-antd/calendar';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import {ReadShowDto, ShowsService} from "../../../services/api";
import {firstValueFrom} from "rxjs";
import {NzTableComponent} from "ng-zorro-antd/table";
import {NzModalComponent, NzModalModule} from "ng-zorro-antd/modal";
import {NzButtonModule} from "ng-zorro-antd/button";
@Component({
selector: 'app-planning',
imports: [NzCalendarModule, CommonModule, FormsModule],
templateUrl: './planning.html',
styleUrl: './planning.css',
selector: 'app-planning',
imports: [NzCalendarModule, CommonModule, FormsModule, NzModalComponent, NzButtonModule, NzModalModule],
templateUrl: './planning.html',
styleUrl: './planning.css',
})
export class Planning {
currentDate: Date = new Date();
selectedDates: Date[] = [];
monthNames = ['Janvier', 'Février', 'Mars', 'Avril', 'Mai', 'Juin',
'Juillet', 'Août', 'Septembre', 'Octobre', 'Novembre', 'Décembre'];
mode: NzCalendarMode = 'month';
export class Planning implements OnInit{
private showsServices = inject(ShowsService)
get currentMonthYear(): string {
return `${this.monthNames[this.currentDate.getMonth()]} ${this.currentDate.getFullYear()}`;
}
shows = signal<ReadShowDto[]>([]);
onValueChange(value: Date): void {
console.log(`Current value: ${value}`);
this.currentDate = value;
// Sélectionner la date cliquée + les 6 jours suivants (7 jours au total)
this.selectedDates = [];
for (let i = 0; i < 7; i++) {
const date = new Date(value);
date.setDate(date.getDate() + i);
this.selectedDates.push(date);
async ngOnInit(){
await this.fetchShows();
}
console.log('Selected dates:', this.selectedDates);
}
onPanelChange(change: { date: Date; mode: string }): void {
console.log(`Current value: ${change.date}`);
console.log(`Current mode: ${change.mode}`);
this.currentDate = change.date;
}
previousMonth(): void {
const newDate = new Date(this.currentDate);
newDate.setMonth(newDate.getMonth() - 1);
this.currentDate = newDate;
}
nextMonth(): void {
const newDate = new Date(this.currentDate);
newDate.setMonth(newDate.getMonth() + 1);
this.currentDate = newDate;
}
previousWeek(): void {
if (this.selectedDates.length > 0) {
const newDate = new Date(this.selectedDates[0]);
newDate.setDate(newDate.getDate() - 7);
this.onValueChange(newDate);
async fetchShows() {
const shows = await firstValueFrom(this.showsServices.getAllShowsEndpoint());
this.shows.set(shows);
}
}
nextWeek(): void {
if (this.selectedDates.length > 0) {
const newDate = new Date(this.selectedDates[0]);
newDate.setDate(newDate.getDate() + 7);
this.onValueChange(newDate);
isVisible = false;
showModal(): void {
if (!this.isVisible) {
this.isVisible = true;
}
else {
this.isVisible = false;
}
}
}
goToToday(): void {
const today = new Date();
this.onValueChange(today);
}
handleOk(): void {
console.log('Button ok clicked!');
this.isVisible = false;
}
isDateSelected(date: Date): boolean {
return this.selectedDates.some(selectedDate =>
selectedDate.getFullYear() === date.getFullYear() &&
selectedDate.getMonth() === date.getMonth() &&
selectedDate.getDate() === date.getDate()
);
}
handleCancel(): void {
console.log('Button cancel clicked!');
this.isVisible = false;
}
isToday(date: Date): boolean {
const today = new Date();
return date.getDate() === today.getDate() &&
date.getMonth() === today.getMonth() &&
date.getFullYear() === today.getFullYear();
}
getDayName(date: Date): string {
const days = ['Dimanche', 'Lundi', 'Mardi', 'Mercredi', 'Jeudi', 'Vendredi', 'Samedi'];
return days[date.getDay()];
}
selectSlot(date: Date, hour: string): void {
this.selectedSlot = { date, hour };
console.log('Slot sélectionné:', date, hour);
}
formatDate(date: Date): string {
const days = ['Dim', 'Lun', 'Mar', 'Mer', 'Jeu', 'Ven', 'Sam'];
return `${days[date.getDay()]} ${date.getDate()} ${date.getFullYear()}`;
}
getHours(): string[] {
return ['8 AM', '10 AM', '11 AM', '12 PM', '14 PM', '16 PM', '18 PM'];
}
}
currentDate: Date = new Date();
selectedDates: Date[] = [];
monthNames = ['Janvier', 'Février', 'Mars', 'Avril', 'Mai', 'Juin',
'Juillet', 'Août', 'Septembre', 'Octobre', 'Novembre', 'Décembre'];
mode: NzCalendarMode = 'month';
get currentMonthYear(): string {
return `${this.monthNames[this.currentDate.getMonth()]} ${this.currentDate.getFullYear()}`;
}
getCurrentMonth(): string {
const today = new Date();
const mois = ['jan', 'fév', 'mar', 'avr', 'mai', 'jun', 'jul', 'aoû', 'sep', 'oct', 'nov', 'déc'];
return mois[today.getMonth()];
}
getCurrentDay(): string {
const today = new Date();
return String(today.getDate());
}
getCurrentDate(): string {
const today = new Date();
const mois = ['janvier', 'février', 'mars', 'avril', 'mai', 'juin', 'juillet', 'août', 'septembre', 'octobre', 'novembre', 'décembre'];
return `${today.getDate()} ${mois[today.getMonth()]} ${today.getFullYear()}`;
}
getDayWeek(): string {
const today = new Date();
const days = ['Dimanche', 'Lundi', 'Mardi', 'Mercredi', 'Jeudi', 'Vendredi', 'Samedi'];
return days[today.getDay()];
}
onValueChange(value: Date): void {
console.log(`Current value: ${value}`);
this.currentDate = value;
// Sélectionner la date cliquée + les 6 jours suivants (7 jours au total)
this.selectedDates = [];
for (let i = 0; i < 7; i++) {
const date = new Date(value);
date.setDate(date.getDate() + i);
this.selectedDates.push(date);
}
console.log('Selected dates:', this.selectedDates);
}
onPanelChange(change: { date: Date; mode: string }): void {
console.log(`Current value: ${change.date}`);
console.log(`Current mode: ${change.mode}`);
this.currentDate = change.date;
}
previousMonth(): void {
const newDate = new Date(this.currentDate);
newDate.setMonth(newDate.getMonth() - 1);
this.currentDate = newDate;
}
nextMonth(): void {
const newDate = new Date(this.currentDate);
newDate.setMonth(newDate.getMonth() + 1);
this.currentDate = newDate;
}
previousWeek(): void {
if (this.selectedDates.length > 0) {
const newDate = new Date(this.selectedDates[0]);
newDate.setDate(newDate.getDate() - 7);
this.onValueChange(newDate);
}
}
nextWeek(): void {
if (this.selectedDates.length > 0) {
const newDate = new Date(this.selectedDates[0]);
newDate.setDate(newDate.getDate() + 7);
this.onValueChange(newDate);
}
}
goToToday(): void {
const today = new Date();
this.onValueChange(today);
}
isDateSelected(date: Date): boolean {
return this.selectedDates.some(selectedDate =>
selectedDate.getFullYear() === date.getFullYear() &&
selectedDate.getMonth() === date.getMonth() &&
selectedDate.getDate() === date.getDate()
);
}
isToday(date: Date): boolean {
const today = new Date();
return date.getDate() === today.getDate() &&
date.getMonth() === today.getMonth() &&
date.getFullYear() === today.getFullYear();
}
getDayName(date: Date): string {
const days = ['Dim', 'Lun', 'Mar', 'Mer', 'Jeu', 'Ven', 'Sam'];
return days[date.getDay()];
}
formatDate(date: Date): string {
const days = ['Dim', 'Lun', 'Mar', 'Mer', 'Jeu', 'Ven', 'Sam'];
return `${days[date.getDay()]} ${date.getDate()} ${date.getFullYear()}`;
}
getHours(): string[] {
return ['8h', '10h', '11h', '12h', '14h', '16h', '18h', '20h', '22h'];
}
// Filtres
isCamionFilterActive = false;
camionFilter(): void {
this.isCamionFilterActive = !this.isCamionFilterActive;
console.log('Filtre Camion:', this.isCamionFilterActive);
}
isShowFilterActive = false;
showFilter(): void {
this.isShowFilterActive = !this.isShowFilterActive;
console.log('Filtre Show:', this.isShowFilterActive);
}
// Sélection de créneaux
selectedSlot: { date: Date; hour: string } | null = null;
isSlotSelected(date: Date, hour: string): boolean {
if (!this.selectedSlot) return false;
return this.selectedSlot.date.getTime() === date.getTime() &&
this.selectedSlot.hour === hour;
}
formatSelectedDate(date: Date): string {
const days = ['Dimanche', 'Lundi', 'Mardi', 'Mercredi', 'Jeudi', 'Vendredi', 'Samedi'];
const months = ['janvier', 'février', 'mars', 'avril', 'mai', 'juin', 'juillet', 'août', 'septembre', 'octobre', 'novembre', 'décembre'];
return `${days[date.getDay()]} ${date.getDate()} ${months[date.getMonth()]}`;
}
createNewProject(): void {
console.log('Création d\'un nouveau projet');
alert('Fonctionnalité à venir : Créer un nouveau projet');
}
getTotalEvents(): number {
// À implémenter avec de vraies données
return 0;
}
getWeekNumber(): number {
if (this.selectedDates.length === 0) return 0;
const date = new Date(this.selectedDates[0]);
const firstDayOfYear = new Date(date.getFullYear(), 0, 1);
const pastDaysOfYear = (date.getTime() - firstDayOfYear.getTime()) / 86400000;
return Math.ceil((pastDaysOfYear + firstDayOfYear.getDay() + 1) / 7);
}
}

View File

@@ -1,4 +1,9 @@
/* You can add global styles to this file, and also import other style files */
:root {
--mauve: #8b7b8b;
--ugly-yellow: #d4a574;
}
* {
margin: 0;
padding: 0;
@@ -21,3 +26,6 @@ button.primary {
color: white;
border-radius: 8px;
}