From 51bf2c7fcdec00aac2aced7db897596b668767b2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20PAILHAREY?= <rpailharey@grandlyon.com>
Date: Tue, 12 Mar 2024 09:58:55 +0000
Subject: [PATCH] feat(print): Update printed page

---
 src/app/app.component.scss                    |  12 +-
 .../enums/orientation.enums.ts                |   3 +-
 .../navigation/navigation.component.html      |  13 +-
 .../navigation/navigation.component.ts        |   4 +-
 .../orientation-recap.component.html          | 168 ++++++++++-----
 .../orientation-recap.component.scss          | 198 ++++++++----------
 .../orientation-recap.component.ts            |  33 ++-
 .../print-header/print-header.component.html  |  11 -
 .../print-header/print-header.component.scss  |  31 ---
 .../print-header/print-header.component.ts    |  21 --
 .../structure-orientator.component.scss       |   1 +
 .../appointment-end.component.html            |   8 +-
 .../appointment-end.component.ts              |  27 ++-
 .../make-appointment.component.ts             |   6 +-
 .../onlineDemarch-form.component.html         |  16 +-
 .../onlineDemarch-form.component.ts           |   6 +-
 .../orientation-form-view.component.html      |   5 +-
 .../orientation-form-view.component.scss      |  15 +-
 .../orientation-form-view.component.ts        | 102 ++++-----
 .../orientation.module.ts                     |   2 -
 src/app/models/structure.model.ts             |  26 +++
 src/app/profile/edit/edit.component.ts        |   4 +-
 src/app/shared/components/index.ts            |   6 +
 .../print-header/print-header.component.html  |  12 ++
 .../print-header/print-header.component.scss  |  61 ++++++
 .../print-header/print-header.component.ts    |  10 +
 .../print-structures-grid.component.html      |  36 ++++
 .../print-structures-grid.component.scss      |  69 ++++++
 .../print-structures-grid.component.ts        |  40 ++++
 ...structure-list-search-print.component.html |  61 ++----
 ...structure-list-search-print.component.scss |  86 ++------
 .../structure-list-search-print.component.ts  |  11 +-
 src/app/utils/orientationUtils.ts             |  41 +---
 src/assets/ico/searchPrintMarker.svg          |   5 -
 src/assets/ico/searchPrintStructure.svg       |  14 --
 src/assets/ico/sprite.svg                     |   6 +
 src/assets/scss/_typography.scss              |  27 +++
 src/assets/tags/sprite.svg                    |  28 +++
 src/styles.scss                               |  14 ++
 39 files changed, 745 insertions(+), 494 deletions(-)
 delete mode 100644 src/app/form/orientation-form-view/global-components/print-header/print-header.component.html
 delete mode 100644 src/app/form/orientation-form-view/global-components/print-header/print-header.component.scss
 delete mode 100644 src/app/form/orientation-form-view/global-components/print-header/print-header.component.ts
 create mode 100644 src/app/shared/components/print-header/print-header.component.html
 create mode 100644 src/app/shared/components/print-header/print-header.component.scss
 create mode 100644 src/app/shared/components/print-header/print-header.component.ts
 create mode 100644 src/app/shared/components/print-structures-grid/print-structures-grid.component.html
 create mode 100644 src/app/shared/components/print-structures-grid/print-structures-grid.component.scss
 create mode 100644 src/app/shared/components/print-structures-grid/print-structures-grid.component.ts
 delete mode 100644 src/assets/ico/searchPrintMarker.svg
 delete mode 100644 src/assets/ico/searchPrintStructure.svg

diff --git a/src/app/app.component.scss b/src/app/app.component.scss
index 4df7e2f2c..ee768c097 100644
--- a/src/app/app.component.scss
+++ b/src/app/app.component.scss
@@ -2,11 +2,13 @@
 @import 'color';
 @import 'layout';
 
-.app-container {
-  display: flex;
-  flex-direction: column;
-  height: 100%;
-  overflow-y: auto;
+@media not print {
+  .app-container {
+    display: flex;
+    flex-direction: column;
+    height: 100%;
+    overflow-y: auto;
+  }
 }
 
 @media print {
diff --git a/src/app/form/orientation-form-view/enums/orientation.enums.ts b/src/app/form/orientation-form-view/enums/orientation.enums.ts
index ef4c4b7b1..f6f0eced3 100644
--- a/src/app/form/orientation-form-view/enums/orientation.enums.ts
+++ b/src/app/form/orientation-form-view/enums/orientation.enums.ts
@@ -6,8 +6,9 @@ export enum AppointmentSteps {
   makeAppointment,
   mediationBeneficiaryInfo,
   structureOrientator,
-  rdvEnd,
   orientationRecap,
+  rdvEnd,
+  orientationPrint,
 }
 
 export enum FiltersSteps {
diff --git a/src/app/form/orientation-form-view/global-components/navigation/navigation.component.html b/src/app/form/orientation-form-view/global-components/navigation/navigation.component.html
index 6fba5574a..ee4229d05 100644
--- a/src/app/form/orientation-form-view/global-components/navigation/navigation.component.html
+++ b/src/app/form/orientation-form-view/global-components/navigation/navigation.component.html
@@ -1,7 +1,7 @@
 <div class="footerForm">
-  <ng-container *ngIf="!shouldResetOrientation">
+  <ng-container *ngIf="!failedOrientation">
     <app-button
-      *ngIf="currentStep !== null && !(isLastStep && needType === 'onlineDemarch')"
+      *ngIf="currentStep !== null && !(isPrevHidden || isLastStep)"
       [variant]="'secondary'"
       [label]="'Précédent'"
       [iconName]="'arrowBack'"
@@ -10,14 +10,15 @@
     <app-button
       *ngIf="!hideNavButtons"
       [variant]="'primary'"
-      [label]="isLastStep ? 'Terminer' : 'Suivant'"
-      [iconPosition]="!isLastStep ? 'right' : 'left'"
-      [iconName]="!isLastStep ? 'arrowForward' : null"
+      [label]="isLastStep ? 'Imprimer' : 'Suivant'"
+      [iconName]="isLastStep ? 'printer' : 'arrowForward'"
+      [iconPosition]="'right'"
+      [wide]="isPrevHidden || isLastStep ? true : false"
       [disabled]="!isPageValid"
       (action)="nextPage()"
     />
   </ng-container>
-  <ng-container *ngIf="shouldResetOrientation">
+  <ng-container *ngIf="failedOrientation">
     <app-button [variant]="'secondary'" [label]="'Cartographie'" (action)="goCarto()" />
     <app-button [variant]="'primary'" [label]="'Recommencer'" (action)="resetOrientation()" />
   </ng-container>
diff --git a/src/app/form/orientation-form-view/global-components/navigation/navigation.component.ts b/src/app/form/orientation-form-view/global-components/navigation/navigation.component.ts
index dbbc8fafc..2485d9024 100644
--- a/src/app/form/orientation-form-view/global-components/navigation/navigation.component.ts
+++ b/src/app/form/orientation-form-view/global-components/navigation/navigation.component.ts
@@ -13,9 +13,10 @@ export class NavigationComponent {
   @Input() currentType: OnlineDemarche | MediationType;
   @Input() isPageValid: boolean;
   @Input() needType: NeedsType;
+  @Input() isPrevHidden = false;
   @Input() isLastStep = false;
   @Input() hideNavButtons = false;
-  @Input() shouldResetOrientation = false;
+  @Input() failedOrientation = false;
 
   @Output() goNext = new EventEmitter<any>();
   @Output() goPrev = new EventEmitter<any>();
@@ -34,6 +35,7 @@ export class NavigationComponent {
     this.goPrev.emit();
   }
   public goCarto(): void {
+    this.goReset.emit();
     this.router.navigateByUrl('/acteurs');
   }
   public resetOrientation(): void {
diff --git a/src/app/form/orientation-form-view/global-components/orientation-recap/orientation-recap.component.html b/src/app/form/orientation-form-view/global-components/orientation-recap/orientation-recap.component.html
index 3d06e8202..608eb3a56 100644
--- a/src/app/form/orientation-form-view/global-components/orientation-recap/orientation-recap.component.html
+++ b/src/app/form/orientation-form-view/global-components/orientation-recap/orientation-recap.component.html
@@ -1,65 +1,123 @@
-<app-print-header />
-<div class="container" [ngClass]="{ onlineMediation: recap }">
-  <div class="main">
-    <div *ngIf="isOrientator()" class="orientator header">
-      <h3 class="uppercase">Orienté par</h3>
-      <div class="content">
-        <div class="infos structureName">{{ orientator.structureName }}</div>
-        <div *ngIf="orientator.structureMail" class="infos">{{ orientator.structureMail }}</div>
-        <div *ngIf="orientator.structurePhone" class="infos">{{ orientator.structurePhone }}</div>
+<app-print-header [isOnlineMediationRecap]="!isToPrint" />
+
+<div class="recapContainer">
+  <!-- Info text -->
+  <div class="show-on-print infos">
+    <div class="inline">
+      <app-svg-icon [iconClass]="'icon-20'" [folder]="'tags'" [icon]="'notification'" />
+      <h2>{{ getRecapTitle() }}</h2>
+    </div>
+    <p [innerHTML]="getRecapInfo()"></p>
+  </div>
+
+  <!-- Beneficiary info -->
+  <section>
+    <h3 class="sectionHeader uppercase">Bénéficiaire</h3>
+    <div class="content">
+      <div class="inline">
+        <app-svg-icon [iconClass]="'icon-20'" [folder]="'tags'" [icon]="'person'" />
+        <p>
+          <span class="category-name">Nom :</span>{{ beneficiary.name | userName }}
+          {{ beneficiary.surname | uppercase }}
+        </p>
+      </div>
+      <div class="inline">
+        <app-svg-icon [iconClass]="'icon-20'" [folder]="'tags'" [icon]="'questionAnswer'" />
+        <p><span class="category-name">Besoin(s) d'aide :</span>{{ getFormattedNeeds() }}</p>
+      </div>
+      <div *ngIf="recap?.language" class="inline">
+        <app-svg-icon [iconClass]="'icon-20'" [folder]="'tags'" [icon]="'website'" />
+        <p><span class="category-name">Langue souhaitée :</span>{{ recap.language }}</p>
       </div>
     </div>
-    <div class="beneficiary header">
-      <h3 class="uppercase">Bénéficiaire</h3>
-      <div class="content">
-        <div fxLayout="row">
-          <div class="label">Nom</div>
-          <div class="info">{{ beneficiary.name | userName }} {{ beneficiary.surname | uppercase }}</div>
-        </div>
-        <div fxLayout="row">
-          <div class="label">Besoin(s) d'aide</div>
-          <div class="info">
-            <div *ngFor="let need of needs">{{ need.displayText }}</div>
-          </div>
-        </div>
-        <div *ngIf="recap?.language" fxLayout="row">
-          <div class="label">Langue souhaitée</div>
-          <div class="info">
-            <div>{{ recap.language }}</div>
-          </div>
-        </div>
-        <div *ngIf="comment" fxLayout="row">
-          <div class="label">Précisions</div>
-          <div class="info">
-            <div>{{ comment }}</div>
-          </div>
-        </div>
+  </section>
+
+  <!-- Orientator -->
+  <section *ngIf="isOrientator()">
+    <h3 class="sectionHeader uppercase">Orienté par</h3>
+    <div class="content">
+      <div class="inline">
+        <app-svg-icon [iconClass]="'icon-20'" [folder]="'tags'" [icon]="'structureType'" />
+        <p><span class="category-name">Nom :</span>{{ orientator.structureName }}</p>
+      </div>
+      <div *ngIf="orientator.structureMail" class="inline">
+        <app-svg-icon [iconClass]="'icon-20'" [folder]="'tags'" [icon]="'mail'" />
+        <p><span class="category-name">Mail :</span>{{ orientator.structureMail }}</p>
+      </div>
+      <div *ngIf="orientator.structurePhone" class="inline">
+        <app-svg-icon [iconClass]="'icon-20'" [folder]="'tags'" [icon]="'phone'" />
+        <p><span class="category-name">Téléphone :</span>{{ orientator.structurePhone }}</p>
       </div>
     </div>
-  </div>
+  </section>
+
+  <!-- Appointment requested -->
+  <section *ngIf="shouldDisplayAppointmentRecap()">
+    <h3 class="sectionHeader uppercase">Demande de rendez-vous auprès de</h3>
+    <div class="content">
+      <div class="inline">
+        <app-svg-icon [iconClass]="'icon-20'" [folder]="'tags'" [icon]="'person'" />
+        <p>
+          <span class="category-name">Nom :</span>{{ socialWorker?.name | userName }}
+          {{ socialWorker?.surname | uppercase }}
+        </p>
+      </div>
+      <div class="inline">
+        <app-svg-icon [iconClass]="'icon-20'" [folder]="'tags'" [icon]="'structure'" />
+        <p><span class="category-name">Structure :</span>{{ structureRDV?.structureName }}</p>
+      </div>
+      <div class="inline">
+        <app-svg-icon [iconClass]="'icon-20'" [folder]="'tags'" [icon]="'address'" />
+        <p>
+          <span class="category-name">Lieu :</span>{{ structureRDV.address.numero }} {{ structureRDV.address.street }},
+          {{ structureRDV.address.commune }}
+        </p>
+      </div>
+      <div *ngIf="structureRDV?.contactPersonEmail" class="inline">
+        <app-svg-icon [iconClass]="'icon-20'" [folder]="'tags'" [icon]="'mail'" />
+        <p><span class="category-name">Mail :</span>{{ structureRDV?.contactPersonEmail }}</p>
+      </div>
+      <div *ngIf="structureRDV?.contactPhone" class="inline">
+        <app-svg-icon [iconClass]="'icon-20'" [folder]="'tags'" [icon]="'phone'" />
+        <p><span class="category-name">Téléphone :</span>{{ structureRDV?.contactPhone }}</p>
+      </div>
+    </div>
+  </section>
+
   <!-- Date display -->
-  <div *ngIf="recap" class="date">
-    <div class="bold">Informations du rendez-vous :</div>
-    <hr />
-    <div class="bold reminder">Le rappel se fera</div>
-    <span class="red bold">{{ recap.day }}</span
-    >&nbsp;<span class="red bold month">{{ recap.month }}</span
-    >&nbsp;<span>entre {{ recap.hours }}</span>
-  </div>
-  <div *ngFor="let structure of structuresToPrint" class="structure">
-    <!-- Structure list -->
-    <div class="title">Informations de la structure :</div>
-    <app-structure-detail-print [structure]="structure" />
-  </div>
+  <section *ngIf="recap">
+    <h3 class="sectionHeader uppercase">Information du rendez-vous</h3>
+    <div class="content">
+      <div class="inline">
+        <app-svg-icon [iconClass]="'icon-20'" [folder]="'tags'" [icon]="'timer'" />
+        <p>
+          <span class="category-name">Le rappel se fera :</span>
+          <span class="red bold">{{ recap.day }}</span
+          >&nbsp;<span class="red bold month">{{ recap.month }}</span
+          >&nbsp;<span>entre</span>&nbsp;<span class="big bold">{{ recap.hours }}</span>
+        </p>
+      </div>
+    </div>
+  </section>
+
+  <!-- Comment -->
+  <section *ngIf="comment">
+    <h3 class="sectionHeader uppercase">Commentaire</h3>
+    <div class="content">{{ comment }}</div>
+  </section>
+
+  <!-- Structure list -->
+  <app-print-structures-grid *ngIf="structuresToPrint" [structures]="structuresToPrint" />
 
   <!-- footer  -->
-  <div *ngIf="recap" class="service-info">
-    <hr />
+  <section *ngIf="recap" class="service-info">
     <div>Besoin d'autres aides avec vos outils numériques ?</div>
-    <div class="digitalAssistance">Votre numéro <span class="red">gratuit</span> d’assistance numérique</div>
-    <div class="number">04 83 43 90 40</div>
-    <div>
-      Appel gratuit de 15h à 17h du lundi au vendredi,<br />le jeudi jusqu’à 19h et le samedi matin de 10h à 12h.
+    <div class="call-info">
+      <div class="digitalAssistance">
+        <span class="number red">04 83 43 90 40</span><br class="hide-on-print" />
+        Votre numéro <span class="red">gratuit</span> d’assistance numérique
+      </div>
+      <div>Appel gratuit de 15h à 17h du lundi au vendredi, le jeudi jusqu’à 19h et le samedi matin de 10h à 12h.</div>
     </div>
-  </div>
+  </section>
 </div>
diff --git a/src/app/form/orientation-form-view/global-components/orientation-recap/orientation-recap.component.scss b/src/app/form/orientation-form-view/global-components/orientation-recap/orientation-recap.component.scss
index c636410a9..6eac91867 100644
--- a/src/app/form/orientation-form-view/global-components/orientation-recap/orientation-recap.component.scss
+++ b/src/app/form/orientation-form-view/global-components/orientation-recap/orientation-recap.component.scss
@@ -2,126 +2,114 @@
 @import 'typography';
 @import 'breakpoint';
 
-.container {
+.red {
+  color: $red;
+}
+
+.recapContainer {
   display: flex;
   flex-direction: column;
-  gap: 1em;
-  flex: 0 0 100%;
-  &.onlineMediation {
+  gap: 32px;
+  max-width: 600px;
+  margin-top: 32px;
+  @media print {
+    gap: 24px;
     margin-top: 24px;
   }
-  * {
-    print-color-adjust: exact;
-  }
-  .main,
-  .structure {
-    display: flex;
-    flex-direction: row;
-    gap: 1.5em;
-  }
-  .structure {
-    flex-flow: column;
-  }
-  .orientator,
-  .beneficiary {
-    flex-grow: 1;
-  }
-  .orientator {
-    flex: 2;
-  }
-  .beneficiary {
-    flex: 3;
-  }
-  ::ng-deep.structure-details-container {
+
+  .infos {
     display: flex;
-    gap: 2em;
-    margin: 0;
-  }
-  ::ng-deep.structureDetails {
-    flex: 2;
-    width: 30vw;
-  }
-  ::ng-deep.accessDetails {
-    padding: 0 !important;
-    flex: 3;
-    width: 50vw;
-  }
-  ::ng-deep.mobile-column {
-    gap: 2em;
-  }
-  .title {
-    @include font-bold-18;
-    padding-bottom: 1em;
-    border-bottom: 1px solid $grey-8;
-  }
-  h3 {
-    @include font-bold-14;
-    color: $grey-3;
-    margin-bottom: 1.5rem;
-    margin-top: 0.5rem;
+    flex-direction: column;
+    gap: 16px;
+
+    p {
+      @include font-regular-12;
+    }
+
+    h2 {
+      @include font-bold-18;
+    }
   }
 
-  .header {
-    background-color: $grey-8;
-    padding: 1rem 1.5rem;
+  section {
+    break-inside: avoid;
+    display: flex;
+    flex-direction: column;
+    gap: 24px;
+    padding: 24px;
+    border-radius: 8px;
+    border: 1px solid $grey-6;
+    @media print {
+      padding: 16px;
+    }
 
+    .sectionHeader {
+      @include font-bold-18;
+      @media print {
+        @include font-bold-14;
+      }
+    }
     .content {
-      color: $black;
-      .label {
-        @include font-regular-14;
-        margin-bottom: 1rem;
-        flex: 1 1 100%;
-        max-width: 20%;
+      display: flex;
+      flex-direction: column;
+      gap: 8px;
+      @include font-regular-14;
+      @media print {
+        @include font-regular-11;
       }
-      .info {
+
+      .category-name {
+        display: inline-block;
+        color: $grey-4-5-1;
+        print-color-adjust: exact;
         @include font-bold-14;
-        margin-bottom: 1rem;
-        max-width: 80%;
-        &.structureName {
-          @include font-bold-18;
+        width: 125px;
+        @media print {
+          @include font-bold-10;
+          width: 100px;
         }
       }
-    }
-  }
-}
-.date {
-  width: 100%;
-  box-sizing: border-box;
-  :first-child {
-    margin-bottom: 1rem;
-  }
-  .reminder {
-    margin-bottom: 0.5rem;
-  }
-  .bold {
-    font-weight: 700;
-  }
-  .month {
-    text-transform: capitalize;
-  }
-}
 
-.service-info {
-  color: $grey-3;
-  font-weight: 400;
+      @media not print {
+        .big {
+          @include font-regular-16;
+        }
+      }
+    }
 
-  display: flex;
-  flex-direction: column;
-  gap: 0.5rem;
+    &.service-info {
+      display: flex;
+      flex-direction: column;
+      gap: 8px;
+      color: $grey-4-5-1;
+      print-color-adjust: exact;
+      @include font-regular-16;
+      @media print {
+        @include font-regular-10;
+      }
 
-  .digitalAssistance {
-    @include font-bold-18;
-  }
-  .number {
-    @include font-bold-24;
-    color: $red;
+      .call-info {
+        display: flex;
+        flex-direction: column;
+        gap: 16px;
+        @include font-regular-14;
+        @media print {
+          gap: 8px;
+          @include font-regular-8;
+        }
+        .digitalAssistance {
+          @include font-regular-24;
+          @media print {
+            @include font-regular-16;
+          }
+          .number {
+            @include font-bold-24;
+            @media print {
+              @include font-bold-16;
+            }
+          }
+        }
+      }
+    }
   }
 }
-
-hr {
-  border: 1px solid $grey-6;
-  width: 100%;
-}
-.red {
-  color: $red;
-}
diff --git a/src/app/form/orientation-form-view/global-components/orientation-recap/orientation-recap.component.ts b/src/app/form/orientation-form-view/global-components/orientation-recap/orientation-recap.component.ts
index de9cc90c3..ea93a0f17 100644
--- a/src/app/form/orientation-form-view/global-components/orientation-recap/orientation-recap.component.ts
+++ b/src/app/form/orientation-form-view/global-components/orientation-recap/orientation-recap.component.ts
@@ -17,6 +17,7 @@ export class OrientationRecapComponent implements OnInit {
   @Input() recapType: RecapsType;
   @Input() socialWorker?: Owner;
   @Input() structureRDV?: Structure;
+  @Input() isToPrint = true;
   @Output() checkValidation = new EventEmitter<any>();
 
   public utils = new Utils();
@@ -73,7 +74,7 @@ export class OrientationRecapComponent implements OnInit {
   }
 
   public isOrientator(): boolean {
-    return !!this.orientator?.structureName;
+    return Boolean(this.orientator?.structureName);
   }
 
   public handleOnlineOrientationRecap(): void {
@@ -89,4 +90,34 @@ export class OrientationRecapComponent implements OnInit {
       language: this.form.get('preferredLanguage').value,
     };
   }
+
+  public getRecapInfo(): string {
+    switch (this.recapType) {
+      case RecapsType.onlineMediation:
+        return 'Vous avez effectué une demande de rendez-vous. vous serez contacté(e) par le professionnel pour convenir d’une date.';
+      case RecapsType.appointment:
+        return 'Votre demande de rendez-vous d’aide numérique a bien été envoyée.<br>Un·e professionnel·le vous rappellera pour fixer une date.';
+      case RecapsType.structure:
+        return 'Pour utiliser votre ordinateur ou smartphone, aller sur internet, réaliser une démarche...<br>Vous pouvez trouver de l’aide ou du matériel dans les lieux suivants.<br>Si possible, appelez-les avant d’y aller pour connaître les horaires et les aides proposées.';
+      default:
+        throw new Error(`Not implemented recap type ${this.recapType}`);
+    }
+  }
+
+  public getRecapTitle(): string {
+    switch (this.recapType) {
+      case RecapsType.onlineMediation:
+        return 'Demander un rendez-vous';
+      case RecapsType.appointment:
+        return 'Demande de rendez-vous d’aide numérique';
+      case RecapsType.structure:
+        return 'Besoin d’aide avec le numérique ?';
+      default:
+        throw new Error(`Not implemented recap type ${this.recapType}`);
+    }
+  }
+
+  public getFormattedNeeds(): string {
+    return this.needs.map((n) => n.displayText).join(', ');
+  }
 }
diff --git a/src/app/form/orientation-form-view/global-components/print-header/print-header.component.html b/src/app/form/orientation-form-view/global-components/print-header/print-header.component.html
deleted file mode 100644
index ea76cf03f..000000000
--- a/src/app/form/orientation-form-view/global-components/print-header/print-header.component.html
+++ /dev/null
@@ -1,11 +0,0 @@
-<div class="header-print">
-  <div class="header-infos">
-    <img src="../../../../../assets/logos/metropoleGrandLyon-red.svg" alt="logo métropole" />
-    <div class="header-title">
-      <div>Réseau des acteurs de l'inclusion numérique de la Métropole de Lyon</div>
-      <h3>Fiche d'orientation</h3>
-    </div>
-  </div>
-  <p class="informationHeader date">{{ date }}</p>
-</div>
-<hr />
diff --git a/src/app/form/orientation-form-view/global-components/print-header/print-header.component.scss b/src/app/form/orientation-form-view/global-components/print-header/print-header.component.scss
deleted file mode 100644
index b28968a26..000000000
--- a/src/app/form/orientation-form-view/global-components/print-header/print-header.component.scss
+++ /dev/null
@@ -1,31 +0,0 @@
-@import 'color';
-@import 'typography';
-
-.header-infos {
-  display: flex;
-  align-items: center;
-  margin-bottom: 2rem;
-  h3 {
-    @include font-bold-16;
-    margin-top: 0.25rem;
-    margin-bottom: 0;
-  }
-  img {
-    margin-right: 3rem;
-    width: 160px;
-  }
-}
-.date {
-  @include font-regular-13;
-  text-align: right;
-  text-transform: capitalize;
-  font-style: italic;
-  font-weight: 400;
-  color: $grey-3;
-  margin: 0;
-}
-hr {
-  border: 1px solid $grey-6;
-  width: 100%;
-  margin-top: 0.5rem;
-}
diff --git a/src/app/form/orientation-form-view/global-components/print-header/print-header.component.ts b/src/app/form/orientation-form-view/global-components/print-header/print-header.component.ts
deleted file mode 100644
index 8ea2cb208..000000000
--- a/src/app/form/orientation-form-view/global-components/print-header/print-header.component.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-import { Component, OnInit } from '@angular/core';
-
-@Component({
-  selector: 'app-print-header',
-  templateUrl: './print-header.component.html',
-  styleUrls: ['./print-header.component.scss'],
-})
-export class PrintHeaderComponent implements OnInit {
-  public date: string;
-
-  ngOnInit(): void {
-    this.date = new Date().toLocaleDateString('fr-FR', {
-      weekday: 'long',
-      year: 'numeric',
-      month: 'long',
-      day: 'numeric',
-      hour: 'numeric',
-      minute: 'numeric',
-    });
-  }
-}
diff --git a/src/app/form/orientation-form-view/global-components/structure-orientator/structure-orientator.component.scss b/src/app/form/orientation-form-view/global-components/structure-orientator/structure-orientator.component.scss
index 93067451d..4d601ad20 100644
--- a/src/app/form/orientation-form-view/global-components/structure-orientator/structure-orientator.component.scss
+++ b/src/app/form/orientation-form-view/global-components/structure-orientator/structure-orientator.component.scss
@@ -7,6 +7,7 @@
   display: flex;
   flex-direction: column;
   gap: 16px;
+  width: 600px;
   .number {
     color: $grey-3;
     @include font-regular-18;
diff --git a/src/app/form/orientation-form-view/online-demarch/appointment/appointment-end/appointment-end.component.html b/src/app/form/orientation-form-view/online-demarch/appointment/appointment-end/appointment-end.component.html
index 5f82bce50..ae7ab85ed 100644
--- a/src/app/form/orientation-form-view/online-demarch/appointment/appointment-end/appointment-end.component.html
+++ b/src/app/form/orientation-form-view/online-demarch/appointment/appointment-end/appointment-end.component.html
@@ -16,8 +16,12 @@
 <!-- Hotline appointment success -->
 <div *ngIf="isOnlineMediation" class="container">
   <img src="../../../../../../assets/form/structureCreated.svg" alt="rdv illustration" />
-  <h2>Votre demande de médiation à distance a été transmise&nbsp;!</h2>
-  <p>La demande de <b>médiation à distance</b> a bien été transmise.</p>
+  <h2>Votre demande de rappel téléphonique a été transmise&nbsp;!</h2>
+  <p>
+    La personne sera rappelée sur le créneau choisi pour {{ needs.length > 1 ? 'les besoins' : 'le besoin' }} "<b
+      >{{ getFormattedNeeds() }}"</b
+    >.
+  </p>
 </div>
 
 <!-- No structure found -->
diff --git a/src/app/form/orientation-form-view/online-demarch/appointment/appointment-end/appointment-end.component.ts b/src/app/form/orientation-form-view/online-demarch/appointment/appointment-end/appointment-end.component.ts
index 9688588a2..70926de0e 100644
--- a/src/app/form/orientation-form-view/online-demarch/appointment/appointment-end/appointment-end.component.ts
+++ b/src/app/form/orientation-form-view/online-demarch/appointment/appointment-end/appointment-end.component.ts
@@ -2,8 +2,8 @@ import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
 import { UntypedFormGroup } from '@angular/forms';
 import { Owner } from '../../../../../models/owner.model';
 import { Structure } from '../../../../../models/structure.model';
-import { NotificationService } from '../../../../../services/notification.service';
 import { OrientationService } from '../../../../../services/orientation.service';
+import { Module } from '../../../../../structure-list/models/module.model';
 
 @Component({
   selector: 'app-appointment-end',
@@ -16,26 +16,25 @@ export class AppointmentEndComponent implements OnInit {
   @Input() socialWorker?: Owner;
   @Input() selectedStructureRDV?: Structure;
   @Input() isOnlineMediation = false;
-  @Output() setResetOrientation = new EventEmitter();
   @Output() checkValidation = new EventEmitter<any>();
 
   public hasStructure = false;
+  public needs: Module[];
 
-  constructor(
-    private notificationService: NotificationService,
-    public orientationService: OrientationService,
-  ) {}
+  constructor(public orientationService: OrientationService) {}
 
   async ngOnInit(): Promise<void> {
     this.checkValidation.emit();
-    if (this.form.get('structureRDV').value || this.structureRDV) this.hasStructure = true;
-    try {
-      if (!this.structureRDV) {
-        this.setResetOrientation.emit();
-      }
-    } catch (error) {
-      console.error(error);
-      this.notificationService.showError('Une erreur est survenue', error.message);
+    if (this.isOnlineMediation) {
+      this.needs = this.form.get('filters').value;
+      return;
     }
+    if (this.form.get('structureRDV').value || this.structureRDV) {
+      this.hasStructure = true;
+    }
+  }
+
+  public getFormattedNeeds(): string {
+    return this.needs.map((n) => n.displayText).join(', ');
   }
 }
diff --git a/src/app/form/orientation-form-view/online-demarch/appointment/make-appointment/make-appointment.component.ts b/src/app/form/orientation-form-view/online-demarch/appointment/make-appointment/make-appointment.component.ts
index 31d331e56..543e9f72f 100644
--- a/src/app/form/orientation-form-view/online-demarch/appointment/make-appointment/make-appointment.component.ts
+++ b/src/app/form/orientation-form-view/online-demarch/appointment/make-appointment/make-appointment.component.ts
@@ -17,7 +17,7 @@ export class MakeAppointmentComponent implements OnInit {
   @Input() structureRDV: Structure;
   @Output() checkValidation = new EventEmitter<any>();
   @Output() socialWorker = new EventEmitter<Owner>();
-  @Output() setResetOrientation = new EventEmitter();
+  @Output() failedOrientation = new EventEmitter<void>();
   @Output() selectedStructureRDV = new EventEmitter<Structure>();
 
   public owners: Owner[];
@@ -85,7 +85,7 @@ export class MakeAppointmentComponent implements OnInit {
         this.owners = filteredOwners;
 
         if (this.owners.length === 0) {
-          this.setResetOrientation.emit();
+          this.failedOrientation.emit();
         }
       });
     } else if (this.orientationService.rdvUser) {
@@ -124,7 +124,7 @@ export class MakeAppointmentComponent implements OnInit {
         this.structures = filteredStructures;
 
         if (this.structures.length === 0) {
-          this.setResetOrientation.emit();
+          this.failedOrientation.emit();
         }
         this.structuresListReady = true;
       });
diff --git a/src/app/form/orientation-form-view/online-demarch/onlineDemarch-form.component.html b/src/app/form/orientation-form-view/online-demarch/onlineDemarch-form.component.html
index de89d9d6a..3dd7e4bf1 100644
--- a/src/app/form/orientation-form-view/online-demarch/onlineDemarch-form.component.html
+++ b/src/app/form/orientation-form-view/online-demarch/onlineDemarch-form.component.html
@@ -52,7 +52,7 @@
     (checkValidation)="checkValidation()"
     (socialWorker)="getSocialWorker($event)"
     (selectedStructureRDV)="getSelectedStructureRDV($event)"
-    (setResetOrientation)="showResetOrientation()"
+    (failedOrientation)="setFailedOrientation()"
   />
   <app-mediation-beneficiary-info
     *ngIf="currentStep === OnlineDemarchesAppointmentSteps.mediationBeneficiaryInfo"
@@ -66,6 +66,15 @@
     [form]="form"
     (validatePage)="checkValidation()"
   />
+  <app-orientation-recap
+    *ngIf="currentStep === OnlineDemarchesAppointmentSteps.orientationRecap"
+    [form]="form"
+    [recapType]="RecapsType.appointment"
+    [socialWorker]="socialWorker"
+    [structureRDV]="structureRDV"
+    [isToPrint]="false"
+    (checkValidation)="checkValidation()"
+  />
   <app-appointment-end
     *ngIf="currentStep === OnlineDemarchesAppointmentSteps.rdvEnd"
     [form]="form"
@@ -73,10 +82,9 @@
     [selectedStructureRDV]="selectedStructureRDV"
     [socialWorker]="socialWorker"
     (checkValidation)="checkValidation()"
-    (setResetOrientation)="showResetOrientation()"
   />
   <app-orientation-recap
-    *ngIf="currentStep === OnlineDemarchesAppointmentSteps.orientationRecap"
+    *ngIf="currentStep === OnlineDemarchesAppointmentSteps.orientationPrint"
     [form]="form"
     [recapType]="RecapsType.appointment"
     [socialWorker]="socialWorker"
@@ -121,6 +129,7 @@
     *ngIf="currentStep === HotlineMediationSteps.orientationRecap"
     [form]="form"
     [recapType]="RecapsType.onlineMediation"
+    [isToPrint]="false"
     (checkValidation)="checkValidation()"
   />
   <app-appointment-end
@@ -128,7 +137,6 @@
     [form]="form"
     [isOnlineMediation]="true"
     (checkValidation)="checkValidation()"
-    (setResetOrientation)="showResetOrientation()"
   />
   <app-orientation-recap
     *ngIf="currentStep === HotlineMediationSteps.orientationPrint"
diff --git a/src/app/form/orientation-form-view/online-demarch/onlineDemarch-form.component.ts b/src/app/form/orientation-form-view/online-demarch/onlineDemarch-form.component.ts
index 6a54df0c4..14f707988 100644
--- a/src/app/form/orientation-form-view/online-demarch/onlineDemarch-form.component.ts
+++ b/src/app/form/orientation-form-view/online-demarch/onlineDemarch-form.component.ts
@@ -36,7 +36,7 @@ export class OnlineDemarchFormComponent {
   @Input() selectedStructureRDV: Structure;
   @Output() validatePage = new EventEmitter<any>();
   @Output() validateStructureRDV = new EventEmitter<Structure>();
-  @Output() setResetOrientation = new EventEmitter<any>();
+  @Output() failedOrientation = new EventEmitter<any>();
 
   public orientationUtils = new OrientationUtils();
   public pagesValidation: any[] = [];
@@ -156,7 +156,7 @@ export class OnlineDemarchFormComponent {
     this.orientationUtils.manuallySetOfPmr(this.filters, event);
     this.checkValidation();
   }
-  public showResetOrientation(): void {
-    this.setResetOrientation.emit();
+  public setFailedOrientation(): void {
+    this.failedOrientation.emit();
   }
 }
diff --git a/src/app/form/orientation-form-view/orientation-form-view.component.html b/src/app/form/orientation-form-view/orientation-form-view.component.html
index b0cc37f06..8586848e5 100644
--- a/src/app/form/orientation-form-view/orientation-form-view.component.html
+++ b/src/app/form/orientation-form-view/orientation-form-view.component.html
@@ -42,18 +42,19 @@
         [structureRDV]="orientationService.rdvStructure"
         (validatePage)="validatePage($event)"
         (validateStructureRDV)="validateStructureRDV($event)"
-        (setResetOrientation)="setResetOrientation()"
+        (failedOrientation)="setFailedOrientation()"
       />
     </ng-container>
   </div>
   <app-navigation
     [currentStep]="currentStep"
+    [isPrevHidden]="isPrevHidden"
     [isLastStep]="isLastStep"
     [needType]="needType"
     [currentType]="currentType"
     [isPageValid]="isPageValid"
     [hideNavButtons]="hideNavButtons"
-    [shouldResetOrientation]="shouldResetOrientation"
+    [failedOrientation]="failedOrientation"
     (goNext)="nextPage()"
     (goPrev)="prevPage()"
     (goReset)="reset()"
diff --git a/src/app/form/orientation-form-view/orientation-form-view.component.scss b/src/app/form/orientation-form-view/orientation-form-view.component.scss
index d94a71fe7..9da32468d 100644
--- a/src/app/form/orientation-form-view/orientation-form-view.component.scss
+++ b/src/app/form/orientation-form-view/orientation-form-view.component.scss
@@ -3,10 +3,12 @@
 @import 'layout';
 @import 'typography';
 
-:host {
-  display: flex;
-  flex-direction: column;
-  flex: 1;
+@media not print {
+  :host {
+    display: flex;
+    flex-direction: column;
+    flex: 1;
+  }
 }
 
 .orientation {
@@ -22,9 +24,12 @@
     @media #{$tablet} {
       padding: 1rem;
     }
+    @media print {
+      padding: 0;
+    }
   }
   .no-max-width {
-    max-width: none;
+    width: 100%;
     padding: 0;
   }
 }
diff --git a/src/app/form/orientation-form-view/orientation-form-view.component.ts b/src/app/form/orientation-form-view/orientation-form-view.component.ts
index 05e2e1a6b..999edc2d6 100644
--- a/src/app/form/orientation-form-view/orientation-form-view.component.ts
+++ b/src/app/form/orientation-form-view/orientation-form-view.component.ts
@@ -71,6 +71,7 @@ export class OrientationFormViewComponent implements OnInit, AfterContentChecked
   public previousNeedType: NeedsType;
   public currentType: MediationType = OnlineDemarche.common;
   public currentStep: MediationStepType = null;
+  public isPrevHidden = false;
   public isLastStep = false;
   public hideNavButtons = false;
   public nbSteps = OrientationFormViewComponent.MAX_STEP;
@@ -80,7 +81,7 @@ export class OrientationFormViewComponent implements OnInit, AfterContentChecked
   public canDeactivate = false;
   public showLoginModal = false;
   public fullScreen = false;
-  public shouldResetOrientation = false;
+  public failedOrientation = false;
   // Categories
   public categories: Record<string, Category> = {
     age: {
@@ -201,21 +202,39 @@ export class OrientationFormViewComponent implements OnInit, AfterContentChecked
     }
   }
 
+  private currentStepIs(orientationType: MediationType, orientationStep: MediationStepType): boolean {
+    return this.currentType === orientationType && this.currentStep === orientationStep;
+  }
+
+  private isOnlineDemarcheOrLearnSkills(): boolean {
+    return this.needType === NeedsType.onlineDemarch || this.needType === NeedsType.learnSkills;
+  }
+  /**
+   * In online procedures (online mediation and appointment), a request is sent to the server before the orientation
+   * summary. isPrevHidden flag prevents from going back in the form after validation.
+   */
+  public checkPrevHidden(): void {
+    const isOnlineMediationSuccess = this.currentStepIs(OnlineDemarche.onlineMediation, HotlineMediationSteps.rdvEnd);
+    const isAppointmentSuccess = this.currentStepIs(OnlineDemarche.appointment, AppointmentSteps.rdvEnd);
+    this.isPrevHidden = this.isOnlineDemarcheOrLearnSkills() && (isOnlineMediationSuccess || isAppointmentSuccess);
+  }
+
   public checkLastStep(): void {
-    const isOnlineDemarcheOrLearnSkills =
-      this.needType === NeedsType.onlineDemarch || this.needType === NeedsType.learnSkills;
-    const isOnlineMediationOrientationRecap =
-      isOnlineDemarcheOrLearnSkills &&
-      this.currentType === OnlineDemarche.onlineMediation &&
-      this.currentStep === HotlineMediationSteps.orientationPrint;
-    const isStructureListOrientationRecap =
-      this.currentType === OnlineDemarche.structureList && this.currentStep === StructuresListSteps.orientationRecap;
-    const isAppointmentOrientationRecap =
-      isOnlineDemarcheOrLearnSkills &&
-      this.currentType === OnlineDemarche.appointment &&
-      this.currentStep === AppointmentSteps.orientationRecap;
+    const isStructureListOrientationRecap = this.currentStepIs(
+      OnlineDemarche.structureList,
+      StructuresListSteps.orientationRecap,
+    );
+    const isAppointmentOrientationRecap = this.currentStepIs(
+      OnlineDemarche.appointment,
+      AppointmentSteps.orientationPrint,
+    );
+    const isOnlineMediationOrientationRecap = this.currentStepIs(
+      OnlineDemarche.onlineMediation,
+      HotlineMediationSteps.orientationPrint,
+    );
     this.isLastStep =
-      isOnlineMediationOrientationRecap || isStructureListOrientationRecap || isAppointmentOrientationRecap;
+      isStructureListOrientationRecap ||
+      (this.isOnlineDemarcheOrLearnSkills() && (isAppointmentOrientationRecap || isOnlineMediationOrientationRecap));
   }
 
   /**
@@ -224,11 +243,9 @@ export class OrientationFormViewComponent implements OnInit, AfterContentChecked
   public async handleAppointment(): Promise<void> {
     const appointment: IAppointment = {
       ...this.onlineDemarcheForm.value,
+      onlineDemarcheType: this.onlineDemarcheForm.value.onlineDemarcheType.filter((item) => item.name !== 'pmrAccess'),
     };
 
-    // pmrAccess filter must not be send in the onlineDemarcheType array of the appointment
-    appointment.onlineDemarcheType = appointment.onlineDemarcheType.filter((item) => item.name !== 'pmrAccess');
-
     await lastValueFrom(this.orientationService.createAppointment(appointment));
     this.canDeactivate = true;
   }
@@ -361,11 +378,7 @@ export class OrientationFormViewComponent implements OnInit, AfterContentChecked
     this.isPageValid = false;
     this.hideNavButtons = false;
     // Handle filters form
-    if (
-      this.isFilterForm() &&
-      this.currentType === GenericOrientationSteps.common &&
-      this.currentStep === FiltersSteps.filterChoice
-    ) {
+    if (this.isFilterForm() && this.currentStepIs(GenericOrientationSteps.common, FiltersSteps.filterChoice)) {
       this.indicatorNeedType = this.needType;
       switch (this.needType) {
         case NeedsType.equipmentAccess:
@@ -398,44 +411,34 @@ export class OrientationFormViewComponent implements OnInit, AfterContentChecked
     // Online demarches or learn skills
     if (this.needType === NeedsType.onlineDemarch || this.needType === NeedsType.learnSkills) {
       if (
-        this.currentType === OnlineDemarche.common &&
-        this.currentStep === OnlineDemarchesCommonSteps.accompanimentType - 1 &&
+        this.currentStepIs(OnlineDemarche.common, OnlineDemarchesCommonSteps.accompanimentType - 1) &&
         (this.orientationService.rdvStructure || this.orientationService.rdvUser)
       ) {
         this.onlineDemarcheForm.get('accompanimentType').patchValue(OnlineDemarche.appointment);
         this.currentStep++;
       }
 
-      if (
-        this.currentType === OnlineDemarche.common &&
-        this.currentStep === OnlineDemarchesCommonSteps.accompanimentType
-      ) {
+      if (this.currentStepIs(OnlineDemarche.common, OnlineDemarchesCommonSteps.accompanimentType)) {
         this.setOnlineProcedureFilters();
         this.setOnlineProceduresForm();
         this.previousNeedType = this.needType;
         return;
       }
       // If no multiple structures, skip orientator
-      if (
-        this.currentType === OnlineDemarche.onlineMediation &&
-        this.currentStep === HotlineMediationSteps.structureOrientator - 1
-      ) {
+      if (this.currentStepIs(OnlineDemarche.onlineMediation, HotlineMediationSteps.structureOrientator - 1)) {
         this.skipStructureOrientator(true);
       }
       // Handle Online appointment
-      if (
-        this.currentType === OnlineDemarche.onlineMediation &&
-        this.currentStep === HotlineMediationSteps.rdvEnd - 1
-      ) {
+      if (this.currentStepIs(OnlineDemarche.onlineMediation, HotlineMediationSteps.rdvEnd - 1)) {
         await this.handleOnlineAppointment();
       }
       // Handle last screen Online appointment and print
-      if (this.currentStep === HotlineMediationSteps.orientationPrint) {
+      if (this.currentStepIs(OnlineDemarche.onlineMediation, HotlineMediationSteps.orientationPrint)) {
         this.printForm();
         return;
       }
       // Handle last screen appointment
-      if (this.currentType === OnlineDemarche.appointment && this.currentStep === AppointmentSteps.rdvEnd - 1) {
+      if (this.currentStepIs(OnlineDemarche.appointment, AppointmentSteps.rdvEnd - 1)) {
         try {
           await this.handleAppointment();
         } catch (e) {
@@ -484,6 +487,7 @@ export class OrientationFormViewComponent implements OnInit, AfterContentChecked
           ).length === 0
         ) {
           this.sendOrientationIndicator(this.structureOrientationForm ?? this.onlineDemarcheForm);
+          this.failedOrientation = true;
           this.currentStep = AppointmentSteps.rdvEnd - 1;
         }
       }
@@ -498,18 +502,15 @@ export class OrientationFormViewComponent implements OnInit, AfterContentChecked
         this.fullScreen = false;
       }
 
-      // after last page, go to new orientation
-      if (this.currentStep === AppointmentSteps.orientationRecap) {
-        this.sendOrientationIndicator(this.structureOrientationForm ?? this.onlineDemarcheForm);
-        history.pushState({ rdvStructure: null, rdvUser: null }, '', '/orientation');
-        window.location.reload();
+      // After last page, print and go to new orientation
+      if (this.currentStep === AppointmentSteps.orientationPrint) {
+        this.printForm();
         return;
       }
     }
 
     if (
-      this.currentType === OnlineDemarche.appointment &&
-      this.currentStep === AppointmentSteps.pmrAccess - 1 &&
+      this.currentStepIs(OnlineDemarche.appointment, AppointmentSteps.pmrAccess - 1) &&
       (this.orientationService.rdvStructure || this.orientationService.rdvUser)
     ) {
       if (this.orientationService.rdvStructure) {
@@ -527,6 +528,7 @@ export class OrientationFormViewComponent implements OnInit, AfterContentChecked
     }
     if (this.currentStep < this.nbSteps) {
       this.currentStep++;
+      this.checkPrevHidden();
       this.checkLastStep();
       this.checkHideNavButtons();
     }
@@ -607,6 +609,7 @@ export class OrientationFormViewComponent implements OnInit, AfterContentChecked
     }
     if (this.currentStep > 0) {
       this.currentStep--;
+      this.checkPrevHidden();
       this.checkLastStep();
       this.checkHideNavButtons();
     }
@@ -619,7 +622,7 @@ export class OrientationFormViewComponent implements OnInit, AfterContentChecked
     this.currentStep = null;
     this.currentType = OnlineDemarche.common;
     this.isLastStep = false;
-    this.shouldResetOrientation = false;
+    this.failedOrientation = false;
     this.nbSteps = OrientationFormViewComponent.MAX_STEP;
     this.isPageValid = false;
     this.needType = undefined;
@@ -734,14 +737,13 @@ export class OrientationFormViewComponent implements OnInit, AfterContentChecked
   public checkHideNavButtons(): void {
     if (
       (this.needType === NeedsType.onlineDemarch || this.needType === NeedsType.learnSkills) &&
-      this.currentType === OnlineDemarche.appointment &&
-      this.currentStep === AppointmentSteps.carto
+      this.currentStepIs(OnlineDemarche.appointment, AppointmentSteps.carto)
     ) {
       this.hideNavButtons = true;
     }
   }
-  public setResetOrientation(): void {
-    this.shouldResetOrientation = true;
+  public setFailedOrientation(): void {
+    this.failedOrientation = true;
   }
   public handleClose(value: boolean): void {
     if (value) {
diff --git a/src/app/form/orientation-form-view/orientation.module.ts b/src/app/form/orientation-form-view/orientation.module.ts
index 6a93092dd..7e1f27cab 100644
--- a/src/app/form/orientation-form-view/orientation.module.ts
+++ b/src/app/form/orientation-form-view/orientation.module.ts
@@ -11,7 +11,6 @@ import { InformationScreenComponent } from './global-components/information-scre
 import { NavigationComponent } from './global-components/navigation/navigation.component';
 import { NeedsSelectionComponent } from './global-components/needs-selection/needs-selection.component';
 import { OrientationRecapComponent } from './global-components/orientation-recap/orientation-recap.component';
-import { PrintHeaderComponent } from './global-components/print-header/print-header.component';
 import { SelectComponent } from './global-components/select/select.component';
 import { StructureOrientatorComponent } from './global-components/structure-orientator/structure-orientator.component';
 import { AppointmentEndComponent } from './online-demarch/appointment/appointment-end/appointment-end.component';
@@ -39,7 +38,6 @@ import { OrientationStructureListComponent } from './orientation-structure-list/
     MediationHoursSelectionComponent,
     OrientationRecapComponent,
     OnlineDemarchFormComponent,
-    PrintHeaderComponent,
     OrientationStructureListComponent,
     OrientationStructureAddressComponent,
     EquipmentBuyTypeComponent,
diff --git a/src/app/models/structure.model.ts b/src/app/models/structure.model.ts
index 15e77b70d..963697a83 100644
--- a/src/app/models/structure.model.ts
+++ b/src/app/models/structure.model.ts
@@ -119,6 +119,28 @@ export class Structure {
     return false;
   }
 
+  /**
+   * Check if a structure proposes help with online administration
+   */
+  public hasFreeOnlineHelp(): boolean {
+    const personalOffers = this.personalOffers.map((po) => po.categories.onlineProcedures);
+    return Boolean(this.categories.onlineProcedures?.length || personalOffers.length);
+  }
+
+  /**
+   * Sells material at solidarity cost
+   */
+  public hasSolidarityMaterial(): boolean {
+    return Boolean(this.categories.solidarityMaterial?.length);
+  }
+
+  /**
+   * Check if a structure has pass Numeric label
+   */
+  public hasPassNumeric(): boolean {
+    return this.categories.labelsQualifications.includes('passNumerique');
+  }
+
   /**
    * Return a range, according to the distance, between [1,3] to get a distance reference.
    * - [0,5km] => 1
@@ -171,6 +193,10 @@ export class Structure {
     );
   }
 
+  public hasFreeWorkshops(): boolean {
+    return this.freeWorkShop !== FreeWorkshop.no;
+  }
+
   public getFreeWorkshopLabel(): string {
     const isFree = this.freeWorkShop !== FreeWorkshop.no;
     const isUnderCondition = this.freeWorkShop === FreeWorkshop.underCondition;
diff --git a/src/app/profile/edit/edit.component.ts b/src/app/profile/edit/edit.component.ts
index 3f9c18914..3802c9f58 100644
--- a/src/app/profile/edit/edit.component.ts
+++ b/src/app/profile/edit/edit.component.ts
@@ -113,7 +113,7 @@ export class EditComponent implements OnInit {
   }
 
   public phoneValid(): boolean {
-    return !!this.userProfile.phone.match(CustomRegExp.PHONE);
+    return Boolean(this.userProfile.phone.match(CustomRegExp.PHONE));
   }
   public nameValid(): boolean {
     return this.userProfile.name !== '';
@@ -125,7 +125,7 @@ export class EditComponent implements OnInit {
     return this.userProfile.description?.length <= 500;
   }
   public emailValid(email: string): boolean {
-    return !!RegExp(CustomRegExp.EMAIL).exec(email);
+    return Boolean(RegExp(CustomRegExp.EMAIL).exec(email));
   }
 
   public getEmailStatus(email: string): 'success' | 'error' {
diff --git a/src/app/shared/components/index.ts b/src/app/shared/components/index.ts
index 5b8843267..7db8c69e0 100644
--- a/src/app/shared/components/index.ts
+++ b/src/app/shared/components/index.ts
@@ -20,6 +20,8 @@ import { InputComponent } from './input/input.component';
 import { LogoCardComponent } from './logo-card/logo-card.component';
 import { MemberCardComponent } from './member-card/member-card.component';
 import { ModalComponent } from './modal/modal.component';
+import { PrintHeaderComponent } from './print-header/print-header.component';
+import { PrintStructuresGridComponent } from './print-structures-grid/print-structures-grid.component';
 import { RadioOptionComponent } from './radio-option/radio-option.component';
 import { RadioComponent } from './radio/radio.component';
 import { SearchBarComponent } from './search-bar/search-bar.component';
@@ -48,6 +50,8 @@ export {
   LogoCardComponent,
   MemberCardComponent,
   ModalComponent,
+  PrintHeaderComponent,
+  PrintStructuresGridComponent,
   ProgressBarComponent,
   RadioOptionComponent,
   StructureDetailPrintComponent,
@@ -82,6 +86,8 @@ export const SharedComponents = [
   LogoCardComponent,
   ModalComponent,
   ProgressBarComponent,
+  PrintHeaderComponent,
+  PrintStructuresGridComponent,
   RadioOptionComponent,
   RadioComponent,
   SearchBarComponent,
diff --git a/src/app/shared/components/print-header/print-header.component.html b/src/app/shared/components/print-header/print-header.component.html
new file mode 100644
index 000000000..60777ce78
--- /dev/null
+++ b/src/app/shared/components/print-header/print-header.component.html
@@ -0,0 +1,12 @@
+<div class="container">
+  <h2 class="hide-on-print title">Récapitulatif{{ isOnlineMediationRecap ? '' : " d'orientation" }}</h2>
+  <div *ngIf="!isOnlineMediationRecap" class="inline">
+    <div class="logos">
+      <img src="../../../../assets/logos/metropoleGrandLyon-red.svg" alt="logo métropole" class="mgl" />
+      <app-svg-icon class="hide-on-print" [iconClass]="'icon-12'" [folder]="'ico'" [icon]="'cross'" />
+      <div class="show-on-print verticalLine"></div>
+      <img src="../../../../assets/logos/resin.svg" alt="logo resin" class="resin" />
+    </div>
+    <div class="right">resin.grandlyon.com</div>
+  </div>
+</div>
diff --git a/src/app/shared/components/print-header/print-header.component.scss b/src/app/shared/components/print-header/print-header.component.scss
new file mode 100644
index 000000000..66d7ed617
--- /dev/null
+++ b/src/app/shared/components/print-header/print-header.component.scss
@@ -0,0 +1,61 @@
+@import 'color';
+@import 'typography';
+
+@media print {
+  @page {
+    size: 595px 842px;
+    margin: 32px 56px;
+  }
+  header,
+  footer {
+    display: none;
+  }
+}
+
+.container {
+  width: 600px;
+  @media print {
+    width: 483px;
+  }
+}
+
+.title {
+  margin-bottom: 32px;
+}
+
+.logos {
+  display: flex;
+  align-items: center;
+  gap: 12px;
+  height: 40px;
+  @media print {
+    gap: 16px;
+    height: 30px;
+  }
+
+  .verticalLine {
+    border-left: 1px solid $grey-1;
+    height: 100%;
+  }
+
+  .mgl {
+    height: 100%;
+  }
+
+  .resin {
+    height: 31px;
+    @media print {
+      height: 24px;
+    }
+  }
+}
+
+.right {
+  @include font-bold-12;
+  margin: auto;
+  margin-right: 0px;
+  visibility: hidden;
+  @media print {
+    visibility: visible;
+  }
+}
diff --git a/src/app/shared/components/print-header/print-header.component.ts b/src/app/shared/components/print-header/print-header.component.ts
new file mode 100644
index 000000000..bc6dc00d8
--- /dev/null
+++ b/src/app/shared/components/print-header/print-header.component.ts
@@ -0,0 +1,10 @@
+import { Component, Input } from '@angular/core';
+
+@Component({
+  selector: 'app-print-header',
+  templateUrl: './print-header.component.html',
+  styleUrls: ['./print-header.component.scss'],
+})
+export class PrintHeaderComponent {
+  @Input() public isOnlineMediationRecap = false;
+}
diff --git a/src/app/shared/components/print-structures-grid/print-structures-grid.component.html b/src/app/shared/components/print-structures-grid/print-structures-grid.component.html
new file mode 100644
index 000000000..9c029c564
--- /dev/null
+++ b/src/app/shared/components/print-structures-grid/print-structures-grid.component.html
@@ -0,0 +1,36 @@
+<div class="contents">
+  <div *ngFor="let commune of this.structuresByCommune | keyvalue" class="city-block">
+    <h3>{{ commune.key }}</h3>
+    <div class="grid">
+      <div *ngFor="let structure of commune.value" class="box">
+        <div class="box-header">
+          <div class="structureName">
+            <img
+              class="structureIcon"
+              alt=""
+              [src]="'../../../assets/ico/' + structure?.getTypeStructureIcon() + '.svg'"
+            />
+            <p>{{ structure.structureName }}</p>
+          </div>
+          <div class="inline">
+            <app-svg-icon [iconClass]="'icon-20'" [folder]="'tags'" [icon]="'address'" />
+            <p>{{ structure.address.numero }} {{ structure.address.street }}, {{ structure.address.commune }}</p>
+          </div>
+          <div *ngIf="structure.contactPhone" class="inline">
+            <app-svg-icon [iconClass]="'icon-20'" [folder]="'tags'" [icon]="'phone'" />
+            <p>{{ structure.contactPhone }}</p>
+          </div>
+          <div *ngIf="structure.contactMail" class="inline">
+            <app-svg-icon [iconClass]="'icon-20'" [folder]="'tags'" [icon]="'mail'" />
+            <p>{{ structure.contactMail }}</p>
+          </div>
+        </div>
+        <ul>
+          <li *ngFor="let service of getServices(structure)">
+            <span>{{ service }}</span>
+          </li>
+        </ul>
+      </div>
+    </div>
+  </div>
+</div>
diff --git a/src/app/shared/components/print-structures-grid/print-structures-grid.component.scss b/src/app/shared/components/print-structures-grid/print-structures-grid.component.scss
new file mode 100644
index 000000000..513dc9d53
--- /dev/null
+++ b/src/app/shared/components/print-structures-grid/print-structures-grid.component.scss
@@ -0,0 +1,69 @@
+@import 'color';
+@import 'typography';
+
+.contents {
+  display: flex;
+  flex-direction: column;
+  gap: 24px;
+
+  .city-block {
+    display: flex;
+    flex-direction: column;
+    gap: 12px;
+
+    h3 {
+      break-after: avoid-page;
+      @include font-bold-16;
+    }
+
+    .grid {
+      display: grid;
+      grid-template-columns: 1fr 1fr;
+      gap: 16px;
+
+      .box {
+        break-inside: avoid-page;
+        border: 1px solid $grey-6;
+        border-radius: 8px;
+        padding: 12px;
+        height: min-content;
+
+        display: flex;
+        flex-direction: column;
+        gap: 10px;
+
+        .box-header {
+          display: flex;
+          flex-direction: column;
+          gap: 8px;
+          @include font-regular-10;
+
+          .structureName {
+            @include font-bold-12;
+            display: flex;
+            align-items: center;
+            gap: 6px;
+
+            .structureIcon {
+              width: 30px;
+            }
+          }
+        }
+
+        ul {
+          padding: 0;
+          margin: 0;
+        }
+        li {
+          padding-left: 2px;
+          list-style-position: inside;
+          @include font-regular-9;
+          span {
+            position: relative;
+            left: -6px;
+          }
+        }
+      }
+    }
+  }
+}
diff --git a/src/app/shared/components/print-structures-grid/print-structures-grid.component.ts b/src/app/shared/components/print-structures-grid/print-structures-grid.component.ts
new file mode 100644
index 000000000..a5a793f63
--- /dev/null
+++ b/src/app/shared/components/print-structures-grid/print-structures-grid.component.ts
@@ -0,0 +1,40 @@
+import { Component, Input, OnInit } from '@angular/core';
+import { Structure } from '../../../models/structure.model';
+
+@Component({
+  selector: 'app-print-structures-grid',
+  templateUrl: './print-structures-grid.component.html',
+  styleUrls: ['./print-structures-grid.component.scss'],
+})
+export class PrintStructuresGridComponent implements OnInit {
+  @Input({ required: true }) structures: Structure[];
+  public structuresByCommune: Record<string, Structure[]>;
+
+  ngOnInit(): void {
+    this.structuresByCommune = this.structures.reduce((communes, structure) => {
+      const commune: Structure[] = communes[structure.address.commune] || [];
+      commune.push(structure);
+      communes[structure.address.commune] = commune;
+      return communes;
+    }, {});
+  }
+
+  getServices(structure: Structure): string[] {
+    const services: string[] = [];
+    if (structure.hasFreeOnlineHelp()) {
+      services.push('Aide gratuite aux démarches en ligne');
+    }
+    if (structure.hasFreeWorkshops()) {
+      services.push('Accompagnement gratuit aux usages numériques');
+    } else {
+      services.push('Formations payantes aux usages numériques');
+    }
+    if (structure.hasSolidarityMaterial()) {
+      services.push('Matériel à tarif solidaire');
+    }
+    if (structure.hasEquipments()) {
+      services.push('Matériel en accès libre');
+    }
+    return services;
+  }
+}
diff --git a/src/app/structure-list/components/structure-list-search-print/structure-list-search-print.component.html b/src/app/structure-list/components/structure-list-search-print/structure-list-search-print.component.html
index 204a702c6..677d9c203 100644
--- a/src/app/structure-list/components/structure-list-search-print/structure-list-search-print.component.html
+++ b/src/app/structure-list/components/structure-list-search-print/structure-list-search-print.component.html
@@ -1,46 +1,17 @@
-<div class="page">
-  <table role="presentation">
-    <thead>
-      <tr>
-        <td>
-          <header>
-            <img class="banner" src="assets/img/resin_print_banner.svg" alt="En-tête Rés'in" />
-          </header>
-        </td>
-      </tr>
-    </thead>
-    <tbody>
-      <tr>
-        <td>
-          <div *ngFor="let commune of this.structuresByCommune | keyvalue" class="communeContainer">
-            <div class="communeHeader">
-              <img class="markerIcon" src="assets/ico/searchPrintMarker.svg" alt="Icône marker" />
-              <h1>{{ commune.key }}</h1>
-            </div>
-            <hr />
-            <div class="structureList">
-              <div *ngFor="let structure of commune.value" class="structure">
-                <img class="structureIcon" src="assets/ico/searchPrintStructure.svg" alt="Icône structure" />
-                <div class="structureInfos">
-                  <p class="structureName">{{ structure.structureName }}</p>
-                  <p>{{ structure.address.numero }} {{ structure.address.street }}, {{ structure.address.commune }}</p>
-                  <p *ngIf="structure.contactPhone">{{ structure.contactPhone }}</p>
-                  <p>{{ structure.contactMail }}</p>
-                </div>
-              </div>
-            </div>
-          </div>
-        </td>
-      </tr>
-    </tbody>
-    <tfoot>
-      <tr>
-        <td>
-          <footer>
-            <a href="https://resin.grandlyon.com">resin.grandlyon.com</a>
-          </footer>
-        </td>
-      </tr>
-    </tfoot>
-  </table>
+<app-print-header />
+
+<div class="contents">
+  <div class="infos">
+    <div class="inline">
+      <app-svg-icon [iconClass]="'icon-20'" [folder]="'tags'" [icon]="'notification'" />
+      <h2>Besoins d'aide avec le numérique ?</h2>
+    </div>
+    <p>
+      Pour utiliser votre ordinateur ou smartphone, aller sur internet, réaliser une démarche...<br />
+      Vous pouvez trouver de l’aide ou du matériel dans les lieux suivants.<br />
+      Si possible, appelez-les avant d’y aller pour connaître les horaires et les aides proposées.
+    </p>
+  </div>
+
+  <app-print-structures-grid [structures]="this.structures" />
 </div>
diff --git a/src/app/structure-list/components/structure-list-search-print/structure-list-search-print.component.scss b/src/app/structure-list/components/structure-list-search-print/structure-list-search-print.component.scss
index 9524ed663..ceaa28f26 100644
--- a/src/app/structure-list/components/structure-list-search-print/structure-list-search-print.component.scss
+++ b/src/app/structure-list/components/structure-list-search-print/structure-list-search-print.component.scss
@@ -1,79 +1,29 @@
 @import 'color';
 @import 'typography';
 
-.page {
+@media screen {
+  :host {
+    display: none;
+  }
+}
+
+.contents {
   display: flex;
   flex-direction: column;
-  align-items: center;
+  gap: 24px;
+  margin-top: 24px;
 
-  .banner {
-    width: 100%;
-  }
-  .communeContainer {
-    break-inside: avoid-page;
-    width: 100%;
-    margin: 0 3.75rem 2rem 3.75rem;
-    .communeHeader {
-      display: flex;
-      gap: 0.25rem;
-      .markerIcon {
-        width: 20px;
-      }
-      h1 {
-        @include font-regular-15;
-        margin: 0;
-      }
-    }
-    hr {
-      margin: 0.5rem 0;
-    }
-    .structureList {
-      display: flex;
-      flex-wrap: wrap;
-      gap: 1rem 0;
+  .infos {
+    display: flex;
+    flex-direction: column;
+    gap: 16px;
 
-      .structure {
-        display: flex;
-        gap: 5px;
-        width: 50%;
-        .structureIcon {
-          width: 13px;
-        }
-        .structureInfos {
-          border-left: 1px solid $grey-5;
-          padding-left: 5px;
-
-          p {
-            @include font-regular-10;
-            margin: 0;
-            &.structureName {
-              font-weight: bold;
-            }
-          }
-        }
-      }
+    h2 {
+      @include font-bold-18;
     }
-  }
-  footer {
-    position: fixed;
-    bottom: 0;
-    width: 100%;
-    text-align: center;
-    @include font-bold-14;
-  }
-}
-
-@media print {
-  thead {
-    display: table-header-group;
-  }
-  tfoot {
-    display: table-footer-group;
-  }
-}
 
-@media screen {
-  :host {
-    display: none;
+    p {
+      @include font-regular-12;
+    }
   }
 }
diff --git a/src/app/structure-list/components/structure-list-search-print/structure-list-search-print.component.ts b/src/app/structure-list/components/structure-list-search-print/structure-list-search-print.component.ts
index 1ddb12867..8b5e3bb1a 100644
--- a/src/app/structure-list/components/structure-list-search-print/structure-list-search-print.component.ts
+++ b/src/app/structure-list/components/structure-list-search-print/structure-list-search-print.component.ts
@@ -1,4 +1,5 @@
 import { Component, OnInit } from '@angular/core';
+import { Structure } from '../../../models/structure.model';
 import { PrintService } from '../../../shared/service/print.service';
 
 @Component({
@@ -7,18 +8,12 @@ import { PrintService } from '../../../shared/service/print.service';
   styleUrls: ['./structure-list-search-print.component.scss'],
 })
 export class StructureListSearchPrintComponent implements OnInit {
-  public structuresByCommune: {};
+  public structures: Structure[];
 
   constructor(private printService: PrintService) {}
 
   ngOnInit(): void {
-    this.structuresByCommune = this.printService.structures.reduce((communes, structure) => {
-      const commune = communes[structure.address.commune] || [];
-      commune.push(structure);
-      communes[structure.address.commune] = commune;
-      return communes;
-    }, {});
-
+    this.structures = this.printService.structures;
     this.printService.onDataReady();
   }
 }
diff --git a/src/app/utils/orientationUtils.ts b/src/app/utils/orientationUtils.ts
index 5057e49c1..6ed58bc55 100644
--- a/src/app/utils/orientationUtils.ts
+++ b/src/app/utils/orientationUtils.ts
@@ -145,33 +145,21 @@ export class OrientationUtils {
     updatePageValid: (isValid: boolean) => void,
     step: HotlineMediationSteps,
   ): void {
-    pagesValidation[HotlineMediationSteps.infoScreen] = {
-      valid: true,
-    };
+    pagesValidation[HotlineMediationSteps.infoScreen] = { valid: true };
     pagesValidation[HotlineMediationSteps.mediationBeneficiaryInfo] = {
       valid: form.get('name').valid && form.get('surname').valid && form.get('phone').valid,
     };
     pagesValidation[HotlineMediationSteps.mediationHoursSelection] = {
       valid: form.get('dateSlot').value !== null,
     };
-    pagesValidation[HotlineMediationSteps.mediationLanguageSelection] = {
-      valid: true,
-    };
-    pagesValidation[HotlineMediationSteps.comments] = {
-      valid: true,
-    };
+    pagesValidation[HotlineMediationSteps.mediationLanguageSelection] = { valid: true };
+    pagesValidation[HotlineMediationSteps.comments] = { valid: true };
     pagesValidation[HotlineMediationSteps.structureOrientator] = {
       valid: form.get('structureOrientator').valid,
     };
-    pagesValidation[HotlineMediationSteps.orientationRecap] = {
-      valid: true,
-    };
-    pagesValidation[HotlineMediationSteps.rdvEnd] = {
-      valid: true,
-    };
-    pagesValidation[HotlineMediationSteps.orientationPrint] = {
-      valid: true,
-    };
+    pagesValidation[HotlineMediationSteps.orientationRecap] = { valid: true };
+    pagesValidation[HotlineMediationSteps.rdvEnd] = { valid: true };
+    pagesValidation[HotlineMediationSteps.orientationPrint] = { valid: true };
     updatePageValid(pagesValidation[step].valid);
   }
 
@@ -205,18 +193,12 @@ export class OrientationUtils {
     updatePageValid: (isValid: boolean) => void,
     step: AppointmentSteps,
   ): void {
-    pagesValidation[AppointmentSteps.infoScreen] = {
-      valid: true,
-    };
+    pagesValidation[AppointmentSteps.infoScreen] = { valid: true };
     pagesValidation[AppointmentSteps.pmrAccess] = {
       valid: form.get('pmrAccess').valid,
     };
-    pagesValidation[AppointmentSteps.location] = {
-      valid: true,
-    };
-    pagesValidation[AppointmentSteps.carto] = {
-      valid: true,
-    };
+    pagesValidation[AppointmentSteps.location] = { valid: true };
+    pagesValidation[AppointmentSteps.carto] = { valid: true };
     pagesValidation[AppointmentSteps.makeAppointment] = {
       valid: form.get('socialWorkerId').valid && form.get('structureRDV').valid,
     };
@@ -231,10 +213,9 @@ export class OrientationUtils {
     pagesValidation[AppointmentSteps.structureOrientator] = {
       valid: form.get('structureOrientator').valid,
     };
-    pagesValidation[AppointmentSteps.rdvEnd] = {
-      valid: true,
-    };
     pagesValidation[AppointmentSteps.orientationRecap] = { valid: true };
+    pagesValidation[AppointmentSteps.rdvEnd] = { valid: true };
+    pagesValidation[AppointmentSteps.orientationPrint] = { valid: true };
 
     updatePageValid(pagesValidation[step].valid);
   }
diff --git a/src/assets/ico/searchPrintMarker.svg b/src/assets/ico/searchPrintMarker.svg
deleted file mode 100644
index aa5f9be87..000000000
--- a/src/assets/ico/searchPrintMarker.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
-    <path fill-rule="evenodd" clip-rule="evenodd"
-        d="M12.3519 15.8973C14.9053 13.5588 16.875 11.7548 16.875 8.7963C16.875 4.97377 13.797 1.875 10 1.875C6.20304 1.875 3.125 4.97377 3.125 8.7963C3.125 11.9219 4.72381 13.3564 7.75803 16.0788C8.43459 16.6858 9.18252 17.3569 10 18.125C10.8107 17.3088 11.6062 16.5803 12.3519 15.8973ZM10 11.5046C11.4858 11.5046 12.6902 10.2921 12.6902 8.7963C12.6902 7.30053 11.4858 6.08796 10 6.08796C8.51423 6.08796 7.30978 7.30053 7.30978 8.7963C7.30978 10.2921 8.51423 11.5046 10 11.5046Z"
-        stroke="#DA3635" stroke-width="1.5" stroke-linecap="round" />
-</svg>
\ No newline at end of file
diff --git a/src/assets/ico/searchPrintStructure.svg b/src/assets/ico/searchPrintStructure.svg
deleted file mode 100644
index 76e96aa44..000000000
--- a/src/assets/ico/searchPrintStructure.svg
+++ /dev/null
@@ -1,14 +0,0 @@
-<svg width="13" height="14" viewBox="0 0 13 14" fill="none" xmlns="http://www.w3.org/2000/svg">
-    <g clip-path="url(#clip0_10059_198649)">
-        <path
-            d="M1.77283 5.40455L6.55919 1.68182L11.3456 5.40455V11.2546C11.3456 11.5366 11.2335 11.8072 11.034 12.0067C10.8346 12.2061 10.564 12.3182 10.2819 12.3182H2.83646C2.55437 12.3182 2.28383 12.2061 2.08436 12.0067C1.88489 11.8072 1.77283 11.5366 1.77283 11.2546V5.40455Z"
-            stroke="#DA3635" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" />
-        <path d="M4.96375 12.3182V7H8.15465V12.3182" stroke="#DA3635" stroke-width="1.5" stroke-linecap="round"
-            stroke-linejoin="round" />
-    </g>
-    <defs>
-        <clipPath id="clip0_10059_198649">
-            <rect width="13" height="13" fill="white" transform="translate(0 0.5)" />
-        </clipPath>
-    </defs>
-</svg>
\ No newline at end of file
diff --git a/src/assets/ico/sprite.svg b/src/assets/ico/sprite.svg
index 3bb4b648f..8333fb7c1 100644
--- a/src/assets/ico/sprite.svg
+++ b/src/assets/ico/sprite.svg
@@ -444,4 +444,10 @@
       d="M15.8333 3.33366H15V2.50033C15 2.04199 14.625 1.66699 14.1667 1.66699C13.7083 1.66699 13.3333 2.04199 13.3333 2.50033V3.33366H6.66667V2.50033C6.66667 2.04199 6.29167 1.66699 5.83333 1.66699C5.375 1.66699 5 2.04199 5 2.50033V3.33366H4.16667C3.24167 3.33366 2.50833 4.08366 2.50833 5.00033L2.5 16.667C2.5 17.5837 3.24167 18.3337 4.16667 18.3337H15.8333C16.75 18.3337 17.5 17.5837 17.5 16.667V5.00033C17.5 4.08366 16.75 3.33366 15.8333 3.33366ZM15.8333 15.8337C15.8333 16.292 15.4583 16.667 15 16.667H5C4.54167 16.667 4.16667 16.292 4.16667 15.8337V7.50033H15.8333V15.8337ZM5.83333 9.16699H7.5V10.8337H5.83333V9.16699ZM9.16667 9.16699H10.8333V10.8337H9.16667V9.16699ZM12.5 9.16699H14.1667V10.8337H12.5V9.16699Z"
       fill="currentColor" />
   </symbol>
+
+  <symbol id="printer" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
+    <path
+      d="M15.8327 6.66667H4.16602C2.78268 6.66667 1.66602 7.78333 1.66602 9.16667V12.5C1.66602 13.4167 2.41602 14.1667 3.33268 14.1667H4.99935V15.8333C4.99935 16.75 5.74935 17.5 6.66602 17.5H13.3327C14.2493 17.5 14.9993 16.75 14.9993 15.8333V14.1667H16.666C17.5827 14.1667 18.3327 13.4167 18.3327 12.5V9.16667C18.3327 7.78333 17.216 6.66667 15.8327 6.66667ZM12.4993 15.8333H7.49935C7.04102 15.8333 6.66602 15.4583 6.66602 15V11.6667H13.3327V15C13.3327 15.4583 12.9577 15.8333 12.4993 15.8333ZM15.8327 10C15.3743 10 14.9993 9.625 14.9993 9.16667C14.9993 8.70833 15.3743 8.33333 15.8327 8.33333C16.291 8.33333 16.666 8.70833 16.666 9.16667C16.666 9.625 16.291 10 15.8327 10ZM14.166 2.5H5.83268C5.37435 2.5 4.99935 2.875 4.99935 3.33333V5C4.99935 5.45833 5.37435 5.83333 5.83268 5.83333H14.166C14.6243 5.83333 14.9993 5.45833 14.9993 5V3.33333C14.9993 2.875 14.6243 2.5 14.166 2.5Z"
+      fill="white" />
+  </symbol>
 </svg>
\ No newline at end of file
diff --git a/src/assets/scss/_typography.scss b/src/assets/scss/_typography.scss
index 61d56bb9a..6bf61fdaf 100644
--- a/src/assets/scss/_typography.scss
+++ b/src/assets/scss/_typography.scss
@@ -1,3 +1,5 @@
+$font-size-8: 0.5rem; // 8px
+$font-size-9: 0.563rem; // 9px
 $font-size-xxxxsmall: 0.625rem; // 10px
 $font-size-xxsmall: 0.75rem; // 12px
 $font-size-xmsmall: 0.813rem; // 13px
@@ -125,16 +127,41 @@ $font-size-xcxlarge: 2rem; // 32px
   font-weight: normal;
   font-size: $font-size-xmsmall;
 }
+@mixin font-bold-12 {
+  font-style: normal;
+  font-weight: bold;
+  font-size: $font-size-xxsmall;
+}
 @mixin font-regular-12 {
   font-style: normal;
   font-weight: normal;
   font-size: $font-size-xxsmall;
 }
+@mixin font-regular-11 {
+  font-style: normal;
+  font-weight: normal;
+  font-size: $font-size-xxsmall;
+}
+@mixin font-bold-10 {
+  font-style: normal;
+  font-weight: bold;
+  font-size: $font-size-xxxxsmall;
+}
 @mixin font-regular-10 {
   font-style: normal;
   font-weight: normal;
   font-size: $font-size-xxxxsmall;
 }
+@mixin font-regular-9 {
+  font-style: normal;
+  font-weight: normal;
+  font-size: $font-size-9;
+}
+@mixin font-regular-8 {
+  font-style: normal;
+  font-weight: normal;
+  font-size: $font-size-8;
+}
 
 @mixin text-ellipsis {
   overflow: hidden;
diff --git a/src/assets/tags/sprite.svg b/src/assets/tags/sprite.svg
index 215451e81..09feaea20 100644
--- a/src/assets/tags/sprite.svg
+++ b/src/assets/tags/sprite.svg
@@ -97,4 +97,32 @@
       fill="#DA3635" />
   </symbol>
 
+  <symbol id="notification" viewBox="0 0 22 22" fill="none" xmlns="http://www.w3.org/2000/svg">
+    <rect width="22" height="22" rx="11" fill="#FFE5E4" />
+    <path
+      d="M11.0004 19.25C11.8254 19.25 12.4929 18.5825 12.4929 17.7575H9.50791C9.50791 18.5825 10.1754 19.25 11.0004 19.25ZM17.2179 15.7175L16.2504 14.75V10.25C16.2504 7.7375 14.4804 5.6375 12.1254 5.1275V4.25C12.1254 3.6275 11.6229 3.125 11.0004 3.125C10.3779 3.125 9.8754 3.6275 9.8754 4.25V5.1275C7.5204 5.6375 5.7504 7.7375 5.7504 10.25V14.75L4.7829 15.7175C4.3104 16.19 4.6404 17 5.3079 17H16.6854C17.3604 17 17.6904 16.19 17.2179 15.7175ZM11.7504 14H10.2504V12.5H11.7504V14ZM11.7504 10.25C11.7504 10.6625 11.4129 11 11.0004 11C10.5879 11 10.2504 10.6625 10.2504 10.25V8.75C10.2504 8.3375 10.5879 8 11.0004 8C11.4129 8 11.7504 8.3375 11.7504 8.75V10.25Z"
+      fill="#DA3635" />
+  </symbol>
+
+  <symbol id="person" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
+    <rect width="20" height="20" rx="10" fill="#FFE5E4" />
+    <path id="Vector"
+      d="M10 10C11.105 10 12 9.105 12 8C12 6.895 11.105 6 10 6C8.895 6 8 6.895 8 8C8 9.105 8.895 10 10 10ZM10 11C8.665 11 6 11.67 6 13V13.5C6 13.775 6.225 14 6.5 14H13.5C13.775 14 14 13.775 14 13.5V13C14 11.67 11.335 11 10 11Z"
+      fill="#DA3635" />
+  </symbol>
+
+  <symbol id="questionAnswer" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
+    <rect width="20" height="20" rx="10" fill="#FFE5E4" />
+    <path
+      d="M14 7H13.5V11C13.5 11.275 13.275 11.5 13 11.5H7V12C7 12.55 7.45 13 8 13H13L15 15V8C15 7.45 14.55 7 14 7ZM12.5 9.5V6C12.5 5.45 12.05 5 11.5 5H6C5.45 5 5 5.45 5 6V12.5L7 10.5H11.5C12.05 10.5 12.5 10.05 12.5 9.5Z"
+      fill="#DA3635" />
+  </symbol>
+
+  <symbol id="timer" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
+    <rect width="20" height="20" rx="10" fill="#FFE5E4" />
+    <path
+      d="M10.9996 4.5H8.99956C8.72456 4.5 8.49956 4.725 8.49956 5C8.49956 5.275 8.72456 5.5 8.99956 5.5H10.9996C11.2746 5.5 11.4996 5.275 11.4996 5C11.4996 4.725 11.2746 4.5 10.9996 4.5ZM9.99956 11C10.2746 11 10.4996 10.775 10.4996 10.5V8.5C10.4996 8.225 10.2746 8 9.99956 8C9.72456 8 9.49956 8.225 9.49956 8.5V10.5C9.49956 10.775 9.72456 11 9.99956 11ZM13.5146 7.695L13.8896 7.32C14.0796 7.13 14.0846 6.815 13.8896 6.62L13.8846 6.615C13.6896 6.42 13.3796 6.425 13.1846 6.615L12.8096 6.99C12.0346 6.37 11.0596 6 9.99956 6C7.59956 6 5.55956 7.98 5.49956 10.38C5.43456 12.92 7.46956 15 9.99956 15C12.4896 15 14.4996 12.985 14.4996 10.5C14.4996 9.44 14.1296 8.465 13.5146 7.695ZM9.99956 14C8.06456 14 6.49956 12.435 6.49956 10.5C6.49956 8.565 8.06456 7 9.99956 7C11.9346 7 13.4996 8.565 13.4996 10.5C13.4996 12.435 11.9346 14 9.99956 14Z"
+      fill="#DA3635" />
+  </symbol>
+
 </svg>
\ No newline at end of file
diff --git a/src/styles.scss b/src/styles.scss
index 933e3c883..9553208f0 100644
--- a/src/styles.scss
+++ b/src/styles.scss
@@ -104,6 +104,10 @@ a {
     color: $info-blue;
     background-image: url('assets/ico/toast-info.svg');
   }
+
+  @media print {
+    display: none;
+  }
 }
 
 // Containers
@@ -245,6 +249,16 @@ button {
     display: none !important;
   }
 }
+.hide-on-print {
+  @media print {
+    display: none !important;
+  }
+}
+.show-on-print {
+  @media not print {
+    display: none !important;
+  }
+}
 
 // AUTOCOMPLETE
 .autocomplete-items {
-- 
GitLab