Created
October 24, 2022 19:40
-
-
Save ncrmro/aab36d35503fd49394ecbdbb4c0b92a9 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React from "react"; | |
import { UserAddressInput } from "~/graphql-types"; | |
import TextField from "~/components/TextField"; | |
interface AddressState extends UserAddressInput { | |
isPrimary: boolean; | |
} | |
export const useAddressState = () => | |
React.useReducer(fieldReducer, { | |
fullName: "", | |
street1: "", | |
street2: null, | |
city: "", | |
state: "", | |
zipcode: "", | |
country: "USA", | |
deliveryInstructions: null, | |
isPrimary: false, | |
}); | |
function fieldReducer( | |
state: AddressState, | |
event: React.ChangeEvent<HTMLInputElement> | |
) { | |
const nextState = structuredClone(state); | |
const { name, value } = event.target; | |
switch (name) { | |
case "street1": | |
case "street2": | |
case "city": | |
case "state": | |
case "zipcode": | |
case "country": | |
case "deliveryInstructions": | |
case "fullName": | |
nextState[name] = value; | |
break; | |
case "isPrimary": | |
nextState[name] = !state.isPrimary; | |
break; | |
default: | |
throw new Error(`Field was not expected: ${name}`); | |
} | |
return nextState; | |
} | |
export const AddressFormFields: React.FC<{ | |
addressState: AddressState; | |
setAddressState: React.Dispatch<React.ChangeEvent<HTMLInputElement>>; | |
}> = ({ addressState, setAddressState }) => { | |
return ( | |
<> | |
<div className="dropdown"> | |
<label htmlFor="country">Country</label> | |
<select name="country" id="country"> | |
<option value="USA">United States of America</option> | |
<option value="CAN">Canada</option> | |
<option value="MEX">Mexico</option> | |
</select> | |
</div> | |
<TextField | |
name="fullName" | |
placeholder="Full Name" | |
value={addressState.fullName} | |
onChange={setAddressState} | |
maxLength={50} | |
required | |
/> | |
<TextField | |
name="street1" | |
value={addressState.street1} | |
placeholder="Street address or P.O Box" | |
onChange={setAddressState} | |
maxLength={60} | |
required | |
autoComplete="address-line1" | |
/> | |
<TextField | |
name="street2" | |
value={addressState.street2 ?? ""} | |
placeholder="Apt, suite, unit, building, floor, etc." | |
onChange={setAddressState} | |
maxLength={60} | |
autoComplete="address-line2" | |
/> | |
<TextField | |
name="city" | |
placeholder="City" | |
value={addressState.city} | |
onChange={setAddressState} | |
maxLength={50} | |
required | |
autoComplete="address-level1" | |
/> | |
<TextField | |
name="state" | |
placeholder="State" | |
value={addressState.state} | |
maxLength={2} | |
onChange={setAddressState} | |
required | |
/> | |
<TextField | |
name="zipcode" | |
placeholder="ZIP Code" | |
value={addressState.zipcode} | |
onChange={setAddressState} | |
maxLength={10} | |
required | |
pattern={"^\\d{5}(?:[-]\\d{4})?$"} | |
title="Zip codes should be 5 digit or 9 with a dash separating the first 5 digits and the last 4" | |
autoComplete="postal-code" | |
/> | |
<div> | |
<label htmlFor="default-address">Make this my primary address</label> | |
<input | |
type="checkbox" | |
name="isPrimary" | |
checked={addressState.isPrimary} | |
onChange={setAddressState} | |
/> | |
</div> | |
<TextField | |
name="deliveryInstructions" | |
placeholder="Delivery Instructions" | |
value={addressState.deliveryInstructions ?? ""} | |
onChange={setAddressState} | |
/> | |
</> | |
); | |
}; | |
export default AddressFormFields; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment