From ff49411e870af5ad97bb1fc5637fecd02195dab7 Mon Sep 17 00:00:00 2001 From: Magdalena Kanicka Date: Sat, 13 Jan 2024 14:46:03 +0100 Subject: [PATCH] Profile UI: initial profile form template --- src/frontend/src/app/app.routes.ts | 8 +- src/frontend/src/app/core/utils/index.ts | 1 + src/frontend/src/app/core/utils/keys-of.ts | 3 + .../src/app/pages/profile-edit/index.ts | 1 + .../profile-edit.component.spec.ts | 22 ++++++ .../profile-edit/profile-edit.component.ts | 75 +++++++++++++++++++ .../app/pages/profile-edit/profile.model.ts | 25 +++++++ 7 files changed, 134 insertions(+), 1 deletion(-) create mode 100644 src/frontend/src/app/core/utils/index.ts create mode 100644 src/frontend/src/app/core/utils/keys-of.ts create mode 100644 src/frontend/src/app/pages/profile-edit/index.ts create mode 100644 src/frontend/src/app/pages/profile-edit/profile-edit.component.spec.ts create mode 100644 src/frontend/src/app/pages/profile-edit/profile-edit.component.ts create mode 100644 src/frontend/src/app/pages/profile-edit/profile.model.ts diff --git a/src/frontend/src/app/app.routes.ts b/src/frontend/src/app/app.routes.ts index de34bde3..613d0385 100644 --- a/src/frontend/src/app/app.routes.ts +++ b/src/frontend/src/app/app.routes.ts @@ -1,3 +1,9 @@ import { type Routes } from '@angular/router'; -export const routes: Routes = []; +export const routes: Routes = [ + { + path: 'profile/edit', + loadComponent: () => + import('./pages/profile-edit').then(m => m.ProfileEditComponent), + }, +]; diff --git a/src/frontend/src/app/core/utils/index.ts b/src/frontend/src/app/core/utils/index.ts new file mode 100644 index 00000000..20b68263 --- /dev/null +++ b/src/frontend/src/app/core/utils/index.ts @@ -0,0 +1 @@ +export * from './keys-of'; diff --git a/src/frontend/src/app/core/utils/keys-of.ts b/src/frontend/src/app/core/utils/keys-of.ts new file mode 100644 index 00000000..d2496bf9 --- /dev/null +++ b/src/frontend/src/app/core/utils/keys-of.ts @@ -0,0 +1,3 @@ +export function keysOf(obj: T): (keyof T)[] { + return Object.keys(obj) as (keyof T)[]; +} diff --git a/src/frontend/src/app/pages/profile-edit/index.ts b/src/frontend/src/app/pages/profile-edit/index.ts new file mode 100644 index 00000000..45d529e3 --- /dev/null +++ b/src/frontend/src/app/pages/profile-edit/index.ts @@ -0,0 +1 @@ +export * from './profile-edit.component'; diff --git a/src/frontend/src/app/pages/profile-edit/profile-edit.component.spec.ts b/src/frontend/src/app/pages/profile-edit/profile-edit.component.spec.ts new file mode 100644 index 00000000..53652a49 --- /dev/null +++ b/src/frontend/src/app/pages/profile-edit/profile-edit.component.spec.ts @@ -0,0 +1,22 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { RouterTestingModule } from '@angular/router/testing'; +import { ProfileEditComponent } from './profile-edit.component'; + +describe('ProfileViewComponent', () => { + let component: ProfileEditComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [ProfileEditComponent, RouterTestingModule], + }).compileComponents(); + + fixture = TestBed.createComponent(ProfileEditComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/frontend/src/app/pages/profile-edit/profile-edit.component.ts b/src/frontend/src/app/pages/profile-edit/profile-edit.component.ts new file mode 100644 index 00000000..ac025da0 --- /dev/null +++ b/src/frontend/src/app/pages/profile-edit/profile-edit.component.ts @@ -0,0 +1,75 @@ +import { ChangeDetectionStrategy, Component } from '@angular/core'; +import { FormBuilder, FormGroup, ReactiveFormsModule } from '@angular/forms'; +import { CommonModule } from '@angular/common'; +import { RouterModule } from '@angular/router'; +import { keysOf } from '@core/utils'; +import { socialMediaInputs } from './profile.model'; + +@Component({ + selector: 'app-profile-edit', + standalone: true, + imports: [ReactiveFormsModule, CommonModule, RouterModule], + changeDetection: ChangeDetectionStrategy.OnPush, + template: ` +
Role
+
Proposal Types
+
Neuron ID
+ +
+
+ + +
+ +
+ + +
+ +
+ Social Media +
+ @for (key of socialMediaKeys; track key) { +
+ + +
+ } +
+
+ +
+ Cancel + +
+
+ `, +}) +export class ProfileEditComponent { + public readonly profileForm!: FormGroup; + + public readonly socialMediaKeys = keysOf(socialMediaInputs); + public readonly socialMediaInputs = socialMediaInputs; + + constructor(formBuilder: FormBuilder) { + this.profileForm = formBuilder.group({ + username: [''], + bio: [''], + socialMedia: formBuilder.group(this.generateSocialMedia()), + }); + } + + public onSubmit(): void { + throw new Error('Method not implemented.'); + } + + private generateSocialMedia(): Record { + return this.socialMediaKeys.reduce( + (accum, value) => ({ + ...accum, + [value]: [''], + }), + {}, + ); + } +} diff --git a/src/frontend/src/app/pages/profile-edit/profile.model.ts b/src/frontend/src/app/pages/profile-edit/profile.model.ts new file mode 100644 index 00000000..76766b38 --- /dev/null +++ b/src/frontend/src/app/pages/profile-edit/profile.model.ts @@ -0,0 +1,25 @@ +export enum SocialMediaType { + DSCVR = 'DSCVR', + OpenChat = 'OpenChat', + Taggr = 'Taggr', + X = 'X', + DfinityForum = 'DfinityForum', + Discord = 'Discord', +} + +export type SocialMediaInputs = { + [K in SocialMediaType]: SocialMediaInputProps; +}; + +export const socialMediaInputs: SocialMediaInputs = { + DSCVR: { label: 'DSCVR' }, + OpenChat: { label: 'Open Chat' }, + Taggr: { label: 'TAGGR' }, + X: { label: 'X (Twitter)' }, + DfinityForum: { label: 'Dfinity Forum' }, + Discord: { label: 'Discord' }, +}; + +export interface SocialMediaInputProps { + label: string; +}