diff --git a/angular.json b/angular.json index 6ff6ea82bb729a7d47c0e13aad7011ce42e08e2d..5483fa1cd096e150f7febcaae44cb71c0e944afb 100644 --- a/angular.json +++ b/angular.json @@ -47,6 +47,10 @@ { "replace": "src/i18n/geosource/geosource.ts", "with": "src/i18n/geosource/geosource.fr.ts" + }, + { + "replace": "src/i18n/contact/contact.ts", + "with": "src/i18n/contact/contact.fr.ts" } ] }, @@ -99,6 +103,10 @@ { "replace": "src/i18n/geosource/geosource.ts", "with": "src/i18n/geosource/geosource.fr.ts" + }, + { + "replace": "src/i18n/contact/contact.ts", + "with": "src/i18n/contact/contact.fr.ts" } ], "outputPath": "dist/fr", diff --git a/src/app/core/components/contact/contact.component.html b/src/app/core/components/contact/contact.component.html index a1b63b4aed848162fe0fe359361652d85308c235..4aedb376d5d12b24831d6ad1af2e757b125349d6 100644 --- a/src/app/core/components/contact/contact.component.html +++ b/src/app/core/components/contact/contact.component.html @@ -1,89 +1,173 @@ -<h1 class="has-text-centered">Contactez nous</h1> +<h1 class="has-text-centered" i18n="@@contact.contactUs">Contact us</h1> -<div class="container"> - <h2>Formulaire de contact</h2> +<div class="section"> + <h2 i18n="@@contact.contactForm">Form contact</h2> - <form [formGroup]="form" class="columns is-multiline"> + <form [formGroup]="form" class="columns is-multiline" (ngSubmit)="send()"> <div class="column is-2-touch is-3"> - <h3>Identité</h3> + <h3 i18n="@@contact.identity">Identity</h3> </div> - - <!-- <div class="notification is-danger" [ngStyle]="{'visibility': (errorLogin === true ? 'visible' : 'hidden')}"> - <button class="delete" (click)="closeErrorMessage()"></button> - <span i18n="@@login.incorrectCredentials">Your credentials are not correct.</span> - </div> --> <div class="column is-10-touch is-9"> <div class="fields-container"> <div class="field"> - <label class="label">Nom</label> - <div class="field"> - <p class="control"> - <input class="input" type="text" formControlName="lastname"> - </p> + <label class="label" for="lastname" i18n="@@contact.lastname">Lastname</label> + <p class="control has-icons-right"> + <input id="lastname" class="input" type="text" formControlName="lastname" [ngClass]="{'is-danger': fieldIsInvalid('lastname'), 'is-success': fieldIsValid('lastname')}"> + <span class="icon is-small is-right has-text-success" *ngIf="fieldIsValid('lastname')"> + <i class="fas fa-check-circle"></i> + </span> + <span class="icon is-small is-right has-text-danger" *ngIf="fieldIsInvalid('lastname')"> + <i class="fas fa-exclamation-circle"></i> + </span> + </p> + + <div class="incorrect-field-message" *ngIf="fieldIsInvalid('lastname')"> + <div *ngIf="form.controls['lastname'].errors.required" i18n="@@contact.errors.missingLastname"> + You must indicate a lastname. + </div> </div> </div> <div class="field"> - <label class="label">Prénom</label> - <div class="field"> - <p class="control"> - <input class="input" type="text" formControlName="firstname"> - </p> + <label class="label" for="firstname" i18n="@@contact.firstname">Firstname</label> + <p class="control has-icons-right"> + <input id="firstname" class="input" type="text" formControlName="firstname" [ngClass]="{'is-danger': fieldIsInvalid('firstname'), 'is-success': fieldIsValid('firstname')}"> + <span class="icon is-small is-right has-text-success" *ngIf="fieldIsValid('firstname')"> + <i class="fas fa-check-circle"></i> + </span> + <span class="icon is-small is-right has-text-danger" *ngIf="fieldIsInvalid('firstname')"> + <i class="fas fa-exclamation-circle"></i> + </span> + </p> + + <div class="incorrect-field-message" *ngIf="fieldIsInvalid('firstname')"> + <div *ngIf="form.controls['firstname'].errors.required" i18n="@@contact.errors.missingFirstname"> + You must indicate a firstname. + </div> </div> </div> <div class="field"> - <label class="label">Email</label> - <div class="field"> - <p class="control"> - <input class="input" type="email" formControlName="email"> - </p> + <label class="label" for="email" i18n="@@contact.email">Email</label> + <p class="control has-icons-right"> + <input id="email" class="input" type="email" formControlName="email" [ngClass]="{'is-danger': fieldIsInvalid('email'), 'is-success': fieldIsValid('email')}"> + <span class="icon is-small is-right has-text-success" *ngIf="fieldIsValid('email')"> + <i class="fas fa-check-circle"></i> + </span> + <span class="icon is-small is-right has-text-danger" *ngIf="fieldIsInvalid('email')"> + <i class="fas fa-exclamation-circle"></i> + </span> + </p> + + <div class="incorrect-field-message" *ngIf="fieldIsInvalid('email')"> + <div *ngIf="form.controls['email'].errors.required" i18n="@@contact.errors.missingEmail"> + You must enter an email address. + </div> + + <div *ngIf="form.controls['email'].errors.email" i18n="@@contact.errors.invalidEmail"> + You must enter a valid email address. + </div> </div> </div> - <!-- <div class="field"> - <label class="label">Confirmez l'adresse mail</label> - <div class="field"> - <p class="control"> - <input class="input" type="email" formControlName="emailConfirmation"> - </p> + <div class="field"> + <label class="label" for="emailConfirmation" i18n="@@contact.emailConfirmation">Confirm your email address</label> + <p class="control has-icons-right"> + <input id="emailConfirmation" class="input" type="email" formControlName="emailConfirmation" [ngClass]="{'is-danger': emailConfirmationError || fieldIsInvalid('emailConfirmation'), 'is-success': !emailConfirmationError && fieldIsValid('emailConfirmation')}"> + <span class="icon is-small is-right has-text-success" *ngIf="!emailConfirmationError && fieldIsValid('emailConfirmation')"> + <i class="fas fa-check-circle"></i> + </span> + <span class="icon is-small is-right has-text-danger" *ngIf="emailConfirmationError || fieldIsInvalid('emailConfirmation')"> + <i class="fas fa-exclamation-circle"></i> + </span> + </p> + + <div class="incorrect-field-message" *ngIf="fieldIsInvalid('emailConfirmation')"> + <div *ngIf="form.controls['emailConfirmation'].errors.required" i18n="@@contact.errors.missingConfirmationEmail"> + You must confirm your email address. + </div> + + <div *ngIf="form.controls['emailConfirmation'].errors.email" i18n="@@contact.errors.invalidEmail"> + You must enter a valid email address. + </div> </div> - </div> --> + <div class="incorrect-field-message" *ngIf="emailConfirmationError"> + <div *ngIf="emailConfirmationError" i18n="@@contact.errors.confirmationEmailNotCorresponding"> + You must enter the same email address. + </div> + </div> + </div> </div> </div> <div class="column is-2-touch is-3"> - <h3>Identité</h3> + <h3 i18n="@@contact.message">Message</h3> </div> <div class="column is-10-touch is-9"> - <div class="fields-container"> <div class="field"> - <label class="label">Sujet</label> - <div class="field"> - <p class="control"> - <input class="input" type="text" formControlName="subject"> - </p> + <label class="label" [for]="subjectLabelFor" i18n="@@contact.subject">Sujet</label> + <div class="dropdown" [ngClass]="{'is-active': subjectDropdownState}" (clickOutside)="closeSubjectDropdown()"> + <div class="dropdown-trigger" (click)="toggleSubject()"> + <button id="subjectDropdown" type="button" class="button" aria-haspopup="true" aria-controls="dropdown-menu"> + <span>{{ selectedSubject !== null && selectedSubject.value !== null ? selectedSubject.value : '---'}}</span> + <span class="icon is-small"> + <i class="fas fa-angle-down" aria-hidden="true"></i> + </span> + </button> + </div> + <div class="dropdown-menu" id="dropdown-menu" role="menu"> + <ul class="dropdown-content"> + <li class="dropdown-item" *ngFor="let sub of subjects" (click)="setSubject(sub)"> + {{ sub.value }} + </li> + </ul> + </div> + </div> + <p class="control has-icons-right subject-input-control" *ngIf="displaySubjectInput === true"> + <input id="subjectInput" class="input" type="text" formControlName="subject" [ngClass]="{'is-danger': fieldIsInvalid('subject'), 'is-success': fieldIsValid('subject')}"> + <span class="icon is-small is-right has-text-success" *ngIf="fieldIsValid('subject')"> + <i class="fas fa-check-circle"></i> + </span> + <span class="icon is-small is-right has-text-danger" *ngIf="fieldIsInvalid('subject')"> + <i class="fas fa-exclamation-circle"></i> + </span> + </p> + + <div class="incorrect-field-message" *ngIf="fieldIsInvalid('subject')"> + <div *ngIf="form.controls['subject'].errors.required" i18n="@@contact.errors.missingSubject"> + You must enter a subject. + </div> </div> </div> <div class="field"> - <label class="label">Message</label> - <div class="field"> - <p class="control"> - <textarea class="input" type="textarea" formControlName="text"></textarea> - </p> + <label class="label" for="text" i18n="@@contact.messageField">Message</label> + <p class="control has-icons-right"> + <textarea id="text" class="textarea has-fixed-size" type="textarea" formControlName="text" [ngClass]="{'is-danger': fieldIsInvalid('text'), 'is-success': fieldIsValid('text')}" + rows=6></textarea> + <span class="icon is-small is-right has-text-success" *ngIf="fieldIsValid('text')"> + <i class="fas fa-check-circle"></i> + </span> + <span class="icon is-small is-right has-text-danger" *ngIf="fieldIsInvalid('text')"> + <i class="fas fa-exclamation-circle"></i> + </span> + </p> + + <div class="incorrect-field-message" *ngIf="fieldIsInvalid('text')"> + <div *ngIf="form.controls['text'].errors.required" i18n="@@contact.errors.invalidMessage"> + You must enter a message. + </div> </div> </div> - <div class="has-text-centered button-wrapper"> - <button class="button is-primary" [disabled]="form.invalid" (click)="send()">Envoyer</button> + <div class="has-text-right button-wrapper"> + <button type="submit" class="button is-primary" [disabled]="formIsInvalid()" i18n="@@contact.send">Envoyer</button> </div> </div> - </div> </form> </div> \ No newline at end of file diff --git a/src/app/core/components/contact/contact.component.scss b/src/app/core/components/contact/contact.component.scss index 1d3bf0bcdc3b5747dc3b3cd413ada3b69ea1de5d..4530458c07aac02751e04f274e5c8cf9c49ec468 100644 --- a/src/app/core/components/contact/contact.component.scss +++ b/src/app/core/components/contact/contact.component.scss @@ -1,13 +1,49 @@ @import '../../../../scss/variables.scss'; -.container { - margin-top: 3rem; - h3 { - margin:0; - } +h1 { + font-size: 2rem; + margin-bottom: 0; +} + +h2 { + font-size: 1.6rem; + margin-bottom: 2rem; +} + +h3 { + margin-top: 0; + margin-bottom: 0; + margin-right: 0; +} + +.section { .fields-container { width: 66%; } + + label { + font-size: 1rem; + font-weight: normal; + font-style: normal; + &:hover { + cursor: pointer; + } + } + + .incorrect-field-message { + color: #333745; + font-style: italic; + font-size: $size-6; + } + + .subject-input-control { + margin-top: 0.5rem; + } + + .dropdown-item:hover { + cursor: pointer; + background-color: lightgrey; + } } .title-label.is-danger { diff --git a/src/app/core/components/contact/contact.component.ts b/src/app/core/components/contact/contact.component.ts index 4ac230863ea5e17e69a35b7c2e78517bb30484f6..4e8957b71464c359769446b20cd29c9448b7ac75 100644 --- a/src/app/core/components/contact/contact.component.ts +++ b/src/app/core/components/contact/contact.component.ts @@ -1,7 +1,9 @@ import { Component, OnInit } from '@angular/core'; -import { FormGroup, FormBuilder, Validators } from '@angular/forms'; -import { EmailService } from '../../services'; +import { FormGroup, FormBuilder, Validators, FormControl } from '@angular/forms'; +import { EmailService, NotificationService } from '../../services'; import { Email } from '../../models'; +import { subjects as Subjects, feedbackMessages } from '../../../../i18n/contact/contact'; +import { Router } from '@angular/router'; @Component({ selector: 'app-contact', @@ -11,20 +13,26 @@ import { Email } from '../../models'; export class ContactComponent implements OnInit { form: FormGroup; + subjectDropdownState = false; + subjects: Subject[] = Subjects; // Keep this line in order to access the subjects in the html template + selectedSubject: Subject = null; + displaySubjectInput = false; constructor( private _fb: FormBuilder, - private emailService: EmailService, + private _emailService: EmailService, + private _notificationService: NotificationService, + private _router: Router, ) { - this.form = this._fb.group({ - firstname: ['', Validators.required], - lastname: ['', Validators.required], - email: ['', [Validators.required, Validators.email]], - // emailConfirmation: ['', [Validators.required, Validators.email]], - subject: ['', Validators.required], - text: ['', Validators.required], - }); - + this.form = this._fb.group( + { + firstname: ['', Validators.required], + lastname: ['', Validators.required], + email: ['', [Validators.required, Validators.email]], + emailConfirmation: ['', [Validators.required, Validators.email]], + subject: ['', Validators.required], + text: ['', Validators.required], + }); } ngOnInit() { @@ -34,13 +42,89 @@ export class ContactComponent implements OnInit { console.log(this.form.value); const email = new Email(this.form.value); console.log(email); - this.emailService.send(email).subscribe( + this._emailService.send(email).subscribe( (res) => { console.log(res); + this._notificationService.notify( + { + type: 'success', + message: feedbackMessages.success, + }, + ); + this.form.reset(); }, (err) => { console.log(err); + this._notificationService.notify( + { + type: 'error', + message: feedbackMessages.error, + }, + ); }, ); } + + get emailConfirmationIsCorrect(): boolean { + const value = this.form.controls.email.value === this.form.controls.emailConfirmation.value ? true : false; + console.log(value); + return value; + } + + get emailConfirmationError() { + // Display the message if + // Input values have been modified + // Input values have been modified but the email values are not similar + return this.form.controls['email'].touched && + this.form.controls['emailConfirmation'].touched && + !this.emailConfirmationIsCorrect; + } + + // Return true if one of the fields at least doesn't respect its validators + // or if the confirmation email is different from the email + formIsInvalid() { + const controls = this.form.controls; + const value = this.form.invalid || this.emailConfirmationError; + console.log('FormInvalid: ', value); + return value; + } + + fieldIsInvalid(field: string) { + return (this.form.controls[field].touched) && this.form.controls[field].invalid; + } + + fieldIsValid(field: string) { + return (this.form.controls[field].touched) && this.form.controls[field].valid; + } + + toggleSubject() { + this.subjectDropdownState = !this.subjectDropdownState; + } + + closeSubjectDropdown() { + this.subjectDropdownState = false; + } + + setSubject(subject: Subject) { + this.toggleSubject(); + this.selectedSubject = subject; + if (this.selectedSubject.key === 'other') { + this.form.controls.subject.patchValue(''); + this.form.controls.subject.reset(); + this.displaySubjectInput = true; + } else { + this.form.controls.subject.patchValue(this.selectedSubject.value); + this.displaySubjectInput = false; + } + } + + get subjectLabelFor(): string { + return this.displaySubjectInput === true ? 'subjectInput' : 'subjectDropdown'; + } + +} + +interface Subject { + key: string; + value: string; } diff --git a/src/app/core/interceptors/http-error-response-interceptor.ts b/src/app/core/interceptors/http-error-response-interceptor.ts index c8bae8b6e53fd88682086548d8078b317ea6006d..a54205a989c1bc62bc6b0ed5342259bb4d5a93a3 100644 --- a/src/app/core/interceptors/http-error-response-interceptor.ts +++ b/src/app/core/interceptors/http-error-response-interceptor.ts @@ -18,7 +18,6 @@ export class HttpErrorResponseInterceptor implements HttpInterceptor { } }, (err) => { - console.log(err); if (err instanceof HttpErrorResponse) { switch (err.status) { case 401: diff --git a/src/app/core/models/email.model.ts b/src/app/core/models/email.model.ts index 603b44846e28704e9235df4f6960e3e20a53346c..c9a21ce1c9dbff20190a705efaa824be6e3086d9 100644 --- a/src/app/core/models/email.model.ts +++ b/src/app/core/models/email.model.ts @@ -1,8 +1,8 @@ import { environment } from '../../../environments/environment'; -export interface IEmail { - to: string[]; +export interface IContactForm { email: string; + emailConfirmation: string; subject: string; text: string; firstname: string; @@ -10,16 +10,17 @@ export interface IEmail { } export class Email { - to: string[]; from: string; subject: string; + firstname: string; + lastname: string; text: string; - constructor(email: IEmail) { - this.to = [environment.emailService.contact]; - this.subject = email.subject; - this.text = email.text; - - this.from = `${email.firstname} ${email.lastname} ${email.email}`; + constructor(contactForm: IContactForm) { + this.subject = contactForm.subject; + this.text = contactForm.text; + this.from = contactForm.email; + this.firstname = contactForm.firstname; + this.lastname = contactForm.lastname; } } diff --git a/src/app/core/models/index.ts b/src/app/core/models/index.ts index 3465a2638380b55ca22fe8bd0ea1e69cd4ac50d2..0d3c38d322c55b79a68bf7e0e53594f3ac8a21c1 100644 --- a/src/app/core/models/index.ts +++ b/src/app/core/models/index.ts @@ -1,7 +1,7 @@ import { Notification, INotification } from './notification.model'; import { IMatomoResponse } from './matomo.model'; -import { IEmail, Email } from './email.model'; +import { IContactForm, Email } from './email.model'; export { Notification, INotification }; export { IMatomoResponse }; -export { IEmail, Email }; +export { IContactForm, Email }; diff --git a/src/app/core/services/email.service.ts b/src/app/core/services/email.service.ts index af75b19f832fb47906557f276ab417026842a820..9ad680edb69015df6f16c1a6780ce253a1c61149 100644 --- a/src/app/core/services/email.service.ts +++ b/src/app/core/services/email.service.ts @@ -11,6 +11,6 @@ export class EmailService { ) {} send(email: Email) { - return this._httpClient.post(environment.emailService.url + '/send', email); + return this._httpClient.post(environment.emailService.url + '/contact', email); } } diff --git a/src/app/shared/directives/click-outside.directive.ts b/src/app/shared/directives/click-outside.directive.ts new file mode 100644 index 0000000000000000000000000000000000000000..d89778c8bacbaeb2b1e0d6bee03c4193ac0c7cae --- /dev/null +++ b/src/app/shared/directives/click-outside.directive.ts @@ -0,0 +1,20 @@ +import { Directive, ElementRef, Output, EventEmitter, HostListener } from '@angular/core'; + +@Directive({ + selector: '[clickOutside]', +}) +export class ClickOutsideDirective { + constructor(private _elementRef: ElementRef) { + } + + @Output() + public clickOutside = new EventEmitter(); + + @HostListener('document:click', ['$event.target']) + public onClick(targetElement) { + const clickedInside = this._elementRef.nativeElement.contains(targetElement); + if (!clickedInside) { + this.clickOutside.emit(null); + } + } +} diff --git a/src/app/shared/directives/index.ts b/src/app/shared/directives/index.ts index 08d1c25f0ae96ac403d347efe562839a3278f1fb..b0c41d9454de5db89af758fe186bf1a5c7862a33 100644 --- a/src/app/shared/directives/index.ts +++ b/src/app/shared/directives/index.ts @@ -1,10 +1,12 @@ import { PreventDefaultDirective } from './prevent-default.directive'; import { DynamicLinks } from './dynamic-links'; +import { ClickOutsideDirective } from './click-outside.directive'; -export { PreventDefaultDirective, DynamicLinks }; +export { PreventDefaultDirective, DynamicLinks, ClickOutsideDirective }; // tslint:disable-next-line:variable-name export const SharedDirectives = [ PreventDefaultDirective, DynamicLinks, + ClickOutsideDirective, ]; diff --git a/src/environments/environment.prod.ts b/src/environments/environment.prod.ts index 7ea977dd7f7ff057586cabc0bf2826d22c5b2fb2..922fed05a92e30d4461d9dc9de869e58ac048c8a 100644 --- a/src/environments/environment.prod.ts +++ b/src/environments/environment.prod.ts @@ -23,6 +23,10 @@ export const environment = { url: servicesProxyUrl + '/loopback/api', }, + emailService: { + url: 'https://kong.alpha.grandlyon.com/email', + }, + // Path to the built app in a particular language angularAppHost: { fr: '/fr', diff --git a/src/environments/environment.ts b/src/environments/environment.ts index 4ad3bf6a4148411a0493396b3458301ab1459758..89444f4c905088c0b356dac8052f67e8bc59834d 100644 --- a/src/environments/environment.ts +++ b/src/environments/environment.ts @@ -25,7 +25,6 @@ export const environment = { emailService: { url: 'https://kong.alpha.grandlyon.com/email', - contact: 'fab.forestier42@gmail.com', }, // Path to the built app in a particular language diff --git a/src/i18n/contact/contact.fr.ts b/src/i18n/contact/contact.fr.ts new file mode 100644 index 0000000000000000000000000000000000000000..8136b61273e65e81410a83fdf365546a93134fbd --- /dev/null +++ b/src/i18n/contact/contact.fr.ts @@ -0,0 +1,35 @@ +export const subjects = [ + { + key: 'licenseQuestion', + value: 'question sur les licences', + }, + { + key: 'technicalQuestion', + value: 'question technique', + }, + { + key: 'anomalyReport', + value: 'signalement d\'anomalie', + }, + { + key: 'contactRequest', + value: 'demande de contact', + }, + { + key: 'infoRequest', + value: 'demande d\'information', + }, + { + key: 'newDataRequest', + value: 'demande de nouvelle donnée', + }, + { + key: 'other', + value: 'autre', + }, +]; + +export const feedbackMessages = { + error: 'Désolé, nous n\'avons pas pu envoyer votre demande, veuillez réessayer ultérieurement', + success: 'Votre message a bien été envoyé', +}; diff --git a/src/i18n/contact/contact.ts b/src/i18n/contact/contact.ts new file mode 100644 index 0000000000000000000000000000000000000000..76cdd9ff63050c7d743d033a9c7c3f0b6aaf1906 --- /dev/null +++ b/src/i18n/contact/contact.ts @@ -0,0 +1,35 @@ +export const subjects = [ + { + key: 'licenseQuestion', + value: 'question about licences', + }, + { + key: 'technicalQuestion', + value: 'technical question', + }, + { + key: 'anomalyReport', + value: 'anomaly report', + }, + { + key: 'contactRequest', + value: 'request contact', + }, + { + key: 'infoRequest', + value: 'information request', + }, + { + key: 'newDataRequest', + value: 'request for new data', + }, + { + key: 'other', + value: 'other', + }, +]; + +export const feedbackMessages = { + error: 'Sorry, we couldn\'t send your message, please try again later', + success: 'You message has been sent successfully.', +}; diff --git a/src/i18n/messages.en.xlf b/src/i18n/messages.en.xlf index 5fd3e499a4fb037ec31cfd05374e0ceeb349b671..d18921ba9c8636f35fb57757482405bc9e436660 100644 --- a/src/i18n/messages.en.xlf +++ b/src/i18n/messages.en.xlf @@ -275,6 +275,82 @@ <source>Go back to home page</source> <target>Go back to home page</target> </trans-unit> + <trans-unit id="contact.contactUs" datatype="html"> + <source>Contact us</source> + <target>Contact us</target> + </trans-unit> + <trans-unit id="contact.contactForm" datatype="html"> + <source>Form contact</source> + <target>Form contact</target> + </trans-unit> + <trans-unit id="contact.identity" datatype="html"> + <source>Identity</source> + <target>Identity</target> + </trans-unit> + <trans-unit id="contact.lastname" datatype="html"> + <source>Lastname</source> + <target>Lastname</target> + </trans-unit> + <trans-unit id="contact.errors.missingLastname" datatype="html"> + <source>You must indicate your lastname.</source> + <target>You must indicate your lastname.</target> + </trans-unit> + <trans-unit id="contact.firstname" datatype="html"> + <source>Firstname</source> + <target>Firstname</target> + </trans-unit> + <trans-unit id="contact.errors.missingFirstname" datatype="html"> + <source>You must indicate a firstname.</source> + <target>You must indicate a firstname.</target> + </trans-unit> + <trans-unit id="contact.email" datatype="html"> + <source>Email</source> + <target>Email</target> + </trans-unit> + <trans-unit id="contact.errors.missingEmail" datatype="html"> + <source>You must enter an email address.</source> + <target>You must enter an email address.</target> + </trans-unit> + <trans-unit id="contact.errors.invalidEmail" datatype="html"> + <source>You must enter a valid email address.</source> + <target>You must enter a valid email address.</target> + </trans-unit> + <trans-unit id="contact.emailConfirmation" datatype="html"> + <source>Confirm your email address</source> + <target>Confirm your email address</target> + </trans-unit> + <trans-unit id="contact.errors.missingConfirmationEmail" datatype="html"> + <source>You must confirm your email address.</source> + <target>You must confirm your email address.</target> + </trans-unit> + <trans-unit id="contact.errors.confirmationEmailNotCorresponding" datatype="html"> + <source>You must enter the same email address.</source> + <target>You must enter the same email address.</target> + </trans-unit> + <trans-unit id="contact.message" datatype="html"> + <source>Message</source> + <target>Message</target> + </trans-unit> + <trans-unit id="contact.subject" datatype="html"> + <source>Subject</source> + <target>Subject</target> + </trans-unit> + <trans-unit id="contact.errors.missingSubject" datatype="html"> + <source>You must enter a subject.</source> + <target>You must enter a subject.</target> + </trans-unit> + <trans-unit id="contact.messageField" datatype="html"> + <source>Message</source> + <target>Message</target> + </trans-unit> + <trans-unit id="contact.errors.invalidMessage" datatype="html"> + <source>You must enter a message.</source> + <target>You must enter a message.</target> + </trans-unit> + <trans-unit id="contact.send" datatype="html"> + <source>Send</source> + <target>Send</target> + </trans-unit> </body> </file> </xliff> diff --git a/src/i18n/messages.fr.xlf b/src/i18n/messages.fr.xlf index 1543096819c509f9b67683168486020a55b31be5..bc90266bdb0cfb18fb635e4939a6d4cc6aad6ed9 100644 --- a/src/i18n/messages.fr.xlf +++ b/src/i18n/messages.fr.xlf @@ -283,6 +283,82 @@ <source>Go back to home page</source> <target>Retour à la page d'accueil</target> </trans-unit> + <trans-unit id="contact.contactUs" datatype="html"> + <source>Contact us</source> + <target>Contactez nous</target> + </trans-unit> + <trans-unit id="contact.contactForm" datatype="html"> + <source>Form contact</source> + <target>Formulaire de contact</target> + </trans-unit> + <trans-unit id="contact.identity" datatype="html"> + <source>Identity</source> + <target>Identité</target> + </trans-unit> + <trans-unit id="contact.lastname" datatype="html"> + <source>Lastname</source> + <target>Nom de famille</target> + </trans-unit> + <trans-unit id="contact.errors.missingLastname" datatype="html"> + <source>You must indicate your lastname.</source> + <target>Veuillez indiquer votre nom de famille.</target> + </trans-unit> + <trans-unit id="contact.firstname" datatype="html"> + <source>Firstname</source> + <target>Prénom</target> + </trans-unit> + <trans-unit id="contact.errors.missingFirstname" datatype="html"> + <source>You must indicate a firstname.</source> + <target>Veuillez indiquer votre prénom.</target> + </trans-unit> + <trans-unit id="contact.email" datatype="html"> + <source>Email</source> + <target>Email</target> + </trans-unit> + <trans-unit id="contact.errors.missingEmail" datatype="html"> + <source>You must enter an email address.</source> + <target>Veuillez saisir votre adresse email.</target> + </trans-unit> + <trans-unit id="contact.errors.invalidEmail" datatype="html"> + <source>You must enter a valid email address.</source> + <target>Veuillez saisir une adresse email valide.</target> + </trans-unit> + <trans-unit id="contact.emailConfirmation" datatype="html"> + <source>Confirm your email address</source> + <target>Confirmez votre adresse email</target> + </trans-unit> + <trans-unit id="contact.errors.missingConfirmationEmail" datatype="html"> + <source>You must confirm your email address.</source> + <target>Veuillez confirmer votre adresse email.</target> + </trans-unit> + <trans-unit id="contact.errors.confirmationEmailNotCorresponding" datatype="html"> + <source>You must enter the same email address.</source> + <target>La confirmation de l'email ne correspond pas à l'adresse email saisie.</target> + </trans-unit> + <trans-unit id="contact.message" datatype="html"> + <source>Message</source> + <target>Message</target> + </trans-unit> + <trans-unit id="contact.subject" datatype="html"> + <source>Subject</source> + <target>Sujet</target> + </trans-unit> + <trans-unit id="contact.errors.missingSubject" datatype="html"> + <source>You must enter a subject.</source> + <target>Veuillez saisir un sujet.</target> + </trans-unit> + <trans-unit id="contact.messageField" datatype="html"> + <source>Message</source> + <target>Message</target> + </trans-unit> + <trans-unit id="contact.errors.invalidMessage" datatype="html"> + <source>You must enter a message.</source> + <target>Veuillez saisir votre message.</target> + </trans-unit> + <trans-unit id="contact.send" datatype="html"> + <source>Send</source> + <target>Envoyer</target> + </trans-unit> </body> </file> </xliff>