| @@ -1,12 +1,14 @@ | |||||
| import { NgModule } from '@angular/core'; | import { NgModule } from '@angular/core'; | ||||
| import { RouterModule, Routes } from '@angular/router'; | import { RouterModule, Routes } from '@angular/router'; | ||||
| import { LoginComponent } from './login/login.component'; | import { LoginComponent } from './login/login.component'; | ||||
| import { MockComponent } from './mock/mock.component'; | |||||
| import { RegisterBusinessComponent } from './register-business/register-business.component'; | import { RegisterBusinessComponent } from './register-business/register-business.component'; | ||||
| import { TabsComponent } from './tabs/tabs.component'; | import { TabsComponent } from './tabs/tabs.component'; | ||||
| const routes: Routes = [ | const routes: Routes = [ | ||||
| { path: '', pathMatch: 'full', redirectTo: 'login' }, | { path: '', pathMatch: 'full', redirectTo: 'login' }, | ||||
| { component: LoginComponent, path: 'login' }, | { component: LoginComponent, path: 'login' }, | ||||
| { component: MockComponent, path: 'mock' }, | |||||
| { component: TabsComponent, path: 'tabs', children : [ | { component: TabsComponent, path: 'tabs', children : [ | ||||
| { | { | ||||
| path: '', pathMatch: 'full', redirectTo: 'register-business' | path: '', pathMatch: 'full', redirectTo: 'register-business' | ||||
| @@ -7,13 +7,15 @@ import { LoginComponent } from './login/login.component'; | |||||
| import { TabsComponent } from './tabs/tabs.component'; | import { TabsComponent } from './tabs/tabs.component'; | ||||
| import { RegisterBusinessComponent } from './register-business/register-business.component'; | import { RegisterBusinessComponent } from './register-business/register-business.component'; | ||||
| import { FormsModule } from '@angular/forms'; | import { FormsModule } from '@angular/forms'; | ||||
| import { MockComponent } from './mock/mock.component'; | |||||
| @NgModule({ | @NgModule({ | ||||
| declarations: [ | declarations: [ | ||||
| AppComponent, | AppComponent, | ||||
| LoginComponent, | LoginComponent, | ||||
| TabsComponent, | TabsComponent, | ||||
| RegisterBusinessComponent | |||||
| RegisterBusinessComponent, | |||||
| MockComponent | |||||
| ], | ], | ||||
| imports: [ | imports: [ | ||||
| BrowserModule, | BrowserModule, | ||||
| @@ -0,0 +1 @@ | |||||
| <p>Mocking external window</p> | |||||
| @@ -0,0 +1,25 @@ | |||||
| import { ComponentFixture, TestBed } from '@angular/core/testing'; | |||||
| import { MockComponent } from './mock.component'; | |||||
| describe('MockComponent', () => { | |||||
| let component: MockComponent; | |||||
| let fixture: ComponentFixture<MockComponent>; | |||||
| beforeEach(async () => { | |||||
| await TestBed.configureTestingModule({ | |||||
| declarations: [ MockComponent ] | |||||
| }) | |||||
| .compileComponents(); | |||||
| }); | |||||
| beforeEach(() => { | |||||
| fixture = TestBed.createComponent(MockComponent); | |||||
| component = fixture.componentInstance; | |||||
| fixture.detectChanges(); | |||||
| }); | |||||
| it('should create', () => { | |||||
| expect(component).toBeTruthy(); | |||||
| }); | |||||
| }); | |||||
| @@ -0,0 +1,15 @@ | |||||
| import { Component, OnInit } from '@angular/core'; | |||||
| @Component({ | |||||
| selector: 'app-mock', | |||||
| templateUrl: './mock.component.html', | |||||
| styleUrls: ['./mock.component.scss'] | |||||
| }) | |||||
| export class MockComponent implements OnInit { | |||||
| constructor() { } | |||||
| ngOnInit(): void { | |||||
| } | |||||
| } | |||||
| @@ -12,33 +12,33 @@ | |||||
| </section> | </section> | ||||
| <p class="description"> | <p class="description"> | ||||
| Lorem, ipsum dolor sit amet consectetur adipisicing elit. Numquam nisi quia fuga nobis magnam accusamus recusandae vitae architecto fugit natus! Nostrum doloremque id laborum sequi magni ducimus perferendis quam aspernatur? | |||||
| This is the full name for a business entity that I wish to reserve, including any required prefixes and suffixes. I understand that this has to be nationally unique, and am not violating any copyrights or trademarks. | |||||
| </p> | </p> | ||||
| <section class="form-message" [ngClass]="{'error' : error.isError}" *ngIf="error"> | |||||
| <h5 *ngIf="error.isError"> Sorry! </h5> | |||||
| <h5 *ngIf="!error.isError"> Yay! </h5> | |||||
| <section class="form-message" [ngClass]="{'error' : error.isInvalid || !error.isUnique}" *ngIf="error"> | |||||
| <h5 *ngIf="error.isInvalid || !error.isUnique"> Sorry! </h5> | |||||
| <h5 *ngIf="!error.isInvalid && error.isUnique"> Yay! </h5> | |||||
| <p> {{ error.message }} </p> | <p> {{ error.message }} </p> | ||||
| </section> | </section> | ||||
| <button class="proceed-button" *ngIf="formState === 'INIT_REGISTER'" | |||||
| (click)="formState = 'CONFIRM_INIT'"> | |||||
| Proceed | |||||
| <button class="proceed-button" *ngIf="error && !error.isInvalid" | |||||
| (click)="confirmName()"> | |||||
| {{ !error?.isUnique ? 'Appeal for name' : 'Proceed' }} | |||||
| </button> | </button> | ||||
| </ng-container> | </ng-container> | ||||
| <section class="confirmation-box" *ngIf="formState === 'CONFIRM_INIT'"> | <section class="confirmation-box" *ngIf="formState === 'CONFIRM_INIT'"> | ||||
| <h5> {{ nameToCheck }} </h5> | <h5> {{ nameToCheck }} </h5> | ||||
| <p class="description"> | <p class="description"> | ||||
| <input type="checkbox"> | |||||
| Lorem, ipsum dolor sit amet consectetur adipisicing elit. At accusamus harum non dolores qui quaerat itaque architecto tenetur maiores dolor! Dolor aspernatur nemo autem et iusto deserunt officiis consectetur laboriosam! | |||||
| <input type="checkbox" [(ngModel)]="agreeToReserve"> | |||||
| I agree that I am reserving a name for my business entity, and am legally authorized to do so according to both national and local laws. I understand that the government will look through my financial records and will consent to the same. | |||||
| </p> | </p> | ||||
| <div class="form-action-buttons"> | <div class="form-action-buttons"> | ||||
| <button (click)="formState = 'INIT_REGISTER'"> | <button (click)="formState = 'INIT_REGISTER'"> | ||||
| Cancel | |||||
| Back | |||||
| </button> | </button> | ||||
| <button (click)="formState = 'REGISTER_FORM'"> | |||||
| <button [disabled]="!agreeToReserve" [ngClass]="{'disabled': !agreeToReserve}" (click)="formState = 'REGISTER_FORM'"> | |||||
| Proceed | Proceed | ||||
| </button> | </button> | ||||
| </div> | </div> | ||||
| @@ -81,30 +81,32 @@ | |||||
| </ng-container> | </ng-container> | ||||
| <div class="plan-list-container" *ngIf="formState === 'SELECT_PLAN'"> | <div class="plan-list-container" *ngIf="formState === 'SELECT_PLAN'"> | ||||
| <ng-container *ngIf="!selectedPlan"> | |||||
| <h5> | |||||
| Your business name application for <br> <strong> {{ nameToCheck }} </strong> is successfully approved! | |||||
| </h5> | |||||
| <ul class="plan-list"> | |||||
| <li *ngFor="let plan of plans"> | |||||
| <h4> {{ plan.name }} </h4> | |||||
| <h2> ₹ {{ plan.amount }}/- <span> (govt fees + taxes extra) </span> </h2> | |||||
| <h4> {{ plan.range }} </h4> | |||||
| <button (click)="selectedPlan = plan"> Pay </button> | |||||
| </li> | |||||
| </ul> | |||||
| </ng-container> | |||||
| <h5> | |||||
| Your business name application for <br> <strong> {{ nameToCheck }} </strong> is successfully approved! | |||||
| </h5> | |||||
| <ul class="plan-list"> | |||||
| <li *ngFor="let plan of plans"> | |||||
| <h4> {{ plan.name }} </h4> | |||||
| <h2> S$ {{ plan.amount }}/- <span> (govt fees + taxes extra) </span> </h2> | |||||
| <h4> {{ plan.range }} </h4> | |||||
| <button (click)="selectPlan(plan)"> Pay </button> | |||||
| </li> | |||||
| </ul> | |||||
| <div class="form-action-buttons"> | |||||
| <button (click)="goBackToFormDetails()"> | |||||
| Back | |||||
| </button> | |||||
| </div> | |||||
| </div> | |||||
| <div class="plan-list-container" *ngIf="formState === 'COMPLETE_PURCHASE'"> | |||||
| <section class="confirmation-box" *ngIf="selectedPlan"> | <section class="confirmation-box" *ngIf="selectedPlan"> | ||||
| <h6> Successfully made payment </h6> | <h6> Successfully made payment </h6> | ||||
| <p class="description"> | <p class="description"> | ||||
| Lorem, ipsum dolor sit amet consectetur adipisicing elit. At accusamus harum non dolores qui quaerat itaque architecto tenetur maiores dolor! Dolor aspernatur nemo autem et iusto deserunt officiis consectetur laboriosam! | |||||
| {{ isAppealing ? | |||||
| 'Please stand by while the Authority Officer contacts you with the results of your appeal' : | |||||
| 'Congratulations! Your name has been reserved for ' + selectedPlan.range + ' time. Please proceed with further setup of your business entity' }} | |||||
| </p> | </p> | ||||
| <div class="form-action-buttons"> | |||||
| <button (click)="formState = 'REGISTER_FORM'" class="highlight"> | |||||
| Next | |||||
| </button> | |||||
| </div> | |||||
| </section> | </section> | ||||
| </div> | </div> | ||||
| @@ -155,6 +155,10 @@ header { | |||||
| height: 5rem; | height: 5rem; | ||||
| vertical-align: middle; | vertical-align: middle; | ||||
| &.disabled { | |||||
| cursor: not-allowed; | |||||
| opacity: 0.5; | |||||
| } | |||||
| &:first-child { | &:first-child { | ||||
| background-color: var(--border-grey); | background-color: var(--border-grey); | ||||
| @@ -240,6 +244,7 @@ header { | |||||
| align-items: flex-start; | align-items: flex-start; | ||||
| justify-content: center; | justify-content: center; | ||||
| list-style: none; | list-style: none; | ||||
| margin-bottom: 30px; | |||||
| li { | li { | ||||
| border: 1px solid var(--border-grey); | border: 1px solid var(--border-grey); | ||||
| @@ -1,23 +1,28 @@ | |||||
| import { Component, OnInit } from '@angular/core'; | import { Component, OnInit } from '@angular/core'; | ||||
| interface Plan { | |||||
| name: string, | |||||
| amount: number, | |||||
| range: string, | |||||
| } | |||||
| @Component({ | @Component({ | ||||
| selector: 'app-register-business', | selector: 'app-register-business', | ||||
| templateUrl: './register-business.component.html', | templateUrl: './register-business.component.html', | ||||
| styleUrls: ['./register-business.component.scss'] | styleUrls: ['./register-business.component.scss'] | ||||
| }) | }) | ||||
| export class RegisterBusinessComponent implements OnInit { | export class RegisterBusinessComponent implements OnInit { | ||||
| formState: 'CHECK_NAME' | 'INIT_REGISTER' | 'CONFIRM_INIT' | 'REGISTER_FORM' | 'SELECT_PLAN' | undefined = 'CHECK_NAME'; | |||||
| nameToCheck: string = 'JK Enterprises'; | |||||
| error: { | |||||
| formState: 'CHECK_NAME' | 'INIT_REGISTER' | 'CONFIRM_INIT' | 'REGISTER_FORM' | 'SELECT_PLAN' | 'COMPLETE_PURCHASE' | undefined = 'SELECT_PLAN'; | |||||
| nameToCheck: string = 'JK Enterprises ACRA Ltd'; | |||||
| isAppealing: boolean = false; | |||||
| agreeToReserve: boolean = false; | |||||
| error?: { | |||||
| message: string, | message: string, | ||||
| isError: boolean, | |||||
| } | undefined; | |||||
| isUnique: boolean, | |||||
| isInvalid: boolean, | |||||
| } | |||||
| plans: Array<{ | |||||
| name: string, | |||||
| amount: number, | |||||
| range: string, | |||||
| }> = [{ | |||||
| plans: Array<Plan> = [{ | |||||
| name: 'Basic', | name: 'Basic', | ||||
| amount: 2000, | amount: 2000, | ||||
| range: 'One Year' | range: 'One Year' | ||||
| @@ -37,6 +42,9 @@ export class RegisterBusinessComponent implements OnInit { | |||||
| range: string, | range: string, | ||||
| } | undefined; | } | undefined; | ||||
| paymentChild: Window | null = null; | |||||
| childCheck: number | undefined; | |||||
| registerForm: Array<{ | registerForm: Array<{ | ||||
| name: string, | name: string, | ||||
| type: 'date' | 'select' | 'text' | 'email' | 'number', | type: 'date' | 'select' | 'text' | 'email' | 'number', | ||||
| @@ -72,7 +80,7 @@ export class RegisterBusinessComponent implements OnInit { | |||||
| }, { | }, { | ||||
| name: 'Capita Investment', | name: 'Capita Investment', | ||||
| type: 'number', | type: 'number', | ||||
| placeholder: 'Enter here in Rupees' | |||||
| placeholder: 'Enter here in Singapore Dollar' | |||||
| }]; | }]; | ||||
| constructor() { } | constructor() { } | ||||
| @@ -80,17 +88,59 @@ export class RegisterBusinessComponent implements OnInit { | |||||
| ngOnInit(): void { | ngOnInit(): void { | ||||
| } | } | ||||
| confirmName() { | |||||
| if (!this.error?.isUnique) { | |||||
| this.isAppealing = true; | |||||
| } | |||||
| this.formState = 'CONFIRM_INIT'; | |||||
| } | |||||
| goBackToFormDetails() { | |||||
| if (typeof this.childCheck !== 'undefined') { | |||||
| window.clearInterval(this.childCheck); | |||||
| this.childCheck = undefined; | |||||
| } | |||||
| if (this.paymentChild && !this.paymentChild.closed) { | |||||
| this.paymentChild?.close() | |||||
| } | |||||
| this.formState = 'REGISTER_FORM' | |||||
| } | |||||
| selectPlan(plan: Plan) { | |||||
| this.selectedPlan = plan; | |||||
| this.paymentChild = window.open('/mock', '_blank', 'toolbar=0,status=0,width=626,height=436'); | |||||
| this.childCheck = window.setInterval(() => { | |||||
| if (this.paymentChild && this.paymentChild.closed) { | |||||
| this.formState = 'COMPLETE_PURCHASE'; | |||||
| window.clearInterval(this.childCheck); | |||||
| this.childCheck = undefined; | |||||
| } | |||||
| }, 1000); | |||||
| } | |||||
| checkName() { | checkName() { | ||||
| if (this.nameToCheck === 'JK Enterprises') { | |||||
| this.formState = 'INIT_REGISTER'; | |||||
| if (!this.nameToCheck.endsWith('Ltd')) { | |||||
| this.error = { | |||||
| message: 'The name should end with the Ltd suffix', | |||||
| isUnique: false, | |||||
| isInvalid: true, | |||||
| }; | |||||
| } else if (this.nameToCheck === 'JK Enterprises Ltd') { | |||||
| this.error = { | this.error = { | ||||
| message: 'JK Enterprises is unavailable', | |||||
| isError: true | |||||
| message: this.nameToCheck + ' is unavailable', | |||||
| isUnique: false, | |||||
| isInvalid: false, | |||||
| }; | }; | ||||
| } else { | } else { | ||||
| this.formState = 'INIT_REGISTER'; | |||||
| this.error = { | this.error = { | ||||
| message: this.nameToCheck + ' is available', | message: this.nameToCheck + ' is available', | ||||
| isError: false | |||||
| isUnique: true, | |||||
| isInvalid: false | |||||
| }; | }; | ||||
| } | } | ||||
| } | } | ||||