All files / src/pages/admin/components AddressForm.tsx

100% Statements 5/5
100% Branches 16/16
100% Functions 2/2
100% Lines 5/5

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147                          2x           125x 13x 13x     125x                                                                                                                                                                                                                                                    
// src/pages/admin/components/AddressForm.tsx
import React from 'react';
import { Address } from '../../../types';
import { MapPinIcon } from 'lucide-react';
import { LoadingSpinner } from '../../../components/LoadingSpinner';
 
interface AddressFormProps {
  address: Partial<Address>;
  onAddressChange: (field: keyof Address, value: string) => void;
  onGeocode: () => void;
  isGeocoding: boolean;
}
 
export const AddressForm: React.FC<AddressFormProps> = ({
  address,
  onAddressChange,
  onGeocode,
  isGeocoding,
}) => {
  const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const { name, value } = e.target;
    onAddressChange(name as keyof Address, value);
  };
 
  return (
    <div className="space-y-4">
      <div className="flex justify-between items-center">
        <h3 className="text-lg font-medium text-gray-900 dark:text-white">Home Address</h3>
        {isGeocoding && (
          <div className="w-4 h-4 text-brand-primary">
            <LoadingSpinner />
          </div>
        )}
        <button
          type="button"
          onClick={onGeocode}
          disabled={isGeocoding}
          className="text-sm bg-gray-200 dark:bg-gray-700 hover:bg-gray-300 dark:hover:bg-gray-600 text-gray-800 dark:text-white font-bold py-1 px-3 rounded-lg flex items-center disabled:opacity-50"
        >
          {isGeocoding ? <LoadingSpinner /> : <MapPinIcon className="w-4 h-4 mr-2" />}
          Re-Geocode
        </button>
      </div>
      <div>
        <label
          htmlFor="address_line_1"
          className="block text-sm font-medium text-gray-700 dark:text-gray-300"
        >
          Address Line 1
        </label>
        <input
          type="text"
          name="address_line_1"
          id="address_line_1"
          value={address.address_line_1 || ''}
          onChange={handleInputChange}
          className="mt-1 block w-full px-3 py-2 bg-white dark:bg-gray-800 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-brand-primary focus:border-brand-primary sm:text-sm"
        />
      </div>
      <div>
        <label
          htmlFor="address_line_2"
          className="block text-sm font-medium text-gray-700 dark:text-gray-300"
        >
          Address Line 2
        </label>
        <input
          type="text"
          name="address_line_2"
          id="address_line_2"
          value={address.address_line_2 || ''}
          onChange={handleInputChange}
          className="mt-1 block w-full px-3 py-2 bg-white dark:bg-gray-800 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-brand-primary focus:border-brand-primary sm:text-sm"
        />
      </div>
      <div className="grid grid-cols-1 gap-4 sm:grid-cols-2">
        <div>
          <label
            htmlFor="city"
            className="block text-sm font-medium text-gray-700 dark:text-gray-300"
          >
            City
          </label>
          <input
            type="text"
            name="city"
            id="city"
            value={address.city || ''}
            onChange={handleInputChange}
            className="mt-1 block w-full px-3 py-2 bg-white dark:bg-gray-800 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-brand-primary focus:border-brand-primary sm:text-sm"
          />
        </div>
        <div>
          <label
            htmlFor="province_state"
            className="block text-sm font-medium text-gray-700 dark:text-gray-300"
          >
            Province / State
          </label>
          <input
            type="text"
            name="province_state"
            id="province_state"
            value={address.province_state || ''}
            onChange={handleInputChange}
            className="mt-1 block w-full px-3 py-2 bg-white dark:bg-gray-800 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-brand-primary focus:border-brand-primary sm:text-sm"
          />
        </div>
      </div>
      <div className="grid grid-cols-1 gap-4 sm:grid-cols-2">
        <div>
          <label
            htmlFor="postal_code"
            className="block text-sm font-medium text-gray-700 dark:text-gray-300"
          >
            Postal / ZIP Code
          </label>
          <input
            type="text"
            name="postal_code"
            id="postal_code"
            value={address.postal_code || ''}
            onChange={handleInputChange}
            className="mt-1 block w-full px-3 py-2 bg-white dark:bg-gray-800 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-brand-primary focus:border-brand-primary sm:text-sm"
          />
        </div>
        <div>
          <label
            htmlFor="country"
            className="block text-sm font-medium text-gray-700 dark:text-gray-300"
          >
            Country
          </label>
          <input
            type="text"
            name="country"
            id="country"
            value={address.country || ''}
            onChange={handleInputChange}
            className="mt-1 block w-full px-3 py-2 bg-white dark:bg-gray-800 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-brand-primary focus:border-brand-primary sm:text-sm"
          />
        </div>
      </div>
    </div>
  );
};