shipping and payment updates
This commit is contained in:
parent
5185cb375d
commit
d1bc0eb45a
@ -36,33 +36,11 @@
|
|||||||
</app-travel-plan>
|
</app-travel-plan>
|
||||||
</mat-step>
|
</mat-step>
|
||||||
|
|
||||||
<!-- Insurance Step -->
|
<!-- Shipping & Payment Step -->
|
||||||
<mat-step *ngIf="applicationType === 'new' || applicationType === 'extend' || applicationType === 'additional'"
|
|
||||||
[completed]="stepsCompleted.insurance" [editable]="stepsCompleted.applicationDetail">
|
|
||||||
<ng-template matStepLabel>Insurance</ng-template>
|
|
||||||
<app-insurance (completed)="onInsuranceSaved($event)" [headerid]="headerid">
|
|
||||||
</app-insurance>
|
|
||||||
</mat-step>
|
|
||||||
|
|
||||||
<!-- Shipping Step -->
|
|
||||||
<mat-step [completed]="stepsCompleted.shipping" [editable]="stepsCompleted.applicationDetail">
|
<mat-step [completed]="stepsCompleted.shipping" [editable]="stepsCompleted.applicationDetail">
|
||||||
<ng-template matStepLabel>Shipping</ng-template>
|
<ng-template matStepLabel>Shipping & Payment</ng-template>
|
||||||
<app-shipping (completed)="onShippingSaved($event)" [headerid]="headerid">
|
<app-shipping (completed)="onShippingSaved($event)" [headerid]="headerid">
|
||||||
</app-shipping>
|
</app-shipping>
|
||||||
</mat-step>
|
</mat-step>
|
||||||
|
|
||||||
<!-- Delivery Method Step -->
|
|
||||||
<mat-step [completed]="stepsCompleted.deliveryMethod" [editable]="stepsCompleted.applicationDetail">
|
|
||||||
<ng-template matStepLabel>Delivery Method</ng-template>
|
|
||||||
<app-delivery (completed)="onDeliveryMethodSaved($event)" [headerid]="headerid">
|
|
||||||
</app-delivery>
|
|
||||||
</mat-step>
|
|
||||||
|
|
||||||
<!-- Payment Step -->
|
|
||||||
<mat-step [completed]="stepsCompleted.payment" [editable]="stepsCompleted.applicationDetail">
|
|
||||||
<ng-template matStepLabel>Payment</ng-template>
|
|
||||||
<app-payment (completed)="onPaymentSaved($event)" [headerid]="headerid">
|
|
||||||
</app-payment>
|
|
||||||
</mat-step>
|
|
||||||
</mat-stepper>
|
</mat-stepper>
|
||||||
</div>
|
</div>
|
||||||
@ -7,18 +7,15 @@ import { ApplicationComponent } from "../application/application.component";
|
|||||||
import { HolderComponent } from '../holder/holder.component';
|
import { HolderComponent } from '../holder/holder.component';
|
||||||
import { GoodsComponent } from '../goods/goods.component';
|
import { GoodsComponent } from '../goods/goods.component';
|
||||||
import { TravelPlanComponent } from '../travel-plan/travel-plan.component';
|
import { TravelPlanComponent } from '../travel-plan/travel-plan.component';
|
||||||
import { InsuranceComponent } from '../insurance/insurance.component';
|
|
||||||
import { PaymentComponent } from '../payment/payment.component';
|
|
||||||
import { ShippingComponent } from '../shipping/shipping.component';
|
import { ShippingComponent } from '../shipping/shipping.component';
|
||||||
import { DeliveryComponent } from '../delivery/delivery.component';
|
|
||||||
import { UserPreferencesService } from '../../core/services/user-preference.service';
|
import { UserPreferencesService } from '../../core/services/user-preference.service';
|
||||||
import { UserPreferences } from '../../core/models/user-preference';
|
import { UserPreferences } from '../../core/models/user-preference';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-add-carnet',
|
selector: 'app-add-carnet',
|
||||||
imports: [AngularMaterialModule, CommonModule, ReactiveFormsModule,
|
imports: [AngularMaterialModule, CommonModule, ReactiveFormsModule,
|
||||||
ApplicationComponent, HolderComponent, GoodsComponent, TravelPlanComponent, InsuranceComponent,
|
ApplicationComponent, HolderComponent, GoodsComponent, TravelPlanComponent,
|
||||||
ShippingComponent, DeliveryComponent, PaymentComponent],
|
ShippingComponent],
|
||||||
templateUrl: './add-carnet.component.html',
|
templateUrl: './add-carnet.component.html',
|
||||||
styleUrl: './add-carnet.component.scss'
|
styleUrl: './add-carnet.component.scss'
|
||||||
})
|
})
|
||||||
@ -36,10 +33,7 @@ export class AddCarnetComponent {
|
|||||||
holderSelection: false,
|
holderSelection: false,
|
||||||
goodsSection: false,
|
goodsSection: false,
|
||||||
travelPlan: false,
|
travelPlan: false,
|
||||||
insurance: false,
|
shipping: false
|
||||||
shipping: false,
|
|
||||||
deliveryMethod: false,
|
|
||||||
payment: false
|
|
||||||
};
|
};
|
||||||
|
|
||||||
constructor(userPrefenceService: UserPreferencesService) {
|
constructor(userPrefenceService: UserPreferencesService) {
|
||||||
@ -51,7 +45,7 @@ export class AddCarnetComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onApplicationDetailCreated(headerid: number): void {
|
onApplicationDetailCreated(headerid: number): void {
|
||||||
this.headerid = this.headerid;
|
this.headerid = headerid;
|
||||||
this.stepsCompleted.applicationDetail = true;
|
this.stepsCompleted.applicationDetail = true;
|
||||||
this.isLinear = false; // Disable linear mode after application detail is created
|
this.isLinear = false; // Disable linear mode after application detail is created
|
||||||
}
|
}
|
||||||
@ -68,19 +62,7 @@ export class AddCarnetComponent {
|
|||||||
this.stepsCompleted.travelPlan = completed;
|
this.stepsCompleted.travelPlan = completed;
|
||||||
}
|
}
|
||||||
|
|
||||||
onInsuranceSaved(completed: boolean): void {
|
|
||||||
this.stepsCompleted.insurance = completed;
|
|
||||||
}
|
|
||||||
|
|
||||||
onShippingSaved(completed: boolean): void {
|
onShippingSaved(completed: boolean): void {
|
||||||
this.stepsCompleted.shipping = completed;
|
this.stepsCompleted.shipping = completed;
|
||||||
}
|
}
|
||||||
|
|
||||||
onDeliveryMethodSaved(completed: boolean): void {
|
|
||||||
this.stepsCompleted.deliveryMethod = completed;
|
|
||||||
}
|
|
||||||
|
|
||||||
onPaymentSaved(completed: boolean): void {
|
|
||||||
this.stepsCompleted.payment = completed;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -102,7 +102,7 @@ export class ApplicationComponent {
|
|||||||
this.applicationDetailService.createApplicationDetails(applicationDetailData).subscribe({
|
this.applicationDetailService.createApplicationDetails(applicationDetailData).subscribe({
|
||||||
next: (applicationData: any) => {
|
next: (applicationData: any) => {
|
||||||
this.notificationService.showSuccess(`Application details added successfully`);
|
this.notificationService.showSuccess(`Application details added successfully`);
|
||||||
this.headerIdCreated.emit(applicationData.HEADERID);
|
this.headerIdCreated.emit(+applicationData.HEADERID);
|
||||||
this.applicationDetailsForm.get('name')?.disable();
|
this.applicationDetailsForm.get('name')?.disable();
|
||||||
this.disableSaveButton = true;
|
this.disableSaveButton = true;
|
||||||
this.isLoading = false;
|
this.isLoading = false;
|
||||||
|
|||||||
@ -1,13 +0,0 @@
|
|||||||
import { Component, EventEmitter, Input, Output } from '@angular/core';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-delivery',
|
|
||||||
imports: [],
|
|
||||||
templateUrl: './delivery.component.html',
|
|
||||||
styleUrl: './delivery.component.scss'
|
|
||||||
})
|
|
||||||
export class DeliveryComponent {
|
|
||||||
@Input() headerid: number = 0;
|
|
||||||
@Output() completed = new EventEmitter<boolean>();
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -23,7 +23,7 @@
|
|||||||
<mat-step *ngIf="applicationType === 'new'" [completed]="stepsCompleted.goodsSection"
|
<mat-step *ngIf="applicationType === 'new'" [completed]="stepsCompleted.goodsSection"
|
||||||
[editable]="stepsCompleted.applicationDetail">
|
[editable]="stepsCompleted.applicationDetail">
|
||||||
<ng-template matStepLabel>Goods Section</ng-template>
|
<ng-template matStepLabel>Goods Section</ng-template>
|
||||||
<app-goods (completed)="onGoodsSectionSaved($event)" [headerid]="headerid"
|
<app-goods (completed)="onGoodsSectionSaved($event)" [headerid]="headerid" [isEditMode]="isEditMode"
|
||||||
[userPreferences]="userPreferences">
|
[userPreferences]="userPreferences">
|
||||||
</app-goods>
|
</app-goods>
|
||||||
</mat-step>
|
</mat-step>
|
||||||
@ -36,33 +36,11 @@
|
|||||||
</app-travel-plan>
|
</app-travel-plan>
|
||||||
</mat-step>
|
</mat-step>
|
||||||
|
|
||||||
<!-- Insurance Step -->
|
<!-- Shipping & Payment Step -->
|
||||||
<mat-step *ngIf="applicationType === 'new' || applicationType === 'extend' || applicationType === 'additional'"
|
|
||||||
[completed]="stepsCompleted.insurance" [editable]="stepsCompleted.applicationDetail">
|
|
||||||
<ng-template matStepLabel>Insurance</ng-template>
|
|
||||||
<app-insurance (completed)="onInsuranceSaved($event)" [headerid]="headerid">
|
|
||||||
</app-insurance>
|
|
||||||
</mat-step>
|
|
||||||
|
|
||||||
<!-- Shipping Step -->
|
|
||||||
<mat-step [completed]="stepsCompleted.shipping" [editable]="stepsCompleted.applicationDetail">
|
<mat-step [completed]="stepsCompleted.shipping" [editable]="stepsCompleted.applicationDetail">
|
||||||
<ng-template matStepLabel>Shipping</ng-template>
|
<ng-template matStepLabel>Shipping & Payment</ng-template>
|
||||||
<app-shipping (completed)="onShippingSaved($event)" [headerid]="headerid">
|
<app-shipping (completed)="onShippingSaved($event)" [headerid]="headerid">
|
||||||
</app-shipping>
|
</app-shipping>
|
||||||
</mat-step>
|
</mat-step>
|
||||||
|
|
||||||
<!-- Delivery Method Step -->
|
|
||||||
<mat-step [completed]="stepsCompleted.deliveryMethod" [editable]="stepsCompleted.applicationDetail">
|
|
||||||
<ng-template matStepLabel>Delivery Method</ng-template>
|
|
||||||
<app-delivery (completed)="onDeliveryMethodSaved($event)" [headerid]="headerid">
|
|
||||||
</app-delivery>
|
|
||||||
</mat-step>
|
|
||||||
|
|
||||||
<!-- Payment Step -->
|
|
||||||
<mat-step [completed]="stepsCompleted.payment" [editable]="stepsCompleted.applicationDetail">
|
|
||||||
<ng-template matStepLabel>Payment</ng-template>
|
|
||||||
<app-payment (completed)="onPaymentSaved($event)" [headerid]="headerid">
|
|
||||||
</app-payment>
|
|
||||||
</mat-step>
|
|
||||||
</mat-stepper>
|
</mat-stepper>
|
||||||
</div>
|
</div>
|
||||||
@ -7,9 +7,6 @@ import { StepperSelectionEvent } from '@angular/cdk/stepper';
|
|||||||
import { GoodsComponent } from '../goods/goods.component';
|
import { GoodsComponent } from '../goods/goods.component';
|
||||||
import { HolderComponent } from '../holder/holder.component';
|
import { HolderComponent } from '../holder/holder.component';
|
||||||
import { ActivatedRoute } from '@angular/router';
|
import { ActivatedRoute } from '@angular/router';
|
||||||
import { DeliveryComponent } from '../delivery/delivery.component';
|
|
||||||
import { InsuranceComponent } from '../insurance/insurance.component';
|
|
||||||
import { PaymentComponent } from '../payment/payment.component';
|
|
||||||
import { ShippingComponent } from '../shipping/shipping.component';
|
import { ShippingComponent } from '../shipping/shipping.component';
|
||||||
import { TravelPlanComponent } from '../travel-plan/travel-plan.component';
|
import { TravelPlanComponent } from '../travel-plan/travel-plan.component';
|
||||||
import { UserPreferences } from '../../core/models/user-preference';
|
import { UserPreferences } from '../../core/models/user-preference';
|
||||||
@ -18,8 +15,7 @@ import { UserPreferencesService } from '../../core/services/user-preference.serv
|
|||||||
@Component({
|
@Component({
|
||||||
selector: 'app-edit-carnet',
|
selector: 'app-edit-carnet',
|
||||||
imports: [AngularMaterialModule, CommonModule, ReactiveFormsModule,
|
imports: [AngularMaterialModule, CommonModule, ReactiveFormsModule,
|
||||||
ApplicationComponent, HolderComponent, GoodsComponent, TravelPlanComponent, InsuranceComponent,
|
ApplicationComponent, HolderComponent, GoodsComponent, TravelPlanComponent, ShippingComponent],
|
||||||
ShippingComponent, DeliveryComponent, PaymentComponent],
|
|
||||||
templateUrl: './edit-carnet.component.html',
|
templateUrl: './edit-carnet.component.html',
|
||||||
styleUrl: './edit-carnet.component.scss'
|
styleUrl: './edit-carnet.component.scss'
|
||||||
})
|
})
|
||||||
@ -37,10 +33,7 @@ export class EditCarnetComponent {
|
|||||||
holderSelection: false,
|
holderSelection: false,
|
||||||
goodsSection: false,
|
goodsSection: false,
|
||||||
travelPlan: false,
|
travelPlan: false,
|
||||||
insurance: false,
|
shipping: false
|
||||||
shipping: false,
|
|
||||||
deliveryMethod: false,
|
|
||||||
payment: false
|
|
||||||
};
|
};
|
||||||
|
|
||||||
private route = inject(ActivatedRoute);
|
private route = inject(ActivatedRoute);
|
||||||
@ -70,19 +63,7 @@ export class EditCarnetComponent {
|
|||||||
this.stepsCompleted.travelPlan = completed;
|
this.stepsCompleted.travelPlan = completed;
|
||||||
}
|
}
|
||||||
|
|
||||||
onInsuranceSaved(completed: boolean): void {
|
|
||||||
this.stepsCompleted.insurance = completed;
|
|
||||||
}
|
|
||||||
|
|
||||||
onShippingSaved(completed: boolean): void {
|
onShippingSaved(completed: boolean): void {
|
||||||
this.stepsCompleted.shipping = completed;
|
this.stepsCompleted.shipping = completed;
|
||||||
}
|
}
|
||||||
|
|
||||||
onDeliveryMethodSaved(completed: boolean): void {
|
|
||||||
this.stepsCompleted.deliveryMethod = completed;
|
|
||||||
}
|
|
||||||
|
|
||||||
onPaymentSaved(completed: boolean): void {
|
|
||||||
this.stepsCompleted.payment = completed;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -89,7 +89,7 @@
|
|||||||
<!-- Value Column -->
|
<!-- Value Column -->
|
||||||
<ng-container matColumnDef="value">
|
<ng-container matColumnDef="value">
|
||||||
<th mat-header-cell *matHeaderCellDef mat-sort-header>Value</th>
|
<th mat-header-cell *matHeaderCellDef mat-sort-header>Value</th>
|
||||||
<td mat-cell *matCellDef="let item">{{ formatDecimalDisplay(item.value, 2) }}</td>
|
<td mat-cell *matCellDef="let item">{{ formatDecimalDisplay(item.value, 2) | currency}}</td>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<!-- Country of Origin Column -->
|
<!-- Country of Origin Column -->
|
||||||
|
|||||||
@ -29,6 +29,7 @@ import { Goods, GoodsItem } from '../../core/models/carnet/goods';
|
|||||||
export class GoodsComponent {
|
export class GoodsComponent {
|
||||||
@Input() headerid: number = 0;
|
@Input() headerid: number = 0;
|
||||||
@Input() userPreferences: UserPreferences = {};
|
@Input() userPreferences: UserPreferences = {};
|
||||||
|
@Input() isEditMode: boolean = false;
|
||||||
@Output() completed = new EventEmitter<boolean>();
|
@Output() completed = new EventEmitter<boolean>();
|
||||||
|
|
||||||
@ViewChild(MatPaginator) paginator!: MatPaginator;
|
@ViewChild(MatPaginator) paginator!: MatPaginator;
|
||||||
@ -85,10 +86,6 @@ export class GoodsComponent {
|
|||||||
value: [0, [Validators.required, Validators.min(1), Validators.pattern(/^\d+(\.\d{1,2})?$/)]],
|
value: [0, [Validators.required, Validators.min(1), Validators.pattern(/^\d+(\.\d{1,2})?$/)]],
|
||||||
countryOfOrigin: ['', Validators.required]
|
countryOfOrigin: ['', Validators.required]
|
||||||
});
|
});
|
||||||
|
|
||||||
this.goodsForm.valueChanges.subscribe(() => {
|
|
||||||
this.completed.emit(this.goodsForm.valid && this.dataSource.data.length > 0);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ngAfterViewInit() {
|
ngAfterViewInit() {
|
||||||
@ -117,6 +114,7 @@ export class GoodsComponent {
|
|||||||
});
|
});
|
||||||
|
|
||||||
this.loadGoodsItems();
|
this.loadGoodsItems();
|
||||||
|
this.completed.emit(this.goodsForm.valid && this.dataSource.data.length > 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -314,10 +312,10 @@ export class GoodsComponent {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
items.map(item => {
|
// items.map(item => {
|
||||||
item.countryOfOrigin = this.getCountryValue(item.countryOfOrigin);
|
// item.countryOfOrigin = this.getCountryValue(item.countryOfOrigin);
|
||||||
item.unitOfMeasure = this.getUnitOfMeasureValue(item.unitOfMeasure);
|
// item.unitOfMeasure = this.getUnitOfMeasureValue(item.unitOfMeasure);
|
||||||
});
|
// });
|
||||||
|
|
||||||
this.goodsService.addGoodsItem(this.headerid, items).subscribe({
|
this.goodsService.addGoodsItem(this.headerid, items).subscribe({
|
||||||
next: () => {
|
next: () => {
|
||||||
@ -395,7 +393,7 @@ export class GoodsComponent {
|
|||||||
this.goodsService.saveGoodsData(this.headerid, formData).subscribe({
|
this.goodsService.saveGoodsData(this.headerid, formData).subscribe({
|
||||||
next: () => {
|
next: () => {
|
||||||
this.notificationService.showSuccess('Goods information saved successfully');
|
this.notificationService.showSuccess('Goods information saved successfully');
|
||||||
this.completed.emit(true);
|
this.completed.emit(this.goodsForm.valid && this.dataSource.data.length > 0);
|
||||||
},
|
},
|
||||||
error: (error) => {
|
error: (error) => {
|
||||||
let errorMessage = this.errorHandler.handleApiError(error, 'Failed to save goods information');
|
let errorMessage = this.errorHandler.handleApiError(error, 'Failed to save goods information');
|
||||||
|
|||||||
@ -1 +0,0 @@
|
|||||||
<p>insurance works!</p>
|
|
||||||
@ -1,12 +0,0 @@
|
|||||||
import { Component, EventEmitter, Input, Output } from '@angular/core';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-insurance',
|
|
||||||
imports: [],
|
|
||||||
templateUrl: './insurance.component.html',
|
|
||||||
styleUrl: './insurance.component.scss'
|
|
||||||
})
|
|
||||||
export class InsuranceComponent {
|
|
||||||
@Input() headerid: number = 0;
|
|
||||||
@Output() completed = new EventEmitter<boolean>();
|
|
||||||
}
|
|
||||||
@ -1 +0,0 @@
|
|||||||
<p>payment works!</p>
|
|
||||||
@ -1,12 +0,0 @@
|
|||||||
import { Component, EventEmitter, Input, Output } from '@angular/core';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-payment',
|
|
||||||
imports: [],
|
|
||||||
templateUrl: './payment.component.html',
|
|
||||||
styleUrl: './payment.component.scss'
|
|
||||||
})
|
|
||||||
export class PaymentComponent {
|
|
||||||
@Input() headerid: number = 0;
|
|
||||||
@Output() completed = new EventEmitter<boolean>();
|
|
||||||
}
|
|
||||||
@ -1 +1,302 @@
|
|||||||
<p>shipping works!</p>
|
<div class="shipping-container">
|
||||||
|
<form [formGroup]="shippingForm" (ngSubmit)="onSubmit()">
|
||||||
|
<!-- Insurance Section -->
|
||||||
|
<div class="section">
|
||||||
|
<h3>Insurance & Bond</h3>
|
||||||
|
<div class="checkbox-group">
|
||||||
|
<mat-checkbox labelPosition="before" formControlName="needsBond">Do you need Bond from
|
||||||
|
us?</mat-checkbox>
|
||||||
|
<mat-checkbox labelPosition="before" formControlName="needsInsurance">Do you need insurance for your
|
||||||
|
goods?</mat-checkbox>
|
||||||
|
<mat-checkbox labelPosition="before" formControlName="needsLostDocProtection">Do you need Lost document
|
||||||
|
protection?</mat-checkbox>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Shipping Section -->
|
||||||
|
<div class="section">
|
||||||
|
<h3>Ship To</h3>
|
||||||
|
<mat-radio-group formControlName="shipTo" class="radio-group" (change)="onShipToChange($event)">
|
||||||
|
<mat-radio-button value="preparer">Preparer</mat-radio-button>
|
||||||
|
<mat-radio-button value="holder">Holder</mat-radio-button>
|
||||||
|
<mat-radio-button value="thirdParty">3rd Party</mat-radio-button>
|
||||||
|
</mat-radio-group>
|
||||||
|
|
||||||
|
<mat-card appearance="outlined" *ngIf="!showAddressForm && !showContactForm">
|
||||||
|
<mat-card-content>
|
||||||
|
<p>{{getAddressLabel()}}</p>
|
||||||
|
</mat-card-content>
|
||||||
|
<mat-card-actions>
|
||||||
|
<button mat-button (click)="editAddressForm()">Edit</button>
|
||||||
|
</mat-card-actions>
|
||||||
|
</mat-card>
|
||||||
|
<div *ngIf="showAddressForm" class="address-form" formGroupName="address">
|
||||||
|
<h4>Shipping Address</h4>
|
||||||
|
|
||||||
|
<!-- Address Information -->
|
||||||
|
<div class="form-row">
|
||||||
|
<mat-form-field appearance="outline" class="address1">
|
||||||
|
<mat-label>Address Line 1</mat-label>
|
||||||
|
<input matInput formControlName="address1" required>
|
||||||
|
<mat-error *ngIf="shippingForm.get('address.address1')?.errors?.['required']">
|
||||||
|
Address is required
|
||||||
|
</mat-error>
|
||||||
|
<mat-error *ngIf="shippingForm.get('address.address1')?.errors?.['maxlength']">
|
||||||
|
Maximum 100 characters allowed
|
||||||
|
</mat-error>
|
||||||
|
</mat-form-field>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-row">
|
||||||
|
<mat-form-field appearance="outline" class="address2">
|
||||||
|
<mat-label>Address Line 2 (Optional)</mat-label>
|
||||||
|
<input matInput formControlName="address2">
|
||||||
|
<mat-error *ngIf="shippingForm.get('address.address2')?.errors?.['maxlength']">
|
||||||
|
Maximum 100 characters allowed
|
||||||
|
</mat-error>
|
||||||
|
</mat-form-field>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Location Information -->
|
||||||
|
<div class="form-row">
|
||||||
|
<mat-form-field appearance="outline" class="city">
|
||||||
|
<mat-label>City</mat-label>
|
||||||
|
<input matInput formControlName="city" required>
|
||||||
|
<mat-error *ngIf="shippingForm.get('address.city')?.errors?.['required']">
|
||||||
|
City is required
|
||||||
|
</mat-error>
|
||||||
|
<mat-error *ngIf="shippingForm.get('address.city')?.errors?.['maxlength']">
|
||||||
|
Maximum 50 characters allowed
|
||||||
|
</mat-error>
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
|
<mat-form-field appearance="outline" class="country">
|
||||||
|
<mat-label>Country</mat-label>
|
||||||
|
<mat-select formControlName="country" required
|
||||||
|
(selectionChange)="onCountryChange($event.value)">
|
||||||
|
<mat-option *ngFor="let country of countries" [value]="country.value">
|
||||||
|
{{ country.name }}
|
||||||
|
</mat-option>
|
||||||
|
</mat-select>
|
||||||
|
<mat-error *ngIf="shippingForm.get('address.country')?.errors?.['required']">
|
||||||
|
Country is required
|
||||||
|
</mat-error>
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
|
<mat-form-field appearance="outline" class="state">
|
||||||
|
<mat-label>State/Province</mat-label>
|
||||||
|
<mat-select formControlName="state" required>
|
||||||
|
<mat-option *ngFor="let state of states" [value]="state.value">
|
||||||
|
{{ state.name }}
|
||||||
|
</mat-option>
|
||||||
|
</mat-select>
|
||||||
|
<mat-error *ngIf="shippingForm.get('address.state')?.errors?.['required']">
|
||||||
|
State is required
|
||||||
|
</mat-error>
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
|
<mat-form-field appearance="outline" class="zip">
|
||||||
|
<mat-label>ZIP/Postal Code</mat-label>
|
||||||
|
<input matInput formControlName="zip" required>
|
||||||
|
<mat-error *ngIf="shippingForm.get('address.zip')?.errors?.['required']">
|
||||||
|
ZIP/Postal code is required
|
||||||
|
</mat-error>
|
||||||
|
<mat-error
|
||||||
|
*ngIf="shippingForm.get('address.country')?.value === 'US' && shippingForm.get('address.zip')?.touched && shippingForm.get('address.zip')?.errors?.['invalidUSZip']">
|
||||||
|
Please enter a valid 5-digit US ZIP code
|
||||||
|
</mat-error>
|
||||||
|
<mat-error
|
||||||
|
*ngIf="shippingForm.get('address.country')?.value === 'CA' && shippingForm.get('address.zip')?.touched && shippingForm.get('address.zip')?.errors?.['invalidCanadaPostal']">
|
||||||
|
Please enter a valid postal code (e.g., A1B2C3)
|
||||||
|
</mat-error>
|
||||||
|
</mat-form-field>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-actions" *ngIf="showAddressForm && shippingForm.get('shipTo')?.value !== 'thirdParty'">
|
||||||
|
<button mat-button type="button" (click)="cancelEditAddressForm()">Cancel</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div *ngIf="showContactForm" class="contact-form" formGroupName="contact">
|
||||||
|
<h4>Contact Information</h4>
|
||||||
|
<div class="form-row">
|
||||||
|
<mat-form-field appearance="outline">
|
||||||
|
<mat-label>First Name</mat-label>
|
||||||
|
<input matInput formControlName="firstName" required>
|
||||||
|
<mat-icon matSuffix>person</mat-icon>
|
||||||
|
<mat-error *ngIf="shippingForm.get('contact.firstName')?.errors?.['required']">
|
||||||
|
First name is required
|
||||||
|
</mat-error>
|
||||||
|
<mat-error *ngIf="shippingForm.get('contact.firstName')?.errors?.['maxlength']">
|
||||||
|
Maximum 50 characters allowed
|
||||||
|
</mat-error>
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
|
<mat-form-field appearance="outline" class="small-field">
|
||||||
|
<mat-label>Middle Initial</mat-label>
|
||||||
|
<input matInput formControlName="middleInitial" maxlength="1">
|
||||||
|
<mat-error *ngIf="shippingForm.get('contact.middleInitial')?.errors?.['maxlength']">
|
||||||
|
Only 1 character allowed
|
||||||
|
</mat-error>
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
|
<mat-form-field appearance="outline">
|
||||||
|
<mat-label>Last Name</mat-label>
|
||||||
|
<input matInput formControlName="lastName" required>
|
||||||
|
<mat-icon matSuffix>person</mat-icon>
|
||||||
|
<mat-error *ngIf="shippingForm.get('contact.lastName')?.errors?.['required']">
|
||||||
|
Last name is required
|
||||||
|
</mat-error>
|
||||||
|
<mat-error *ngIf="shippingForm.get('contact.lastName')?.errors?.['maxlength']">
|
||||||
|
Maximum 50 characters allowed
|
||||||
|
</mat-error>
|
||||||
|
</mat-form-field>
|
||||||
|
</div>
|
||||||
|
<div class="form-row">
|
||||||
|
<mat-form-field appearance="outline">
|
||||||
|
<mat-label>Title</mat-label>
|
||||||
|
<input matInput formControlName="title" required>
|
||||||
|
<mat-icon matSuffix>work</mat-icon>
|
||||||
|
<mat-error *ngIf="shippingForm.get('contact.title')?.errors?.['required']">
|
||||||
|
Title is required
|
||||||
|
</mat-error>
|
||||||
|
<mat-error *ngIf="shippingForm.get('contact.title')?.errors?.['maxlength']">
|
||||||
|
Maximum 100 characters allowed
|
||||||
|
</mat-error>
|
||||||
|
</mat-form-field>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-row">
|
||||||
|
<mat-form-field appearance="outline">
|
||||||
|
<mat-label>Phone</mat-label>
|
||||||
|
<input matInput formControlName="phone" required>
|
||||||
|
<mat-icon matSuffix>phone</mat-icon>
|
||||||
|
<mat-error *ngIf="shippingForm.get('contact.phone')?.errors?.['required']">
|
||||||
|
Phone is required
|
||||||
|
</mat-error>
|
||||||
|
<mat-error *ngIf="shippingForm.get('contact.phone')?.errors?.['pattern']">
|
||||||
|
Please enter a valid phone number (10-15 digits)
|
||||||
|
</mat-error>
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
|
<mat-form-field appearance="outline">
|
||||||
|
<mat-label>Mobile</mat-label>
|
||||||
|
<input matInput formControlName="mobile">
|
||||||
|
<mat-icon matSuffix>smartphone</mat-icon>
|
||||||
|
<mat-error *ngIf="shippingForm.get('contact.mobile')?.errors?.['required']">
|
||||||
|
Mobile is required
|
||||||
|
</mat-error>
|
||||||
|
<mat-error *ngIf="shippingForm.get('contact.mobile')?.errors?.['pattern']">
|
||||||
|
Please enter a valid mobile number (10-15 digits)
|
||||||
|
</mat-error>
|
||||||
|
</mat-form-field>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-row">
|
||||||
|
<mat-form-field appearance="outline">
|
||||||
|
<mat-label>Fax</mat-label>
|
||||||
|
<input matInput formControlName="fax">
|
||||||
|
<mat-icon matSuffix>fax</mat-icon>
|
||||||
|
<mat-error *ngIf="shippingForm.get('contact.fax')?.errors?.['pattern']">
|
||||||
|
Please enter a valid fax number (10-15 digits)
|
||||||
|
</mat-error>
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
|
<mat-form-field appearance="outline">
|
||||||
|
<mat-label>Email</mat-label>
|
||||||
|
<input matInput formControlName="email" required>
|
||||||
|
<mat-icon matSuffix>email</mat-icon>
|
||||||
|
<mat-error *ngIf="shippingForm.get('contact.email')?.errors?.['required']">
|
||||||
|
Email is required
|
||||||
|
</mat-error>
|
||||||
|
<mat-error *ngIf="shippingForm.get('contact.email')?.errors?.['email']">
|
||||||
|
Please enter a valid email address
|
||||||
|
</mat-error>
|
||||||
|
<mat-error *ngIf="shippingForm.get('contact.email')?.errors?.['maxlength']">
|
||||||
|
Maximum 100 characters allowed
|
||||||
|
</mat-error>
|
||||||
|
</mat-form-field>
|
||||||
|
</div>
|
||||||
|
<div class="form-row">
|
||||||
|
<mat-form-field appearance="outline" class="full-width">
|
||||||
|
<mat-label>Reference Number</mat-label>
|
||||||
|
<input matInput formControlName="refNumber">
|
||||||
|
</mat-form-field>
|
||||||
|
</div>
|
||||||
|
<div class="form-row">
|
||||||
|
<mat-form-field appearance="outline" class="full-width">
|
||||||
|
<mat-label>Notes</mat-label>
|
||||||
|
<textarea matInput formControlName="notes" rows="2"></textarea>
|
||||||
|
</mat-form-field>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Delivery Section -->
|
||||||
|
<div class="section">
|
||||||
|
<h3>Delivery Method</h3>
|
||||||
|
<div class="form-row">
|
||||||
|
<mat-form-field appearance="outline">
|
||||||
|
<mat-label>Delivery Type</mat-label>
|
||||||
|
<mat-select formControlName="deliveryType" required>
|
||||||
|
<mat-option *ngFor="let deliveryType of deliveryTypes" [value]="deliveryType.value">
|
||||||
|
{{ deliveryType.name }}
|
||||||
|
</mat-option>
|
||||||
|
</mat-select>
|
||||||
|
<mat-error *ngIf="shippingForm.get('deliveryType')?.errors?.['required']">
|
||||||
|
Delivery Type is required
|
||||||
|
</mat-error>
|
||||||
|
</mat-form-field>
|
||||||
|
<mat-form-field appearance="outline">
|
||||||
|
<mat-label>Delivery Method</mat-label>
|
||||||
|
<mat-select formControlName="deliveryMethod" required>
|
||||||
|
<mat-option *ngFor="let deliveryMethod of deliveryMethods" [value]="deliveryMethod.value">
|
||||||
|
{{ deliveryMethod.name }}
|
||||||
|
</mat-option>
|
||||||
|
</mat-select>
|
||||||
|
<mat-error *ngIf="shippingForm.get('deliveryMethod')?.errors?.['required']">
|
||||||
|
Delivery Method is required
|
||||||
|
</mat-error>
|
||||||
|
</mat-form-field>
|
||||||
|
</div>
|
||||||
|
<div *ngIf="shippingForm.get('deliveryMethod')?.value === 'customerCourier'" class="form-row">
|
||||||
|
<mat-form-field appearance="outline" class="full-width">
|
||||||
|
<mat-label>Courier Account Number</mat-label>
|
||||||
|
<input matInput formControlName="courierAccount">
|
||||||
|
<mat-error>Required when using customer courier</mat-error>
|
||||||
|
</mat-form-field>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Payment Section -->
|
||||||
|
<div class="section">
|
||||||
|
<h3>Payment Method</h3>
|
||||||
|
<div class="form-row">
|
||||||
|
<mat-form-field appearance="outline">
|
||||||
|
<mat-label>Payment Method</mat-label>
|
||||||
|
<mat-select formControlName="paymentMethod" required>
|
||||||
|
<mat-option *ngFor="let paymentType of paymentTypes" [value]="paymentType.value">
|
||||||
|
{{ paymentType.name }}
|
||||||
|
</mat-option>
|
||||||
|
</mat-select>
|
||||||
|
<mat-error *ngIf="shippingForm.get('paymentMethod')?.errors?.['required']">
|
||||||
|
Payment Method is required
|
||||||
|
</mat-error>
|
||||||
|
</mat-form-field>
|
||||||
|
</div>
|
||||||
|
<!-- <div class="form-row">
|
||||||
|
<mat-form-field appearance="outline" class="full-width">
|
||||||
|
<mat-label>Payment Notes</mat-label>
|
||||||
|
<textarea matInput formControlName="notes" rows="2"></textarea>
|
||||||
|
</mat-form-field>
|
||||||
|
</div> -->
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-actions">
|
||||||
|
<button mat-raised-button color="primary" type="submit" [disabled]="shippingForm.invalid || isLoading">
|
||||||
|
<span *ngIf="!isLoading">Save</span>
|
||||||
|
<mat-spinner *ngIf="isLoading" diameter="24"></mat-spinner>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
@ -0,0 +1,76 @@
|
|||||||
|
.shipping-container {
|
||||||
|
padding: 16px;
|
||||||
|
|
||||||
|
.section {
|
||||||
|
margin-bottom: 24px;
|
||||||
|
padding: 16px;
|
||||||
|
border: 1px solid #e0e0e0;
|
||||||
|
border-radius: 4px;
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
margin: 0px 0px 16px 0px;
|
||||||
|
color: var(--mat-sys-primary);
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
h4 {
|
||||||
|
margin: 16px 0 8px;
|
||||||
|
color: var(--mat-sys-primary);
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mat-mdc-card-content:first-child {
|
||||||
|
padding: 0 16px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.checkbox-group {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.radio-group {
|
||||||
|
display: flex;
|
||||||
|
gap: 16px;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-row {
|
||||||
|
display: flex;
|
||||||
|
gap: 16px;
|
||||||
|
|
||||||
|
mat-form-field {
|
||||||
|
flex: 1;
|
||||||
|
margin-bottom: 6px;
|
||||||
|
|
||||||
|
&.full-width {
|
||||||
|
flex: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.small-field {
|
||||||
|
max-width: 120px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-actions {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
gap: 16px;
|
||||||
|
margin-top: 16px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.shipping-container {
|
||||||
|
.form-row {
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 8px;
|
||||||
|
|
||||||
|
mat-form-field {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,12 +1,376 @@
|
|||||||
import { Component, EventEmitter, Input, Output } from '@angular/core';
|
import { CommonModule } from '@angular/common';
|
||||||
|
import { Component, EventEmitter, inject, Input, Output } from '@angular/core';
|
||||||
|
import { ReactiveFormsModule, FormBuilder, FormGroup, Validators } from '@angular/forms';
|
||||||
|
import { NotificationService } from '../../core/services/common/notification.service';
|
||||||
|
import { AngularMaterialModule } from '../../shared/module/angular-material.module';
|
||||||
|
import { ShippingService } from '../../core/services/carnet/shipping.service';
|
||||||
|
import { ApiErrorHandlerService } from '../../core/services/common/api-error-handler.service';
|
||||||
|
import { CommonService } from '../../core/services/common/common.service';
|
||||||
|
import { Shipping } from '../../core/models/carnet/shipping';
|
||||||
|
import { Country } from '../../core/models/country';
|
||||||
|
import { State } from '../../core/models/state';
|
||||||
|
import { ZipCodeValidator } from '../../shared/validators/zipcode-validator';
|
||||||
|
import { Subject, takeUntil } from 'rxjs';
|
||||||
|
import { DeliveryType } from '../../core/models/delivery-type';
|
||||||
|
import { DeliveryMethod } from '../../core/models/delivery-method';
|
||||||
|
import { PaymentType } from '../../core/models/payment-type';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-shipping',
|
selector: 'app-shipping',
|
||||||
imports: [],
|
imports: [AngularMaterialModule, CommonModule, ReactiveFormsModule],
|
||||||
templateUrl: './shipping.component.html',
|
templateUrl: './shipping.component.html',
|
||||||
styleUrl: './shipping.component.scss'
|
styleUrl: './shipping.component.scss'
|
||||||
})
|
})
|
||||||
export class ShippingComponent {
|
export class ShippingComponent {
|
||||||
@Input() headerid: number = 0;
|
@Input() headerid: number = 0;
|
||||||
|
@Input() isEditMode = false;
|
||||||
@Output() completed = new EventEmitter<boolean>();
|
@Output() completed = new EventEmitter<boolean>();
|
||||||
}
|
|
||||||
|
private fb = inject(FormBuilder);
|
||||||
|
private shippingService = inject(ShippingService);
|
||||||
|
private notificationService = inject(NotificationService);
|
||||||
|
private errorHandler = inject(ApiErrorHandlerService);
|
||||||
|
private commonService = inject(CommonService);
|
||||||
|
|
||||||
|
shippingForm: FormGroup;
|
||||||
|
isLoading = false;
|
||||||
|
showAddressForm = false;
|
||||||
|
showContactForm = false;
|
||||||
|
|
||||||
|
countriesHasStates = ['US', 'CA', 'MX'];
|
||||||
|
countries: Country[] = [];
|
||||||
|
states: State[] = [];
|
||||||
|
deliveryTypes: DeliveryType[] = [];
|
||||||
|
deliveryMethods: DeliveryMethod[] = [];
|
||||||
|
paymentTypes: PaymentType[] = [];
|
||||||
|
|
||||||
|
private destroy$ = new Subject<void>();
|
||||||
|
|
||||||
|
// preparer contact and address mock data
|
||||||
|
preparerContact = {
|
||||||
|
firstName: 'John',
|
||||||
|
lastName: 'Doe',
|
||||||
|
middleInitial: 'A',
|
||||||
|
title: 'Mr.',
|
||||||
|
phone: '1234567890',
|
||||||
|
mobile: '0987654321',
|
||||||
|
fax: '1234567890',
|
||||||
|
email: 'j@doe.com',
|
||||||
|
}
|
||||||
|
|
||||||
|
preparerAddress = {
|
||||||
|
address1: '123 Main St',
|
||||||
|
address2: 'Suite 100',
|
||||||
|
city: 'Anytown',
|
||||||
|
state: 'CA',
|
||||||
|
zip: '12345',
|
||||||
|
country: 'US'
|
||||||
|
};
|
||||||
|
|
||||||
|
holderAddress = {
|
||||||
|
address1: '456 Holder St',
|
||||||
|
address2: 'Apt 200',
|
||||||
|
city: 'Othertown',
|
||||||
|
state: 'NY',
|
||||||
|
zip: '67890',
|
||||||
|
country: 'US'
|
||||||
|
};
|
||||||
|
|
||||||
|
holderContact = {
|
||||||
|
firstName: 'Jane',
|
||||||
|
lastName: 'Smith',
|
||||||
|
middleInitial: 'B',
|
||||||
|
title: 'Ms.',
|
||||||
|
phone: '2345678901',
|
||||||
|
mobile: '1098765432',
|
||||||
|
fax: '2345678901',
|
||||||
|
email: 'jan@sm.cm'
|
||||||
|
};
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.shippingForm = this.fb.group({
|
||||||
|
needsBond: [false],
|
||||||
|
needsInsurance: [false],
|
||||||
|
needsLostDocProtection: [false],
|
||||||
|
shipTo: ['preparer', Validators.required],
|
||||||
|
address: this.fb.group({
|
||||||
|
address1: ['', [Validators.required, Validators.maxLength(100)]],
|
||||||
|
address2: ['', [Validators.maxLength(100)]],
|
||||||
|
city: ['', [Validators.required, Validators.maxLength(50)]],
|
||||||
|
state: ['', Validators.required],
|
||||||
|
country: ['', Validators.required],
|
||||||
|
zip: ['', [Validators.required, ZipCodeValidator('country')]],
|
||||||
|
}),
|
||||||
|
contact: this.fb.group({
|
||||||
|
firstName: ['', [Validators.required, Validators.maxLength(50)]],
|
||||||
|
lastName: ['', [Validators.required, Validators.maxLength(50)]],
|
||||||
|
middleInitial: ['', [Validators.maxLength(1)]],
|
||||||
|
title: ['', [Validators.required, Validators.maxLength(100)]],
|
||||||
|
phone: ['', [Validators.required, Validators.pattern(/^[0-9]{10,15}$/)]],
|
||||||
|
mobile: ['', [Validators.required, Validators.pattern(/^[0-9]{10,15}$/)]],
|
||||||
|
fax: ['', [Validators.pattern(/^[0-9]{10,15}$/)]],
|
||||||
|
email: ['', [Validators.required, Validators.email, Validators.maxLength(100)]],
|
||||||
|
refNumber: [''],
|
||||||
|
notes: ['']
|
||||||
|
}),
|
||||||
|
deliveryType: ['', Validators.required],
|
||||||
|
deliveryMethod: ['', Validators.required],
|
||||||
|
courierAccount: [''],
|
||||||
|
paymentMethod: ['', Validators.required],
|
||||||
|
notes: ['']
|
||||||
|
});
|
||||||
|
|
||||||
|
// Update form validation based on selections
|
||||||
|
// this.shippingForm.get('shipTo')?.valueChanges.subscribe(value => {
|
||||||
|
// this.updateShippingValidation(value);
|
||||||
|
// });
|
||||||
|
|
||||||
|
this.shippingForm.get('deliveryMethod')?.valueChanges.subscribe(value => {
|
||||||
|
const courierControl = this.shippingForm.get('courierAccount');
|
||||||
|
if (value === 'customerCourier') {
|
||||||
|
courierControl?.setValidators([Validators.required]);
|
||||||
|
} else {
|
||||||
|
courierControl?.clearValidators();
|
||||||
|
}
|
||||||
|
courierControl?.updateValueAndValidity();
|
||||||
|
});
|
||||||
|
|
||||||
|
this.shippingForm.valueChanges.subscribe(() => {
|
||||||
|
this.completed.emit(this.shippingForm.valid);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
this.loadCountries();
|
||||||
|
this.loadDeliveryTypes();
|
||||||
|
this.loadDeliveryMethods();
|
||||||
|
this.loadPaymentTypes();
|
||||||
|
|
||||||
|
if (this.headerid && this.isEditMode) {
|
||||||
|
this.loadShippingData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnDestroy(): void {
|
||||||
|
this.destroy$.next();
|
||||||
|
this.destroy$.complete();
|
||||||
|
}
|
||||||
|
|
||||||
|
onCountryChange(country: string): void {
|
||||||
|
this.shippingForm.get('address.state')?.reset();
|
||||||
|
|
||||||
|
if (country) {
|
||||||
|
this.loadStates(country);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.shippingForm.get('address.zip')?.updateValueAndValidity();
|
||||||
|
}
|
||||||
|
|
||||||
|
loadCountries(): void {
|
||||||
|
this.commonService.getCountries(0)
|
||||||
|
.pipe(takeUntil(this.destroy$))
|
||||||
|
.subscribe({
|
||||||
|
next: (countries) => {
|
||||||
|
this.countries = countries;
|
||||||
|
},
|
||||||
|
error: (error) => {
|
||||||
|
console.error('Failed to load countries', error);
|
||||||
|
this.isLoading = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
loadDeliveryTypes(): void {
|
||||||
|
this.commonService.getDeliveryTypes(0)
|
||||||
|
.pipe(takeUntil(this.destroy$))
|
||||||
|
.subscribe({
|
||||||
|
next: (deliveryTypes) => {
|
||||||
|
this.deliveryTypes = deliveryTypes;
|
||||||
|
},
|
||||||
|
error: (error) => {
|
||||||
|
console.error('Failed to load delivery types', error);
|
||||||
|
this.isLoading = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
loadDeliveryMethods(): void {
|
||||||
|
this.commonService.getDeliveryMethods(0)
|
||||||
|
.pipe(takeUntil(this.destroy$))
|
||||||
|
.subscribe({
|
||||||
|
next: (deliveryMethods) => {
|
||||||
|
this.deliveryMethods = deliveryMethods;
|
||||||
|
},
|
||||||
|
error: (error) => {
|
||||||
|
console.error('Failed to load delivery methods', error);
|
||||||
|
this.isLoading = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
loadPaymentTypes(): void {
|
||||||
|
this.commonService.getPaymentTypes(0)
|
||||||
|
.pipe(takeUntil(this.destroy$))
|
||||||
|
.subscribe({
|
||||||
|
next: (paymentTypes) => {
|
||||||
|
this.paymentTypes = paymentTypes;
|
||||||
|
},
|
||||||
|
error: (error) => {
|
||||||
|
console.error('Failed to load payment types', error);
|
||||||
|
this.isLoading = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
loadStates(country: string): void {
|
||||||
|
this.isLoading = true;
|
||||||
|
country = this.countriesHasStates.includes(country) ? country : 'FN';
|
||||||
|
this.commonService.getStates(country, 0)
|
||||||
|
.pipe(takeUntil(this.destroy$))
|
||||||
|
.subscribe({
|
||||||
|
next: (states) => {
|
||||||
|
this.states = states;
|
||||||
|
const stateControl = this.shippingForm.get('contact.state');
|
||||||
|
if (this.countriesHasStates.includes(country)) {
|
||||||
|
stateControl?.enable();
|
||||||
|
} else {
|
||||||
|
stateControl?.disable();
|
||||||
|
stateControl?.setValue('FN');
|
||||||
|
}
|
||||||
|
this.isLoading = false;
|
||||||
|
},
|
||||||
|
error: (error) => {
|
||||||
|
console.error('Failed to load states', error);
|
||||||
|
this.isLoading = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
loadShippingData(): void {
|
||||||
|
this.isLoading = true;
|
||||||
|
this.shippingService.getShippingData(this.headerid).subscribe({
|
||||||
|
next: (data: Shipping) => {
|
||||||
|
this.patchShippingData(data);
|
||||||
|
this.isLoading = false;
|
||||||
|
},
|
||||||
|
error: (error: any) => {
|
||||||
|
let errorMessage = this.errorHandler.handleApiError(error, 'Failed to load shipping and payments data');
|
||||||
|
this.notificationService.showError(errorMessage);
|
||||||
|
this.isLoading = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
patchShippingData(shipping: Shipping): void {
|
||||||
|
this.shippingForm.patchValue({
|
||||||
|
needsBond: shipping.needsBond,
|
||||||
|
needsInsurance: shipping.needsInsurance,
|
||||||
|
needsLostDocProtection: shipping.needsLostDocProtection,
|
||||||
|
shipTo: shipping.shipTo,
|
||||||
|
address: shipping.address,
|
||||||
|
contact: shipping.contact,
|
||||||
|
deliveryType: shipping.deliveryType,
|
||||||
|
deliveryMethod: shipping.deliveryMethod,
|
||||||
|
courierAccount: shipping.courierAccount,
|
||||||
|
paymentMethod: shipping.paymentMethod,
|
||||||
|
notes: shipping.notes
|
||||||
|
});
|
||||||
|
|
||||||
|
if (shipping.address?.country) {
|
||||||
|
this.loadStates(shipping.address?.country);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
updateShippingValidation(shipTo: string): void {
|
||||||
|
// const addressGroup = this.shippingForm.get('address') as FormGroup;
|
||||||
|
// const contactGroup = this.shippingForm.get('contact') as FormGroup;
|
||||||
|
|
||||||
|
// if (shipTo === 'thirdParty') {
|
||||||
|
// Object.keys(addressGroup.controls).forEach(key => {
|
||||||
|
// addressGroup.get(key)?.setValidators(Validators.required);
|
||||||
|
// });
|
||||||
|
// Object.keys(contactGroup.controls).forEach(key => {
|
||||||
|
// if (key !== 'middleInitial' && key !== 'fax' && key !== 'notes' && key !== 'refNumber') {
|
||||||
|
// contactGroup.get(key)?.setValidators(Validators.required);
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
// } else {
|
||||||
|
// Object.keys(addressGroup.controls).forEach(key => {
|
||||||
|
// addressGroup.get(key)?.clearValidators();
|
||||||
|
// });
|
||||||
|
// Object.keys(contactGroup.controls).forEach(key => {
|
||||||
|
// contactGroup.get(key)?.clearValidators();
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
|
||||||
|
// addressGroup.updateValueAndValidity();
|
||||||
|
// contactGroup.updateValueAndValidity();
|
||||||
|
}
|
||||||
|
|
||||||
|
onSubmit(): void {
|
||||||
|
if (this.shippingForm.invalid) {
|
||||||
|
this.shippingForm.markAllAsTouched();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.isLoading = true;
|
||||||
|
const shippingData = this.shippingForm.value;
|
||||||
|
|
||||||
|
this.shippingService.saveShippingDetails(this.headerid, shippingData).subscribe({
|
||||||
|
next: () => {
|
||||||
|
this.notificationService.showSuccess('Shipping & payments information saved successfully');
|
||||||
|
this.completed.emit(true);
|
||||||
|
this.isLoading = false;
|
||||||
|
},
|
||||||
|
error: (error) => {
|
||||||
|
let errorMessage = this.errorHandler.handleApiError(error, 'Failed to save shipping and payment information');
|
||||||
|
this.notificationService.showError(errorMessage);
|
||||||
|
this.isLoading = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
getAddressLabel(): string {
|
||||||
|
let shipTo = this.shippingForm.get('shipTo')?.value;
|
||||||
|
|
||||||
|
if (shipTo === 'preparer') {
|
||||||
|
return `${this.preparerContact.firstName} ${this.preparerContact.lastName}, ${this.preparerAddress.address1}, ${this.preparerAddress.city}, ${this.preparerAddress.state}, ${this.preparerAddress.zip}, ${this.preparerAddress.country}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shipTo === 'holder') {
|
||||||
|
return `${this.holderContact.firstName} ${this.holderContact.lastName}, ${this.holderAddress.address1}, ${this.holderAddress.city}, ${this.holderAddress.state}, ${this.holderAddress.zip}, ${this.holderAddress.country}`;
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
editAddressForm(): void {
|
||||||
|
this.showAddressForm = true;
|
||||||
|
let shipTo = this.shippingForm.get('shipTo')?.value;
|
||||||
|
|
||||||
|
if (shipTo === 'preparer') {
|
||||||
|
this.shippingForm.get('address')?.patchValue(this.preparerAddress);
|
||||||
|
this.loadStates(this.preparerAddress.country);
|
||||||
|
} else if (shipTo === 'holder') {
|
||||||
|
this.shippingForm.get('address')?.patchValue(this.holderAddress);
|
||||||
|
this.loadStates(this.preparerAddress.country);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cancelEditAddressForm(): void {
|
||||||
|
this.showAddressForm = false;
|
||||||
|
this.shippingForm.get('address')?.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
onShipToChange(event: any): void {
|
||||||
|
const shipTo = event.value;
|
||||||
|
this.showAddressForm = false;
|
||||||
|
this.showContactForm = false;
|
||||||
|
|
||||||
|
if (shipTo === 'thirdParty') {
|
||||||
|
this.shippingForm.get('contact')?.reset();
|
||||||
|
this.shippingForm.get('address')?.reset();
|
||||||
|
this.showAddressForm = true;
|
||||||
|
this.showContactForm = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,2 +0,0 @@
|
|||||||
export interface Delivery {
|
|
||||||
}
|
|
||||||
@ -1,2 +0,0 @@
|
|||||||
export interface Insurance {
|
|
||||||
}
|
|
||||||
@ -1,2 +0,0 @@
|
|||||||
export interface Payment {
|
|
||||||
}
|
|
||||||
8
src/app/core/models/carnet/shipping-address.ts
Normal file
8
src/app/core/models/carnet/shipping-address.ts
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
export interface ShippingAddress {
|
||||||
|
address1: string;
|
||||||
|
address2?: string | null;
|
||||||
|
city: string;
|
||||||
|
state: string;
|
||||||
|
country: string;
|
||||||
|
zip: string;
|
||||||
|
}
|
||||||
12
src/app/core/models/carnet/shipping-contact.ts
Normal file
12
src/app/core/models/carnet/shipping-contact.ts
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
export interface ShippingContact {
|
||||||
|
firstName: string;
|
||||||
|
lastName: string;
|
||||||
|
middleInitial?: string | null;
|
||||||
|
title: string;
|
||||||
|
phone: string;
|
||||||
|
mobile: string;
|
||||||
|
fax?: string | null;
|
||||||
|
email: string;
|
||||||
|
refNumber?: string | null;
|
||||||
|
notes?: string | null;
|
||||||
|
}
|
||||||
@ -1,2 +1,23 @@
|
|||||||
|
import { ShippingAddress } from "./shipping-address";
|
||||||
|
import { ShippingContact } from "./shipping-contact";
|
||||||
|
|
||||||
export interface Shipping {
|
export interface Shipping {
|
||||||
|
// Insurance details
|
||||||
|
needsBond: boolean;
|
||||||
|
needsInsurance: boolean;
|
||||||
|
needsLostDocProtection: boolean;
|
||||||
|
|
||||||
|
// Shipping details
|
||||||
|
shipTo: string;
|
||||||
|
address?: ShippingAddress;
|
||||||
|
contact?: ShippingContact;
|
||||||
|
|
||||||
|
// Delivery details
|
||||||
|
deliveryType: string;
|
||||||
|
deliveryMethod: string;
|
||||||
|
courierAccount?: string;
|
||||||
|
|
||||||
|
// Payment details
|
||||||
|
paymentMethod: string;
|
||||||
|
notes?: string;
|
||||||
}
|
}
|
||||||
|
|||||||
5
src/app/core/models/delivery-method.ts
Normal file
5
src/app/core/models/delivery-method.ts
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
export interface DeliveryMethod {
|
||||||
|
name: string;
|
||||||
|
id: string;
|
||||||
|
value: string;
|
||||||
|
}
|
||||||
5
src/app/core/models/payment-type.ts
Normal file
5
src/app/core/models/payment-type.ts
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
export interface PaymentType {
|
||||||
|
name: string;
|
||||||
|
id: string;
|
||||||
|
value: string;
|
||||||
|
}
|
||||||
@ -1,9 +0,0 @@
|
|||||||
import { Injectable } from '@angular/core';
|
|
||||||
|
|
||||||
@Injectable({
|
|
||||||
providedIn: 'root'
|
|
||||||
})
|
|
||||||
export class DeliveryService {
|
|
||||||
|
|
||||||
constructor() { }
|
|
||||||
}
|
|
||||||
@ -1,9 +0,0 @@
|
|||||||
import { Injectable } from '@angular/core';
|
|
||||||
|
|
||||||
@Injectable({
|
|
||||||
providedIn: 'root'
|
|
||||||
})
|
|
||||||
export class PaymentService {
|
|
||||||
|
|
||||||
constructor() { }
|
|
||||||
}
|
|
||||||
@ -1,9 +1,103 @@
|
|||||||
import { Injectable } from '@angular/core';
|
import { inject, Injectable } from '@angular/core';
|
||||||
|
import { environment } from '../../../../environments/environment';
|
||||||
|
import { HttpClient } from '@angular/common/http';
|
||||||
|
import { filter, map, Observable } from 'rxjs';
|
||||||
|
import { UserService } from '../common/user.service';
|
||||||
|
import { Shipping } from '../../models/carnet/shipping';
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root'
|
providedIn: 'root'
|
||||||
})
|
})
|
||||||
export class ShippingService {
|
export class ShippingService {
|
||||||
|
private apiUrl = environment.apiUrl;
|
||||||
|
private apiDb = environment.apiDb;
|
||||||
|
|
||||||
constructor() { }
|
private http = inject(HttpClient);
|
||||||
|
private userService = inject(UserService);
|
||||||
|
|
||||||
|
getShippingData(headerid: number): Shipping | any {
|
||||||
|
return this.http.get<any[]>(`${this.apiUrl}/${this.apiDb}/GetShipPaymentDetailstoEdit/${this.userService.getUserSpid()}/${this.userService.getUser()}/${headerid}`).pipe(
|
||||||
|
filter(response => response.length > 0),
|
||||||
|
map(response => this.mapToShippingData(response?.[0])));
|
||||||
|
}
|
||||||
|
|
||||||
|
private mapToShippingData(shippingDetails: any): Shipping {
|
||||||
|
|
||||||
|
let shippingData: Shipping = {
|
||||||
|
shipTo: shippingDetails.SHIPADDRTYPE,
|
||||||
|
deliveryType: shippingDetails.DELIVERYTYPE,
|
||||||
|
deliveryMethod: shippingDetails.DELIVERYMETHOD,
|
||||||
|
courierAccount: shippingDetails.CUSTCOURIERNO,
|
||||||
|
paymentMethod: shippingDetails.PAYMENTMETHOD,
|
||||||
|
|
||||||
|
notes: shippingDetails.NOTES,
|
||||||
|
needsBond: shippingDetails.INSPROTECTION === 'Y',
|
||||||
|
needsInsurance: shippingDetails.LDIPROTECTION === 'Y',
|
||||||
|
needsLostDocProtection: shippingDetails.LDIPROTECTION === 'Y'
|
||||||
|
};
|
||||||
|
|
||||||
|
if (shippingDetails.address) {
|
||||||
|
shippingData.address = {
|
||||||
|
address1: shippingDetails.ADDRESS1,
|
||||||
|
address2: shippingDetails.ADDRESS2,
|
||||||
|
city: shippingDetails.CITY,
|
||||||
|
state: shippingDetails.STATE,
|
||||||
|
zip: shippingDetails.ZIP,
|
||||||
|
country: shippingDetails.COUNTRY
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shippingDetails.contact) {
|
||||||
|
shippingData.contact = {
|
||||||
|
firstName: shippingDetails.FIRSTNAME,
|
||||||
|
lastName: shippingDetails.LASTNAME,
|
||||||
|
middleInitial: shippingDetails.MIDDLEINITIAL,
|
||||||
|
title: shippingDetails.TITLE,
|
||||||
|
phone: shippingDetails.PHONENO,
|
||||||
|
mobile: shippingDetails.MOBILENO,
|
||||||
|
fax: shippingDetails.FAXNO,
|
||||||
|
email: shippingDetails.EMAILADDRESS,
|
||||||
|
refNumber: shippingDetails.REFNO,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return shippingData;
|
||||||
|
}
|
||||||
|
|
||||||
|
saveShippingDetails(headerid: number, shippingData: Shipping): Observable<any> {
|
||||||
|
|
||||||
|
const shippingDetails = {
|
||||||
|
P_HEADERID: headerid,
|
||||||
|
P_SHIPTOTYPE: shippingData.shipTo,
|
||||||
|
P_DELIVERYTYPE: shippingData.deliveryType,
|
||||||
|
P_DELIVERYMETHOD: shippingData.deliveryMethod,
|
||||||
|
P_CUSTCOURIERNO: shippingData.courierAccount,
|
||||||
|
P_PAYMENTMETHOD: shippingData.paymentMethod,
|
||||||
|
P_NOTES: shippingData.notes,
|
||||||
|
|
||||||
|
P_FORMOFSECURITY: shippingData.needsBond ? 'Y' : 'N',
|
||||||
|
P_INSPROTECTION: shippingData.needsInsurance ? 'Y' : 'N',
|
||||||
|
P_LDIPROTECTION: shippingData.needsLostDocProtection ? 'Y' : 'N',
|
||||||
|
|
||||||
|
address1: shippingData.address?.address1 || '',
|
||||||
|
address2: shippingData.address?.address2 || null,
|
||||||
|
city: shippingData.address?.city || '',
|
||||||
|
state: shippingData.address?.state || '',
|
||||||
|
zip: shippingData.address?.zip || '',
|
||||||
|
country: shippingData.address?.country || '',
|
||||||
|
|
||||||
|
firstName: shippingData.contact?.firstName || '',
|
||||||
|
lastName: shippingData.contact?.lastName || '',
|
||||||
|
middleInitial: shippingData.contact?.middleInitial || null,
|
||||||
|
title: shippingData.contact?.title || '',
|
||||||
|
phone: shippingData.contact?.phone || '',
|
||||||
|
mobile: shippingData.contact?.mobile || '',
|
||||||
|
fax: shippingData.contact?.fax || null,
|
||||||
|
emailAddress: shippingData.contact?.email || '',
|
||||||
|
refNo: shippingData.contact?.refNumber || '',
|
||||||
|
P_USERID: this.userService.getUser()
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.http.patch(`${this.apiUrl}/${this.apiDb}/UpdateShippingDetails`, shippingDetails);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -13,6 +13,8 @@ import { CargoSurety } from '../../models/cargo-surety';
|
|||||||
import { CarnetStatus } from '../../models/carnet-status';
|
import { CarnetStatus } from '../../models/carnet-status';
|
||||||
import { Country } from '../../models/country';
|
import { Country } from '../../models/country';
|
||||||
import { UnitOfMeasure } from '../../models/unitofmeasure';
|
import { UnitOfMeasure } from '../../models/unitofmeasure';
|
||||||
|
import { DeliveryMethod } from '../../models/delivery-method';
|
||||||
|
import { PaymentType } from '../../models/payment-type';
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root'
|
providedIn: 'root'
|
||||||
@ -156,7 +158,30 @@ export class CommonService {
|
|||||||
name: item.PARAMDESC,
|
name: item.PARAMDESC,
|
||||||
id: item.PARAMID,
|
id: item.PARAMID,
|
||||||
value: item.PARAMVALUE,
|
value: item.PARAMVALUE,
|
||||||
color: item.ADDLPARAMVALUE1,
|
}))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
getDeliveryMethods(_spid: number = 0): Observable<DeliveryMethod[]> {
|
||||||
|
return this.http.get<any[]>(`${this.apiUrl}/${this.apiDb}/GetParamValues?P_PARAMTYPE=007&P_SPID=0`).pipe(
|
||||||
|
map((response) =>
|
||||||
|
response.map((item) => ({
|
||||||
|
name: item.PARAMDESC,
|
||||||
|
id: item.PARAMID,
|
||||||
|
value: item.PARAMVALUE,
|
||||||
|
}))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
getPaymentTypes(_spid: number = 0): Observable<PaymentType[]> {
|
||||||
|
return this.http.get<any[]>(`${this.apiUrl}/${this.apiDb}/GetParamValues?P_PARAMTYPE=008&P_SPID=0`).pipe(
|
||||||
|
map((response) =>
|
||||||
|
response.map((item) => ({
|
||||||
|
name: item.PARAMDESC,
|
||||||
|
id: item.PARAMID,
|
||||||
|
value: item.PARAMVALUE,
|
||||||
}))
|
}))
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|||||||
@ -11,7 +11,7 @@
|
|||||||
<div class="questions-section">
|
<div class="questions-section">
|
||||||
<div class="question-row">
|
<div class="question-row">
|
||||||
<mat-radio-group (change)="newCarnet($event)">
|
<mat-radio-group (change)="newCarnet($event)">
|
||||||
<mat-label>Do you need a new carnet?</mat-label>
|
<mat-label class="question">Do you need a new carnet?</mat-label>
|
||||||
<mat-radio-button [value]="true">Yes</mat-radio-button>
|
<mat-radio-button [value]="true">Yes</mat-radio-button>
|
||||||
<mat-radio-button [value]="false">No</mat-radio-button>
|
<mat-radio-button [value]="false">No</mat-radio-button>
|
||||||
</mat-radio-group>
|
</mat-radio-group>
|
||||||
@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
<div class="question-row">
|
<div class="question-row">
|
||||||
<mat-radio-group (change)="additionalSets($event)">
|
<mat-radio-group (change)="additionalSets($event)">
|
||||||
<mat-label>Do you need additional sets?</mat-label>
|
<mat-label class="question">Do you need additional sets?</mat-label>
|
||||||
<mat-radio-button [value]="true">Yes</mat-radio-button>
|
<mat-radio-button [value]="true">Yes</mat-radio-button>
|
||||||
<mat-radio-button [value]="false">No</mat-radio-button>
|
<mat-radio-button [value]="false">No</mat-radio-button>
|
||||||
</mat-radio-group>
|
</mat-radio-group>
|
||||||
@ -27,7 +27,8 @@
|
|||||||
|
|
||||||
<div class="question-row">
|
<div class="question-row">
|
||||||
<mat-radio-group (change)="duplicateCarnet($event)">
|
<mat-radio-group (change)="duplicateCarnet($event)">
|
||||||
<mat-label>Did you lose your carnet? Are you looking for duplicates?</mat-label>
|
<mat-label class="question">Did you lose your carnet? Are you looking for
|
||||||
|
duplicates?</mat-label>
|
||||||
<mat-radio-button [value]="true">Yes</mat-radio-button>
|
<mat-radio-button [value]="true">Yes</mat-radio-button>
|
||||||
<mat-radio-button [value]="false">No</mat-radio-button>
|
<mat-radio-button [value]="false">No</mat-radio-button>
|
||||||
</mat-radio-group>
|
</mat-radio-group>
|
||||||
@ -35,7 +36,7 @@
|
|||||||
|
|
||||||
<div class="question-row">
|
<div class="question-row">
|
||||||
<mat-radio-group (change)="extendCarnet($event)">
|
<mat-radio-group (change)="extendCarnet($event)">
|
||||||
<mat-label>Do you need to extend the carnet?</mat-label>
|
<mat-label class="question">Do you need to extend the carnet?</mat-label>
|
||||||
<mat-radio-button [value]="true">Yes</mat-radio-button>
|
<mat-radio-button [value]="true">Yes</mat-radio-button>
|
||||||
<mat-radio-button [value]="false">No</mat-radio-button>
|
<mat-radio-button [value]="false">No</mat-radio-button>
|
||||||
</mat-radio-group>
|
</mat-radio-group>
|
||||||
|
|||||||
@ -21,9 +21,12 @@
|
|||||||
|
|
||||||
.questions-section {
|
.questions-section {
|
||||||
flex: 0 0 70%;
|
flex: 0 0 70%;
|
||||||
padding: 24px 0px;
|
padding: 12px 16px;
|
||||||
margin-bottom: 24px;
|
margin-bottom: 46px;
|
||||||
margin-left: 1rem;
|
margin-left: 1rem;
|
||||||
|
margin-top: 24px;
|
||||||
|
background: var(--mat-sys-surface);
|
||||||
|
border-radius: 4px;
|
||||||
|
|
||||||
.question-row {
|
.question-row {
|
||||||
margin-bottom: 1rem;
|
margin-bottom: 1rem;
|
||||||
@ -32,6 +35,15 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
gap: 8px;
|
gap: 8px;
|
||||||
|
|
||||||
|
.question {
|
||||||
|
color: var(--mat-sys-on-surface);
|
||||||
|
font-family: var(--mat-sys-body-medium-font);
|
||||||
|
line-height: var(--mat-sys-body-medium-line-height);
|
||||||
|
font-size: var(--mat-sys-body-medium-size);
|
||||||
|
letter-spacing: var(--mat-sys-body-medium-tracking);
|
||||||
|
font-weight: var(--mat-sys-medium-font-weight);
|
||||||
|
}
|
||||||
|
|
||||||
mat-radio-button {
|
mat-radio-button {
|
||||||
margin-top: -5px;
|
margin-top: -5px;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user