Skip to content

Commit

Permalink
Merge pull request #80 from Potits-chats/feature/Association
Browse files Browse the repository at this point in the history
Feature/association
  • Loading branch information
marion-sgr authored Sep 7, 2024
2 parents 0097fc2 + 1eee331 commit 66d043b
Show file tree
Hide file tree
Showing 4 changed files with 191 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,138 @@ <h3 class="truncate text-sm font-medium text-gray-900">{{ association.nom }}</h3
</li>
</ul>
</div>

<!-- Accordéon : Rajouter mon association ? -->
<div class="px-4 py-4 mx-auto sm:max-w-xl md:max-w-full lg:max-w-screen-xl md:px-24 lg:px-8 lg:py-10">
<p-accordion class="w-full">
<p-accordionTab>
<ng-template pTemplate="header">
<div class="flex align-items-center">
<i class="pi pi-plus-circle mr-2"></i>
<span class="vertical-align-middle">Rajouter mon association ?</span>
</div>
</ng-template>
<ng-template pTemplate="content">
<section class="text-gray-600 body-font relative">
<div class="container px-5 py-24 mx-auto">
<div class="flex flex-col text-center w-full mb-12">
<h1 class="sm:text-3xl text-2xl font-medium title-font mb-4 text-gray-900">Créer une Association</h1>
<p class="leading-relaxed text-base">Remplissez les informations ci-dessous pour créer une nouvelle association.</p>
</div>
<form [formGroup]="associationForm" (ngSubmit)="onSubmit()" class="lg:w-1/2 md:w-2/3 mx-auto">
<div class="flex flex-wrap -m-2">
<!-- Nom -->
<div class="p-2 w-full">
<div class="relative">
<label for="nom" class="leading-7 text-sm text-gray-600">Nom de l'association
<span class="text-red-500 text-xs mt-1" *ngIf="associationForm.get('nom')?.errors?.['required']">*</span>
</label>
<input type="text" id="nom" name="nom" formControlName="nom" class="w-full bg-gray-100 bg-opacity-50 rounded border border-gray-300 focus:border-indigo-500 focus:bg-white focus:ring-2 focus:ring-indigo-200 text-base outline-none text-gray-700 py-1 px-3 leading-8 transition-colors duration-200 ease-in-out"
[class.border-red-500]="associationForm.controls['nom'].touched && associationForm.controls['nom'].invalid"
[class.border-green-500]="associationForm.controls['nom'].touched && associationForm.controls['nom'].valid">
<div *ngIf="associationForm.controls['nom'].touched && associationForm.controls['nom'].invalid" class="text-red-500 text-xs mt-1">
{{ getErrorMessage('nom') }}
</div>
</div>
</div>

<!-- URL -->
<div class="p-2 w-full">
<div class="relative">
<label for="url" class="leading-7 text-sm text-gray-600">Site Web
<span class="text-red-500 text-xs mt-1" *ngIf="associationForm.get('url')?.errors?.['required']">*</span>
</label>
<input type="url" id="url" name="url" formControlName="url" class="w-full bg-gray-100 bg-opacity-50 rounded border border-gray-300 focus:border-indigo-500 focus:bg-white focus:ring-2 focus:ring-indigo-200 text-base outline-none text-gray-700 py-1 px-3 leading-8 transition-colors duration-200 ease-in-out"
[class.border-red-500]="associationForm.controls['url'].touched && associationForm.controls['url'].invalid"
[class.border-green-500]="associationForm.controls['url'].touched && associationForm.controls['url'].valid">
<div *ngIf="associationForm.controls['url'].touched && associationForm.controls['url'].invalid" class="text-red-500 text-xs mt-1">
{{ getErrorMessage('url') }}
</div>
</div>
</div>

<!-- Ville -->
<div class="p-2 w-full">
<div class="relative">
<label for="ville" class="leading-7 text-sm text-gray-600">Ville
<span class="text-red-500 text-xs mt-1" *ngIf="associationForm.get('ville')?.errors?.['required']">*</span>
</label>
<input type="text" id="ville" name="ville" formControlName="ville" class="w-full bg-gray-100 bg-opacity-50 rounded border border-gray-300 focus:border-indigo-500 focus:bg-white focus:ring-2 focus:ring-indigo-200 text-base outline-none text-gray-700 py-1 px-3 leading-8 transition-colors duration-200 ease-in-out"
[class.border-red-500]="associationForm.controls['ville'].touched && associationForm.controls['ville'].invalid"
[class.border-green-500]="associationForm.controls['ville'].touched && associationForm.controls['ville'].valid">
<div *ngIf="associationForm.controls['ville'].touched && associationForm.controls['ville'].invalid" class="text-red-500 text-xs mt-1">
{{ getErrorMessage('ville') }}
</div>
</div>
</div>

