Poorly designed starting point component: almost done!
This commit is contained in:
parent
171377d0b5
commit
d13bfbbd25
9 changed files with 115 additions and 65 deletions
29
package-lock.json
generated
29
package-lock.json
generated
|
@ -15,8 +15,6 @@
|
|||
"@angular/platform-browser": "^20.0.0",
|
||||
"@angular/router": "^20.0.0",
|
||||
"@ngrx/signals": "^19.2.1",
|
||||
"@ngrx/store": "^19.2.1",
|
||||
"@ngrx/store-devtools": "^19.2.1",
|
||||
"rxjs": "~7.8.0",
|
||||
"tslib": "^2.3.0"
|
||||
},
|
||||
|
@ -2246,33 +2244,6 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@ngrx/store": {
|
||||
"version": "19.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@ngrx/store/-/store-19.2.1.tgz",
|
||||
"integrity": "sha512-c5vQId7YoAhM0y4HASrz9mtLju+28vJspd6OBlhPbBlSae8GN8m9S/oav+8LaSY19yh95cZ5B/nMcLNNWgL/jA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"tslib": "^2.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@angular/core": "^19.0.0",
|
||||
"rxjs": "^6.5.3 || ^7.5.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@ngrx/store-devtools": {
|
||||
"version": "19.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@ngrx/store-devtools/-/store-devtools-19.2.1.tgz",
|
||||
"integrity": "sha512-gj1YO+4yl6D0l9vzLWdw07TQSu5UPKgsSLsNJfDLXraaLCUcB8voAp4J7zohN8qR5ixDuHeMoiSSVuklQ75u2w==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"tslib": "^2.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@angular/core": "^19.0.0",
|
||||
"@ngrx/store": "19.2.1",
|
||||
"rxjs": "^6.5.3 || ^7.5.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@npmcli/agent": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@npmcli/agent/-/agent-3.0.0.tgz",
|
||||
|
|
|
@ -16,8 +16,6 @@
|
|||
"@angular/platform-browser": "^20.0.0",
|
||||
"@angular/router": "^20.0.0",
|
||||
"@ngrx/signals": "^19.2.1",
|
||||
"@ngrx/store": "^19.2.1",
|
||||
"@ngrx/store-devtools": "^19.2.1",
|
||||
"rxjs": "~7.8.0",
|
||||
"tslib": "^2.3.0"
|
||||
},
|
||||
|
|
|
@ -1,21 +1,5 @@
|
|||
import {
|
||||
ApplicationConfig,
|
||||
isDevMode,
|
||||
provideBrowserGlobalErrorListeners,
|
||||
provideZonelessChangeDetection,
|
||||
} from '@angular/core';
|
||||
import { provideStoreDevtools } from '@ngrx/store-devtools';
|
||||
import { ApplicationConfig, provideBrowserGlobalErrorListeners, provideZonelessChangeDetection } from '@angular/core';
|
||||
|
||||
export const appConfig: ApplicationConfig = {
|
||||
providers: [
|
||||
provideBrowserGlobalErrorListeners(),
|
||||
provideZonelessChangeDetection(),
|
||||
provideStoreDevtools({
|
||||
maxAge: 25,
|
||||
logOnly: !isDevMode(),
|
||||
autoPause: true,
|
||||
trace: false,
|
||||
traceLimit: 75,
|
||||
}),
|
||||
],
|
||||
providers: [provideBrowserGlobalErrorListeners(), provideZonelessChangeDetection()],
|
||||
};
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
<main>
|
||||
@switch (currentView()) {
|
||||
@case ('startingPoint') {
|
||||
<app-starting-point></app-starting-point>
|
||||
}
|
||||
@default {
|
||||
<app-starting-point></app-starting-point>
|
||||
}
|
||||
|
|
|
@ -1,15 +1,24 @@
|
|||
import { patchState, signalStore, withMethods, withState } from '@ngrx/signals';
|
||||
import { patchState, signalStore, watchState, withHooks, withMethods, withState } from '@ngrx/signals';
|
||||
import { AfterHighSchool, Gender } from './views/starting-point/starting-point.state';
|
||||
|
||||
export type AppState = {
|
||||
currentView: CurrentView;
|
||||
name: string;
|
||||
gender: Gender;
|
||||
afterHighSchool: AfterHighSchool;
|
||||
};
|
||||
|
||||
export enum CurrentView {
|
||||
StartingPoint = 'startingPoint',
|
||||
CollegeSelection = 'collegeSelection',
|
||||
FirstJobHighSchoolDiploma = 'firstJobHighSchoolDiploma',
|
||||
}
|
||||
|
||||
const initialState: AppState = {
|
||||
currentView: CurrentView.StartingPoint,
|
||||
name: '',
|
||||
gender: Gender.Undefined,
|
||||
afterHighSchool: AfterHighSchool.Undefined,
|
||||
};
|
||||
|
||||
export const AppStateStore = signalStore(
|
||||
|
@ -17,9 +26,31 @@ export const AppStateStore = signalStore(
|
|||
withState(initialState),
|
||||
withMethods(store => ({
|
||||
updateCurrentView: (currentView: CurrentView) =>
|
||||
patchState(store, () => ({
|
||||
...store,
|
||||
patchState(store, state => ({
|
||||
...state,
|
||||
currentView,
|
||||
})),
|
||||
}))
|
||||
updateStartingPointState: ({
|
||||
name,
|
||||
gender,
|
||||
afterHighSchool,
|
||||
}: {
|
||||
name: string;
|
||||
gender: Gender;
|
||||
afterHighSchool: AfterHighSchool;
|
||||
}) =>
|
||||
patchState(store, state => ({
|
||||
...state,
|
||||
name,
|
||||
gender,
|
||||
afterHighSchool,
|
||||
})),
|
||||
})),
|
||||
withHooks({
|
||||
onInit: store => {
|
||||
watchState(store, ({ currentView }) => {
|
||||
console.log(`Current View: ${currentView}`);
|
||||
});
|
||||
},
|
||||
})
|
||||
);
|
||||
|
|
|
@ -1,7 +1,25 @@
|
|||
<h1>
|
||||
Hello {{ name() }}
|
||||
</h1>
|
||||
<form [formGroup]="form">
|
||||
<label for="name">Your Name: </label>
|
||||
<input id="name" type="text" formControlName="name">
|
||||
<form [formGroup]="form" (submit)="onSubmit()">
|
||||
<div class="name">
|
||||
<label for="name">Your Name: </label>
|
||||
<input id="name" type="text" formControlName="name">
|
||||
</div>
|
||||
<div class="gender">
|
||||
<label for="gender">Your Gender:</label>
|
||||
<select id="gender" formControlName="gender">
|
||||
<option value="">--Please select a gender--</option>
|
||||
@for (option of genders(); track $index) {
|
||||
<option value="{{ option.value }}">{{ option.desc }}</option>
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
<div class="after-high-school">
|
||||
<label for="after-high-school">What You're Doing After Graduation:</label>
|
||||
<select id="after-high-school" formControlName="afterHighSchool">
|
||||
<option value="">--Please select an option--</option>
|
||||
@for (option of afterHighSchoolOptions(); track $index) {
|
||||
<option value="{{ option.value }}">{{ option.desc }}</option>
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
<button type="submit">Next</button>
|
||||
</form>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import { patchState, signalStore, withMethods, withState } from '@ngrx/signals';
|
||||
import { effect } from '@angular/core';
|
||||
import { getState, patchState, signalStore, watchState, withHooks, withMethods, withState } from '@ngrx/signals';
|
||||
|
||||
export type StartingPointState = {
|
||||
name: string;
|
||||
|
@ -33,5 +34,12 @@ export const StartingPointStateStore = signalStore(
|
|||
gender: gender ?? Gender.Undefined,
|
||||
afterHighSchool: afterHighSchool ?? AfterHighSchool.Undefined,
|
||||
})),
|
||||
}))
|
||||
})),
|
||||
withHooks({
|
||||
onInit: store => {
|
||||
watchState(store, state => {
|
||||
console.log(state);
|
||||
});
|
||||
},
|
||||
})
|
||||
);
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
import { ChangeDetectionStrategy, Component, computed, inject, OnInit, Signal } from '@angular/core';
|
||||
import { ChangeDetectionStrategy, Component, effect, inject, OnInit, signal } from '@angular/core';
|
||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
import { FormBuilder, ReactiveFormsModule, Validators } from '@angular/forms';
|
||||
import { StartingPointState, StartingPointStateStore } from './starting-point.state';
|
||||
import { AppStateStore, CurrentView } from '../../app.state';
|
||||
import { getState } from '@ngrx/signals';
|
||||
|
||||
export interface StartingPointForm {
|
||||
name: string;
|
||||
|
@ -30,6 +32,7 @@ export enum AfterHighSchool {
|
|||
providers: [StartingPointStateStore],
|
||||
})
|
||||
export class StartingPoint implements OnInit {
|
||||
private readonly globalState = inject(AppStateStore);
|
||||
private readonly state = inject(StartingPointStateStore);
|
||||
readonly name = this.state.name;
|
||||
|
||||
|
@ -40,6 +43,28 @@ export class StartingPoint implements OnInit {
|
|||
afterHighSchool: [AfterHighSchool.Undefined, Validators.required],
|
||||
});
|
||||
|
||||
readonly genders = signal<Array<{ desc: string; value: Gender }>>([
|
||||
{
|
||||
desc: 'Female',
|
||||
value: Gender.Female,
|
||||
},
|
||||
{
|
||||
desc: 'Male',
|
||||
value: Gender.Male,
|
||||
},
|
||||
]).asReadonly();
|
||||
|
||||
readonly afterHighSchoolOptions = signal<Array<{ desc: string; value: AfterHighSchool }>>([
|
||||
{
|
||||
desc: 'Go to College',
|
||||
value: AfterHighSchool.College,
|
||||
},
|
||||
{
|
||||
desc: 'Enter the Workforce',
|
||||
value: AfterHighSchool.Workforce,
|
||||
},
|
||||
]).asReadonly();
|
||||
|
||||
constructor() {
|
||||
this.form.valueChanges
|
||||
.pipe(takeUntilDestroyed())
|
||||
|
@ -49,4 +74,19 @@ export class StartingPoint implements OnInit {
|
|||
}
|
||||
|
||||
ngOnInit(): void {}
|
||||
|
||||
onSubmit() {
|
||||
const startingPointState = getState(this.state);
|
||||
this.globalState.updateStartingPointState(startingPointState);
|
||||
|
||||
switch (startingPointState.afterHighSchool) {
|
||||
case AfterHighSchool.College:
|
||||
this.globalState.updateCurrentView(CurrentView.CollegeSelection);
|
||||
break;
|
||||
|
||||
case AfterHighSchool.Workforce:
|
||||
this.globalState.updateCurrentView(CurrentView.FirstJobHighSchoolDiploma);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,9 +26,6 @@
|
|||
"references": [
|
||||
{
|
||||
"path": "./tsconfig.app.json"
|
||||
},
|
||||
{
|
||||
"path": "./tsconfig.spec.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue