Skip to content

Commit

Permalink
feat: horaires semaines (#374)
Browse files Browse the repository at this point in the history
* feat: add horaires about even or odd weeks

* feat: multiple horaires and description layout

* fix: revert horaires detail

* fix: delete console log

* fix: retour pr
  • Loading branch information
abelkhay committed Oct 12, 2023
1 parent 968d5f5 commit 4c80390
Show file tree
Hide file tree
Showing 9 changed files with 162 additions and 38 deletions.
Original file line number Diff line number Diff line change
@@ -1,2 +1,11 @@
<p class="my-3 presentation-resume" *ngIf="resume">{{ resume }}</p>
<p class="my-3 presentation-detail" *ngIf="detail">{{ detail }}</p>
<ng-container *ngIf="resume || detail; else noDescription">
<p class="my-3 presentation-resume" *ngIf="resume">{{ resume }}</p>
<p class="my-3 presentation-detail" *ngIf="detail">{{ detail }}</p>
</ng-container>
<ng-template #noDescription>
<div class="mt-4 text-center">
La description de ce lieu
<br />
n'est pas encore renseignée
</div>
</ng-template>
Original file line number Diff line number Diff line change
@@ -1,37 +1,41 @@
<h2 class="h5 text-muted-dark mb-3 d-print-none text-uppercase">Horaires</h2>
<div class="d-flex">
<h2 class="h6 mb-3 d-print-none fw-bold flex-grow-1" *ngIf="sousTitre">{{ sousTitre }}</h2>
<small class="text-muted">
<em>{{ getWeekByIteration(weekOffset) }}</em>
</small>
</div>
<small class="text-muted-dark fw-bold mb-2 d-none d-print-block">Horaires d'ouverture</small>
<ng-container *ngIf="horaires; else noOpeningHours">
<table class="table table-horaires table-borderless table-sm mb-0 text-prewrap">
<ng-container *ngIf="horaires">
<table class="table table-horaires table-borderless mb-0 text-prewrap align-middle">
<tbody>
<tr>
<th scope="row" class="day text-muted fw-bold">Lundi</th>
<td>{{ horaires['Lundi'] }}</td>
<tr class="bg-light">
<th class="day text-muted fw-bold">Lundi</th>
<td class="text-end">{{ horaires['Lundi'] }}</td>
</tr>
<tr>
<th scope="row" class="day text-muted fw-bold">Mardi</th>
<td>{{ horaires['Mardi'] }}</td>
<td class="text-end">{{ horaires['Mardi'] }}</td>
</tr>
<tr>
<tr class="bg-light">
<th scope="row" class="day text-muted fw-bold">Mercredi</th>
<td>{{ horaires['Mercredi'] }}</td>
<td class="text-end">{{ horaires['Mercredi'] }}</td>
</tr>
<tr>
<th scope="row" class="day text-muted fw-bold">Jeudi</th>
<td>{{ horaires['Jeudi'] }}</td>
<td class="text-end">{{ horaires['Jeudi'] }}</td>
</tr>
<tr>
<tr class="bg-light">
<th scope="row" class="day text-muted fw-bold">Vendredi</th>
<td>{{ horaires['Vendredi'] }}</td>
<td class="text-end">{{ horaires['Vendredi'] }}</td>
</tr>
<tr>
<th class="day text-muted fw-bold">Samedi</th>
<td>{{ horaires['Samedi'] }}</td>
<td class="text-end">{{ horaires['Samedi'] }}</td>
</tr>
<tr>
<tr class="bg-light">
<th scope="row" class="day text-muted fw-bold">Dimanche</th>
<td>{{ horaires['Dimanche'] }}</td>
<td class="text-end">{{ horaires['Dimanche'] }}</td>
</tr>
</tbody>
</table>
</ng-container>
<ng-template #noOpeningHours>Horaires d'ouverture inconnus</ng-template>
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
import { HorairesPresentation } from '../../../../core/presenters';
import { HorairesPresentation, getIntervalWeekByOffset } from '../../../../core/presenters';

@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
Expand All @@ -8,4 +8,11 @@ import { HorairesPresentation } from '../../../../core/presenters';
})
export class HorairesComponent {
@Input() public horaires?: HorairesPresentation;
@Input() public sousTitre: string = '';
@Input() public weekOffset: string | number = '';

public getWeekByIteration(weekOffset: string | number): string {
const today = new Date();
return getIntervalWeekByOffset(weekOffset, today);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,25 +50,64 @@
[distance]="lieuMediationNumerique.distance"
[status]="lieuMediationNumerique.status"></app-informations-pratiques>
</li>
<li
class="list-group-item"
*ngIf="lieuMediationNumerique.presentation?.detail || lieuMediationNumerique.presentation?.resume">
<app-description
[detail]="lieuMediationNumerique.presentation?.detail"
[resume]="lieuMediationNumerique.presentation?.resume"></app-description>
</li>
<li class="list-group-item border-0" *ngIf="lieuMediationNumerique.accessibilite === undefined">
<app-accessibilite [accessibilite]="lieuMediationNumerique.accessibilite"></app-accessibilite>
</li>
<li class="list-group-item">
<div class="row">
<div class="col-md-5 mt-4">
<app-horaires [horaires]="lieuMediationNumerique.horaires"></app-horaires>
</div>
<div class="col-md-7 mt-md-0 mt-4">
<app-services [services]="lieuMediationNumerique.services"></app-services>
<div class="row mb-5">
<ng-container *ngIf="lieuMediationNumerique.horaires; else noOpeningHours">
<div class="col-md-6 mt-4">
<app-horaires [horaires]="lieuMediationNumerique.horaires" sousTitre="Cette semaine" weekOffset="0"></app-horaires>
</div>
</ng-container>
<ng-template #noOpeningHours>
<div class="col-md-6 mt-4 d-flex justify-content-center align-items-center text-center">
Les Horaires de ce lieu
<br />
sont inconnus
</div>
</ng-template>
<div class="col-md-6 mt-md-0 mt-4 d-flex align-items-center justify-content-center">
<div>
<app-description
[detail]="lieuMediationNumerique.presentation?.detail"
[resume]="lieuMediationNumerique.presentation?.resume"></app-description>
</div>
</div>
</div>
<ng-container *ngIf="lieuMediationNumerique.full_horaires">
<app-collapse #collapseHorairesDetaille [control]="collapseHorairesDetailleControl">
<li class="list-group-item border-0 border-top">
<div class="row">
<h2 class="h5 my-3 d-print-none fw-bold text-muted">Horaires détaillées</h2>
<div
class="col-md-6 mt-4"
*ngFor="let weekHoraires of lieuMediationNumerique.full_horaires; let weekOffset = index">
<app-horaires [horaires]="weekHoraires" [weekOffset]="weekOffset + 1"></app-horaires>
</div>
</div>
</li>
</app-collapse>
<div class="my-3">
<small *ngIf="collapseHorairesDetaille.isCollapsed$ | async" class="d-flex justify-content-center text-primary my-1">
<i class="ri ri-error-warning-line ms-2 text-primary" aria-hidden="true"></i>
Attention, les horaires de cette structure varient en fonction des semaines
</small>
<div class="d-flex justify-content-center">
<button
class="btn btn-sm btn-secondary my-2"
#collapseHorairesDetailleControl
aria-controls="collapseHorairesDetaille"
[attr.aria-expanded]="collapseHorairesDetaille.isExpanded$ | async"
(click)="collapseHorairesDetaille.toggle()">
{{ (collapseHorairesDetaille.isCollapsed$ | async) ? 'Afficher tout les horaires' : 'Réduire les horaires' }}
</button>
</div>
</div>
</ng-container>
</li>
<li class="list-group-item border-0">
<app-services [services]="lieuMediationNumerique.services"></app-services>
</li>
<li class="list-group-item border-0" *ngIf="lieuMediationNumerique.accessibilite === undefined">
<app-accessibilite [accessibilite]="lieuMediationNumerique.accessibilite"></app-accessibilite>
</li>
<li class="list-group-item" *ngIf="lieuMediationNumerique.aidants">
<app-aidants [aidants]="lieuMediationNumerique.aidants"></app-aidants>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export type LieuMediationNumeriqueDetailsPresentation = {
code_postal: string;
services: Service[];
horaires?: HorairesPresentation;
full_horaires?: HorairesPresentation[];
status?: OpeningState;
typologies?: string;
contact?: Contact;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
ModalitesAccompagnement
} from '@gouvfr-anct/lieux-de-mediation-numerique';
import { LieuMediationNumeriqueWithAidants, NO_LOCALISATION } from '../../../core/models';
import { geographicDistance, openingState, parseHoraires } from '../../../core/presenters';
import { geographicDistance, HorairesPresentation, openingState, parseHoraires } from '../../../core/presenters';
import { LieuxMediationNumeriqueRepository } from '../../../core/repositories';
import { ifAny } from '../../../core/utilities';
import {
Expand Down Expand Up @@ -470,6 +470,21 @@ const notEmpty = (
): ModaliteAccompagnementPresentation[] | undefined =>
modalitesAccompagnementPresentation.length > 0 ? modalitesAccompagnementPresentation : undefined;

const getHorairesWeeksByWeeks =
(date: Date) =>
(horaires: string): HorairesPresentation[] => {
return Array(5)
.fill(null)
.map((_, i) => parseHoraires(new Date(date.getTime() + i * 7 * 24 * 60 * 60 * 1000))(horaires))
.filter((horaires): horaires is HorairesPresentation => horaires != null)
.slice(1);
};

const ifAnyHorairesWithWeeks =
(date: Date) =>
(horaires?: string): HorairesPresentation[] | {} =>
horaires?.includes('week') ? ifAny('full_horaires', getHorairesWeeksByWeeks(date)(horaires)) : [];

export class LieuxMediationNumeriqueDetailsPresenter {
public constructor(private readonly lieuxMediationNumeriqueRepository: LieuxMediationNumeriqueRepository) {}

Expand Down Expand Up @@ -501,6 +516,7 @@ export class LieuxMediationNumeriqueDetailsPresenter {
code_postal: lieu.adresse.code_postal,
services: lieu.services,
...ifAny('horaires', parseHoraires(date)(lieu.horaires)),
...ifAnyHorairesWithWeeks(date)(lieu.horaires),
...ifAny('status', openingState(date)(lieu.horaires)),
...ifAny('typologies', lieu.typologies?.map((typologie) => typologieMatchingMap.get(typologie) || '').join(', ')),
...ifAny('contact', lieu.contact),
Expand Down
34 changes: 34 additions & 0 deletions src/features/core/presenters/horaires/horaires.presenter.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,40 @@ describe('horaires presenter', (): void => {
expect(timeTableOpeningHours).toStrictEqual(undefined);
});

it('should get horaires for odd week', (): void => {
const openingHours: string = 'week 1-53/2 Mo 09:30-12:30,13:30-15:30; PH off';
const date: Date = new Date('2022-07-22T09:00:00.000Z');

const timeTableOpeningHours = parseHoraires(date)(openingHours);

expect(timeTableOpeningHours).toStrictEqual({
Lundi: '09h30 - 12h30\n13h30 - 15h30',
Mardi: 'Fermé',
Mercredi: 'Fermé',
Jeudi: 'Fermé',
Vendredi: 'Fermé',
Samedi: 'Fermé',
Dimanche: 'Fermé'
});
});

it('should get horaires full closed if we are in even week', (): void => {
const openingHours: string = 'week 1-53/2 Mo 09:30-12:30,13:30-15:30; PH off';
const date: Date = new Date('2022-07-29T09:00:00.000Z');

const timeTableOpeningHours = parseHoraires(date)(openingHours);

expect(timeTableOpeningHours).toStrictEqual({
Lundi: 'Fermé',
Mardi: 'Fermé',
Mercredi: 'Fermé',
Jeudi: 'Fermé',
Vendredi: 'Fermé',
Samedi: 'Fermé',
Dimanche: 'Fermé'
});
});

it('should get Ouvert state', (): void => {
const openingHours: string = 'Mo-Fr 09:00-12:00,14:00-18:30; Sa 08:30-12:00';
const date: Date = new Date('2022-07-22T09:00:00.000Z');
Expand Down
16 changes: 15 additions & 1 deletion src/features/core/presenters/horaires/horaires.presenter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,13 @@ const initialTimeTableOpeningHours: HorairesPresentation = {
Samedi: 'Fermé',
Dimanche: 'Fermé'
};

export const parseHoraires =
(date: Date) =>
(horairesOSM?: string): HorairesPresentation | undefined => {
try {
return horairesOSM
? new opening_hours(horairesOSM)
? new opening_hours(horairesOSM, null)
.getOpenIntervals(firstTimeOfTheDay(firstDayOfTheWeek(date)), lastTimeOfTheDay(lastDayOfTheWeek(date)))
.reduce(
(
Expand Down Expand Up @@ -153,3 +154,16 @@ export const isOpenOn =
return false;
}
};

export const getIntervalWeekByOffset = (weekOffset: string | number, today: Date): string => {
const startOfTheWeek = new Date(today);
startOfTheWeek.setDate(today.getDate() - today.getDay() + 1);
startOfTheWeek.setDate(startOfTheWeek.getDate() + parseInt(weekOffset.toString()) * 7);
const endOfTheWeek = new Date(startOfTheWeek);
endOfTheWeek.setDate(startOfTheWeek.getDate() + 6);
const year = today.getFullYear().toString().slice(-2);

return `Du ${startOfTheWeek.toLocaleDateString().replace(/\/\d{4}/, `/${year}`)} au ${endOfTheWeek
.toLocaleDateString()
.replace(/\/\d{4}/, `/${year}`)}`;
};
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import { FilterPresentation } from '../filter';
import { LieuMediationNumeriquePresentation } from './lieu-mediation-numerique.presentation';
import { byBoundingBox } from './helpers/bounding-box';
import { byDistance, filteredLieuxMediationNumerique } from './helpers/filter';
import { LabelNational, LieuMediationNumerique, Localisation, Typologie } from '@gouvfr-anct/lieux-de-mediation-numerique';
import { LabelNational, LieuMediationNumerique, Localisation } from '@gouvfr-anct/lieux-de-mediation-numerique';
import { ResultFoundPresentation, Searchable } from '../../../adresse';
import { NO_LOCALISATION } from '../../models';
import { WithLieuxCount } from '../collectivite-territoriale';
Expand Down

0 comments on commit 4c80390

Please sign in to comment.