diff --git a/src/app/features/checkout/address/address.ts b/src/app/features/checkout/address/address.ts
index ed76393..56404fd 100644
--- a/src/app/features/checkout/address/address.ts
+++ b/src/app/features/checkout/address/address.ts
@@ -1,9 +1,16 @@
-import { Component, inject, OnInit } from "@angular/core";
+import { Component, inject, OnInit, signal } from "@angular/core";
import { AddressForm } from "../components/address-form/address-form";
import { GoBack } from "@app/shared/components/go-back/go-back";
import { AddressSelect } from "../components/address-select/address-select";
import { OrderSummery } from "../components/order-summery/order-summery";
-import { AddressService } from "@app/features/checkout/services/address-service";
+import {
+ AddressRequest,
+ AddressResponse,
+ AddressService,
+} from "@app/features/checkout/services/address-service";
+import { AuthService } from "@core/services/auth-service";
+import { User } from "@core/models/user.model";
+import { switchMap } from "rxjs";
@Component({
selector: "app-address",
@@ -13,6 +20,41 @@ import { AddressService } from "@app/features/checkout/services/address-service"
})
export class Address implements OnInit {
addressService = inject(AddressService);
+ authService = inject(AuthService);
+ private user: User | undefined;
+ protected addresses = signal
([]);
- ngOnInit() {}
+ ngOnInit(): void {
+ this.authService
+ .getCurrentUser()
+ .pipe(
+ switchMap((user) => {
+ this.user = user;
+ if (user?.id) {
+ return this.addressService.fetchAddresses(user.id);
+ }
+ return [];
+ }),
+ )
+ .subscribe({
+ next: (addresses) => {
+ this.addresses.set(addresses.data);
+ },
+ });
+ }
+
+ createNewAddress(addressData: AddressRequest) {
+ this.addressService.createAddress(this.user!.id, addressData).subscribe({
+ next: (address) => this.addresses.update((addresses) => [...addresses, address]),
+ });
+ }
+ updateAddress(addressData: AddressResponse) {
+ console.log(addressData);
+ this.addressService.updateAddress(addressData.id, addressData).subscribe({
+ next: (address) =>
+ this.addresses.update((addresses) =>
+ addresses.map((a) => (a.id === address.id ? address : a)),
+ ),
+ });
+ }
}
diff --git a/src/app/features/checkout/components/address-form/address-form.html b/src/app/features/checkout/components/address-form/address-form.html
index d5a240f..6ac7da9 100644
--- a/src/app/features/checkout/components/address-form/address-form.html
+++ b/src/app/features/checkout/components/address-form/address-form.html
@@ -1,8 +1,14 @@
-
-
-
+
+
+
-
diff --git a/src/app/features/checkout/components/address-form/address-form.ts b/src/app/features/checkout/components/address-form/address-form.ts
index 12e9728..0250074 100644
--- a/src/app/features/checkout/components/address-form/address-form.ts
+++ b/src/app/features/checkout/components/address-form/address-form.ts
@@ -1,6 +1,7 @@
-import { Component } from "@angular/core";
+import { Component, EventEmitter, Input, Output, signal } from "@angular/core";
import { FormControl, FormGroup, ReactiveFormsModule, Validators } from "@angular/forms";
import { Error } from "@app/shared/components/error/error";
+import { AddressRequest, AddressResponse } from "@app/features/checkout/services/address-service";
@Component({
selector: "app-address-form",
@@ -9,12 +10,55 @@ import { Error } from "@app/shared/components/error/error";
styleUrl: "./address-form.css",
})
export class AddressForm {
+ @Input() set initialData(address: AddressResponse) {
+ if (address) {
+ this.addressForm.patchValue(address);
+ this.address.set(address);
+ this.isEditing.set(true);
+ }
+ }
+ @Output() submitAddress: EventEmitter = new EventEmitter();
+ @Output() updateAddress: EventEmitter = new EventEmitter();
+ @Output() editingCanceled: EventEmitter = new EventEmitter();
+
+ protected isEditing = signal(false);
+ protected address = signal(null);
+
addressForm = new FormGroup({
- firstName: new FormControl("", { validators: Validators.required }),
- lastName: new FormControl("", { validators: Validators.required }),
- streetAddress: new FormControl("", { validators: Validators.required }),
+ firstName: new FormControl("", {
+ validators: [Validators.required, Validators.pattern("^[a-zA-Z]\\S+$")],
+ }),
+ lastName: new FormControl("", {
+ validators: [Validators.required, Validators.pattern("^[a-zA-Z]\\S+$")],
+ }),
+ street: new FormControl("", { validators: Validators.required }),
city: new FormControl("", { validators: Validators.required }),
state: new FormControl("", { validators: Validators.required }),
- pinCode: new FormControl("", { validators: Validators.required }),
+ pinCode: new FormControl("", {
+ validators: [Validators.required, Validators.pattern("^[0-9]{6}$")],
+ }),
});
+
+ submitForm() {
+ if (this.addressForm.invalid) {
+ this.addressForm.markAllAsTouched();
+ return;
+ }
+
+ const emittedData = this.addressForm.getRawValue() as AddressRequest;
+ this.addressForm.reset();
+
+ if (this.isEditing()) {
+ const mergedData = { ...this.address(), ...emittedData };
+ console.log(mergedData);
+ this.updateAddress.emit(mergedData as unknown as AddressResponse);
+ } else {
+ this.submitAddress.emit(emittedData);
+ }
+ }
+
+ cancelEditing() {
+ this.addressForm.reset();
+ this.editingCanceled.emit();
+ }
}
diff --git a/src/app/features/checkout/components/address-select/address-select.html b/src/app/features/checkout/components/address-select/address-select.html
index 1fb2a0e..da89163 100644
--- a/src/app/features/checkout/components/address-select/address-select.html
+++ b/src/app/features/checkout/components/address-select/address-select.html
@@ -1,10 +1,20 @@
+@if (!isEditing()) {
-
Kushal Saha
-
48 St, Park Avenue, New Towm, 700021
+
{{[address.firstName, address.lastName] | fullname}}
+
+ {{`${address.street}, ${address.city}, ${address.pinCode}`}}
+
-
+
+} @else{
+
+}
diff --git a/src/app/features/checkout/components/address-select/address-select.ts b/src/app/features/checkout/components/address-select/address-select.ts
index 18a7490..64cc7ea 100644
--- a/src/app/features/checkout/components/address-select/address-select.ts
+++ b/src/app/features/checkout/components/address-select/address-select.ts
@@ -1,9 +1,30 @@
-import { Component } from "@angular/core";
+import { Component, EventEmitter, Input, Output, signal } from "@angular/core";
+import { AddressResponse } from "@app/features/checkout/services/address-service";
+import { FullnamePipe } from "@shared/pipes/fullname-pipe";
+import { AddressForm } from "@app/features/checkout/components/address-form/address-form";
@Component({
selector: "app-address-select",
- imports: [],
+ imports: [FullnamePipe, AddressForm],
templateUrl: "./address-select.html",
styleUrl: "./address-select.css",
})
-export class AddressSelect {}
+export class AddressSelect {
+ @Input() address!: AddressResponse;
+ @Output() addressUpdated: EventEmitter = new EventEmitter();
+
+ protected isEditing = signal(false);
+
+ editForm() {
+ this.isEditing.set(true);
+ }
+
+ cancelEditing() {
+ this.isEditing.set(false);
+ }
+
+ updateAddress(address: AddressResponse) {
+ this.isEditing.set(false);
+ this.addressUpdated.emit(address);
+ }
+}
diff --git a/src/app/features/checkout/services/address-service.ts b/src/app/features/checkout/services/address-service.ts
index 4aacac9..db6001e 100644
--- a/src/app/features/checkout/services/address-service.ts
+++ b/src/app/features/checkout/services/address-service.ts
@@ -1,6 +1,20 @@
import { inject, Injectable } from "@angular/core";
import { HttpClient } from "@angular/common/http";
import { API_URL } from "@core/tokens/api-url-tokens";
+import { PaginatedResponse } from "@core/models/paginated.model";
+
+export interface AddressRequest {
+ firstName: string;
+ lastName: string;
+ street: string;
+ city: string;
+ state: string;
+ pinCode: string;
+}
+
+export interface AddressResponse extends AddressRequest {
+ id: number;
+}
@Injectable({
providedIn: "root",
@@ -10,6 +24,20 @@ export class AddressService {
apiUrl = inject(API_URL);
fetchAddresses(userId: number) {
- return this.http.get(`${this.apiUrl}/user/${userId}/addresses`);
+ return this.http.get>(
+ `${this.apiUrl}/user/${userId}/addresses`,
+ );
+ }
+
+ createAddress(userId: number, data: AddressRequest) {
+ return this.http.post(`${this.apiUrl}/user/${userId}/addresses`, data);
+ }
+ updateAddress(addressId: number, data: AddressRequest) {
+ return this.http.patch(`${this.apiUrl}/addresses/${addressId}`, data);
+ }
+ deleteAddress(userId: number, addressId: number) {
+ return this.http.delete(
+ `${this.apiUrl}/user/${userId}/addresses/${addressId}`,
+ );
}
}
diff --git a/src/app/shared/pipes/fullname-pipe.spec.ts b/src/app/shared/pipes/fullname-pipe.spec.ts
new file mode 100644
index 0000000..8032c7e
--- /dev/null
+++ b/src/app/shared/pipes/fullname-pipe.spec.ts
@@ -0,0 +1,8 @@
+import { FullnamePipe } from "./fullname-pipe";
+
+describe("FullnamePipe", () => {
+ it("create an instance", () => {
+ const pipe = new FullnamePipe();
+ expect(pipe).toBeTruthy();
+ });
+});
diff --git a/src/app/shared/pipes/fullname-pipe.ts b/src/app/shared/pipes/fullname-pipe.ts
new file mode 100644
index 0000000..ff153bd
--- /dev/null
+++ b/src/app/shared/pipes/fullname-pipe.ts
@@ -0,0 +1,13 @@
+import { Pipe, PipeTransform } from "@angular/core";
+import { TitleCasePipe } from "@angular/common";
+
+@Pipe({
+ name: "fullname",
+})
+export class FullnamePipe implements PipeTransform {
+ titlecase = new TitleCasePipe();
+
+ transform(values: string[]): unknown {
+ return this.titlecase.transform(values.join(" "));
+ }
+}