<!-- Description courte -->
<div class="p-2 w-full">
<div class="relative">
<label for="shortDescription" class="leading-7 text-sm text-gray-600">Description courte
<span class="text-red-500 text-xs mt-1" *ngIf="associationForm.get('shortDescription')?.errors?.['required']">*</span>
</label>
<textarea id="shortDescription" name="shortDescription" formControlName="shortDescription" class="w-full bg-gray-100 bg-opacity-50 rounded border border-gray-300 focus:border-indigo-500 focus:bg-white focus:ring-2 focus:ring-indigo-200 h-32 text-base outline-none text-gray-700 py-1 px-3 resize-none leading-6 transition-colors duration-200 ease-in-out"
[class.border-red-500]="associationForm.controls['shortDescription'].touched && associationForm.controls['shortDescription'].invalid"
[class.border-green-500]="associationForm.controls['shortDescription'].touched && associationForm.controls['shortDescription'].valid"></textarea>
<div *ngIf="associationForm.controls['shortDescription'].touched && associationForm.controls['shortDescription'].invalid" class="text-red-500 text-xs mt-1">
{{ getErrorMessage('shortDescription') }}
</div>
</div>
</div>

<!-- Description -->
<div class="p-2 w-full">
<div class="relative">
<label for="description" class="leading-7 text-sm text-gray-600">Description
<span class="text-red-500 text-xs mt-1" *ngIf="associationForm.get('description')?.errors?.['required']">*</span>
</label>
<textarea id="description" name="description" formControlName="description" class="w-full bg-gray-100 bg-opacity-50 rounded border border-gray-300 focus:border-indigo-500 focus:bg-white focus:ring-2 focus:ring-indigo-200 h-32 text-base outline-none text-gray-700 py-1 px-3 resize-none leading-6 transition-colors duration-200 ease-in-out"
[class.border-red-500]="associationForm.controls['description'].touched && associationForm.controls['description'].invalid"
[class.border-green-500]="associationForm.controls['description'].touched && associationForm.controls['description'].valid"></textarea>
<div *ngIf="associationForm.controls['description'].touched && associationForm.controls['description'].invalid" class="text-red-500 text-xs mt-1">
{{ getErrorMessage('description') }}
</div>
</div>
</div>

<!-- Téléphone -->
<div class="p-2 w-full">
<div class="relative">
<label for="tel" class="leading-7 text-sm text-gray-600">Téléphone
<span class="text-red-500 text-xs mt-1" *ngIf="associationForm.get('tel')?.errors?.['required']">*</span>
</label>
<input type="text" id="tel" name="tel" formControlName="tel" class="w-full bg-gray-100 bg-opacity-50 rounded border border-gray-300 focus:border-indigo-500 focus:bg-white focus:ring-2 focus:ring-indigo-200 text-base outline-none text-gray-700 py-1 px-3 leading-8 transition-colors duration-200 ease-in-out"
[class.border-red-500]="associationForm.controls['tel'].touched && associationForm.controls['tel'].invalid"
[class.border-green-500]="associationForm.controls['tel'].touched && associationForm.controls['tel'].valid">
<div *ngIf="associationForm.controls['tel'].touched && associationForm.controls['tel'].invalid" class="text-red-500 text-xs mt-1">
{{ getErrorMessage('tel') }}
</div>
</div>
</div>

