From 6c3ff3e4c8c743005caf01e8d7b563a5d5f45434 Mon Sep 17 00:00:00 2001 From: Jessica Sampaio-Herlitz <102844641+jessampaio@users.noreply.github.com> Date: Mon, 5 Aug 2024 19:14:52 -0400 Subject: [PATCH 1/7] wip - modified the address component to handle country selection --- packages/ui/src/components/address.tsx | 74 +++++++++++++++++++++++++- 1 file changed, 72 insertions(+), 2 deletions(-) diff --git a/packages/ui/src/components/address.tsx b/packages/ui/src/components/address.tsx index 6ee20961..fd12d6c3 100644 --- a/packages/ui/src/components/address.tsx +++ b/packages/ui/src/components/address.tsx @@ -1,10 +1,29 @@ import { type PropsWithChildren } from 'react'; +import React, { useContext, useState } from 'react'; import { Input, type InputProps } from './input'; import { Select, type SelectProps } from './select'; +type AddressContextValue = { + countryAbbreviation: string; + setCountryAbbreviation(country: string): void; +}; + +const AddressContext = React.createContext({ + countryAbbreviation: 'US', + setCountryAbbreviation: (_: string) => {}, +}); + export const Address = ({ children }: PropsWithChildren) => { - return
{children}
; + const [countryAbbreviation, setCountryAbbreviation] = useState('US'); + + return ( + +
{children}
; +
+ ); }; Address.City = function City(props: InputProps) { @@ -91,10 +110,45 @@ const USA_STATES: State[] = [ { abbreviation: 'WY', name: 'Wyoming' }, ]; +const CA_PROVINCES: State[] = [ + { name: 'Alberta', abbreviation: 'AB' }, + { name: 'British Columbia ', abbreviation: 'BC' }, + { name: 'Manitoba ', abbreviation: 'MB' }, + { name: 'New Brunswick', abbreviation: 'NB' }, + { name: 'Newfoundland and Labrador', abbreviation: 'NL' }, + { name: 'Northwest Territories', abbreviation: 'NT' }, + { name: 'Nova Scotia', abbreviation: 'NS' }, + { name: 'Nunavut', abbreviation: 'NU' }, + { name: 'Ontario', abbreviation: 'ON' }, + { name: 'Prince Edward Island ', abbreviation: 'PE' }, + { name: 'Quebec ', abbreviation: 'QC' }, + { name: 'Saskatchewan ', abbreviation: 'SK' }, + { name: 'Yukon', abbreviation: 'YT' }, +]; + +type Country = { + abbreviation: string; + name: string; +}; + +const COUNTRIES: Country[] = [ + { abbreviation: 'CA', name: 'Canada' }, + { abbreviation: 'US', name: 'United States' }, +]; + +const mapCountryAbbreviationToStates = { + CA: CA_PROVINCES, + US: USA_STATES, +}; + Address.State = function State(props: SelectProps) { + const { countryAbbreviation } = useContext(AddressContext); + + const states = mapCountryAbbreviationToStates[countryAbbreviation]; + return ( ); }; + +Address.Country = function Country(props: SelectProps) { + const { setCountryAbbreviation } = useContext(AddressContext); + + return ( + + ); +}; From eba0131e6365b0424b81710b729aab49591db458 Mon Sep 17 00:00:00 2001 From: Jessica Sampaio-Herlitz <102844641+jessampaio@users.noreply.github.com> Date: Sat, 17 Aug 2024 14:36:55 -0400 Subject: [PATCH 2/7] Updated claimSwagPack and orderSwagPack to pass in country --- .../_profile.home.claim-swag-pack._index.tsx | 56 +++++++++++-------- .../modules/swag-pack/swag-pack.service.ts | 3 +- .../src/modules/swag-pack/swag-pack.types.ts | 1 + .../swag-pack/use-cases/claim-swag-pack.ts | 3 + packages/types/src/domain/types.ts | 1 + packages/ui/src/components/address.tsx | 2 +- 6 files changed, 41 insertions(+), 25 deletions(-) diff --git a/apps/member-profile/app/routes/_profile.home.claim-swag-pack._index.tsx b/apps/member-profile/app/routes/_profile.home.claim-swag-pack._index.tsx index 180646c9..ad7e27a0 100644 --- a/apps/member-profile/app/routes/_profile.home.claim-swag-pack._index.tsx +++ b/apps/member-profile/app/routes/_profile.home.claim-swag-pack._index.tsx @@ -78,6 +78,7 @@ export async function action({ request }: ActionFunctionArgs) { addressState: data.addressState, addressZip: data.addressZip, studentId: user(session), + addressCountry: data.addressCountry, }); return redirect(Route['/home/claim-swag-pack/confirmation']); @@ -104,20 +105,22 @@ export default function ClaimSwagPack() { }> - - {(inventory) => { - return inventory > 0 ? ( - - ) : ( - - Unfortunately, we ran out of swag pack inventory. However, we're - restocking ASAP and you should be able to claim a pack in the - next 2-4 weeks. Sorry about any inconvenience and thank you for - your patience! - - ); - }} - + { + + {(inventory) => { + return inventory > 0 ? ( + + ) : ( + + Unfortunately, we ran out of swag pack inventory. However, + we're restocking ASAP and you should be able to claim a pack + in the next 2-4 weeks. Sorry about any inconvenience and thank + you for your patience! + + ); + }} + + } ); @@ -164,15 +167,10 @@ function ClaimSwagPackForm() { - - + @@ -190,6 +188,18 @@ function ClaimSwagPackForm() { /> + + + { // SwagUp would have an endpoint like POST /token/test to know if the // token needed to be refreshed or not, but this is our current // workaround. + const response = await fetch(`${SWAG_UP_API_URL}/accounts?limit=1`, { headers: { Authorization: `Bearer ${accessToken}`, diff --git a/packages/core/src/modules/swag-pack/swag-pack.types.ts b/packages/core/src/modules/swag-pack/swag-pack.types.ts index 687113cb..ab55b095 100644 --- a/packages/core/src/modules/swag-pack/swag-pack.types.ts +++ b/packages/core/src/modules/swag-pack/swag-pack.types.ts @@ -9,6 +9,7 @@ export const ClaimSwagPackInput = z.object({ addressState: Address.shape.state, addressZip: Address.shape.zip, studentId: Student.shape.id, + addressCountry: Address.shape.country, }); export type ClaimSwagPackInput = z.infer; diff --git a/packages/core/src/modules/swag-pack/use-cases/claim-swag-pack.ts b/packages/core/src/modules/swag-pack/use-cases/claim-swag-pack.ts index e11d36ae..1674c97c 100644 --- a/packages/core/src/modules/swag-pack/use-cases/claim-swag-pack.ts +++ b/packages/core/src/modules/swag-pack/use-cases/claim-swag-pack.ts @@ -10,6 +10,7 @@ export async function claimSwagPack({ addressState, addressZip, studentId, + addressCountry, }: ClaimSwagPackInput) { const student = await db .selectFrom('students') @@ -25,6 +26,7 @@ export async function claimSwagPack({ line2: addressLine2, state: addressState, zip: addressZip, + country: addressCountry, }, email: student.email, firstName: student.firstName, @@ -40,6 +42,7 @@ export async function claimSwagPack({ addressLine2, addressState, addressZip, + addressCountry, claimedSwagPackAt: new Date(), swagUpOrderId: swagPackOrderId, }) diff --git a/packages/types/src/domain/types.ts b/packages/types/src/domain/types.ts index 2d57d8fc..8c661ef7 100644 --- a/packages/types/src/domain/types.ts +++ b/packages/types/src/domain/types.ts @@ -21,6 +21,7 @@ export const Address = z.object({ line2: z.string().trim().optional(), state: z.string().trim().min(1), zip: z.string().trim().min(1), + country: z.string().trim().length(2), }); export type Address = z.infer; diff --git a/packages/ui/src/components/address.tsx b/packages/ui/src/components/address.tsx index fd12d6c3..bdc11401 100644 --- a/packages/ui/src/components/address.tsx +++ b/packages/ui/src/components/address.tsx @@ -21,7 +21,7 @@ export const Address = ({ children }: PropsWithChildren) => { -
{children}
; +
{children}
); }; From 731da35df7809e5bf6e06ce67a56eec0991f5d29 Mon Sep 17 00:00:00 2001 From: Jessica Sampaio-Herlitz <102844641+jessampaio@users.noreply.github.com> Date: Sat, 17 Aug 2024 14:48:28 -0400 Subject: [PATCH 3/7] fixed type on address component --- packages/ui/src/components/address.tsx | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/ui/src/components/address.tsx b/packages/ui/src/components/address.tsx index bdc11401..bf023ecb 100644 --- a/packages/ui/src/components/address.tsx +++ b/packages/ui/src/components/address.tsx @@ -136,7 +136,7 @@ const COUNTRIES: Country[] = [ { abbreviation: 'US', name: 'United States' }, ]; -const mapCountryAbbreviationToStates = { +const mapCountryAbbreviationToStates: Record = { CA: CA_PROVINCES, US: USA_STATES, }; @@ -163,7 +163,10 @@ Address.Country = function Country(props: SelectProps) { const { setCountryAbbreviation } = useContext(AddressContext); return ( - setCountryAbbreviation(e.currentTarget.value)} + > {COUNTRIES.map((country: Country) => { return (
- - + - - - - + + + + diff --git a/packages/ui/src/components/address.tsx b/packages/ui/src/components/address.tsx index bf023ecb..45729f9e 100644 --- a/packages/ui/src/components/address.tsx +++ b/packages/ui/src/components/address.tsx @@ -112,17 +112,17 @@ const USA_STATES: State[] = [ const CA_PROVINCES: State[] = [ { name: 'Alberta', abbreviation: 'AB' }, - { name: 'British Columbia ', abbreviation: 'BC' }, - { name: 'Manitoba ', abbreviation: 'MB' }, + { name: 'British Columbia', abbreviation: 'BC' }, + { name: 'Manitoba', abbreviation: 'MB' }, { name: 'New Brunswick', abbreviation: 'NB' }, { name: 'Newfoundland and Labrador', abbreviation: 'NL' }, { name: 'Northwest Territories', abbreviation: 'NT' }, { name: 'Nova Scotia', abbreviation: 'NS' }, { name: 'Nunavut', abbreviation: 'NU' }, { name: 'Ontario', abbreviation: 'ON' }, - { name: 'Prince Edward Island ', abbreviation: 'PE' }, - { name: 'Quebec ', abbreviation: 'QC' }, - { name: 'Saskatchewan ', abbreviation: 'SK' }, + { name: 'Prince Edward Island', abbreviation: 'PE' }, + { name: 'Quebec', abbreviation: 'QC' }, + { name: 'Saskatchewan', abbreviation: 'SK' }, { name: 'Yukon', abbreviation: 'YT' }, ]; From feb3dbb518f3509d2027db88e55800b25072e43e Mon Sep 17 00:00:00 2001 From: Rami Abdou Date: Thu, 22 Aug 2024 14:54:10 -0700 Subject: [PATCH 6/7] handle canada address --- .../_profile.home.claim-swag-pack._index.tsx | 37 +-- .../modules/swag-pack/swag-pack.service.ts | 1 - .../src/modules/swag-pack/swag-pack.types.ts | 2 +- .../swag-pack/use-cases/claim-swag-pack.ts | 62 ++++- ...0240822172825_students_address_country.ts} | 0 packages/types/src/domain/types.ts | 2 +- packages/ui/src/components/address.tsx | 234 +++++++++--------- packages/ui/src/components/form.tsx | 6 +- 8 files changed, 197 insertions(+), 147 deletions(-) rename packages/db/src/migrations/{20240817185242_add_address_country_to_students_table.ts => 20240822172825_students_address_country.ts} (100%) diff --git a/apps/member-profile/app/routes/_profile.home.claim-swag-pack._index.tsx b/apps/member-profile/app/routes/_profile.home.claim-swag-pack._index.tsx index 5b84bd2e..34decaa6 100644 --- a/apps/member-profile/app/routes/_profile.home.claim-swag-pack._index.tsx +++ b/apps/member-profile/app/routes/_profile.home.claim-swag-pack._index.tsx @@ -54,16 +54,12 @@ export async function loader({ request }: LoaderFunctionArgs) { }); } -const ClaimSwagPackFormData = ClaimSwagPackInput.omit({ - studentId: true, -}); - export async function action({ request }: ActionFunctionArgs) { const session = await ensureUserAuthenticated(request); const { data, errors, ok } = await validateForm( request, - ClaimSwagPackFormData + ClaimSwagPackInput.omit({ studentId: true }) ); if (!ok) { @@ -71,16 +67,20 @@ export async function action({ request }: ActionFunctionArgs) { } try { - await claimSwagPack({ + const result = await claimSwagPack({ addressCity: data.addressCity, + addressCountry: data.addressCountry, addressLine1: data.addressLine1, addressLine2: data.addressLine2, addressState: data.addressState, addressZip: data.addressZip, studentId: user(session), - addressCountry: data.addressCountry, }); + if (!result.ok) { + return json({ error: result.error }, { status: result.code }); + } + return redirect(Route['/home/claim-swag-pack/confirmation']); } catch (e) { reportException(e); @@ -92,7 +92,7 @@ export async function action({ request }: ActionFunctionArgs) { } } -const keys = ClaimSwagPackFormData.keyof().enum; +const keys = ClaimSwagPackInput.keyof().enum; export default function ClaimSwagPack() { const { inventoryPromise } = useLoaderData(); @@ -143,6 +143,19 @@ function ClaimSwagPackForm() { Let us know where to send your swag pack!
+ + + + - - - -
diff --git a/packages/core/src/modules/swag-pack/swag-pack.service.ts b/packages/core/src/modules/swag-pack/swag-pack.service.ts index 90df27cd..118732f8 100644 --- a/packages/core/src/modules/swag-pack/swag-pack.service.ts +++ b/packages/core/src/modules/swag-pack/swag-pack.service.ts @@ -205,7 +205,6 @@ async function retrieveTokens(): Promise { // SwagUp would have an endpoint like POST /token/test to know if the // token needed to be refreshed or not, but this is our current // workaround. - const response = await fetch(`${SWAG_UP_API_URL}/accounts?limit=1`, { headers: { Authorization: `Bearer ${accessToken}`, diff --git a/packages/core/src/modules/swag-pack/swag-pack.types.ts b/packages/core/src/modules/swag-pack/swag-pack.types.ts index ab55b095..3a3e85ec 100644 --- a/packages/core/src/modules/swag-pack/swag-pack.types.ts +++ b/packages/core/src/modules/swag-pack/swag-pack.types.ts @@ -4,12 +4,12 @@ import { Address, Student } from '@oyster/types'; export const ClaimSwagPackInput = z.object({ addressCity: Address.shape.city, + addressCountry: Address.shape.country, addressLine1: Address.shape.line1, addressLine2: Address.shape.line2, addressState: Address.shape.state, addressZip: Address.shape.zip, studentId: Student.shape.id, - addressCountry: Address.shape.country, }); export type ClaimSwagPackInput = z.infer; diff --git a/packages/core/src/modules/swag-pack/use-cases/claim-swag-pack.ts b/packages/core/src/modules/swag-pack/use-cases/claim-swag-pack.ts index 1674c97c..6c46827a 100644 --- a/packages/core/src/modules/swag-pack/use-cases/claim-swag-pack.ts +++ b/packages/core/src/modules/swag-pack/use-cases/claim-swag-pack.ts @@ -1,32 +1,76 @@ +import dedent from 'dedent'; + import { db } from '@oyster/db'; +import { job } from '@/infrastructure/bull/use-cases/job'; +import { fail, type Result, success } from '@/shared/utils/core.utils'; import { orderSwagPack } from '../swag-pack.service'; import { type ClaimSwagPackInput } from '../swag-pack.types'; export async function claimSwagPack({ addressCity, + addressCountry, addressLine1, addressLine2, addressState, addressZip, studentId, - addressCountry, -}: ClaimSwagPackInput) { +}: ClaimSwagPackInput): Promise { + // We save the address regardless if the swag pack order failed or not so + // we'll be able to send them something in the future. const student = await db - .selectFrom('students') - .select(['email', 'firstName', 'lastName']) + .updateTable('students') + .set({ + addressCity, + addressCountry, + addressLine1, + addressLine2, + addressState, + addressZip, + }) .where('id', '=', studentId) + .returning(['email', 'firstName', 'lastName']) .executeTakeFirstOrThrow(); + // Currently, SwagUp only supports the US, but not Puerto Rico. + // See: https://support.swagup.com/en/articles/6952397-international-shipments-restricted-items + const isAddressSupported = addressCountry === 'US' && addressState !== 'PR'; + + // If the address isn't supported, then we'll send a notification to our + // team to create a gift card manually for them. + if (!isAddressSupported) { + const notification = dedent` + ${student.firstName} ${student.lastName} (${student.email}) is attempting to claim a swag pack, but they're either from Puerto Rico or Canada, which is not supported for our product. + + We let them know we'll send them a merch store gift card in the next "few days"! + `; + + job('notification.slack.send', { + message: notification, + workspace: 'internal', + }); + + const error = dedent` + Unfortunately, our swag pack provider, SwagUp, does not support shipments to Puerto Rico and Canada. Instead, we will send you a gift card to our official merch store. + + Our team has been notified, please give us a few days to complete this request! + `; + + return fail({ + code: 400, + error, + }); + } + const swagPackOrderId = await orderSwagPack({ contact: { address: { city: addressCity, + country: addressCountry, line1: addressLine1, line2: addressLine2, state: addressState, zip: addressZip, - country: addressCountry, }, email: student.email, firstName: student.firstName, @@ -37,15 +81,11 @@ export async function claimSwagPack({ await db .updateTable('students') .set({ - addressCity, - addressLine1, - addressLine2, - addressState, - addressZip, - addressCountry, claimedSwagPackAt: new Date(), swagUpOrderId: swagPackOrderId, }) .where('id', '=', studentId) .execute(); + + return success({}); } diff --git a/packages/db/src/migrations/20240817185242_add_address_country_to_students_table.ts b/packages/db/src/migrations/20240822172825_students_address_country.ts similarity index 100% rename from packages/db/src/migrations/20240817185242_add_address_country_to_students_table.ts rename to packages/db/src/migrations/20240822172825_students_address_country.ts diff --git a/packages/types/src/domain/types.ts b/packages/types/src/domain/types.ts index 8c661ef7..af350e40 100644 --- a/packages/types/src/domain/types.ts +++ b/packages/types/src/domain/types.ts @@ -17,11 +17,11 @@ export type Entity = z.infer; export const Address = z.object({ city: z.string().trim().min(1), + country: z.string().trim().min(2).max(3), line1: z.string().trim().min(1), line2: z.string().trim().optional(), state: z.string().trim().min(1), zip: z.string().trim().min(1), - country: z.string().trim().length(2), }); export type Address = z.infer; diff --git a/packages/ui/src/components/address.tsx b/packages/ui/src/components/address.tsx index 45729f9e..e4ff3f0c 100644 --- a/packages/ui/src/components/address.tsx +++ b/packages/ui/src/components/address.tsx @@ -4,23 +4,23 @@ import React, { useContext, useState } from 'react'; import { Input, type InputProps } from './input'; import { Select, type SelectProps } from './select'; -type AddressContextValue = { - countryAbbreviation: string; - setCountryAbbreviation(country: string): void; +type SupportedCountry = 'CA' | 'US'; + +type AddressContext = { + country: SupportedCountry; + setCountry(country: SupportedCountry): void; }; -const AddressContext = React.createContext({ - countryAbbreviation: 'US', - setCountryAbbreviation: (_: string) => {}, +const AddressContext = React.createContext({ + country: 'US', + setCountry: (_: SupportedCountry) => {}, }); export const Address = ({ children }: PropsWithChildren) => { - const [countryAbbreviation, setCountryAbbreviation] = useState('US'); + const [country, setCountry] = useState('US'); return ( - +
{children}
); @@ -30,6 +30,40 @@ Address.City = function City(props: InputProps) { return ; }; +type Country = { + abbreviation: SupportedCountry; + name: string; +}; + +const COUNTRIES: Country[] = [ + { abbreviation: 'CA', name: 'Canada' }, + { abbreviation: 'US', name: 'United States' }, +]; + +const DEFAULT_COUNTRY: SupportedCountry = 'US'; + +Address.Country = function Country(props: SelectProps) { + const { setCountry } = useContext(AddressContext); + + return ( + + ); +}; + Address.HalfGrid = function HalfGrid({ children }: PropsWithChildren) { return (
@@ -55,100 +89,87 @@ type State = { name: string; }; -const USA_STATES: State[] = [ - { abbreviation: 'AL', name: 'Alabama' }, - { abbreviation: 'AK', name: 'Alaska' }, - { abbreviation: 'AZ', name: 'Arizona' }, - { abbreviation: 'AR', name: 'Arkansas' }, - { abbreviation: 'CA', name: 'California' }, - { abbreviation: 'CO', name: 'Colorado' }, - { abbreviation: 'CT', name: 'Connecticut' }, - { abbreviation: 'DE', name: 'Delaware' }, - { abbreviation: 'DC', name: 'District Of Columbia' }, - { abbreviation: 'FL', name: 'Florida' }, - { abbreviation: 'GA', name: 'Georgia' }, - { abbreviation: 'HI', name: 'Hawaii' }, - { abbreviation: 'ID', name: 'Idaho' }, - { abbreviation: 'IL', name: 'Illinois' }, - { abbreviation: 'IN', name: 'Indiana' }, - { abbreviation: 'IA', name: 'Iowa' }, - { abbreviation: 'KS', name: 'Kansas' }, - { abbreviation: 'KY', name: 'Kentucky' }, - { abbreviation: 'LA', name: 'Louisiana' }, - { abbreviation: 'ME', name: 'Maine' }, - { abbreviation: 'MD', name: 'Maryland' }, - { abbreviation: 'MA', name: 'Massachusetts' }, - { abbreviation: 'MI', name: 'Michigan' }, - { abbreviation: 'MN', name: 'Minnesota' }, - { abbreviation: 'MS', name: 'Mississippi' }, - { abbreviation: 'MO', name: 'Missouri' }, - { abbreviation: 'MT', name: 'Montana' }, - { abbreviation: 'NE', name: 'Nebraska' }, - { abbreviation: 'NV', name: 'Nevada' }, - { abbreviation: 'NH', name: 'New Hampshire' }, - { abbreviation: 'NJ', name: 'New Jersey' }, - { abbreviation: 'NM', name: 'New Mexico' }, - { abbreviation: 'NY', name: 'New York' }, - { abbreviation: 'NC', name: 'North Carolina' }, - { abbreviation: 'ND', name: 'North Dakota' }, - { abbreviation: 'OH', name: 'Ohio' }, - { abbreviation: 'OK', name: 'Oklahoma' }, - { abbreviation: 'OR', name: 'Oregon' }, - { abbreviation: 'PA', name: 'Pennsylvania' }, - { abbreviation: 'PR', name: 'Puerto Rico' }, - { abbreviation: 'RI', name: 'Rhode Island' }, - { abbreviation: 'SC', name: 'South Carolina' }, - { abbreviation: 'SD', name: 'South Dakota' }, - { abbreviation: 'TN', name: 'Tennessee' }, - { abbreviation: 'TX', name: 'Texas' }, - { abbreviation: 'UT', name: 'Utah' }, - { abbreviation: 'VT', name: 'Vermont' }, - { abbreviation: 'VA', name: 'Virginia' }, - { abbreviation: 'WA', name: 'Washington' }, - { abbreviation: 'WV', name: 'West Virginia' }, - { abbreviation: 'WI', name: 'Wisconsin' }, - { abbreviation: 'WY', name: 'Wyoming' }, -]; - -const CA_PROVINCES: State[] = [ - { name: 'Alberta', abbreviation: 'AB' }, - { name: 'British Columbia', abbreviation: 'BC' }, - { name: 'Manitoba', abbreviation: 'MB' }, - { name: 'New Brunswick', abbreviation: 'NB' }, - { name: 'Newfoundland and Labrador', abbreviation: 'NL' }, - { name: 'Northwest Territories', abbreviation: 'NT' }, - { name: 'Nova Scotia', abbreviation: 'NS' }, - { name: 'Nunavut', abbreviation: 'NU' }, - { name: 'Ontario', abbreviation: 'ON' }, - { name: 'Prince Edward Island', abbreviation: 'PE' }, - { name: 'Quebec', abbreviation: 'QC' }, - { name: 'Saskatchewan', abbreviation: 'SK' }, - { name: 'Yukon', abbreviation: 'YT' }, -]; - -type Country = { - abbreviation: string; - name: string; -}; - -const COUNTRIES: Country[] = [ - { abbreviation: 'CA', name: 'Canada' }, - { abbreviation: 'US', name: 'United States' }, -]; - -const mapCountryAbbreviationToStates: Record = { - CA: CA_PROVINCES, - US: USA_STATES, +const COUNTRY_TO_STATES: Record = { + CA: [ + { abbreviation: 'AB', name: 'Alberta' }, + { abbreviation: 'BC', name: 'British Columbia' }, + { abbreviation: 'MB', name: 'Manitoba' }, + { abbreviation: 'NB', name: 'New Brunswick' }, + { abbreviation: 'NL', name: 'Newfoundland and Labrador' }, + { abbreviation: 'NT', name: 'Northwest Territories' }, + { abbreviation: 'NS', name: 'Nova Scotia' }, + { abbreviation: 'NU', name: 'Nunavut' }, + { abbreviation: 'ON', name: 'Ontario' }, + { abbreviation: 'PE', name: 'Prince Edward Island' }, + { abbreviation: 'QC', name: 'Quebec' }, + { abbreviation: 'SK', name: 'Saskatchewan' }, + { abbreviation: 'YT', name: 'Yukon' }, + ], + + US: [ + { abbreviation: 'AL', name: 'Alabama' }, + { abbreviation: 'AK', name: 'Alaska' }, + { abbreviation: 'AZ', name: 'Arizona' }, + { abbreviation: 'AR', name: 'Arkansas' }, + { abbreviation: 'CA', name: 'California' }, + { abbreviation: 'CO', name: 'Colorado' }, + { abbreviation: 'CT', name: 'Connecticut' }, + { abbreviation: 'DE', name: 'Delaware' }, + { abbreviation: 'DC', name: 'District Of Columbia' }, + { abbreviation: 'FL', name: 'Florida' }, + { abbreviation: 'GA', name: 'Georgia' }, + { abbreviation: 'HI', name: 'Hawaii' }, + { abbreviation: 'ID', name: 'Idaho' }, + { abbreviation: 'IL', name: 'Illinois' }, + { abbreviation: 'IN', name: 'Indiana' }, + { abbreviation: 'IA', name: 'Iowa' }, + { abbreviation: 'KS', name: 'Kansas' }, + { abbreviation: 'KY', name: 'Kentucky' }, + { abbreviation: 'LA', name: 'Louisiana' }, + { abbreviation: 'ME', name: 'Maine' }, + { abbreviation: 'MD', name: 'Maryland' }, + { abbreviation: 'MA', name: 'Massachusetts' }, + { abbreviation: 'MI', name: 'Michigan' }, + { abbreviation: 'MN', name: 'Minnesota' }, + { abbreviation: 'MS', name: 'Mississippi' }, + { abbreviation: 'MO', name: 'Missouri' }, + { abbreviation: 'MT', name: 'Montana' }, + { abbreviation: 'NE', name: 'Nebraska' }, + { abbreviation: 'NV', name: 'Nevada' }, + { abbreviation: 'NH', name: 'New Hampshire' }, + { abbreviation: 'NJ', name: 'New Jersey' }, + { abbreviation: 'NM', name: 'New Mexico' }, + { abbreviation: 'NY', name: 'New York' }, + { abbreviation: 'NC', name: 'North Carolina' }, + { abbreviation: 'ND', name: 'North Dakota' }, + { abbreviation: 'OH', name: 'Ohio' }, + { abbreviation: 'OK', name: 'Oklahoma' }, + { abbreviation: 'OR', name: 'Oregon' }, + { abbreviation: 'PA', name: 'Pennsylvania' }, + { abbreviation: 'PR', name: 'Puerto Rico' }, + { abbreviation: 'RI', name: 'Rhode Island' }, + { abbreviation: 'SC', name: 'South Carolina' }, + { abbreviation: 'SD', name: 'South Dakota' }, + { abbreviation: 'TN', name: 'Tennessee' }, + { abbreviation: 'TX', name: 'Texas' }, + { abbreviation: 'UT', name: 'Utah' }, + { abbreviation: 'VT', name: 'Vermont' }, + { abbreviation: 'VA', name: 'Virginia' }, + { abbreviation: 'WA', name: 'Washington' }, + { abbreviation: 'WV', name: 'West Virginia' }, + { abbreviation: 'WI', name: 'Wisconsin' }, + { abbreviation: 'WY', name: 'Wyoming' }, + ], }; Address.State = function State(props: SelectProps) { - const { countryAbbreviation } = useContext(AddressContext); + const { country } = useContext(AddressContext); - const states = mapCountryAbbreviationToStates[countryAbbreviation]; + const states = COUNTRY_TO_STATES[country]; return ( ); }; - -Address.Country = function Country(props: SelectProps) { - const { setCountryAbbreviation } = useContext(AddressContext); - - return ( - - ); -}; diff --git a/packages/ui/src/components/form.tsx b/packages/ui/src/components/form.tsx index 47137915..41dbfbc9 100644 --- a/packages/ui/src/components/form.tsx +++ b/packages/ui/src/components/form.tsx @@ -9,7 +9,11 @@ import { zodErrorMap } from '../utils/zod'; export const Form = () => {}; Form.ErrorMessage = function FormErrorMessage({ children }: PropsWithChildren) { - return children ? {children} : null; + return children ? ( + + {children} + + ) : null; }; type FormFieldProps = { From d287930615effc14d3b9e7a9076fc3d27d595a21 Mon Sep 17 00:00:00 2001 From: Rami Abdou Date: Thu, 22 Aug 2024 14:57:12 -0700 Subject: [PATCH 7/7] use default value from context --- packages/ui/src/components/address.tsx | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/ui/src/components/address.tsx b/packages/ui/src/components/address.tsx index e4ff3f0c..1fa11554 100644 --- a/packages/ui/src/components/address.tsx +++ b/packages/ui/src/components/address.tsx @@ -40,14 +40,12 @@ const COUNTRIES: Country[] = [ { abbreviation: 'US', name: 'United States' }, ]; -const DEFAULT_COUNTRY: SupportedCountry = 'US'; - Address.Country = function Country(props: SelectProps) { - const { setCountry } = useContext(AddressContext); + const { country, setCountry } = useContext(AddressContext); return (