From 9ad6ffadcb39311cd67a366828b3fda0c35a5aca Mon Sep 17 00:00:00 2001 From: Xenos F Date: Tue, 19 Mar 2024 18:23:15 +0800 Subject: [PATCH 1/9] Add confirmation prompt --- .../instructor-request-form.component.html | 1 + .../instructor-request-form.component.scss | 0 .../instructor-request-form.component.spec.ts | 21 +++++++++++++++++++ .../instructor-request-form.component.ts | 10 +++++++++ .../request-page/request-page.component.html | 18 +++++++++++++++- .../request-page/request-page.component.ts | 5 +++++ .../request-page/request-page.module.ts | 4 ++++ 7 files changed, 58 insertions(+), 1 deletion(-) create mode 100644 src/web/app/pages-static/request-page/instructor-request-form/instructor-request-form.component.html create mode 100644 src/web/app/pages-static/request-page/instructor-request-form/instructor-request-form.component.scss create mode 100644 src/web/app/pages-static/request-page/instructor-request-form/instructor-request-form.component.spec.ts create mode 100644 src/web/app/pages-static/request-page/instructor-request-form/instructor-request-form.component.ts diff --git a/src/web/app/pages-static/request-page/instructor-request-form/instructor-request-form.component.html b/src/web/app/pages-static/request-page/instructor-request-form/instructor-request-form.component.html new file mode 100644 index 00000000000..379bef727bd --- /dev/null +++ b/src/web/app/pages-static/request-page/instructor-request-form/instructor-request-form.component.html @@ -0,0 +1 @@ +

instructor-request-form works!

diff --git a/src/web/app/pages-static/request-page/instructor-request-form/instructor-request-form.component.scss b/src/web/app/pages-static/request-page/instructor-request-form/instructor-request-form.component.scss new file mode 100644 index 00000000000..e69de29bb2d diff --git a/src/web/app/pages-static/request-page/instructor-request-form/instructor-request-form.component.spec.ts b/src/web/app/pages-static/request-page/instructor-request-form/instructor-request-form.component.spec.ts new file mode 100644 index 00000000000..fc17d4d68ba --- /dev/null +++ b/src/web/app/pages-static/request-page/instructor-request-form/instructor-request-form.component.spec.ts @@ -0,0 +1,21 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { InstructorRequestFormComponent } from './instructor-request-form.component'; + +describe('InstructorRequestFormComponent', () => { + let component: InstructorRequestFormComponent; + let fixture: ComponentFixture; + + beforeEach(() => { + TestBed.configureTestingModule({ + declarations: [InstructorRequestFormComponent] + }); + fixture = TestBed.createComponent(InstructorRequestFormComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/web/app/pages-static/request-page/instructor-request-form/instructor-request-form.component.ts b/src/web/app/pages-static/request-page/instructor-request-form/instructor-request-form.component.ts new file mode 100644 index 00000000000..90cec9cd07b --- /dev/null +++ b/src/web/app/pages-static/request-page/instructor-request-form/instructor-request-form.component.ts @@ -0,0 +1,10 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'tm-instructor-request-form', + templateUrl: './instructor-request-form.component.html', + styleUrls: ['./instructor-request-form.component.scss'] +}) +export class InstructorRequestFormComponent { + +} diff --git a/src/web/app/pages-static/request-page/request-page.component.html b/src/web/app/pages-static/request-page/request-page.component.html index 6314f2563bd..66c240259f9 100644 --- a/src/web/app/pages-static/request-page/request-page.component.html +++ b/src/web/app/pages-static/request-page/request-page.component.html @@ -1,6 +1,22 @@

Request for an Account

+

+ Request for an instructor account using this form if you are an instructor and want to use TEAMMATES to manage peer evaluations and/or other feedback paths of your students. +

+
+
+

+ Note: Students should not use this form to request for TEAMMATES accounts, as students do not need accounts to use TEAMMATES. Instead, TEAMMATES will email students (who have been added to TEAMMATES by a course instructor) an access link when there is a TEAMMATES session available for them to access. +

+ Back to home page + +
+ + + + +

Cannot see the request form below? Click here. @@ -11,4 +27,4 @@

The URL for the account request form is not set. -
+ \ No newline at end of file diff --git a/src/web/app/pages-static/request-page/request-page.component.ts b/src/web/app/pages-static/request-page/request-page.component.ts index 6cb307baa4b..62de55b07cf 100644 --- a/src/web/app/pages-static/request-page/request-page.component.ts +++ b/src/web/app/pages-static/request-page/request-page.component.ts @@ -13,6 +13,7 @@ import { environment } from '../../../environments/environment'; export class RequestPageComponent { accountRequestFormUrl: SafeResourceUrl | null; + isDeclarationDone: boolean = false; constructor(private sanitizer: DomSanitizer) { this.accountRequestFormUrl = environment.accountRequestFormUrl @@ -20,4 +21,8 @@ export class RequestPageComponent { : null; } + onDeclarationButtonClicked() { + this.isDeclarationDone = true; + } + } diff --git a/src/web/app/pages-static/request-page/request-page.module.ts b/src/web/app/pages-static/request-page/request-page.module.ts index 9c16ee6fc4b..91a76b354d6 100644 --- a/src/web/app/pages-static/request-page/request-page.module.ts +++ b/src/web/app/pages-static/request-page/request-page.module.ts @@ -2,6 +2,8 @@ import { CommonModule } from '@angular/common'; import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; import { RequestPageComponent } from './request-page.component'; +import { InstructorRequestFormComponent } from './instructor-request-form/instructor-request-form.component'; +import { TeammatesRouterModule } from '../../components/teammates-router/teammates-router.module'; const routes: Routes = [ { @@ -16,6 +18,7 @@ const routes: Routes = [ @NgModule({ declarations: [ RequestPageComponent, + InstructorRequestFormComponent, ], exports: [ RequestPageComponent, @@ -23,6 +26,7 @@ const routes: Routes = [ imports: [ CommonModule, RouterModule.forChild(routes), + TeammatesRouterModule ], }) export class RequestPageModule { } From 7be6abea5c201fcd0ee4cd3d54019c1bee6c9fa2 Mon Sep 17 00:00:00 2001 From: Xenos F Date: Tue, 19 Mar 2024 18:25:38 +0800 Subject: [PATCH 2/9] Remove old form iframe --- .../request-page/request-page.component.html | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/src/web/app/pages-static/request-page/request-page.component.html b/src/web/app/pages-static/request-page/request-page.component.html index 66c240259f9..4757ba69d14 100644 --- a/src/web/app/pages-static/request-page/request-page.component.html +++ b/src/web/app/pages-static/request-page/request-page.component.html @@ -14,17 +14,3 @@

- - - -
-

- Cannot see the request form below? Click here. -

- -
-
- The URL for the account request form is not set. -
\ No newline at end of file From f5fc131d22a5753f37fcfeb5e52ccbec861045f3 Mon Sep 17 00:00:00 2001 From: Xenos F Date: Tue, 19 Mar 2024 18:30:01 +0800 Subject: [PATCH 3/9] Improve declaration view spacing --- .../app/pages-static/request-page/request-page.component.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/web/app/pages-static/request-page/request-page.component.html b/src/web/app/pages-static/request-page/request-page.component.html index 4757ba69d14..9454c161540 100644 --- a/src/web/app/pages-static/request-page/request-page.component.html +++ b/src/web/app/pages-static/request-page/request-page.component.html @@ -10,7 +10,7 @@

Note: Students should not use this form to request for TEAMMATES accounts, as students do not need accounts to use TEAMMATES. Instead, TEAMMATES will email students (who have been added to TEAMMATES by a course instructor) an access link when there is a TEAMMATES session available for them to access.

Back to home page - + - +
From 7f8fce676dc229a22d731e7dd415f038b84e4a19 Mon Sep 17 00:00:00 2001 From: Xenos F Date: Wed, 20 Mar 2024 13:08:54 +0800 Subject: [PATCH 4/9] Edit page heading phrasing for clarity --- .../app/pages-static/request-page/request-page.component.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/web/app/pages-static/request-page/request-page.component.html b/src/web/app/pages-static/request-page/request-page.component.html index 9454c161540..afaca4db529 100644 --- a/src/web/app/pages-static/request-page/request-page.component.html +++ b/src/web/app/pages-static/request-page/request-page.component.html @@ -1,5 +1,5 @@

- Request for an Account + Request for an Instructor Account

Request for an instructor account using this form if you are an instructor and want to use TEAMMATES to manage peer evaluations and/or other feedback paths of your students. From 97bc62a098cd101d8f34f3b6083328a7e18704ec Mon Sep 17 00:00:00 2001 From: Xenos F Date: Thu, 21 Mar 2024 01:57:20 +0800 Subject: [PATCH 5/9] Create request form --- .../instructor-request-form.component.html | 99 ++++++++++++++++++- .../instructor-request-form.component.scss | 22 +++++ .../instructor-request-form.component.ts | 45 +++++++++ .../request-page/request-page.module.ts | 6 +- 4 files changed, 169 insertions(+), 3 deletions(-) diff --git a/src/web/app/pages-static/request-page/instructor-request-form/instructor-request-form.component.html b/src/web/app/pages-static/request-page/instructor-request-form/instructor-request-form.component.html index 379bef727bd..c19d224aa57 100644 --- a/src/web/app/pages-static/request-page/instructor-request-form/instructor-request-form.component.html +++ b/src/web/app/pages-static/request-page/instructor-request-form/instructor-request-form.component.html @@ -1 +1,98 @@ -

instructor-request-form works!

+ +
+
+ +

+ This is the name that will be shown to your students. You may include salutation (Dr. Prof. etc.) +

+ +
+
+
+ +

+ Please give full name of the university/institution. +

+ +
+
+
+ +

+ Which country is your university/institution based in? +

+ +
+
+
+ +

+ Please use the email address given to you by your school/university + (not your personal Gmail/Hotmail address). + Note that this email address will be visible to the students you enroll in TEAMMATES. +

+ +
+
+
+ + +
+
+
+ + +
+
+ +
\ No newline at end of file diff --git a/src/web/app/pages-static/request-page/instructor-request-form/instructor-request-form.component.scss b/src/web/app/pages-static/request-page/instructor-request-form/instructor-request-form.component.scss index e69de29bb2d..81cd48b8c03 100644 --- a/src/web/app/pages-static/request-page/instructor-request-form/instructor-request-form.component.scss +++ b/src/web/app/pages-static/request-page/instructor-request-form/instructor-request-form.component.scss @@ -0,0 +1,22 @@ +label.qn { + font-weight: bold; + font-size: 1rem; + margin-bottom: 0.3rem; +} + +.form-group { + margin-bottom: 0.5rem; +} + +.form-group.required > label:after { + content:"*"; + color: red; +} + +.help-block { + margin-bottom: 0.8rem; +} + +.red-font { + color: red; +} diff --git a/src/web/app/pages-static/request-page/instructor-request-form/instructor-request-form.component.ts b/src/web/app/pages-static/request-page/instructor-request-form/instructor-request-form.component.ts index 90cec9cd07b..a8def209518 100644 --- a/src/web/app/pages-static/request-page/instructor-request-form/instructor-request-form.component.ts +++ b/src/web/app/pages-static/request-page/instructor-request-form/instructor-request-form.component.ts @@ -1,4 +1,7 @@ import { Component } from '@angular/core'; +import { FormControl, FormGroup, Validators } from '@angular/forms'; + +const URL_REGEX = '(http(s)?:\/\/.)?(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)'; @Component({ selector: 'tm-instructor-request-form', @@ -7,4 +10,46 @@ import { Component } from '@angular/core'; }) export class InstructorRequestFormComponent { + arf = new FormGroup({ + name: new FormControl('', [Validators.required]), + institution: new FormControl('', [Validators.required]), + country: new FormControl('', [Validators.required]), + email: new FormControl('', [Validators.required, Validators.email]), + homePage: new FormControl('', [Validators.pattern(URL_REGEX)]), + comments: new FormControl('') + }, {updateOn: 'submit'}); + + // Create members for easier access of arf controls + name = this.arf.controls.name; + institution = this.arf.controls.institution; + country = this.arf.controls.country; + email = this.arf.controls.email; + homePage = this.arf.controls.homePage; + comments = this.arf.controls.comments; + + hasSubmitAttempt = false; + + isFieldRequired(field: FormControl): boolean { + return field.hasValidator(Validators.required); + } + + isFieldInvalid(field: FormControl): boolean { + return field.touched && field.invalid; + } + + getFieldValidationClasses(field: FormControl): string { + let str = ""; + if (this.hasSubmitAttempt) { + if (field.invalid) { + str = "is-invalid"; + } else if (field.value !== "") { + str = "is-valid"; + } + } + return str; + } + + onSubmit() { + this.hasSubmitAttempt = true; + } } diff --git a/src/web/app/pages-static/request-page/request-page.module.ts b/src/web/app/pages-static/request-page/request-page.module.ts index 91a76b354d6..6e252062496 100644 --- a/src/web/app/pages-static/request-page/request-page.module.ts +++ b/src/web/app/pages-static/request-page/request-page.module.ts @@ -4,6 +4,7 @@ import { RouterModule, Routes } from '@angular/router'; import { RequestPageComponent } from './request-page.component'; import { InstructorRequestFormComponent } from './instructor-request-form/instructor-request-form.component'; import { TeammatesRouterModule } from '../../components/teammates-router/teammates-router.module'; +import { ReactiveFormsModule } from '@angular/forms'; const routes: Routes = [ { @@ -18,7 +19,7 @@ const routes: Routes = [ @NgModule({ declarations: [ RequestPageComponent, - InstructorRequestFormComponent, + InstructorRequestFormComponent ], exports: [ RequestPageComponent, @@ -26,7 +27,8 @@ const routes: Routes = [ imports: [ CommonModule, RouterModule.forChild(routes), - TeammatesRouterModule + TeammatesRouterModule, + ReactiveFormsModule ], }) export class RequestPageModule { } From 3b957d94ac77c73210cd1feba2e672628e407ad2 Mon Sep 17 00:00:00 2001 From: Xenos F Date: Thu, 21 Mar 2024 02:19:09 +0800 Subject: [PATCH 6/9] Add validation messages --- .../instructor-request-form.component.html | 65 +++++++++++++++++-- .../instructor-request-form.component.ts | 1 + 2 files changed, 59 insertions(+), 7 deletions(-) diff --git a/src/web/app/pages-static/request-page/instructor-request-form/instructor-request-form.component.html b/src/web/app/pages-static/request-page/instructor-request-form/instructor-request-form.component.html index c19d224aa57..bfbd00dac20 100644 --- a/src/web/app/pages-static/request-page/instructor-request-form/instructor-request-form.component.html +++ b/src/web/app/pages-static/request-page/instructor-request-form/instructor-request-form.component.html @@ -4,22 +4,33 @@

-

-

-

-

-

-
diff --git a/src/web/app/pages-static/request-page/instructor-request-form/instructor-request-form.component.ts b/src/web/app/pages-static/request-page/instructor-request-form/instructor-request-form.component.ts index b5e4515e720..a9012df1574 100644 --- a/src/web/app/pages-static/request-page/instructor-request-form/instructor-request-form.component.ts +++ b/src/web/app/pages-static/request-page/instructor-request-form/instructor-request-form.component.ts @@ -34,7 +34,7 @@ export class InstructorRequestFormComponent { } isFieldInvalid(field: FormControl): boolean { - return field.touched && field.invalid; + return field.invalid; } getFieldValidationClasses(field: FormControl): string { From f3845cc22ba688dcc3870d7289436450e1153bc6 Mon Sep 17 00:00:00 2001 From: Xenos F Date: Sat, 23 Mar 2024 12:15:10 +0800 Subject: [PATCH 8/9] Set up form submission confirmation --- .../InstructorRequestFormData.ts | 8 ++++ .../instructor-request-form.component.ts | 39 ++++++++++++++++++- .../request-page/request-page.component.html | 9 ++++- .../request-page/request-page.component.ts | 7 +++- 4 files changed, 58 insertions(+), 5 deletions(-) create mode 100644 src/web/app/pages-static/request-page/instructor-request-form/InstructorRequestFormData.ts diff --git a/src/web/app/pages-static/request-page/instructor-request-form/InstructorRequestFormData.ts b/src/web/app/pages-static/request-page/instructor-request-form/InstructorRequestFormData.ts new file mode 100644 index 00000000000..0b1014d9585 --- /dev/null +++ b/src/web/app/pages-static/request-page/instructor-request-form/InstructorRequestFormData.ts @@ -0,0 +1,8 @@ +export type InstructorRequestFormData = { + name: string; + institution: string; + country: string; + email: string; + homePage: string; + comments: string; +} \ No newline at end of file diff --git a/src/web/app/pages-static/request-page/instructor-request-form/instructor-request-form.component.ts b/src/web/app/pages-static/request-page/instructor-request-form/instructor-request-form.component.ts index a9012df1574..dc2684354e5 100644 --- a/src/web/app/pages-static/request-page/instructor-request-form/instructor-request-form.component.ts +++ b/src/web/app/pages-static/request-page/instructor-request-form/instructor-request-form.component.ts @@ -1,12 +1,13 @@ -import { Component } from '@angular/core'; +import { Component, EventEmitter, Output } from '@angular/core'; import { FormControl, FormGroup, Validators } from '@angular/forms'; +import { InstructorRequestFormData } from './InstructorRequestFormData'; const URL_REGEX = '(http(s)?:\/\/.)?(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)'; @Component({ selector: 'tm-instructor-request-form', templateUrl: './instructor-request-form.component.html', - styleUrls: ['./instructor-request-form.component.scss'] + styleUrls: ['./instructor-request-form.component.scss'], }) export class InstructorRequestFormComponent { @@ -29,6 +30,8 @@ export class InstructorRequestFormComponent { hasSubmitAttempt = false; + @Output() requestSubmitted = new EventEmitter(); + isFieldRequired(field: FormControl): boolean { return field.hasValidator(Validators.required); } @@ -51,6 +54,38 @@ export class InstructorRequestFormComponent { onSubmit() { this.hasSubmitAttempt = true; + + if (this.arf.invalid) { + // Do not submit form + return; + } + + let name = this.name.value!.trim(); + let email = this.email.value!.trim(); + let country = this.country.value!.trim(); + let institution = this.institution.value!.trim(); + let combinedInstitution = country + " " + institution; + let homePage = this.homePage.value!; + let comments = this.comments.value!.trim(); + + let submittedData = { + name: name, + email: email, + institution: combinedInstitution, + homePage: homePage, + comments: comments + } // TODO: connect to API + console.log(submittedData); + + // Pass form input to parent to display confirmation + this.requestSubmitted.emit({ + name: name, + institution: institution, + country: country, + email: email, + homePage: homePage, + comments: comments + }); } } diff --git a/src/web/app/pages-static/request-page/request-page.component.html b/src/web/app/pages-static/request-page/request-page.component.html index afaca4db529..017c1384c18 100644 --- a/src/web/app/pages-static/request-page/request-page.component.html +++ b/src/web/app/pages-static/request-page/request-page.component.html @@ -12,5 +12,10 @@

Back to home page - -
+
+ +
+ name: {{submittedFormData!.name}} +
+
+
\ No newline at end of file diff --git a/src/web/app/pages-static/request-page/request-page.component.ts b/src/web/app/pages-static/request-page/request-page.component.ts index 62de55b07cf..e23b025deaf 100644 --- a/src/web/app/pages-static/request-page/request-page.component.ts +++ b/src/web/app/pages-static/request-page/request-page.component.ts @@ -1,6 +1,7 @@ import { Component } from '@angular/core'; import { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser'; import { environment } from '../../../environments/environment'; +import { InstructorRequestFormData } from './instructor-request-form/InstructorRequestFormData'; /** * Account request page. @@ -13,7 +14,8 @@ import { environment } from '../../../environments/environment'; export class RequestPageComponent { accountRequestFormUrl: SafeResourceUrl | null; - isDeclarationDone: boolean = false; + isDeclarationDone: boolean = true; + submittedFormData: InstructorRequestFormData | null = null; constructor(private sanitizer: DomSanitizer) { this.accountRequestFormUrl = environment.accountRequestFormUrl @@ -25,4 +27,7 @@ export class RequestPageComponent { this.isDeclarationDone = true; } + onRequestSubmitted(data: InstructorRequestFormData) { + this.submittedFormData = data; + } } From 17baed658640139564461be59d220c081c12a9be Mon Sep 17 00:00:00 2001 From: Xenos F Date: Sun, 24 Mar 2024 20:49:57 +0800 Subject: [PATCH 9/9] Create submission acknowledgement view --- .../instructor-request-form.component.html | 2 +- .../request-page/request-page.component.html | 72 ++++++++++++++----- 2 files changed, 57 insertions(+), 17 deletions(-) diff --git a/src/web/app/pages-static/request-page/instructor-request-form/instructor-request-form.component.html b/src/web/app/pages-static/request-page/instructor-request-form/instructor-request-form.component.html index 23f8ff02822..e107db79a4c 100644 --- a/src/web/app/pages-static/request-page/instructor-request-form/instructor-request-form.component.html +++ b/src/web/app/pages-static/request-page/instructor-request-form/instructor-request-form.component.html @@ -2,7 +2,7 @@ Questions marked with an asterisk * are required.

- +