<!-- URL Google Maps Embed -->
<div class="p-2 w-full">
<div class="relative">
<label for="urlGoogleMapsEmbled" class="leading-7 text-sm text-gray-600">URL Google Maps
<span class="text-red-500 text-xs mt-1" *ngIf="associationForm.get('urlGoogleMapsEmbled')?.errors?.['required']">*</span>
</label>
<input type="url" id="urlGoogleMapsEmbled" name="urlGoogleMapsEmbled" formControlName="urlGoogleMapsEmbled" class="w-full bg-gray-100 bg-opacity-50 rounded border border-gray-300 focus:border-indigo-500 focus:bg-white focus:ring-2 focus:ring-indigo-200 text-base outline-none text-gray-700 py-1 px-3 leading-8 transition-colors duration-200 ease-in-out"
[class.border-red-500]="associationForm.controls['urlGoogleMapsEmbled'].touched && associationForm.controls['urlGoogleMapsEmbled'].invalid"
[class.border-green-500]="associationForm.controls['urlGoogleMapsEmbled'].touched && associationForm.controls['urlGoogleMapsEmbled'].valid">
<div *ngIf="associationForm.controls['urlGoogleMapsEmbled'].touched && associationForm.controls['urlGoogleMapsEmbled'].invalid" class="text-red-500 text-xs mt-1">
{{ getErrorMessage('urlGoogleMapsEmbled') }}
</div>
</div>
</div>
<div class="p-2 w-full">
<button type="submit" [disabled]="associationForm.invalid" class="flex mx-auto text-white bg-indigo-500 border-0 py-2 px-8 focus:outline-none hover:bg-indigo-600 rounded text-lg">Créer l'association</button>
</div>
</div>
</form>
</div>
</section>
</ng-template>
</p-accordionTab>
</p-accordion>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { AuthService } from '@auth0/auth0-angular';
import { Subscription } from 'rxjs';
import { Association } from '../../../interfaces/interfaces';
import { faLocationDot, faPen } from '@fortawesome/free-solid-svg-icons';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';


@Component({
Expand All @@ -19,26 +20,40 @@ export class AssociationsListComponent {
isAuthenticated: boolean = false;
faLocationDot = faLocationDot;
faPen = faPen;

associationForm!: FormGroup;


constructor(
private appService: AppService,
private sanitizer: DomSanitizer,
private toastr: ToastrService,
public auth: AuthService,
@Inject(DOCUMENT) private doc: Document
@Inject(DOCUMENT) private doc: Document,
private fb: FormBuilder
) {}

associations: Association[] = [];
private subscriptions = new Subscription();

async ngOnInit() {
this.getAssociations();
this.associationForm = this.fb.group({
nom: ['', [Validators.required, Validators.minLength(3)]],
url: ['', Validators.required],
ville: ['', Validators.required],
description: ['', [Validators.required, Validators.minLength(10)]],
shortDescription: ['', [Validators.required, Validators.minLength(10)]],
tel: ['', [Validators.required]],
urlGoogleMapsEmbled: ['', [Validators.required, Validators.minLength(10)]]
});
}


getAssociations() {
const associationSubscription = this.appService.getAllAssociations().subscribe({
next: (associations) => {
this.associations = associations;
console.log('🚀 ~ AssociationsListComponent ~ associationSubscription ~ this.associations:', this.associations);
this.isLoaded = true;
},
error: (error) => {
Expand All @@ -51,11 +66,40 @@ export class AssociationsListComponent {

this.subscriptions.add(associationSubscription);
}

ngOnDestroy() {
this.subscriptions.unsubscribe();
}

getErrorMessage(controlName: string): string {
const control = this.associationForm.get(controlName);
if (control?.hasError('required')) {
return 'Ce champ est requis';
}
if (control?.hasError('minlength')) {
const minLength = control?.errors?.['minlength'].requiredLength;
return `Ce champ doit contenir au moins ${minLength} caractères`;
}
return '';
}


onSubmit() {
if (this.associationForm.valid) {
console.log('Form Data:', this.associationForm.value);
this.appService.createAsso(this.associationForm.value).subscribe({
next: (response) => {
console.log('response:', response);
this.toastr.success('Association créée avec succès, elle va être vérifiée par un administrateur', 'Succès');
this.associationForm.reset();
},
error: (error) => {
this.toastr.error('Une erreur est survenue, veuillez réessayer plus tard', 'Erreur');
console.error('error:', error);
}
});
}
}

sanitizeHtml(html: string): SafeHtml {
return this.sanitizer.bypassSecurityTrustHtml(html);
}
Expand Down
2 changes: 1 addition & 1 deletion src/app/interfaces/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ export interface Utilisateur {
}

export interface Association {
id: number;
id?: number;
nom: string;
url: string;
ville: string;
Expand Down
8 changes: 8 additions & 0 deletions src/app/services/app.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,14 @@ export class AppService {
);
}

createAsso(asso: Association): Observable<Association> {
return this.http.post(this.api + '/associations', asso).pipe(
map((res: any) => res),
share(),
take(1)
);
}

createFavori(favori: Favori): Observable<Favori> {
return this.http.post(this.api + '/favoris', favori).pipe(
map((res: any) => res),
Expand Down

1 comment on commit 66d043b

@vercel
Copy link

@vercel vercel bot commented on 66d043b Sep 7, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.