exercises

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

checkout.component.html (8894B)


      1 <form [formGroup]="checkoutForm" (ngSubmit)="onSubmit()">
      2   <section class="card mb-3 col">
      3     <div class="card-body row g-3">
      4       <h5 class="fs-6">Billing Information</h5>
      5       <div class="mb-3 col-6">
      6         <label class="form-label">
      7           First Name
      8           <span class="text-danger">*</span>
      9           <input
     10             type="text"
     11             class="form-control"
     12             [class.is-invalid]="isFieldInvalid('firstName')"
     13             placeholder="John"
     14             formControlName="firstName" />
     15           @if (isFieldInvalid('firstName')) {
     16             <div class="invalid-feedback d-block">
     17               <i class="bi bi-exclamation-circle me-1"></i>
     18               {{ getFieldError('firstName') }}
     19             </div>
     20           }
     21         </label>
     22       </div>
     23 
     24       <!-- Last Name -->
     25       <div class="mb-3 col-6">
     26         <label class="form-label">
     27           Last Name
     28           <span class="text-danger">*</span>
     29           <input
     30             type="text"
     31             class="form-control"
     32             [class.is-invalid]="isFieldInvalid('lastName')"
     33             placeholder="Doe"
     34             formControlName="lastName" />
     35           @if (isFieldInvalid('lastName')) {
     36             <div class="invalid-feedback d-block">
     37               <i class="bi bi-exclamation-circle me-1"></i>
     38               {{ getFieldError('lastName') }}
     39             </div>
     40           }
     41         </label>
     42       </div>
     43 
     44       <!-- Email -->
     45       <div class="mb-3 col-6">
     46         <label class="form-label">
     47           Email
     48           <span class="text-danger">*</span>
     49           <input
     50             type="email"
     51             class="form-control"
     52             [class.is-invalid]="isFieldInvalid('email')"
     53             placeholder="name@example.com"
     54             formControlName="email" />
     55           @if (isFieldInvalid('email')) {
     56             <div class="invalid-feedback d-block">
     57               <i class="bi bi-exclamation-circle me-1"></i>
     58               {{ getFieldError('email') }}
     59             </div>
     60           }
     61         </label>
     62       </div>
     63 
     64       <!-- Phone Number -->
     65       <div class="mb-3 col-6">
     66         <label class="form-label">
     67           Phone Number
     68           <span class="text-danger">*</span>
     69           <input
     70             type="tel"
     71             class="form-control"
     72             [class.is-invalid]="isFieldInvalid('phoneNumber')"
     73             placeholder="+1 (555) 123-4567"
     74             formControlName="phoneNumber" />
     75           @if (isFieldInvalid('phoneNumber')) {
     76             <div class="invalid-feedback d-block">
     77               <i class="bi bi-exclamation-circle me-1"></i>
     78               {{ getFieldError('phoneNumber') }}
     79             </div>
     80           }
     81         </label>
     82       </div>
     83 
     84       <!-- Card Input -->
     85       <div class="mb-3 col-6">
     86         <label class="form-label">
     87           Card Number
     88           <span class="text-danger">*</span>
     89         </label>
     90         <div class="card-input"></div>
     91         @if (submitted() && cardInputComponent && !cardInputComponent.isValidCard()) {
     92           <div class="invalid-feedback d-block">
     93             <i class="bi bi-exclamation-circle me-1"></i>
     94             Please enter a valid 16-digit card number
     95           </div>
     96         }
     97       </div>
     98     </div>
     99   </section>
    100 
    101   <!-- Address Section -->
    102   <section class="card mb-3 col">
    103     <div class="card-body row g-3">
    104       <h5 class="fs-6">Shipping Address</h5>
    105       <!-- Address Line 1 -->
    106       <div class="mb-3 col-12">
    107         <label class="form-label">
    108           Address Line 1
    109           <span class="text-danger">*</span>
    110           <input
    111             type="text"
    112             class="form-control"
    113             [class.is-invalid]="isFieldInvalid('addressLine1')"
    114             placeholder="123 Main St"
    115             formControlName="addressLine1" />
    116           @if (isFieldInvalid('addressLine1')) {
    117             <div class="invalid-feedback d-block">
    118               <i class="bi bi-exclamation-circle me-1"></i>
    119               {{ getFieldError('addressLine1') }}
    120             </div>
    121           }
    122         </label>
    123       </div>
    124 
    125       <!-- Address Line 2 -->
    126       <div class="mb-3 col-12">
    127         <label class="form-label">
    128           Address Line 2 (Optional)
    129           <input
    130             type="text"
    131             class="form-control"
    132             placeholder="Apt, Suite, Unit, etc."
    133             formControlName="addressLine2" />
    134         </label>
    135       </div>
    136 
    137       <!-- City -->
    138       <div class="mb-3 col-6">
    139         <label class="form-label">
    140           City
    141           <span class="text-danger">*</span>
    142           <input
    143             type="text"
    144             class="form-control"
    145             [class.is-invalid]="isFieldInvalid('city')"
    146             placeholder="City"
    147             formControlName="city" />
    148           @if (isFieldInvalid('city')) {
    149             <div class="invalid-feedback d-block">
    150               <i class="bi bi-exclamation-circle me-1"></i>
    151               {{ getFieldError('city') }}
    152             </div>
    153           }
    154         </label>
    155       </div>
    156 
    157       <!-- State / Province -->
    158       <div class="mb-3 col-6">
    159         <label class="form-label">
    160           State / Province
    161           <span class="text-danger">*</span>
    162           <input
    163             type="text"
    164             class="form-control"
    165             [class.is-invalid]="isFieldInvalid('state')"
    166             placeholder="State / Province"
    167             formControlName="state" />
    168           @if (isFieldInvalid('state')) {
    169             <div class="invalid-feedback d-block">
    170               <i class="bi bi-exclamation-circle me-1"></i>
    171               {{ getFieldError('state') }}
    172             </div>
    173           }
    174         </label>
    175       </div>
    176 
    177       <!-- ZIP / Postal Code -->
    178       <div class="mb-3 col-6">
    179         <label class="form-label">
    180           ZIP / Postal Code
    181           <span class="text-danger">*</span>
    182           <input
    183             type="text"
    184             class="form-control"
    185             [class.is-invalid]="isFieldInvalid('zipCode')"
    186             placeholder="12345"
    187             formControlName="zipCode" />
    188           @if (isFieldInvalid('zipCode')) {
    189             <div class="invalid-feedback d-block">
    190               <i class="bi bi-exclamation-circle me-1"></i>
    191               {{ getFieldError('zipCode') }}
    192             </div>
    193           }
    194         </label>
    195       </div>
    196 
    197       <!-- Country -->
    198       <div class="mb-3 col-6">
    199         <label class="form-label">
    200           Country
    201           <span class="text-danger">*</span>
    202           <input
    203             type="text"
    204             class="form-control"
    205             [class.is-invalid]="isFieldInvalid('country')"
    206             placeholder="US"
    207             formControlName="country" />
    208           @if (isFieldInvalid('country')) {
    209             <div class="invalid-feedback d-block">
    210               <i class="bi bi-exclamation-circle me-1"></i>
    211               {{ getFieldError('country') }}
    212             </div>
    213           }
    214         </label>
    215       </div>
    216     </div>
    217   </section>
    218 
    219   <!-- Shipping Options Section -->
    220   <section class="card mb-3">
    221     <div class="card-body">
    222       <h5 class="fs-6">Shipping Options <span class="text-danger">*</span></h5>
    223       <div class="list-group">
    224         @for (option of shippingOptions; track option.value) {
    225           <label class="list-group-item">
    226             <input class="form-check-input me-2" type="radio" [value]="option.value" formControlName="shippingOption" />
    227             <i class="bi {{ option.icon }} me-2"></i>
    228             {{ option.label }}
    229           </label>
    230         }
    231       </div>
    232       @if (isFieldInvalid('shippingOption')) {
    233         <div class="invalid-feedback d-block mt-2">
    234           <i class="bi bi-exclamation-circle me-1"></i>
    235           {{ getFieldError('shippingOption') }}
    236         </div>
    237       }
    238     </div>
    239   </section>
    240 
    241   <!-- Terms & Conditions Section -->
    242   <section class="card mb-3">
    243     <div class="card-body">
    244       <div class="form-check">
    245         <input
    246           class="form-check-input"
    247           type="checkbox"
    248           id="agreeToTerms"
    249           formControlName="agreeToTerms"
    250           [class.is-invalid]="isFieldInvalid('agreeToTerms')" />
    251         <label class="form-check-label" for="agreeToTerms">
    252           I agree to the payment terms and confirm the order
    253           <span class="text-danger">*</span>
    254         </label>
    255         @if (isFieldInvalid('agreeToTerms')) {
    256           <div class="invalid-feedback d-block">
    257             <i class="bi bi-exclamation-circle me-1"></i>
    258             You must agree to the terms before proceeding
    259           </div>
    260         }
    261       </div>
    262     </div>
    263   </section>
    264 
    265   <!-- Submit Button -->
    266   <div class="d-grid">
    267     <button type="submit" class="btn btn-primary btn-sm btn-lg" [disabled]="isSubmitting()">
    268       @if (isSubmitting()) {
    269         <span class="spinner-border spinner-border-sm me-2" role="status" aria-hidden="true"></span>
    270         Processing...
    271       } @else {
    272         <i class="bi bi-credit-card me-2"></i>
    273         Place Order
    274       }
    275     </button>
    276   </div>
    277 </form>