1414 * limitations under the License.
1515 */
1616
17- import { Component , EventEmitter , Output } from "@angular/core" ;
17+ import { Component , EventEmitter , Output , OnInit } from "@angular/core" ;
1818import { CommonModule } from "@angular/common" ;
19- import { injectForm , TanStackField } from "@tanstack/angular-form" ;
19+ import { injectForm , TanStackField , TanStackAppField } from "@tanstack/angular-form" ;
2020import { injectSignInAuthFormSchema , injectTranslation , injectUI } from "../../../provider" ;
21- import { ButtonComponent } from "../../../components/button/button.component" ;
2221import { TermsAndPrivacyComponent } from "../../../components/terms-and-privacy/terms-and-privacy.component" ;
2322import { FirebaseUIError , signInWithEmailAndPassword } from "@firebase-ui/core" ;
2423
24+ import {
25+ FormInputComponent ,
26+ FormSubmitComponent ,
27+ FormErrorMessageComponent ,
28+ } from "../../../components/form/form.component" ;
29+ import { UserCredential } from "firebase/auth" ;
30+
2531@Component ( {
2632 selector : "fui-sign-in-auth-form" ,
2733 standalone : true ,
28- imports : [ CommonModule , TanStackField , ButtonComponent , TermsAndPrivacyComponent ] ,
34+ imports : [
35+ CommonModule ,
36+ TanStackField ,
37+ TanStackAppField ,
38+ TermsAndPrivacyComponent ,
39+ FormInputComponent ,
40+ FormSubmitComponent ,
41+ FormErrorMessageComponent ,
42+ ] ,
2943 template : `
3044 <form (submit)="handleSubmit($event)" class="fui-form">
3145 <fieldset>
32- <ng-container [tanstackField]="form" name="email" #email="field">
33- <label [for]="email.api.name">
34- <span>{{ emailLabel | async }}</span>
35- <input
36- type="email"
37- [id]="email.api.name"
38- [name]="email.api.name"
39- [value]="email.api.state.value"
40- (blur)="email.api.handleBlur()"
41- (input)="email.api.handleChange($any($event).target.value)"
42- [attr.aria-invalid]="!!email.api.state.meta.errors.length"
43- />
44- <span role="alert" aria-live="polite" class="fui-form__error" *ngIf="!!email.api.state.meta.errors.length">
45- {{ email.api.state.meta.errors.join(", ") }}
46- </span>
47- </label>
48- </ng-container>
46+ <fui-form-input
47+ name="email"
48+ tanstack-app-field
49+ [tanstackField]="form"
50+ label="Email Label TODO"
51+ ></fui-form-input>
4952 </fieldset>
5053 <fieldset>
51- <ng-container [tanstackField]="form" name="password" #password="field">
52- <label [for]="password.api.name">
53- <span class="flex">
54- <span class="flex-grow">{{ passwordLabel() }}</span>
55- @if(forgotPassword) {
56- <button type="button" (click)="forgotPassword.emit()" class="fui-form__action">
57- {{ forgotPasswordLabel() }}
58- </button>
59- }
60- </span>
61- <input
62- type="password"
63- [id]="password.api.name"
64- [name]="password.api.name"
65- [value]="password.api.state.value"
66- (blur)="password.api.handleBlur()"
67- (input)="password.api.handleChange($any($event).target.value)"
68- [attr.aria-invalid]="!!password.api.state.meta.errors.length"
69- />
70- <span
71- role="alert"
72- aria-live="polite"
73- class="fui-form__error"
74- *ngIf="!!password.api.state.meta.errors.length"
75- >
76- {{ password.api.state.meta.errors.join(", ") }}
77- </span>
78- </label>
79- </ng-container>
54+ <fui-form-input name="password" tanstack-app-field [tanstackField]="form" label="Password Label TODO">
55+ @if (forgotPassword) {
56+ <button fui-form-action (click)="forgotPassword.emit()">
57+ {{ forgotPasswordLabel() }}
58+ </button>
59+ }
60+ </fui-form-input>
8061 </fieldset>
8162
8263 <fui-terms-and-privacy></fui-terms-and-privacy>
8364
8465 <fieldset>
85- <button fui-button type=" submit" >
66+ <fui-form- submit>
8667 {{ signInLabel() }}
87- </button >
88- <div class=" fui-form__error" *ngIf="formError">{{ formError }}</div >
68+ </fui-form-submit >
69+ <fui-form-error-message></fui-form-error-message >
8970 </fieldset>
9071
91- @if(register) {
92- <div class="flex justify-center items-center">
93- <button type="button" (click)="register.emit()" class="fui-form__action">
94- {{ noAccountLabel() }} {{ registerLabel() }}
95- </button>
96- </div>
72+ @if (register) {
73+ <button fui-form-action (click)="register.emit()">{{ noAccountLabel() }} {{ registerLabel() }}</button>
9774 }
9875 </form>
9976 ` ,
10077} )
101- export class SignInAuthFormComponent {
78+ export class SignInAuthFormComponent implements OnInit {
10279 private ui = injectUI ( ) ;
10380 private formSchema = injectSignInAuthFormSchema ( ) ;
10481
@@ -112,6 +89,7 @@ export class SignInAuthFormComponent {
11289
11390 @Output ( ) forgotPassword = new EventEmitter < void > ( ) ;
11491 @Output ( ) register = new EventEmitter < void > ( ) ;
92+ @Output ( ) signIn ?: EventEmitter < UserCredential > ;
11593
11694 formError : string | null = null ;
11795
@@ -120,59 +98,32 @@ export class SignInAuthFormComponent {
12098 email : "" ,
12199 password : "" ,
122100 } ,
123- validators : {
124- onBlur : this . formSchema ( ) ,
125- onSubmit : this . formSchema ( ) ,
126- } ,
127- } ) as any ; // TODO(ehesp): Fix this - types go too deep
128-
129- async handleSubmit ( event : SubmitEvent ) {
130- event . preventDefault ( ) ;
131- event . stopPropagation ( ) ;
132-
133- const email = this . form . state . values . email ;
134- const password = this . form . state . values . password ;
101+ } ) ;
135102
136- if ( ! email || ! password ) {
137- return ;
138- }
139-
140- await this . validateAndSignIn ( email , password ) ;
103+ handleSubmit ( event : SubmitEvent ) {
104+ event . preventDefault ( )
105+ event . stopPropagation ( )
106+ this . form . handleSubmit ( )
141107 }
142108
143- async validateAndSignIn ( email : string , password : string ) {
144- try {
145- const validationResult = this . formSchema ( ) . safeParse ( {
146- email,
147- password,
148- } ) ;
149-
150- if ( ! validationResult . success ) {
151- const validationErrors = validationResult . error . format ( ) ;
152-
153- if ( validationErrors . email ?. _errors ?. length ) {
154- this . formError = validationErrors . email . _errors [ 0 ] ;
155- return ;
156- }
157-
158- if ( validationErrors . password ?. _errors ?. length ) {
159- this . formError = validationErrors . password . _errors [ 0 ] ;
160- return ;
161- }
162-
163- this . formError = this . unknownErrorLabel ( ) ;
164- return ;
165- }
166-
167- this . formError = null ;
168- await signInWithEmailAndPassword ( this . ui ( ) , email , password ) ;
169- } catch ( error ) {
170- if ( error instanceof FirebaseUIError ) {
171- this . formError = error . message ;
172- return ;
173- }
174-
175- this . formError = this . unknownErrorLabel ( ) ;
176- }
109+ ngOnInit ( ) {
110+ this . form . update ( {
111+ validators : {
112+ onBlur : this . formSchema ( ) ,
113+ onSubmit : this . formSchema ( ) ,
114+ onSubmitAsync : async ( { value } ) => {
115+ try {
116+ const credential = await signInWithEmailAndPassword ( this . ui ( ) , value . email , value . password ) ;
117+ this . signIn ?. emit ( credential ) ;
118+ } catch ( error ) {
119+ if ( error instanceof FirebaseUIError ) {
120+ return error . message ;
121+ }
122+
123+ return this . unknownErrorLabel ( ) ;
124+ }
125+ } ,
126+ } ,
127+ } ) ;
177128 }
178129}
0 commit comments