Skip to content
Snippets Groups Projects
Commit f5abd5e5 authored by Hugo SUBTIL's avatar Hugo SUBTIL
Browse files

feat: add connect redirection + handle structure join

parent 60fa0c8e
No related branches found
No related tags found
3 merge requests!85Recette,!84Dev,!76Fix/add user to structure
Showing
with 184 additions and 12 deletions
...@@ -12,6 +12,7 @@ import { ProfileComponent } from './profile/profile.component'; ...@@ -12,6 +12,7 @@ import { ProfileComponent } from './profile/profile.component';
import { ResetEmailComponent } from './reset-email/reset-email.component'; import { ResetEmailComponent } from './reset-email/reset-email.component';
import { ResetPasswordComponent } from './reset-password/reset-password.component'; import { ResetPasswordComponent } from './reset-password/reset-password.component';
import { TempUserResolver } from './resolvers/temp-user.resolver'; import { TempUserResolver } from './resolvers/temp-user.resolver';
import { StructureJoinComponent } from './structure-join/structure-join.component';
import { StructureDetailsComponent } from './structure-list/components/structure-details/structure-details.component'; import { StructureDetailsComponent } from './structure-list/components/structure-details/structure-details.component';
import { StructureListComponent } from './structure-list/structure-list.component'; import { StructureListComponent } from './structure-list/structure-list.component';
import { UserVerificationComponent } from './user-verification/user-verification.component'; import { UserVerificationComponent } from './user-verification/user-verification.component';
...@@ -67,6 +68,11 @@ const routes: Routes = [ ...@@ -67,6 +68,11 @@ const routes: Routes = [
canActivate: [AuthGuard], canActivate: [AuthGuard],
component: ProfileComponent, component: ProfileComponent,
}, },
{
path: 'join',
canActivate: [AuthGuard],
component: StructureJoinComponent,
},
{ {
path: 'reset-password', path: 'reset-password',
component: ResetPasswordComponent, component: ResetPasswordComponent,
......
...@@ -31,6 +31,7 @@ import { AdminGuard } from './guards/admin.guard'; ...@@ -31,6 +31,7 @@ import { AdminGuard } from './guards/admin.guard';
import { DeactivateGuard } from './guards/deactivate.guard'; import { DeactivateGuard } from './guards/deactivate.guard';
import { FooterFormComponent } from './form/footer-form/footer-form.component'; import { FooterFormComponent } from './form/footer-form/footer-form.component';
import { TempUserResolver } from './resolvers/temp-user.resolver'; import { TempUserResolver } from './resolvers/temp-user.resolver';
import { StructureJoinComponent } from './structure-join/structure-join.component';
@NgModule({ @NgModule({
declarations: [ declarations: [
...@@ -51,6 +52,7 @@ import { TempUserResolver } from './resolvers/temp-user.resolver'; ...@@ -51,6 +52,7 @@ import { TempUserResolver } from './resolvers/temp-user.resolver';
ResetPasswordComponent, ResetPasswordComponent,
FormComponent, FormComponent,
FooterFormComponent, FooterFormComponent,
StructureJoinComponent,
], ],
imports: [BrowserModule, HttpClientModule, AppRoutingModule, SharedModule, MapModule, ProfileModule, AdminModule], imports: [BrowserModule, HttpClientModule, AppRoutingModule, SharedModule, MapModule, ProfileModule, AdminModule],
providers: [ providers: [
......
...@@ -53,8 +53,8 @@ ...@@ -53,8 +53,8 @@
fxLayoutAlign="space-between center" fxLayoutAlign="space-between center"
fxLayoutAlign.lt-sm="center" fxLayoutAlign.lt-sm="center"
> >
<h2> <h2 class="no-wrap">
Revendiquer la structure <span>{{ claimStructure.structureName }}</span> {{ isJoinMode ? 'Rejoindre' : 'Revendiquer' }} la structure <span>{{ claimStructure.structureName }}</span>
</h2> </h2>
<div> <div>
<p>Une fois réalisé cela vous permettra de devenir propriétaire de cette structure</p> <p>Une fois réalisé cela vous permettra de devenir propriétaire de cette structure</p>
......
...@@ -109,6 +109,9 @@ h3 { ...@@ -109,6 +109,9 @@ h3 {
span { span {
color: $secondary-color; color: $secondary-color;
} }
&.no-wrap {
white-space: nowrap;
}
} }
h3 { h3 {
@include cn-bold-22; @include cn-bold-22;
......
...@@ -70,6 +70,7 @@ export class FormComponent implements OnInit { ...@@ -70,6 +70,7 @@ export class FormComponent implements OnInit {
public isEditMode = false; public isEditMode = false;
public isClaimMode = false; public isClaimMode = false;
public isAccountMode = false; public isAccountMode = false;
public isJoinMode = false;
public isLoading = false; public isLoading = false;
public isWifiChoosen = false; public isWifiChoosen = false;
...@@ -97,6 +98,10 @@ export class FormComponent implements OnInit { ...@@ -97,6 +98,10 @@ export class FormComponent implements OnInit {
this.initForm(new Structure(history.state.data)); this.initForm(new Structure(history.state.data));
} else if (history.state.newUser) { } else if (history.state.newUser) {
this.isClaimMode = true; this.isClaimMode = true;
// Handle join strucutre, the case is very similar to claim
if (history.state.isJoin) {
this.isJoinMode = true;
}
this.createAccountForm(); this.createAccountForm();
this.claimStructure = history.state.newUser; this.claimStructure = history.state.newUser;
this.setValidationsForm(); this.setValidationsForm();
...@@ -550,9 +555,16 @@ export class FormComponent implements OnInit { ...@@ -550,9 +555,16 @@ export class FormComponent implements OnInit {
const user = new User(this.accountForm.value); const user = new User(this.accountForm.value);
// Create user and claim structure // Create user and claim structure
this.authService.register(user).subscribe(() => { this.authService.register(user).subscribe(() => {
this.structureService.claimStructureWithAccount(this.claimStructure._id, user).subscribe(() => { // If joinMode, send join request, if not send claim request;
this.progressStatus = 100; if (this.isJoinMode) {
}); this.structureService.joinStructure(this.claimStructure._id, user.email).subscribe(() => {
this.progressStatus = 100;
});
} else {
this.structureService.claimStructureWithAccount(this.claimStructure._id, user).subscribe(() => {
this.progressStatus = 100;
});
}
}); });
} }
...@@ -615,6 +627,21 @@ export class FormComponent implements OnInit { ...@@ -615,6 +627,21 @@ export class FormComponent implements OnInit {
this.progressStatus -= 25; this.progressStatus -= 25;
} }
/**
* Page algo for claim structure case
*/
public previousPageAccount(): void {
if (this.currentPage == PageTypeEnum.accountCredentials) {
this.currentPage = PageTypeEnum.accountInfo;
this.updatePageValid();
} else if (this.currentPage == PageTypeEnum.cgu) {
this.currentPage = PageTypeEnum.accountCredentials;
this.updatePageValid();
}
this.progressStatus -= 25;
}
public nextPage(): void { public nextPage(): void {
if (this.isClaimMode) { if (this.isClaimMode) {
this.nextPageClaim(); this.nextPageClaim();
...@@ -648,6 +675,8 @@ export class FormComponent implements OnInit { ...@@ -648,6 +675,8 @@ export class FormComponent implements OnInit {
public previousPage(): void { public previousPage(): void {
if (this.isClaimMode) { if (this.isClaimMode) {
this.previousPageClaim(); this.previousPageClaim();
} else if (this.isAccountMode) {
this.previousPageAccount();
} else { } else {
// Check if user already connected to skip accountForm pages. // Check if user already connected to skip accountForm pages.
if (this.currentPage == PageTypeEnum.structureNameAndAddress && this.profile) { if (this.currentPage == PageTypeEnum.structureNameAndAddress && this.profile) {
......
...@@ -10,10 +10,11 @@ import { Observable } from 'rxjs'; ...@@ -10,10 +10,11 @@ import { Observable } from 'rxjs';
export class AuthGuard implements CanActivate { export class AuthGuard implements CanActivate {
constructor(private authService: AuthService, private router: Router) {} constructor(private authService: AuthService, private router: Router) {}
canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): UrlTree | boolean { canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
if (this.authService.isLoggedIn()) { if (this.authService.isLoggedIn()) {
return true; return true;
} }
return this.router.parseUrl('/home'); this.router.navigate(['/home'], { queryParams: { returnUrl: state.url } });
return false;
} }
} }
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { NavigationEnd, NavigationStart, Router } from '@angular/router'; import { ActivatedRoute, NavigationEnd, NavigationStart, Router } from '@angular/router';
import { ProfileService } from '../profile/services/profile.service'; import { ProfileService } from '../profile/services/profile.service';
import { AuthService } from '../services/auth.service'; import { AuthService } from '../services/auth.service';
...@@ -13,20 +13,39 @@ export class HeaderComponent implements OnInit { ...@@ -13,20 +13,39 @@ export class HeaderComponent implements OnInit {
public isPopUpOpen = false; public isPopUpOpen = false;
public displaySignUp = true; public displaySignUp = true;
public currentRoute = ''; public currentRoute = '';
public formeRoute = '/create-structure'; public formRoute = '/create-structure';
public returnUrl = null;
constructor(private authService: AuthService, private profileService: ProfileService, private router: Router) { constructor(
private authService: AuthService,
private profileService: ProfileService,
private router: Router,
private route: ActivatedRoute
) {
this.router.events.subscribe((event) => { this.router.events.subscribe((event) => {
if (event instanceof NavigationEnd) { if (event instanceof NavigationEnd) {
this.currentRoute = event.url; this.currentRoute = event.url;
} }
}); });
} }
ngOnInit(): void {} ngOnInit(): void {
this.route.queryParams.subscribe((params) => {
if (params.verified || params.returnUrl) {
Promise.resolve().then(() => {
if (!this.isLoggedIn) {
this.isPopUpOpen = true;
this.displaySignUp = true;
}
});
this.returnUrl = params.returnUrl;
}
});
}
public openMenu(): void { public openMenu(): void {
this.showMenu = true; this.showMenu = true;
} }
public closeMenu(route: string): void { public closeMenu(route: string): void {
this.router.navigateByUrl(route); this.router.navigateByUrl(route);
this.showMenu = false; this.showMenu = false;
...@@ -47,6 +66,9 @@ export class HeaderComponent implements OnInit { ...@@ -47,6 +66,9 @@ export class HeaderComponent implements OnInit {
} else { } else {
this.isPopUpOpen = false; this.isPopUpOpen = false;
} }
if (this.returnUrl && this.isLoggedIn) {
this.router.navigateByUrl(this.returnUrl);
}
} }
public get isAdmin(): boolean { public get isAdmin(): boolean {
...@@ -58,6 +80,6 @@ export class HeaderComponent implements OnInit { ...@@ -58,6 +80,6 @@ export class HeaderComponent implements OnInit {
} }
public displayLogo(): boolean { public displayLogo(): boolean {
return this.formeRoute !== this.currentRoute; return this.formRoute !== this.currentRoute;
} }
} }
...@@ -50,6 +50,14 @@ export class StructureService { ...@@ -50,6 +50,14 @@ export class StructureService {
return this.http.get<Structure>(`${this.baseUrl}/${id}`); return this.http.get<Structure>(`${this.baseUrl}/${id}`);
} }
public validateStructureJoin(id: string, userId: string, state: boolean): Observable<Structure> {
return this.http.post<any>(`${this.baseUrl}/${id}/join/${userId}/${state}`, null);
}
public joinStructure(id: string, email: string): Observable<Structure> {
return this.http.post<any>(`${this.baseUrl}/${id}/join`, { email });
}
public delete(id: string): Observable<Structure> { public delete(id: string): Observable<Structure> {
return this.http.delete<Structure>(`${this.baseUrl}/${id}`); return this.http.delete<Structure>(`${this.baseUrl}/${id}`);
} }
......
<div fxLayout="column" class="content-container full-screen">
<div class="section-container" fxLayout="column" fxLayoutAlign="center center">
<h1>Validation de la demande de rattachement</h1>
<p>Merci de patienter...</p>
</div>
</div>
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { StructureJoinComponent } from './structure-join.component';
describe('StructureJoinComponent', () => {
let component: StructureJoinComponent;
let fixture: ComponentFixture<StructureJoinComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ StructureJoinComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(StructureJoinComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
import { Component, OnInit } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router';
import { StructureService } from '../services/structure.service';
@Component({
selector: 'app-structure-join',
templateUrl: './structure-join.component.html',
styleUrls: ['./structure-join.component.scss'],
})
export class StructureJoinComponent implements OnInit {
constructor(private router: Router, private route: ActivatedRoute, private structureService: StructureService) {}
ngOnInit(): void {
this.route.queryParamMap.subscribe((params) => {
if (
params.get('id') &&
params.get('userId') &&
(params.get('status') === 'true' || params.get('status') === 'false')
) {
this.structureService
.validateStructureJoin(params.get('id'), params.get('userId'), params.get('status') === 'true' ? true : false)
.subscribe(
(res) => {
this.router.navigateByUrl('/home');
},
(err) => {
this.router.navigateByUrl('/home');
}
);
}
});
}
}
...@@ -118,6 +118,7 @@ ...@@ -118,6 +118,7 @@
</div> </div>
<div fxLayout="row" fxLayoutAlign="center center" class="hide-on-print"> <div fxLayout="row" fxLayoutAlign="center center" class="hide-on-print">
<a *ngIf="!isClaimed" (click)="handleClaim()" class="primary" tabindex="0">Revendiquer cette structure</a> <a *ngIf="!isClaimed" (click)="handleClaim()" class="primary" tabindex="0">Revendiquer cette structure</a>
<a *ngIf="displayJoin()" (click)="handleJoin()" class="primary" tabindex="0">Rejoindre cette structure</a>
<!-- temporary remove edit --> <!-- temporary remove edit -->
<a <a
*ngIf="profileService.isLinkedToStructure(structure._id) || profileService.isAdmin()" *ngIf="profileService.isLinkedToStructure(structure._id) || profileService.isAdmin()"
...@@ -326,3 +327,11 @@ ...@@ -326,3 +327,11 @@
" "
(closed)="claimStructure($event)" (closed)="claimStructure($event)"
></app-modal-confirmation> ></app-modal-confirmation>
<app-modal-confirmation
[openned]="joinModalOpenned"
[content]="
'Voulez-vous vraiment rejoindre cette structure&nbsp;? Une demande sera envoyée aux membres pour validation'
"
(closed)="joinStructure($event)"
></app-modal-confirmation>
...@@ -36,6 +36,7 @@ export class StructureDetailsComponent implements OnInit { ...@@ -36,6 +36,7 @@ export class StructureDetailsComponent implements OnInit {
public currentProfile: User = null; public currentProfile: User = null;
public deleteModalOpenned = false; public deleteModalOpenned = false;
public claimModalOpenned = false; public claimModalOpenned = false;
public joinModalOpenned = false;
constructor( constructor(
private printService: PrintService, private printService: PrintService,
...@@ -122,6 +123,10 @@ export class StructureDetailsComponent implements OnInit { ...@@ -122,6 +123,10 @@ export class StructureDetailsComponent implements OnInit {
this.claimModalOpenned = !this.claimModalOpenned; this.claimModalOpenned = !this.claimModalOpenned;
} }
public toggleJoinModal(): void {
this.joinModalOpenned = !this.joinModalOpenned;
}
public handleClaim(): void { public handleClaim(): void {
if (this.userIsLoggedIn()) { if (this.userIsLoggedIn()) {
this.toggleClaimModal(); this.toggleClaimModal();
...@@ -130,6 +135,14 @@ export class StructureDetailsComponent implements OnInit { ...@@ -130,6 +135,14 @@ export class StructureDetailsComponent implements OnInit {
} }
} }
public handleJoin(): void {
if (this.userIsLoggedIn()) {
this.toggleJoinModal();
} else {
this.router.navigate(['create-structure'], { state: { newUser: this.structure, isJoin: true } });
}
}
public deleteStructure(shouldDelete: boolean): void { public deleteStructure(shouldDelete: boolean): void {
this.toggleDeleteModal(); this.toggleDeleteModal();
if (shouldDelete) { if (shouldDelete) {
...@@ -156,6 +169,15 @@ export class StructureDetailsComponent implements OnInit { ...@@ -156,6 +169,15 @@ export class StructureDetailsComponent implements OnInit {
} }
} }
public joinStructure(shouldClaim: boolean): void {
this.toggleJoinModal();
if (shouldClaim) {
this.structureService.joinStructure(this.structure._id, this.authService.userValue.username).subscribe((res) => {
this.isClaimed = true;
});
}
}
public getAccessLabel(accessModality: AccessModality): string { public getAccessLabel(accessModality: AccessModality): string {
switch (accessModality) { switch (accessModality) {
case AccessModality.free: case AccessModality.free:
...@@ -222,4 +244,10 @@ export class StructureDetailsComponent implements OnInit { ...@@ -222,4 +244,10 @@ export class StructureDetailsComponent implements OnInit {
['ordinateurs', 'tablettes', 'bornesNumeriques', 'imprimantes', 'scanners', 'wifiEnAccesLibre'].includes(eqpt) ['ordinateurs', 'tablettes', 'bornesNumeriques', 'imprimantes', 'scanners', 'wifiEnAccesLibre'].includes(eqpt)
); );
} }
public displayJoin(): boolean {
return (
!(this.profileService.isLinkedToStructure(this.structure._id) || this.profileService.isAdmin()) && this.isClaimed
);
}
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment