chore: add husky pre-commit hook and lint-staged configuration

- Created a pre-commit hook in .husky to run lint-staged.
- Added .lintstagedrc.mjs to format frontend files with Prettier and apply Spotless to backend Java files.
- Introduced .prettierignore to exclude specific directories from formatting.
This commit is contained in:
nessar committed 2026-08-17 14:18:16 +02:00
1 parent 5d2d85aa8c
commit 878da155bd
564 files changed
+61467 -47179

No files matched your search

@@ -1,11 +1,11 @@
import { Component, inject, signal } from '@angular/core';
import {
AbstractControl,
FormControl,
FormGroup,
ReactiveFormsModule,
ValidationErrors,
Validators,
AbstractControl,
FormControl,
FormGroup,
ReactiveFormsModule,
ValidationErrors,
Validators,
} from '@angular/forms';
import { MatButtonModule } from '@angular/material/button';
import { MAT_DIALOG_DATA, MatDialogModule, MatDialogRef } from '@angular/material/dialog';
@@ -19,69 +19,71 @@ import { RentPayment, RentPaymentService } from '../../services/rent-payment.ser
import { isRentPaymentDataStale, RENT_PAYMENT_DATA_STALE } from '../rent-payment-dialog-result';
@Component({
selector: 'app-rent-payment-refund-dialog',
imports: [
ReactiveFormsModule,
MatButtonModule,
MatDialogModule,
MatFormFieldModule,
MatInputModule,
MatProgressSpinnerModule,
],
templateUrl: './rent-payment-refund-dialog.html',
styleUrl: './rent-payment-refund-dialog.css',
selector: 'app-rent-payment-refund-dialog',
imports: [
ReactiveFormsModule,
MatButtonModule,
MatDialogModule,
MatFormFieldModule,
MatInputModule,
MatProgressSpinnerModule,
],
templateUrl: './rent-payment-refund-dialog.html',
styleUrl: './rent-payment-refund-dialog.css',
})
export class RentPaymentRefundDialog {
readonly payment = inject<RentPayment>(MAT_DIALOG_DATA);
private readonly dialogRef = inject(MatDialogRef<RentPaymentRefundDialog>);
private readonly payments = inject(RentPaymentService);
private readonly operationId = crypto.randomUUID();
readonly today = localIsoDate();
readonly saving = signal(false);
readonly error = signal('');
readonly formatEuro = formatEuro;
readonly payment = inject<RentPayment>(MAT_DIALOG_DATA);
private readonly dialogRef = inject(MatDialogRef<RentPaymentRefundDialog>);
private readonly payments = inject(RentPaymentService);
private readonly operationId = crypto.randomUUID();
readonly today = localIsoDate();
readonly saving = signal(false);
readonly error = signal('');
readonly formatEuro = formatEuro;
readonly form = new FormGroup({
refundedAt: new FormControl(this.today, {
nonNullable: true,
validators: [Validators.required, this.notFuture.bind(this)],
}),
amount: new FormControl(this.payment.unallocatedBalance, {
nonNullable: true,
validators: [
Validators.required,
Validators.min(0.01),
Validators.max(this.payment.unallocatedBalance),
],
}),
});
readonly form = new FormGroup({
refundedAt: new FormControl(this.today, {
nonNullable: true,
validators: [Validators.required, this.notFuture.bind(this)],
}),
amount: new FormControl(this.payment.unallocatedBalance, {
nonNullable: true,
validators: [
Validators.required,
Validators.min(0.01),
Validators.max(this.payment.unallocatedBalance),
],
}),
});
submit(): void {
this.form.markAllAsTouched();
if (this.form.invalid || this.saving()) return;
this.saving.set(true);
this.error.set('');
this.payments
.refund(this.payment.id, {
operationId: this.operationId,
paymentVersion: this.payment.version,
timeZone: browserTimeZone,
...this.form.getRawValue(),
})
.pipe(finalize(() => this.saving.set(false)))
.subscribe({
next: (payment) => this.dialogRef.close(payment),
error: (error) => {
if (isRentPaymentDataStale(error)) {
this.dialogRef.close(RENT_PAYMENT_DATA_STALE);
return;
}
this.error.set(httpErrorMessage(error, 'Impossible d’enregistrer ce remboursement.'));
},
});
}
submit(): void {
this.form.markAllAsTouched();
if (this.form.invalid || this.saving()) return;
this.saving.set(true);
this.error.set('');
this.payments
.refund(this.payment.id, {
operationId: this.operationId,
paymentVersion: this.payment.version,
timeZone: browserTimeZone,
...this.form.getRawValue(),
})
.pipe(finalize(() => this.saving.set(false)))
.subscribe({
next: (payment) => this.dialogRef.close(payment),
error: (error) => {
if (isRentPaymentDataStale(error)) {
this.dialogRef.close(RENT_PAYMENT_DATA_STALE);
return;
}
this.error.set(
httpErrorMessage(error, 'Impossible d’enregistrer ce remboursement.'),
);
},
});
}
private notFuture(control: AbstractControl<string>): ValidationErrors | null {
return control.value > this.today ? { futureDate: true } : null;
}
private notFuture(control: AbstractControl<string>): ValidationErrors | null {
return control.value > this.today ? { futureDate: true } : null;
}
}