Skip to content

Instantly share code, notes, and snippets.

@ncrmro
Created October 24, 2022 19:40
Show Gist options
  • Save ncrmro/aab36d35503fd49394ecbdbb4c0b92a9 to your computer and use it in GitHub Desktop.
Save ncrmro/aab36d35503fd49394ecbdbb4c0b92a9 to your computer and use it in GitHub Desktop.
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