Enhance calendar functionality: display year in month header, highlight past dates, and update date selection logic
This commit is contained in:
1 parent
6bc03be89a
commit
7fc7653e6f
6 files changed
+71
-14
No files matched your search
@@ -1,5 +1,5 @@
|
|||||||
<div class="calendar">
|
<div class="calendar">
|
||||||
<h3>{{ getMonthName() }}</h3>
|
<h3>{{ getMonthName() }} {{ year }}</h3>
|
||||||
<div class="row header">
|
<div class="row header">
|
||||||
<p class="day">L</p>
|
<p class="day">L</p>
|
||||||
<p class="day">M</p>
|
<p class="day">M</p>
|
||||||
@@ -16,7 +16,7 @@
|
|||||||
@if (day === null) {
|
@if (day === null) {
|
||||||
<p class="day empty"></p>
|
<p class="day empty"></p>
|
||||||
} @else {
|
} @else {
|
||||||
<p [class.start]="selectedDates.isStart(day)" [class.end]="selectedDates.isEnd(day)" [class.selected]="selectedDates.isSelected(day)"
|
<p [class.past]="day < getNow()" [class.start]="selectedDates.isStart(day)" [class.end]="selectedDates.isEnd(day)" [class.selected]="selectedDates.isSelected(day)"
|
||||||
[class]="selectedDates.getClasses(day)" class="day number" [matTooltip]="selectedDates.getTooltip(day)" [matTooltipShowDelay]="500">{{ day.getDate() }}</p>
|
[class]="selectedDates.getClasses(day)" class="day number" [matTooltip]="selectedDates.getTooltip(day)" [matTooltipShowDelay]="500">{{ day.getDate() }}</p>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -101,3 +101,7 @@
|
|||||||
.other {
|
.other {
|
||||||
background-color: #ff9b9b;
|
background-color: #ff9b9b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.past {
|
||||||
|
color: #b0b0b0;
|
||||||
|
}
|
||||||
@@ -16,6 +16,12 @@ export class CalendarMonth implements OnInit {
|
|||||||
@Input({ required: true })
|
@Input({ required: true })
|
||||||
year!: number;
|
year!: number;
|
||||||
|
|
||||||
|
getNow(): Date {
|
||||||
|
const now = new Date();
|
||||||
|
now.setHours(0, 0, 0, 0);
|
||||||
|
return now;
|
||||||
|
}
|
||||||
|
|
||||||
currentMonth: Date = new Date();
|
currentMonth: Date = new Date();
|
||||||
|
|
||||||
weeksInAMonth: Month = [];
|
weeksInAMonth: Month = [];
|
||||||
|
|||||||
@@ -7,10 +7,10 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
@for (month of [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]; track $index) {
|
@for (month of months; track $index) {
|
||||||
<mat-card>
|
<mat-card>
|
||||||
<mat-card-content>
|
<mat-card-content>
|
||||||
<app-calendar-month [monthIndex]="month" [year]="year" [selectedDates]="selectedDates"></app-calendar-month>
|
<app-calendar-month [monthIndex]="month" [year]="getYear(month)" [selectedDates]="selectedDates"></app-calendar-month>
|
||||||
</mat-card-content>
|
</mat-card-content>
|
||||||
</mat-card>
|
</mat-card>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { Component, OnInit, effect, signal } from '@angular/core';
|
|||||||
import { UserInputService } from '../../services/user-input-service';
|
import { UserInputService } from '../../services/user-input-service';
|
||||||
import { MatCard, MatCardContent } from '@angular/material/card';
|
import { MatCard, MatCardContent } from '@angular/material/card';
|
||||||
import { CalendarMonth } from "../calendar-month/calendar-month";
|
import { CalendarMonth } from "../calendar-month/calendar-month";
|
||||||
import { CalendarService, SelectedDates, VacationsNumber } from '../../services/calendar-service';
|
import { CalendarService, SelectedDates } from '../../services/calendar-service';
|
||||||
import { CommonModule } from '@angular/common';
|
import { CommonModule } from '@angular/common';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@@ -16,7 +16,7 @@ export class CalendarYear implements OnInit {
|
|||||||
|
|
||||||
constructor(private userInput: UserInputService, private calendarService: CalendarService) {
|
constructor(private userInput: UserInputService, private calendarService: CalendarService) {
|
||||||
effect(() => {
|
effect(() => {
|
||||||
this.selectedDates = this.calendarService.getSelectedDatesForYear(this.year);
|
this.selectedDates = this.calendarService.getSelectedDatesForYear();
|
||||||
const vacationData = this.userInput.vacationNumberSignal();
|
const vacationData = this.userInput.vacationNumberSignal();
|
||||||
this.isLoading.set(true);
|
this.isLoading.set(true);
|
||||||
// Simulate server-side calculation with a small delay
|
// Simulate server-side calculation with a small delay
|
||||||
@@ -31,9 +31,15 @@ export class CalendarYear implements OnInit {
|
|||||||
|
|
||||||
protected selectedDates: SelectedDates = new SelectedDates();
|
protected selectedDates: SelectedDates = new SelectedDates();
|
||||||
|
|
||||||
protected year: number = 2026;
|
getYear(monthIndex: number): number {
|
||||||
|
const offset = new Date().getMonth() <= monthIndex ? 0 : 1;
|
||||||
|
return new Date().getFullYear() + offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
// months starting from actual date
|
||||||
|
protected months: number[] = Array.from({ length: 12 }, (_, i) => (new Date().getMonth() + i) % 12);
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.selectedDates = this.calendarService.getSelectedDatesForYear(this.year);
|
this.selectedDates = this.calendarService.getSelectedDatesForYear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -13,9 +13,17 @@ const allTypesOptions: HolidaysTypes.Options = {
|
|||||||
})
|
})
|
||||||
export class CalendarService {
|
export class CalendarService {
|
||||||
|
|
||||||
getSelectedDatesForYear(year: number): SelectedDates {
|
// Get selected dates from current date to the next year
|
||||||
const holidays = this.getHolidays(year);
|
getSelectedDatesFromNow(): SelectedDates {
|
||||||
const monthInAYear = CalendarService.monthsInYear(year);
|
const holidays = this.getHolidays();
|
||||||
|
let selectedDates: SelectedDates = new SelectedDates();
|
||||||
|
// Logic to populate selectedDates from now until the next year
|
||||||
|
return selectedDates;
|
||||||
|
}
|
||||||
|
|
||||||
|
getSelectedDatesForYear(): SelectedDates {
|
||||||
|
const holidays = this.getHolidays();
|
||||||
|
const monthInAYear = CalendarService.monthsInAYearFromNow();
|
||||||
let selectedDates: SelectedDates = new SelectedDates();
|
let selectedDates: SelectedDates = new SelectedDates();
|
||||||
for (const weeksInAMonth of monthInAYear) {
|
for (const weeksInAMonth of monthInAYear) {
|
||||||
for (const daysInAWeek of weeksInAMonth) {
|
for (const daysInAWeek of weeksInAMonth) {
|
||||||
@@ -45,10 +53,12 @@ export class CalendarService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
getHolidays(year: number): Date[] {
|
getHolidays(): Date[] {
|
||||||
// Logic to return holidays for the given year
|
// Logic to return holidays for the given year
|
||||||
const hd = new Holidays('FR', allTypesOptions);
|
const hd = new Holidays('FR', allTypesOptions);
|
||||||
const holidays = hd.getHolidays(year, lang);
|
const holidays = hd.getHolidays(new Date().getFullYear(), lang);
|
||||||
|
const holidaysPlusOne = hd.getHolidays(new Date().getFullYear() + 1, lang);
|
||||||
|
holidays.push(...holidaysPlusOne);
|
||||||
let holidaysDate: Date[] = holidays.map(holiday => new Date(holiday.date));
|
let holidaysDate: Date[] = holidays.map(holiday => new Date(holiday.date));
|
||||||
return holidaysDate;
|
return holidaysDate;
|
||||||
}
|
}
|
||||||
@@ -97,6 +107,19 @@ export class CalendarService {
|
|||||||
}
|
}
|
||||||
return months;
|
return months;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static monthsInAYearFromNow(): Year {
|
||||||
|
const months: Year = [];
|
||||||
|
const currentMonthIndex = new Date().getMonth();
|
||||||
|
const currentYear = new Date().getFullYear();
|
||||||
|
for (let i = 0; i < 12; i++) {
|
||||||
|
const monthIndex = (currentMonthIndex + i) % 12;
|
||||||
|
const year = currentYear + Math.floor((currentMonthIndex + i) / 12);
|
||||||
|
months.push(this.weeksInMonth(monthIndex, year));
|
||||||
|
}
|
||||||
|
return months;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export type VacationsNumber = {
|
export type VacationsNumber = {
|
||||||
@@ -548,7 +571,22 @@ export class SelectedDates implements SelectedDateInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
lookForVacationRec(vacType: DayType): { apply: () => void; heuristic: number } {
|
lookForVacationRec(vacType: DayType): { apply: () => void; heuristic: number } {
|
||||||
const daysOfYear = CalendarService.monthsInYear(2026);
|
const daysOfYear = CalendarService.monthsInAYearFromNow();
|
||||||
|
const now = new Date();
|
||||||
|
now.setHours(0, 0, 0, 0);
|
||||||
|
daysOfYear.forEach(month => {
|
||||||
|
month.forEach(week => {
|
||||||
|
week.forEach(day => {
|
||||||
|
if (day) {
|
||||||
|
if (day)
|
||||||
|
day.setHours(0, 0, 0, 0);
|
||||||
|
if (day && day < now) {
|
||||||
|
week[week.indexOf(day)] = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
const tempDatesBackup = [...this._datesSelected];
|
const tempDatesBackup = [...this._datesSelected];
|
||||||
let strategies: { apply: () => void; heuristic: number; value: Date }[] = [];
|
let strategies: { apply: () => void; heuristic: number; value: Date }[] = [];
|
||||||
for (const month of daysOfYear) {
|
for (const month of daysOfYear) {
|
||||||
@@ -582,6 +620,9 @@ export class SelectedDates implements SelectedDateInterface {
|
|||||||
const bestStrategy = strategies.reduce((best, current) =>
|
const bestStrategy = strategies.reduce((best, current) =>
|
||||||
current.heuristic > best.heuristic ? current : best
|
current.heuristic > best.heuristic ? current : best
|
||||||
);
|
);
|
||||||
|
strategies.forEach(strategy => {
|
||||||
|
console.log(`Strategy for ${strategy.value.toDateString()} has heuristic ${strategy.heuristic}`);
|
||||||
|
});
|
||||||
bestStrategy.apply();
|
bestStrategy.apply();
|
||||||
return bestStrategy;
|
return bestStrategy;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user