From e2cf89fa0408ffcc7b78f59653e72f8392040031 Mon Sep 17 00:00:00 2001 From: lytrankieio123 Date: Mon, 18 Oct 2021 16:17:05 +0700 Subject: [PATCH 01/27] enhance: link T&C, privacy --- .../CustomerInfoForm/CustomerInfoForm.tsx | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/components/modules/checkout/CheckoutInfo/components/CustomerInfoForm/CustomerInfoForm.tsx b/src/components/modules/checkout/CheckoutInfo/components/CustomerInfoForm/CustomerInfoForm.tsx index 5894683d7..7e4715986 100644 --- a/src/components/modules/checkout/CheckoutInfo/components/CustomerInfoForm/CustomerInfoForm.tsx +++ b/src/components/modules/checkout/CheckoutInfo/components/CustomerInfoForm/CustomerInfoForm.tsx @@ -2,6 +2,7 @@ import Link from 'next/link' import React, { useRef } from 'react' import { ButtonCommon, Inputcommon } from 'src/components/common' import InputCommon from 'src/components/common/InputCommon/InputCommon' +import { ROUTE } from 'src/utils/constanst.utils' import { CheckOutForm } from 'src/utils/types.utils' import s from './CustomerInfoForm.module.scss' interface CustomerInfoFormProps { @@ -31,14 +32,18 @@ const CustomerInfoForm = ({ id, onConfirm }: CustomerInfoFormProps) => {
By clicking continue you agree to Casper's{' '} { - - terms and conditions + + + terms and conditions + }{' '} and{' '} { - - privacy policy + + + privacy policy + } . From 28e0c8e4af051cd44848a79643bdbbe2332d3432 Mon Sep 17 00:00:00 2001 From: lytrankieio123 Date: Mon, 18 Oct 2021 16:22:41 +0700 Subject: [PATCH 02/27] :blue_book: docs: OrderState :%s --- src/utils/types.utils.ts | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/utils/types.utils.ts b/src/utils/types.utils.ts index 59243b80f..e3eee3e9d 100644 --- a/src/utils/types.utils.ts +++ b/src/utils/types.utils.ts @@ -62,3 +62,18 @@ export type PromiseWithKey = { promise: PromiseLike keyResult?: string, } + +// ref https://www.vendure.io/docs/typescript-api/orders/order-state/ +export type OrderState = | 'Created' + | 'AddingItems' + | 'ArrangingPayment' + | 'PaymentAuthorized' + | 'PaymentSettled' + | 'PartiallyShipped' + | 'Shipped' + | 'PartiallyDelivered' + | 'Delivered' + | 'Modifying' + | 'ArrangingAdditionalPayment' + | 'Cancelled' + From 8a2e06a0fa3b9e55216a65b386431837f011504f Mon Sep 17 00:00:00 2001 From: lytrankieio123 Date: Mon, 18 Oct 2021 17:38:08 +0700 Subject: [PATCH 03/27] :sparkles: feat: setCustomerForOrder :%s --- framework/vendure/schema.d.ts | 485 ++++++++++-------- .../mutations/set-customer-order-mutation.ts | 24 + package.json | 3 +- pages/checkout.tsx | 3 +- .../Layout/LayoutContent/LayoutContent.tsx | 1 - .../common/LayoutCheckout/LayoutCheckout.tsx | 19 +- .../common/MessageCommon/MessageCommon.tsx | 2 +- .../contexts/Message/MessageContext.tsx | 2 +- .../contexts/Message/MessageProvider.tsx | 7 +- .../hooks/cart/useGetActiveOrder.tsx | 1 - src/components/hooks/order/index.ts | 2 + .../hooks/order/useSetCustomerForOrder.tsx | 47 ++ .../CustomerInfoForm/CustomerInfoForm.tsx | 25 +- .../checkout/CheckoutPage/CheckoutPage.tsx | 5 + 14 files changed, 384 insertions(+), 242 deletions(-) create mode 100644 framework/vendure/utils/mutations/set-customer-order-mutation.ts create mode 100644 src/components/hooks/order/index.ts create mode 100644 src/components/hooks/order/useSetCustomerForOrder.tsx diff --git a/framework/vendure/schema.d.ts b/framework/vendure/schema.d.ts index cef42ff5d..baf37c7f3 100644 --- a/framework/vendure/schema.d.ts +++ b/framework/vendure/schema.d.ts @@ -306,9 +306,52 @@ export type MutationResetPasswordArgs = { password: Scalars['String'] } +export type ActiveOrderCustomerFragment = Pick & { + customer?: Maybe>; + lines: Array>; +}; + +export type SetCustomerForOrderMutationVariables = Exact<{ + input: CreateCustomerInput; +}>; + +export type SetCustomerForOrderMutation = { __typename?: 'Mutation' } & { + setCustomerForOrder: + | ({ __typename: 'ActiveOrderCustomerFragment' } & Pick) + | ({ __typename: 'AlreadyLoggedInError' } & Pick< + AlreadyLoggedInError, + 'errorCode' | 'message' + >) + | ({ __typename: 'EmailAddressConflictError' } & Pick< + EmailAddressConflictError, + 'errorCode' | 'message' + >) + | ({ __typename: 'NoActiveOrderError' } & Pick< + NoActiveOrderError, + 'errorCode' | 'message' + >) +} + +export type SetCustomerForOrderMutation = { __typename?: 'Mutation' } & { + setCustomerForOrder: + | ({ __typename: 'ActiveOrderCustomerFragment' } & Pick) + | ({ __typename: 'AlreadyLoggedInError' } & Pick< + AlreadyLoggedInError, + 'errorCode' | 'message' + >) + | ({ __typename: 'EmailAddressConflictError' } & Pick< + EmailAddressConflictError, + 'errorCode' | 'message' + >) + | ({ __typename: 'NoActiveOrderError' } & Pick< + NoActiveOrderError, + 'errorCode' | 'message' + >) +} + export type Address = Node & { updateCustomerAddress: - | { + | { __typename?: 'Address' id: Scalars['ID'] } @@ -1471,7 +1514,7 @@ export type CustomerListOptions = { export type Customer = Node & { updateCustomer: - | { + | { __typename?: 'Customer' id: Scalars['ID'] } @@ -1482,7 +1525,7 @@ export type Customer = Node & { title?: Maybe firstName: Scalars['String'] lastName: Scalars['String'] - phoneNumber?: Maybe + phoneNumber?: Maybe emailAddress: Scalars['String'] addresses?: Maybe> orders: OrderList @@ -3017,56 +3060,56 @@ export type CartFragment = { __typename?: 'Order' } & Pick< | 'totalWithTax' | 'currencyCode' > & { - customer?: Maybe<{ __typename?: 'Customer' } & Pick> - lines: Array< - { __typename?: 'OrderLine' } & Pick< - OrderLine, + customer?: Maybe<{ __typename?: 'Customer' } & Pick> + lines: Array< + { __typename?: 'OrderLine' } & Pick< + OrderLine, + | 'id' + | 'quantity' + | 'linePriceWithTax' + | 'discountedLinePriceWithTax' + | 'unitPriceWithTax' + | 'discountedUnitPriceWithTax' + > & { + featuredAsset?: Maybe< + { __typename?: 'Asset' } & Pick + > + discounts: Array< + { __typename?: 'Discount' } & Pick< + Discount, + 'description' | 'amount' + > + > + productVariant: { __typename?: 'ProductVariant' } & Pick< + ProductVariant, | 'id' - | 'quantity' - | 'linePriceWithTax' - | 'discountedLinePriceWithTax' - | 'unitPriceWithTax' - | 'discountedUnitPriceWithTax' - > & { - featuredAsset?: Maybe< - { __typename?: 'Asset' } & Pick - > - discounts: Array< - { __typename?: 'Discount' } & Pick< - Discount, - 'description' | 'amount' - > - > - productVariant: { __typename?: 'ProductVariant' } & Pick< - ProductVariant, - | 'id' - | 'name' - | 'sku' - | 'price' - | 'priceWithTax' - | 'stockLevel' - | 'productId' - > & { product: { __typename?: 'Product' } & Pick } - } - > - } + | 'name' + | 'sku' + | 'price' + | 'priceWithTax' + | 'stockLevel' + | 'productId' + > & { product: { __typename?: 'Product' } & Pick } + } + > +} export type SearchResultFragment = { __typename?: 'SearchResult' } & Pick< SearchResult, 'productId' | 'sku' | 'productName' | 'description' | 'slug' | 'sku' | 'currencyCode' - | 'productAsset' | 'price' | 'priceWithTax' | 'currencyCode' + | 'productAsset' | 'price' | 'priceWithTax' | 'currencyCode' | 'collectionIds' | 'productVariantId' | 'facetValueIds' | "productVariantName" > & { - productAsset?: Maybe< - { __typename?: 'SearchResultAsset' } & Pick< - SearchResultAsset, - 'id' | 'preview' - > + productAsset?: Maybe< + { __typename?: 'SearchResultAsset' } & Pick< + SearchResultAsset, + 'id' | 'preview' > - priceWithTax: - | ({ __typename?: 'PriceRange' } & Pick) - | ({ __typename?: 'SinglePrice' } & Pick) - } + > + priceWithTax: + | ({ __typename?: 'PriceRange' } & Pick) + | ({ __typename?: 'SinglePrice' } & Pick) +} export type AddItemToOrderMutationVariables = Exact<{ variantId: Scalars['ID'] @@ -3075,23 +3118,23 @@ export type AddItemToOrderMutationVariables = Exact<{ export type AddItemToOrderMutation = { __typename?: 'Mutation' } & { addItemToOrder: - | ({ __typename: 'Order' } & CartFragment) - | ({ __typename: 'OrderModificationError' } & Pick< - OrderModificationError, - 'errorCode' | 'message' - >) - | ({ __typename: 'OrderLimitError' } & Pick< - OrderLimitError, - 'errorCode' | 'message' - >) - | ({ __typename: 'NegativeQuantityError' } & Pick< - NegativeQuantityError, - 'errorCode' | 'message' - >) - | ({ __typename: 'InsufficientStockError' } & Pick< - InsufficientStockError, - 'errorCode' | 'message' - >) + | ({ __typename: 'Order' } & CartFragment) + | ({ __typename: 'OrderModificationError' } & Pick< + OrderModificationError, + 'errorCode' | 'message' + >) + | ({ __typename: 'OrderLimitError' } & Pick< + OrderLimitError, + 'errorCode' | 'message' + >) + | ({ __typename: 'NegativeQuantityError' } & Pick< + NegativeQuantityError, + 'errorCode' | 'message' + >) + | ({ __typename: 'InsufficientStockError' } & Pick< + InsufficientStockError, + 'errorCode' | 'message' + >) } export type AdjustOrderLineMutationVariables = Exact<{ @@ -3101,23 +3144,23 @@ export type AdjustOrderLineMutationVariables = Exact<{ export type AdjustOrderLineMutation = { __typename?: 'Mutation' } & { adjustOrderLine: - | ({ __typename: 'Order' } & CartFragment) - | ({ __typename: 'OrderModificationError' } & Pick< - OrderModificationError, - 'errorCode' | 'message' - >) - | ({ __typename: 'OrderLimitError' } & Pick< - OrderLimitError, - 'errorCode' | 'message' - >) - | ({ __typename: 'NegativeQuantityError' } & Pick< - NegativeQuantityError, - 'errorCode' | 'message' - >) - | ({ __typename: 'InsufficientStockError' } & Pick< - InsufficientStockError, - 'errorCode' | 'message' - >) + | ({ __typename: 'Order' } & CartFragment) + | ({ __typename: 'OrderModificationError' } & Pick< + OrderModificationError, + 'errorCode' | 'message' + >) + | ({ __typename: 'OrderLimitError' } & Pick< + OrderLimitError, + 'errorCode' | 'message' + >) + | ({ __typename: 'NegativeQuantityError' } & Pick< + NegativeQuantityError, + 'errorCode' | 'message' + >) + | ({ __typename: 'InsufficientStockError' } & Pick< + InsufficientStockError, + 'errorCode' | 'message' + >) } export type LoginMutationVariables = Exact<{ @@ -3127,49 +3170,49 @@ export type LoginMutationVariables = Exact<{ export type LoginMutation = { __typename?: 'Mutation' } & { login: - | ({ __typename: 'CurrentUser' } & Pick) - | ({ __typename: 'InvalidCredentialsError' } & Pick< - InvalidCredentialsError, - 'errorCode' | 'message' - >) - | ({ __typename: 'NotVerifiedError' } & Pick< - NotVerifiedError, - 'errorCode' | 'message' - >) - | ({ __typename: 'NativeAuthStrategyError' } & Pick< - NativeAuthStrategyError, - 'errorCode' | 'message' - >) + | ({ __typename: 'CurrentUser' } & Pick) + | ({ __typename: 'InvalidCredentialsError' } & Pick< + InvalidCredentialsError, + 'errorCode' | 'message' + >) + | ({ __typename: 'NotVerifiedError' } & Pick< + NotVerifiedError, + 'errorCode' | 'message' + >) + | ({ __typename: 'NativeAuthStrategyError' } & Pick< + NativeAuthStrategyError, + 'errorCode' | 'message' + >) } export type ResetPasswordMutation = { __typename?: 'Mutation' } & { resetPassword: - | ({ __typename: 'CurrentUser' } & Pick) - | ({ __typename: 'PasswordResetTokenInvalidError' } & Pick< - PasswordResetTokenInvalidError, - 'errorCode' | 'message' - >) - | ({ __typename: 'PasswordResetTokenExpiredError' } & Pick< - PasswordResetTokenExpiredError, - 'errorCode' | 'message' - >) - | ({ __typename: 'NativeAuthStrategyError' } & Pick< - NativeAuthStrategyError, - 'errorCode' | 'message' - >) + | ({ __typename: 'CurrentUser' } & Pick) + | ({ __typename: 'PasswordResetTokenInvalidError' } & Pick< + PasswordResetTokenInvalidError, + 'errorCode' | 'message' + >) + | ({ __typename: 'PasswordResetTokenExpiredError' } & Pick< + PasswordResetTokenExpiredError, + 'errorCode' | 'message' + >) + | ({ __typename: 'NativeAuthStrategyError' } & Pick< + NativeAuthStrategyError, + 'errorCode' | 'message' + >) } export type SignupMutation = { __typename?: 'Mutation' } & { registerCustomerAccount: - | ({ __typename: 'Success' } & Pick) - | ({ __typename: 'MissingPasswordError' } & Pick< - MissingPasswordError, - 'errorCode' | 'message' - >) - | ({ __typename: 'NativeAuthStrategyError' } & Pick< - NativeAuthStrategyError, - 'errorCode' | 'message' - >) + | ({ __typename: 'Success' } & Pick) + | ({ __typename: 'MissingPasswordError' } & Pick< + MissingPasswordError, + 'errorCode' | 'message' + >) + | ({ __typename: 'NativeAuthStrategyError' } & Pick< + NativeAuthStrategyError, + 'errorCode' | 'message' + >) } export type VerifyCustomerAccountVariables = Exact<{ @@ -3179,27 +3222,27 @@ export type VerifyCustomerAccountVariables = Exact<{ export type VerifyCustomerAccountMutation = { __typename?: 'Mutation' } & { verifyCustomerAccount: - | ({ __typename: 'CurrentUser' } & Pick) - | ({ __typename: 'VerificationTokenInvalidError' } & Pick< - VerificationTokenInvalidError, - 'errorCode' | 'message' - >) - | ({ __typename: 'VerificationTokenExpiredError' } & Pick< - VerificationTokenExpiredError, - 'errorCode' | 'message' - >) - | ({ __typename: 'MissingPasswordError' } & Pick< - MissingPasswordError, - 'errorCode' | 'message' - >) - | ({ __typename: 'PasswordAlreadySetError' } & Pick< - PasswordAlreadySetError, - 'errorCode' | 'message' - >) - | ({ __typename: 'NativeAuthStrategyError' } & Pick< - NativeAuthStrategyError, - 'errorCode' | 'message' - >) + | ({ __typename: 'CurrentUser' } & Pick) + | ({ __typename: 'VerificationTokenInvalidError' } & Pick< + VerificationTokenInvalidError, + 'errorCode' | 'message' + >) + | ({ __typename: 'VerificationTokenExpiredError' } & Pick< + VerificationTokenExpiredError, + 'errorCode' | 'message' + >) + | ({ __typename: 'MissingPasswordError' } & Pick< + MissingPasswordError, + 'errorCode' | 'message' + >) + | ({ __typename: 'PasswordAlreadySetError' } & Pick< + PasswordAlreadySetError, + 'errorCode' | 'message' + >) + | ({ __typename: 'NativeAuthStrategyError' } & Pick< + NativeAuthStrategyError, + 'errorCode' | 'message' + >) } export type LogoutMutationVariables = Exact<{ [key: string]: never }> @@ -3214,11 +3257,11 @@ export type RemoveOrderLineMutationVariables = Exact<{ export type RemoveOrderLineMutation = { __typename?: 'Mutation' } & { removeOrderLine: - | ({ __typename: 'Order' } & CartFragment) - | ({ __typename: 'OrderModificationError' } & Pick< - OrderModificationError, - 'errorCode' | 'message' - >) + | ({ __typename: 'Order' } & CartFragment) + | ({ __typename: 'OrderModificationError' } & Pick< + OrderModificationError, + 'errorCode' | 'message' + >) } export type SignupMutationVariables = Exact<{ @@ -3228,15 +3271,15 @@ export type SignupMutationVariables = Exact<{ export type RequestPasswordReset = { __typename?: 'Mutation' } & { requestPasswordReset: - | ({ __typename: 'Success' } & Pick) - | ({ __typename: 'MissingPasswordError' } & Pick< - MissingPasswordError, - 'errorCode' | 'message' - >) - | ({ __typename: 'NativeAuthStrategyError' } & Pick< - NativeAuthStrategyError, - 'errorCode' | 'message' - >) + | ({ __typename: 'Success' } & Pick) + | ({ __typename: 'MissingPasswordError' } & Pick< + MissingPasswordError, + 'errorCode' | 'message' + >) + | ({ __typename: 'NativeAuthStrategyError' } & Pick< + NativeAuthStrategyError, + 'errorCode' | 'message' + >) } @@ -3248,7 +3291,7 @@ export type ActiveCustomerQuery = { __typename?: 'Query' } & { { __typename?: 'Customer' } & Pick< Customer, Favorite, - 'id' | 'firstName' | 'lastName' | 'emailAddress' | 'addresses' | 'phoneNumber'| 'orders' + 'id' | 'firstName' | 'lastName' | 'emailAddress' | 'addresses' | 'phoneNumber' | 'orders' > > } @@ -3267,7 +3310,7 @@ export type FavoriteList = PaginatedList & { totalItems: Int! } -type Favorite = Node & { +type Favorite = Node & { id: ID! createdAt: DateTime! updatedAt: DateTime! @@ -3277,7 +3320,7 @@ type Favorite = Node & { -type FavouriteOption = Customer & { +type FavouriteOption = Customer & { favorites(options: FavoriteListOptions): FavoriteList! } @@ -3308,13 +3351,13 @@ export type GetAllFacetsQuery = { __typename?: 'Query' } & { { __typename?: 'Facet' } & Pick< Facet, 'id' | 'name' | 'code' | 'values' - > + > & { - parent?: Maybe<{ __typename?: 'Facet' } & Pick> - children?: Maybe< - Array<{ __typename?: 'Facet' } & Pick> - > - } + parent?: Maybe<{ __typename?: 'Facet' } & Pick> + children?: Maybe< + Array<{ __typename?: 'Facet' } & Pick> + > + } >, 'totalItems' } @@ -3327,11 +3370,11 @@ export type GetAllCollectionsQuery = { __typename?: 'Query' } & { Collection, 'id' | 'name' | 'slug' > & { - parent?: Maybe<{ __typename?: 'Collection' } & Pick> - children?: Maybe< - Array<{ __typename?: 'Collection' } & Pick> - > - } + parent?: Maybe<{ __typename?: 'Collection' } & Pick> + children?: Maybe< + Array<{ __typename?: 'Collection' } & Pick> + > + } >, 'totalItems' } @@ -3352,15 +3395,15 @@ export type GetCollectionsQuery = { __typename?: 'Query' } & { Collection, 'id' | 'name' | 'description' | 'slug' > & { - productVariants: { __typename?: 'ProductVariantList' } & Pick< - ProductVariantList, - 'totalItems' - > - parent?: Maybe<{ __typename?: 'Collection' } & Pick> - children?: Maybe< - Array<{ __typename?: 'Collection' } & Pick> - > - } + productVariants: { __typename?: 'ProductVariantList' } & Pick< + ProductVariantList, + 'totalItems' + > + parent?: Maybe<{ __typename?: 'Collection' } & Pick> + children?: Maybe< + Array<{ __typename?: 'Collection' } & Pick> + > + } > } } @@ -3375,60 +3418,60 @@ export type GetProductQuery = { __typename?: 'Query' } & { Product, 'id' | 'name' | 'slug' | 'description' > & { - assets: Array< - { __typename?: 'Asset' } & Pick - > - variants: Array< - { __typename?: 'ProductVariant' } & Pick< - ProductVariant, - 'id' | 'priceWithTax' | 'currencyCode' | 'price' | "name" - > & { - options: Array< - { __typename?: 'ProductOption' } & Pick< - ProductOption, - 'id' | 'name' | 'code' | 'groupId' - > & { - group: { __typename?: 'ProductOptionGroup' } & Pick< - ProductOptionGroup, - 'id' - > & { - options: Array< - { __typename?: 'ProductOption' } & Pick< - ProductOption, - 'name' - > - > - } - } - > - } - > - optionGroups: Array< - { __typename?: 'ProductOptionGroup' } & Pick< - ProductOptionGroup, - 'id' | 'code' | 'name' - > & { - options: Array< - { __typename?: 'ProductOption' } & Pick< - ProductOption, - 'id' | 'name' + assets: Array< + { __typename?: 'Asset' } & Pick + > + variants: Array< + { __typename?: 'ProductVariant' } & Pick< + ProductVariant, + 'id' | 'priceWithTax' | 'currencyCode' | 'price' | "name" + > & { + options: Array< + { __typename?: 'ProductOption' } & Pick< + ProductOption, + 'id' | 'name' | 'code' | 'groupId' + > & { + group: { __typename?: 'ProductOptionGroup' } & Pick< + ProductOptionGroup, + 'id' + > & { + options: Array< + { __typename?: 'ProductOption' } & Pick< + ProductOption, + 'name' + > > - > + } } - > - facetValues: Array< - { __typename?: 'FacetValue' } & Pick< - FacetValue, - 'id' > - > - collections: Array< - { __typename?: 'Collection' } & Pick< - Collection, - 'id'|"name" + } + > + optionGroups: Array< + { __typename?: 'ProductOptionGroup' } & Pick< + ProductOptionGroup, + 'id' | 'code' | 'name' + > & { + options: Array< + { __typename?: 'ProductOption' } & Pick< + ProductOption, + 'id' | 'name' + > > + } + > + facetValues: Array< + { __typename?: 'FacetValue' } & Pick< + FacetValue, + 'id' > - } + > + collections: Array< + { __typename?: 'Collection' } & Pick< + Collection, + 'id' | "name" + > + > + } > } diff --git a/framework/vendure/utils/mutations/set-customer-order-mutation.ts b/framework/vendure/utils/mutations/set-customer-order-mutation.ts new file mode 100644 index 000000000..d4face1e9 --- /dev/null +++ b/framework/vendure/utils/mutations/set-customer-order-mutation.ts @@ -0,0 +1,24 @@ +export const setCustomerForOrderMutation = /* GraphQL */ ` +mutation setCustomerForOrder($input: CreateCustomerInput!) { + setCustomerForOrder(input: $input) { + __typename + ... on Order { + id + createdAt + updatedAt + code + customer { + id + firstName + lastName + emailAddress + phoneNumber + } + } + ... on ErrorResult { + errorCode + message + } + } +} +` diff --git a/package.json b/package.json index 8474be667..6db6e1de1 100644 --- a/package.json +++ b/package.json @@ -2,8 +2,9 @@ "name": "nextjs-commerce", "version": "1.0.0", "scripts": { - "dev": "NODE_OPTIONS='--inspect' PORT=3005 next dev", + "dev": "set NODE_OPTIONS='--inspect' && set PORT=3005 && next dev", "dev-windows": "set NODE_OPTIONS='--inspect' && set PORT=3005 && next dev", + "dev-macos": "set NODE_OPTIONS='--inspect' && set PORT=3005 && next dev", "build": "next build", "start": "PORT=3005 next start", "analyze": "BUNDLE_ANALYZE=both yarn build", diff --git a/pages/checkout.tsx b/pages/checkout.tsx index ae502f0e9..860f04bc1 100644 --- a/pages/checkout.tsx +++ b/pages/checkout.tsx @@ -4,7 +4,8 @@ import { CheckoutPage } from 'src/components/modules/checkout'; export default function Checkout() { return ( <> - + + ) } diff --git a/src/components/common/Layout/LayoutContent/LayoutContent.tsx b/src/components/common/Layout/LayoutContent/LayoutContent.tsx index 7bfddafe7..87a224366 100644 --- a/src/components/common/Layout/LayoutContent/LayoutContent.tsx +++ b/src/components/common/Layout/LayoutContent/LayoutContent.tsx @@ -1,7 +1,6 @@ import { useRouter } from 'next/router' import { FC } from 'react' import { useMessage } from 'src/components/contexts' -import { useModalCommon } from 'src/components/hooks' import { FILTER_PAGE, ROUTE } from 'src/utils/constanst.utils' import { CartDrawer, Footer, MessageCommon, ScrollToTop } from '../..' import Header from '../../Header/Header' diff --git a/src/components/common/LayoutCheckout/LayoutCheckout.tsx b/src/components/common/LayoutCheckout/LayoutCheckout.tsx index 06c632418..68490c87a 100644 --- a/src/components/common/LayoutCheckout/LayoutCheckout.tsx +++ b/src/components/common/LayoutCheckout/LayoutCheckout.tsx @@ -1,3 +1,4 @@ +import { MessageProvider } from 'src/components/contexts' import s from './LayoutCheckout.module.scss' interface Props { @@ -6,14 +7,18 @@ interface Props { const LayoutCheckout = ({ children }: Props) => { return ( -
-
{children}
-
-
- © 2021 Online Grocery + <> + +
+
{children}
+
+
+ © 2021 Online Grocery +
+
-
-
+ + ) } diff --git a/src/components/common/MessageCommon/MessageCommon.tsx b/src/components/common/MessageCommon/MessageCommon.tsx index f15f8f443..16040d963 100644 --- a/src/components/common/MessageCommon/MessageCommon.tsx +++ b/src/components/common/MessageCommon/MessageCommon.tsx @@ -1,4 +1,4 @@ -import React, { memo, useEffect } from 'react' +import React, { memo } from 'react' import s from './MessageCommon.module.scss' import MessageItem, { MessageItemProps } from './MessageItem/MessageItem' diff --git a/src/components/contexts/Message/MessageContext.tsx b/src/components/contexts/Message/MessageContext.tsx index f9399498e..fef8497c0 100644 --- a/src/components/contexts/Message/MessageContext.tsx +++ b/src/components/contexts/Message/MessageContext.tsx @@ -6,7 +6,7 @@ export type MessageContextType = { removeMessage: (id: number) => void showMessageSuccess: (content: string, timeout?: number) => void showMessageInfo: (content: string, timeout?: number) => void - showMessageError: (content: string, timeout?: number) => void + showMessageError: (content?: string, timeout?: number) => void showMessageWarning: (content: string, timeout?: number) => void } export const DEFAULT_MESSAGE_CONTEXT: MessageContextType = { diff --git a/src/components/contexts/Message/MessageProvider.tsx b/src/components/contexts/Message/MessageProvider.tsx index 0ccde8609..bf2706f5e 100644 --- a/src/components/contexts/Message/MessageProvider.tsx +++ b/src/components/contexts/Message/MessageProvider.tsx @@ -1,5 +1,6 @@ -import { ReactNode, useCallback, useState } from 'react' +import { ReactNode, useState } from 'react' import { MessageItemProps } from 'src/components/common/MessageCommon/MessageItem/MessageItem' +import { LANGUAGE } from 'src/utils/language.utils' import { MessageContext } from './MessageContext' type Props = { @@ -33,8 +34,8 @@ export function MessageProvider({ children }: Props) { createNewMessage(content, timeout, 'info') } - const showMessageError = (content: string, timeout?: number) => { - createNewMessage(content, timeout, 'error') + const showMessageError = (content?: string, timeout?: number) => { + createNewMessage(content || LANGUAGE.MESSAGE.ERROR, timeout, 'error') } const showMessageWarning = (content: string, timeout?: number) => { diff --git a/src/components/hooks/cart/useGetActiveOrder.tsx b/src/components/hooks/cart/useGetActiveOrder.tsx index 4c26a1786..c8898c222 100644 --- a/src/components/hooks/cart/useGetActiveOrder.tsx +++ b/src/components/hooks/cart/useGetActiveOrder.tsx @@ -1,4 +1,3 @@ -import { Cart } from '@commerce/types/cart' import { ActiveOrderQuery } from '@framework/schema' import { cartFragment } from '@framework/utils/fragments/cart-fragment' import { normalizeCart } from '@framework/utils/normalize' diff --git a/src/components/hooks/order/index.ts b/src/components/hooks/order/index.ts new file mode 100644 index 000000000..f644f7917 --- /dev/null +++ b/src/components/hooks/order/index.ts @@ -0,0 +1,2 @@ +export { default as useSetCustomerForOrder } from './useSetCustomerForOrder' + diff --git a/src/components/hooks/order/useSetCustomerForOrder.tsx b/src/components/hooks/order/useSetCustomerForOrder.tsx new file mode 100644 index 000000000..521c72be2 --- /dev/null +++ b/src/components/hooks/order/useSetCustomerForOrder.tsx @@ -0,0 +1,47 @@ +import { CreateCustomerInput, SetCustomerForOrderMutation } from '@framework/schema' +import { setCustomerForOrderMutation } from '@framework/utils/mutations/set-customer-order-mutation' +import { useState } from 'react' +import { CommonError } from 'src/domains/interfaces/CommonError' +import rawFetcher from 'src/utils/rawFetcher' +import { useGetActiveOrder } from '../cart' + + +const useSetCustomerForOrder = () => { + const [loading, setLoading] = useState(false) + const [error, setError] = useState(null) + const { mutate } = useGetActiveOrder() + + const setCustomerForOrder = (input: CreateCustomerInput, + fCallBack: (isSuccess: boolean, message?: string) => void + ) => { + setError(null) + setLoading(true) + rawFetcher({ + query: setCustomerForOrderMutation, + variables: {input}, + }) + .then(({ data, headers }) => { + console.log("data here: ", data) + if (data.setCustomerForOrder.__typename === 'ActiveOrderCustomerFragment') { + console.log("success: ") + + fCallBack(true) + mutate() + } else { + console.log("fail ") + + fCallBack(false, data.setCustomerForOrder.message) + } + + }) + .catch((error) => { + setError(error) + fCallBack(false, error.message) + }) + .finally(() => setLoading(false)) + } + + return { loading, setCustomerForOrder, error } +} + +export default useSetCustomerForOrder diff --git a/src/components/modules/checkout/CheckoutInfo/components/CustomerInfoForm/CustomerInfoForm.tsx b/src/components/modules/checkout/CheckoutInfo/components/CustomerInfoForm/CustomerInfoForm.tsx index 7e4715986..50c19fa30 100644 --- a/src/components/modules/checkout/CheckoutInfo/components/CustomerInfoForm/CustomerInfoForm.tsx +++ b/src/components/modules/checkout/CheckoutInfo/components/CustomerInfoForm/CustomerInfoForm.tsx @@ -2,6 +2,8 @@ import Link from 'next/link' import React, { useRef } from 'react' import { ButtonCommon, Inputcommon } from 'src/components/common' import InputCommon from 'src/components/common/InputCommon/InputCommon' +import { useMessage } from 'src/components/contexts' +import { useSetCustomerForOrder } from 'src/components/hooks/order' import { ROUTE } from 'src/utils/constanst.utils' import { CheckOutForm } from 'src/utils/types.utils' import s from './CustomerInfoForm.module.scss' @@ -13,13 +15,26 @@ interface CustomerInfoFormProps { const CustomerInfoForm = ({ id, onConfirm }: CustomerInfoFormProps) => { const nameRef = useRef>(null) const emailRef = useRef>(null) + const { setCustomerForOrder, loading } = useSetCustomerForOrder() + const { showMessageError } = useMessage() const handleConfirmClick = () => { - onConfirm && - onConfirm(id, { - name: nameRef?.current?.getValue().toString(), - email: emailRef.current?.getValue().toString(), - }) + setCustomerForOrder({ firstName: 'Ly', lastName: 'Tran', emailAddress: 'test7@gmail.com' }, onSubmitCalBack) + // onConfirm && + // onConfirm(id, { + // name: nameRef?.current?.getValue().toString(), + // email: emailRef.current?.getValue().toString(), + // }) + } + const onSubmitCalBack = (isSuccess: boolean, msg?: string) => { + // TODO: + if (isSuccess) { + + } else { + console.log("error here") + showMessageError(msg) + } + } return ( diff --git a/src/components/modules/checkout/CheckoutPage/CheckoutPage.tsx b/src/components/modules/checkout/CheckoutPage/CheckoutPage.tsx index 8cfcc31f3..4755d329e 100644 --- a/src/components/modules/checkout/CheckoutPage/CheckoutPage.tsx +++ b/src/components/modules/checkout/CheckoutPage/CheckoutPage.tsx @@ -1,5 +1,7 @@ import classNames from 'classnames' import React, { useState } from 'react' +import { MessageCommon } from 'src/components/common' +import { useMessage } from 'src/components/contexts' import IconHide from 'src/components/icons/IconHide' import { CHECKOUT_BILL_DATA } from 'src/utils/demo-data' import { CheckoutBill, CheckoutInfo } from '..' @@ -8,7 +10,9 @@ interface CheckoutPageProps { } const CheckoutPage = ({}: CheckoutPageProps) => { + const { messages, removeMessage } = useMessage() const [isShow, setIsShow] = useState(false) + const onClose = () => { setIsShow(false) } @@ -17,6 +21,7 @@ const CheckoutPage = ({}: CheckoutPageProps) => { } return (
+
From 2667facd98b80d4e6832ddce5df437b531816774 Mon Sep 17 00:00:00 2001 From: lytrankieio123 Date: Mon, 18 Oct 2021 19:52:22 +0700 Subject: [PATCH 04/27] :sparkles: feat: (checkout) fill out customer info in order :%s --- .../components/FormLogin/FormLogin.tsx | 8 +- .../ChekoutNotePolicy.module.scss | 6 + .../ChekoutNotePolicy/ChekoutNotePolicy.tsx | 31 +++++ .../CustomerInfoForm.module.scss | 7 - .../CustomerInfoForm/CustomerInfoForm.tsx | 130 ++++++++++++------ src/styles/_utilities.scss | 2 +- src/utils/language.utils.ts | 5 +- 7 files changed, 132 insertions(+), 57 deletions(-) create mode 100644 src/components/modules/checkout/CheckoutInfo/components/ChekoutNotePolicy/ChekoutNotePolicy.module.scss create mode 100644 src/components/modules/checkout/CheckoutInfo/components/ChekoutNotePolicy/ChekoutNotePolicy.tsx diff --git a/src/components/common/ModalAuthenticate/components/FormLogin/FormLogin.tsx b/src/components/common/ModalAuthenticate/components/FormLogin/FormLogin.tsx index 279137a84..3f4ac6816 100644 --- a/src/components/common/ModalAuthenticate/components/FormLogin/FormLogin.tsx +++ b/src/components/common/ModalAuthenticate/components/FormLogin/FormLogin.tsx @@ -17,11 +17,11 @@ interface Props { onSwitch: () => void } -const DisplayingErrorMessagesSchema = Yup.object().shape({ - email: Yup.string().email('Your email was wrong').required('Required'), +const displayingErrorMessagesSchema = Yup.object().shape({ + email: Yup.string().email(LANGUAGE.MESSAGE.INVALID_EMAIL).required(LANGUAGE.MESSAGE.REQUIRED), password: Yup.string() .max(30, 'Password is too long') - .required('Required'), + .required(LANGUAGE.MESSAGE.REQUIRED), }) const FormLogin = ({ onSwitch, isHide }: Props) => { @@ -56,7 +56,7 @@ const FormLogin = ({ onSwitch, isHide }: Props) => { password: '', email: '', }} - validationSchema={DisplayingErrorMessagesSchema} + validationSchema={displayingErrorMessagesSchema} onSubmit={onLogin} > diff --git a/src/components/modules/checkout/CheckoutInfo/components/ChekoutNotePolicy/ChekoutNotePolicy.module.scss b/src/components/modules/checkout/CheckoutInfo/components/ChekoutNotePolicy/ChekoutNotePolicy.module.scss new file mode 100644 index 000000000..83f678cf2 --- /dev/null +++ b/src/components/modules/checkout/CheckoutInfo/components/ChekoutNotePolicy/ChekoutNotePolicy.module.scss @@ -0,0 +1,6 @@ +@import "../../../../../../styles/utilities"; + +.chekoutNotePolicy { + @apply caption; + margin-bottom: 1.6rem; +} diff --git a/src/components/modules/checkout/CheckoutInfo/components/ChekoutNotePolicy/ChekoutNotePolicy.tsx b/src/components/modules/checkout/CheckoutInfo/components/ChekoutNotePolicy/ChekoutNotePolicy.tsx new file mode 100644 index 000000000..9c988ae03 --- /dev/null +++ b/src/components/modules/checkout/CheckoutInfo/components/ChekoutNotePolicy/ChekoutNotePolicy.tsx @@ -0,0 +1,31 @@ +import Link from 'next/link' +import React, { memo } from 'react' +import { ROUTE } from 'src/utils/constanst.utils' +import s from './ChekoutNotePolicy.module.scss' + +const ChekoutNotePolicy = memo(() => { + return ( +
+ By clicking continue you agree to Casper's{' '} + { + + + terms and conditions + + + }{' '} + and{' '} + { + + + privacy policy + + + } + . +
+ ) +}) + +ChekoutNotePolicy.displayName = 'ChekoutNotePolicy' +export default ChekoutNotePolicy diff --git a/src/components/modules/checkout/CheckoutInfo/components/CustomerInfoForm/CustomerInfoForm.module.scss b/src/components/modules/checkout/CheckoutInfo/components/CustomerInfoForm/CustomerInfoForm.module.scss index 863a716b8..10dd6ec36 100644 --- a/src/components/modules/checkout/CheckoutInfo/components/CustomerInfoForm/CustomerInfoForm.module.scss +++ b/src/components/modules/checkout/CheckoutInfo/components/CustomerInfoForm/CustomerInfoForm.module.scss @@ -10,15 +10,8 @@ .bottom{ margin-top: 2.4rem; @apply flex justify-between items-center; - .note{ - font-size: 1.2rem; - line-height: 2rem; - } @screen sm-only { @apply flex-col items-start; - .button { - padding-top: 2rem; - } } } diff --git a/src/components/modules/checkout/CheckoutInfo/components/CustomerInfoForm/CustomerInfoForm.tsx b/src/components/modules/checkout/CheckoutInfo/components/CustomerInfoForm/CustomerInfoForm.tsx index 50c19fa30..8df2ab1fb 100644 --- a/src/components/modules/checkout/CheckoutInfo/components/CustomerInfoForm/CustomerInfoForm.tsx +++ b/src/components/modules/checkout/CheckoutInfo/components/CustomerInfoForm/CustomerInfoForm.tsx @@ -1,25 +1,34 @@ -import Link from 'next/link' +import { Form, Formik } from 'formik' import React, { useRef } from 'react' -import { ButtonCommon, Inputcommon } from 'src/components/common' -import InputCommon from 'src/components/common/InputCommon/InputCommon' +import { ButtonCommon, InputFiledInForm } from 'src/components/common' import { useMessage } from 'src/components/contexts' import { useSetCustomerForOrder } from 'src/components/hooks/order' -import { ROUTE } from 'src/utils/constanst.utils' -import { CheckOutForm } from 'src/utils/types.utils' +import { LANGUAGE } from 'src/utils/language.utils' +import { CustomInputCommon } from 'src/utils/type.utils' +import * as Yup from 'yup' +import ChekoutNotePolicy from '../ChekoutNotePolicy/ChekoutNotePolicy' import s from './CustomerInfoForm.module.scss' -interface CustomerInfoFormProps { - onConfirm?: (id: number, formInfo: CheckOutForm) => void - id: number +interface Props { + isHide: boolean + onSwitch: () => void } -const CustomerInfoForm = ({ id, onConfirm }: CustomerInfoFormProps) => { - const nameRef = useRef>(null) - const emailRef = useRef>(null) +const displayingErrorMessagesSchema = Yup.object().shape({ + firstName: Yup.string().required(LANGUAGE.MESSAGE.REQUIRED), + lastName: Yup.string().required(LANGUAGE.MESSAGE.REQUIRED), + emailAddress: Yup.string().email(LANGUAGE.MESSAGE.INVALID_EMAIL).required(LANGUAGE.MESSAGE.REQUIRED), +}) + +const CustomerInfoForm = ({ onSwitch, isHide }: Props) => { + const firstNameRef = useRef(null) + const emailRef = useRef(null) const { setCustomerForOrder, loading } = useSetCustomerForOrder() const { showMessageError } = useMessage() - const handleConfirmClick = () => { - setCustomerForOrder({ firstName: 'Ly', lastName: 'Tran', emailAddress: 'test7@gmail.com' }, onSubmitCalBack) + const handleSubmit = (values: { firstName: string, lastName: string, emailAddress: string }) => { + console.log('on submit: ', values) + const { firstName, lastName, emailAddress } = values + setCustomerForOrder({ firstName, lastName, emailAddress }, onSubmitCalBack) // onConfirm && // onConfirm(id, { // name: nameRef?.current?.getValue().toString(), @@ -28,8 +37,9 @@ const CustomerInfoForm = ({ id, onConfirm }: CustomerInfoFormProps) => { } const onSubmitCalBack = (isSuccess: boolean, msg?: string) => { // TODO: + console.log("result: ", isSuccess, msg) if (isSuccess) { - + } else { console.log("error here") showMessageError(msg) @@ -38,38 +48,70 @@ const CustomerInfoForm = ({ id, onConfirm }: CustomerInfoFormProps) => { } return ( -
+
- - + + {({ errors, touched, isValid, submitForm }) => ( +
+
+
+ + + +
+ +
+
+ + + Continue to Shipping + +
+
+ )} +
-
-
- By clicking continue you agree to Casper's{' '} - { - - - terms and conditions - - - }{' '} - and{' '} - { - - - privacy policy - - - } - . -
-
- - Continue to Shipping - -
-
-
+ ) } diff --git a/src/styles/_utilities.scss b/src/styles/_utilities.scss index af566560a..570c1069d 100644 --- a/src/styles/_utilities.scss +++ b/src/styles/_utilities.scss @@ -201,7 +201,7 @@ } } .line { - @apply flex justify-between items-center; + @apply flex justify-between items-start; > div { flex: 1; &:not(:last-child) { diff --git a/src/utils/language.utils.ts b/src/utils/language.utils.ts index 921c29435..2005f900d 100644 --- a/src/utils/language.utils.ts +++ b/src/utils/language.utils.ts @@ -11,6 +11,9 @@ export const LANGUAGE = { SEARCH: 'Search', }, MESSAGE: { - ERROR: 'Something went wrong! Please try again!' + ERROR: 'Something went wrong! Please try again!', + INVALID_EMAIL: 'Your email was wrong', + REQUIRED: 'Required', + } } \ No newline at end of file From ae8bb2840287f1aab64f867cb9900d58c5a468ff Mon Sep 17 00:00:00 2001 From: lytrankieio123 Date: Tue, 19 Oct 2021 11:07:47 +0700 Subject: [PATCH 05/27] :wrench: config: cookie :%s --- .../hooks/order/useSetCustomerForOrder.tsx | 9 ++------ .../ShippingInfoForm/ShippingInfoForm.tsx | 2 ++ src/utils/fetcher.ts | 12 ++++++---- src/utils/rawFetcher.ts | 22 +++++++++++-------- 4 files changed, 25 insertions(+), 20 deletions(-) diff --git a/src/components/hooks/order/useSetCustomerForOrder.tsx b/src/components/hooks/order/useSetCustomerForOrder.tsx index 521c72be2..a209c107e 100644 --- a/src/components/hooks/order/useSetCustomerForOrder.tsx +++ b/src/components/hooks/order/useSetCustomerForOrder.tsx @@ -18,18 +18,13 @@ const useSetCustomerForOrder = () => { setLoading(true) rawFetcher({ query: setCustomerForOrderMutation, - variables: {input}, + variables: { input }, }) - .then(({ data, headers }) => { - console.log("data here: ", data) + .then(({ data }) => { if (data.setCustomerForOrder.__typename === 'ActiveOrderCustomerFragment') { - console.log("success: ") - fCallBack(true) mutate() } else { - console.log("fail ") - fCallBack(false, data.setCustomerForOrder.message) } diff --git a/src/components/modules/checkout/CheckoutInfo/components/ShippingInfoForm/ShippingInfoForm.tsx b/src/components/modules/checkout/CheckoutInfo/components/ShippingInfoForm/ShippingInfoForm.tsx index 04217d706..64fe3ce6e 100644 --- a/src/components/modules/checkout/CheckoutInfo/components/ShippingInfoForm/ShippingInfoForm.tsx +++ b/src/components/modules/checkout/CheckoutInfo/components/ShippingInfoForm/ShippingInfoForm.tsx @@ -14,9 +14,11 @@ interface ShippingInfoFormProps { const option = [ { name: 'Hồ Chí Minh', + value: 'Hồ Chí Minh', }, { name: 'Hà Nội', + value: 'Hà Nội', }, ] diff --git a/src/utils/fetcher.ts b/src/utils/fetcher.ts index a86367398..a0c5222cc 100644 --- a/src/utils/fetcher.ts +++ b/src/utils/fetcher.ts @@ -1,4 +1,4 @@ -import { request } from 'graphql-request' +import { GraphQLClient } from 'graphql-request' import { RequestDocument, Variables } from 'graphql-request/dist/types' import { LOCAL_STORAGE_KEY } from './constanst.utils' @@ -12,11 +12,15 @@ interface QueryOptions { const fetcher = async (options: QueryOptions): Promise => { const { query, variables } = options const token = localStorage.getItem(LOCAL_STORAGE_KEY.TOKEN) - const res = await request( - process.env.NEXT_PUBLIC_VENDURE_SHOP_API_URL as string, + const graphQLClient = new GraphQLClient(process.env.NEXT_PUBLIC_VENDURE_SHOP_API_URL as string, { + credentials: 'include', + mode: 'cors', + headers: token ? { Authorization: 'Bearer ' + token } : {}, + }) + + const res = await graphQLClient.request( query, variables, - token ? { Authorization: 'Bearer ' + token } : {} ) return res diff --git a/src/utils/rawFetcher.ts b/src/utils/rawFetcher.ts index c26b2ab20..6c87dc4a9 100644 --- a/src/utils/rawFetcher.ts +++ b/src/utils/rawFetcher.ts @@ -1,7 +1,6 @@ -import { rawRequest } from 'graphql-request' +import { GraphQLClient } from 'graphql-request' import { RequestDocument, Variables } from 'graphql-request/dist/types' import { LOCAL_STORAGE_KEY } from './constanst.utils' - interface QueryOptions { query: RequestDocument variables?: Variables @@ -16,15 +15,20 @@ const rawFetcher = ({ }: QueryOptions): Promise<{ data: T; headers: any }> => { onLoad(true) const token = localStorage.getItem(LOCAL_STORAGE_KEY.TOKEN) - return rawRequest( - process.env.NEXT_PUBLIC_VENDURE_SHOP_API_URL as string, + + const graphQLClient = new GraphQLClient(process.env.NEXT_PUBLIC_VENDURE_SHOP_API_URL as string, { + credentials: 'include', + mode: 'cors', + headers: token ? { Authorization: 'Bearer ' + token } : {}, + }) + + return graphQLClient.rawRequest( query as string, variables, - token ? { Authorization: 'Bearer ' + token } : {} - ) - .then(({ data, headers }) => { - return { data, headers } - }) + ) + .then(({ data, headers }) => { + return { data, headers } + }) .finally(() => onLoad(false)) } From 107585b0322134a4e80c459112e9e335fff8fa34 Mon Sep 17 00:00:00 2001 From: lytrankieio123 Date: Tue, 19 Oct 2021 11:08:25 +0700 Subject: [PATCH 06/27] :sparkles: feat: test checkout :%s --- .../checkout/CheckoutInfo/CheckoutInfo.tsx | 72 ++++++++++++------- 1 file changed, 45 insertions(+), 27 deletions(-) diff --git a/src/components/modules/checkout/CheckoutInfo/CheckoutInfo.tsx b/src/components/modules/checkout/CheckoutInfo/CheckoutInfo.tsx index 423f92635..0a07a6c5b 100644 --- a/src/components/modules/checkout/CheckoutInfo/CheckoutInfo.tsx +++ b/src/components/modules/checkout/CheckoutInfo/CheckoutInfo.tsx @@ -1,6 +1,7 @@ import React, { useState } from 'react' -import { Logo } from 'src/components/common' +import { ButtonCommon, Logo } from 'src/components/common' import CheckoutCollapse from 'src/components/common/CheckoutCollapse/CheckoutCollapse' +import { useAddProductToCart, useGetActiveOrder } from 'src/components/hooks/cart' import { removeItem } from 'src/utils/funtion.utils' import { CheckOutForm } from 'src/utils/types.utils' import s from './CheckoutInfo.module.scss' @@ -8,43 +9,43 @@ import CustomerInfoForm from './components/CustomerInfoForm/CustomerInfoForm' import PaymentInfoForm from './components/PaymentInfoForm/PaymentInfoForm' import ShippingInfoForm from './components/ShippingInfoForm/ShippingInfoForm' interface CheckoutInfoProps { - onViewCart:()=>void + onViewCart: () => void } -const CheckoutInfo = ({onViewCart}: CheckoutInfoProps) => { +const CheckoutInfo = ({ onViewCart }: CheckoutInfoProps) => { const [active, setActive] = useState(1) const [done, setDone] = useState([]) const [info, setInfo] = useState({}) - const onEdit = (id:number) => { - setActive(id) - setDone(removeItem(done,id)) - } + const onEdit = (id: number) => { + setActive(id) + setDone(removeItem(done, id)) + } - const onConfirm = (id:number,formInfo:CheckOutForm) => { - if(id+1>formList.length){ - console.log({...info,...formInfo}) - }else{ - if(done.length>0){ - for (let i = id+1; i <= formList.length; i++) { - if(!done.includes(i)){ + const onConfirm = (id: number, formInfo: CheckOutForm) => { + if (id + 1 > formList.length) { + console.log({ ...info, ...formInfo }) + } else { + if (done.length > 0) { + for (let i = id + 1; i <= formList.length; i++) { + if (!done.includes(i)) { setActive(i) } } - }else{ - setActive(id+1) + } else { + setActive(id + 1) } - setDone([...done,id]) - } - setInfo({...info,...formInfo}) - } + setDone([...done, id]) + } + setInfo({ ...info, ...formInfo }) + } - const getNote = (id:number) => { + const getNote = (id: number) => { switch (id) { case 1: return `${info.name}, ${info.email}` - case 2: - return `${info.address}, ${info.state}, ${info.city}, ${info.code}, ${info.phone}, ` + case 2: + return `${info.address}, ${info.state}, ${info.city}, ${info.code}, ${info.phone}, ` default: return "" } @@ -54,21 +55,38 @@ const CheckoutInfo = ({onViewCart}: CheckoutInfoProps) => { { id: 1, title: 'Customer Information', - form: , + form: , }, { id: 2, title: 'Shipping Information', - form: , + form: , }, { id: 3, title: 'Payment Information', - form: , + form: , }, ] + + // TODO: remove + const { addProduct } = useAddProductToCart() + + const createOrder = () => { + addProduct({ variantId: "63", quantity: 1 }, handleAddToCartCallback) + } + const handleAddToCartCallback = (isSuccess: boolean, message?: string) => { + console.log("after create order: ", isSuccess, message) + + } + + const {order} = useGetActiveOrder() + console.log("active order: ", order) + return (
+ test create order + test get active order
View cart
@@ -76,7 +94,7 @@ const CheckoutInfo = ({onViewCart}: CheckoutInfoProps) => { {formList.map((item) => { let note = getNote(item.id) return Date: Tue, 19 Oct 2021 11:09:25 +0700 Subject: [PATCH 07/27] :fire: remove: log :%s --- src/components/modules/checkout/CheckoutInfo/CheckoutInfo.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/components/modules/checkout/CheckoutInfo/CheckoutInfo.tsx b/src/components/modules/checkout/CheckoutInfo/CheckoutInfo.tsx index 0a07a6c5b..bec1fd132 100644 --- a/src/components/modules/checkout/CheckoutInfo/CheckoutInfo.tsx +++ b/src/components/modules/checkout/CheckoutInfo/CheckoutInfo.tsx @@ -76,12 +76,11 @@ const CheckoutInfo = ({ onViewCart }: CheckoutInfoProps) => { addProduct({ variantId: "63", quantity: 1 }, handleAddToCartCallback) } const handleAddToCartCallback = (isSuccess: boolean, message?: string) => { - console.log("after create order: ", isSuccess, message) + // console.log("after create order: ", isSuccess, message) } const {order} = useGetActiveOrder() - console.log("active order: ", order) return (
From ae647003bc8dd50dca803b5437130d861b066f76 Mon Sep 17 00:00:00 2001 From: lytrankieio123 Date: Tue, 19 Oct 2021 17:30:00 +0700 Subject: [PATCH 08/27] :sparkles: feat: add shipping address to order :%s --- framework/commerce/types/cart.ts | 5 + framework/vendure/schema.d.ts | 16 +- .../vendure/utils/fragments/cart-fragment.ts | 3 + .../set-order-shipping-address-mutation.ts | 25 + framework/vendure/utils/normalize.ts | 5 + .../CheckoutCollapse/CheckoutCollapse.tsx | 14 +- .../ModalAuthenticate/ModalAuthenticate.tsx | 12 +- .../components/FormLogin/FormLogin.tsx | 6 +- .../common/ModalConfirm/ModalConfirm.tsx | 5 +- .../SelectFieldInForm.module.scss | 19 + .../SelectFieldInForm/SelectFieldInForm.tsx | 106 + src/components/common/index.ts | 1 + .../hooks/cart/useGetActiveOrder.tsx | 3 +- src/components/hooks/order/index.ts | 1 + .../hooks/order/useSetCustomerForOrder.tsx | 8 +- .../order/useSetOrderShippingAddress.tsx | 43 + .../checkout/CheckoutInfo/CheckoutInfo.tsx | 111 +- .../CustomerInfoForm/CustomerInfoForm.tsx | 48 +- .../ModalConfirmLogin.module.scss | 0 .../ModalConfirmLogin/ModalConfirmLogin.tsx | 31 + .../ShippingInfoForm/ShippingInfoForm.tsx | 230 +- .../CheckoutPage/CheckoutPage.module.scss | 2 +- src/domains/data/CountryCode.ts | 3227 +++++++++++++++++ src/utils/types.utils.ts | 5 +- 24 files changed, 3767 insertions(+), 159 deletions(-) create mode 100644 framework/vendure/utils/mutations/set-order-shipping-address-mutation.ts create mode 100644 src/components/common/SelectFieldInForm/SelectFieldInForm.module.scss create mode 100644 src/components/common/SelectFieldInForm/SelectFieldInForm.tsx create mode 100644 src/components/hooks/order/useSetOrderShippingAddress.tsx create mode 100644 src/components/modules/checkout/CheckoutInfo/components/CustomerInfoForm/ModalConfirmLogin/ModalConfirmLogin.module.scss create mode 100644 src/components/modules/checkout/CheckoutInfo/components/CustomerInfoForm/ModalConfirmLogin/ModalConfirmLogin.tsx create mode 100644 src/domains/data/CountryCode.ts diff --git a/framework/commerce/types/cart.ts b/framework/commerce/types/cart.ts index b3d3b1e59..936ba427d 100644 --- a/framework/commerce/types/cart.ts +++ b/framework/commerce/types/cart.ts @@ -62,6 +62,11 @@ export type Cart = { id: string // ID of the customer to which the cart belongs. customerId?: string + customer?: { + firstName: string, + lastName: string, + emailAddress: string, + } // The email assigned to this cart email?: string // The date and time when the cart was created. diff --git a/framework/vendure/schema.d.ts b/framework/vendure/schema.d.ts index baf37c7f3..ecd45190f 100644 --- a/framework/vendure/schema.d.ts +++ b/framework/vendure/schema.d.ts @@ -332,17 +332,9 @@ export type SetCustomerForOrderMutation = { __typename?: 'Mutation' } & { >) } -export type SetCustomerForOrderMutation = { __typename?: 'Mutation' } & { - setCustomerForOrder: - | ({ __typename: 'ActiveOrderCustomerFragment' } & Pick) - | ({ __typename: 'AlreadyLoggedInError' } & Pick< - AlreadyLoggedInError, - 'errorCode' | 'message' - >) - | ({ __typename: 'EmailAddressConflictError' } & Pick< - EmailAddressConflictError, - 'errorCode' | 'message' - >) +export type SetOrderShippingAddressMutation = { __typename?: 'Mutation' } & { + setOrderShippingAddress: + | ({ __typename: 'Order' } & Pick) | ({ __typename: 'NoActiveOrderError' } & Pick< NoActiveOrderError, 'errorCode' | 'message' @@ -3060,7 +3052,7 @@ export type CartFragment = { __typename?: 'Order' } & Pick< | 'totalWithTax' | 'currencyCode' > & { - customer?: Maybe<{ __typename?: 'Customer' } & Pick> + customer?: Maybe<{ __typename?: 'Customer' } & Pick> lines: Array< { __typename?: 'OrderLine' } & Pick< OrderLine, diff --git a/framework/vendure/utils/fragments/cart-fragment.ts b/framework/vendure/utils/fragments/cart-fragment.ts index 54ac08912..a9b14d2d4 100644 --- a/framework/vendure/utils/fragments/cart-fragment.ts +++ b/framework/vendure/utils/fragments/cart-fragment.ts @@ -11,6 +11,9 @@ export const cartFragment = /* GraphQL */ ` currencyCode customer { id + firstName + lastName + emailAddress } lines { id diff --git a/framework/vendure/utils/mutations/set-order-shipping-address-mutation.ts b/framework/vendure/utils/mutations/set-order-shipping-address-mutation.ts new file mode 100644 index 000000000..ee36fb68d --- /dev/null +++ b/framework/vendure/utils/mutations/set-order-shipping-address-mutation.ts @@ -0,0 +1,25 @@ +export const setOrderShippingAddressMutation = /* GraphQL */ ` +mutation setOrderShippingAddress($input: CreateAddressInput!) { + setOrderShippingAddress(input: $input) { + __typename + ... on Order { + id + createdAt + updatedAt + code + shippingAddress { + streetLine1 + city + province + postalCode + countryCode + phoneNumber + } + } + ... on ErrorResult { + errorCode + message + } + } +} +` diff --git a/framework/vendure/utils/normalize.ts b/framework/vendure/utils/normalize.ts index 871352070..c1bbc93b0 100644 --- a/framework/vendure/utils/normalize.ts +++ b/framework/vendure/utils/normalize.ts @@ -45,6 +45,11 @@ export function normalizeCart(order: CartFragment): Cart { subtotalPrice: order.subTotalWithTax / 100, totalPrice: order.totalWithTax / 100, customerId: order.customer?.id, + customer: { + firstName: order.customer?.firstName || '', + lastName: order.customer?.lastName || '', + emailAddress: order.customer?.emailAddress || '', + }, lineItems: order.lines?.map((l) => ({ id: l.id, name: l.productVariant.name, diff --git a/src/components/common/CheckoutCollapse/CheckoutCollapse.tsx b/src/components/common/CheckoutCollapse/CheckoutCollapse.tsx index 077b94a79..9e6446ac3 100644 --- a/src/components/common/CheckoutCollapse/CheckoutCollapse.tsx +++ b/src/components/common/CheckoutCollapse/CheckoutCollapse.tsx @@ -1,8 +1,6 @@ import classNames from 'classnames' -import { divide } from 'lodash' import React from 'react' import { IconDoneCheckout } from 'src/components/icons' -import { CheckOutForm } from 'src/utils/types.utils' import s from './CheckoutCollapse.module.scss' interface CheckoutCollapseProps { visible: boolean @@ -14,6 +12,7 @@ interface CheckoutCollapseProps { onOpen?: (id:number) => void onEditClick?:(id:number) => void note?:string + disableEdit?: boolean } const CheckoutCollapse = ({ @@ -25,14 +24,15 @@ const CheckoutCollapse = ({ note, onOpen, onClose, - onEditClick + onEditClick, + disableEdit, }: CheckoutCollapseProps) => { const handleTitleClick = () => { if(visible){ onClose && onClose(id) - }else{ - onOpen && onOpen(id) - } + } else if (!disableEdit) { + onOpen && onOpen(id) + } } const handleEdit = () => { onEditClick && onEditClick(id) @@ -48,7 +48,7 @@ const CheckoutCollapse = ({ {title}
- {isEdit &&
{'Edit'}
} + {!disableEdit && isEdit &&
{'Edit'}
}
{(!visible && isEdit) && (
{note}
) }
{children}
diff --git a/src/components/common/ModalAuthenticate/ModalAuthenticate.tsx b/src/components/common/ModalAuthenticate/ModalAuthenticate.tsx index 145155268..6b773cf98 100644 --- a/src/components/common/ModalAuthenticate/ModalAuthenticate.tsx +++ b/src/components/common/ModalAuthenticate/ModalAuthenticate.tsx @@ -12,9 +12,11 @@ interface Props { visible: boolean closeModal: () => void mode?: '' | 'register' + initialEmail?: string + disableRedirect ?: boolean } -const ModalAuthenticate = ({ visible, mode, closeModal }: Props) => { +const ModalAuthenticate = ({ visible, mode, closeModal, initialEmail, disableRedirect }: Props) => { const [isLogin, setIsLogin] = useState(true) const { customer } = useActiveCustomer() const router = useRouter() @@ -30,9 +32,11 @@ const ModalAuthenticate = ({ visible, mode, closeModal }: Props) => { useEffect(() => { if (visible && customer) { closeModal() - router.push(ROUTE.ACCOUNT) + if (!disableRedirect) { + router.push(ROUTE.ACCOUNT) + } } - }, [customer, visible, closeModal, router]) + }, [customer, visible, closeModal, router, disableRedirect]) const onSwitch = () => { setIsLogin(!isLogin) @@ -51,7 +55,7 @@ const ModalAuthenticate = ({ visible, mode, closeModal }: Props) => { [s.register]: !isLogin, })} > - +
diff --git a/src/components/common/ModalAuthenticate/components/FormLogin/FormLogin.tsx b/src/components/common/ModalAuthenticate/components/FormLogin/FormLogin.tsx index 3f4ac6816..8264fc70a 100644 --- a/src/components/common/ModalAuthenticate/components/FormLogin/FormLogin.tsx +++ b/src/components/common/ModalAuthenticate/components/FormLogin/FormLogin.tsx @@ -15,6 +15,8 @@ import styles from './FormLogin.module.scss' interface Props { isHide: boolean onSwitch: () => void + initialEmail?: string + } const displayingErrorMessagesSchema = Yup.object().shape({ @@ -24,7 +26,7 @@ const displayingErrorMessagesSchema = Yup.object().shape({ .required(LANGUAGE.MESSAGE.REQUIRED), }) -const FormLogin = ({ onSwitch, isHide }: Props) => { +const FormLogin = ({ onSwitch, isHide, initialEmail = ''}: Props) => { const emailRef = useRef(null) const { loading, login } = useLogin() const { showMessageSuccess, showMessageError } = useMessage() @@ -54,7 +56,7 @@ const FormLogin = ({ onSwitch, isHide }: Props) => { { return ( - + {children}
- {cancelText} + {cancelText}
{okText}
diff --git a/src/components/common/SelectFieldInForm/SelectFieldInForm.module.scss b/src/components/common/SelectFieldInForm/SelectFieldInForm.module.scss new file mode 100644 index 000000000..e50b5e0f5 --- /dev/null +++ b/src/components/common/SelectFieldInForm/SelectFieldInForm.module.scss @@ -0,0 +1,19 @@ +@import "../../../styles/form"; + +.inputWrap { + @extend .formInputWrap; + .inputInner { + select { + @apply w-full; + background-color: var(--white); + padding: 1.6rem 1.6rem; + border: 1px solid var(--border-line); + border-radius: 0.8rem; + &:focus { + outline: none; + border: 1px solid var(--primary); + @apply shadow-md; + } + } + } +} diff --git a/src/components/common/SelectFieldInForm/SelectFieldInForm.tsx b/src/components/common/SelectFieldInForm/SelectFieldInForm.tsx new file mode 100644 index 000000000..3a650fa1c --- /dev/null +++ b/src/components/common/SelectFieldInForm/SelectFieldInForm.tsx @@ -0,0 +1,106 @@ +import classNames from "classnames" +import { Field } from "formik" +import { useMemo } from "react" +import { IconCheck, IconError } from "src/components/icons" +import s from './SelectFieldInForm.module.scss' + + +interface Props { + placeholder?: string + styleType?: 'default' | 'custom' + backgroundTransparent?: boolean + icon?: React.ReactNode + isIconSuffix?: boolean + isShowIconSuccess?: boolean + name: string + error?: string + options: any[] + keyNameOption?: string[] + keyValueOption?: string + nameSeperator?: string + +} + +const SelectFieldInForm = ({ + name, + placeholder, + options, + styleType = 'default', + icon, + backgroundTransparent = false, + isIconSuffix = true, + isShowIconSuccess, + error, + keyNameOption = ['name'], + keyValueOption = 'value', + nameSeperator = " ", + +}: Props) => { + const iconElement = useMemo(() => { + if (error) { + return ( + + {' '} + + ) + } else if (isShowIconSuccess) { + return ( + + {' '} + + ) + } else if (icon) { + return {icon} + } + return <> + }, [icon, error, isShowIconSuccess]) + + return ( +
+
+ {iconElement} + + { + options.map((item) => { + let name = '' + keyNameOption.map((key) => { + if (name) { + name += nameSeperator + } + name += item[key] + }) + name = name.trim() + return + }) + } + + +
+ {error &&
{error}
} +
+ ) +} + +export default SelectFieldInForm diff --git a/src/components/common/index.ts b/src/components/common/index.ts index 2b7724b73..a27830aae 100644 --- a/src/components/common/index.ts +++ b/src/components/common/index.ts @@ -50,6 +50,7 @@ export { default as RecommendedRecipes} from './RecommendedRecipes/RecommendedRe export { default as LayoutCheckout} from './LayoutCheckout/LayoutCheckout' export { default as InputPasswordFiledInForm} from './InputPasswordFiledInForm/InputPasswordFiledInForm' export { default as InputFiledInForm} from './InputFiledInForm/InputFiledInForm' +export { default as SelectFieldInForm} from './SelectFieldInForm/SelectFieldInForm' export { default as MessageCommon} from './MessageCommon/MessageCommon' export { default as FormForgot} from './ForgotPassword/FormForgot/FormForgot' export { default as FormResetPassword} from './ForgotPassword/FormResetPassword/FormResetPassword' diff --git a/src/components/hooks/cart/useGetActiveOrder.tsx b/src/components/hooks/cart/useGetActiveOrder.tsx index c8898c222..cb7af3f2e 100644 --- a/src/components/hooks/cart/useGetActiveOrder.tsx +++ b/src/components/hooks/cart/useGetActiveOrder.tsx @@ -15,8 +15,7 @@ const query = gql` const useGetActiveOrder = () => { const { data, ...rest } = useSWR([query], gglFetcher) - return { order: data?.activeOrder ? normalizeCart(data!.activeOrder) : null, ...rest } - + return { order: data?.activeOrder ? normalizeCart(data!.activeOrder) : null, ...rest } } export default useGetActiveOrder diff --git a/src/components/hooks/order/index.ts b/src/components/hooks/order/index.ts index f644f7917..0aef836be 100644 --- a/src/components/hooks/order/index.ts +++ b/src/components/hooks/order/index.ts @@ -1,2 +1,3 @@ export { default as useSetCustomerForOrder } from './useSetCustomerForOrder' +export { default as useSetOrderShippingAddress } from './useSetOrderShippingAddress' diff --git a/src/components/hooks/order/useSetCustomerForOrder.tsx b/src/components/hooks/order/useSetCustomerForOrder.tsx index a209c107e..beb1e5b72 100644 --- a/src/components/hooks/order/useSetCustomerForOrder.tsx +++ b/src/components/hooks/order/useSetCustomerForOrder.tsx @@ -12,7 +12,7 @@ const useSetCustomerForOrder = () => { const { mutate } = useGetActiveOrder() const setCustomerForOrder = (input: CreateCustomerInput, - fCallBack: (isSuccess: boolean, message?: string) => void + fCallBack: (isSuccess: boolean, message?: CommonError) => void ) => { setError(null) setLoading(true) @@ -21,17 +21,17 @@ const useSetCustomerForOrder = () => { variables: { input }, }) .then(({ data }) => { - if (data.setCustomerForOrder.__typename === 'ActiveOrderCustomerFragment') { + if (data.setCustomerForOrder.__typename === 'Order') { fCallBack(true) mutate() } else { - fCallBack(false, data.setCustomerForOrder.message) + fCallBack(false, data.setCustomerForOrder) } }) .catch((error) => { setError(error) - fCallBack(false, error.message) + fCallBack(false, error) }) .finally(() => setLoading(false)) } diff --git a/src/components/hooks/order/useSetOrderShippingAddress.tsx b/src/components/hooks/order/useSetOrderShippingAddress.tsx new file mode 100644 index 000000000..353cb01c7 --- /dev/null +++ b/src/components/hooks/order/useSetOrderShippingAddress.tsx @@ -0,0 +1,43 @@ +import { CreateAddressInput, SetOrderShippingAddressMutation } from '@framework/schema' +import { setOrderShippingAddressMutation } from '@framework/utils/mutations/set-order-shipping-address-mutation' +import { useState } from 'react' +import { CommonError } from 'src/domains/interfaces/CommonError' +import rawFetcher from 'src/utils/rawFetcher' +import { useGetActiveOrder } from '../cart' + + +const useSetOrderShippingAddress = () => { + const [loading, setLoading] = useState(false) + const [error, setError] = useState(null) + const { mutate } = useGetActiveOrder() + + const setOrderShippingAddress = (input: CreateAddressInput, + fCallBack: (isSuccess: boolean, message?: string) => void + ) => { + setError(null) + setLoading(true) + rawFetcher({ + query: setOrderShippingAddressMutation, + variables: { input }, + }) + .then(({ data }) => { + console.log("data: ", data) + if (data.setOrderShippingAddress.__typename === 'Order') { + fCallBack(true) + mutate() + } else { + fCallBack(false, data.setOrderShippingAddress.message) + } + + }) + .catch((error) => { + setError(error) + fCallBack(false, error.message) + }) + .finally(() => setLoading(false)) + } + + return { loading, setOrderShippingAddress, error } +} + +export default useSetOrderShippingAddress diff --git a/src/components/modules/checkout/CheckoutInfo/CheckoutInfo.tsx b/src/components/modules/checkout/CheckoutInfo/CheckoutInfo.tsx index bec1fd132..cd59f2128 100644 --- a/src/components/modules/checkout/CheckoutInfo/CheckoutInfo.tsx +++ b/src/components/modules/checkout/CheckoutInfo/CheckoutInfo.tsx @@ -1,6 +1,7 @@ -import React, { useState } from 'react' +import React, { useEffect, useState } from 'react' import { ButtonCommon, Logo } from 'src/components/common' import CheckoutCollapse from 'src/components/common/CheckoutCollapse/CheckoutCollapse' +import { useActiveCustomer } from 'src/components/hooks/auth' import { useAddProductToCart, useGetActiveOrder } from 'src/components/hooks/cart' import { removeItem } from 'src/utils/funtion.utils' import { CheckOutForm } from 'src/utils/types.utils' @@ -12,39 +13,79 @@ interface CheckoutInfoProps { onViewCart: () => void } +enum CheckoutStep { + CustomerInfo = 1, + ShippingInfo = 2, + PaymentInfo = 3, +} + const CheckoutInfo = ({ onViewCart }: CheckoutInfoProps) => { - const [active, setActive] = useState(1) - const [done, setDone] = useState([]) + const [activeStep, setActiveStep] = useState(1) + const [doneSteps, setDoneSteps] = useState([]) const [info, setInfo] = useState({}) + const { order } = useGetActiveOrder() + const { customer } = useActiveCustomer() - const onEdit = (id: number) => { - setActive(id) - setDone(removeItem(done, id)) - } + useEffect(() => { + if (customer) { + if (!doneSteps.includes(CheckoutStep.CustomerInfo)) { - const onConfirm = (id: number, formInfo: CheckOutForm) => { - if (id + 1 > formList.length) { - console.log({ ...info, ...formInfo }) - } else { - if (done.length > 0) { - for (let i = id + 1; i <= formList.length; i++) { - if (!done.includes(i)) { - setActive(i) + if (doneSteps.length > 0) { + for (let i = CheckoutStep.CustomerInfo + 1; i <= Object.keys(CheckoutStep).length; i++) { + if (!doneSteps.includes(i)) { + setActiveStep(i) + } } + } else { + setActiveStep(CheckoutStep.CustomerInfo + 1) } - } else { - setActive(id + 1) + + setDoneSteps([...doneSteps, CheckoutStep.CustomerInfo]) } - setDone([...done, id]) } - setInfo({ ...info, ...formInfo }) + }, [customer, doneSteps]) + + + const onEdit = (id: CheckoutStep) => { + setActiveStep(id) + setDoneSteps(removeItem(doneSteps, id)) } - const getNote = (id: number) => { + const updateActiveStep = (step: CheckoutStep) => { + if (doneSteps.length > 0) { + for (let i = step + 1; i <= Object.keys(CheckoutStep).length; i++) { + if (!doneSteps.includes(i)) { + setActiveStep(i) + } + } + } else { + setActiveStep(step + 1) + } + } + + const onConfirm = (step: CheckoutStep) => { + if (step + 1 > formList.length) { + // TODO: checkout + console.log("finish: ", order) + } else { + updateActiveStep(step) + setDoneSteps([...doneSteps, step]) + } + } + + + const getNote = (id: CheckoutStep) => { switch (id) { - case 1: - return `${info.name}, ${info.email}` - case 2: + case CheckoutStep.CustomerInfo: + // console.log("order info; ", order?.customer) + if (order?.customer) { + return `${order?.customer?.firstName} ${order?.customer?.lastName}, ${order?.customer?.emailAddress}` + } else if (customer) { + return `${customer.firstName} ${customer.lastName}, ${customer.emailAddress}` + } else { + return '' + } + case CheckoutStep.ShippingInfo: return `${info.address}, ${info.state}, ${info.city}, ${info.code}, ${info.phone}, ` default: return "" @@ -53,19 +94,19 @@ const CheckoutInfo = ({ onViewCart }: CheckoutInfoProps) => { const formList = [ { - id: 1, + id: CheckoutStep.CustomerInfo, title: 'Customer Information', - form: , + form: , }, { - id: 2, + id: CheckoutStep.ShippingInfo, title: 'Shipping Information', - form: , + form: , }, { - id: 3, + id: CheckoutStep.PaymentInfo, title: 'Payment Information', - form: , + form: , }, ] @@ -77,15 +118,16 @@ const CheckoutInfo = ({ onViewCart }: CheckoutInfoProps) => { } const handleAddToCartCallback = (isSuccess: boolean, message?: string) => { // console.log("after create order: ", isSuccess, message) - } - const {order} = useGetActiveOrder() return (
+ {/* TODO: remove */} test create order - test get active order + test get activeStep order + +
View cart
@@ -95,11 +137,12 @@ const CheckoutInfo = ({ onViewCart }: CheckoutInfoProps) => { return {item.form} diff --git a/src/components/modules/checkout/CheckoutInfo/components/CustomerInfoForm/CustomerInfoForm.tsx b/src/components/modules/checkout/CheckoutInfo/components/CustomerInfoForm/CustomerInfoForm.tsx index 8df2ab1fb..6c6098f91 100644 --- a/src/components/modules/checkout/CheckoutInfo/components/CustomerInfoForm/CustomerInfoForm.tsx +++ b/src/components/modules/checkout/CheckoutInfo/components/CustomerInfoForm/CustomerInfoForm.tsx @@ -1,16 +1,22 @@ import { Form, Formik } from 'formik' -import React, { useRef } from 'react' +import React, { useRef, useState } from 'react' import { ButtonCommon, InputFiledInForm } from 'src/components/common' +import ModalAuthenticate from 'src/components/common/ModalAuthenticate/ModalAuthenticate' import { useMessage } from 'src/components/contexts' +import { useModalCommon } from 'src/components/hooks' import { useSetCustomerForOrder } from 'src/components/hooks/order' +import { ErrorCode } from 'src/domains/enums/ErrorCode' +import { CommonError } from 'src/domains/interfaces/CommonError' import { LANGUAGE } from 'src/utils/language.utils' import { CustomInputCommon } from 'src/utils/type.utils' +import { CheckOutForm } from 'src/utils/types.utils' import * as Yup from 'yup' import ChekoutNotePolicy from '../ChekoutNotePolicy/ChekoutNotePolicy' import s from './CustomerInfoForm.module.scss' +import ModalConfirmLogin from './ModalConfirmLogin/ModalConfirmLogin' interface Props { - isHide: boolean - onSwitch: () => void + id: number + onConfirm: (id: number) => void } const displayingErrorMessagesSchema = Yup.object().shape({ @@ -19,32 +25,36 @@ const displayingErrorMessagesSchema = Yup.object().shape({ emailAddress: Yup.string().email(LANGUAGE.MESSAGE.INVALID_EMAIL).required(LANGUAGE.MESSAGE.REQUIRED), }) -const CustomerInfoForm = ({ onSwitch, isHide }: Props) => { +const CustomerInfoForm = ({ id, onConfirm }: Props) => { const firstNameRef = useRef(null) - const emailRef = useRef(null) const { setCustomerForOrder, loading } = useSetCustomerForOrder() const { showMessageError } = useMessage() + const [emailAddress, setEmailAddress] = useState('') + const { visible: visibleModalConfirmLogin, closeModal: closeModalConfirmLogin, openModal: openModalConfirmLogin } = useModalCommon({ initialValue: false }) + const { visible: visibleModalAuthen, closeModal: closeModalAuthen, openModal: openModalAuthen } = useModalCommon({ initialValue: false }) + const handleSubmit = (values: { firstName: string, lastName: string, emailAddress: string }) => { - console.log('on submit: ', values) const { firstName, lastName, emailAddress } = values + setEmailAddress(emailAddress) setCustomerForOrder({ firstName, lastName, emailAddress }, onSubmitCalBack) - // onConfirm && - // onConfirm(id, { - // name: nameRef?.current?.getValue().toString(), - // email: emailRef.current?.getValue().toString(), - // }) } - const onSubmitCalBack = (isSuccess: boolean, msg?: string) => { + const onSubmitCalBack = (isSuccess: boolean, error?: CommonError) => { // TODO: - console.log("result: ", isSuccess, msg) if (isSuccess) { - + onConfirm(id) } else { - console.log("error here") - showMessageError(msg) + if (error?.errorCode === ErrorCode.EmailAddressConflictError) { + // show modal common + openModalConfirmLogin() + } else { + showMessageError(error?.message) + } } - + } + const handleCloseModalConfirmLogin = () => { + closeModalConfirmLogin() + openModalAuthen() } return ( @@ -58,7 +68,6 @@ const CustomerInfoForm = ({ onSwitch, isHide }: Props) => { }} validationSchema={displayingErrorMessagesSchema} onSubmit={handleSubmit} - > {({ errors, touched, isValid, submitForm }) => (
@@ -90,7 +99,6 @@ const CustomerInfoForm = ({ onSwitch, isHide }: Props) => { { )}
+ + ) } diff --git a/src/components/modules/checkout/CheckoutInfo/components/CustomerInfoForm/ModalConfirmLogin/ModalConfirmLogin.module.scss b/src/components/modules/checkout/CheckoutInfo/components/CustomerInfoForm/ModalConfirmLogin/ModalConfirmLogin.module.scss new file mode 100644 index 000000000..e69de29bb diff --git a/src/components/modules/checkout/CheckoutInfo/components/CustomerInfoForm/ModalConfirmLogin/ModalConfirmLogin.tsx b/src/components/modules/checkout/CheckoutInfo/components/CustomerInfoForm/ModalConfirmLogin/ModalConfirmLogin.tsx new file mode 100644 index 000000000..c7723906b --- /dev/null +++ b/src/components/modules/checkout/CheckoutInfo/components/CustomerInfoForm/ModalConfirmLogin/ModalConfirmLogin.tsx @@ -0,0 +1,31 @@ +import React from 'react'; +import { ModalConfirm } from 'src/components/common'; +import { LANGUAGE } from 'src/utils/language.utils'; + +interface Props { + visible: boolean + closeModal: () => void + handleOk: () => void + email: string +} + +const ModalConfirmLogin = ({ visible, closeModal, handleOk, email }: Props) => { + return ( +
+ +
+

Account already exists for email {email}

+

Please signin to continue or use another email

+
+
+
+ ); +}; + +export default ModalConfirmLogin; \ No newline at end of file diff --git a/src/components/modules/checkout/CheckoutInfo/components/ShippingInfoForm/ShippingInfoForm.tsx b/src/components/modules/checkout/CheckoutInfo/components/ShippingInfoForm/ShippingInfoForm.tsx index 64fe3ce6e..f57b113bc 100644 --- a/src/components/modules/checkout/CheckoutInfo/components/ShippingInfoForm/ShippingInfoForm.tsx +++ b/src/components/modules/checkout/CheckoutInfo/components/ShippingInfoForm/ShippingInfoForm.tsx @@ -1,17 +1,37 @@ -import React, { useRef } from 'react' -import { ButtonCommon, Inputcommon, SelectCommon } from 'src/components/common' +import React, { useEffect, useRef } from 'react' +import { ButtonCommon, Inputcommon, InputFiledInForm, SelectCommon, SelectFieldInForm } from 'src/components/common' import s from './ShippingInfoForm.module.scss' import Link from 'next/link' import { CustomInputCommon } from 'src/utils/type.utils' import { Shipping } from 'src/components/icons' import { CheckOutForm } from 'src/utils/types.utils' +import { Form, Formik } from 'formik' +import { LANGUAGE } from 'src/utils/language.utils' +import * as Yup from 'yup' +import ChekoutNotePolicy from '../ChekoutNotePolicy/ChekoutNotePolicy' +import { useSetOrderShippingAddress } from 'src/components/hooks/order' +import { useMessage } from 'src/components/contexts' +import { COUNTRY_CODE } from 'src/domains/data/countryCode' interface ShippingInfoFormProps { - onConfirm?: (id:number,formInfo:CheckOutForm)=>void - id:number + id: number + activeStep: number + onConfirm: (id: number) => void + } -const option = [ + +const displayingErrorMessagesSchema = Yup.object().shape({ + streetLine1: Yup.string().required(LANGUAGE.MESSAGE.REQUIRED), + city: Yup.string().required(LANGUAGE.MESSAGE.REQUIRED), + province: Yup.string().required(LANGUAGE.MESSAGE.REQUIRED), + postalCode: Yup.number().required(LANGUAGE.MESSAGE.REQUIRED), + countryCode: Yup.string().required(LANGUAGE.MESSAGE.REQUIRED), + phoneNumber: Yup.string().required(LANGUAGE.MESSAGE.REQUIRED), + +}) + +const provinceOptions = [ { name: 'Hồ Chí Minh', value: 'Hồ Chí Minh', @@ -22,77 +42,147 @@ const option = [ }, ] -const ShippingInfoForm = ({onConfirm,id}: ShippingInfoFormProps) => { +const ShippingInfoForm = ({ onConfirm, id, activeStep }: ShippingInfoFormProps) => { const addressRef = useRef(null) - const cityRef = useRef(null) - const stateRef = useRef(null) - const codeRef = useRef(null) - const phoneRef = useRef(null) - const handleConfirmClick = () => { - onConfirm && onConfirm(id,{ - address: addressRef?.current?.getValue().toString(), - city: cityRef.current?.getValue().toString(), - state: stateRef?.current?.getValue().toString(), - code: Number(codeRef.current?.getValue()), - phone: Number(phoneRef?.current?.getValue()), - }) + const { setOrderShippingAddress } = useSetOrderShippingAddress() + const { showMessageError } = useMessage() + + useEffect(() => { + setTimeout(() => { + addressRef.current?.focus() + }, 500); + }, [activeStep]) + + const handleSubmit = (values: any) => { + console.log("values: ", values) + setOrderShippingAddress(values, onSubmitCalBack) + + // onConfirm && onConfirm(id) } + const onSubmitCalBack = (isSuccess: boolean, msg?: string) => { + if (isSuccess) { + onConfirm(id) + } else { + showMessageError(msg) + } + } + + return (
- - -
- State - -
- -
-
-
- -
-
- Standard Delivery Method -
-
-
-
- Free -
-
-
-
-
-
- By clicking continue you agree to Casper's{' '} - { - - terms and conditions - - }{' '} - and{' '} - { - - privacy policy - - } - . -
-
- - Continue to Payment - -
+ + {({ errors, touched, isValid, submitForm }) => ( + +
+
+ +
+
+
+ +
+ +
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+ +
+
+ + {/* */} + + Continue to Payment + +
+
+ + )} +
) diff --git a/src/components/modules/checkout/CheckoutPage/CheckoutPage.module.scss b/src/components/modules/checkout/CheckoutPage/CheckoutPage.module.scss index ec7b19dc2..dabbde19e 100644 --- a/src/components/modules/checkout/CheckoutPage/CheckoutPage.module.scss +++ b/src/components/modules/checkout/CheckoutPage/CheckoutPage.module.scss @@ -1,6 +1,6 @@ @import "../../../../styles/utilities"; .warrper{ - @apply flex w-full h-full absolute; + @apply flex w-full; .right { display: none; @screen lg { diff --git a/src/domains/data/CountryCode.ts b/src/domains/data/CountryCode.ts new file mode 100644 index 000000000..423abc60a --- /dev/null +++ b/src/domains/data/CountryCode.ts @@ -0,0 +1,3227 @@ +// A standardized code for the country [ISO 3166-1](https://en.wikipedia.org/wiki/List_of_ISO_3166_country_codes) +export const COUNTRY_CODE = [ + { + "name": "Afghanistan", + "alpha-2": "AF", + "alpha-3": "AFG", + "country-code": "004", + "iso_3166-2": "ISO 3166-2:AF", + "region": "Asia", + "sub-region": "Southern Asia", + "intermediate-region": "", + "region-code": "142", + "sub-region-code": "034", + "intermediate-region-code": "" + }, + { + "name": "Åland Islands", + "alpha-2": "AX", + "alpha-3": "ALA", + "country-code": "248", + "iso_3166-2": "ISO 3166-2:AX", + "region": "Europe", + "sub-region": "Northern Europe", + "intermediate-region": "", + "region-code": "150", + "sub-region-code": "154", + "intermediate-region-code": "" + }, + { + "name": "Albania", + "alpha-2": "AL", + "alpha-3": "ALB", + "country-code": "008", + "iso_3166-2": "ISO 3166-2:AL", + "region": "Europe", + "sub-region": "Southern Europe", + "intermediate-region": "", + "region-code": "150", + "sub-region-code": "039", + "intermediate-region-code": "" + }, + { + "name": "Algeria", + "alpha-2": "DZ", + "alpha-3": "DZA", + "country-code": "012", + "iso_3166-2": "ISO 3166-2:DZ", + "region": "Africa", + "sub-region": "Northern Africa", + "intermediate-region": "", + "region-code": "002", + "sub-region-code": "015", + "intermediate-region-code": "" + }, + { + "name": "American Samoa", + "alpha-2": "AS", + "alpha-3": "ASM", + "country-code": "016", + "iso_3166-2": "ISO 3166-2:AS", + "region": "Oceania", + "sub-region": "Polynesia", + "intermediate-region": "", + "region-code": "009", + "sub-region-code": "061", + "intermediate-region-code": "" + }, + { + "name": "Andorra", + "alpha-2": "AD", + "alpha-3": "AND", + "country-code": "020", + "iso_3166-2": "ISO 3166-2:AD", + "region": "Europe", + "sub-region": "Southern Europe", + "intermediate-region": "", + "region-code": "150", + "sub-region-code": "039", + "intermediate-region-code": "" + }, + { + "name": "Angola", + "alpha-2": "AO", + "alpha-3": "AGO", + "country-code": "024", + "iso_3166-2": "ISO 3166-2:AO", + "region": "Africa", + "sub-region": "Sub-Saharan Africa", + "intermediate-region": "Middle Africa", + "region-code": "002", + "sub-region-code": "202", + "intermediate-region-code": "017" + }, + { + "name": "Anguilla", + "alpha-2": "AI", + "alpha-3": "AIA", + "country-code": "660", + "iso_3166-2": "ISO 3166-2:AI", + "region": "Americas", + "sub-region": "Latin America and the Caribbean", + "intermediate-region": "Caribbean", + "region-code": "019", + "sub-region-code": "419", + "intermediate-region-code": "029" + }, + { + "name": "Antigua and Barbuda", + "alpha-2": "AG", + "alpha-3": "ATG", + "country-code": "028", + "iso_3166-2": "ISO 3166-2:AG", + "region": "Americas", + "sub-region": "Latin America and the Caribbean", + "intermediate-region": "Caribbean", + "region-code": "019", + "sub-region-code": "419", + "intermediate-region-code": "029" + }, + { + "name": "Argentina", + "alpha-2": "AR", + "alpha-3": "ARG", + "country-code": "032", + "iso_3166-2": "ISO 3166-2:AR", + "region": "Americas", + "sub-region": "Latin America and the Caribbean", + "intermediate-region": "South America", + "region-code": "019", + "sub-region-code": "419", + "intermediate-region-code": "005" + }, + { + "name": "Armenia", + "alpha-2": "AM", + "alpha-3": "ARM", + "country-code": "051", + "iso_3166-2": "ISO 3166-2:AM", + "region": "Asia", + "sub-region": "Western Asia", + "intermediate-region": "", + "region-code": "142", + "sub-region-code": "145", + "intermediate-region-code": "" + }, + { + "name": "Aruba", + "alpha-2": "AW", + "alpha-3": "ABW", + "country-code": "533", + "iso_3166-2": "ISO 3166-2:AW", + "region": "Americas", + "sub-region": "Latin America and the Caribbean", + "intermediate-region": "Caribbean", + "region-code": "019", + "sub-region-code": "419", + "intermediate-region-code": "029" + }, + { + "name": "Australia", + "alpha-2": "AU", + "alpha-3": "AUS", + "country-code": "036", + "iso_3166-2": "ISO 3166-2:AU", + "region": "Oceania", + "sub-region": "Australia and New Zealand", + "intermediate-region": "", + "region-code": "009", + "sub-region-code": "053", + "intermediate-region-code": "" + }, + { + "name": "Austria", + "alpha-2": "AT", + "alpha-3": "AUT", + "country-code": "040", + "iso_3166-2": "ISO 3166-2:AT", + "region": "Europe", + "sub-region": "Western Europe", + "intermediate-region": "", + "region-code": "150", + "sub-region-code": "155", + "intermediate-region-code": "" + }, + { + "name": "Azerbaijan", + "alpha-2": "AZ", + "alpha-3": "AZE", + "country-code": "031", + "iso_3166-2": "ISO 3166-2:AZ", + "region": "Asia", + "sub-region": "Western Asia", + "intermediate-region": "", + "region-code": "142", + "sub-region-code": "145", + "intermediate-region-code": "" + }, + { + "name": "Bahamas", + "alpha-2": "BS", + "alpha-3": "BHS", + "country-code": "044", + "iso_3166-2": "ISO 3166-2:BS", + "region": "Americas", + "sub-region": "Latin America and the Caribbean", + "intermediate-region": "Caribbean", + "region-code": "019", + "sub-region-code": "419", + "intermediate-region-code": "029" + }, + { + "name": "Bahrain", + "alpha-2": "BH", + "alpha-3": "BHR", + "country-code": "048", + "iso_3166-2": "ISO 3166-2:BH", + "region": "Asia", + "sub-region": "Western Asia", + "intermediate-region": "", + "region-code": "142", + "sub-region-code": "145", + "intermediate-region-code": "" + }, + { + "name": "Bangladesh", + "alpha-2": "BD", + "alpha-3": "BGD", + "country-code": "050", + "iso_3166-2": "ISO 3166-2:BD", + "region": "Asia", + "sub-region": "Southern Asia", + "intermediate-region": "", + "region-code": "142", + "sub-region-code": "034", + "intermediate-region-code": "" + }, + { + "name": "Barbados", + "alpha-2": "BB", + "alpha-3": "BRB", + "country-code": "052", + "iso_3166-2": "ISO 3166-2:BB", + "region": "Americas", + "sub-region": "Latin America and the Caribbean", + "intermediate-region": "Caribbean", + "region-code": "019", + "sub-region-code": "419", + "intermediate-region-code": "029" + }, + { + "name": "Belarus", + "alpha-2": "BY", + "alpha-3": "BLR", + "country-code": "112", + "iso_3166-2": "ISO 3166-2:BY", + "region": "Europe", + "sub-region": "Eastern Europe", + "intermediate-region": "", + "region-code": "150", + "sub-region-code": "151", + "intermediate-region-code": "" + }, + { + "name": "Belgium", + "alpha-2": "BE", + "alpha-3": "BEL", + "country-code": "056", + "iso_3166-2": "ISO 3166-2:BE", + "region": "Europe", + "sub-region": "Western Europe", + "intermediate-region": "", + "region-code": "150", + "sub-region-code": "155", + "intermediate-region-code": "" + }, + { + "name": "Belize", + "alpha-2": "BZ", + "alpha-3": "BLZ", + "country-code": "084", + "iso_3166-2": "ISO 3166-2:BZ", + "region": "Americas", + "sub-region": "Latin America and the Caribbean", + "intermediate-region": "Central America", + "region-code": "019", + "sub-region-code": "419", + "intermediate-region-code": "013" + }, + { + "name": "Benin", + "alpha-2": "BJ", + "alpha-3": "BEN", + "country-code": "204", + "iso_3166-2": "ISO 3166-2:BJ", + "region": "Africa", + "sub-region": "Sub-Saharan Africa", + "intermediate-region": "Western Africa", + "region-code": "002", + "sub-region-code": "202", + "intermediate-region-code": "011" + }, + { + "name": "Bermuda", + "alpha-2": "BM", + "alpha-3": "BMU", + "country-code": "060", + "iso_3166-2": "ISO 3166-2:BM", + "region": "Americas", + "sub-region": "Northern America", + "intermediate-region": "", + "region-code": "019", + "sub-region-code": "021", + "intermediate-region-code": "" + }, + { + "name": "Bhutan", + "alpha-2": "BT", + "alpha-3": "BTN", + "country-code": "064", + "iso_3166-2": "ISO 3166-2:BT", + "region": "Asia", + "sub-region": "Southern Asia", + "intermediate-region": "", + "region-code": "142", + "sub-region-code": "034", + "intermediate-region-code": "" + }, + { + "name": "Bolivia (Plurinational State of)", + "alpha-2": "BO", + "alpha-3": "BOL", + "country-code": "068", + "iso_3166-2": "ISO 3166-2:BO", + "region": "Americas", + "sub-region": "Latin America and the Caribbean", + "intermediate-region": "South America", + "region-code": "019", + "sub-region-code": "419", + "intermediate-region-code": "005" + }, + { + "name": "Bonaire, Sint Eustatius and Saba", + "alpha-2": "BQ", + "alpha-3": "BES", + "country-code": "535", + "iso_3166-2": "ISO 3166-2:BQ", + "region": "Americas", + "sub-region": "Latin America and the Caribbean", + "intermediate-region": "Caribbean", + "region-code": "019", + "sub-region-code": "419", + "intermediate-region-code": "029" + }, + { + "name": "Bosnia and Herzegovina", + "alpha-2": "BA", + "alpha-3": "BIH", + "country-code": "070", + "iso_3166-2": "ISO 3166-2:BA", + "region": "Europe", + "sub-region": "Southern Europe", + "intermediate-region": "", + "region-code": "150", + "sub-region-code": "039", + "intermediate-region-code": "" + }, + { + "name": "Botswana", + "alpha-2": "BW", + "alpha-3": "BWA", + "country-code": "072", + "iso_3166-2": "ISO 3166-2:BW", + "region": "Africa", + "sub-region": "Sub-Saharan Africa", + "intermediate-region": "Southern Africa", + "region-code": "002", + "sub-region-code": "202", + "intermediate-region-code": "018" + }, + { + "name": "Bouvet Island", + "alpha-2": "BV", + "alpha-3": "BVT", + "country-code": "074", + "iso_3166-2": "ISO 3166-2:BV", + "region": "Americas", + "sub-region": "Latin America and the Caribbean", + "intermediate-region": "South America", + "region-code": "019", + "sub-region-code": "419", + "intermediate-region-code": "005" + }, + { + "name": "Brazil", + "alpha-2": "BR", + "alpha-3": "BRA", + "country-code": "076", + "iso_3166-2": "ISO 3166-2:BR", + "region": "Americas", + "sub-region": "Latin America and the Caribbean", + "intermediate-region": "South America", + "region-code": "019", + "sub-region-code": "419", + "intermediate-region-code": "005" + }, + { + "name": "British Indian Ocean Territory", + "alpha-2": "IO", + "alpha-3": "IOT", + "country-code": "086", + "iso_3166-2": "ISO 3166-2:IO", + "region": "Africa", + "sub-region": "Sub-Saharan Africa", + "intermediate-region": "Eastern Africa", + "region-code": "002", + "sub-region-code": "202", + "intermediate-region-code": "014" + }, + { + "name": "Brunei Darussalam", + "alpha-2": "BN", + "alpha-3": "BRN", + "country-code": "096", + "iso_3166-2": "ISO 3166-2:BN", + "region": "Asia", + "sub-region": "South-eastern Asia", + "intermediate-region": "", + "region-code": "142", + "sub-region-code": "035", + "intermediate-region-code": "" + }, + { + "name": "Bulgaria", + "alpha-2": "BG", + "alpha-3": "BGR", + "country-code": "100", + "iso_3166-2": "ISO 3166-2:BG", + "region": "Europe", + "sub-region": "Eastern Europe", + "intermediate-region": "", + "region-code": "150", + "sub-region-code": "151", + "intermediate-region-code": "" + }, + { + "name": "Burkina Faso", + "alpha-2": "BF", + "alpha-3": "BFA", + "country-code": "854", + "iso_3166-2": "ISO 3166-2:BF", + "region": "Africa", + "sub-region": "Sub-Saharan Africa", + "intermediate-region": "Western Africa", + "region-code": "002", + "sub-region-code": "202", + "intermediate-region-code": "011" + }, + { + "name": "Burundi", + "alpha-2": "BI", + "alpha-3": "BDI", + "country-code": "108", + "iso_3166-2": "ISO 3166-2:BI", + "region": "Africa", + "sub-region": "Sub-Saharan Africa", + "intermediate-region": "Eastern Africa", + "region-code": "002", + "sub-region-code": "202", + "intermediate-region-code": "014" + }, + { + "name": "Cabo Verde", + "alpha-2": "CV", + "alpha-3": "CPV", + "country-code": "132", + "iso_3166-2": "ISO 3166-2:CV", + "region": "Africa", + "sub-region": "Sub-Saharan Africa", + "intermediate-region": "Western Africa", + "region-code": "002", + "sub-region-code": "202", + "intermediate-region-code": "011" + }, + { + "name": "Cambodia", + "alpha-2": "KH", + "alpha-3": "KHM", + "country-code": "116", + "iso_3166-2": "ISO 3166-2:KH", + "region": "Asia", + "sub-region": "South-eastern Asia", + "intermediate-region": "", + "region-code": "142", + "sub-region-code": "035", + "intermediate-region-code": "" + }, + { + "name": "Cameroon", + "alpha-2": "CM", + "alpha-3": "CMR", + "country-code": "120", + "iso_3166-2": "ISO 3166-2:CM", + "region": "Africa", + "sub-region": "Sub-Saharan Africa", + "intermediate-region": "Middle Africa", + "region-code": "002", + "sub-region-code": "202", + "intermediate-region-code": "017" + }, + { + "name": "Canada", + "alpha-2": "CA", + "alpha-3": "CAN", + "country-code": "124", + "iso_3166-2": "ISO 3166-2:CA", + "region": "Americas", + "sub-region": "Northern America", + "intermediate-region": "", + "region-code": "019", + "sub-region-code": "021", + "intermediate-region-code": "" + }, + { + "name": "Cayman Islands", + "alpha-2": "KY", + "alpha-3": "CYM", + "country-code": "136", + "iso_3166-2": "ISO 3166-2:KY", + "region": "Americas", + "sub-region": "Latin America and the Caribbean", + "intermediate-region": "Caribbean", + "region-code": "019", + "sub-region-code": "419", + "intermediate-region-code": "029" + }, + { + "name": "Central African Republic", + "alpha-2": "CF", + "alpha-3": "CAF", + "country-code": "140", + "iso_3166-2": "ISO 3166-2:CF", + "region": "Africa", + "sub-region": "Sub-Saharan Africa", + "intermediate-region": "Middle Africa", + "region-code": "002", + "sub-region-code": "202", + "intermediate-region-code": "017" + }, + { + "name": "Chad", + "alpha-2": "TD", + "alpha-3": "TCD", + "country-code": "148", + "iso_3166-2": "ISO 3166-2:TD", + "region": "Africa", + "sub-region": "Sub-Saharan Africa", + "intermediate-region": "Middle Africa", + "region-code": "002", + "sub-region-code": "202", + "intermediate-region-code": "017" + }, + { + "name": "Chile", + "alpha-2": "CL", + "alpha-3": "CHL", + "country-code": "152", + "iso_3166-2": "ISO 3166-2:CL", + "region": "Americas", + "sub-region": "Latin America and the Caribbean", + "intermediate-region": "South America", + "region-code": "019", + "sub-region-code": "419", + "intermediate-region-code": "005" + }, + { + "name": "China", + "alpha-2": "CN", + "alpha-3": "CHN", + "country-code": "156", + "iso_3166-2": "ISO 3166-2:CN", + "region": "Asia", + "sub-region": "Eastern Asia", + "intermediate-region": "", + "region-code": "142", + "sub-region-code": "030", + "intermediate-region-code": "" + }, + { + "name": "Christmas Island", + "alpha-2": "CX", + "alpha-3": "CXR", + "country-code": "162", + "iso_3166-2": "ISO 3166-2:CX", + "region": "Oceania", + "sub-region": "Australia and New Zealand", + "intermediate-region": "", + "region-code": "009", + "sub-region-code": "053", + "intermediate-region-code": "" + }, + { + "name": "Cocos (Keeling) Islands", + "alpha-2": "CC", + "alpha-3": "CCK", + "country-code": "166", + "iso_3166-2": "ISO 3166-2:CC", + "region": "Oceania", + "sub-region": "Australia and New Zealand", + "intermediate-region": "", + "region-code": "009", + "sub-region-code": "053", + "intermediate-region-code": "" + }, + { + "name": "Colombia", + "alpha-2": "CO", + "alpha-3": "COL", + "country-code": "170", + "iso_3166-2": "ISO 3166-2:CO", + "region": "Americas", + "sub-region": "Latin America and the Caribbean", + "intermediate-region": "South America", + "region-code": "019", + "sub-region-code": "419", + "intermediate-region-code": "005" + }, + { + "name": "Comoros", + "alpha-2": "KM", + "alpha-3": "COM", + "country-code": "174", + "iso_3166-2": "ISO 3166-2:KM", + "region": "Africa", + "sub-region": "Sub-Saharan Africa", + "intermediate-region": "Eastern Africa", + "region-code": "002", + "sub-region-code": "202", + "intermediate-region-code": "014" + }, + { + "name": "Congo", + "alpha-2": "CG", + "alpha-3": "COG", + "country-code": "178", + "iso_3166-2": "ISO 3166-2:CG", + "region": "Africa", + "sub-region": "Sub-Saharan Africa", + "intermediate-region": "Middle Africa", + "region-code": "002", + "sub-region-code": "202", + "intermediate-region-code": "017" + }, + { + "name": "Congo (Democratic Republic of the)", + "alpha-2": "CD", + "alpha-3": "COD", + "country-code": "180", + "iso_3166-2": "ISO 3166-2:CD", + "region": "Africa", + "sub-region": "Sub-Saharan Africa", + "intermediate-region": "Middle Africa", + "region-code": "002", + "sub-region-code": "202", + "intermediate-region-code": "017" + }, + { + "name": "Cook Islands", + "alpha-2": "CK", + "alpha-3": "COK", + "country-code": "184", + "iso_3166-2": "ISO 3166-2:CK", + "region": "Oceania", + "sub-region": "Polynesia", + "intermediate-region": "", + "region-code": "009", + "sub-region-code": "061", + "intermediate-region-code": "" + }, + { + "name": "Costa Rica", + "alpha-2": "CR", + "alpha-3": "CRI", + "country-code": "188", + "iso_3166-2": "ISO 3166-2:CR", + "region": "Americas", + "sub-region": "Latin America and the Caribbean", + "intermediate-region": "Central America", + "region-code": "019", + "sub-region-code": "419", + "intermediate-region-code": "013" + }, + { + "name": "Côte d'Ivoire", + "alpha-2": "CI", + "alpha-3": "CIV", + "country-code": "384", + "iso_3166-2": "ISO 3166-2:CI", + "region": "Africa", + "sub-region": "Sub-Saharan Africa", + "intermediate-region": "Western Africa", + "region-code": "002", + "sub-region-code": "202", + "intermediate-region-code": "011" + }, + { + "name": "Croatia", + "alpha-2": "HR", + "alpha-3": "HRV", + "country-code": "191", + "iso_3166-2": "ISO 3166-2:HR", + "region": "Europe", + "sub-region": "Southern Europe", + "intermediate-region": "", + "region-code": "150", + "sub-region-code": "039", + "intermediate-region-code": "" + }, + { + "name": "Cuba", + "alpha-2": "CU", + "alpha-3": "CUB", + "country-code": "192", + "iso_3166-2": "ISO 3166-2:CU", + "region": "Americas", + "sub-region": "Latin America and the Caribbean", + "intermediate-region": "Caribbean", + "region-code": "019", + "sub-region-code": "419", + "intermediate-region-code": "029" + }, + { + "name": "Curaçao", + "alpha-2": "CW", + "alpha-3": "CUW", + "country-code": "531", + "iso_3166-2": "ISO 3166-2:CW", + "region": "Americas", + "sub-region": "Latin America and the Caribbean", + "intermediate-region": "Caribbean", + "region-code": "019", + "sub-region-code": "419", + "intermediate-region-code": "029" + }, + { + "name": "Cyprus", + "alpha-2": "CY", + "alpha-3": "CYP", + "country-code": "196", + "iso_3166-2": "ISO 3166-2:CY", + "region": "Asia", + "sub-region": "Western Asia", + "intermediate-region": "", + "region-code": "142", + "sub-region-code": "145", + "intermediate-region-code": "" + }, + { + "name": "Czechia", + "alpha-2": "CZ", + "alpha-3": "CZE", + "country-code": "203", + "iso_3166-2": "ISO 3166-2:CZ", + "region": "Europe", + "sub-region": "Eastern Europe", + "intermediate-region": "", + "region-code": "150", + "sub-region-code": "151", + "intermediate-region-code": "" + }, + { + "name": "Denmark", + "alpha-2": "DK", + "alpha-3": "DNK", + "country-code": "208", + "iso_3166-2": "ISO 3166-2:DK", + "region": "Europe", + "sub-region": "Northern Europe", + "intermediate-region": "", + "region-code": "150", + "sub-region-code": "154", + "intermediate-region-code": "" + }, + { + "name": "Djibouti", + "alpha-2": "DJ", + "alpha-3": "DJI", + "country-code": "262", + "iso_3166-2": "ISO 3166-2:DJ", + "region": "Africa", + "sub-region": "Sub-Saharan Africa", + "intermediate-region": "Eastern Africa", + "region-code": "002", + "sub-region-code": "202", + "intermediate-region-code": "014" + }, + { + "name": "Dominica", + "alpha-2": "DM", + "alpha-3": "DMA", + "country-code": "212", + "iso_3166-2": "ISO 3166-2:DM", + "region": "Americas", + "sub-region": "Latin America and the Caribbean", + "intermediate-region": "Caribbean", + "region-code": "019", + "sub-region-code": "419", + "intermediate-region-code": "029" + }, + { + "name": "Dominican Republic", + "alpha-2": "DO", + "alpha-3": "DOM", + "country-code": "214", + "iso_3166-2": "ISO 3166-2:DO", + "region": "Americas", + "sub-region": "Latin America and the Caribbean", + "intermediate-region": "Caribbean", + "region-code": "019", + "sub-region-code": "419", + "intermediate-region-code": "029" + }, + { + "name": "Ecuador", + "alpha-2": "EC", + "alpha-3": "ECU", + "country-code": "218", + "iso_3166-2": "ISO 3166-2:EC", + "region": "Americas", + "sub-region": "Latin America and the Caribbean", + "intermediate-region": "South America", + "region-code": "019", + "sub-region-code": "419", + "intermediate-region-code": "005" + }, + { + "name": "Egypt", + "alpha-2": "EG", + "alpha-3": "EGY", + "country-code": "818", + "iso_3166-2": "ISO 3166-2:EG", + "region": "Africa", + "sub-region": "Northern Africa", + "intermediate-region": "", + "region-code": "002", + "sub-region-code": "015", + "intermediate-region-code": "" + }, + { + "name": "El Salvador", + "alpha-2": "SV", + "alpha-3": "SLV", + "country-code": "222", + "iso_3166-2": "ISO 3166-2:SV", + "region": "Americas", + "sub-region": "Latin America and the Caribbean", + "intermediate-region": "Central America", + "region-code": "019", + "sub-region-code": "419", + "intermediate-region-code": "013" + }, + { + "name": "Equatorial Guinea", + "alpha-2": "GQ", + "alpha-3": "GNQ", + "country-code": "226", + "iso_3166-2": "ISO 3166-2:GQ", + "region": "Africa", + "sub-region": "Sub-Saharan Africa", + "intermediate-region": "Middle Africa", + "region-code": "002", + "sub-region-code": "202", + "intermediate-region-code": "017" + }, + { + "name": "Eritrea", + "alpha-2": "ER", + "alpha-3": "ERI", + "country-code": "232", + "iso_3166-2": "ISO 3166-2:ER", + "region": "Africa", + "sub-region": "Sub-Saharan Africa", + "intermediate-region": "Eastern Africa", + "region-code": "002", + "sub-region-code": "202", + "intermediate-region-code": "014" + }, + { + "name": "Estonia", + "alpha-2": "EE", + "alpha-3": "EST", + "country-code": "233", + "iso_3166-2": "ISO 3166-2:EE", + "region": "Europe", + "sub-region": "Northern Europe", + "intermediate-region": "", + "region-code": "150", + "sub-region-code": "154", + "intermediate-region-code": "" + }, + { + "name": "Eswatini", + "alpha-2": "SZ", + "alpha-3": "SWZ", + "country-code": "748", + "iso_3166-2": "ISO 3166-2:SZ", + "region": "Africa", + "sub-region": "Sub-Saharan Africa", + "intermediate-region": "Southern Africa", + "region-code": "002", + "sub-region-code": "202", + "intermediate-region-code": "018" + }, + { + "name": "Ethiopia", + "alpha-2": "ET", + "alpha-3": "ETH", + "country-code": "231", + "iso_3166-2": "ISO 3166-2:ET", + "region": "Africa", + "sub-region": "Sub-Saharan Africa", + "intermediate-region": "Eastern Africa", + "region-code": "002", + "sub-region-code": "202", + "intermediate-region-code": "014" + }, + { + "name": "Falkland Islands (Malvinas)", + "alpha-2": "FK", + "alpha-3": "FLK", + "country-code": "238", + "iso_3166-2": "ISO 3166-2:FK", + "region": "Americas", + "sub-region": "Latin America and the Caribbean", + "intermediate-region": "South America", + "region-code": "019", + "sub-region-code": "419", + "intermediate-region-code": "005" + }, + { + "name": "Faroe Islands", + "alpha-2": "FO", + "alpha-3": "FRO", + "country-code": "234", + "iso_3166-2": "ISO 3166-2:FO", + "region": "Europe", + "sub-region": "Northern Europe", + "intermediate-region": "", + "region-code": "150", + "sub-region-code": "154", + "intermediate-region-code": "" + }, + { + "name": "Fiji", + "alpha-2": "FJ", + "alpha-3": "FJI", + "country-code": "242", + "iso_3166-2": "ISO 3166-2:FJ", + "region": "Oceania", + "sub-region": "Melanesia", + "intermediate-region": "", + "region-code": "009", + "sub-region-code": "054", + "intermediate-region-code": "" + }, + { + "name": "Finland", + "alpha-2": "FI", + "alpha-3": "FIN", + "country-code": "246", + "iso_3166-2": "ISO 3166-2:FI", + "region": "Europe", + "sub-region": "Northern Europe", + "intermediate-region": "", + "region-code": "150", + "sub-region-code": "154", + "intermediate-region-code": "" + }, + { + "name": "France", + "alpha-2": "FR", + "alpha-3": "FRA", + "country-code": "250", + "iso_3166-2": "ISO 3166-2:FR", + "region": "Europe", + "sub-region": "Western Europe", + "intermediate-region": "", + "region-code": "150", + "sub-region-code": "155", + "intermediate-region-code": "" + }, + { + "name": "French Guiana", + "alpha-2": "GF", + "alpha-3": "GUF", + "country-code": "254", + "iso_3166-2": "ISO 3166-2:GF", + "region": "Americas", + "sub-region": "Latin America and the Caribbean", + "intermediate-region": "South America", + "region-code": "019", + "sub-region-code": "419", + "intermediate-region-code": "005" + }, + { + "name": "French Polynesia", + "alpha-2": "PF", + "alpha-3": "PYF", + "country-code": "258", + "iso_3166-2": "ISO 3166-2:PF", + "region": "Oceania", + "sub-region": "Polynesia", + "intermediate-region": "", + "region-code": "009", + "sub-region-code": "061", + "intermediate-region-code": "" + }, + { + "name": "French Southern Territories", + "alpha-2": "TF", + "alpha-3": "ATF", + "country-code": "260", + "iso_3166-2": "ISO 3166-2:TF", + "region": "Africa", + "sub-region": "Sub-Saharan Africa", + "intermediate-region": "Eastern Africa", + "region-code": "002", + "sub-region-code": "202", + "intermediate-region-code": "014" + }, + { + "name": "Gabon", + "alpha-2": "GA", + "alpha-3": "GAB", + "country-code": "266", + "iso_3166-2": "ISO 3166-2:GA", + "region": "Africa", + "sub-region": "Sub-Saharan Africa", + "intermediate-region": "Middle Africa", + "region-code": "002", + "sub-region-code": "202", + "intermediate-region-code": "017" + }, + { + "name": "Gambia", + "alpha-2": "GM", + "alpha-3": "GMB", + "country-code": "270", + "iso_3166-2": "ISO 3166-2:GM", + "region": "Africa", + "sub-region": "Sub-Saharan Africa", + "intermediate-region": "Western Africa", + "region-code": "002", + "sub-region-code": "202", + "intermediate-region-code": "011" + }, + { + "name": "Georgia", + "alpha-2": "GE", + "alpha-3": "GEO", + "country-code": "268", + "iso_3166-2": "ISO 3166-2:GE", + "region": "Asia", + "sub-region": "Western Asia", + "intermediate-region": "", + "region-code": "142", + "sub-region-code": "145", + "intermediate-region-code": "" + }, + { + "name": "Germany", + "alpha-2": "DE", + "alpha-3": "DEU", + "country-code": "276", + "iso_3166-2": "ISO 3166-2:DE", + "region": "Europe", + "sub-region": "Western Europe", + "intermediate-region": "", + "region-code": "150", + "sub-region-code": "155", + "intermediate-region-code": "" + }, + { + "name": "Ghana", + "alpha-2": "GH", + "alpha-3": "GHA", + "country-code": "288", + "iso_3166-2": "ISO 3166-2:GH", + "region": "Africa", + "sub-region": "Sub-Saharan Africa", + "intermediate-region": "Western Africa", + "region-code": "002", + "sub-region-code": "202", + "intermediate-region-code": "011" + }, + { + "name": "Gibraltar", + "alpha-2": "GI", + "alpha-3": "GIB", + "country-code": "292", + "iso_3166-2": "ISO 3166-2:GI", + "region": "Europe", + "sub-region": "Southern Europe", + "intermediate-region": "", + "region-code": "150", + "sub-region-code": "039", + "intermediate-region-code": "" + }, + { + "name": "Greece", + "alpha-2": "GR", + "alpha-3": "GRC", + "country-code": "300", + "iso_3166-2": "ISO 3166-2:GR", + "region": "Europe", + "sub-region": "Southern Europe", + "intermediate-region": "", + "region-code": "150", + "sub-region-code": "039", + "intermediate-region-code": "" + }, + { + "name": "Greenland", + "alpha-2": "GL", + "alpha-3": "GRL", + "country-code": "304", + "iso_3166-2": "ISO 3166-2:GL", + "region": "Americas", + "sub-region": "Northern America", + "intermediate-region": "", + "region-code": "019", + "sub-region-code": "021", + "intermediate-region-code": "" + }, + { + "name": "Grenada", + "alpha-2": "GD", + "alpha-3": "GRD", + "country-code": "308", + "iso_3166-2": "ISO 3166-2:GD", + "region": "Americas", + "sub-region": "Latin America and the Caribbean", + "intermediate-region": "Caribbean", + "region-code": "019", + "sub-region-code": "419", + "intermediate-region-code": "029" + }, + { + "name": "Guadeloupe", + "alpha-2": "GP", + "alpha-3": "GLP", + "country-code": "312", + "iso_3166-2": "ISO 3166-2:GP", + "region": "Americas", + "sub-region": "Latin America and the Caribbean", + "intermediate-region": "Caribbean", + "region-code": "019", + "sub-region-code": "419", + "intermediate-region-code": "029" + }, + { + "name": "Guam", + "alpha-2": "GU", + "alpha-3": "GUM", + "country-code": "316", + "iso_3166-2": "ISO 3166-2:GU", + "region": "Oceania", + "sub-region": "Micronesia", + "intermediate-region": "", + "region-code": "009", + "sub-region-code": "057", + "intermediate-region-code": "" + }, + { + "name": "Guatemala", + "alpha-2": "GT", + "alpha-3": "GTM", + "country-code": "320", + "iso_3166-2": "ISO 3166-2:GT", + "region": "Americas", + "sub-region": "Latin America and the Caribbean", + "intermediate-region": "Central America", + "region-code": "019", + "sub-region-code": "419", + "intermediate-region-code": "013" + }, + { + "name": "Guernsey", + "alpha-2": "GG", + "alpha-3": "GGY", + "country-code": "831", + "iso_3166-2": "ISO 3166-2:GG", + "region": "Europe", + "sub-region": "Northern Europe", + "intermediate-region": "Channel Islands", + "region-code": "150", + "sub-region-code": "154", + "intermediate-region-code": "830" + }, + { + "name": "Guinea", + "alpha-2": "GN", + "alpha-3": "GIN", + "country-code": "324", + "iso_3166-2": "ISO 3166-2:GN", + "region": "Africa", + "sub-region": "Sub-Saharan Africa", + "intermediate-region": "Western Africa", + "region-code": "002", + "sub-region-code": "202", + "intermediate-region-code": "011" + }, + { + "name": "Guinea-Bissau", + "alpha-2": "GW", + "alpha-3": "GNB", + "country-code": "624", + "iso_3166-2": "ISO 3166-2:GW", + "region": "Africa", + "sub-region": "Sub-Saharan Africa", + "intermediate-region": "Western Africa", + "region-code": "002", + "sub-region-code": "202", + "intermediate-region-code": "011" + }, + { + "name": "Guyana", + "alpha-2": "GY", + "alpha-3": "GUY", + "country-code": "328", + "iso_3166-2": "ISO 3166-2:GY", + "region": "Americas", + "sub-region": "Latin America and the Caribbean", + "intermediate-region": "South America", + "region-code": "019", + "sub-region-code": "419", + "intermediate-region-code": "005" + }, + { + "name": "Haiti", + "alpha-2": "HT", + "alpha-3": "HTI", + "country-code": "332", + "iso_3166-2": "ISO 3166-2:HT", + "region": "Americas", + "sub-region": "Latin America and the Caribbean", + "intermediate-region": "Caribbean", + "region-code": "019", + "sub-region-code": "419", + "intermediate-region-code": "029" + }, + { + "name": "Heard Island and McDonald Islands", + "alpha-2": "HM", + "alpha-3": "HMD", + "country-code": "334", + "iso_3166-2": "ISO 3166-2:HM", + "region": "Oceania", + "sub-region": "Australia and New Zealand", + "intermediate-region": "", + "region-code": "009", + "sub-region-code": "053", + "intermediate-region-code": "" + }, + { + "name": "Holy See", + "alpha-2": "VA", + "alpha-3": "VAT", + "country-code": "336", + "iso_3166-2": "ISO 3166-2:VA", + "region": "Europe", + "sub-region": "Southern Europe", + "intermediate-region": "", + "region-code": "150", + "sub-region-code": "039", + "intermediate-region-code": "" + }, + { + "name": "Honduras", + "alpha-2": "HN", + "alpha-3": "HND", + "country-code": "340", + "iso_3166-2": "ISO 3166-2:HN", + "region": "Americas", + "sub-region": "Latin America and the Caribbean", + "intermediate-region": "Central America", + "region-code": "019", + "sub-region-code": "419", + "intermediate-region-code": "013" + }, + { + "name": "Hong Kong", + "alpha-2": "HK", + "alpha-3": "HKG", + "country-code": "344", + "iso_3166-2": "ISO 3166-2:HK", + "region": "Asia", + "sub-region": "Eastern Asia", + "intermediate-region": "", + "region-code": "142", + "sub-region-code": "030", + "intermediate-region-code": "" + }, + { + "name": "Hungary", + "alpha-2": "HU", + "alpha-3": "HUN", + "country-code": "348", + "iso_3166-2": "ISO 3166-2:HU", + "region": "Europe", + "sub-region": "Eastern Europe", + "intermediate-region": "", + "region-code": "150", + "sub-region-code": "151", + "intermediate-region-code": "" + }, + { + "name": "Iceland", + "alpha-2": "IS", + "alpha-3": "ISL", + "country-code": "352", + "iso_3166-2": "ISO 3166-2:IS", + "region": "Europe", + "sub-region": "Northern Europe", + "intermediate-region": "", + "region-code": "150", + "sub-region-code": "154", + "intermediate-region-code": "" + }, + { + "name": "India", + "alpha-2": "IN", + "alpha-3": "IND", + "country-code": "356", + "iso_3166-2": "ISO 3166-2:IN", + "region": "Asia", + "sub-region": "Southern Asia", + "intermediate-region": "", + "region-code": "142", + "sub-region-code": "034", + "intermediate-region-code": "" + }, + { + "name": "Indonesia", + "alpha-2": "ID", + "alpha-3": "IDN", + "country-code": "360", + "iso_3166-2": "ISO 3166-2:ID", + "region": "Asia", + "sub-region": "South-eastern Asia", + "intermediate-region": "", + "region-code": "142", + "sub-region-code": "035", + "intermediate-region-code": "" + }, + { + "name": "Iran (Islamic Republic of)", + "alpha-2": "IR", + "alpha-3": "IRN", + "country-code": "364", + "iso_3166-2": "ISO 3166-2:IR", + "region": "Asia", + "sub-region": "Southern Asia", + "intermediate-region": "", + "region-code": "142", + "sub-region-code": "034", + "intermediate-region-code": "" + }, + { + "name": "Iraq", + "alpha-2": "IQ", + "alpha-3": "IRQ", + "country-code": "368", + "iso_3166-2": "ISO 3166-2:IQ", + "region": "Asia", + "sub-region": "Western Asia", + "intermediate-region": "", + "region-code": "142", + "sub-region-code": "145", + "intermediate-region-code": "" + }, + { + "name": "Ireland", + "alpha-2": "IE", + "alpha-3": "IRL", + "country-code": "372", + "iso_3166-2": "ISO 3166-2:IE", + "region": "Europe", + "sub-region": "Northern Europe", + "intermediate-region": "", + "region-code": "150", + "sub-region-code": "154", + "intermediate-region-code": "" + }, + { + "name": "Isle of Man", + "alpha-2": "IM", + "alpha-3": "IMN", + "country-code": "833", + "iso_3166-2": "ISO 3166-2:IM", + "region": "Europe", + "sub-region": "Northern Europe", + "intermediate-region": "", + "region-code": "150", + "sub-region-code": "154", + "intermediate-region-code": "" + }, + { + "name": "Israel", + "alpha-2": "IL", + "alpha-3": "ISR", + "country-code": "376", + "iso_3166-2": "ISO 3166-2:IL", + "region": "Asia", + "sub-region": "Western Asia", + "intermediate-region": "", + "region-code": "142", + "sub-region-code": "145", + "intermediate-region-code": "" + }, + { + "name": "Italy", + "alpha-2": "IT", + "alpha-3": "ITA", + "country-code": "380", + "iso_3166-2": "ISO 3166-2:IT", + "region": "Europe", + "sub-region": "Southern Europe", + "intermediate-region": "", + "region-code": "150", + "sub-region-code": "039", + "intermediate-region-code": "" + }, + { + "name": "Jamaica", + "alpha-2": "JM", + "alpha-3": "JAM", + "country-code": "388", + "iso_3166-2": "ISO 3166-2:JM", + "region": "Americas", + "sub-region": "Latin America and the Caribbean", + "intermediate-region": "Caribbean", + "region-code": "019", + "sub-region-code": "419", + "intermediate-region-code": "029" + }, + { + "name": "Japan", + "alpha-2": "JP", + "alpha-3": "JPN", + "country-code": "392", + "iso_3166-2": "ISO 3166-2:JP", + "region": "Asia", + "sub-region": "Eastern Asia", + "intermediate-region": "", + "region-code": "142", + "sub-region-code": "030", + "intermediate-region-code": "" + }, + { + "name": "Jersey", + "alpha-2": "JE", + "alpha-3": "JEY", + "country-code": "832", + "iso_3166-2": "ISO 3166-2:JE", + "region": "Europe", + "sub-region": "Northern Europe", + "intermediate-region": "Channel Islands", + "region-code": "150", + "sub-region-code": "154", + "intermediate-region-code": "830" + }, + { + "name": "Jordan", + "alpha-2": "JO", + "alpha-3": "JOR", + "country-code": "400", + "iso_3166-2": "ISO 3166-2:JO", + "region": "Asia", + "sub-region": "Western Asia", + "intermediate-region": "", + "region-code": "142", + "sub-region-code": "145", + "intermediate-region-code": "" + }, + { + "name": "Kazakhstan", + "alpha-2": "KZ", + "alpha-3": "KAZ", + "country-code": "398", + "iso_3166-2": "ISO 3166-2:KZ", + "region": "Asia", + "sub-region": "Central Asia", + "intermediate-region": "", + "region-code": "142", + "sub-region-code": "143", + "intermediate-region-code": "" + }, + { + "name": "Kenya", + "alpha-2": "KE", + "alpha-3": "KEN", + "country-code": "404", + "iso_3166-2": "ISO 3166-2:KE", + "region": "Africa", + "sub-region": "Sub-Saharan Africa", + "intermediate-region": "Eastern Africa", + "region-code": "002", + "sub-region-code": "202", + "intermediate-region-code": "014" + }, + { + "name": "Kiribati", + "alpha-2": "KI", + "alpha-3": "KIR", + "country-code": "296", + "iso_3166-2": "ISO 3166-2:KI", + "region": "Oceania", + "sub-region": "Micronesia", + "intermediate-region": "", + "region-code": "009", + "sub-region-code": "057", + "intermediate-region-code": "" + }, + { + "name": "Korea (Democratic People's Republic of)", + "alpha-2": "KP", + "alpha-3": "PRK", + "country-code": "408", + "iso_3166-2": "ISO 3166-2:KP", + "region": "Asia", + "sub-region": "Eastern Asia", + "intermediate-region": "", + "region-code": "142", + "sub-region-code": "030", + "intermediate-region-code": "" + }, + { + "name": "Korea (Republic of)", + "alpha-2": "KR", + "alpha-3": "KOR", + "country-code": "410", + "iso_3166-2": "ISO 3166-2:KR", + "region": "Asia", + "sub-region": "Eastern Asia", + "intermediate-region": "", + "region-code": "142", + "sub-region-code": "030", + "intermediate-region-code": "" + }, + { + "name": "Kuwait", + "alpha-2": "KW", + "alpha-3": "KWT", + "country-code": "414", + "iso_3166-2": "ISO 3166-2:KW", + "region": "Asia", + "sub-region": "Western Asia", + "intermediate-region": "", + "region-code": "142", + "sub-region-code": "145", + "intermediate-region-code": "" + }, + { + "name": "Kyrgyzstan", + "alpha-2": "KG", + "alpha-3": "KGZ", + "country-code": "417", + "iso_3166-2": "ISO 3166-2:KG", + "region": "Asia", + "sub-region": "Central Asia", + "intermediate-region": "", + "region-code": "142", + "sub-region-code": "143", + "intermediate-region-code": "" + }, + { + "name": "Lao People's Democratic Republic", + "alpha-2": "LA", + "alpha-3": "LAO", + "country-code": "418", + "iso_3166-2": "ISO 3166-2:LA", + "region": "Asia", + "sub-region": "South-eastern Asia", + "intermediate-region": "", + "region-code": "142", + "sub-region-code": "035", + "intermediate-region-code": "" + }, + { + "name": "Latvia", + "alpha-2": "LV", + "alpha-3": "LVA", + "country-code": "428", + "iso_3166-2": "ISO 3166-2:LV", + "region": "Europe", + "sub-region": "Northern Europe", + "intermediate-region": "", + "region-code": "150", + "sub-region-code": "154", + "intermediate-region-code": "" + }, + { + "name": "Lebanon", + "alpha-2": "LB", + "alpha-3": "LBN", + "country-code": "422", + "iso_3166-2": "ISO 3166-2:LB", + "region": "Asia", + "sub-region": "Western Asia", + "intermediate-region": "", + "region-code": "142", + "sub-region-code": "145", + "intermediate-region-code": "" + }, + { + "name": "Lesotho", + "alpha-2": "LS", + "alpha-3": "LSO", + "country-code": "426", + "iso_3166-2": "ISO 3166-2:LS", + "region": "Africa", + "sub-region": "Sub-Saharan Africa", + "intermediate-region": "Southern Africa", + "region-code": "002", + "sub-region-code": "202", + "intermediate-region-code": "018" + }, + { + "name": "Liberia", + "alpha-2": "LR", + "alpha-3": "LBR", + "country-code": "430", + "iso_3166-2": "ISO 3166-2:LR", + "region": "Africa", + "sub-region": "Sub-Saharan Africa", + "intermediate-region": "Western Africa", + "region-code": "002", + "sub-region-code": "202", + "intermediate-region-code": "011" + }, + { + "name": "Libya", + "alpha-2": "LY", + "alpha-3": "LBY", + "country-code": "434", + "iso_3166-2": "ISO 3166-2:LY", + "region": "Africa", + "sub-region": "Northern Africa", + "intermediate-region": "", + "region-code": "002", + "sub-region-code": "015", + "intermediate-region-code": "" + }, + { + "name": "Liechtenstein", + "alpha-2": "LI", + "alpha-3": "LIE", + "country-code": "438", + "iso_3166-2": "ISO 3166-2:LI", + "region": "Europe", + "sub-region": "Western Europe", + "intermediate-region": "", + "region-code": "150", + "sub-region-code": "155", + "intermediate-region-code": "" + }, + { + "name": "Lithuania", + "alpha-2": "LT", + "alpha-3": "LTU", + "country-code": "440", + "iso_3166-2": "ISO 3166-2:LT", + "region": "Europe", + "sub-region": "Northern Europe", + "intermediate-region": "", + "region-code": "150", + "sub-region-code": "154", + "intermediate-region-code": "" + }, + { + "name": "Luxembourg", + "alpha-2": "LU", + "alpha-3": "LUX", + "country-code": "442", + "iso_3166-2": "ISO 3166-2:LU", + "region": "Europe", + "sub-region": "Western Europe", + "intermediate-region": "", + "region-code": "150", + "sub-region-code": "155", + "intermediate-region-code": "" + }, + { + "name": "Macao", + "alpha-2": "MO", + "alpha-3": "MAC", + "country-code": "446", + "iso_3166-2": "ISO 3166-2:MO", + "region": "Asia", + "sub-region": "Eastern Asia", + "intermediate-region": "", + "region-code": "142", + "sub-region-code": "030", + "intermediate-region-code": "" + }, + { + "name": "Macedonia (the former Yugoslav Republic of)", + "alpha-2": "MK", + "alpha-3": "MKD", + "country-code": "807", + "iso_3166-2": "ISO 3166-2:MK", + "region": "Europe", + "sub-region": "Southern Europe", + "intermediate-region": "", + "region-code": "150", + "sub-region-code": "039", + "intermediate-region-code": "" + }, + { + "name": "Madagascar", + "alpha-2": "MG", + "alpha-3": "MDG", + "country-code": "450", + "iso_3166-2": "ISO 3166-2:MG", + "region": "Africa", + "sub-region": "Sub-Saharan Africa", + "intermediate-region": "Eastern Africa", + "region-code": "002", + "sub-region-code": "202", + "intermediate-region-code": "014" + }, + { + "name": "Malawi", + "alpha-2": "MW", + "alpha-3": "MWI", + "country-code": "454", + "iso_3166-2": "ISO 3166-2:MW", + "region": "Africa", + "sub-region": "Sub-Saharan Africa", + "intermediate-region": "Eastern Africa", + "region-code": "002", + "sub-region-code": "202", + "intermediate-region-code": "014" + }, + { + "name": "Malaysia", + "alpha-2": "MY", + "alpha-3": "MYS", + "country-code": "458", + "iso_3166-2": "ISO 3166-2:MY", + "region": "Asia", + "sub-region": "South-eastern Asia", + "intermediate-region": "", + "region-code": "142", + "sub-region-code": "035", + "intermediate-region-code": "" + }, + { + "name": "Maldives", + "alpha-2": "MV", + "alpha-3": "MDV", + "country-code": "462", + "iso_3166-2": "ISO 3166-2:MV", + "region": "Asia", + "sub-region": "Southern Asia", + "intermediate-region": "", + "region-code": "142", + "sub-region-code": "034", + "intermediate-region-code": "" + }, + { + "name": "Mali", + "alpha-2": "ML", + "alpha-3": "MLI", + "country-code": "466", + "iso_3166-2": "ISO 3166-2:ML", + "region": "Africa", + "sub-region": "Sub-Saharan Africa", + "intermediate-region": "Western Africa", + "region-code": "002", + "sub-region-code": "202", + "intermediate-region-code": "011" + }, + { + "name": "Malta", + "alpha-2": "MT", + "alpha-3": "MLT", + "country-code": "470", + "iso_3166-2": "ISO 3166-2:MT", + "region": "Europe", + "sub-region": "Southern Europe", + "intermediate-region": "", + "region-code": "150", + "sub-region-code": "039", + "intermediate-region-code": "" + }, + { + "name": "Marshall Islands", + "alpha-2": "MH", + "alpha-3": "MHL", + "country-code": "584", + "iso_3166-2": "ISO 3166-2:MH", + "region": "Oceania", + "sub-region": "Micronesia", + "intermediate-region": "", + "region-code": "009", + "sub-region-code": "057", + "intermediate-region-code": "" + }, + { + "name": "Martinique", + "alpha-2": "MQ", + "alpha-3": "MTQ", + "country-code": "474", + "iso_3166-2": "ISO 3166-2:MQ", + "region": "Americas", + "sub-region": "Latin America and the Caribbean", + "intermediate-region": "Caribbean", + "region-code": "019", + "sub-region-code": "419", + "intermediate-region-code": "029" + }, + { + "name": "Mauritania", + "alpha-2": "MR", + "alpha-3": "MRT", + "country-code": "478", + "iso_3166-2": "ISO 3166-2:MR", + "region": "Africa", + "sub-region": "Sub-Saharan Africa", + "intermediate-region": "Western Africa", + "region-code": "002", + "sub-region-code": "202", + "intermediate-region-code": "011" + }, + { + "name": "Mauritius", + "alpha-2": "MU", + "alpha-3": "MUS", + "country-code": "480", + "iso_3166-2": "ISO 3166-2:MU", + "region": "Africa", + "sub-region": "Sub-Saharan Africa", + "intermediate-region": "Eastern Africa", + "region-code": "002", + "sub-region-code": "202", + "intermediate-region-code": "014" + }, + { + "name": "Mayotte", + "alpha-2": "YT", + "alpha-3": "MYT", + "country-code": "175", + "iso_3166-2": "ISO 3166-2:YT", + "region": "Africa", + "sub-region": "Sub-Saharan Africa", + "intermediate-region": "Eastern Africa", + "region-code": "002", + "sub-region-code": "202", + "intermediate-region-code": "014" + }, + { + "name": "Mexico", + "alpha-2": "MX", + "alpha-3": "MEX", + "country-code": "484", + "iso_3166-2": "ISO 3166-2:MX", + "region": "Americas", + "sub-region": "Latin America and the Caribbean", + "intermediate-region": "Central America", + "region-code": "019", + "sub-region-code": "419", + "intermediate-region-code": "013" + }, + { + "name": "Micronesia (Federated States of)", + "alpha-2": "FM", + "alpha-3": "FSM", + "country-code": "583", + "iso_3166-2": "ISO 3166-2:FM", + "region": "Oceania", + "sub-region": "Micronesia", + "intermediate-region": "", + "region-code": "009", + "sub-region-code": "057", + "intermediate-region-code": "" + }, + { + "name": "Moldova (Republic of)", + "alpha-2": "MD", + "alpha-3": "MDA", + "country-code": "498", + "iso_3166-2": "ISO 3166-2:MD", + "region": "Europe", + "sub-region": "Eastern Europe", + "intermediate-region": "", + "region-code": "150", + "sub-region-code": "151", + "intermediate-region-code": "" + }, + { + "name": "Monaco", + "alpha-2": "MC", + "alpha-3": "MCO", + "country-code": "492", + "iso_3166-2": "ISO 3166-2:MC", + "region": "Europe", + "sub-region": "Western Europe", + "intermediate-region": "", + "region-code": "150", + "sub-region-code": "155", + "intermediate-region-code": "" + }, + { + "name": "Mongolia", + "alpha-2": "MN", + "alpha-3": "MNG", + "country-code": "496", + "iso_3166-2": "ISO 3166-2:MN", + "region": "Asia", + "sub-region": "Eastern Asia", + "intermediate-region": "", + "region-code": "142", + "sub-region-code": "030", + "intermediate-region-code": "" + }, + { + "name": "Montenegro", + "alpha-2": "ME", + "alpha-3": "MNE", + "country-code": "499", + "iso_3166-2": "ISO 3166-2:ME", + "region": "Europe", + "sub-region": "Southern Europe", + "intermediate-region": "", + "region-code": "150", + "sub-region-code": "039", + "intermediate-region-code": "" + }, + { + "name": "Montserrat", + "alpha-2": "MS", + "alpha-3": "MSR", + "country-code": "500", + "iso_3166-2": "ISO 3166-2:MS", + "region": "Americas", + "sub-region": "Latin America and the Caribbean", + "intermediate-region": "Caribbean", + "region-code": "019", + "sub-region-code": "419", + "intermediate-region-code": "029" + }, + { + "name": "Morocco", + "alpha-2": "MA", + "alpha-3": "MAR", + "country-code": "504", + "iso_3166-2": "ISO 3166-2:MA", + "region": "Africa", + "sub-region": "Northern Africa", + "intermediate-region": "", + "region-code": "002", + "sub-region-code": "015", + "intermediate-region-code": "" + }, + { + "name": "Mozambique", + "alpha-2": "MZ", + "alpha-3": "MOZ", + "country-code": "508", + "iso_3166-2": "ISO 3166-2:MZ", + "region": "Africa", + "sub-region": "Sub-Saharan Africa", + "intermediate-region": "Eastern Africa", + "region-code": "002", + "sub-region-code": "202", + "intermediate-region-code": "014" + }, + { + "name": "Myanmar", + "alpha-2": "MM", + "alpha-3": "MMR", + "country-code": "104", + "iso_3166-2": "ISO 3166-2:MM", + "region": "Asia", + "sub-region": "South-eastern Asia", + "intermediate-region": "", + "region-code": "142", + "sub-region-code": "035", + "intermediate-region-code": "" + }, + { + "name": "Namibia", + "alpha-2": "NA", + "alpha-3": "NAM", + "country-code": "516", + "iso_3166-2": "ISO 3166-2:NA", + "region": "Africa", + "sub-region": "Sub-Saharan Africa", + "intermediate-region": "Southern Africa", + "region-code": "002", + "sub-region-code": "202", + "intermediate-region-code": "018" + }, + { + "name": "Nauru", + "alpha-2": "NR", + "alpha-3": "NRU", + "country-code": "520", + "iso_3166-2": "ISO 3166-2:NR", + "region": "Oceania", + "sub-region": "Micronesia", + "intermediate-region": "", + "region-code": "009", + "sub-region-code": "057", + "intermediate-region-code": "" + }, + { + "name": "Nepal", + "alpha-2": "NP", + "alpha-3": "NPL", + "country-code": "524", + "iso_3166-2": "ISO 3166-2:NP", + "region": "Asia", + "sub-region": "Southern Asia", + "intermediate-region": "", + "region-code": "142", + "sub-region-code": "034", + "intermediate-region-code": "" + }, + { + "name": "Netherlands", + "alpha-2": "NL", + "alpha-3": "NLD", + "country-code": "528", + "iso_3166-2": "ISO 3166-2:NL", + "region": "Europe", + "sub-region": "Western Europe", + "intermediate-region": "", + "region-code": "150", + "sub-region-code": "155", + "intermediate-region-code": "" + }, + { + "name": "New Caledonia", + "alpha-2": "NC", + "alpha-3": "NCL", + "country-code": "540", + "iso_3166-2": "ISO 3166-2:NC", + "region": "Oceania", + "sub-region": "Melanesia", + "intermediate-region": "", + "region-code": "009", + "sub-region-code": "054", + "intermediate-region-code": "" + }, + { + "name": "New Zealand", + "alpha-2": "NZ", + "alpha-3": "NZL", + "country-code": "554", + "iso_3166-2": "ISO 3166-2:NZ", + "region": "Oceania", + "sub-region": "Australia and New Zealand", + "intermediate-region": "", + "region-code": "009", + "sub-region-code": "053", + "intermediate-region-code": "" + }, + { + "name": "Nicaragua", + "alpha-2": "NI", + "alpha-3": "NIC", + "country-code": "558", + "iso_3166-2": "ISO 3166-2:NI", + "region": "Americas", + "sub-region": "Latin America and the Caribbean", + "intermediate-region": "Central America", + "region-code": "019", + "sub-region-code": "419", + "intermediate-region-code": "013" + }, + { + "name": "Niger", + "alpha-2": "NE", + "alpha-3": "NER", + "country-code": "562", + "iso_3166-2": "ISO 3166-2:NE", + "region": "Africa", + "sub-region": "Sub-Saharan Africa", + "intermediate-region": "Western Africa", + "region-code": "002", + "sub-region-code": "202", + "intermediate-region-code": "011" + }, + { + "name": "Nigeria", + "alpha-2": "NG", + "alpha-3": "NGA", + "country-code": "566", + "iso_3166-2": "ISO 3166-2:NG", + "region": "Africa", + "sub-region": "Sub-Saharan Africa", + "intermediate-region": "Western Africa", + "region-code": "002", + "sub-region-code": "202", + "intermediate-region-code": "011" + }, + { + "name": "Niue", + "alpha-2": "NU", + "alpha-3": "NIU", + "country-code": "570", + "iso_3166-2": "ISO 3166-2:NU", + "region": "Oceania", + "sub-region": "Polynesia", + "intermediate-region": "", + "region-code": "009", + "sub-region-code": "061", + "intermediate-region-code": "" + }, + { + "name": "Norfolk Island", + "alpha-2": "NF", + "alpha-3": "NFK", + "country-code": "574", + "iso_3166-2": "ISO 3166-2:NF", + "region": "Oceania", + "sub-region": "Australia and New Zealand", + "intermediate-region": "", + "region-code": "009", + "sub-region-code": "053", + "intermediate-region-code": "" + }, + { + "name": "Northern Mariana Islands", + "alpha-2": "MP", + "alpha-3": "MNP", + "country-code": "580", + "iso_3166-2": "ISO 3166-2:MP", + "region": "Oceania", + "sub-region": "Micronesia", + "intermediate-region": "", + "region-code": "009", + "sub-region-code": "057", + "intermediate-region-code": "" + }, + { + "name": "Norway", + "alpha-2": "NO", + "alpha-3": "NOR", + "country-code": "578", + "iso_3166-2": "ISO 3166-2:NO", + "region": "Europe", + "sub-region": "Northern Europe", + "intermediate-region": "", + "region-code": "150", + "sub-region-code": "154", + "intermediate-region-code": "" + }, + { + "name": "Oman", + "alpha-2": "OM", + "alpha-3": "OMN", + "country-code": "512", + "iso_3166-2": "ISO 3166-2:OM", + "region": "Asia", + "sub-region": "Western Asia", + "intermediate-region": "", + "region-code": "142", + "sub-region-code": "145", + "intermediate-region-code": "" + }, + { + "name": "Pakistan", + "alpha-2": "PK", + "alpha-3": "PAK", + "country-code": "586", + "iso_3166-2": "ISO 3166-2:PK", + "region": "Asia", + "sub-region": "Southern Asia", + "intermediate-region": "", + "region-code": "142", + "sub-region-code": "034", + "intermediate-region-code": "" + }, + { + "name": "Palau", + "alpha-2": "PW", + "alpha-3": "PLW", + "country-code": "585", + "iso_3166-2": "ISO 3166-2:PW", + "region": "Oceania", + "sub-region": "Micronesia", + "intermediate-region": "", + "region-code": "009", + "sub-region-code": "057", + "intermediate-region-code": "" + }, + { + "name": "Palestine, State of", + "alpha-2": "PS", + "alpha-3": "PSE", + "country-code": "275", + "iso_3166-2": "ISO 3166-2:PS", + "region": "Asia", + "sub-region": "Western Asia", + "intermediate-region": "", + "region-code": "142", + "sub-region-code": "145", + "intermediate-region-code": "" + }, + { + "name": "Panama", + "alpha-2": "PA", + "alpha-3": "PAN", + "country-code": "591", + "iso_3166-2": "ISO 3166-2:PA", + "region": "Americas", + "sub-region": "Latin America and the Caribbean", + "intermediate-region": "Central America", + "region-code": "019", + "sub-region-code": "419", + "intermediate-region-code": "013" + }, + { + "name": "Papua New Guinea", + "alpha-2": "PG", + "alpha-3": "PNG", + "country-code": "598", + "iso_3166-2": "ISO 3166-2:PG", + "region": "Oceania", + "sub-region": "Melanesia", + "intermediate-region": "", + "region-code": "009", + "sub-region-code": "054", + "intermediate-region-code": "" + }, + { + "name": "Paraguay", + "alpha-2": "PY", + "alpha-3": "PRY", + "country-code": "600", + "iso_3166-2": "ISO 3166-2:PY", + "region": "Americas", + "sub-region": "Latin America and the Caribbean", + "intermediate-region": "South America", + "region-code": "019", + "sub-region-code": "419", + "intermediate-region-code": "005" + }, + { + "name": "Peru", + "alpha-2": "PE", + "alpha-3": "PER", + "country-code": "604", + "iso_3166-2": "ISO 3166-2:PE", + "region": "Americas", + "sub-region": "Latin America and the Caribbean", + "intermediate-region": "South America", + "region-code": "019", + "sub-region-code": "419", + "intermediate-region-code": "005" + }, + { + "name": "Philippines", + "alpha-2": "PH", + "alpha-3": "PHL", + "country-code": "608", + "iso_3166-2": "ISO 3166-2:PH", + "region": "Asia", + "sub-region": "South-eastern Asia", + "intermediate-region": "", + "region-code": "142", + "sub-region-code": "035", + "intermediate-region-code": "" + }, + { + "name": "Pitcairn", + "alpha-2": "PN", + "alpha-3": "PCN", + "country-code": "612", + "iso_3166-2": "ISO 3166-2:PN", + "region": "Oceania", + "sub-region": "Polynesia", + "intermediate-region": "", + "region-code": "009", + "sub-region-code": "061", + "intermediate-region-code": "" + }, + { + "name": "Poland", + "alpha-2": "PL", + "alpha-3": "POL", + "country-code": "616", + "iso_3166-2": "ISO 3166-2:PL", + "region": "Europe", + "sub-region": "Eastern Europe", + "intermediate-region": "", + "region-code": "150", + "sub-region-code": "151", + "intermediate-region-code": "" + }, + { + "name": "Portugal", + "alpha-2": "PT", + "alpha-3": "PRT", + "country-code": "620", + "iso_3166-2": "ISO 3166-2:PT", + "region": "Europe", + "sub-region": "Southern Europe", + "intermediate-region": "", + "region-code": "150", + "sub-region-code": "039", + "intermediate-region-code": "" + }, + { + "name": "Puerto Rico", + "alpha-2": "PR", + "alpha-3": "PRI", + "country-code": "630", + "iso_3166-2": "ISO 3166-2:PR", + "region": "Americas", + "sub-region": "Latin America and the Caribbean", + "intermediate-region": "Caribbean", + "region-code": "019", + "sub-region-code": "419", + "intermediate-region-code": "029" + }, + { + "name": "Qatar", + "alpha-2": "QA", + "alpha-3": "QAT", + "country-code": "634", + "iso_3166-2": "ISO 3166-2:QA", + "region": "Asia", + "sub-region": "Western Asia", + "intermediate-region": "", + "region-code": "142", + "sub-region-code": "145", + "intermediate-region-code": "" + }, + { + "name": "Réunion", + "alpha-2": "RE", + "alpha-3": "REU", + "country-code": "638", + "iso_3166-2": "ISO 3166-2:RE", + "region": "Africa", + "sub-region": "Sub-Saharan Africa", + "intermediate-region": "Eastern Africa", + "region-code": "002", + "sub-region-code": "202", + "intermediate-region-code": "014" + }, + { + "name": "Romania", + "alpha-2": "RO", + "alpha-3": "ROU", + "country-code": "642", + "iso_3166-2": "ISO 3166-2:RO", + "region": "Europe", + "sub-region": "Eastern Europe", + "intermediate-region": "", + "region-code": "150", + "sub-region-code": "151", + "intermediate-region-code": "" + }, + { + "name": "Russian Federation", + "alpha-2": "RU", + "alpha-3": "RUS", + "country-code": "643", + "iso_3166-2": "ISO 3166-2:RU", + "region": "Europe", + "sub-region": "Eastern Europe", + "intermediate-region": "", + "region-code": "150", + "sub-region-code": "151", + "intermediate-region-code": "" + }, + { + "name": "Rwanda", + "alpha-2": "RW", + "alpha-3": "RWA", + "country-code": "646", + "iso_3166-2": "ISO 3166-2:RW", + "region": "Africa", + "sub-region": "Sub-Saharan Africa", + "intermediate-region": "Eastern Africa", + "region-code": "002", + "sub-region-code": "202", + "intermediate-region-code": "014" + }, + { + "name": "Saint Barthélemy", + "alpha-2": "BL", + "alpha-3": "BLM", + "country-code": "652", + "iso_3166-2": "ISO 3166-2:BL", + "region": "Americas", + "sub-region": "Latin America and the Caribbean", + "intermediate-region": "Caribbean", + "region-code": "019", + "sub-region-code": "419", + "intermediate-region-code": "029" + }, + { + "name": "Saint Helena, Ascension and Tristan da Cunha", + "alpha-2": "SH", + "alpha-3": "SHN", + "country-code": "654", + "iso_3166-2": "ISO 3166-2:SH", + "region": "Africa", + "sub-region": "Sub-Saharan Africa", + "intermediate-region": "Western Africa", + "region-code": "002", + "sub-region-code": "202", + "intermediate-region-code": "011" + }, + { + "name": "Saint Kitts and Nevis", + "alpha-2": "KN", + "alpha-3": "KNA", + "country-code": "659", + "iso_3166-2": "ISO 3166-2:KN", + "region": "Americas", + "sub-region": "Latin America and the Caribbean", + "intermediate-region": "Caribbean", + "region-code": "019", + "sub-region-code": "419", + "intermediate-region-code": "029" + }, + { + "name": "Saint Lucia", + "alpha-2": "LC", + "alpha-3": "LCA", + "country-code": "662", + "iso_3166-2": "ISO 3166-2:LC", + "region": "Americas", + "sub-region": "Latin America and the Caribbean", + "intermediate-region": "Caribbean", + "region-code": "019", + "sub-region-code": "419", + "intermediate-region-code": "029" + }, + { + "name": "Saint Martin (French part)", + "alpha-2": "MF", + "alpha-3": "MAF", + "country-code": "663", + "iso_3166-2": "ISO 3166-2:MF", + "region": "Americas", + "sub-region": "Latin America and the Caribbean", + "intermediate-region": "Caribbean", + "region-code": "019", + "sub-region-code": "419", + "intermediate-region-code": "029" + }, + { + "name": "Saint Pierre and Miquelon", + "alpha-2": "PM", + "alpha-3": "SPM", + "country-code": "666", + "iso_3166-2": "ISO 3166-2:PM", + "region": "Americas", + "sub-region": "Northern America", + "intermediate-region": "", + "region-code": "019", + "sub-region-code": "021", + "intermediate-region-code": "" + }, + { + "name": "Saint Vincent and the Grenadines", + "alpha-2": "VC", + "alpha-3": "VCT", + "country-code": "670", + "iso_3166-2": "ISO 3166-2:VC", + "region": "Americas", + "sub-region": "Latin America and the Caribbean", + "intermediate-region": "Caribbean", + "region-code": "019", + "sub-region-code": "419", + "intermediate-region-code": "029" + }, + { + "name": "Samoa", + "alpha-2": "WS", + "alpha-3": "WSM", + "country-code": "882", + "iso_3166-2": "ISO 3166-2:WS", + "region": "Oceania", + "sub-region": "Polynesia", + "intermediate-region": "", + "region-code": "009", + "sub-region-code": "061", + "intermediate-region-code": "" + }, + { + "name": "San Marino", + "alpha-2": "SM", + "alpha-3": "SMR", + "country-code": "674", + "iso_3166-2": "ISO 3166-2:SM", + "region": "Europe", + "sub-region": "Southern Europe", + "intermediate-region": "", + "region-code": "150", + "sub-region-code": "039", + "intermediate-region-code": "" + }, + { + "name": "Sao Tome and Principe", + "alpha-2": "ST", + "alpha-3": "STP", + "country-code": "678", + "iso_3166-2": "ISO 3166-2:ST", + "region": "Africa", + "sub-region": "Sub-Saharan Africa", + "intermediate-region": "Middle Africa", + "region-code": "002", + "sub-region-code": "202", + "intermediate-region-code": "017" + }, + { + "name": "Saudi Arabia", + "alpha-2": "SA", + "alpha-3": "SAU", + "country-code": "682", + "iso_3166-2": "ISO 3166-2:SA", + "region": "Asia", + "sub-region": "Western Asia", + "intermediate-region": "", + "region-code": "142", + "sub-region-code": "145", + "intermediate-region-code": "" + }, + { + "name": "Senegal", + "alpha-2": "SN", + "alpha-3": "SEN", + "country-code": "686", + "iso_3166-2": "ISO 3166-2:SN", + "region": "Africa", + "sub-region": "Sub-Saharan Africa", + "intermediate-region": "Western Africa", + "region-code": "002", + "sub-region-code": "202", + "intermediate-region-code": "011" + }, + { + "name": "Serbia", + "alpha-2": "RS", + "alpha-3": "SRB", + "country-code": "688", + "iso_3166-2": "ISO 3166-2:RS", + "region": "Europe", + "sub-region": "Southern Europe", + "intermediate-region": "", + "region-code": "150", + "sub-region-code": "039", + "intermediate-region-code": "" + }, + { + "name": "Seychelles", + "alpha-2": "SC", + "alpha-3": "SYC", + "country-code": "690", + "iso_3166-2": "ISO 3166-2:SC", + "region": "Africa", + "sub-region": "Sub-Saharan Africa", + "intermediate-region": "Eastern Africa", + "region-code": "002", + "sub-region-code": "202", + "intermediate-region-code": "014" + }, + { + "name": "Sierra Leone", + "alpha-2": "SL", + "alpha-3": "SLE", + "country-code": "694", + "iso_3166-2": "ISO 3166-2:SL", + "region": "Africa", + "sub-region": "Sub-Saharan Africa", + "intermediate-region": "Western Africa", + "region-code": "002", + "sub-region-code": "202", + "intermediate-region-code": "011" + }, + { + "name": "Singapore", + "alpha-2": "SG", + "alpha-3": "SGP", + "country-code": "702", + "iso_3166-2": "ISO 3166-2:SG", + "region": "Asia", + "sub-region": "South-eastern Asia", + "intermediate-region": "", + "region-code": "142", + "sub-region-code": "035", + "intermediate-region-code": "" + }, + { + "name": "Sint Maarten (Dutch part)", + "alpha-2": "SX", + "alpha-3": "SXM", + "country-code": "534", + "iso_3166-2": "ISO 3166-2:SX", + "region": "Americas", + "sub-region": "Latin America and the Caribbean", + "intermediate-region": "Caribbean", + "region-code": "019", + "sub-region-code": "419", + "intermediate-region-code": "029" + }, + { + "name": "Slovakia", + "alpha-2": "SK", + "alpha-3": "SVK", + "country-code": "703", + "iso_3166-2": "ISO 3166-2:SK", + "region": "Europe", + "sub-region": "Eastern Europe", + "intermediate-region": "", + "region-code": "150", + "sub-region-code": "151", + "intermediate-region-code": "" + }, + { + "name": "Slovenia", + "alpha-2": "SI", + "alpha-3": "SVN", + "country-code": "705", + "iso_3166-2": "ISO 3166-2:SI", + "region": "Europe", + "sub-region": "Southern Europe", + "intermediate-region": "", + "region-code": "150", + "sub-region-code": "039", + "intermediate-region-code": "" + }, + { + "name": "Solomon Islands", + "alpha-2": "SB", + "alpha-3": "SLB", + "country-code": "090", + "iso_3166-2": "ISO 3166-2:SB", + "region": "Oceania", + "sub-region": "Melanesia", + "intermediate-region": "", + "region-code": "009", + "sub-region-code": "054", + "intermediate-region-code": "" + }, + { + "name": "Somalia", + "alpha-2": "SO", + "alpha-3": "SOM", + "country-code": "706", + "iso_3166-2": "ISO 3166-2:SO", + "region": "Africa", + "sub-region": "Sub-Saharan Africa", + "intermediate-region": "Eastern Africa", + "region-code": "002", + "sub-region-code": "202", + "intermediate-region-code": "014" + }, + { + "name": "South Africa", + "alpha-2": "ZA", + "alpha-3": "ZAF", + "country-code": "710", + "iso_3166-2": "ISO 3166-2:ZA", + "region": "Africa", + "sub-region": "Sub-Saharan Africa", + "intermediate-region": "Southern Africa", + "region-code": "002", + "sub-region-code": "202", + "intermediate-region-code": "018" + }, + { + "name": "South Georgia and the South Sandwich Islands", + "alpha-2": "GS", + "alpha-3": "SGS", + "country-code": "239", + "iso_3166-2": "ISO 3166-2:GS", + "region": "Americas", + "sub-region": "Latin America and the Caribbean", + "intermediate-region": "South America", + "region-code": "019", + "sub-region-code": "419", + "intermediate-region-code": "005" + }, + { + "name": "South Sudan", + "alpha-2": "SS", + "alpha-3": "SSD", + "country-code": "728", + "iso_3166-2": "ISO 3166-2:SS", + "region": "Africa", + "sub-region": "Sub-Saharan Africa", + "intermediate-region": "Eastern Africa", + "region-code": "002", + "sub-region-code": "202", + "intermediate-region-code": "014" + }, + { + "name": "Spain", + "alpha-2": "ES", + "alpha-3": "ESP", + "country-code": "724", + "iso_3166-2": "ISO 3166-2:ES", + "region": "Europe", + "sub-region": "Southern Europe", + "intermediate-region": "", + "region-code": "150", + "sub-region-code": "039", + "intermediate-region-code": "" + }, + { + "name": "Sri Lanka", + "alpha-2": "LK", + "alpha-3": "LKA", + "country-code": "144", + "iso_3166-2": "ISO 3166-2:LK", + "region": "Asia", + "sub-region": "Southern Asia", + "intermediate-region": "", + "region-code": "142", + "sub-region-code": "034", + "intermediate-region-code": "" + }, + { + "name": "Sudan", + "alpha-2": "SD", + "alpha-3": "SDN", + "country-code": "729", + "iso_3166-2": "ISO 3166-2:SD", + "region": "Africa", + "sub-region": "Northern Africa", + "intermediate-region": "", + "region-code": "002", + "sub-region-code": "015", + "intermediate-region-code": "" + }, + { + "name": "Suriname", + "alpha-2": "SR", + "alpha-3": "SUR", + "country-code": "740", + "iso_3166-2": "ISO 3166-2:SR", + "region": "Americas", + "sub-region": "Latin America and the Caribbean", + "intermediate-region": "South America", + "region-code": "019", + "sub-region-code": "419", + "intermediate-region-code": "005" + }, + { + "name": "Svalbard and Jan Mayen", + "alpha-2": "SJ", + "alpha-3": "SJM", + "country-code": "744", + "iso_3166-2": "ISO 3166-2:SJ", + "region": "Europe", + "sub-region": "Northern Europe", + "intermediate-region": "", + "region-code": "150", + "sub-region-code": "154", + "intermediate-region-code": "" + }, + { + "name": "Sweden", + "alpha-2": "SE", + "alpha-3": "SWE", + "country-code": "752", + "iso_3166-2": "ISO 3166-2:SE", + "region": "Europe", + "sub-region": "Northern Europe", + "intermediate-region": "", + "region-code": "150", + "sub-region-code": "154", + "intermediate-region-code": "" + }, + { + "name": "Switzerland", + "alpha-2": "CH", + "alpha-3": "CHE", + "country-code": "756", + "iso_3166-2": "ISO 3166-2:CH", + "region": "Europe", + "sub-region": "Western Europe", + "intermediate-region": "", + "region-code": "150", + "sub-region-code": "155", + "intermediate-region-code": "" + }, + { + "name": "Syrian Arab Republic", + "alpha-2": "SY", + "alpha-3": "SYR", + "country-code": "760", + "iso_3166-2": "ISO 3166-2:SY", + "region": "Asia", + "sub-region": "Western Asia", + "intermediate-region": "", + "region-code": "142", + "sub-region-code": "145", + "intermediate-region-code": "" + }, + { + "name": "Taiwan, Province of China", + "alpha-2": "TW", + "alpha-3": "TWN", + "country-code": "158", + "iso_3166-2": "ISO 3166-2:TW", + "region": "Asia", + "sub-region": "Eastern Asia", + "intermediate-region": "", + "region-code": "142", + "sub-region-code": "030", + "intermediate-region-code": "" + }, + { + "name": "Tajikistan", + "alpha-2": "TJ", + "alpha-3": "TJK", + "country-code": "762", + "iso_3166-2": "ISO 3166-2:TJ", + "region": "Asia", + "sub-region": "Central Asia", + "intermediate-region": "", + "region-code": "142", + "sub-region-code": "143", + "intermediate-region-code": "" + }, + { + "name": "Tanzania, United Republic of", + "alpha-2": "TZ", + "alpha-3": "TZA", + "country-code": "834", + "iso_3166-2": "ISO 3166-2:TZ", + "region": "Africa", + "sub-region": "Sub-Saharan Africa", + "intermediate-region": "Eastern Africa", + "region-code": "002", + "sub-region-code": "202", + "intermediate-region-code": "014" + }, + { + "name": "Thailand", + "alpha-2": "TH", + "alpha-3": "THA", + "country-code": "764", + "iso_3166-2": "ISO 3166-2:TH", + "region": "Asia", + "sub-region": "South-eastern Asia", + "intermediate-region": "", + "region-code": "142", + "sub-region-code": "035", + "intermediate-region-code": "" + }, + { + "name": "Timor-Leste", + "alpha-2": "TL", + "alpha-3": "TLS", + "country-code": "626", + "iso_3166-2": "ISO 3166-2:TL", + "region": "Asia", + "sub-region": "South-eastern Asia", + "intermediate-region": "", + "region-code": "142", + "sub-region-code": "035", + "intermediate-region-code": "" + }, + { + "name": "Togo", + "alpha-2": "TG", + "alpha-3": "TGO", + "country-code": "768", + "iso_3166-2": "ISO 3166-2:TG", + "region": "Africa", + "sub-region": "Sub-Saharan Africa", + "intermediate-region": "Western Africa", + "region-code": "002", + "sub-region-code": "202", + "intermediate-region-code": "011" + }, + { + "name": "Tokelau", + "alpha-2": "TK", + "alpha-3": "TKL", + "country-code": "772", + "iso_3166-2": "ISO 3166-2:TK", + "region": "Oceania", + "sub-region": "Polynesia", + "intermediate-region": "", + "region-code": "009", + "sub-region-code": "061", + "intermediate-region-code": "" + }, + { + "name": "Tonga", + "alpha-2": "TO", + "alpha-3": "TON", + "country-code": "776", + "iso_3166-2": "ISO 3166-2:TO", + "region": "Oceania", + "sub-region": "Polynesia", + "intermediate-region": "", + "region-code": "009", + "sub-region-code": "061", + "intermediate-region-code": "" + }, + { + "name": "Trinidad and Tobago", + "alpha-2": "TT", + "alpha-3": "TTO", + "country-code": "780", + "iso_3166-2": "ISO 3166-2:TT", + "region": "Americas", + "sub-region": "Latin America and the Caribbean", + "intermediate-region": "Caribbean", + "region-code": "019", + "sub-region-code": "419", + "intermediate-region-code": "029" + }, + { + "name": "Tunisia", + "alpha-2": "TN", + "alpha-3": "TUN", + "country-code": "788", + "iso_3166-2": "ISO 3166-2:TN", + "region": "Africa", + "sub-region": "Northern Africa", + "intermediate-region": "", + "region-code": "002", + "sub-region-code": "015", + "intermediate-region-code": "" + }, + { + "name": "Turkey", + "alpha-2": "TR", + "alpha-3": "TUR", + "country-code": "792", + "iso_3166-2": "ISO 3166-2:TR", + "region": "Asia", + "sub-region": "Western Asia", + "intermediate-region": "", + "region-code": "142", + "sub-region-code": "145", + "intermediate-region-code": "" + }, + { + "name": "Turkmenistan", + "alpha-2": "TM", + "alpha-3": "TKM", + "country-code": "795", + "iso_3166-2": "ISO 3166-2:TM", + "region": "Asia", + "sub-region": "Central Asia", + "intermediate-region": "", + "region-code": "142", + "sub-region-code": "143", + "intermediate-region-code": "" + }, + { + "name": "Turks and Caicos Islands", + "alpha-2": "TC", + "alpha-3": "TCA", + "country-code": "796", + "iso_3166-2": "ISO 3166-2:TC", + "region": "Americas", + "sub-region": "Latin America and the Caribbean", + "intermediate-region": "Caribbean", + "region-code": "019", + "sub-region-code": "419", + "intermediate-region-code": "029" + }, + { + "name": "Tuvalu", + "alpha-2": "TV", + "alpha-3": "TUV", + "country-code": "798", + "iso_3166-2": "ISO 3166-2:TV", + "region": "Oceania", + "sub-region": "Polynesia", + "intermediate-region": "", + "region-code": "009", + "sub-region-code": "061", + "intermediate-region-code": "" + }, + { + "name": "Uganda", + "alpha-2": "UG", + "alpha-3": "UGA", + "country-code": "800", + "iso_3166-2": "ISO 3166-2:UG", + "region": "Africa", + "sub-region": "Sub-Saharan Africa", + "intermediate-region": "Eastern Africa", + "region-code": "002", + "sub-region-code": "202", + "intermediate-region-code": "014" + }, + { + "name": "Ukraine", + "alpha-2": "UA", + "alpha-3": "UKR", + "country-code": "804", + "iso_3166-2": "ISO 3166-2:UA", + "region": "Europe", + "sub-region": "Eastern Europe", + "intermediate-region": "", + "region-code": "150", + "sub-region-code": "151", + "intermediate-region-code": "" + }, + { + "name": "United Arab Emirates", + "alpha-2": "AE", + "alpha-3": "ARE", + "country-code": "784", + "iso_3166-2": "ISO 3166-2:AE", + "region": "Asia", + "sub-region": "Western Asia", + "intermediate-region": "", + "region-code": "142", + "sub-region-code": "145", + "intermediate-region-code": "" + }, + { + "name": "United Kingdom of Great Britain and Northern Ireland", + "alpha-2": "GB", + "alpha-3": "GBR", + "country-code": "826", + "iso_3166-2": "ISO 3166-2:GB", + "region": "UK", + "sub-region": "Northern Europe", + "intermediate-region": "", + "region-code": "150", + "sub-region-code": "154", + "intermediate-region-code": "" + }, + { + "name": "United States of America", + "alpha-2": "US", + "alpha-3": "USA", + "country-code": "840", + "iso_3166-2": "ISO 3166-2:US", + "region": "Americas", + "sub-region": "Northern America", + "intermediate-region": "", + "region-code": "019", + "sub-region-code": "021", + "intermediate-region-code": "" + }, + { + "name": "United States Minor Outlying Islands", + "alpha-2": "UM", + "alpha-3": "UMI", + "country-code": "581", + "iso_3166-2": "ISO 3166-2:UM", + "region": "Oceania", + "sub-region": "Micronesia", + "intermediate-region": "", + "region-code": "009", + "sub-region-code": "057", + "intermediate-region-code": "" + }, + { + "name": "Uruguay", + "alpha-2": "UY", + "alpha-3": "URY", + "country-code": "858", + "iso_3166-2": "ISO 3166-2:UY", + "region": "Americas", + "sub-region": "Latin America and the Caribbean", + "intermediate-region": "South America", + "region-code": "019", + "sub-region-code": "419", + "intermediate-region-code": "005" + }, + { + "name": "Uzbekistan", + "alpha-2": "UZ", + "alpha-3": "UZB", + "country-code": "860", + "iso_3166-2": "ISO 3166-2:UZ", + "region": "Asia", + "sub-region": "Central Asia", + "intermediate-region": "", + "region-code": "142", + "sub-region-code": "143", + "intermediate-region-code": "" + }, + { + "name": "Vanuatu", + "alpha-2": "VU", + "alpha-3": "VUT", + "country-code": "548", + "iso_3166-2": "ISO 3166-2:VU", + "region": "Oceania", + "sub-region": "Melanesia", + "intermediate-region": "", + "region-code": "009", + "sub-region-code": "054", + "intermediate-region-code": "" + }, + { + "name": "Venezuela (Bolivarian Republic of)", + "alpha-2": "VE", + "alpha-3": "VEN", + "country-code": "862", + "iso_3166-2": "ISO 3166-2:VE", + "region": "Americas", + "sub-region": "Latin America and the Caribbean", + "intermediate-region": "South America", + "region-code": "019", + "sub-region-code": "419", + "intermediate-region-code": "005" + }, + { + "name": "Viet Nam", + "alpha-2": "VN", + "alpha-3": "VNM", + "country-code": "704", + "iso_3166-2": "ISO 3166-2:VN", + "region": "Asia", + "sub-region": "South-eastern Asia", + "intermediate-region": "", + "region-code": "142", + "sub-region-code": "035", + "intermediate-region-code": "" + }, + { + "name": "Virgin Islands (British)", + "alpha-2": "VG", + "alpha-3": "VGB", + "country-code": "092", + "iso_3166-2": "ISO 3166-2:VG", + "region": "Americas", + "sub-region": "Latin America and the Caribbean", + "intermediate-region": "Caribbean", + "region-code": "019", + "sub-region-code": "419", + "intermediate-region-code": "029" + }, + { + "name": "Virgin Islands (U.S.)", + "alpha-2": "VI", + "alpha-3": "VIR", + "country-code": "850", + "iso_3166-2": "ISO 3166-2:VI", + "region": "Americas", + "sub-region": "Latin America and the Caribbean", + "intermediate-region": "Caribbean", + "region-code": "019", + "sub-region-code": "419", + "intermediate-region-code": "029" + }, + { + "name": "Wallis and Futuna", + "alpha-2": "WF", + "alpha-3": "WLF", + "country-code": "876", + "iso_3166-2": "ISO 3166-2:WF", + "region": "Oceania", + "sub-region": "Polynesia", + "intermediate-region": "", + "region-code": "009", + "sub-region-code": "061", + "intermediate-region-code": "" + }, + { + "name": "Western Sahara", + "alpha-2": "EH", + "alpha-3": "ESH", + "country-code": "732", + "iso_3166-2": "ISO 3166-2:EH", + "region": "Africa", + "sub-region": "Northern Africa", + "intermediate-region": "", + "region-code": "002", + "sub-region-code": "015", + "intermediate-region-code": "" + }, + { + "name": "Yemen", + "alpha-2": "YE", + "alpha-3": "YEM", + "country-code": "887", + "iso_3166-2": "ISO 3166-2:YE", + "region": "Asia", + "sub-region": "Western Asia", + "intermediate-region": "", + "region-code": "142", + "sub-region-code": "145", + "intermediate-region-code": "" + }, + { + "name": "Zambia", + "alpha-2": "ZM", + "alpha-3": "ZMB", + "country-code": "894", + "iso_3166-2": "ISO 3166-2:ZM", + "region": "Africa", + "sub-region": "Sub-Saharan Africa", + "intermediate-region": "Eastern Africa", + "region-code": "002", + "sub-region-code": "202", + "intermediate-region-code": "014" + }, + { + "name": "Zimbabwe", + "alpha-2": "ZW", + "alpha-3": "ZWE", + "country-code": "716", + "iso_3166-2": "ISO 3166-2:ZW", + "region": "Africa", + "sub-region": "Sub-Saharan Africa", + "intermediate-region": "Eastern Africa", + "region-code": "002", + "sub-region-code": "202", + "intermediate-region-code": "014" + } +] diff --git a/src/utils/types.utils.ts b/src/utils/types.utils.ts index 055fb799c..17eee66f0 100644 --- a/src/utils/types.utils.ts +++ b/src/utils/types.utils.ts @@ -34,8 +34,9 @@ export interface BlogProps { } export interface CheckOutForm { - name?: string - email?: string + firstName?: string + lastName?: string + emailAddress?: string address?: string city?: string state?: string From 9603f0dc6ca7f3d657b8b64246612ed0d7c6ecbf Mon Sep 17 00:00:00 2001 From: lytrankieio123 Date: Tue, 19 Oct 2021 17:50:27 +0700 Subject: [PATCH 09/27] :sparkles: feat: add shipping address to order :%s --- framework/commerce/types/cart.ts | 9 +++++++ framework/vendure/schema.d.ts | 1 + .../vendure/utils/fragments/cart-fragment.ts | 8 ++++++ framework/vendure/utils/normalize.ts | 16 ++++++++--- .../checkout/CheckoutInfo/CheckoutInfo.tsx | 18 ++++++++----- .../CustomerInfoForm/CustomerInfoForm.tsx | 1 - .../PaymentInfoForm/PaymentInfoForm.tsx | 27 +++++-------------- .../ShippingInfoForm/ShippingInfoForm.tsx | 17 +++++------- src/utils/types.utils.ts | 13 --------- 9 files changed, 55 insertions(+), 55 deletions(-) diff --git a/framework/commerce/types/cart.ts b/framework/commerce/types/cart.ts index 936ba427d..7fbfb23f7 100644 --- a/framework/commerce/types/cart.ts +++ b/framework/commerce/types/cart.ts @@ -1,3 +1,4 @@ +import { Shipping } from 'src/components/icons'; import type { Discount, Measurement, Image } from './common' export type SelectedOption = { @@ -67,6 +68,14 @@ export type Cart = { lastName: string, emailAddress: string, } + shippingAddress?: { + streetLine1: string, + city: string, + province: string, + postalCode: string, + countryCode: string, + phoneNumber: string, + } // The email assigned to this cart email?: string // The date and time when the cart was created. diff --git a/framework/vendure/schema.d.ts b/framework/vendure/schema.d.ts index ecd45190f..16614ca65 100644 --- a/framework/vendure/schema.d.ts +++ b/framework/vendure/schema.d.ts @@ -3052,6 +3052,7 @@ export type CartFragment = { __typename?: 'Order' } & Pick< | 'totalWithTax' | 'currencyCode' > & { + shippingAddress?: Maybe<{ __typename?: 'OrderAddress' } & Pick> customer?: Maybe<{ __typename?: 'Customer' } & Pick> lines: Array< { __typename?: 'OrderLine' } & Pick< diff --git a/framework/vendure/utils/fragments/cart-fragment.ts b/framework/vendure/utils/fragments/cart-fragment.ts index a9b14d2d4..8a7ac64e7 100644 --- a/framework/vendure/utils/fragments/cart-fragment.ts +++ b/framework/vendure/utils/fragments/cart-fragment.ts @@ -15,6 +15,14 @@ export const cartFragment = /* GraphQL */ ` lastName emailAddress } + shippingAddress { + streetLine1 + city + province + postalCode + countryCode + phoneNumber + } lines { id quantity diff --git a/framework/vendure/utils/normalize.ts b/framework/vendure/utils/normalize.ts index c1bbc93b0..e2a0fb83d 100644 --- a/framework/vendure/utils/normalize.ts +++ b/framework/vendure/utils/normalize.ts @@ -1,6 +1,6 @@ import { Cart } from '@commerce/types/cart' import { ProductCard, Product } from '@commerce/types/product' -import { CartFragment, SearchResultFragment,Favorite } from '../schema' +import { CartFragment, SearchResultFragment, Favorite } from '../schema' export function normalizeSearchResult(item: SearchResultFragment): ProductCard { return { @@ -11,10 +11,10 @@ export function normalizeSearchResult(item: SearchResultFragment): ProductCard { price: (item.priceWithTax as any).min / 100, currencyCode: item.currencyCode, productVariantId: item.productVariantId, - productVariantName:item.productVariantName, + productVariantName: item.productVariantName, facetValueIds: item.facetValueIds, collectionIds: item.collectionIds, - + // TODO: // oldPrice: item.price // discount @@ -50,6 +50,14 @@ export function normalizeCart(order: CartFragment): Cart { lastName: order.customer?.lastName || '', emailAddress: order.customer?.emailAddress || '', }, + shippingAddress: { + streetLine1: order.shippingAddress?.streetLine1 || '', + city: order.shippingAddress?.city || '', + province: order.shippingAddress?.province || '', + postalCode: order.shippingAddress?.postalCode || '', + countryCode: order.shippingAddress?.countryCode || '', + phoneNumber: order.shippingAddress?.phoneNumber || '', + }, lineItems: order.lines?.map((l) => ({ id: l.id, name: l.productVariant.name, @@ -84,7 +92,7 @@ export function normalizeProductCard(product: Product): ProductCard { price: product.price, currencyCode: product.currencyCode, productVariantId: product.variants?.[0].id.toString(), - productVariantName:product.variants?.[0].name, + productVariantName: product.variants?.[0].name, facetValueIds: product.facetValueIds, collectionIds: product.collectionIds, } diff --git a/src/components/modules/checkout/CheckoutInfo/CheckoutInfo.tsx b/src/components/modules/checkout/CheckoutInfo/CheckoutInfo.tsx index cd59f2128..753d9e8cf 100644 --- a/src/components/modules/checkout/CheckoutInfo/CheckoutInfo.tsx +++ b/src/components/modules/checkout/CheckoutInfo/CheckoutInfo.tsx @@ -4,7 +4,6 @@ import CheckoutCollapse from 'src/components/common/CheckoutCollapse/CheckoutCol import { useActiveCustomer } from 'src/components/hooks/auth' import { useAddProductToCart, useGetActiveOrder } from 'src/components/hooks/cart' import { removeItem } from 'src/utils/funtion.utils' -import { CheckOutForm } from 'src/utils/types.utils' import s from './CheckoutInfo.module.scss' import CustomerInfoForm from './components/CustomerInfoForm/CustomerInfoForm' import PaymentInfoForm from './components/PaymentInfoForm/PaymentInfoForm' @@ -22,7 +21,6 @@ enum CheckoutStep { const CheckoutInfo = ({ onViewCart }: CheckoutInfoProps) => { const [activeStep, setActiveStep] = useState(1) const [doneSteps, setDoneSteps] = useState([]) - const [info, setInfo] = useState({}) const { order } = useGetActiveOrder() const { customer } = useActiveCustomer() @@ -53,12 +51,16 @@ const CheckoutInfo = ({ onViewCart }: CheckoutInfoProps) => { const updateActiveStep = (step: CheckoutStep) => { if (doneSteps.length > 0) { - for (let i = step + 1; i <= Object.keys(CheckoutStep).length; i++) { + for (let i = step + 1; i < Object.keys(CheckoutStep).length; i++) { if (!doneSteps.includes(i)) { + // console.log("here: ", doneSteps, i) setActiveStep(i) + return } } } else { + // console.log("here 2: ", doneSteps, step) + setActiveStep(step + 1) } } @@ -86,7 +88,11 @@ const CheckoutInfo = ({ onViewCart }: CheckoutInfoProps) => { return '' } case CheckoutStep.ShippingInfo: - return `${info.address}, ${info.state}, ${info.city}, ${info.code}, ${info.phone}, ` + if (order?.shippingAddress) { + const { streetLine1, city, province, postalCode, countryCode, phoneNumber } = order.shippingAddress + return `${streetLine1}, ${city}, ${province}, ${postalCode}, ${countryCode}, ${phoneNumber}` + } + return '' default: return "" } @@ -96,12 +102,12 @@ const CheckoutInfo = ({ onViewCart }: CheckoutInfoProps) => { { id: CheckoutStep.CustomerInfo, title: 'Customer Information', - form: , + form: , }, { id: CheckoutStep.ShippingInfo, title: 'Shipping Information', - form: , + form: , }, { id: CheckoutStep.PaymentInfo, diff --git a/src/components/modules/checkout/CheckoutInfo/components/CustomerInfoForm/CustomerInfoForm.tsx b/src/components/modules/checkout/CheckoutInfo/components/CustomerInfoForm/CustomerInfoForm.tsx index 6c6098f91..9ea2f2f1b 100644 --- a/src/components/modules/checkout/CheckoutInfo/components/CustomerInfoForm/CustomerInfoForm.tsx +++ b/src/components/modules/checkout/CheckoutInfo/components/CustomerInfoForm/CustomerInfoForm.tsx @@ -9,7 +9,6 @@ import { ErrorCode } from 'src/domains/enums/ErrorCode' import { CommonError } from 'src/domains/interfaces/CommonError' import { LANGUAGE } from 'src/utils/language.utils' import { CustomInputCommon } from 'src/utils/type.utils' -import { CheckOutForm } from 'src/utils/types.utils' import * as Yup from 'yup' import ChekoutNotePolicy from '../ChekoutNotePolicy/ChekoutNotePolicy' import s from './CustomerInfoForm.module.scss' diff --git a/src/components/modules/checkout/CheckoutInfo/components/PaymentInfoForm/PaymentInfoForm.tsx b/src/components/modules/checkout/CheckoutInfo/components/PaymentInfoForm/PaymentInfoForm.tsx index eac100fb0..de72812c3 100644 --- a/src/components/modules/checkout/CheckoutInfo/components/PaymentInfoForm/PaymentInfoForm.tsx +++ b/src/components/modules/checkout/CheckoutInfo/components/PaymentInfoForm/PaymentInfoForm.tsx @@ -1,19 +1,18 @@ import React from 'react' import { ButtonCommon, TabCommon, TabPane } from 'src/components/common' -import { CheckOutForm } from 'src/utils/types.utils' import BankTransfer from '../BankTransfer/BankTransfer' -import Link from 'next/link' - -import s from './PaymentInfoForm.module.scss' +import ChekoutNotePolicy from '../ChekoutNotePolicy/ChekoutNotePolicy' import CreditCardForm from '../CreditCardForm/CreditCardForm' +import s from './PaymentInfoForm.module.scss' + interface PaymentInfoFormProps { - onConfirm?: (id: number, formInfo: CheckOutForm) => void + onConfirm?: (id: number) => void id: number } const PaymentInfoForm = ({onConfirm,id}: PaymentInfoFormProps) => { const handleConfirmClick = () => { - onConfirm && onConfirm(id,{}) + onConfirm && onConfirm(id) } return (
@@ -29,21 +28,7 @@ const PaymentInfoForm = ({onConfirm,id}: PaymentInfoFormProps) => {
-
- By clicking continue you agree to Casper's{' '} - { - - terms and conditions - - }{' '} - and{' '} - { - - privacy policy - - } - . -
+
Submit Order diff --git a/src/components/modules/checkout/CheckoutInfo/components/ShippingInfoForm/ShippingInfoForm.tsx b/src/components/modules/checkout/CheckoutInfo/components/ShippingInfoForm/ShippingInfoForm.tsx index f57b113bc..f2439a6d7 100644 --- a/src/components/modules/checkout/CheckoutInfo/components/ShippingInfoForm/ShippingInfoForm.tsx +++ b/src/components/modules/checkout/CheckoutInfo/components/ShippingInfoForm/ShippingInfoForm.tsx @@ -1,17 +1,14 @@ -import React, { useEffect, useRef } from 'react' -import { ButtonCommon, Inputcommon, InputFiledInForm, SelectCommon, SelectFieldInForm } from 'src/components/common' -import s from './ShippingInfoForm.module.scss' -import Link from 'next/link' -import { CustomInputCommon } from 'src/utils/type.utils' -import { Shipping } from 'src/components/icons' -import { CheckOutForm } from 'src/utils/types.utils' import { Form, Formik } from 'formik' +import React, { useEffect, useRef } from 'react' +import { ButtonCommon, InputFiledInForm, SelectFieldInForm } from 'src/components/common' +import { useMessage } from 'src/components/contexts' +import { useSetOrderShippingAddress } from 'src/components/hooks/order' +import { COUNTRY_CODE } from 'src/domains/data/countryCode' import { LANGUAGE } from 'src/utils/language.utils' +import { CustomInputCommon } from 'src/utils/type.utils' import * as Yup from 'yup' import ChekoutNotePolicy from '../ChekoutNotePolicy/ChekoutNotePolicy' -import { useSetOrderShippingAddress } from 'src/components/hooks/order' -import { useMessage } from 'src/components/contexts' -import { COUNTRY_CODE } from 'src/domains/data/countryCode' +import s from './ShippingInfoForm.module.scss' interface ShippingInfoFormProps { id: number diff --git a/src/utils/types.utils.ts b/src/utils/types.utils.ts index 17eee66f0..ec796a55c 100644 --- a/src/utils/types.utils.ts +++ b/src/utils/types.utils.ts @@ -33,19 +33,6 @@ export interface BlogProps { imageSrc: string } -export interface CheckOutForm { - firstName?: string - lastName?: string - emailAddress?: string - address?: string - city?: string - state?: string - code?: number - phone?: number - method?: string - shipping_fee?: number -} - export type MouseAndTouchEvent = MouseEvent | TouchEvent export enum SortOrder { From 693935a480f4f531b8af52c141fd36352440f05a Mon Sep 17 00:00:00 2001 From: lytrankieio123 Date: Tue, 19 Oct 2021 18:48:10 +0700 Subject: [PATCH 10/27] :sparkles: feat: apply coupon code for order :%s --- framework/vendure/schema.d.ts | 31 ++++++ .../mutations/apply-coupon-code-mutation.ts | 21 ++++ .../ButtonCommon/ButtonCommon.module.scss | 2 +- src/components/hooks/order/index.ts | 1 + .../hooks/order/useApplyCouponCode.tsx | 41 ++++++++ .../CheckoutBill/CheckoutBill.module.scss | 5 - .../checkout/CheckoutBill/CheckoutBill.tsx | 9 +- .../FormPromotionCode.module.scss | 19 ++++ .../FormPromotionCode/FormPromotionCode.tsx | 97 +++++++++++++++++++ .../checkout/CheckoutInfo/CheckoutInfo.tsx | 2 +- .../CustomerInfoForm/CustomerInfoForm.tsx | 11 ++- .../ShippingInfoForm/ShippingInfoForm.tsx | 5 +- .../CheckoutPage/CheckoutPage.module.scss | 5 +- src/utils/language.utils.ts | 3 +- 14 files changed, 229 insertions(+), 23 deletions(-) create mode 100644 framework/vendure/utils/mutations/apply-coupon-code-mutation.ts create mode 100644 src/components/hooks/order/useApplyCouponCode.tsx create mode 100644 src/components/modules/checkout/CheckoutBill/FormPromotionCode/FormPromotionCode.module.scss create mode 100644 src/components/modules/checkout/CheckoutBill/FormPromotionCode/FormPromotionCode.tsx diff --git a/framework/vendure/schema.d.ts b/framework/vendure/schema.d.ts index 16614ca65..ae4467159 100644 --- a/framework/vendure/schema.d.ts +++ b/framework/vendure/schema.d.ts @@ -3053,6 +3053,7 @@ export type CartFragment = { __typename?: 'Order' } & Pick< | 'currencyCode' > & { shippingAddress?: Maybe<{ __typename?: 'OrderAddress' } & Pick> + discounts?: Maybe<{ __typename?: 'Discount' } & Pick> customer?: Maybe<{ __typename?: 'Customer' } & Pick> lines: Array< { __typename?: 'OrderLine' } & Pick< @@ -3156,6 +3157,36 @@ export type AdjustOrderLineMutation = { __typename?: 'Mutation' } & { >) } + +export type ApplyCouponCodeMutationVariables = Exact<{ + couponCode: Scalars['String']; +}>; + +export type ApplyCouponCodeMutation = { + applyCouponCode: + | TestOrderFragmentFragment + | Pick + | Pick + | Pick; +}; + +export type ApplyCouponCodeMutation = { __typename?: 'Mutation' } & { + applyCouponCode: + | ({ __typename: 'Order' } & CartFragment) + | ({ __typename: 'CouponCodeExpiredError' } & Pick< + CouponCodeExpiredError, + 'errorCode' | 'message' + >) + | ({ __typename: 'CouponCodeInvalidError' } & Pick< + CouponCodeInvalidError, + 'errorCode' | 'message' + >) + | ({ __typename: 'CouponCodeLimitError' } & Pick< + CouponCodeLimitError, + 'errorCode' | 'message' + >) +} + export type LoginMutationVariables = Exact<{ username: Scalars['String'] password: Scalars['String'] diff --git a/framework/vendure/utils/mutations/apply-coupon-code-mutation.ts b/framework/vendure/utils/mutations/apply-coupon-code-mutation.ts new file mode 100644 index 000000000..c5b1a9a90 --- /dev/null +++ b/framework/vendure/utils/mutations/apply-coupon-code-mutation.ts @@ -0,0 +1,21 @@ +export const applyCouponCodeMutation = /* GraphQL */ ` +mutation applyCouponCode($couponCode: String!) { + applyCouponCode(couponCode: $couponCode) { + __typename + ... on Order { + id + createdAt + updatedAt + discounts { + type + amount + amountWithTax + } + } + ... on ErrorResult { + errorCode + message + } + } +} +` diff --git a/src/components/common/ButtonCommon/ButtonCommon.module.scss b/src/components/common/ButtonCommon/ButtonCommon.module.scss index 318180ede..69c07c670 100644 --- a/src/components/common/ButtonCommon/ButtonCommon.module.scss +++ b/src/components/common/ButtonCommon/ButtonCommon.module.scss @@ -1,7 +1,7 @@ @import "../../../styles/utilities"; .buttonCommon { - @apply shape-common; + @apply shape-common h-full; &:hover { .inner { @apply shadow-md; diff --git a/src/components/hooks/order/index.ts b/src/components/hooks/order/index.ts index 0aef836be..bf6383122 100644 --- a/src/components/hooks/order/index.ts +++ b/src/components/hooks/order/index.ts @@ -1,3 +1,4 @@ export { default as useSetCustomerForOrder } from './useSetCustomerForOrder' export { default as useSetOrderShippingAddress } from './useSetOrderShippingAddress' +export { default as useApplyCouponCode } from './useApplyCouponCode' diff --git a/src/components/hooks/order/useApplyCouponCode.tsx b/src/components/hooks/order/useApplyCouponCode.tsx new file mode 100644 index 000000000..be2c77878 --- /dev/null +++ b/src/components/hooks/order/useApplyCouponCode.tsx @@ -0,0 +1,41 @@ +import { ApplyCouponCodeMutation } from '@framework/schema' +import { applyCouponCodeMutation } from '@framework/utils/mutations/apply-coupon-code-mutation' +import { useState } from 'react' +import { CommonError } from 'src/domains/interfaces/CommonError' +import rawFetcher from 'src/utils/rawFetcher' +import { useGetActiveOrder } from '../cart' + + +const useApplyCouponCode = () => { + const [loading, setLoading] = useState(false) + const [error, setError] = useState(null) + const { mutate } = useGetActiveOrder() + + const applyCouponCode = (couponCode: string, + fCallBack: (isSuccess: boolean, message?: string) => void + ) => { + setError(null) + setLoading(true) + rawFetcher({ + query: applyCouponCodeMutation, + variables: { couponCode }, + }) + .then(({ data }) => { + if (data.applyCouponCode.__typename === 'Order') { + fCallBack(true) + mutate() + } else { + fCallBack(false, data.applyCouponCode.message) + } + }) + .catch((error) => { + setError(error) + fCallBack(false, error.message) + }) + .finally(() => setLoading(false)) + } + + return { loading, applyCouponCode, error } +} + +export default useApplyCouponCode diff --git a/src/components/modules/checkout/CheckoutBill/CheckoutBill.module.scss b/src/components/modules/checkout/CheckoutBill/CheckoutBill.module.scss index 84dea0f06..8cd564917 100644 --- a/src/components/modules/checkout/CheckoutBill/CheckoutBill.module.scss +++ b/src/components/modules/checkout/CheckoutBill/CheckoutBill.module.scss @@ -18,11 +18,6 @@ min-height: 52.8rem; } .bot { - .promo { - // padding: 3.2rem; - @apply bg-gray flex justify-between items-center; - min-height: 6.4rem; - } .price { margin-top: 3.2rem; .line { diff --git a/src/components/modules/checkout/CheckoutBill/CheckoutBill.tsx b/src/components/modules/checkout/CheckoutBill/CheckoutBill.tsx index 259397980..a7f593764 100644 --- a/src/components/modules/checkout/CheckoutBill/CheckoutBill.tsx +++ b/src/components/modules/checkout/CheckoutBill/CheckoutBill.tsx @@ -1,8 +1,8 @@ import React from 'react' -import s from './CheckoutBill.module.scss' import { CardItemCheckout } from '../../../common' import { CardItemCheckoutProps } from '../../../common/CardItemCheckout/CardItemCheckout' -import { IconCirclePlus } from 'src/components/icons' +import s from './CheckoutBill.module.scss' +import FormPromotionCode from './FormPromotionCode/FormPromotionCode' interface CheckoutBillProps { data: CardItemCheckoutProps[] @@ -20,10 +20,7 @@ const CheckoutBill = ({ data }: CheckoutBillProps) => { })}
-
- Apply Promotion Code - -
+
Subtotal diff --git a/src/components/modules/checkout/CheckoutBill/FormPromotionCode/FormPromotionCode.module.scss b/src/components/modules/checkout/CheckoutBill/FormPromotionCode/FormPromotionCode.module.scss new file mode 100644 index 000000000..1391a5e00 --- /dev/null +++ b/src/components/modules/checkout/CheckoutBill/FormPromotionCode/FormPromotionCode.module.scss @@ -0,0 +1,19 @@ +.promo { + @apply bg-gray flex justify-between items-center; + min-height: 6.4rem; + .modalPromotion { + min-width: 40rem; + .bottom { + @apply flex justify-end items-center; + margin-top: 3.2rem; + button { + &:first-child { + margin-right: 0.8rem; + @screen md { + margin-right: 3.2rem; + } + } + } + } + } +} diff --git a/src/components/modules/checkout/CheckoutBill/FormPromotionCode/FormPromotionCode.tsx b/src/components/modules/checkout/CheckoutBill/FormPromotionCode/FormPromotionCode.tsx new file mode 100644 index 000000000..5fc3c95ee --- /dev/null +++ b/src/components/modules/checkout/CheckoutBill/FormPromotionCode/FormPromotionCode.tsx @@ -0,0 +1,97 @@ +import { Form, Formik } from 'formik'; +import React, { useEffect, useRef } from 'react'; +import { ButtonCommon, InputFiledInForm, ModalCommon } from 'src/components/common'; +import { useMessage } from 'src/components/contexts'; +import { useModalCommon } from 'src/components/hooks'; +import { useApplyCouponCode } from 'src/components/hooks/order'; +import { IconCirclePlus } from 'src/components/icons'; +import { LANGUAGE } from 'src/utils/language.utils'; +import { CustomInputCommon } from 'src/utils/type.utils'; +import * as Yup from 'yup'; +import s from './FormPromotionCode.module.scss'; + +const displayingErrorMessagesSchema = Yup.object().shape({ + couponCode: Yup.string().required(LANGUAGE.MESSAGE.REQUIRED), +}) + +const FormPromotionCode = () => { + const { visible, openModal, closeModal } = useModalCommon({ initialValue: false }) + const { showMessageError, showMessageSuccess } = useMessage() + const { applyCouponCode, loading } = useApplyCouponCode() + const inputRef = useRef(null) + + useEffect(() => { + setTimeout(() => { + if (visible) { + inputRef.current?.focus() + } + }, 500); + }, [visible]) + + const handleSubmit = (values: { couponCode: string }) => { + applyCouponCode(values.couponCode, onSubmitCalBack) + } + + const onSubmitCalBack = (isSuccess: boolean, msg?: string) => { + // TODO: + if (isSuccess) { + showMessageSuccess("Applied coupon code successfully.", 5000) + closeModal() + } else { + showMessageError(msg) + } + } + + return ( +
+ Apply Promotion Code + + +
+ + {({ errors, touched, isValid, submitForm }) => ( +
+
+ + +
+
+ + {LANGUAGE.BUTTON_LABEL.CANCEL} + + + Apply promotion code + +
+
+ )} +
+
+
+
+ ); +}; + +export default FormPromotionCode; \ No newline at end of file diff --git a/src/components/modules/checkout/CheckoutInfo/CheckoutInfo.tsx b/src/components/modules/checkout/CheckoutInfo/CheckoutInfo.tsx index 753d9e8cf..65321167e 100644 --- a/src/components/modules/checkout/CheckoutInfo/CheckoutInfo.tsx +++ b/src/components/modules/checkout/CheckoutInfo/CheckoutInfo.tsx @@ -132,7 +132,7 @@ const CheckoutInfo = ({ onViewCart }: CheckoutInfoProps) => { {/* TODO: remove */} test create order test get activeStep order - + TOTAL: {order?.totalPrice}
diff --git a/src/components/modules/checkout/CheckoutInfo/components/CustomerInfoForm/CustomerInfoForm.tsx b/src/components/modules/checkout/CheckoutInfo/components/CustomerInfoForm/CustomerInfoForm.tsx index 9ea2f2f1b..fb18b79e3 100644 --- a/src/components/modules/checkout/CheckoutInfo/components/CustomerInfoForm/CustomerInfoForm.tsx +++ b/src/components/modules/checkout/CheckoutInfo/components/CustomerInfoForm/CustomerInfoForm.tsx @@ -1,5 +1,5 @@ import { Form, Formik } from 'formik' -import React, { useRef, useState } from 'react' +import React, { useEffect, useRef, useState } from 'react' import { ButtonCommon, InputFiledInForm } from 'src/components/common' import ModalAuthenticate from 'src/components/common/ModalAuthenticate/ModalAuthenticate' import { useMessage } from 'src/components/contexts' @@ -16,6 +16,8 @@ import ModalConfirmLogin from './ModalConfirmLogin/ModalConfirmLogin' interface Props { id: number onConfirm: (id: number) => void + activeStep: number + } const displayingErrorMessagesSchema = Yup.object().shape({ @@ -24,7 +26,7 @@ const displayingErrorMessagesSchema = Yup.object().shape({ emailAddress: Yup.string().email(LANGUAGE.MESSAGE.INVALID_EMAIL).required(LANGUAGE.MESSAGE.REQUIRED), }) -const CustomerInfoForm = ({ id, onConfirm }: Props) => { +const CustomerInfoForm = ({ id, onConfirm, activeStep }: Props) => { const firstNameRef = useRef(null) const { setCustomerForOrder, loading } = useSetCustomerForOrder() const { showMessageError } = useMessage() @@ -32,6 +34,11 @@ const CustomerInfoForm = ({ id, onConfirm }: Props) => { const { visible: visibleModalConfirmLogin, closeModal: closeModalConfirmLogin, openModal: openModalConfirmLogin } = useModalCommon({ initialValue: false }) const { visible: visibleModalAuthen, closeModal: closeModalAuthen, openModal: openModalAuthen } = useModalCommon({ initialValue: false }) + useEffect(() => { + setTimeout(() => { + firstNameRef.current?.focus() + }, 500); + }, [activeStep]) const handleSubmit = (values: { firstName: string, lastName: string, emailAddress: string }) => { const { firstName, lastName, emailAddress } = values diff --git a/src/components/modules/checkout/CheckoutInfo/components/ShippingInfoForm/ShippingInfoForm.tsx b/src/components/modules/checkout/CheckoutInfo/components/ShippingInfoForm/ShippingInfoForm.tsx index f2439a6d7..f1931d7fb 100644 --- a/src/components/modules/checkout/CheckoutInfo/components/ShippingInfoForm/ShippingInfoForm.tsx +++ b/src/components/modules/checkout/CheckoutInfo/components/ShippingInfoForm/ShippingInfoForm.tsx @@ -41,7 +41,7 @@ const provinceOptions = [ const ShippingInfoForm = ({ onConfirm, id, activeStep }: ShippingInfoFormProps) => { const addressRef = useRef(null) - const { setOrderShippingAddress } = useSetOrderShippingAddress() + const { setOrderShippingAddress, loading } = useSetOrderShippingAddress() const { showMessageError } = useMessage() useEffect(() => { @@ -171,8 +171,7 @@ const ShippingInfoForm = ({ onConfirm, id, activeStep }: ShippingInfoFormProps)
- {/* */} - + Continue to Payment
diff --git a/src/components/modules/checkout/CheckoutPage/CheckoutPage.module.scss b/src/components/modules/checkout/CheckoutPage/CheckoutPage.module.scss index dabbde19e..a1e68d863 100644 --- a/src/components/modules/checkout/CheckoutPage/CheckoutPage.module.scss +++ b/src/components/modules/checkout/CheckoutPage/CheckoutPage.module.scss @@ -46,10 +46,7 @@ color:var(--text-base); } } - button{ - margin-top: 2rem; - width: 100%; - } + } } } diff --git a/src/utils/language.utils.ts b/src/utils/language.utils.ts index 2005f900d..7a8abd6b4 100644 --- a/src/utils/language.utils.ts +++ b/src/utils/language.utils.ts @@ -5,7 +5,8 @@ export const LANGUAGE = { CONFIRM:'Confirm', ADD_TO_CARD: 'Add to Cart', PREORDER: 'Pre-Order Now', - SIGNIN :'Sign In' + SIGNIN :'Sign In', + CANCEL: 'Cancel', }, PLACE_HOLDER: { SEARCH: 'Search', From 3abada4777974b880fef9e0f82ff064a5ecc323e Mon Sep 17 00:00:00 2001 From: lytrankieio123 Date: Tue, 19 Oct 2021 19:32:42 +0700 Subject: [PATCH 11/27] :sparkles: feat: show bill discount and total :%s --- framework/commerce/types/cart.ts | 2 ++ framework/commerce/types/common.ts | 1 + framework/vendure/schema.d.ts | 4 ++- .../vendure/utils/fragments/cart-fragment.ts | 6 ++++ framework/vendure/utils/normalize.ts | 6 ++++ .../CardItemCheckout/CardItemCheckout.tsx | 21 ++++++++----- .../checkout/CheckoutBill/CheckoutBill.tsx | 30 ++++++++++++------- .../checkout/CheckoutInfo/CheckoutInfo.tsx | 4 +-- .../checkout/CheckoutPage/CheckoutPage.tsx | 16 +++++----- 9 files changed, 61 insertions(+), 29 deletions(-) diff --git a/framework/commerce/types/cart.ts b/framework/commerce/types/cart.ts index 7fbfb23f7..15e24d32e 100644 --- a/framework/commerce/types/cart.ts +++ b/framework/commerce/types/cart.ts @@ -93,8 +93,10 @@ export type Cart = { // The sum of all the prices of all the items in the cart. // Duties, taxes and discounts included. totalPrice: number + totalQuantity: number // Discounts that have been applied on the cart. discounts?: Discount[] + totalDiscount: number } /** diff --git a/framework/commerce/types/common.ts b/framework/commerce/types/common.ts index 06908c464..d3eca1e68 100644 --- a/framework/commerce/types/common.ts +++ b/framework/commerce/types/common.ts @@ -1,6 +1,7 @@ export type Discount = { // The value of the discount, can be an amount or percentage value: number + description?: string } export type Measurement = { diff --git a/framework/vendure/schema.d.ts b/framework/vendure/schema.d.ts index ae4467159..b2e0f198e 100644 --- a/framework/vendure/schema.d.ts +++ b/framework/vendure/schema.d.ts @@ -3053,7 +3053,9 @@ export type CartFragment = { __typename?: 'Order' } & Pick< | 'currencyCode' > & { shippingAddress?: Maybe<{ __typename?: 'OrderAddress' } & Pick> - discounts?: Maybe<{ __typename?: 'Discount' } & Pick> + discounts: Array< + { __typename?: 'Discount' } & Pick + > customer?: Maybe<{ __typename?: 'Customer' } & Pick> lines: Array< { __typename?: 'OrderLine' } & Pick< diff --git a/framework/vendure/utils/fragments/cart-fragment.ts b/framework/vendure/utils/fragments/cart-fragment.ts index 8a7ac64e7..f0a34b8e3 100644 --- a/framework/vendure/utils/fragments/cart-fragment.ts +++ b/framework/vendure/utils/fragments/cart-fragment.ts @@ -9,6 +9,12 @@ export const cartFragment = /* GraphQL */ ` total totalWithTax currencyCode + discounts { + type + description + amount + amountWithTax + } customer { id firstName diff --git a/framework/vendure/utils/normalize.ts b/framework/vendure/utils/normalize.ts index e2a0fb83d..a3aeffd28 100644 --- a/framework/vendure/utils/normalize.ts +++ b/framework/vendure/utils/normalize.ts @@ -36,10 +36,12 @@ export function normalizeFavoriteProductResult(item: Favorite) { export function normalizeCart(order: CartFragment): Cart { + console.log("raw rs: ", order) return { id: order.id.toString(), createdAt: order.createdAt, taxesIncluded: true, + totalQuantity: order.totalQuantity, lineItemsSubtotalPrice: order.subTotalWithTax / 100, currency: { code: order.currencyCode }, subtotalPrice: order.subTotalWithTax / 100, @@ -58,6 +60,10 @@ export function normalizeCart(order: CartFragment): Cart { countryCode: order.shippingAddress?.countryCode || '', phoneNumber: order.shippingAddress?.phoneNumber || '', }, + totalDiscount: order.discounts?.reduce((total, item) => total + item.amountWithTax, 0) / 100 || 0, + discounts: order.discounts.map(item => { + return { value: item.amountWithTax, description: item.description } + }), lineItems: order.lines?.map((l) => ({ id: l.id, name: l.productVariant.name, diff --git a/src/components/common/CardItemCheckout/CardItemCheckout.tsx b/src/components/common/CardItemCheckout/CardItemCheckout.tsx index e67057aa6..40fbf6b37 100644 --- a/src/components/common/CardItemCheckout/CardItemCheckout.tsx +++ b/src/components/common/CardItemCheckout/CardItemCheckout.tsx @@ -1,24 +1,29 @@ +import { LineItem } from '@commerce/types/cart' import React from 'react' +import { ImgWithLink } from '..' import s from "./CardItemCheckout.module.scss" -import { ProductProps } from 'src/utils/types.utils' -export interface CardItemCheckoutProps extends ProductProps { - quantity:number +export interface CardItemCheckoutProps extends LineItem { + currency: { code: string } } -const CardItemCheckout = ({imageSrc,name,price,weight,quantity,category}: CardItemCheckoutProps) => { +const CardItemCheckout = ({ + quantity, + variant, + name, + currency }: CardItemCheckoutProps) => { return (
- image +
- {`${name} (${weight})`} + {name} {variant?.weight ? `(${variant.weight})` : ''}
- Quantity: + Quantity:
- {`${quantity} x ${price}`} + {`${quantity} x ${variant?.price} ${currency?.code}`}
diff --git a/src/components/modules/checkout/CheckoutBill/CheckoutBill.tsx b/src/components/modules/checkout/CheckoutBill/CheckoutBill.tsx index a7f593764..34d468f94 100644 --- a/src/components/modules/checkout/CheckoutBill/CheckoutBill.tsx +++ b/src/components/modules/checkout/CheckoutBill/CheckoutBill.tsx @@ -1,30 +1,38 @@ -import React from 'react' +import { Cart } from '@commerce/types/cart' +import React, { useMemo } from 'react' import { CardItemCheckout } from '../../../common' -import { CardItemCheckoutProps } from '../../../common/CardItemCheckout/CardItemCheckout' import s from './CheckoutBill.module.scss' import FormPromotionCode from './FormPromotionCode/FormPromotionCode' interface CheckoutBillProps { - data: CardItemCheckoutProps[] + // data: CardItemCheckoutProps[] + data: Cart | null } const CheckoutBill = ({ data }: CheckoutBillProps) => { + console.log("data here***: ", data) + return (
-
- Your cart ({data.length}) -
+
+ Your cart ({data?.totalQuantity}) +
- {data.map((item) => { - return + {data?.lineItems?.map((item) => { + return })}
- +
+ TODO: here +
+ Discount {(data?.discounts?.length || 0) > 0 && `(${data?.discounts?.map(item => item.description).join(",")})`} +
{data?.totalDiscount} {data?.currency?.code}
+
Subtotal -
RP 120.500
+
{data?.subtotalPrice} {data?.currency?.code}
Shipping @@ -32,7 +40,7 @@ const CheckoutBill = ({ data }: CheckoutBillProps) => {
Estimated Total -
RP 120.500
+
{data?.totalPrice} {data?.currency?.code}
diff --git a/src/components/modules/checkout/CheckoutInfo/CheckoutInfo.tsx b/src/components/modules/checkout/CheckoutInfo/CheckoutInfo.tsx index 65321167e..fdab2da6f 100644 --- a/src/components/modules/checkout/CheckoutInfo/CheckoutInfo.tsx +++ b/src/components/modules/checkout/CheckoutInfo/CheckoutInfo.tsx @@ -102,7 +102,7 @@ const CheckoutInfo = ({ onViewCart }: CheckoutInfoProps) => { { id: CheckoutStep.CustomerInfo, title: 'Customer Information', - form: , + form: , }, { id: CheckoutStep.ShippingInfo, @@ -120,7 +120,7 @@ const CheckoutInfo = ({ onViewCart }: CheckoutInfoProps) => { const { addProduct } = useAddProductToCart() const createOrder = () => { - addProduct({ variantId: "63", quantity: 1 }, handleAddToCartCallback) + addProduct({ variantId: "92", quantity: 2 }, handleAddToCartCallback) } const handleAddToCartCallback = (isSuccess: boolean, message?: string) => { // console.log("after create order: ", isSuccess, message) diff --git a/src/components/modules/checkout/CheckoutPage/CheckoutPage.tsx b/src/components/modules/checkout/CheckoutPage/CheckoutPage.tsx index 4755d329e..05bc176a7 100644 --- a/src/components/modules/checkout/CheckoutPage/CheckoutPage.tsx +++ b/src/components/modules/checkout/CheckoutPage/CheckoutPage.tsx @@ -2,6 +2,7 @@ import classNames from 'classnames' import React, { useState } from 'react' import { MessageCommon } from 'src/components/common' import { useMessage } from 'src/components/contexts' +import { useGetActiveOrder } from 'src/components/hooks/cart' import IconHide from 'src/components/icons/IconHide' import { CHECKOUT_BILL_DATA } from 'src/utils/demo-data' import { CheckoutBill, CheckoutInfo } from '..' @@ -9,29 +10,30 @@ import s from "./CheckoutPage.module.scss" interface CheckoutPageProps { } -const CheckoutPage = ({}: CheckoutPageProps) => { +const CheckoutPage = ({ }: CheckoutPageProps) => { const { messages, removeMessage } = useMessage() const [isShow, setIsShow] = useState(false) + const { order } = useGetActiveOrder() const onClose = () => { setIsShow(false) } - const onViewCart =() => { + const onViewCart = () => { setIsShow(true) } return (
-
-
-
+
+
+

Your Cart({CHECKOUT_BILL_DATA.length})

-
+
- +
From c09789d4ac9776cab9673a7ccb1fd625b56558a6 Mon Sep 17 00:00:00 2001 From: lytrankieio123 Date: Wed, 20 Oct 2021 09:28:42 +0700 Subject: [PATCH 12/27] :fire: remove: log :%s --- framework/vendure/utils/normalize.ts | 1 - .../components/ProductCartItem/ProductCartItem.tsx | 3 ++- .../modules/checkout/CheckoutBill/CheckoutBill.tsx | 6 ++---- .../modules/checkout/CheckoutPage/CheckoutPage.tsx | 2 +- 4 files changed, 5 insertions(+), 7 deletions(-) diff --git a/framework/vendure/utils/normalize.ts b/framework/vendure/utils/normalize.ts index a3aeffd28..d81fbc2f1 100644 --- a/framework/vendure/utils/normalize.ts +++ b/framework/vendure/utils/normalize.ts @@ -36,7 +36,6 @@ export function normalizeFavoriteProductResult(item: Favorite) { export function normalizeCart(order: CartFragment): Cart { - console.log("raw rs: ", order) return { id: order.id.toString(), createdAt: order.createdAt, diff --git a/src/components/common/CartDrawer/components/ProductCartItem/ProductCartItem.tsx b/src/components/common/CartDrawer/components/ProductCartItem/ProductCartItem.tsx index ef219d31d..57a6e2b20 100644 --- a/src/components/common/CartDrawer/components/ProductCartItem/ProductCartItem.tsx +++ b/src/components/common/CartDrawer/components/ProductCartItem/ProductCartItem.tsx @@ -74,7 +74,8 @@ const ProductCartItem = ({ {discounts.length > 0 && (
{/* {oldPrice} */} - {discounts[0]} + {/* TODO: edit the value */} + {discounts[0]?.value}
)}
{variant?.price} {currency?.code}
diff --git a/src/components/modules/checkout/CheckoutBill/CheckoutBill.tsx b/src/components/modules/checkout/CheckoutBill/CheckoutBill.tsx index 34d468f94..433df66d1 100644 --- a/src/components/modules/checkout/CheckoutBill/CheckoutBill.tsx +++ b/src/components/modules/checkout/CheckoutBill/CheckoutBill.tsx @@ -1,5 +1,5 @@ import { Cart } from '@commerce/types/cart' -import React, { useMemo } from 'react' +import React from 'react' import { CardItemCheckout } from '../../../common' import s from './CheckoutBill.module.scss' import FormPromotionCode from './FormPromotionCode/FormPromotionCode' @@ -10,8 +10,7 @@ interface CheckoutBillProps { } const CheckoutBill = ({ data }: CheckoutBillProps) => { - console.log("data here***: ", data) - + // console.log("data here***: ", data) return (
@@ -25,7 +24,6 @@ const CheckoutBill = ({ data }: CheckoutBillProps) => {
- TODO: here
Discount {(data?.discounts?.length || 0) > 0 && `(${data?.discounts?.map(item => item.description).join(",")})`}
{data?.totalDiscount} {data?.currency?.code}
diff --git a/src/components/modules/checkout/CheckoutPage/CheckoutPage.tsx b/src/components/modules/checkout/CheckoutPage/CheckoutPage.tsx index 05bc176a7..fcec64922 100644 --- a/src/components/modules/checkout/CheckoutPage/CheckoutPage.tsx +++ b/src/components/modules/checkout/CheckoutPage/CheckoutPage.tsx @@ -33,7 +33,7 @@ const CheckoutPage = ({ }: CheckoutPageProps) => {

Your Cart({CHECKOUT_BILL_DATA.length})

- +
From 6b99405bce46f8df4688e573191a86b03547c5b5 Mon Sep 17 00:00:00 2001 From: lytrankieio123 Date: Wed, 20 Oct 2021 13:30:31 +0700 Subject: [PATCH 13/27] :sparkles: feat: useAvailableCountries :%s --- framework/vendure/schema.d.ts | 33 +++++++++++++++---- .../queries/available-countries-query.ts | 16 +++++++++ src/components/hooks/order/index.ts | 1 + .../hooks/order/useAvailableCountries.tsx | 14 ++++++++ .../ShippingInfoForm/ShippingInfoForm.tsx | 22 +++++++++---- 5 files changed, 72 insertions(+), 14 deletions(-) create mode 100644 framework/vendure/utils/queries/available-countries-query.ts create mode 100644 src/components/hooks/order/useAvailableCountries.tsx diff --git a/framework/vendure/schema.d.ts b/framework/vendure/schema.d.ts index b2e0f198e..e2a6ab600 100644 --- a/framework/vendure/schema.d.ts +++ b/framework/vendure/schema.d.ts @@ -3052,10 +3052,10 @@ export type CartFragment = { __typename?: 'Order' } & Pick< | 'totalWithTax' | 'currencyCode' > & { - shippingAddress?: Maybe<{ __typename?: 'OrderAddress' } & Pick> + shippingAddress?: Maybe<{ __typename?: 'OrderAddress' } & Pick> discounts: Array< - { __typename?: 'Discount' } & Pick - > + { __typename?: 'Discount' } & Pick + > customer?: Maybe<{ __typename?: 'Customer' } & Pick> lines: Array< { __typename?: 'OrderLine' } & Pick< @@ -3166,10 +3166,10 @@ export type ApplyCouponCodeMutationVariables = Exact<{ export type ApplyCouponCodeMutation = { applyCouponCode: - | TestOrderFragmentFragment - | Pick - | Pick - | Pick; + | TestOrderFragmentFragment + | Pick + | Pick + | Pick; }; export type ApplyCouponCodeMutation = { __typename?: 'Mutation' } & { @@ -3344,6 +3344,25 @@ type Favorite = Node & { customer: Customer! } +export type GetAvailableCountriesQueryVariables = Exact<{ [key: string]: never; }>; + + +// export type GetAvailableCountriesQuery = { countries: ( +// { __typename?: 'CountryList' } +// & { items: Array<( +// { __typename?: 'Country' } +// & Pick +// )> } +// ) }; + +export type GetAvailableCountriesQuery = { + availableCountries: + { __typename?: 'CountryList' } + & Array<( + { __typename?: 'Country' } + & Pick + )> +}; type FavouriteOption = Customer & { diff --git a/framework/vendure/utils/queries/available-countries-query.ts b/framework/vendure/utils/queries/available-countries-query.ts new file mode 100644 index 000000000..f1da8c408 --- /dev/null +++ b/framework/vendure/utils/queries/available-countries-query.ts @@ -0,0 +1,16 @@ +export const availableCountriesQuery = /* GraphQL */ ` +query availableCountriesQuery { + availableCountries { + ...Country + __typename + } +} + +fragment Country on Country { + id + code + name + enabled + __typename +} +` diff --git a/src/components/hooks/order/index.ts b/src/components/hooks/order/index.ts index bf6383122..7ec92f670 100644 --- a/src/components/hooks/order/index.ts +++ b/src/components/hooks/order/index.ts @@ -1,4 +1,5 @@ export { default as useSetCustomerForOrder } from './useSetCustomerForOrder' export { default as useSetOrderShippingAddress } from './useSetOrderShippingAddress' export { default as useApplyCouponCode } from './useApplyCouponCode' +export { default as useAvailableCountries } from './useAvailableCountries' diff --git a/src/components/hooks/order/useAvailableCountries.tsx b/src/components/hooks/order/useAvailableCountries.tsx new file mode 100644 index 000000000..51099965a --- /dev/null +++ b/src/components/hooks/order/useAvailableCountries.tsx @@ -0,0 +1,14 @@ +import { GetAvailableCountriesQuery } from '@framework/schema' +import { availableCountriesQuery } from '@framework/utils/queries/available-countries-query' +import gglFetcher from 'src/utils/gglFetcher' +import useSWR from 'swr' + +const useAvailableCountries = () => { + const { data, isValidating } = useSWR([availableCountriesQuery], gglFetcher) + return { + countries: data?.availableCountries, + loading: isValidating, + } +} + +export default useAvailableCountries diff --git a/src/components/modules/checkout/CheckoutInfo/components/ShippingInfoForm/ShippingInfoForm.tsx b/src/components/modules/checkout/CheckoutInfo/components/ShippingInfoForm/ShippingInfoForm.tsx index f1931d7fb..6331daf6d 100644 --- a/src/components/modules/checkout/CheckoutInfo/components/ShippingInfoForm/ShippingInfoForm.tsx +++ b/src/components/modules/checkout/CheckoutInfo/components/ShippingInfoForm/ShippingInfoForm.tsx @@ -2,7 +2,7 @@ import { Form, Formik } from 'formik' import React, { useEffect, useRef } from 'react' import { ButtonCommon, InputFiledInForm, SelectFieldInForm } from 'src/components/common' import { useMessage } from 'src/components/contexts' -import { useSetOrderShippingAddress } from 'src/components/hooks/order' +import { useAvailableCountries, useSetOrderShippingAddress } from 'src/components/hooks/order' import { COUNTRY_CODE } from 'src/domains/data/countryCode' import { LANGUAGE } from 'src/utils/language.utils' import { CustomInputCommon } from 'src/utils/type.utils' @@ -28,6 +28,9 @@ const displayingErrorMessagesSchema = Yup.object().shape({ }) +const DEFAULT_COUNTRY_CODE = 'MY' +const DEFAULT_PROVINCE = 'Sabah' + const provinceOptions = [ { name: 'Hồ Chí Minh', @@ -37,12 +40,17 @@ const provinceOptions = [ name: 'Hà Nội', value: 'Hà Nội', }, + { + name: 'Sabah', + value: 'Sabah', + }, ] const ShippingInfoForm = ({ onConfirm, id, activeStep }: ShippingInfoFormProps) => { const addressRef = useRef(null) const { setOrderShippingAddress, loading } = useSetOrderShippingAddress() const { showMessageError } = useMessage() + const { countries } = useAvailableCountries() useEffect(() => { setTimeout(() => { @@ -74,9 +82,9 @@ const ShippingInfoForm = ({ onConfirm, id, activeStep }: ShippingInfoFormProps) { streetLine1: '', city: '', - province: '', + province: DEFAULT_PROVINCE, postalCode: '', - countryCode: '', + countryCode: DEFAULT_COUNTRY_CODE, phoneNumber: '', }} validationSchema={displayingErrorMessagesSchema} @@ -141,12 +149,11 @@ const ShippingInfoForm = ({ onConfirm, id, activeStep }: ShippingInfoFormProps)
)} +
) From 77e157e1093a66af6dabfeaf1a596d90fc9a79df Mon Sep 17 00:00:00 2001 From: lytrankieio123 Date: Wed, 20 Oct 2021 13:31:09 +0700 Subject: [PATCH 14/27] :fire: remove: useless file country code :%s --- .../ShippingInfoForm/ShippingInfoForm.tsx | 1 - src/domains/data/CountryCode.ts | 3227 ----------------- 2 files changed, 3228 deletions(-) delete mode 100644 src/domains/data/CountryCode.ts diff --git a/src/components/modules/checkout/CheckoutInfo/components/ShippingInfoForm/ShippingInfoForm.tsx b/src/components/modules/checkout/CheckoutInfo/components/ShippingInfoForm/ShippingInfoForm.tsx index 6331daf6d..012882277 100644 --- a/src/components/modules/checkout/CheckoutInfo/components/ShippingInfoForm/ShippingInfoForm.tsx +++ b/src/components/modules/checkout/CheckoutInfo/components/ShippingInfoForm/ShippingInfoForm.tsx @@ -3,7 +3,6 @@ import React, { useEffect, useRef } from 'react' import { ButtonCommon, InputFiledInForm, SelectFieldInForm } from 'src/components/common' import { useMessage } from 'src/components/contexts' import { useAvailableCountries, useSetOrderShippingAddress } from 'src/components/hooks/order' -import { COUNTRY_CODE } from 'src/domains/data/countryCode' import { LANGUAGE } from 'src/utils/language.utils' import { CustomInputCommon } from 'src/utils/type.utils' import * as Yup from 'yup' diff --git a/src/domains/data/CountryCode.ts b/src/domains/data/CountryCode.ts deleted file mode 100644 index 423abc60a..000000000 --- a/src/domains/data/CountryCode.ts +++ /dev/null @@ -1,3227 +0,0 @@ -// A standardized code for the country [ISO 3166-1](https://en.wikipedia.org/wiki/List_of_ISO_3166_country_codes) -export const COUNTRY_CODE = [ - { - "name": "Afghanistan", - "alpha-2": "AF", - "alpha-3": "AFG", - "country-code": "004", - "iso_3166-2": "ISO 3166-2:AF", - "region": "Asia", - "sub-region": "Southern Asia", - "intermediate-region": "", - "region-code": "142", - "sub-region-code": "034", - "intermediate-region-code": "" - }, - { - "name": "Åland Islands", - "alpha-2": "AX", - "alpha-3": "ALA", - "country-code": "248", - "iso_3166-2": "ISO 3166-2:AX", - "region": "Europe", - "sub-region": "Northern Europe", - "intermediate-region": "", - "region-code": "150", - "sub-region-code": "154", - "intermediate-region-code": "" - }, - { - "name": "Albania", - "alpha-2": "AL", - "alpha-3": "ALB", - "country-code": "008", - "iso_3166-2": "ISO 3166-2:AL", - "region": "Europe", - "sub-region": "Southern Europe", - "intermediate-region": "", - "region-code": "150", - "sub-region-code": "039", - "intermediate-region-code": "" - }, - { - "name": "Algeria", - "alpha-2": "DZ", - "alpha-3": "DZA", - "country-code": "012", - "iso_3166-2": "ISO 3166-2:DZ", - "region": "Africa", - "sub-region": "Northern Africa", - "intermediate-region": "", - "region-code": "002", - "sub-region-code": "015", - "intermediate-region-code": "" - }, - { - "name": "American Samoa", - "alpha-2": "AS", - "alpha-3": "ASM", - "country-code": "016", - "iso_3166-2": "ISO 3166-2:AS", - "region": "Oceania", - "sub-region": "Polynesia", - "intermediate-region": "", - "region-code": "009", - "sub-region-code": "061", - "intermediate-region-code": "" - }, - { - "name": "Andorra", - "alpha-2": "AD", - "alpha-3": "AND", - "country-code": "020", - "iso_3166-2": "ISO 3166-2:AD", - "region": "Europe", - "sub-region": "Southern Europe", - "intermediate-region": "", - "region-code": "150", - "sub-region-code": "039", - "intermediate-region-code": "" - }, - { - "name": "Angola", - "alpha-2": "AO", - "alpha-3": "AGO", - "country-code": "024", - "iso_3166-2": "ISO 3166-2:AO", - "region": "Africa", - "sub-region": "Sub-Saharan Africa", - "intermediate-region": "Middle Africa", - "region-code": "002", - "sub-region-code": "202", - "intermediate-region-code": "017" - }, - { - "name": "Anguilla", - "alpha-2": "AI", - "alpha-3": "AIA", - "country-code": "660", - "iso_3166-2": "ISO 3166-2:AI", - "region": "Americas", - "sub-region": "Latin America and the Caribbean", - "intermediate-region": "Caribbean", - "region-code": "019", - "sub-region-code": "419", - "intermediate-region-code": "029" - }, - { - "name": "Antigua and Barbuda", - "alpha-2": "AG", - "alpha-3": "ATG", - "country-code": "028", - "iso_3166-2": "ISO 3166-2:AG", - "region": "Americas", - "sub-region": "Latin America and the Caribbean", - "intermediate-region": "Caribbean", - "region-code": "019", - "sub-region-code": "419", - "intermediate-region-code": "029" - }, - { - "name": "Argentina", - "alpha-2": "AR", - "alpha-3": "ARG", - "country-code": "032", - "iso_3166-2": "ISO 3166-2:AR", - "region": "Americas", - "sub-region": "Latin America and the Caribbean", - "intermediate-region": "South America", - "region-code": "019", - "sub-region-code": "419", - "intermediate-region-code": "005" - }, - { - "name": "Armenia", - "alpha-2": "AM", - "alpha-3": "ARM", - "country-code": "051", - "iso_3166-2": "ISO 3166-2:AM", - "region": "Asia", - "sub-region": "Western Asia", - "intermediate-region": "", - "region-code": "142", - "sub-region-code": "145", - "intermediate-region-code": "" - }, - { - "name": "Aruba", - "alpha-2": "AW", - "alpha-3": "ABW", - "country-code": "533", - "iso_3166-2": "ISO 3166-2:AW", - "region": "Americas", - "sub-region": "Latin America and the Caribbean", - "intermediate-region": "Caribbean", - "region-code": "019", - "sub-region-code": "419", - "intermediate-region-code": "029" - }, - { - "name": "Australia", - "alpha-2": "AU", - "alpha-3": "AUS", - "country-code": "036", - "iso_3166-2": "ISO 3166-2:AU", - "region": "Oceania", - "sub-region": "Australia and New Zealand", - "intermediate-region": "", - "region-code": "009", - "sub-region-code": "053", - "intermediate-region-code": "" - }, - { - "name": "Austria", - "alpha-2": "AT", - "alpha-3": "AUT", - "country-code": "040", - "iso_3166-2": "ISO 3166-2:AT", - "region": "Europe", - "sub-region": "Western Europe", - "intermediate-region": "", - "region-code": "150", - "sub-region-code": "155", - "intermediate-region-code": "" - }, - { - "name": "Azerbaijan", - "alpha-2": "AZ", - "alpha-3": "AZE", - "country-code": "031", - "iso_3166-2": "ISO 3166-2:AZ", - "region": "Asia", - "sub-region": "Western Asia", - "intermediate-region": "", - "region-code": "142", - "sub-region-code": "145", - "intermediate-region-code": "" - }, - { - "name": "Bahamas", - "alpha-2": "BS", - "alpha-3": "BHS", - "country-code": "044", - "iso_3166-2": "ISO 3166-2:BS", - "region": "Americas", - "sub-region": "Latin America and the Caribbean", - "intermediate-region": "Caribbean", - "region-code": "019", - "sub-region-code": "419", - "intermediate-region-code": "029" - }, - { - "name": "Bahrain", - "alpha-2": "BH", - "alpha-3": "BHR", - "country-code": "048", - "iso_3166-2": "ISO 3166-2:BH", - "region": "Asia", - "sub-region": "Western Asia", - "intermediate-region": "", - "region-code": "142", - "sub-region-code": "145", - "intermediate-region-code": "" - }, - { - "name": "Bangladesh", - "alpha-2": "BD", - "alpha-3": "BGD", - "country-code": "050", - "iso_3166-2": "ISO 3166-2:BD", - "region": "Asia", - "sub-region": "Southern Asia", - "intermediate-region": "", - "region-code": "142", - "sub-region-code": "034", - "intermediate-region-code": "" - }, - { - "name": "Barbados", - "alpha-2": "BB", - "alpha-3": "BRB", - "country-code": "052", - "iso_3166-2": "ISO 3166-2:BB", - "region": "Americas", - "sub-region": "Latin America and the Caribbean", - "intermediate-region": "Caribbean", - "region-code": "019", - "sub-region-code": "419", - "intermediate-region-code": "029" - }, - { - "name": "Belarus", - "alpha-2": "BY", - "alpha-3": "BLR", - "country-code": "112", - "iso_3166-2": "ISO 3166-2:BY", - "region": "Europe", - "sub-region": "Eastern Europe", - "intermediate-region": "", - "region-code": "150", - "sub-region-code": "151", - "intermediate-region-code": "" - }, - { - "name": "Belgium", - "alpha-2": "BE", - "alpha-3": "BEL", - "country-code": "056", - "iso_3166-2": "ISO 3166-2:BE", - "region": "Europe", - "sub-region": "Western Europe", - "intermediate-region": "", - "region-code": "150", - "sub-region-code": "155", - "intermediate-region-code": "" - }, - { - "name": "Belize", - "alpha-2": "BZ", - "alpha-3": "BLZ", - "country-code": "084", - "iso_3166-2": "ISO 3166-2:BZ", - "region": "Americas", - "sub-region": "Latin America and the Caribbean", - "intermediate-region": "Central America", - "region-code": "019", - "sub-region-code": "419", - "intermediate-region-code": "013" - }, - { - "name": "Benin", - "alpha-2": "BJ", - "alpha-3": "BEN", - "country-code": "204", - "iso_3166-2": "ISO 3166-2:BJ", - "region": "Africa", - "sub-region": "Sub-Saharan Africa", - "intermediate-region": "Western Africa", - "region-code": "002", - "sub-region-code": "202", - "intermediate-region-code": "011" - }, - { - "name": "Bermuda", - "alpha-2": "BM", - "alpha-3": "BMU", - "country-code": "060", - "iso_3166-2": "ISO 3166-2:BM", - "region": "Americas", - "sub-region": "Northern America", - "intermediate-region": "", - "region-code": "019", - "sub-region-code": "021", - "intermediate-region-code": "" - }, - { - "name": "Bhutan", - "alpha-2": "BT", - "alpha-3": "BTN", - "country-code": "064", - "iso_3166-2": "ISO 3166-2:BT", - "region": "Asia", - "sub-region": "Southern Asia", - "intermediate-region": "", - "region-code": "142", - "sub-region-code": "034", - "intermediate-region-code": "" - }, - { - "name": "Bolivia (Plurinational State of)", - "alpha-2": "BO", - "alpha-3": "BOL", - "country-code": "068", - "iso_3166-2": "ISO 3166-2:BO", - "region": "Americas", - "sub-region": "Latin America and the Caribbean", - "intermediate-region": "South America", - "region-code": "019", - "sub-region-code": "419", - "intermediate-region-code": "005" - }, - { - "name": "Bonaire, Sint Eustatius and Saba", - "alpha-2": "BQ", - "alpha-3": "BES", - "country-code": "535", - "iso_3166-2": "ISO 3166-2:BQ", - "region": "Americas", - "sub-region": "Latin America and the Caribbean", - "intermediate-region": "Caribbean", - "region-code": "019", - "sub-region-code": "419", - "intermediate-region-code": "029" - }, - { - "name": "Bosnia and Herzegovina", - "alpha-2": "BA", - "alpha-3": "BIH", - "country-code": "070", - "iso_3166-2": "ISO 3166-2:BA", - "region": "Europe", - "sub-region": "Southern Europe", - "intermediate-region": "", - "region-code": "150", - "sub-region-code": "039", - "intermediate-region-code": "" - }, - { - "name": "Botswana", - "alpha-2": "BW", - "alpha-3": "BWA", - "country-code": "072", - "iso_3166-2": "ISO 3166-2:BW", - "region": "Africa", - "sub-region": "Sub-Saharan Africa", - "intermediate-region": "Southern Africa", - "region-code": "002", - "sub-region-code": "202", - "intermediate-region-code": "018" - }, - { - "name": "Bouvet Island", - "alpha-2": "BV", - "alpha-3": "BVT", - "country-code": "074", - "iso_3166-2": "ISO 3166-2:BV", - "region": "Americas", - "sub-region": "Latin America and the Caribbean", - "intermediate-region": "South America", - "region-code": "019", - "sub-region-code": "419", - "intermediate-region-code": "005" - }, - { - "name": "Brazil", - "alpha-2": "BR", - "alpha-3": "BRA", - "country-code": "076", - "iso_3166-2": "ISO 3166-2:BR", - "region": "Americas", - "sub-region": "Latin America and the Caribbean", - "intermediate-region": "South America", - "region-code": "019", - "sub-region-code": "419", - "intermediate-region-code": "005" - }, - { - "name": "British Indian Ocean Territory", - "alpha-2": "IO", - "alpha-3": "IOT", - "country-code": "086", - "iso_3166-2": "ISO 3166-2:IO", - "region": "Africa", - "sub-region": "Sub-Saharan Africa", - "intermediate-region": "Eastern Africa", - "region-code": "002", - "sub-region-code": "202", - "intermediate-region-code": "014" - }, - { - "name": "Brunei Darussalam", - "alpha-2": "BN", - "alpha-3": "BRN", - "country-code": "096", - "iso_3166-2": "ISO 3166-2:BN", - "region": "Asia", - "sub-region": "South-eastern Asia", - "intermediate-region": "", - "region-code": "142", - "sub-region-code": "035", - "intermediate-region-code": "" - }, - { - "name": "Bulgaria", - "alpha-2": "BG", - "alpha-3": "BGR", - "country-code": "100", - "iso_3166-2": "ISO 3166-2:BG", - "region": "Europe", - "sub-region": "Eastern Europe", - "intermediate-region": "", - "region-code": "150", - "sub-region-code": "151", - "intermediate-region-code": "" - }, - { - "name": "Burkina Faso", - "alpha-2": "BF", - "alpha-3": "BFA", - "country-code": "854", - "iso_3166-2": "ISO 3166-2:BF", - "region": "Africa", - "sub-region": "Sub-Saharan Africa", - "intermediate-region": "Western Africa", - "region-code": "002", - "sub-region-code": "202", - "intermediate-region-code": "011" - }, - { - "name": "Burundi", - "alpha-2": "BI", - "alpha-3": "BDI", - "country-code": "108", - "iso_3166-2": "ISO 3166-2:BI", - "region": "Africa", - "sub-region": "Sub-Saharan Africa", - "intermediate-region": "Eastern Africa", - "region-code": "002", - "sub-region-code": "202", - "intermediate-region-code": "014" - }, - { - "name": "Cabo Verde", - "alpha-2": "CV", - "alpha-3": "CPV", - "country-code": "132", - "iso_3166-2": "ISO 3166-2:CV", - "region": "Africa", - "sub-region": "Sub-Saharan Africa", - "intermediate-region": "Western Africa", - "region-code": "002", - "sub-region-code": "202", - "intermediate-region-code": "011" - }, - { - "name": "Cambodia", - "alpha-2": "KH", - "alpha-3": "KHM", - "country-code": "116", - "iso_3166-2": "ISO 3166-2:KH", - "region": "Asia", - "sub-region": "South-eastern Asia", - "intermediate-region": "", - "region-code": "142", - "sub-region-code": "035", - "intermediate-region-code": "" - }, - { - "name": "Cameroon", - "alpha-2": "CM", - "alpha-3": "CMR", - "country-code": "120", - "iso_3166-2": "ISO 3166-2:CM", - "region": "Africa", - "sub-region": "Sub-Saharan Africa", - "intermediate-region": "Middle Africa", - "region-code": "002", - "sub-region-code": "202", - "intermediate-region-code": "017" - }, - { - "name": "Canada", - "alpha-2": "CA", - "alpha-3": "CAN", - "country-code": "124", - "iso_3166-2": "ISO 3166-2:CA", - "region": "Americas", - "sub-region": "Northern America", - "intermediate-region": "", - "region-code": "019", - "sub-region-code": "021", - "intermediate-region-code": "" - }, - { - "name": "Cayman Islands", - "alpha-2": "KY", - "alpha-3": "CYM", - "country-code": "136", - "iso_3166-2": "ISO 3166-2:KY", - "region": "Americas", - "sub-region": "Latin America and the Caribbean", - "intermediate-region": "Caribbean", - "region-code": "019", - "sub-region-code": "419", - "intermediate-region-code": "029" - }, - { - "name": "Central African Republic", - "alpha-2": "CF", - "alpha-3": "CAF", - "country-code": "140", - "iso_3166-2": "ISO 3166-2:CF", - "region": "Africa", - "sub-region": "Sub-Saharan Africa", - "intermediate-region": "Middle Africa", - "region-code": "002", - "sub-region-code": "202", - "intermediate-region-code": "017" - }, - { - "name": "Chad", - "alpha-2": "TD", - "alpha-3": "TCD", - "country-code": "148", - "iso_3166-2": "ISO 3166-2:TD", - "region": "Africa", - "sub-region": "Sub-Saharan Africa", - "intermediate-region": "Middle Africa", - "region-code": "002", - "sub-region-code": "202", - "intermediate-region-code": "017" - }, - { - "name": "Chile", - "alpha-2": "CL", - "alpha-3": "CHL", - "country-code": "152", - "iso_3166-2": "ISO 3166-2:CL", - "region": "Americas", - "sub-region": "Latin America and the Caribbean", - "intermediate-region": "South America", - "region-code": "019", - "sub-region-code": "419", - "intermediate-region-code": "005" - }, - { - "name": "China", - "alpha-2": "CN", - "alpha-3": "CHN", - "country-code": "156", - "iso_3166-2": "ISO 3166-2:CN", - "region": "Asia", - "sub-region": "Eastern Asia", - "intermediate-region": "", - "region-code": "142", - "sub-region-code": "030", - "intermediate-region-code": "" - }, - { - "name": "Christmas Island", - "alpha-2": "CX", - "alpha-3": "CXR", - "country-code": "162", - "iso_3166-2": "ISO 3166-2:CX", - "region": "Oceania", - "sub-region": "Australia and New Zealand", - "intermediate-region": "", - "region-code": "009", - "sub-region-code": "053", - "intermediate-region-code": "" - }, - { - "name": "Cocos (Keeling) Islands", - "alpha-2": "CC", - "alpha-3": "CCK", - "country-code": "166", - "iso_3166-2": "ISO 3166-2:CC", - "region": "Oceania", - "sub-region": "Australia and New Zealand", - "intermediate-region": "", - "region-code": "009", - "sub-region-code": "053", - "intermediate-region-code": "" - }, - { - "name": "Colombia", - "alpha-2": "CO", - "alpha-3": "COL", - "country-code": "170", - "iso_3166-2": "ISO 3166-2:CO", - "region": "Americas", - "sub-region": "Latin America and the Caribbean", - "intermediate-region": "South America", - "region-code": "019", - "sub-region-code": "419", - "intermediate-region-code": "005" - }, - { - "name": "Comoros", - "alpha-2": "KM", - "alpha-3": "COM", - "country-code": "174", - "iso_3166-2": "ISO 3166-2:KM", - "region": "Africa", - "sub-region": "Sub-Saharan Africa", - "intermediate-region": "Eastern Africa", - "region-code": "002", - "sub-region-code": "202", - "intermediate-region-code": "014" - }, - { - "name": "Congo", - "alpha-2": "CG", - "alpha-3": "COG", - "country-code": "178", - "iso_3166-2": "ISO 3166-2:CG", - "region": "Africa", - "sub-region": "Sub-Saharan Africa", - "intermediate-region": "Middle Africa", - "region-code": "002", - "sub-region-code": "202", - "intermediate-region-code": "017" - }, - { - "name": "Congo (Democratic Republic of the)", - "alpha-2": "CD", - "alpha-3": "COD", - "country-code": "180", - "iso_3166-2": "ISO 3166-2:CD", - "region": "Africa", - "sub-region": "Sub-Saharan Africa", - "intermediate-region": "Middle Africa", - "region-code": "002", - "sub-region-code": "202", - "intermediate-region-code": "017" - }, - { - "name": "Cook Islands", - "alpha-2": "CK", - "alpha-3": "COK", - "country-code": "184", - "iso_3166-2": "ISO 3166-2:CK", - "region": "Oceania", - "sub-region": "Polynesia", - "intermediate-region": "", - "region-code": "009", - "sub-region-code": "061", - "intermediate-region-code": "" - }, - { - "name": "Costa Rica", - "alpha-2": "CR", - "alpha-3": "CRI", - "country-code": "188", - "iso_3166-2": "ISO 3166-2:CR", - "region": "Americas", - "sub-region": "Latin America and the Caribbean", - "intermediate-region": "Central America", - "region-code": "019", - "sub-region-code": "419", - "intermediate-region-code": "013" - }, - { - "name": "Côte d'Ivoire", - "alpha-2": "CI", - "alpha-3": "CIV", - "country-code": "384", - "iso_3166-2": "ISO 3166-2:CI", - "region": "Africa", - "sub-region": "Sub-Saharan Africa", - "intermediate-region": "Western Africa", - "region-code": "002", - "sub-region-code": "202", - "intermediate-region-code": "011" - }, - { - "name": "Croatia", - "alpha-2": "HR", - "alpha-3": "HRV", - "country-code": "191", - "iso_3166-2": "ISO 3166-2:HR", - "region": "Europe", - "sub-region": "Southern Europe", - "intermediate-region": "", - "region-code": "150", - "sub-region-code": "039", - "intermediate-region-code": "" - }, - { - "name": "Cuba", - "alpha-2": "CU", - "alpha-3": "CUB", - "country-code": "192", - "iso_3166-2": "ISO 3166-2:CU", - "region": "Americas", - "sub-region": "Latin America and the Caribbean", - "intermediate-region": "Caribbean", - "region-code": "019", - "sub-region-code": "419", - "intermediate-region-code": "029" - }, - { - "name": "Curaçao", - "alpha-2": "CW", - "alpha-3": "CUW", - "country-code": "531", - "iso_3166-2": "ISO 3166-2:CW", - "region": "Americas", - "sub-region": "Latin America and the Caribbean", - "intermediate-region": "Caribbean", - "region-code": "019", - "sub-region-code": "419", - "intermediate-region-code": "029" - }, - { - "name": "Cyprus", - "alpha-2": "CY", - "alpha-3": "CYP", - "country-code": "196", - "iso_3166-2": "ISO 3166-2:CY", - "region": "Asia", - "sub-region": "Western Asia", - "intermediate-region": "", - "region-code": "142", - "sub-region-code": "145", - "intermediate-region-code": "" - }, - { - "name": "Czechia", - "alpha-2": "CZ", - "alpha-3": "CZE", - "country-code": "203", - "iso_3166-2": "ISO 3166-2:CZ", - "region": "Europe", - "sub-region": "Eastern Europe", - "intermediate-region": "", - "region-code": "150", - "sub-region-code": "151", - "intermediate-region-code": "" - }, - { - "name": "Denmark", - "alpha-2": "DK", - "alpha-3": "DNK", - "country-code": "208", - "iso_3166-2": "ISO 3166-2:DK", - "region": "Europe", - "sub-region": "Northern Europe", - "intermediate-region": "", - "region-code": "150", - "sub-region-code": "154", - "intermediate-region-code": "" - }, - { - "name": "Djibouti", - "alpha-2": "DJ", - "alpha-3": "DJI", - "country-code": "262", - "iso_3166-2": "ISO 3166-2:DJ", - "region": "Africa", - "sub-region": "Sub-Saharan Africa", - "intermediate-region": "Eastern Africa", - "region-code": "002", - "sub-region-code": "202", - "intermediate-region-code": "014" - }, - { - "name": "Dominica", - "alpha-2": "DM", - "alpha-3": "DMA", - "country-code": "212", - "iso_3166-2": "ISO 3166-2:DM", - "region": "Americas", - "sub-region": "Latin America and the Caribbean", - "intermediate-region": "Caribbean", - "region-code": "019", - "sub-region-code": "419", - "intermediate-region-code": "029" - }, - { - "name": "Dominican Republic", - "alpha-2": "DO", - "alpha-3": "DOM", - "country-code": "214", - "iso_3166-2": "ISO 3166-2:DO", - "region": "Americas", - "sub-region": "Latin America and the Caribbean", - "intermediate-region": "Caribbean", - "region-code": "019", - "sub-region-code": "419", - "intermediate-region-code": "029" - }, - { - "name": "Ecuador", - "alpha-2": "EC", - "alpha-3": "ECU", - "country-code": "218", - "iso_3166-2": "ISO 3166-2:EC", - "region": "Americas", - "sub-region": "Latin America and the Caribbean", - "intermediate-region": "South America", - "region-code": "019", - "sub-region-code": "419", - "intermediate-region-code": "005" - }, - { - "name": "Egypt", - "alpha-2": "EG", - "alpha-3": "EGY", - "country-code": "818", - "iso_3166-2": "ISO 3166-2:EG", - "region": "Africa", - "sub-region": "Northern Africa", - "intermediate-region": "", - "region-code": "002", - "sub-region-code": "015", - "intermediate-region-code": "" - }, - { - "name": "El Salvador", - "alpha-2": "SV", - "alpha-3": "SLV", - "country-code": "222", - "iso_3166-2": "ISO 3166-2:SV", - "region": "Americas", - "sub-region": "Latin America and the Caribbean", - "intermediate-region": "Central America", - "region-code": "019", - "sub-region-code": "419", - "intermediate-region-code": "013" - }, - { - "name": "Equatorial Guinea", - "alpha-2": "GQ", - "alpha-3": "GNQ", - "country-code": "226", - "iso_3166-2": "ISO 3166-2:GQ", - "region": "Africa", - "sub-region": "Sub-Saharan Africa", - "intermediate-region": "Middle Africa", - "region-code": "002", - "sub-region-code": "202", - "intermediate-region-code": "017" - }, - { - "name": "Eritrea", - "alpha-2": "ER", - "alpha-3": "ERI", - "country-code": "232", - "iso_3166-2": "ISO 3166-2:ER", - "region": "Africa", - "sub-region": "Sub-Saharan Africa", - "intermediate-region": "Eastern Africa", - "region-code": "002", - "sub-region-code": "202", - "intermediate-region-code": "014" - }, - { - "name": "Estonia", - "alpha-2": "EE", - "alpha-3": "EST", - "country-code": "233", - "iso_3166-2": "ISO 3166-2:EE", - "region": "Europe", - "sub-region": "Northern Europe", - "intermediate-region": "", - "region-code": "150", - "sub-region-code": "154", - "intermediate-region-code": "" - }, - { - "name": "Eswatini", - "alpha-2": "SZ", - "alpha-3": "SWZ", - "country-code": "748", - "iso_3166-2": "ISO 3166-2:SZ", - "region": "Africa", - "sub-region": "Sub-Saharan Africa", - "intermediate-region": "Southern Africa", - "region-code": "002", - "sub-region-code": "202", - "intermediate-region-code": "018" - }, - { - "name": "Ethiopia", - "alpha-2": "ET", - "alpha-3": "ETH", - "country-code": "231", - "iso_3166-2": "ISO 3166-2:ET", - "region": "Africa", - "sub-region": "Sub-Saharan Africa", - "intermediate-region": "Eastern Africa", - "region-code": "002", - "sub-region-code": "202", - "intermediate-region-code": "014" - }, - { - "name": "Falkland Islands (Malvinas)", - "alpha-2": "FK", - "alpha-3": "FLK", - "country-code": "238", - "iso_3166-2": "ISO 3166-2:FK", - "region": "Americas", - "sub-region": "Latin America and the Caribbean", - "intermediate-region": "South America", - "region-code": "019", - "sub-region-code": "419", - "intermediate-region-code": "005" - }, - { - "name": "Faroe Islands", - "alpha-2": "FO", - "alpha-3": "FRO", - "country-code": "234", - "iso_3166-2": "ISO 3166-2:FO", - "region": "Europe", - "sub-region": "Northern Europe", - "intermediate-region": "", - "region-code": "150", - "sub-region-code": "154", - "intermediate-region-code": "" - }, - { - "name": "Fiji", - "alpha-2": "FJ", - "alpha-3": "FJI", - "country-code": "242", - "iso_3166-2": "ISO 3166-2:FJ", - "region": "Oceania", - "sub-region": "Melanesia", - "intermediate-region": "", - "region-code": "009", - "sub-region-code": "054", - "intermediate-region-code": "" - }, - { - "name": "Finland", - "alpha-2": "FI", - "alpha-3": "FIN", - "country-code": "246", - "iso_3166-2": "ISO 3166-2:FI", - "region": "Europe", - "sub-region": "Northern Europe", - "intermediate-region": "", - "region-code": "150", - "sub-region-code": "154", - "intermediate-region-code": "" - }, - { - "name": "France", - "alpha-2": "FR", - "alpha-3": "FRA", - "country-code": "250", - "iso_3166-2": "ISO 3166-2:FR", - "region": "Europe", - "sub-region": "Western Europe", - "intermediate-region": "", - "region-code": "150", - "sub-region-code": "155", - "intermediate-region-code": "" - }, - { - "name": "French Guiana", - "alpha-2": "GF", - "alpha-3": "GUF", - "country-code": "254", - "iso_3166-2": "ISO 3166-2:GF", - "region": "Americas", - "sub-region": "Latin America and the Caribbean", - "intermediate-region": "South America", - "region-code": "019", - "sub-region-code": "419", - "intermediate-region-code": "005" - }, - { - "name": "French Polynesia", - "alpha-2": "PF", - "alpha-3": "PYF", - "country-code": "258", - "iso_3166-2": "ISO 3166-2:PF", - "region": "Oceania", - "sub-region": "Polynesia", - "intermediate-region": "", - "region-code": "009", - "sub-region-code": "061", - "intermediate-region-code": "" - }, - { - "name": "French Southern Territories", - "alpha-2": "TF", - "alpha-3": "ATF", - "country-code": "260", - "iso_3166-2": "ISO 3166-2:TF", - "region": "Africa", - "sub-region": "Sub-Saharan Africa", - "intermediate-region": "Eastern Africa", - "region-code": "002", - "sub-region-code": "202", - "intermediate-region-code": "014" - }, - { - "name": "Gabon", - "alpha-2": "GA", - "alpha-3": "GAB", - "country-code": "266", - "iso_3166-2": "ISO 3166-2:GA", - "region": "Africa", - "sub-region": "Sub-Saharan Africa", - "intermediate-region": "Middle Africa", - "region-code": "002", - "sub-region-code": "202", - "intermediate-region-code": "017" - }, - { - "name": "Gambia", - "alpha-2": "GM", - "alpha-3": "GMB", - "country-code": "270", - "iso_3166-2": "ISO 3166-2:GM", - "region": "Africa", - "sub-region": "Sub-Saharan Africa", - "intermediate-region": "Western Africa", - "region-code": "002", - "sub-region-code": "202", - "intermediate-region-code": "011" - }, - { - "name": "Georgia", - "alpha-2": "GE", - "alpha-3": "GEO", - "country-code": "268", - "iso_3166-2": "ISO 3166-2:GE", - "region": "Asia", - "sub-region": "Western Asia", - "intermediate-region": "", - "region-code": "142", - "sub-region-code": "145", - "intermediate-region-code": "" - }, - { - "name": "Germany", - "alpha-2": "DE", - "alpha-3": "DEU", - "country-code": "276", - "iso_3166-2": "ISO 3166-2:DE", - "region": "Europe", - "sub-region": "Western Europe", - "intermediate-region": "", - "region-code": "150", - "sub-region-code": "155", - "intermediate-region-code": "" - }, - { - "name": "Ghana", - "alpha-2": "GH", - "alpha-3": "GHA", - "country-code": "288", - "iso_3166-2": "ISO 3166-2:GH", - "region": "Africa", - "sub-region": "Sub-Saharan Africa", - "intermediate-region": "Western Africa", - "region-code": "002", - "sub-region-code": "202", - "intermediate-region-code": "011" - }, - { - "name": "Gibraltar", - "alpha-2": "GI", - "alpha-3": "GIB", - "country-code": "292", - "iso_3166-2": "ISO 3166-2:GI", - "region": "Europe", - "sub-region": "Southern Europe", - "intermediate-region": "", - "region-code": "150", - "sub-region-code": "039", - "intermediate-region-code": "" - }, - { - "name": "Greece", - "alpha-2": "GR", - "alpha-3": "GRC", - "country-code": "300", - "iso_3166-2": "ISO 3166-2:GR", - "region": "Europe", - "sub-region": "Southern Europe", - "intermediate-region": "", - "region-code": "150", - "sub-region-code": "039", - "intermediate-region-code": "" - }, - { - "name": "Greenland", - "alpha-2": "GL", - "alpha-3": "GRL", - "country-code": "304", - "iso_3166-2": "ISO 3166-2:GL", - "region": "Americas", - "sub-region": "Northern America", - "intermediate-region": "", - "region-code": "019", - "sub-region-code": "021", - "intermediate-region-code": "" - }, - { - "name": "Grenada", - "alpha-2": "GD", - "alpha-3": "GRD", - "country-code": "308", - "iso_3166-2": "ISO 3166-2:GD", - "region": "Americas", - "sub-region": "Latin America and the Caribbean", - "intermediate-region": "Caribbean", - "region-code": "019", - "sub-region-code": "419", - "intermediate-region-code": "029" - }, - { - "name": "Guadeloupe", - "alpha-2": "GP", - "alpha-3": "GLP", - "country-code": "312", - "iso_3166-2": "ISO 3166-2:GP", - "region": "Americas", - "sub-region": "Latin America and the Caribbean", - "intermediate-region": "Caribbean", - "region-code": "019", - "sub-region-code": "419", - "intermediate-region-code": "029" - }, - { - "name": "Guam", - "alpha-2": "GU", - "alpha-3": "GUM", - "country-code": "316", - "iso_3166-2": "ISO 3166-2:GU", - "region": "Oceania", - "sub-region": "Micronesia", - "intermediate-region": "", - "region-code": "009", - "sub-region-code": "057", - "intermediate-region-code": "" - }, - { - "name": "Guatemala", - "alpha-2": "GT", - "alpha-3": "GTM", - "country-code": "320", - "iso_3166-2": "ISO 3166-2:GT", - "region": "Americas", - "sub-region": "Latin America and the Caribbean", - "intermediate-region": "Central America", - "region-code": "019", - "sub-region-code": "419", - "intermediate-region-code": "013" - }, - { - "name": "Guernsey", - "alpha-2": "GG", - "alpha-3": "GGY", - "country-code": "831", - "iso_3166-2": "ISO 3166-2:GG", - "region": "Europe", - "sub-region": "Northern Europe", - "intermediate-region": "Channel Islands", - "region-code": "150", - "sub-region-code": "154", - "intermediate-region-code": "830" - }, - { - "name": "Guinea", - "alpha-2": "GN", - "alpha-3": "GIN", - "country-code": "324", - "iso_3166-2": "ISO 3166-2:GN", - "region": "Africa", - "sub-region": "Sub-Saharan Africa", - "intermediate-region": "Western Africa", - "region-code": "002", - "sub-region-code": "202", - "intermediate-region-code": "011" - }, - { - "name": "Guinea-Bissau", - "alpha-2": "GW", - "alpha-3": "GNB", - "country-code": "624", - "iso_3166-2": "ISO 3166-2:GW", - "region": "Africa", - "sub-region": "Sub-Saharan Africa", - "intermediate-region": "Western Africa", - "region-code": "002", - "sub-region-code": "202", - "intermediate-region-code": "011" - }, - { - "name": "Guyana", - "alpha-2": "GY", - "alpha-3": "GUY", - "country-code": "328", - "iso_3166-2": "ISO 3166-2:GY", - "region": "Americas", - "sub-region": "Latin America and the Caribbean", - "intermediate-region": "South America", - "region-code": "019", - "sub-region-code": "419", - "intermediate-region-code": "005" - }, - { - "name": "Haiti", - "alpha-2": "HT", - "alpha-3": "HTI", - "country-code": "332", - "iso_3166-2": "ISO 3166-2:HT", - "region": "Americas", - "sub-region": "Latin America and the Caribbean", - "intermediate-region": "Caribbean", - "region-code": "019", - "sub-region-code": "419", - "intermediate-region-code": "029" - }, - { - "name": "Heard Island and McDonald Islands", - "alpha-2": "HM", - "alpha-3": "HMD", - "country-code": "334", - "iso_3166-2": "ISO 3166-2:HM", - "region": "Oceania", - "sub-region": "Australia and New Zealand", - "intermediate-region": "", - "region-code": "009", - "sub-region-code": "053", - "intermediate-region-code": "" - }, - { - "name": "Holy See", - "alpha-2": "VA", - "alpha-3": "VAT", - "country-code": "336", - "iso_3166-2": "ISO 3166-2:VA", - "region": "Europe", - "sub-region": "Southern Europe", - "intermediate-region": "", - "region-code": "150", - "sub-region-code": "039", - "intermediate-region-code": "" - }, - { - "name": "Honduras", - "alpha-2": "HN", - "alpha-3": "HND", - "country-code": "340", - "iso_3166-2": "ISO 3166-2:HN", - "region": "Americas", - "sub-region": "Latin America and the Caribbean", - "intermediate-region": "Central America", - "region-code": "019", - "sub-region-code": "419", - "intermediate-region-code": "013" - }, - { - "name": "Hong Kong", - "alpha-2": "HK", - "alpha-3": "HKG", - "country-code": "344", - "iso_3166-2": "ISO 3166-2:HK", - "region": "Asia", - "sub-region": "Eastern Asia", - "intermediate-region": "", - "region-code": "142", - "sub-region-code": "030", - "intermediate-region-code": "" - }, - { - "name": "Hungary", - "alpha-2": "HU", - "alpha-3": "HUN", - "country-code": "348", - "iso_3166-2": "ISO 3166-2:HU", - "region": "Europe", - "sub-region": "Eastern Europe", - "intermediate-region": "", - "region-code": "150", - "sub-region-code": "151", - "intermediate-region-code": "" - }, - { - "name": "Iceland", - "alpha-2": "IS", - "alpha-3": "ISL", - "country-code": "352", - "iso_3166-2": "ISO 3166-2:IS", - "region": "Europe", - "sub-region": "Northern Europe", - "intermediate-region": "", - "region-code": "150", - "sub-region-code": "154", - "intermediate-region-code": "" - }, - { - "name": "India", - "alpha-2": "IN", - "alpha-3": "IND", - "country-code": "356", - "iso_3166-2": "ISO 3166-2:IN", - "region": "Asia", - "sub-region": "Southern Asia", - "intermediate-region": "", - "region-code": "142", - "sub-region-code": "034", - "intermediate-region-code": "" - }, - { - "name": "Indonesia", - "alpha-2": "ID", - "alpha-3": "IDN", - "country-code": "360", - "iso_3166-2": "ISO 3166-2:ID", - "region": "Asia", - "sub-region": "South-eastern Asia", - "intermediate-region": "", - "region-code": "142", - "sub-region-code": "035", - "intermediate-region-code": "" - }, - { - "name": "Iran (Islamic Republic of)", - "alpha-2": "IR", - "alpha-3": "IRN", - "country-code": "364", - "iso_3166-2": "ISO 3166-2:IR", - "region": "Asia", - "sub-region": "Southern Asia", - "intermediate-region": "", - "region-code": "142", - "sub-region-code": "034", - "intermediate-region-code": "" - }, - { - "name": "Iraq", - "alpha-2": "IQ", - "alpha-3": "IRQ", - "country-code": "368", - "iso_3166-2": "ISO 3166-2:IQ", - "region": "Asia", - "sub-region": "Western Asia", - "intermediate-region": "", - "region-code": "142", - "sub-region-code": "145", - "intermediate-region-code": "" - }, - { - "name": "Ireland", - "alpha-2": "IE", - "alpha-3": "IRL", - "country-code": "372", - "iso_3166-2": "ISO 3166-2:IE", - "region": "Europe", - "sub-region": "Northern Europe", - "intermediate-region": "", - "region-code": "150", - "sub-region-code": "154", - "intermediate-region-code": "" - }, - { - "name": "Isle of Man", - "alpha-2": "IM", - "alpha-3": "IMN", - "country-code": "833", - "iso_3166-2": "ISO 3166-2:IM", - "region": "Europe", - "sub-region": "Northern Europe", - "intermediate-region": "", - "region-code": "150", - "sub-region-code": "154", - "intermediate-region-code": "" - }, - { - "name": "Israel", - "alpha-2": "IL", - "alpha-3": "ISR", - "country-code": "376", - "iso_3166-2": "ISO 3166-2:IL", - "region": "Asia", - "sub-region": "Western Asia", - "intermediate-region": "", - "region-code": "142", - "sub-region-code": "145", - "intermediate-region-code": "" - }, - { - "name": "Italy", - "alpha-2": "IT", - "alpha-3": "ITA", - "country-code": "380", - "iso_3166-2": "ISO 3166-2:IT", - "region": "Europe", - "sub-region": "Southern Europe", - "intermediate-region": "", - "region-code": "150", - "sub-region-code": "039", - "intermediate-region-code": "" - }, - { - "name": "Jamaica", - "alpha-2": "JM", - "alpha-3": "JAM", - "country-code": "388", - "iso_3166-2": "ISO 3166-2:JM", - "region": "Americas", - "sub-region": "Latin America and the Caribbean", - "intermediate-region": "Caribbean", - "region-code": "019", - "sub-region-code": "419", - "intermediate-region-code": "029" - }, - { - "name": "Japan", - "alpha-2": "JP", - "alpha-3": "JPN", - "country-code": "392", - "iso_3166-2": "ISO 3166-2:JP", - "region": "Asia", - "sub-region": "Eastern Asia", - "intermediate-region": "", - "region-code": "142", - "sub-region-code": "030", - "intermediate-region-code": "" - }, - { - "name": "Jersey", - "alpha-2": "JE", - "alpha-3": "JEY", - "country-code": "832", - "iso_3166-2": "ISO 3166-2:JE", - "region": "Europe", - "sub-region": "Northern Europe", - "intermediate-region": "Channel Islands", - "region-code": "150", - "sub-region-code": "154", - "intermediate-region-code": "830" - }, - { - "name": "Jordan", - "alpha-2": "JO", - "alpha-3": "JOR", - "country-code": "400", - "iso_3166-2": "ISO 3166-2:JO", - "region": "Asia", - "sub-region": "Western Asia", - "intermediate-region": "", - "region-code": "142", - "sub-region-code": "145", - "intermediate-region-code": "" - }, - { - "name": "Kazakhstan", - "alpha-2": "KZ", - "alpha-3": "KAZ", - "country-code": "398", - "iso_3166-2": "ISO 3166-2:KZ", - "region": "Asia", - "sub-region": "Central Asia", - "intermediate-region": "", - "region-code": "142", - "sub-region-code": "143", - "intermediate-region-code": "" - }, - { - "name": "Kenya", - "alpha-2": "KE", - "alpha-3": "KEN", - "country-code": "404", - "iso_3166-2": "ISO 3166-2:KE", - "region": "Africa", - "sub-region": "Sub-Saharan Africa", - "intermediate-region": "Eastern Africa", - "region-code": "002", - "sub-region-code": "202", - "intermediate-region-code": "014" - }, - { - "name": "Kiribati", - "alpha-2": "KI", - "alpha-3": "KIR", - "country-code": "296", - "iso_3166-2": "ISO 3166-2:KI", - "region": "Oceania", - "sub-region": "Micronesia", - "intermediate-region": "", - "region-code": "009", - "sub-region-code": "057", - "intermediate-region-code": "" - }, - { - "name": "Korea (Democratic People's Republic of)", - "alpha-2": "KP", - "alpha-3": "PRK", - "country-code": "408", - "iso_3166-2": "ISO 3166-2:KP", - "region": "Asia", - "sub-region": "Eastern Asia", - "intermediate-region": "", - "region-code": "142", - "sub-region-code": "030", - "intermediate-region-code": "" - }, - { - "name": "Korea (Republic of)", - "alpha-2": "KR", - "alpha-3": "KOR", - "country-code": "410", - "iso_3166-2": "ISO 3166-2:KR", - "region": "Asia", - "sub-region": "Eastern Asia", - "intermediate-region": "", - "region-code": "142", - "sub-region-code": "030", - "intermediate-region-code": "" - }, - { - "name": "Kuwait", - "alpha-2": "KW", - "alpha-3": "KWT", - "country-code": "414", - "iso_3166-2": "ISO 3166-2:KW", - "region": "Asia", - "sub-region": "Western Asia", - "intermediate-region": "", - "region-code": "142", - "sub-region-code": "145", - "intermediate-region-code": "" - }, - { - "name": "Kyrgyzstan", - "alpha-2": "KG", - "alpha-3": "KGZ", - "country-code": "417", - "iso_3166-2": "ISO 3166-2:KG", - "region": "Asia", - "sub-region": "Central Asia", - "intermediate-region": "", - "region-code": "142", - "sub-region-code": "143", - "intermediate-region-code": "" - }, - { - "name": "Lao People's Democratic Republic", - "alpha-2": "LA", - "alpha-3": "LAO", - "country-code": "418", - "iso_3166-2": "ISO 3166-2:LA", - "region": "Asia", - "sub-region": "South-eastern Asia", - "intermediate-region": "", - "region-code": "142", - "sub-region-code": "035", - "intermediate-region-code": "" - }, - { - "name": "Latvia", - "alpha-2": "LV", - "alpha-3": "LVA", - "country-code": "428", - "iso_3166-2": "ISO 3166-2:LV", - "region": "Europe", - "sub-region": "Northern Europe", - "intermediate-region": "", - "region-code": "150", - "sub-region-code": "154", - "intermediate-region-code": "" - }, - { - "name": "Lebanon", - "alpha-2": "LB", - "alpha-3": "LBN", - "country-code": "422", - "iso_3166-2": "ISO 3166-2:LB", - "region": "Asia", - "sub-region": "Western Asia", - "intermediate-region": "", - "region-code": "142", - "sub-region-code": "145", - "intermediate-region-code": "" - }, - { - "name": "Lesotho", - "alpha-2": "LS", - "alpha-3": "LSO", - "country-code": "426", - "iso_3166-2": "ISO 3166-2:LS", - "region": "Africa", - "sub-region": "Sub-Saharan Africa", - "intermediate-region": "Southern Africa", - "region-code": "002", - "sub-region-code": "202", - "intermediate-region-code": "018" - }, - { - "name": "Liberia", - "alpha-2": "LR", - "alpha-3": "LBR", - "country-code": "430", - "iso_3166-2": "ISO 3166-2:LR", - "region": "Africa", - "sub-region": "Sub-Saharan Africa", - "intermediate-region": "Western Africa", - "region-code": "002", - "sub-region-code": "202", - "intermediate-region-code": "011" - }, - { - "name": "Libya", - "alpha-2": "LY", - "alpha-3": "LBY", - "country-code": "434", - "iso_3166-2": "ISO 3166-2:LY", - "region": "Africa", - "sub-region": "Northern Africa", - "intermediate-region": "", - "region-code": "002", - "sub-region-code": "015", - "intermediate-region-code": "" - }, - { - "name": "Liechtenstein", - "alpha-2": "LI", - "alpha-3": "LIE", - "country-code": "438", - "iso_3166-2": "ISO 3166-2:LI", - "region": "Europe", - "sub-region": "Western Europe", - "intermediate-region": "", - "region-code": "150", - "sub-region-code": "155", - "intermediate-region-code": "" - }, - { - "name": "Lithuania", - "alpha-2": "LT", - "alpha-3": "LTU", - "country-code": "440", - "iso_3166-2": "ISO 3166-2:LT", - "region": "Europe", - "sub-region": "Northern Europe", - "intermediate-region": "", - "region-code": "150", - "sub-region-code": "154", - "intermediate-region-code": "" - }, - { - "name": "Luxembourg", - "alpha-2": "LU", - "alpha-3": "LUX", - "country-code": "442", - "iso_3166-2": "ISO 3166-2:LU", - "region": "Europe", - "sub-region": "Western Europe", - "intermediate-region": "", - "region-code": "150", - "sub-region-code": "155", - "intermediate-region-code": "" - }, - { - "name": "Macao", - "alpha-2": "MO", - "alpha-3": "MAC", - "country-code": "446", - "iso_3166-2": "ISO 3166-2:MO", - "region": "Asia", - "sub-region": "Eastern Asia", - "intermediate-region": "", - "region-code": "142", - "sub-region-code": "030", - "intermediate-region-code": "" - }, - { - "name": "Macedonia (the former Yugoslav Republic of)", - "alpha-2": "MK", - "alpha-3": "MKD", - "country-code": "807", - "iso_3166-2": "ISO 3166-2:MK", - "region": "Europe", - "sub-region": "Southern Europe", - "intermediate-region": "", - "region-code": "150", - "sub-region-code": "039", - "intermediate-region-code": "" - }, - { - "name": "Madagascar", - "alpha-2": "MG", - "alpha-3": "MDG", - "country-code": "450", - "iso_3166-2": "ISO 3166-2:MG", - "region": "Africa", - "sub-region": "Sub-Saharan Africa", - "intermediate-region": "Eastern Africa", - "region-code": "002", - "sub-region-code": "202", - "intermediate-region-code": "014" - }, - { - "name": "Malawi", - "alpha-2": "MW", - "alpha-3": "MWI", - "country-code": "454", - "iso_3166-2": "ISO 3166-2:MW", - "region": "Africa", - "sub-region": "Sub-Saharan Africa", - "intermediate-region": "Eastern Africa", - "region-code": "002", - "sub-region-code": "202", - "intermediate-region-code": "014" - }, - { - "name": "Malaysia", - "alpha-2": "MY", - "alpha-3": "MYS", - "country-code": "458", - "iso_3166-2": "ISO 3166-2:MY", - "region": "Asia", - "sub-region": "South-eastern Asia", - "intermediate-region": "", - "region-code": "142", - "sub-region-code": "035", - "intermediate-region-code": "" - }, - { - "name": "Maldives", - "alpha-2": "MV", - "alpha-3": "MDV", - "country-code": "462", - "iso_3166-2": "ISO 3166-2:MV", - "region": "Asia", - "sub-region": "Southern Asia", - "intermediate-region": "", - "region-code": "142", - "sub-region-code": "034", - "intermediate-region-code": "" - }, - { - "name": "Mali", - "alpha-2": "ML", - "alpha-3": "MLI", - "country-code": "466", - "iso_3166-2": "ISO 3166-2:ML", - "region": "Africa", - "sub-region": "Sub-Saharan Africa", - "intermediate-region": "Western Africa", - "region-code": "002", - "sub-region-code": "202", - "intermediate-region-code": "011" - }, - { - "name": "Malta", - "alpha-2": "MT", - "alpha-3": "MLT", - "country-code": "470", - "iso_3166-2": "ISO 3166-2:MT", - "region": "Europe", - "sub-region": "Southern Europe", - "intermediate-region": "", - "region-code": "150", - "sub-region-code": "039", - "intermediate-region-code": "" - }, - { - "name": "Marshall Islands", - "alpha-2": "MH", - "alpha-3": "MHL", - "country-code": "584", - "iso_3166-2": "ISO 3166-2:MH", - "region": "Oceania", - "sub-region": "Micronesia", - "intermediate-region": "", - "region-code": "009", - "sub-region-code": "057", - "intermediate-region-code": "" - }, - { - "name": "Martinique", - "alpha-2": "MQ", - "alpha-3": "MTQ", - "country-code": "474", - "iso_3166-2": "ISO 3166-2:MQ", - "region": "Americas", - "sub-region": "Latin America and the Caribbean", - "intermediate-region": "Caribbean", - "region-code": "019", - "sub-region-code": "419", - "intermediate-region-code": "029" - }, - { - "name": "Mauritania", - "alpha-2": "MR", - "alpha-3": "MRT", - "country-code": "478", - "iso_3166-2": "ISO 3166-2:MR", - "region": "Africa", - "sub-region": "Sub-Saharan Africa", - "intermediate-region": "Western Africa", - "region-code": "002", - "sub-region-code": "202", - "intermediate-region-code": "011" - }, - { - "name": "Mauritius", - "alpha-2": "MU", - "alpha-3": "MUS", - "country-code": "480", - "iso_3166-2": "ISO 3166-2:MU", - "region": "Africa", - "sub-region": "Sub-Saharan Africa", - "intermediate-region": "Eastern Africa", - "region-code": "002", - "sub-region-code": "202", - "intermediate-region-code": "014" - }, - { - "name": "Mayotte", - "alpha-2": "YT", - "alpha-3": "MYT", - "country-code": "175", - "iso_3166-2": "ISO 3166-2:YT", - "region": "Africa", - "sub-region": "Sub-Saharan Africa", - "intermediate-region": "Eastern Africa", - "region-code": "002", - "sub-region-code": "202", - "intermediate-region-code": "014" - }, - { - "name": "Mexico", - "alpha-2": "MX", - "alpha-3": "MEX", - "country-code": "484", - "iso_3166-2": "ISO 3166-2:MX", - "region": "Americas", - "sub-region": "Latin America and the Caribbean", - "intermediate-region": "Central America", - "region-code": "019", - "sub-region-code": "419", - "intermediate-region-code": "013" - }, - { - "name": "Micronesia (Federated States of)", - "alpha-2": "FM", - "alpha-3": "FSM", - "country-code": "583", - "iso_3166-2": "ISO 3166-2:FM", - "region": "Oceania", - "sub-region": "Micronesia", - "intermediate-region": "", - "region-code": "009", - "sub-region-code": "057", - "intermediate-region-code": "" - }, - { - "name": "Moldova (Republic of)", - "alpha-2": "MD", - "alpha-3": "MDA", - "country-code": "498", - "iso_3166-2": "ISO 3166-2:MD", - "region": "Europe", - "sub-region": "Eastern Europe", - "intermediate-region": "", - "region-code": "150", - "sub-region-code": "151", - "intermediate-region-code": "" - }, - { - "name": "Monaco", - "alpha-2": "MC", - "alpha-3": "MCO", - "country-code": "492", - "iso_3166-2": "ISO 3166-2:MC", - "region": "Europe", - "sub-region": "Western Europe", - "intermediate-region": "", - "region-code": "150", - "sub-region-code": "155", - "intermediate-region-code": "" - }, - { - "name": "Mongolia", - "alpha-2": "MN", - "alpha-3": "MNG", - "country-code": "496", - "iso_3166-2": "ISO 3166-2:MN", - "region": "Asia", - "sub-region": "Eastern Asia", - "intermediate-region": "", - "region-code": "142", - "sub-region-code": "030", - "intermediate-region-code": "" - }, - { - "name": "Montenegro", - "alpha-2": "ME", - "alpha-3": "MNE", - "country-code": "499", - "iso_3166-2": "ISO 3166-2:ME", - "region": "Europe", - "sub-region": "Southern Europe", - "intermediate-region": "", - "region-code": "150", - "sub-region-code": "039", - "intermediate-region-code": "" - }, - { - "name": "Montserrat", - "alpha-2": "MS", - "alpha-3": "MSR", - "country-code": "500", - "iso_3166-2": "ISO 3166-2:MS", - "region": "Americas", - "sub-region": "Latin America and the Caribbean", - "intermediate-region": "Caribbean", - "region-code": "019", - "sub-region-code": "419", - "intermediate-region-code": "029" - }, - { - "name": "Morocco", - "alpha-2": "MA", - "alpha-3": "MAR", - "country-code": "504", - "iso_3166-2": "ISO 3166-2:MA", - "region": "Africa", - "sub-region": "Northern Africa", - "intermediate-region": "", - "region-code": "002", - "sub-region-code": "015", - "intermediate-region-code": "" - }, - { - "name": "Mozambique", - "alpha-2": "MZ", - "alpha-3": "MOZ", - "country-code": "508", - "iso_3166-2": "ISO 3166-2:MZ", - "region": "Africa", - "sub-region": "Sub-Saharan Africa", - "intermediate-region": "Eastern Africa", - "region-code": "002", - "sub-region-code": "202", - "intermediate-region-code": "014" - }, - { - "name": "Myanmar", - "alpha-2": "MM", - "alpha-3": "MMR", - "country-code": "104", - "iso_3166-2": "ISO 3166-2:MM", - "region": "Asia", - "sub-region": "South-eastern Asia", - "intermediate-region": "", - "region-code": "142", - "sub-region-code": "035", - "intermediate-region-code": "" - }, - { - "name": "Namibia", - "alpha-2": "NA", - "alpha-3": "NAM", - "country-code": "516", - "iso_3166-2": "ISO 3166-2:NA", - "region": "Africa", - "sub-region": "Sub-Saharan Africa", - "intermediate-region": "Southern Africa", - "region-code": "002", - "sub-region-code": "202", - "intermediate-region-code": "018" - }, - { - "name": "Nauru", - "alpha-2": "NR", - "alpha-3": "NRU", - "country-code": "520", - "iso_3166-2": "ISO 3166-2:NR", - "region": "Oceania", - "sub-region": "Micronesia", - "intermediate-region": "", - "region-code": "009", - "sub-region-code": "057", - "intermediate-region-code": "" - }, - { - "name": "Nepal", - "alpha-2": "NP", - "alpha-3": "NPL", - "country-code": "524", - "iso_3166-2": "ISO 3166-2:NP", - "region": "Asia", - "sub-region": "Southern Asia", - "intermediate-region": "", - "region-code": "142", - "sub-region-code": "034", - "intermediate-region-code": "" - }, - { - "name": "Netherlands", - "alpha-2": "NL", - "alpha-3": "NLD", - "country-code": "528", - "iso_3166-2": "ISO 3166-2:NL", - "region": "Europe", - "sub-region": "Western Europe", - "intermediate-region": "", - "region-code": "150", - "sub-region-code": "155", - "intermediate-region-code": "" - }, - { - "name": "New Caledonia", - "alpha-2": "NC", - "alpha-3": "NCL", - "country-code": "540", - "iso_3166-2": "ISO 3166-2:NC", - "region": "Oceania", - "sub-region": "Melanesia", - "intermediate-region": "", - "region-code": "009", - "sub-region-code": "054", - "intermediate-region-code": "" - }, - { - "name": "New Zealand", - "alpha-2": "NZ", - "alpha-3": "NZL", - "country-code": "554", - "iso_3166-2": "ISO 3166-2:NZ", - "region": "Oceania", - "sub-region": "Australia and New Zealand", - "intermediate-region": "", - "region-code": "009", - "sub-region-code": "053", - "intermediate-region-code": "" - }, - { - "name": "Nicaragua", - "alpha-2": "NI", - "alpha-3": "NIC", - "country-code": "558", - "iso_3166-2": "ISO 3166-2:NI", - "region": "Americas", - "sub-region": "Latin America and the Caribbean", - "intermediate-region": "Central America", - "region-code": "019", - "sub-region-code": "419", - "intermediate-region-code": "013" - }, - { - "name": "Niger", - "alpha-2": "NE", - "alpha-3": "NER", - "country-code": "562", - "iso_3166-2": "ISO 3166-2:NE", - "region": "Africa", - "sub-region": "Sub-Saharan Africa", - "intermediate-region": "Western Africa", - "region-code": "002", - "sub-region-code": "202", - "intermediate-region-code": "011" - }, - { - "name": "Nigeria", - "alpha-2": "NG", - "alpha-3": "NGA", - "country-code": "566", - "iso_3166-2": "ISO 3166-2:NG", - "region": "Africa", - "sub-region": "Sub-Saharan Africa", - "intermediate-region": "Western Africa", - "region-code": "002", - "sub-region-code": "202", - "intermediate-region-code": "011" - }, - { - "name": "Niue", - "alpha-2": "NU", - "alpha-3": "NIU", - "country-code": "570", - "iso_3166-2": "ISO 3166-2:NU", - "region": "Oceania", - "sub-region": "Polynesia", - "intermediate-region": "", - "region-code": "009", - "sub-region-code": "061", - "intermediate-region-code": "" - }, - { - "name": "Norfolk Island", - "alpha-2": "NF", - "alpha-3": "NFK", - "country-code": "574", - "iso_3166-2": "ISO 3166-2:NF", - "region": "Oceania", - "sub-region": "Australia and New Zealand", - "intermediate-region": "", - "region-code": "009", - "sub-region-code": "053", - "intermediate-region-code": "" - }, - { - "name": "Northern Mariana Islands", - "alpha-2": "MP", - "alpha-3": "MNP", - "country-code": "580", - "iso_3166-2": "ISO 3166-2:MP", - "region": "Oceania", - "sub-region": "Micronesia", - "intermediate-region": "", - "region-code": "009", - "sub-region-code": "057", - "intermediate-region-code": "" - }, - { - "name": "Norway", - "alpha-2": "NO", - "alpha-3": "NOR", - "country-code": "578", - "iso_3166-2": "ISO 3166-2:NO", - "region": "Europe", - "sub-region": "Northern Europe", - "intermediate-region": "", - "region-code": "150", - "sub-region-code": "154", - "intermediate-region-code": "" - }, - { - "name": "Oman", - "alpha-2": "OM", - "alpha-3": "OMN", - "country-code": "512", - "iso_3166-2": "ISO 3166-2:OM", - "region": "Asia", - "sub-region": "Western Asia", - "intermediate-region": "", - "region-code": "142", - "sub-region-code": "145", - "intermediate-region-code": "" - }, - { - "name": "Pakistan", - "alpha-2": "PK", - "alpha-3": "PAK", - "country-code": "586", - "iso_3166-2": "ISO 3166-2:PK", - "region": "Asia", - "sub-region": "Southern Asia", - "intermediate-region": "", - "region-code": "142", - "sub-region-code": "034", - "intermediate-region-code": "" - }, - { - "name": "Palau", - "alpha-2": "PW", - "alpha-3": "PLW", - "country-code": "585", - "iso_3166-2": "ISO 3166-2:PW", - "region": "Oceania", - "sub-region": "Micronesia", - "intermediate-region": "", - "region-code": "009", - "sub-region-code": "057", - "intermediate-region-code": "" - }, - { - "name": "Palestine, State of", - "alpha-2": "PS", - "alpha-3": "PSE", - "country-code": "275", - "iso_3166-2": "ISO 3166-2:PS", - "region": "Asia", - "sub-region": "Western Asia", - "intermediate-region": "", - "region-code": "142", - "sub-region-code": "145", - "intermediate-region-code": "" - }, - { - "name": "Panama", - "alpha-2": "PA", - "alpha-3": "PAN", - "country-code": "591", - "iso_3166-2": "ISO 3166-2:PA", - "region": "Americas", - "sub-region": "Latin America and the Caribbean", - "intermediate-region": "Central America", - "region-code": "019", - "sub-region-code": "419", - "intermediate-region-code": "013" - }, - { - "name": "Papua New Guinea", - "alpha-2": "PG", - "alpha-3": "PNG", - "country-code": "598", - "iso_3166-2": "ISO 3166-2:PG", - "region": "Oceania", - "sub-region": "Melanesia", - "intermediate-region": "", - "region-code": "009", - "sub-region-code": "054", - "intermediate-region-code": "" - }, - { - "name": "Paraguay", - "alpha-2": "PY", - "alpha-3": "PRY", - "country-code": "600", - "iso_3166-2": "ISO 3166-2:PY", - "region": "Americas", - "sub-region": "Latin America and the Caribbean", - "intermediate-region": "South America", - "region-code": "019", - "sub-region-code": "419", - "intermediate-region-code": "005" - }, - { - "name": "Peru", - "alpha-2": "PE", - "alpha-3": "PER", - "country-code": "604", - "iso_3166-2": "ISO 3166-2:PE", - "region": "Americas", - "sub-region": "Latin America and the Caribbean", - "intermediate-region": "South America", - "region-code": "019", - "sub-region-code": "419", - "intermediate-region-code": "005" - }, - { - "name": "Philippines", - "alpha-2": "PH", - "alpha-3": "PHL", - "country-code": "608", - "iso_3166-2": "ISO 3166-2:PH", - "region": "Asia", - "sub-region": "South-eastern Asia", - "intermediate-region": "", - "region-code": "142", - "sub-region-code": "035", - "intermediate-region-code": "" - }, - { - "name": "Pitcairn", - "alpha-2": "PN", - "alpha-3": "PCN", - "country-code": "612", - "iso_3166-2": "ISO 3166-2:PN", - "region": "Oceania", - "sub-region": "Polynesia", - "intermediate-region": "", - "region-code": "009", - "sub-region-code": "061", - "intermediate-region-code": "" - }, - { - "name": "Poland", - "alpha-2": "PL", - "alpha-3": "POL", - "country-code": "616", - "iso_3166-2": "ISO 3166-2:PL", - "region": "Europe", - "sub-region": "Eastern Europe", - "intermediate-region": "", - "region-code": "150", - "sub-region-code": "151", - "intermediate-region-code": "" - }, - { - "name": "Portugal", - "alpha-2": "PT", - "alpha-3": "PRT", - "country-code": "620", - "iso_3166-2": "ISO 3166-2:PT", - "region": "Europe", - "sub-region": "Southern Europe", - "intermediate-region": "", - "region-code": "150", - "sub-region-code": "039", - "intermediate-region-code": "" - }, - { - "name": "Puerto Rico", - "alpha-2": "PR", - "alpha-3": "PRI", - "country-code": "630", - "iso_3166-2": "ISO 3166-2:PR", - "region": "Americas", - "sub-region": "Latin America and the Caribbean", - "intermediate-region": "Caribbean", - "region-code": "019", - "sub-region-code": "419", - "intermediate-region-code": "029" - }, - { - "name": "Qatar", - "alpha-2": "QA", - "alpha-3": "QAT", - "country-code": "634", - "iso_3166-2": "ISO 3166-2:QA", - "region": "Asia", - "sub-region": "Western Asia", - "intermediate-region": "", - "region-code": "142", - "sub-region-code": "145", - "intermediate-region-code": "" - }, - { - "name": "Réunion", - "alpha-2": "RE", - "alpha-3": "REU", - "country-code": "638", - "iso_3166-2": "ISO 3166-2:RE", - "region": "Africa", - "sub-region": "Sub-Saharan Africa", - "intermediate-region": "Eastern Africa", - "region-code": "002", - "sub-region-code": "202", - "intermediate-region-code": "014" - }, - { - "name": "Romania", - "alpha-2": "RO", - "alpha-3": "ROU", - "country-code": "642", - "iso_3166-2": "ISO 3166-2:RO", - "region": "Europe", - "sub-region": "Eastern Europe", - "intermediate-region": "", - "region-code": "150", - "sub-region-code": "151", - "intermediate-region-code": "" - }, - { - "name": "Russian Federation", - "alpha-2": "RU", - "alpha-3": "RUS", - "country-code": "643", - "iso_3166-2": "ISO 3166-2:RU", - "region": "Europe", - "sub-region": "Eastern Europe", - "intermediate-region": "", - "region-code": "150", - "sub-region-code": "151", - "intermediate-region-code": "" - }, - { - "name": "Rwanda", - "alpha-2": "RW", - "alpha-3": "RWA", - "country-code": "646", - "iso_3166-2": "ISO 3166-2:RW", - "region": "Africa", - "sub-region": "Sub-Saharan Africa", - "intermediate-region": "Eastern Africa", - "region-code": "002", - "sub-region-code": "202", - "intermediate-region-code": "014" - }, - { - "name": "Saint Barthélemy", - "alpha-2": "BL", - "alpha-3": "BLM", - "country-code": "652", - "iso_3166-2": "ISO 3166-2:BL", - "region": "Americas", - "sub-region": "Latin America and the Caribbean", - "intermediate-region": "Caribbean", - "region-code": "019", - "sub-region-code": "419", - "intermediate-region-code": "029" - }, - { - "name": "Saint Helena, Ascension and Tristan da Cunha", - "alpha-2": "SH", - "alpha-3": "SHN", - "country-code": "654", - "iso_3166-2": "ISO 3166-2:SH", - "region": "Africa", - "sub-region": "Sub-Saharan Africa", - "intermediate-region": "Western Africa", - "region-code": "002", - "sub-region-code": "202", - "intermediate-region-code": "011" - }, - { - "name": "Saint Kitts and Nevis", - "alpha-2": "KN", - "alpha-3": "KNA", - "country-code": "659", - "iso_3166-2": "ISO 3166-2:KN", - "region": "Americas", - "sub-region": "Latin America and the Caribbean", - "intermediate-region": "Caribbean", - "region-code": "019", - "sub-region-code": "419", - "intermediate-region-code": "029" - }, - { - "name": "Saint Lucia", - "alpha-2": "LC", - "alpha-3": "LCA", - "country-code": "662", - "iso_3166-2": "ISO 3166-2:LC", - "region": "Americas", - "sub-region": "Latin America and the Caribbean", - "intermediate-region": "Caribbean", - "region-code": "019", - "sub-region-code": "419", - "intermediate-region-code": "029" - }, - { - "name": "Saint Martin (French part)", - "alpha-2": "MF", - "alpha-3": "MAF", - "country-code": "663", - "iso_3166-2": "ISO 3166-2:MF", - "region": "Americas", - "sub-region": "Latin America and the Caribbean", - "intermediate-region": "Caribbean", - "region-code": "019", - "sub-region-code": "419", - "intermediate-region-code": "029" - }, - { - "name": "Saint Pierre and Miquelon", - "alpha-2": "PM", - "alpha-3": "SPM", - "country-code": "666", - "iso_3166-2": "ISO 3166-2:PM", - "region": "Americas", - "sub-region": "Northern America", - "intermediate-region": "", - "region-code": "019", - "sub-region-code": "021", - "intermediate-region-code": "" - }, - { - "name": "Saint Vincent and the Grenadines", - "alpha-2": "VC", - "alpha-3": "VCT", - "country-code": "670", - "iso_3166-2": "ISO 3166-2:VC", - "region": "Americas", - "sub-region": "Latin America and the Caribbean", - "intermediate-region": "Caribbean", - "region-code": "019", - "sub-region-code": "419", - "intermediate-region-code": "029" - }, - { - "name": "Samoa", - "alpha-2": "WS", - "alpha-3": "WSM", - "country-code": "882", - "iso_3166-2": "ISO 3166-2:WS", - "region": "Oceania", - "sub-region": "Polynesia", - "intermediate-region": "", - "region-code": "009", - "sub-region-code": "061", - "intermediate-region-code": "" - }, - { - "name": "San Marino", - "alpha-2": "SM", - "alpha-3": "SMR", - "country-code": "674", - "iso_3166-2": "ISO 3166-2:SM", - "region": "Europe", - "sub-region": "Southern Europe", - "intermediate-region": "", - "region-code": "150", - "sub-region-code": "039", - "intermediate-region-code": "" - }, - { - "name": "Sao Tome and Principe", - "alpha-2": "ST", - "alpha-3": "STP", - "country-code": "678", - "iso_3166-2": "ISO 3166-2:ST", - "region": "Africa", - "sub-region": "Sub-Saharan Africa", - "intermediate-region": "Middle Africa", - "region-code": "002", - "sub-region-code": "202", - "intermediate-region-code": "017" - }, - { - "name": "Saudi Arabia", - "alpha-2": "SA", - "alpha-3": "SAU", - "country-code": "682", - "iso_3166-2": "ISO 3166-2:SA", - "region": "Asia", - "sub-region": "Western Asia", - "intermediate-region": "", - "region-code": "142", - "sub-region-code": "145", - "intermediate-region-code": "" - }, - { - "name": "Senegal", - "alpha-2": "SN", - "alpha-3": "SEN", - "country-code": "686", - "iso_3166-2": "ISO 3166-2:SN", - "region": "Africa", - "sub-region": "Sub-Saharan Africa", - "intermediate-region": "Western Africa", - "region-code": "002", - "sub-region-code": "202", - "intermediate-region-code": "011" - }, - { - "name": "Serbia", - "alpha-2": "RS", - "alpha-3": "SRB", - "country-code": "688", - "iso_3166-2": "ISO 3166-2:RS", - "region": "Europe", - "sub-region": "Southern Europe", - "intermediate-region": "", - "region-code": "150", - "sub-region-code": "039", - "intermediate-region-code": "" - }, - { - "name": "Seychelles", - "alpha-2": "SC", - "alpha-3": "SYC", - "country-code": "690", - "iso_3166-2": "ISO 3166-2:SC", - "region": "Africa", - "sub-region": "Sub-Saharan Africa", - "intermediate-region": "Eastern Africa", - "region-code": "002", - "sub-region-code": "202", - "intermediate-region-code": "014" - }, - { - "name": "Sierra Leone", - "alpha-2": "SL", - "alpha-3": "SLE", - "country-code": "694", - "iso_3166-2": "ISO 3166-2:SL", - "region": "Africa", - "sub-region": "Sub-Saharan Africa", - "intermediate-region": "Western Africa", - "region-code": "002", - "sub-region-code": "202", - "intermediate-region-code": "011" - }, - { - "name": "Singapore", - "alpha-2": "SG", - "alpha-3": "SGP", - "country-code": "702", - "iso_3166-2": "ISO 3166-2:SG", - "region": "Asia", - "sub-region": "South-eastern Asia", - "intermediate-region": "", - "region-code": "142", - "sub-region-code": "035", - "intermediate-region-code": "" - }, - { - "name": "Sint Maarten (Dutch part)", - "alpha-2": "SX", - "alpha-3": "SXM", - "country-code": "534", - "iso_3166-2": "ISO 3166-2:SX", - "region": "Americas", - "sub-region": "Latin America and the Caribbean", - "intermediate-region": "Caribbean", - "region-code": "019", - "sub-region-code": "419", - "intermediate-region-code": "029" - }, - { - "name": "Slovakia", - "alpha-2": "SK", - "alpha-3": "SVK", - "country-code": "703", - "iso_3166-2": "ISO 3166-2:SK", - "region": "Europe", - "sub-region": "Eastern Europe", - "intermediate-region": "", - "region-code": "150", - "sub-region-code": "151", - "intermediate-region-code": "" - }, - { - "name": "Slovenia", - "alpha-2": "SI", - "alpha-3": "SVN", - "country-code": "705", - "iso_3166-2": "ISO 3166-2:SI", - "region": "Europe", - "sub-region": "Southern Europe", - "intermediate-region": "", - "region-code": "150", - "sub-region-code": "039", - "intermediate-region-code": "" - }, - { - "name": "Solomon Islands", - "alpha-2": "SB", - "alpha-3": "SLB", - "country-code": "090", - "iso_3166-2": "ISO 3166-2:SB", - "region": "Oceania", - "sub-region": "Melanesia", - "intermediate-region": "", - "region-code": "009", - "sub-region-code": "054", - "intermediate-region-code": "" - }, - { - "name": "Somalia", - "alpha-2": "SO", - "alpha-3": "SOM", - "country-code": "706", - "iso_3166-2": "ISO 3166-2:SO", - "region": "Africa", - "sub-region": "Sub-Saharan Africa", - "intermediate-region": "Eastern Africa", - "region-code": "002", - "sub-region-code": "202", - "intermediate-region-code": "014" - }, - { - "name": "South Africa", - "alpha-2": "ZA", - "alpha-3": "ZAF", - "country-code": "710", - "iso_3166-2": "ISO 3166-2:ZA", - "region": "Africa", - "sub-region": "Sub-Saharan Africa", - "intermediate-region": "Southern Africa", - "region-code": "002", - "sub-region-code": "202", - "intermediate-region-code": "018" - }, - { - "name": "South Georgia and the South Sandwich Islands", - "alpha-2": "GS", - "alpha-3": "SGS", - "country-code": "239", - "iso_3166-2": "ISO 3166-2:GS", - "region": "Americas", - "sub-region": "Latin America and the Caribbean", - "intermediate-region": "South America", - "region-code": "019", - "sub-region-code": "419", - "intermediate-region-code": "005" - }, - { - "name": "South Sudan", - "alpha-2": "SS", - "alpha-3": "SSD", - "country-code": "728", - "iso_3166-2": "ISO 3166-2:SS", - "region": "Africa", - "sub-region": "Sub-Saharan Africa", - "intermediate-region": "Eastern Africa", - "region-code": "002", - "sub-region-code": "202", - "intermediate-region-code": "014" - }, - { - "name": "Spain", - "alpha-2": "ES", - "alpha-3": "ESP", - "country-code": "724", - "iso_3166-2": "ISO 3166-2:ES", - "region": "Europe", - "sub-region": "Southern Europe", - "intermediate-region": "", - "region-code": "150", - "sub-region-code": "039", - "intermediate-region-code": "" - }, - { - "name": "Sri Lanka", - "alpha-2": "LK", - "alpha-3": "LKA", - "country-code": "144", - "iso_3166-2": "ISO 3166-2:LK", - "region": "Asia", - "sub-region": "Southern Asia", - "intermediate-region": "", - "region-code": "142", - "sub-region-code": "034", - "intermediate-region-code": "" - }, - { - "name": "Sudan", - "alpha-2": "SD", - "alpha-3": "SDN", - "country-code": "729", - "iso_3166-2": "ISO 3166-2:SD", - "region": "Africa", - "sub-region": "Northern Africa", - "intermediate-region": "", - "region-code": "002", - "sub-region-code": "015", - "intermediate-region-code": "" - }, - { - "name": "Suriname", - "alpha-2": "SR", - "alpha-3": "SUR", - "country-code": "740", - "iso_3166-2": "ISO 3166-2:SR", - "region": "Americas", - "sub-region": "Latin America and the Caribbean", - "intermediate-region": "South America", - "region-code": "019", - "sub-region-code": "419", - "intermediate-region-code": "005" - }, - { - "name": "Svalbard and Jan Mayen", - "alpha-2": "SJ", - "alpha-3": "SJM", - "country-code": "744", - "iso_3166-2": "ISO 3166-2:SJ", - "region": "Europe", - "sub-region": "Northern Europe", - "intermediate-region": "", - "region-code": "150", - "sub-region-code": "154", - "intermediate-region-code": "" - }, - { - "name": "Sweden", - "alpha-2": "SE", - "alpha-3": "SWE", - "country-code": "752", - "iso_3166-2": "ISO 3166-2:SE", - "region": "Europe", - "sub-region": "Northern Europe", - "intermediate-region": "", - "region-code": "150", - "sub-region-code": "154", - "intermediate-region-code": "" - }, - { - "name": "Switzerland", - "alpha-2": "CH", - "alpha-3": "CHE", - "country-code": "756", - "iso_3166-2": "ISO 3166-2:CH", - "region": "Europe", - "sub-region": "Western Europe", - "intermediate-region": "", - "region-code": "150", - "sub-region-code": "155", - "intermediate-region-code": "" - }, - { - "name": "Syrian Arab Republic", - "alpha-2": "SY", - "alpha-3": "SYR", - "country-code": "760", - "iso_3166-2": "ISO 3166-2:SY", - "region": "Asia", - "sub-region": "Western Asia", - "intermediate-region": "", - "region-code": "142", - "sub-region-code": "145", - "intermediate-region-code": "" - }, - { - "name": "Taiwan, Province of China", - "alpha-2": "TW", - "alpha-3": "TWN", - "country-code": "158", - "iso_3166-2": "ISO 3166-2:TW", - "region": "Asia", - "sub-region": "Eastern Asia", - "intermediate-region": "", - "region-code": "142", - "sub-region-code": "030", - "intermediate-region-code": "" - }, - { - "name": "Tajikistan", - "alpha-2": "TJ", - "alpha-3": "TJK", - "country-code": "762", - "iso_3166-2": "ISO 3166-2:TJ", - "region": "Asia", - "sub-region": "Central Asia", - "intermediate-region": "", - "region-code": "142", - "sub-region-code": "143", - "intermediate-region-code": "" - }, - { - "name": "Tanzania, United Republic of", - "alpha-2": "TZ", - "alpha-3": "TZA", - "country-code": "834", - "iso_3166-2": "ISO 3166-2:TZ", - "region": "Africa", - "sub-region": "Sub-Saharan Africa", - "intermediate-region": "Eastern Africa", - "region-code": "002", - "sub-region-code": "202", - "intermediate-region-code": "014" - }, - { - "name": "Thailand", - "alpha-2": "TH", - "alpha-3": "THA", - "country-code": "764", - "iso_3166-2": "ISO 3166-2:TH", - "region": "Asia", - "sub-region": "South-eastern Asia", - "intermediate-region": "", - "region-code": "142", - "sub-region-code": "035", - "intermediate-region-code": "" - }, - { - "name": "Timor-Leste", - "alpha-2": "TL", - "alpha-3": "TLS", - "country-code": "626", - "iso_3166-2": "ISO 3166-2:TL", - "region": "Asia", - "sub-region": "South-eastern Asia", - "intermediate-region": "", - "region-code": "142", - "sub-region-code": "035", - "intermediate-region-code": "" - }, - { - "name": "Togo", - "alpha-2": "TG", - "alpha-3": "TGO", - "country-code": "768", - "iso_3166-2": "ISO 3166-2:TG", - "region": "Africa", - "sub-region": "Sub-Saharan Africa", - "intermediate-region": "Western Africa", - "region-code": "002", - "sub-region-code": "202", - "intermediate-region-code": "011" - }, - { - "name": "Tokelau", - "alpha-2": "TK", - "alpha-3": "TKL", - "country-code": "772", - "iso_3166-2": "ISO 3166-2:TK", - "region": "Oceania", - "sub-region": "Polynesia", - "intermediate-region": "", - "region-code": "009", - "sub-region-code": "061", - "intermediate-region-code": "" - }, - { - "name": "Tonga", - "alpha-2": "TO", - "alpha-3": "TON", - "country-code": "776", - "iso_3166-2": "ISO 3166-2:TO", - "region": "Oceania", - "sub-region": "Polynesia", - "intermediate-region": "", - "region-code": "009", - "sub-region-code": "061", - "intermediate-region-code": "" - }, - { - "name": "Trinidad and Tobago", - "alpha-2": "TT", - "alpha-3": "TTO", - "country-code": "780", - "iso_3166-2": "ISO 3166-2:TT", - "region": "Americas", - "sub-region": "Latin America and the Caribbean", - "intermediate-region": "Caribbean", - "region-code": "019", - "sub-region-code": "419", - "intermediate-region-code": "029" - }, - { - "name": "Tunisia", - "alpha-2": "TN", - "alpha-3": "TUN", - "country-code": "788", - "iso_3166-2": "ISO 3166-2:TN", - "region": "Africa", - "sub-region": "Northern Africa", - "intermediate-region": "", - "region-code": "002", - "sub-region-code": "015", - "intermediate-region-code": "" - }, - { - "name": "Turkey", - "alpha-2": "TR", - "alpha-3": "TUR", - "country-code": "792", - "iso_3166-2": "ISO 3166-2:TR", - "region": "Asia", - "sub-region": "Western Asia", - "intermediate-region": "", - "region-code": "142", - "sub-region-code": "145", - "intermediate-region-code": "" - }, - { - "name": "Turkmenistan", - "alpha-2": "TM", - "alpha-3": "TKM", - "country-code": "795", - "iso_3166-2": "ISO 3166-2:TM", - "region": "Asia", - "sub-region": "Central Asia", - "intermediate-region": "", - "region-code": "142", - "sub-region-code": "143", - "intermediate-region-code": "" - }, - { - "name": "Turks and Caicos Islands", - "alpha-2": "TC", - "alpha-3": "TCA", - "country-code": "796", - "iso_3166-2": "ISO 3166-2:TC", - "region": "Americas", - "sub-region": "Latin America and the Caribbean", - "intermediate-region": "Caribbean", - "region-code": "019", - "sub-region-code": "419", - "intermediate-region-code": "029" - }, - { - "name": "Tuvalu", - "alpha-2": "TV", - "alpha-3": "TUV", - "country-code": "798", - "iso_3166-2": "ISO 3166-2:TV", - "region": "Oceania", - "sub-region": "Polynesia", - "intermediate-region": "", - "region-code": "009", - "sub-region-code": "061", - "intermediate-region-code": "" - }, - { - "name": "Uganda", - "alpha-2": "UG", - "alpha-3": "UGA", - "country-code": "800", - "iso_3166-2": "ISO 3166-2:UG", - "region": "Africa", - "sub-region": "Sub-Saharan Africa", - "intermediate-region": "Eastern Africa", - "region-code": "002", - "sub-region-code": "202", - "intermediate-region-code": "014" - }, - { - "name": "Ukraine", - "alpha-2": "UA", - "alpha-3": "UKR", - "country-code": "804", - "iso_3166-2": "ISO 3166-2:UA", - "region": "Europe", - "sub-region": "Eastern Europe", - "intermediate-region": "", - "region-code": "150", - "sub-region-code": "151", - "intermediate-region-code": "" - }, - { - "name": "United Arab Emirates", - "alpha-2": "AE", - "alpha-3": "ARE", - "country-code": "784", - "iso_3166-2": "ISO 3166-2:AE", - "region": "Asia", - "sub-region": "Western Asia", - "intermediate-region": "", - "region-code": "142", - "sub-region-code": "145", - "intermediate-region-code": "" - }, - { - "name": "United Kingdom of Great Britain and Northern Ireland", - "alpha-2": "GB", - "alpha-3": "GBR", - "country-code": "826", - "iso_3166-2": "ISO 3166-2:GB", - "region": "UK", - "sub-region": "Northern Europe", - "intermediate-region": "", - "region-code": "150", - "sub-region-code": "154", - "intermediate-region-code": "" - }, - { - "name": "United States of America", - "alpha-2": "US", - "alpha-3": "USA", - "country-code": "840", - "iso_3166-2": "ISO 3166-2:US", - "region": "Americas", - "sub-region": "Northern America", - "intermediate-region": "", - "region-code": "019", - "sub-region-code": "021", - "intermediate-region-code": "" - }, - { - "name": "United States Minor Outlying Islands", - "alpha-2": "UM", - "alpha-3": "UMI", - "country-code": "581", - "iso_3166-2": "ISO 3166-2:UM", - "region": "Oceania", - "sub-region": "Micronesia", - "intermediate-region": "", - "region-code": "009", - "sub-region-code": "057", - "intermediate-region-code": "" - }, - { - "name": "Uruguay", - "alpha-2": "UY", - "alpha-3": "URY", - "country-code": "858", - "iso_3166-2": "ISO 3166-2:UY", - "region": "Americas", - "sub-region": "Latin America and the Caribbean", - "intermediate-region": "South America", - "region-code": "019", - "sub-region-code": "419", - "intermediate-region-code": "005" - }, - { - "name": "Uzbekistan", - "alpha-2": "UZ", - "alpha-3": "UZB", - "country-code": "860", - "iso_3166-2": "ISO 3166-2:UZ", - "region": "Asia", - "sub-region": "Central Asia", - "intermediate-region": "", - "region-code": "142", - "sub-region-code": "143", - "intermediate-region-code": "" - }, - { - "name": "Vanuatu", - "alpha-2": "VU", - "alpha-3": "VUT", - "country-code": "548", - "iso_3166-2": "ISO 3166-2:VU", - "region": "Oceania", - "sub-region": "Melanesia", - "intermediate-region": "", - "region-code": "009", - "sub-region-code": "054", - "intermediate-region-code": "" - }, - { - "name": "Venezuela (Bolivarian Republic of)", - "alpha-2": "VE", - "alpha-3": "VEN", - "country-code": "862", - "iso_3166-2": "ISO 3166-2:VE", - "region": "Americas", - "sub-region": "Latin America and the Caribbean", - "intermediate-region": "South America", - "region-code": "019", - "sub-region-code": "419", - "intermediate-region-code": "005" - }, - { - "name": "Viet Nam", - "alpha-2": "VN", - "alpha-3": "VNM", - "country-code": "704", - "iso_3166-2": "ISO 3166-2:VN", - "region": "Asia", - "sub-region": "South-eastern Asia", - "intermediate-region": "", - "region-code": "142", - "sub-region-code": "035", - "intermediate-region-code": "" - }, - { - "name": "Virgin Islands (British)", - "alpha-2": "VG", - "alpha-3": "VGB", - "country-code": "092", - "iso_3166-2": "ISO 3166-2:VG", - "region": "Americas", - "sub-region": "Latin America and the Caribbean", - "intermediate-region": "Caribbean", - "region-code": "019", - "sub-region-code": "419", - "intermediate-region-code": "029" - }, - { - "name": "Virgin Islands (U.S.)", - "alpha-2": "VI", - "alpha-3": "VIR", - "country-code": "850", - "iso_3166-2": "ISO 3166-2:VI", - "region": "Americas", - "sub-region": "Latin America and the Caribbean", - "intermediate-region": "Caribbean", - "region-code": "019", - "sub-region-code": "419", - "intermediate-region-code": "029" - }, - { - "name": "Wallis and Futuna", - "alpha-2": "WF", - "alpha-3": "WLF", - "country-code": "876", - "iso_3166-2": "ISO 3166-2:WF", - "region": "Oceania", - "sub-region": "Polynesia", - "intermediate-region": "", - "region-code": "009", - "sub-region-code": "061", - "intermediate-region-code": "" - }, - { - "name": "Western Sahara", - "alpha-2": "EH", - "alpha-3": "ESH", - "country-code": "732", - "iso_3166-2": "ISO 3166-2:EH", - "region": "Africa", - "sub-region": "Northern Africa", - "intermediate-region": "", - "region-code": "002", - "sub-region-code": "015", - "intermediate-region-code": "" - }, - { - "name": "Yemen", - "alpha-2": "YE", - "alpha-3": "YEM", - "country-code": "887", - "iso_3166-2": "ISO 3166-2:YE", - "region": "Asia", - "sub-region": "Western Asia", - "intermediate-region": "", - "region-code": "142", - "sub-region-code": "145", - "intermediate-region-code": "" - }, - { - "name": "Zambia", - "alpha-2": "ZM", - "alpha-3": "ZMB", - "country-code": "894", - "iso_3166-2": "ISO 3166-2:ZM", - "region": "Africa", - "sub-region": "Sub-Saharan Africa", - "intermediate-region": "Eastern Africa", - "region-code": "002", - "sub-region-code": "202", - "intermediate-region-code": "014" - }, - { - "name": "Zimbabwe", - "alpha-2": "ZW", - "alpha-3": "ZWE", - "country-code": "716", - "iso_3166-2": "ISO 3166-2:ZW", - "region": "Africa", - "sub-region": "Sub-Saharan Africa", - "intermediate-region": "Eastern Africa", - "region-code": "002", - "sub-region-code": "202", - "intermediate-region-code": "014" - } -] From 558b0a554633a38123d3c904fcf4a640847b6208 Mon Sep 17 00:00:00 2001 From: lytrankieio123 Date: Wed, 20 Oct 2021 13:36:22 +0700 Subject: [PATCH 15/27] :sparkles: feat: add shipping method UI :%s --- .../ShippingInfoForm/ShippingInfoForm.tsx | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/components/modules/checkout/CheckoutInfo/components/ShippingInfoForm/ShippingInfoForm.tsx b/src/components/modules/checkout/CheckoutInfo/components/ShippingInfoForm/ShippingInfoForm.tsx index 012882277..459b69324 100644 --- a/src/components/modules/checkout/CheckoutInfo/components/ShippingInfoForm/ShippingInfoForm.tsx +++ b/src/components/modules/checkout/CheckoutInfo/components/ShippingInfoForm/ShippingInfoForm.tsx @@ -3,6 +3,7 @@ import React, { useEffect, useRef } from 'react' import { ButtonCommon, InputFiledInForm, SelectFieldInForm } from 'src/components/common' import { useMessage } from 'src/components/contexts' import { useAvailableCountries, useSetOrderShippingAddress } from 'src/components/hooks/order' +import { Shipping } from 'src/components/icons' import { LANGUAGE } from 'src/utils/language.utils' import { CustomInputCommon } from 'src/utils/type.utils' import * as Yup from 'yup' @@ -175,6 +176,21 @@ const ShippingInfoForm = ({ onConfirm, id, activeStep }: ShippingInfoFormProps) onEnter={isValid ? submitForm : undefined} />
+
+
+
+ +
+
+ Standard Delivery Method +
+
+
+
+ Free +
+
+
From d5eade99b45f2da99fd01986517a544db18b4731 Mon Sep 17 00:00:00 2001 From: lytrankieio123 Date: Wed, 20 Oct 2021 16:03:30 +0700 Subject: [PATCH 16/27] :recycle: enhan: flow input customer info at checkout :%s --- src/components/common/ModalConfirm/ModalConfirm.tsx | 6 +++--- .../modules/checkout/CheckoutInfo/CheckoutInfo.tsx | 3 +-- .../components/CustomerInfoForm/CustomerInfoForm.tsx | 11 +++++++++-- .../ModalConfirmLogin/ModalConfirmLogin.module.scss | 5 +++++ .../ModalConfirmLogin/ModalConfirmLogin.tsx | 3 ++- 5 files changed, 20 insertions(+), 8 deletions(-) diff --git a/src/components/common/ModalConfirm/ModalConfirm.tsx b/src/components/common/ModalConfirm/ModalConfirm.tsx index adc855168..ac6ccc00c 100644 --- a/src/components/common/ModalConfirm/ModalConfirm.tsx +++ b/src/components/common/ModalConfirm/ModalConfirm.tsx @@ -5,7 +5,7 @@ import s from './ModalConfirm.module.scss' interface ModalConfirmProps extends ModalCommonProps { okText?: String cancelText?: String - loading?:boolean + loading?: boolean onOk?: () => void onCancel?: () => void } @@ -26,9 +26,9 @@ const ModalConfirm = ({ {children}
- {cancelText} + {cancelText}
- {okText} + {okText}
) diff --git a/src/components/modules/checkout/CheckoutInfo/CheckoutInfo.tsx b/src/components/modules/checkout/CheckoutInfo/CheckoutInfo.tsx index fdab2da6f..a35a13df2 100644 --- a/src/components/modules/checkout/CheckoutInfo/CheckoutInfo.tsx +++ b/src/components/modules/checkout/CheckoutInfo/CheckoutInfo.tsx @@ -79,8 +79,7 @@ const CheckoutInfo = ({ onViewCart }: CheckoutInfoProps) => { const getNote = (id: CheckoutStep) => { switch (id) { case CheckoutStep.CustomerInfo: - // console.log("order info; ", order?.customer) - if (order?.customer) { + if (order?.customer?.emailAddress) { return `${order?.customer?.firstName} ${order?.customer?.lastName}, ${order?.customer?.emailAddress}` } else if (customer) { return `${customer.firstName} ${customer.lastName}, ${customer.emailAddress}` diff --git a/src/components/modules/checkout/CheckoutInfo/components/CustomerInfoForm/CustomerInfoForm.tsx b/src/components/modules/checkout/CheckoutInfo/components/CustomerInfoForm/CustomerInfoForm.tsx index fb18b79e3..65177f043 100644 --- a/src/components/modules/checkout/CheckoutInfo/components/CustomerInfoForm/CustomerInfoForm.tsx +++ b/src/components/modules/checkout/CheckoutInfo/components/CustomerInfoForm/CustomerInfoForm.tsx @@ -28,6 +28,7 @@ const displayingErrorMessagesSchema = Yup.object().shape({ const CustomerInfoForm = ({ id, onConfirm, activeStep }: Props) => { const firstNameRef = useRef(null) + const emailRef = useRef(null) const { setCustomerForOrder, loading } = useSetCustomerForOrder() const { showMessageError } = useMessage() const [emailAddress, setEmailAddress] = useState('') @@ -58,11 +59,16 @@ const CustomerInfoForm = ({ id, onConfirm, activeStep }: Props) => { } } } - const handleCloseModalConfirmLogin = () => { + const handleOpenModalLogin = () => { closeModalConfirmLogin() openModalAuthen() } + const handleCloseModalConfirmLogin = () => { + closeModalConfirmLogin() + emailRef.current?.focus() + } + return (
@@ -110,6 +116,7 @@ const CustomerInfoForm = ({ id, onConfirm, activeStep }: Props) => { ? errors.emailAddress.toString() : '' } + ref={emailRef} isShowIconSuccess={touched.emailAddress && !errors.emailAddress} onEnter={isValid ? submitForm : undefined} @@ -125,7 +132,7 @@ const CustomerInfoForm = ({ id, onConfirm, activeStep }: Props) => { )}
- +
) diff --git a/src/components/modules/checkout/CheckoutInfo/components/CustomerInfoForm/ModalConfirmLogin/ModalConfirmLogin.module.scss b/src/components/modules/checkout/CheckoutInfo/components/CustomerInfoForm/ModalConfirmLogin/ModalConfirmLogin.module.scss index e69de29bb..ca70f06a7 100644 --- a/src/components/modules/checkout/CheckoutInfo/components/CustomerInfoForm/ModalConfirmLogin/ModalConfirmLogin.module.scss +++ b/src/components/modules/checkout/CheckoutInfo/components/CustomerInfoForm/ModalConfirmLogin/ModalConfirmLogin.module.scss @@ -0,0 +1,5 @@ + +.modalConfirmLogin { + min-width: 40rem; + text-align: center; +} \ No newline at end of file diff --git a/src/components/modules/checkout/CheckoutInfo/components/CustomerInfoForm/ModalConfirmLogin/ModalConfirmLogin.tsx b/src/components/modules/checkout/CheckoutInfo/components/CustomerInfoForm/ModalConfirmLogin/ModalConfirmLogin.tsx index c7723906b..bf2445eb9 100644 --- a/src/components/modules/checkout/CheckoutInfo/components/CustomerInfoForm/ModalConfirmLogin/ModalConfirmLogin.tsx +++ b/src/components/modules/checkout/CheckoutInfo/components/CustomerInfoForm/ModalConfirmLogin/ModalConfirmLogin.tsx @@ -1,6 +1,7 @@ import React from 'react'; import { ModalConfirm } from 'src/components/common'; import { LANGUAGE } from 'src/utils/language.utils'; +import s from './ModalConfirmLogin.module.scss' interface Props { visible: boolean @@ -19,7 +20,7 @@ const ModalConfirmLogin = ({ visible, closeModal, handleOk, email }: Props) => { okText={LANGUAGE.BUTTON_LABEL.SIGNIN} cancelText="Change email address" > -
+

Account already exists for email {email}

Please signin to continue or use another email

From f2c23c4527d2fcbd12f2044f2a44b70ac4084525 Mon Sep 17 00:00:00 2001 From: lytrankieio123 Date: Wed, 20 Oct 2021 16:03:41 +0700 Subject: [PATCH 17/27] update active order after login --- src/components/hooks/auth/useLogin.tsx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/components/hooks/auth/useLogin.tsx b/src/components/hooks/auth/useLogin.tsx index d38390004..c0125f73a 100644 --- a/src/components/hooks/auth/useLogin.tsx +++ b/src/components/hooks/auth/useLogin.tsx @@ -6,6 +6,7 @@ import { LoginMutation } from '@framework/schema' import { LOCAL_STORAGE_KEY } from 'src/utils/constanst.utils' import { errorMapping } from 'src/utils/errrorMapping' import { loginMutation } from '@framework/utils/mutations/log-in-mutation' +import { useGetActiveOrder } from '../cart' interface LoginInput { username: string @@ -16,6 +17,7 @@ const useLogin = () => { const [loading, setLoading] = useState(false) const [error, setError] = useState(null) const { mutate } = useActiveCustomer() + const { mutate: mutateOrder } = useGetActiveOrder() const login = (options: LoginInput, fCallBack: (isSuccess: boolean, message?: string) => void @@ -34,6 +36,7 @@ const useLogin = () => { if (authToken != null) { localStorage.setItem(LOCAL_STORAGE_KEY.TOKEN, authToken) mutate() + mutateOrder() } fCallBack(true) }) From bbbf4f7adcd145ece2f0095fae22edb1fcea1f51 Mon Sep 17 00:00:00 2001 From: lytrankieio123 Date: Wed, 20 Oct 2021 16:40:42 +0700 Subject: [PATCH 18/27] :art: styles: checkout page :%s --- .../LayoutCheckout/LayoutCheckout.module.scss | 3 +++ .../CheckoutBill/CheckoutBill.module.scss | 7 ++++- .../checkout/CheckoutBill/CheckoutBill.tsx | 27 +++++++++++++++---- .../checkout/CheckoutInfo/CheckoutInfo.tsx | 19 ++++++------- .../CustomerInfoForm/CustomerInfoForm.tsx | 2 ++ .../CheckoutPage/CheckoutPage.module.scss | 1 + 6 files changed, 42 insertions(+), 17 deletions(-) diff --git a/src/components/common/LayoutCheckout/LayoutCheckout.module.scss b/src/components/common/LayoutCheckout/LayoutCheckout.module.scss index 8a32d20a7..82e8d8a0e 100644 --- a/src/components/common/LayoutCheckout/LayoutCheckout.module.scss +++ b/src/components/common/LayoutCheckout/LayoutCheckout.module.scss @@ -4,8 +4,11 @@ flex-direction: column; min-height: 100vh; > main { + display: flex; flex: 1; position: relative; + max-width: min(100%, 1536px); + margin: auto; } .footer { @apply spacing-horizontal; diff --git a/src/components/modules/checkout/CheckoutBill/CheckoutBill.module.scss b/src/components/modules/checkout/CheckoutBill/CheckoutBill.module.scss index 8cd564917..713a984a5 100644 --- a/src/components/modules/checkout/CheckoutBill/CheckoutBill.module.scss +++ b/src/components/modules/checkout/CheckoutBill/CheckoutBill.module.scss @@ -1,6 +1,7 @@ .warpper { padding: 3.2rem; min-width: 100%; + min-height: 100%; @screen lg { max-width: 56.3rem; @apply flex justify-between flex-col; @@ -14,10 +15,14 @@ display: block; } } + .empty { + @apply flex flex-col justify-center items-center; + } .list { - min-height: 52.8rem; + // min-height: 52.8rem; } .bot { + margin-top: auto; .price { margin-top: 3.2rem; .line { diff --git a/src/components/modules/checkout/CheckoutBill/CheckoutBill.tsx b/src/components/modules/checkout/CheckoutBill/CheckoutBill.tsx index 433df66d1..7b4196279 100644 --- a/src/components/modules/checkout/CheckoutBill/CheckoutBill.tsx +++ b/src/components/modules/checkout/CheckoutBill/CheckoutBill.tsx @@ -1,8 +1,11 @@ import { Cart } from '@commerce/types/cart' import React from 'react' -import { CardItemCheckout } from '../../../common' +import { ROUTE } from 'src/utils/constanst.utils' +import { LANGUAGE } from 'src/utils/language.utils' +import { ButtonCommon, CardItemCheckout, EmptyCommon } from '../../../common' import s from './CheckoutBill.module.scss' import FormPromotionCode from './FormPromotionCode/FormPromotionCode' +import Link from 'next/link' interface CheckoutBillProps { // data: CardItemCheckoutProps[] @@ -14,8 +17,18 @@ const CheckoutBill = ({ data }: CheckoutBillProps) => { return (
- Your cart ({data?.totalQuantity}) + Your cart ({data?.totalQuantity || 0})
+ { + !data?.totalQuantity && + }
{data?.lineItems?.map((item) => { return @@ -26,11 +39,15 @@ const CheckoutBill = ({ data }: CheckoutBillProps) => {
Discount {(data?.discounts?.length || 0) > 0 && `(${data?.discounts?.map(item => item.description).join(",")})`} -
{data?.totalDiscount} {data?.currency?.code}
+
+ {data?.totalDiscount ? `${data?.totalDiscount} ${data?.currency?.code}` : "0"} +
Subtotal -
{data?.subtotalPrice} {data?.currency?.code}
+
+ {data?.subtotalPrice ? `${data?.subtotalPrice} ${data?.currency?.code}` : "0"} +
Shipping @@ -38,7 +55,7 @@ const CheckoutBill = ({ data }: CheckoutBillProps) => {
Estimated Total -
{data?.totalPrice} {data?.currency?.code}
+
{data?.totalPrice ? `${data?.totalPrice} ${data?.currency?.code}` : "0"}
diff --git a/src/components/modules/checkout/CheckoutInfo/CheckoutInfo.tsx b/src/components/modules/checkout/CheckoutInfo/CheckoutInfo.tsx index a35a13df2..8b3267238 100644 --- a/src/components/modules/checkout/CheckoutInfo/CheckoutInfo.tsx +++ b/src/components/modules/checkout/CheckoutInfo/CheckoutInfo.tsx @@ -116,22 +116,19 @@ const CheckoutInfo = ({ onViewCart }: CheckoutInfoProps) => { ] // TODO: remove - const { addProduct } = useAddProductToCart() - - const createOrder = () => { - addProduct({ variantId: "92", quantity: 2 }, handleAddToCartCallback) - } - const handleAddToCartCallback = (isSuccess: boolean, message?: string) => { - // console.log("after create order: ", isSuccess, message) - } + // const { addProduct } = useAddProductToCart() + // const createOrder = () => { + // addProduct({ variantId: "92", quantity: 2 }, handleAddToCartCallback) + // } + // const handleAddToCartCallback = (isSuccess: boolean, message?: string) => { + // // console.log("after create order: ", isSuccess, message) + // } return (
{/* TODO: remove */} - test create order - test get activeStep order - TOTAL: {order?.totalPrice} + {/* test create order */}
diff --git a/src/components/modules/checkout/CheckoutInfo/components/CustomerInfoForm/CustomerInfoForm.tsx b/src/components/modules/checkout/CheckoutInfo/components/CustomerInfoForm/CustomerInfoForm.tsx index 65177f043..254983dda 100644 --- a/src/components/modules/checkout/CheckoutInfo/components/CustomerInfoForm/CustomerInfoForm.tsx +++ b/src/components/modules/checkout/CheckoutInfo/components/CustomerInfoForm/CustomerInfoForm.tsx @@ -54,6 +54,8 @@ const CustomerInfoForm = ({ id, onConfirm, activeStep }: Props) => { if (error?.errorCode === ErrorCode.EmailAddressConflictError) { // show modal common openModalConfirmLogin() + } else if (error?.errorCode === ErrorCode.NoActiveOrderError) { + showMessageError("Your cart is empty! Please add items to the cart!") } else { showMessageError(error?.message) } diff --git a/src/components/modules/checkout/CheckoutPage/CheckoutPage.module.scss b/src/components/modules/checkout/CheckoutPage/CheckoutPage.module.scss index a1e68d863..bd519be01 100644 --- a/src/components/modules/checkout/CheckoutPage/CheckoutPage.module.scss +++ b/src/components/modules/checkout/CheckoutPage/CheckoutPage.module.scss @@ -1,6 +1,7 @@ @import "../../../../styles/utilities"; .warrper{ @apply flex w-full; + min-height: 100%; .right { display: none; @screen lg { From f959ac8ea2852d167a510b61aa008c411e5bbcf5 Mon Sep 17 00:00:00 2001 From: lytrankieio123 Date: Wed, 20 Oct 2021 16:47:48 +0700 Subject: [PATCH 19/27] :bug: bug: change active step in checkout :%s --- .../modules/checkout/CheckoutInfo/CheckoutInfo.tsx | 12 ++++-------- src/utils/funtion.utils.ts | 2 +- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/src/components/modules/checkout/CheckoutInfo/CheckoutInfo.tsx b/src/components/modules/checkout/CheckoutInfo/CheckoutInfo.tsx index 8b3267238..2a0046caf 100644 --- a/src/components/modules/checkout/CheckoutInfo/CheckoutInfo.tsx +++ b/src/components/modules/checkout/CheckoutInfo/CheckoutInfo.tsx @@ -1,9 +1,8 @@ import React, { useEffect, useState } from 'react' -import { ButtonCommon, Logo } from 'src/components/common' +import { Logo } from 'src/components/common' import CheckoutCollapse from 'src/components/common/CheckoutCollapse/CheckoutCollapse' import { useActiveCustomer } from 'src/components/hooks/auth' -import { useAddProductToCart, useGetActiveOrder } from 'src/components/hooks/cart' -import { removeItem } from 'src/utils/funtion.utils' +import { useGetActiveOrder } from 'src/components/hooks/cart' import s from './CheckoutInfo.module.scss' import CustomerInfoForm from './components/CustomerInfoForm/CustomerInfoForm' import PaymentInfoForm from './components/PaymentInfoForm/PaymentInfoForm' @@ -46,21 +45,17 @@ const CheckoutInfo = ({ onViewCart }: CheckoutInfoProps) => { const onEdit = (id: CheckoutStep) => { setActiveStep(id) - setDoneSteps(removeItem(doneSteps, id)) } const updateActiveStep = (step: CheckoutStep) => { if (doneSteps.length > 0) { for (let i = step + 1; i < Object.keys(CheckoutStep).length; i++) { if (!doneSteps.includes(i)) { - // console.log("here: ", doneSteps, i) setActiveStep(i) return } } } else { - // console.log("here 2: ", doneSteps, step) - setActiveStep(step + 1) } } @@ -129,7 +124,7 @@ const CheckoutInfo = ({ onViewCart }: CheckoutInfoProps) => {
{/* TODO: remove */} {/* test create order */} - + doneSteps = {JSON.stringify(doneSteps)}
View cart
@@ -143,6 +138,7 @@ const CheckoutInfo = ({ onViewCart }: CheckoutInfoProps) => { title={item.title} onEditClick={onEdit} isEdit={doneSteps.includes(item.id)} + onClose={onConfirm} note={note} disableEdit={customer && item.id === CheckoutStep.CustomerInfo} > diff --git a/src/utils/funtion.utils.ts b/src/utils/funtion.utils.ts index 94521e072..1989bfd30 100644 --- a/src/utils/funtion.utils.ts +++ b/src/utils/funtion.utils.ts @@ -1,6 +1,6 @@ import { Collection } from '@commerce/types/collection'; import { Facet } from "@commerce/types/facet"; -import { Product, ProductCard, ProductOption, ProductOptionValues } from "@commerce/types/product"; +import { Product, ProductCard, ProductOptionValues } from "@commerce/types/product"; import { FacetValue, SearchResultSortParameter } from './../../framework/vendure/schema.d'; import { CODE_FACET_DISCOUNT, CODE_FACET_FEATURED, CODE_FACET_FEATURED_VARIANT, FACET, PRODUCT_SORT_OPTION_VALUE } from "./constanst.utils"; import { PromiseWithKey, SelectedOptions, SortOrder } from "./types.utils"; From aba0e43b931683e4ad4a6f584099780a3bcb373d Mon Sep 17 00:00:00 2001 From: lytrankieio123 Date: Wed, 20 Oct 2021 17:46:03 +0700 Subject: [PATCH 20/27] :art: styles: shipping method :%s --- framework/vendure/schema.d.ts | 11 ++- .../set-order-shipping-method-mutation.ts | 35 +++++++ src/components/hooks/order/index.ts | 2 +- .../hooks/order/useSetOrderShippingMethod.tsx | 41 ++++++++ .../checkout/CheckoutInfo/CheckoutInfo.tsx | 5 +- .../ChekoutNotePolicy/ChekoutNotePolicy.tsx | 2 +- .../ShippingInfoForm.module.scss | 19 +--- .../ShippingInfoForm/ShippingInfoForm.tsx | 26 ++--- .../ShippingMethod/ShippingMethod.module.scss | 39 ++++++++ .../ShippingMethod/ShippingMethod.tsx | 94 +++++++++++++++++++ .../ShippingMethodItem.module.scss | 19 ++++ .../ShippingMethodItem/ShippingMethodItem.tsx | 29 ++++++ .../checkout/CheckoutPage/CheckoutPage.tsx | 2 +- 13 files changed, 280 insertions(+), 44 deletions(-) create mode 100644 framework/vendure/utils/mutations/set-order-shipping-method-mutation.ts create mode 100644 src/components/hooks/order/useSetOrderShippingMethod.tsx create mode 100644 src/components/modules/checkout/CheckoutInfo/components/ShippingMethod/ShippingMethod.module.scss create mode 100644 src/components/modules/checkout/CheckoutInfo/components/ShippingMethod/ShippingMethod.tsx create mode 100644 src/components/modules/checkout/CheckoutInfo/components/ShippingMethod/ShippingMethodItem/ShippingMethodItem.module.scss create mode 100644 src/components/modules/checkout/CheckoutInfo/components/ShippingMethod/ShippingMethodItem/ShippingMethodItem.tsx diff --git a/framework/vendure/schema.d.ts b/framework/vendure/schema.d.ts index e2a6ab600..6a2778597 100644 --- a/framework/vendure/schema.d.ts +++ b/framework/vendure/schema.d.ts @@ -365,8 +365,17 @@ export type Address = Node & { customFields?: Maybe } +export type SetShippingMethodMutationVariables = Exact<{ + id: Scalars['ID']; +}>; - +export type SetShippingMethodMutation = { + setOrderShippingMethod: + | TestOrderFragmentFragment + | Pick + | Pick + | Pick; +}; export type Asset = Node & { __typename?: 'Asset' diff --git a/framework/vendure/utils/mutations/set-order-shipping-method-mutation.ts b/framework/vendure/utils/mutations/set-order-shipping-method-mutation.ts new file mode 100644 index 000000000..e43331908 --- /dev/null +++ b/framework/vendure/utils/mutations/set-order-shipping-method-mutation.ts @@ -0,0 +1,35 @@ +export const setShippingMethodMutation = /* GraphQL */ ` +mutation SetShippingMethod($id: ID!) { + setOrderShippingMethod(shippingMethodId: $id) { + ...Cart + ...ErrorResult + __typename + } +} + +fragment Cart on Order { + id + code + state + active + shippingLines { + priceWithTax + shippingMethod { + id + code + name + description + __typename + } + __typename + } + + __typename +} + +fragment ErrorResult on ErrorResult { + errorCode + message + __typename +} +` diff --git a/src/components/hooks/order/index.ts b/src/components/hooks/order/index.ts index 7ec92f670..b7d785c92 100644 --- a/src/components/hooks/order/index.ts +++ b/src/components/hooks/order/index.ts @@ -2,4 +2,4 @@ export { default as useSetCustomerForOrder } from './useSetCustomerForOrder' export { default as useSetOrderShippingAddress } from './useSetOrderShippingAddress' export { default as useApplyCouponCode } from './useApplyCouponCode' export { default as useAvailableCountries } from './useAvailableCountries' - +export { default as useSetOrderShippingMethod } from './useSetOrderShippingMethod' diff --git a/src/components/hooks/order/useSetOrderShippingMethod.tsx b/src/components/hooks/order/useSetOrderShippingMethod.tsx new file mode 100644 index 000000000..bed63f72b --- /dev/null +++ b/src/components/hooks/order/useSetOrderShippingMethod.tsx @@ -0,0 +1,41 @@ +import { SetShippingMethodMutation } from '@framework/schema' +import { setShippingMethodMutation } from '@framework/utils/mutations/set-order-shipping-method-mutation' +import { useState } from 'react' +import { CommonError } from 'src/domains/interfaces/CommonError' +import rawFetcher from 'src/utils/rawFetcher' +import { useGetActiveOrder } from '../cart' + + +const useSetOrderShippingMethod = () => { + const [loading, setLoading] = useState(false) + const [error, setError] = useState(null) + const { mutate } = useGetActiveOrder() + + const setOrderShippingMethod = (id: string, + fCallBack: (isSuccess: boolean, message?: string) => void + ) => { + setError(null) + setLoading(true) + rawFetcher({ + query: setShippingMethodMutation, + variables: { id }, + }) + .then(({ data }) => { + if (data.setOrderShippingMethod.__typename === 'Order') { + fCallBack(true) + mutate() + } else { + fCallBack(false, data.setOrderShippingMethod.message) + } + }) + .catch((error) => { + setError(error) + fCallBack(false, error.message) + }) + .finally(() => setLoading(false)) + } + + return { loading, setOrderShippingMethod, error } +} + +export default useSetOrderShippingMethod diff --git a/src/components/modules/checkout/CheckoutInfo/CheckoutInfo.tsx b/src/components/modules/checkout/CheckoutInfo/CheckoutInfo.tsx index 2a0046caf..68a8e71b5 100644 --- a/src/components/modules/checkout/CheckoutInfo/CheckoutInfo.tsx +++ b/src/components/modules/checkout/CheckoutInfo/CheckoutInfo.tsx @@ -9,6 +9,7 @@ import PaymentInfoForm from './components/PaymentInfoForm/PaymentInfoForm' import ShippingInfoForm from './components/ShippingInfoForm/ShippingInfoForm' interface CheckoutInfoProps { onViewCart: () => void + currency?: string } enum CheckoutStep { @@ -17,7 +18,7 @@ enum CheckoutStep { PaymentInfo = 3, } -const CheckoutInfo = ({ onViewCart }: CheckoutInfoProps) => { +const CheckoutInfo = ({ onViewCart, currency = "" }: CheckoutInfoProps) => { const [activeStep, setActiveStep] = useState(1) const [doneSteps, setDoneSteps] = useState([]) const { order } = useGetActiveOrder() @@ -101,7 +102,7 @@ const CheckoutInfo = ({ onViewCart }: CheckoutInfoProps) => { { id: CheckoutStep.ShippingInfo, title: 'Shipping Information', - form: , + form: , }, { id: CheckoutStep.PaymentInfo, diff --git a/src/components/modules/checkout/CheckoutInfo/components/ChekoutNotePolicy/ChekoutNotePolicy.tsx b/src/components/modules/checkout/CheckoutInfo/components/ChekoutNotePolicy/ChekoutNotePolicy.tsx index 9c988ae03..c5cf41955 100644 --- a/src/components/modules/checkout/CheckoutInfo/components/ChekoutNotePolicy/ChekoutNotePolicy.tsx +++ b/src/components/modules/checkout/CheckoutInfo/components/ChekoutNotePolicy/ChekoutNotePolicy.tsx @@ -18,7 +18,7 @@ const ChekoutNotePolicy = memo(() => { { - privacy policy + privacy policy } diff --git a/src/components/modules/checkout/CheckoutInfo/components/ShippingInfoForm/ShippingInfoForm.module.scss b/src/components/modules/checkout/CheckoutInfo/components/ShippingInfoForm/ShippingInfoForm.module.scss index aa177fc88..5eaefab13 100644 --- a/src/components/modules/checkout/CheckoutInfo/components/ShippingInfoForm/ShippingInfoForm.module.scss +++ b/src/components/modules/checkout/CheckoutInfo/components/ShippingInfoForm/ShippingInfoForm.module.scss @@ -24,22 +24,5 @@ width: 50%; } } - .method{ - width: 100%; - height: 5.6rem; - padding: 1.6rem; - border-radius: 0.8rem; - @apply flex justify-between items-center border border-solid border-line bg-gray; - .left{ - @apply flex; - .name{ - margin-left: 1.6rem; - color: var(--text-active); - } - } - .price{ - font-weight: bold; - color: var(--text-active); - } - } + } \ No newline at end of file diff --git a/src/components/modules/checkout/CheckoutInfo/components/ShippingInfoForm/ShippingInfoForm.tsx b/src/components/modules/checkout/CheckoutInfo/components/ShippingInfoForm/ShippingInfoForm.tsx index 459b69324..fb62c0f24 100644 --- a/src/components/modules/checkout/CheckoutInfo/components/ShippingInfoForm/ShippingInfoForm.tsx +++ b/src/components/modules/checkout/CheckoutInfo/components/ShippingInfoForm/ShippingInfoForm.tsx @@ -3,17 +3,19 @@ import React, { useEffect, useRef } from 'react' import { ButtonCommon, InputFiledInForm, SelectFieldInForm } from 'src/components/common' import { useMessage } from 'src/components/contexts' import { useAvailableCountries, useSetOrderShippingAddress } from 'src/components/hooks/order' -import { Shipping } from 'src/components/icons' import { LANGUAGE } from 'src/utils/language.utils' import { CustomInputCommon } from 'src/utils/type.utils' import * as Yup from 'yup' import ChekoutNotePolicy from '../ChekoutNotePolicy/ChekoutNotePolicy' +import ShippingMethod from '../ShippingMethod/ShippingMethod' import s from './ShippingInfoForm.module.scss' interface ShippingInfoFormProps { id: number activeStep: number onConfirm: (id: number) => void + currency: string + } @@ -31,6 +33,7 @@ const displayingErrorMessagesSchema = Yup.object().shape({ const DEFAULT_COUNTRY_CODE = 'MY' const DEFAULT_PROVINCE = 'Sabah' +// TODO: update data const provinceOptions = [ { name: 'Hồ Chí Minh', @@ -46,7 +49,7 @@ const provinceOptions = [ }, ] -const ShippingInfoForm = ({ onConfirm, id, activeStep }: ShippingInfoFormProps) => { +const ShippingInfoForm = ({ onConfirm, id, activeStep , currency}: ShippingInfoFormProps) => { const addressRef = useRef(null) const { setOrderShippingAddress, loading } = useSetOrderShippingAddress() const { showMessageError } = useMessage() @@ -59,10 +62,7 @@ const ShippingInfoForm = ({ onConfirm, id, activeStep }: ShippingInfoFormProps) }, [activeStep]) const handleSubmit = (values: any) => { - console.log("values: ", values) setOrderShippingAddress(values, onSubmitCalBack) - - // onConfirm && onConfirm(id) } const onSubmitCalBack = (isSuccess: boolean, msg?: string) => { @@ -176,21 +176,7 @@ const ShippingInfoForm = ({ onConfirm, id, activeStep }: ShippingInfoFormProps) onEnter={isValid ? submitForm : undefined} />
-
-
-
- -
-
- Standard Delivery Method -
-
-
-
- Free -
-
-
+
diff --git a/src/components/modules/checkout/CheckoutInfo/components/ShippingMethod/ShippingMethod.module.scss b/src/components/modules/checkout/CheckoutInfo/components/ShippingMethod/ShippingMethod.module.scss new file mode 100644 index 000000000..d078368e4 --- /dev/null +++ b/src/components/modules/checkout/CheckoutInfo/components/ShippingMethod/ShippingMethod.module.scss @@ -0,0 +1,39 @@ +.shippingMethod { + @apply relative; + .method { + @apply w-full flex justify-between items-center border border-solid border-line bg-gray cursor-pointer; + height: 5.6rem; + padding: 1.6rem; + border-radius: 0.8rem; + .left { + @apply flex; + .name { + margin-left: 1.6rem; + color: var(--text-active); + } + } + .price { + font-weight: bold; + color: var(--text-active); + } + } + + .options { + @apply absolute transition-all duration-200 overflow-hidden; + transform: translateX(-100%); + opacity: 0; + margin-top: 0.8rem; + top: 6rem; + left: 0; + width: 100%; + background: var(--white); + border: 1px solid var(--border-line); + border-radius: 0.8rem; + &.show { + z-index: 10; + opacity: 1; + transform: none; + position: initial; + } + } +} diff --git a/src/components/modules/checkout/CheckoutInfo/components/ShippingMethod/ShippingMethod.tsx b/src/components/modules/checkout/CheckoutInfo/components/ShippingMethod/ShippingMethod.tsx new file mode 100644 index 000000000..c6b1ca845 --- /dev/null +++ b/src/components/modules/checkout/CheckoutInfo/components/ShippingMethod/ShippingMethod.tsx @@ -0,0 +1,94 @@ +import { ShippingMethodQuote } from '@framework/schema' +import classNames from 'classnames' +import React, { memo, useState } from 'react' +import { useMessage } from 'src/components/contexts' +import { useSetOrderShippingMethod } from 'src/components/hooks/order' +import { Shipping } from 'src/components/icons' +import s from './ShippingMethod.module.scss' +import ShippingMethodItem from './ShippingMethodItem/ShippingMethodItem' + +const MOCKUP_DATA = [ + { + "id": "1", + "name": "Standard Shipping", + "description": "", + "price": 0, + "priceWithTax": 0, + "code": "standard-shipping" + }, + { + "id": "2", + "name": "Express Shipping", + "description": "", + "price": 1000, + "priceWithTax": 1000, + "code": "express-shipping" + } +] +interface Props { + currency: string +} + +const ShippingMethod = memo(({ currency }: Props) => { + const { setOrderShippingMethod } = useSetOrderShippingMethod() + const [selectedValue, setSelectedValue] = useState(MOCKUP_DATA[0]) + const { showMessageError } = useMessage() + const [isShowOptions, setIsShowOptions] = useState(false) + + const onChange = (id: string) => { + const newValue = MOCKUP_DATA.find(item => item.id === id) + if (newValue) { + setSelectedValue(newValue) + if (newValue?.id) { + setOrderShippingMethod(newValue?.id, onSubmitCalBack) + } + } + setIsShowOptions(false) + } + + const onSubmitCalBack = (isSuccess: boolean, msg?: string) => { + if (!isSuccess) { + showMessageError(msg) + } + } + + const onCollapseOptions = () => { + setIsShowOptions(!isShowOptions) + } + + + return ( +
+
+
+
+ +
+
+ {selectedValue.name} +
+
+
+
+ {selectedValue.price ? `${selectedValue.price / 100} ${currency}` : "Free"} +
+
+
+
+
    + {MOCKUP_DATA.map(item => )} +
+
+
+ ) +}) + +ShippingMethod.displayName = 'ShippingMethod' +export default ShippingMethod diff --git a/src/components/modules/checkout/CheckoutInfo/components/ShippingMethod/ShippingMethodItem/ShippingMethodItem.module.scss b/src/components/modules/checkout/CheckoutInfo/components/ShippingMethod/ShippingMethodItem/ShippingMethodItem.module.scss new file mode 100644 index 000000000..4aa06484c --- /dev/null +++ b/src/components/modules/checkout/CheckoutInfo/components/ShippingMethod/ShippingMethodItem/ShippingMethodItem.module.scss @@ -0,0 +1,19 @@ +.shippingMethodItem { + @apply flex justify-between items-center cursor-pointer transition-all duration-200; + width: 100%; + padding: 1.6rem; + &:hover { + @apply bg-gray; + } + .left { + @apply flex; + .name { + margin-left: 1.6rem; + color: var(--text-active); + } + } + .price { + font-weight: bold; + color: var(--text-active); + } +} diff --git a/src/components/modules/checkout/CheckoutInfo/components/ShippingMethod/ShippingMethodItem/ShippingMethodItem.tsx b/src/components/modules/checkout/CheckoutInfo/components/ShippingMethod/ShippingMethodItem/ShippingMethodItem.tsx new file mode 100644 index 000000000..43685e3db --- /dev/null +++ b/src/components/modules/checkout/CheckoutInfo/components/ShippingMethod/ShippingMethodItem/ShippingMethodItem.tsx @@ -0,0 +1,29 @@ +import React, { memo } from 'react' +import s from './ShippingMethodItem.module.scss' + +interface Props { + id: string + name: string + price: number + currency: string + onSelect: (id: string) => void +} + +const ShippingMethodItem = memo(({ id, name, price, currency, onSelect }: Props) => { + const handleSelect = () => { + onSelect(id) + } + return ( +
  • +
    + {name} +
    +
    + {price ? `${price / 100} ${currency}` : "Free"} +
    +
  • + ) +}) + +ShippingMethodItem.displayName = 'ShippingMethodItem' +export default ShippingMethodItem diff --git a/src/components/modules/checkout/CheckoutPage/CheckoutPage.tsx b/src/components/modules/checkout/CheckoutPage/CheckoutPage.tsx index fcec64922..d467ed2c4 100644 --- a/src/components/modules/checkout/CheckoutPage/CheckoutPage.tsx +++ b/src/components/modules/checkout/CheckoutPage/CheckoutPage.tsx @@ -24,7 +24,7 @@ const CheckoutPage = ({ }: CheckoutPageProps) => { return (
    -
    +
    From bcdbea405924634b5e411a3dc57a109161bd52d8 Mon Sep 17 00:00:00 2001 From: lytrankieio123 Date: Thu, 21 Oct 2021 09:47:45 +0700 Subject: [PATCH 21/27] :sparkles: feat: useGetActiveOrderForCheckout :%s --- framework/commerce/types/cart.ts | 33 ++++- framework/vendure/schema.d.ts | 5 + .../vendure/utils/fragments/cart-fragment.ts | 17 --- framework/vendure/utils/normalize.ts | 45 ++++++- .../active-order-for-checkout-query.ts | 116 ++++++++++++++++++ .../hooks/cart/useRemoveProductInCart.tsx | 7 +- .../order/useGetActiveOrderForCheckout.tsx | 13 ++ .../checkout/CheckoutBill/CheckoutBill.tsx | 6 +- .../checkout/CheckoutInfo/CheckoutInfo.tsx | 26 ++-- .../ShippingInfoForm/ShippingInfoForm.tsx | 6 +- .../ShippingMethod/ShippingMethod.tsx | 11 +- .../checkout/CheckoutPage/CheckoutPage.tsx | 4 +- 12 files changed, 241 insertions(+), 48 deletions(-) create mode 100644 framework/vendure/utils/queries/active-order-for-checkout-query.ts create mode 100644 src/components/hooks/order/useGetActiveOrderForCheckout.tsx diff --git a/framework/commerce/types/cart.ts b/framework/commerce/types/cart.ts index 15e24d32e..e0d56b3bb 100644 --- a/framework/commerce/types/cart.ts +++ b/framework/commerce/types/cart.ts @@ -1,5 +1,5 @@ -import { Shipping } from 'src/components/icons'; -import type { Discount, Measurement, Image } from './common' +import { ShippingMethod } from '@framework/schema'; +import type { Discount, Image, Measurement } from './common'; export type SelectedOption = { // The option's id. @@ -60,6 +60,31 @@ export type ProductVariant = { // Shopping cart, a.k.a Checkout export type Cart = { + id: string + // ID of the customer to which the cart belongs. + customerId?: string + // The email assigned to this cart + email?: string + // The date and time when the cart was created. + createdAt: string + // The currency used for this cart + currency: { code: string } + // Specifies if taxes are included in the line items. + taxesIncluded: boolean + lineItems: LineItem[] + // The sum of all the prices of all the items in the cart. + // Duties, taxes, shipping and discounts excluded. + lineItemsSubtotalPrice: number + // Price of the cart before duties, shipping and taxes. + subtotalPrice: number + // The sum of all the prices of all the items in the cart. + // Duties, taxes and discounts included. + totalPrice: number + // Discounts that have been applied on the cart. + discounts?: Discount[] +} + +export type CartCheckout = { id: string // ID of the customer to which the cart belongs. customerId?: string @@ -97,6 +122,10 @@ export type Cart = { // Discounts that have been applied on the cart. discounts?: Discount[] totalDiscount: number + shippingLine: { + priceWithTax: number + shippingMethod: ShippingMethod + } } /** diff --git a/framework/vendure/schema.d.ts b/framework/vendure/schema.d.ts index 6a2778597..cc3c0bc9c 100644 --- a/framework/vendure/schema.d.ts +++ b/framework/vendure/schema.d.ts @@ -3066,6 +3066,11 @@ export type CartFragment = { __typename?: 'Order' } & Pick< { __typename?: 'Discount' } & Pick > customer?: Maybe<{ __typename?: 'Customer' } & Pick> + shippingLines: Array< + Pick & { + shippingMethod: Pick; + } + > lines: Array< { __typename?: 'OrderLine' } & Pick< OrderLine, diff --git a/framework/vendure/utils/fragments/cart-fragment.ts b/framework/vendure/utils/fragments/cart-fragment.ts index f0a34b8e3..54ac08912 100644 --- a/framework/vendure/utils/fragments/cart-fragment.ts +++ b/framework/vendure/utils/fragments/cart-fragment.ts @@ -9,25 +9,8 @@ export const cartFragment = /* GraphQL */ ` total totalWithTax currencyCode - discounts { - type - description - amount - amountWithTax - } customer { id - firstName - lastName - emailAddress - } - shippingAddress { - streetLine1 - city - province - postalCode - countryCode - phoneNumber } lines { id diff --git a/framework/vendure/utils/normalize.ts b/framework/vendure/utils/normalize.ts index d81fbc2f1..e318d7535 100644 --- a/framework/vendure/utils/normalize.ts +++ b/framework/vendure/utils/normalize.ts @@ -1,6 +1,6 @@ -import { Cart } from '@commerce/types/cart' -import { ProductCard, Product } from '@commerce/types/product' -import { CartFragment, SearchResultFragment, Favorite } from '../schema' +import { Cart, CartCheckout } from '@commerce/types/cart' +import { Product, ProductCard } from '@commerce/types/product' +import { CartFragment, Favorite, SearchResultFragment, ShippingMethod } from '../schema' export function normalizeSearchResult(item: SearchResultFragment): ProductCard { return { @@ -36,6 +36,41 @@ export function normalizeFavoriteProductResult(item: Favorite) { export function normalizeCart(order: CartFragment): Cart { + return { + id: order.id.toString(), + createdAt: order.createdAt, + taxesIncluded: true, + lineItemsSubtotalPrice: order.subTotalWithTax / 100, + currency: { code: order.currencyCode }, + subtotalPrice: order.subTotalWithTax / 100, + totalPrice: order.totalWithTax / 100, + customerId: order.customer?.id, + lineItems: order.lines?.map((l) => ({ + id: l.id, + name: l.productVariant.name, + quantity: l.quantity, + slug: l.productVariant.product.slug, + variantId: l.productVariant.id, + productId: l.productVariant.productId, + images: [{ url: l.featuredAsset?.preview + '?preset=thumb' || '' }], + discounts: l.discounts.map((d) => ({ value: d.amount / 100 })), + path: '', + variant: { + id: l.productVariant.id, + name: l.productVariant.name, + sku: l.productVariant.sku, + price: l.discountedUnitPriceWithTax / 100, + listPrice: l.unitPriceWithTax / 100, + image: { + url: l.featuredAsset?.preview + '?preset=thumb' || '', + }, + requiresShipping: true, + }, + })), + } +} + +export function normalizeCartForCheckout(order: CartFragment): CartCheckout { return { id: order.id.toString(), createdAt: order.createdAt, @@ -59,6 +94,10 @@ export function normalizeCart(order: CartFragment): Cart { countryCode: order.shippingAddress?.countryCode || '', phoneNumber: order.shippingAddress?.phoneNumber || '', }, + shippingLine: { + priceWithTax: order.shippingLines[0].priceWithTax, + shippingMethod: order.shippingLines[0].shippingMethod as ShippingMethod + }, totalDiscount: order.discounts?.reduce((total, item) => total + item.amountWithTax, 0) / 100 || 0, discounts: order.discounts.map(item => { return { value: item.amountWithTax, description: item.description } diff --git a/framework/vendure/utils/queries/active-order-for-checkout-query.ts b/framework/vendure/utils/queries/active-order-for-checkout-query.ts new file mode 100644 index 000000000..7acedc492 --- /dev/null +++ b/framework/vendure/utils/queries/active-order-for-checkout-query.ts @@ -0,0 +1,116 @@ +export const getActiveOrderForCheckoutQuery = /* GraphQL */ ` +query getActiveOrderForCheckout { + activeOrder { + ...Cart + shippingAddress { + ...OrderAddress + __typename + } + __typename + } +} + +fragment Cart on Order { + id + code + state + active + customer { + id + firstName + lastName + emailAddress + } + lines { + id + featuredAsset { + ...Asset + __typename + } + unitPrice + unitPriceWithTax + quantity + linePriceWithTax + discountedLinePriceWithTax + unitPriceWithTax + discountedUnitPriceWithTax + productVariant { + id + name + price + priceWithTax + stockLevel + productId + product { + slug + } + __typename + } + discounts { + amount + amountWithTax + description + adjustmentSource + type + __typename + } + __typename + } + totalQuantity + subTotal + subTotalWithTax + total + totalWithTax + shipping + shippingWithTax + currencyCode + shippingLines { + priceWithTax + shippingMethod { + id + code + name + description + __typename + } + __typename + } + discounts { + amount + amountWithTax + description + adjustmentSource + type + __typename + } + __typename +} + +fragment Asset on Asset { + id + width + height + name + preview + focalPoint { + x + y + __typename + } + __typename +} + +fragment OrderAddress on OrderAddress { + fullName + company + streetLine1 + streetLine2 + city + province + postalCode + country + phoneNumber + __typename +} +` + diff --git a/src/components/hooks/cart/useRemoveProductInCart.tsx b/src/components/hooks/cart/useRemoveProductInCart.tsx index d66fd4306..27fcb8de2 100644 --- a/src/components/hooks/cart/useRemoveProductInCart.tsx +++ b/src/components/hooks/cart/useRemoveProductInCart.tsx @@ -1,11 +1,10 @@ +import { RemoveOrderLineMutation, RemoveOrderLineMutationVariables } from '@framework/schema' +import { removeOrderLineMutation } from '@framework/utils/mutations/remove-order-line-mutation' import { useState } from 'react' import { CommonError } from 'src/domains/interfaces/CommonError' -import rawFetcher from 'src/utils/rawFetcher' -import { AdjustOrderLineMutationVariables,AdjustOrderLineMutation, RemoveOrderLineMutation, RemoveOrderLineMutationVariables } from '@framework/schema' import { errorMapping } from 'src/utils/errrorMapping' +import rawFetcher from 'src/utils/rawFetcher' import { useGetActiveOrder } from '.' -import { adjustOrderLineMutation } from '@framework/utils/mutations/adjust-order-line-mutation' -import { removeOrderLineMutation } from '@framework/utils/mutations/remove-order-line-mutation' const useRemoveProductInCart = () => { const [loading, setLoading] = useState(false) diff --git a/src/components/hooks/order/useGetActiveOrderForCheckout.tsx b/src/components/hooks/order/useGetActiveOrderForCheckout.tsx new file mode 100644 index 000000000..fb69f82be --- /dev/null +++ b/src/components/hooks/order/useGetActiveOrderForCheckout.tsx @@ -0,0 +1,13 @@ +import { ActiveOrderQuery } from '@framework/schema' +import { normalizeCartForCheckout } from '@framework/utils/normalize' +import { getActiveOrderForCheckoutQuery } from '@framework/utils/queries/active-order-for-checkout-query' +import gglFetcher from 'src/utils/gglFetcher' +import useSWR from 'swr' + + +const useGetActiveOrderForCheckout = () => { + const { data, ...rest } = useSWR([getActiveOrderForCheckoutQuery], gglFetcher) + return { order: data?.activeOrder ? normalizeCartForCheckout(data!.activeOrder) : null, ...rest } +} + +export default useGetActiveOrderForCheckout diff --git a/src/components/modules/checkout/CheckoutBill/CheckoutBill.tsx b/src/components/modules/checkout/CheckoutBill/CheckoutBill.tsx index 7b4196279..59a0eee20 100644 --- a/src/components/modules/checkout/CheckoutBill/CheckoutBill.tsx +++ b/src/components/modules/checkout/CheckoutBill/CheckoutBill.tsx @@ -1,15 +1,15 @@ -import { Cart } from '@commerce/types/cart' +import { CartCheckout } from '@commerce/types/cart' +import Link from 'next/link' import React from 'react' import { ROUTE } from 'src/utils/constanst.utils' import { LANGUAGE } from 'src/utils/language.utils' import { ButtonCommon, CardItemCheckout, EmptyCommon } from '../../../common' import s from './CheckoutBill.module.scss' import FormPromotionCode from './FormPromotionCode/FormPromotionCode' -import Link from 'next/link' interface CheckoutBillProps { // data: CardItemCheckoutProps[] - data: Cart | null + data: CartCheckout | null } const CheckoutBill = ({ data }: CheckoutBillProps) => { diff --git a/src/components/modules/checkout/CheckoutInfo/CheckoutInfo.tsx b/src/components/modules/checkout/CheckoutInfo/CheckoutInfo.tsx index 68a8e71b5..47f5ed7a0 100644 --- a/src/components/modules/checkout/CheckoutInfo/CheckoutInfo.tsx +++ b/src/components/modules/checkout/CheckoutInfo/CheckoutInfo.tsx @@ -2,27 +2,30 @@ import React, { useEffect, useState } from 'react' import { Logo } from 'src/components/common' import CheckoutCollapse from 'src/components/common/CheckoutCollapse/CheckoutCollapse' import { useActiveCustomer } from 'src/components/hooks/auth' -import { useGetActiveOrder } from 'src/components/hooks/cart' +import useGetActiveOrderForCheckout from 'src/components/hooks/order/useGetActiveOrderForCheckout' import s from './CheckoutInfo.module.scss' import CustomerInfoForm from './components/CustomerInfoForm/CustomerInfoForm' import PaymentInfoForm from './components/PaymentInfoForm/PaymentInfoForm' import ShippingInfoForm from './components/ShippingInfoForm/ShippingInfoForm' +import ShippingMethod from './components/ShippingMethod/ShippingMethod' interface CheckoutInfoProps { onViewCart: () => void currency?: string } -enum CheckoutStep { +export enum CheckoutStep { CustomerInfo = 1, - ShippingInfo = 2, - PaymentInfo = 3, + ShippingAddressInfo = 2, + ShippingMethodInfo = 3, + PaymentInfo = 4, } const CheckoutInfo = ({ onViewCart, currency = "" }: CheckoutInfoProps) => { const [activeStep, setActiveStep] = useState(1) const [doneSteps, setDoneSteps] = useState([]) - const { order } = useGetActiveOrder() + const { order } = useGetActiveOrderForCheckout() const { customer } = useActiveCustomer() + console.log("active order checkout: ", order) useEffect(() => { if (customer) { @@ -82,7 +85,7 @@ const CheckoutInfo = ({ onViewCart, currency = "" }: CheckoutInfoProps) => { } else { return '' } - case CheckoutStep.ShippingInfo: + case CheckoutStep.ShippingAddressInfo: if (order?.shippingAddress) { const { streetLine1, city, province, postalCode, countryCode, phoneNumber } = order.shippingAddress return `${streetLine1}, ${city}, ${province}, ${postalCode}, ${countryCode}, ${phoneNumber}` @@ -100,9 +103,14 @@ const CheckoutInfo = ({ onViewCart, currency = "" }: CheckoutInfoProps) => { form: , }, { - id: CheckoutStep.ShippingInfo, - title: 'Shipping Information', - form: , + id: CheckoutStep.ShippingAddressInfo, + title: 'Shipping Address Information', + form: , + }, + { + id: CheckoutStep.ShippingMethodInfo, + title: 'Shipping Method Information', + form: , }, { id: CheckoutStep.PaymentInfo, diff --git a/src/components/modules/checkout/CheckoutInfo/components/ShippingInfoForm/ShippingInfoForm.tsx b/src/components/modules/checkout/CheckoutInfo/components/ShippingInfoForm/ShippingInfoForm.tsx index fb62c0f24..63cde8385 100644 --- a/src/components/modules/checkout/CheckoutInfo/components/ShippingInfoForm/ShippingInfoForm.tsx +++ b/src/components/modules/checkout/CheckoutInfo/components/ShippingInfoForm/ShippingInfoForm.tsx @@ -7,15 +7,12 @@ import { LANGUAGE } from 'src/utils/language.utils' import { CustomInputCommon } from 'src/utils/type.utils' import * as Yup from 'yup' import ChekoutNotePolicy from '../ChekoutNotePolicy/ChekoutNotePolicy' -import ShippingMethod from '../ShippingMethod/ShippingMethod' import s from './ShippingInfoForm.module.scss' interface ShippingInfoFormProps { id: number activeStep: number onConfirm: (id: number) => void - currency: string - } @@ -49,7 +46,7 @@ const provinceOptions = [ }, ] -const ShippingInfoForm = ({ onConfirm, id, activeStep , currency}: ShippingInfoFormProps) => { +const ShippingInfoForm = ({ onConfirm, id, activeStep }: ShippingInfoFormProps) => { const addressRef = useRef(null) const { setOrderShippingAddress, loading } = useSetOrderShippingAddress() const { showMessageError } = useMessage() @@ -176,7 +173,6 @@ const ShippingInfoForm = ({ onConfirm, id, activeStep , currency}: ShippingInfoF onEnter={isValid ? submitForm : undefined} />
    -
    diff --git a/src/components/modules/checkout/CheckoutInfo/components/ShippingMethod/ShippingMethod.tsx b/src/components/modules/checkout/CheckoutInfo/components/ShippingMethod/ShippingMethod.tsx index c6b1ca845..911650646 100644 --- a/src/components/modules/checkout/CheckoutInfo/components/ShippingMethod/ShippingMethod.tsx +++ b/src/components/modules/checkout/CheckoutInfo/components/ShippingMethod/ShippingMethod.tsx @@ -4,6 +4,7 @@ import React, { memo, useState } from 'react' import { useMessage } from 'src/components/contexts' import { useSetOrderShippingMethod } from 'src/components/hooks/order' import { Shipping } from 'src/components/icons' +import { CheckoutStep } from '../../CheckoutInfo' import s from './ShippingMethod.module.scss' import ShippingMethodItem from './ShippingMethodItem/ShippingMethodItem' @@ -27,13 +28,15 @@ const MOCKUP_DATA = [ ] interface Props { currency: string + onConfirm: (id: number) => void + } -const ShippingMethod = memo(({ currency }: Props) => { +const ShippingMethod = memo(({ currency, onConfirm }: Props) => { const { setOrderShippingMethod } = useSetOrderShippingMethod() const [selectedValue, setSelectedValue] = useState(MOCKUP_DATA[0]) const { showMessageError } = useMessage() - const [isShowOptions, setIsShowOptions] = useState(false) + const [isShowOptions, setIsShowOptions] = useState(true) const onChange = (id: string) => { const newValue = MOCKUP_DATA.find(item => item.id === id) @@ -47,7 +50,9 @@ const ShippingMethod = memo(({ currency }: Props) => { } const onSubmitCalBack = (isSuccess: boolean, msg?: string) => { - if (!isSuccess) { + if (isSuccess) { + onConfirm(CheckoutStep.ShippingMethodInfo) + } else { showMessageError(msg) } } diff --git a/src/components/modules/checkout/CheckoutPage/CheckoutPage.tsx b/src/components/modules/checkout/CheckoutPage/CheckoutPage.tsx index d467ed2c4..5c53d0898 100644 --- a/src/components/modules/checkout/CheckoutPage/CheckoutPage.tsx +++ b/src/components/modules/checkout/CheckoutPage/CheckoutPage.tsx @@ -2,7 +2,7 @@ import classNames from 'classnames' import React, { useState } from 'react' import { MessageCommon } from 'src/components/common' import { useMessage } from 'src/components/contexts' -import { useGetActiveOrder } from 'src/components/hooks/cart' +import useGetActiveOrderForCheckout from 'src/components/hooks/order/useGetActiveOrderForCheckout' import IconHide from 'src/components/icons/IconHide' import { CHECKOUT_BILL_DATA } from 'src/utils/demo-data' import { CheckoutBill, CheckoutInfo } from '..' @@ -13,7 +13,7 @@ interface CheckoutPageProps { const CheckoutPage = ({ }: CheckoutPageProps) => { const { messages, removeMessage } = useMessage() const [isShow, setIsShow] = useState(false) - const { order } = useGetActiveOrder() + const { order } = useGetActiveOrderForCheckout() const onClose = () => { setIsShow(false) From 357e700e32fed599b43dd74ad2cc4d75cc6fc674 Mon Sep 17 00:00:00 2001 From: lytrankieio123 Date: Thu, 21 Oct 2021 09:52:15 +0700 Subject: [PATCH 22/27] :recycle: enhan: normalize shippingLine price :%s --- framework/vendure/utils/normalize.ts | 2 +- .../modules/checkout/CheckoutBill/CheckoutBill.tsx | 9 ++++----- .../modules/checkout/CheckoutInfo/CheckoutInfo.tsx | 13 ------------- 3 files changed, 5 insertions(+), 19 deletions(-) diff --git a/framework/vendure/utils/normalize.ts b/framework/vendure/utils/normalize.ts index e318d7535..7a2ab0d24 100644 --- a/framework/vendure/utils/normalize.ts +++ b/framework/vendure/utils/normalize.ts @@ -95,7 +95,7 @@ export function normalizeCartForCheckout(order: CartFragment): CartCheckout { phoneNumber: order.shippingAddress?.phoneNumber || '', }, shippingLine: { - priceWithTax: order.shippingLines[0].priceWithTax, + priceWithTax: order.shippingLines[0].priceWithTax / 100, shippingMethod: order.shippingLines[0].shippingMethod as ShippingMethod }, totalDiscount: order.discounts?.reduce((total, item) => total + item.amountWithTax, 0) / 100 || 0, diff --git a/src/components/modules/checkout/CheckoutBill/CheckoutBill.tsx b/src/components/modules/checkout/CheckoutBill/CheckoutBill.tsx index 59a0eee20..dc4462704 100644 --- a/src/components/modules/checkout/CheckoutBill/CheckoutBill.tsx +++ b/src/components/modules/checkout/CheckoutBill/CheckoutBill.tsx @@ -13,7 +13,6 @@ interface CheckoutBillProps { } const CheckoutBill = ({ data }: CheckoutBillProps) => { - // console.log("data here***: ", data) return (
    @@ -40,22 +39,22 @@ const CheckoutBill = ({ data }: CheckoutBillProps) => {
    Discount {(data?.discounts?.length || 0) > 0 && `(${data?.discounts?.map(item => item.description).join(",")})`}
    - {data?.totalDiscount ? `${data?.totalDiscount} ${data?.currency?.code}` : "0"} + {data?.totalDiscount || 0} {data?.currency?.code}
    Subtotal
    - {data?.subtotalPrice ? `${data?.subtotalPrice} ${data?.currency?.code}` : "0"} + {data?.subtotalPrice || 0} {data?.currency?.code}
    Shipping -
    Free
    +
    {data?.shippingLine.priceWithTax || 0} {data?.currency?.code}
    Estimated Total -
    {data?.totalPrice ? `${data?.totalPrice} ${data?.currency?.code}` : "0"}
    +
    {data?.totalPrice || 0} {data?.currency?.code}
    diff --git a/src/components/modules/checkout/CheckoutInfo/CheckoutInfo.tsx b/src/components/modules/checkout/CheckoutInfo/CheckoutInfo.tsx index 47f5ed7a0..f48a41920 100644 --- a/src/components/modules/checkout/CheckoutInfo/CheckoutInfo.tsx +++ b/src/components/modules/checkout/CheckoutInfo/CheckoutInfo.tsx @@ -119,21 +119,8 @@ const CheckoutInfo = ({ onViewCart, currency = "" }: CheckoutInfoProps) => { }, ] - // TODO: remove - // const { addProduct } = useAddProductToCart() - - // const createOrder = () => { - // addProduct({ variantId: "92", quantity: 2 }, handleAddToCartCallback) - // } - // const handleAddToCartCallback = (isSuccess: boolean, message?: string) => { - // // console.log("after create order: ", isSuccess, message) - // } - return (
    - {/* TODO: remove */} - {/* test create order */} - doneSteps = {JSON.stringify(doneSteps)}
    View cart
    From 6b397fc1531d6f028f49527f3532512f139ed854 Mon Sep 17 00:00:00 2001 From: lytrankieio123 Date: Thu, 21 Oct 2021 10:20:17 +0700 Subject: [PATCH 23/27] :sparkles: feat: set shipping method :%s --- framework/vendure/schema.d.ts | 7 +++ .../eligible-shipping-methods-query.ts | 13 ++++++ src/components/hooks/order/index.ts | 3 ++ .../hooks/order/useApplyCouponCode.tsx | 4 +- .../order/useEligibleShippingMethods.tsx | 14 ++++++ .../hooks/order/useSetCustomerForOrder.tsx | 4 +- .../order/useSetOrderShippingAddress.tsx | 5 +-- .../hooks/order/useSetOrderShippingMethod.tsx | 4 +- .../checkout/CheckoutBill/CheckoutBill.tsx | 1 - .../checkout/CheckoutInfo/CheckoutInfo.tsx | 8 ++-- .../ShippingMethod/ShippingMethod.module.scss | 11 ----- .../ShippingMethod/ShippingMethod.tsx | 43 ++++--------------- .../checkout/CheckoutPage/CheckoutPage.tsx | 4 +- 13 files changed, 61 insertions(+), 60 deletions(-) create mode 100644 framework/vendure/utils/queries/eligible-shipping-methods-query.ts create mode 100644 src/components/hooks/order/useEligibleShippingMethods.tsx diff --git a/framework/vendure/schema.d.ts b/framework/vendure/schema.d.ts index cc3c0bc9c..df1f3c706 100644 --- a/framework/vendure/schema.d.ts +++ b/framework/vendure/schema.d.ts @@ -377,6 +377,13 @@ export type SetShippingMethodMutation = { | Pick; }; + +export type GetEligibleMethodsQuery = { + eligibleShippingMethods: Array< + Pick + >; +}; + export type Asset = Node & { __typename?: 'Asset' id: Scalars['ID'] diff --git a/framework/vendure/utils/queries/eligible-shipping-methods-query.ts b/framework/vendure/utils/queries/eligible-shipping-methods-query.ts new file mode 100644 index 000000000..a85b6f102 --- /dev/null +++ b/framework/vendure/utils/queries/eligible-shipping-methods-query.ts @@ -0,0 +1,13 @@ +export const getEligibleShippingMethods = /* GraphQL */ ` +query getEligibleShippingMethods { + eligibleShippingMethods { + id + name + description + price + priceWithTax + metadata + __typename + } +} +` diff --git a/src/components/hooks/order/index.ts b/src/components/hooks/order/index.ts index b7d785c92..9c20a24be 100644 --- a/src/components/hooks/order/index.ts +++ b/src/components/hooks/order/index.ts @@ -3,3 +3,6 @@ export { default as useSetOrderShippingAddress } from './useSetOrderShippingAddr export { default as useApplyCouponCode } from './useApplyCouponCode' export { default as useAvailableCountries } from './useAvailableCountries' export { default as useSetOrderShippingMethod } from './useSetOrderShippingMethod' +export { default as useGetActiveOrderForCheckout } from './useGetActiveOrderForCheckout' +export { default as useEligibleShippingMethods } from './useEligibleShippingMethods' + diff --git a/src/components/hooks/order/useApplyCouponCode.tsx b/src/components/hooks/order/useApplyCouponCode.tsx index be2c77878..329682ed8 100644 --- a/src/components/hooks/order/useApplyCouponCode.tsx +++ b/src/components/hooks/order/useApplyCouponCode.tsx @@ -3,13 +3,13 @@ import { applyCouponCodeMutation } from '@framework/utils/mutations/apply-coupon import { useState } from 'react' import { CommonError } from 'src/domains/interfaces/CommonError' import rawFetcher from 'src/utils/rawFetcher' -import { useGetActiveOrder } from '../cart' +import { useGetActiveOrderForCheckout } from '.' const useApplyCouponCode = () => { const [loading, setLoading] = useState(false) const [error, setError] = useState(null) - const { mutate } = useGetActiveOrder() + const { mutate } = useGetActiveOrderForCheckout() const applyCouponCode = (couponCode: string, fCallBack: (isSuccess: boolean, message?: string) => void diff --git a/src/components/hooks/order/useEligibleShippingMethods.tsx b/src/components/hooks/order/useEligibleShippingMethods.tsx new file mode 100644 index 000000000..cd4b64019 --- /dev/null +++ b/src/components/hooks/order/useEligibleShippingMethods.tsx @@ -0,0 +1,14 @@ +import { GetEligibleMethodsQuery, ShippingMethodQuote } from '@framework/schema' +import { getEligibleShippingMethods } from '@framework/utils/queries/eligible-shipping-methods-query' +import gglFetcher from 'src/utils/gglFetcher' +import useSWR from 'swr' + +const useEligibleShippingMethods = () => { + const { data, isValidating } = useSWR([getEligibleShippingMethods], gglFetcher) + return { + eligibleShippingMethods: data?.eligibleShippingMethods as ShippingMethodQuote[], + loading: isValidating, + } +} + +export default useEligibleShippingMethods diff --git a/src/components/hooks/order/useSetCustomerForOrder.tsx b/src/components/hooks/order/useSetCustomerForOrder.tsx index beb1e5b72..028f255cc 100644 --- a/src/components/hooks/order/useSetCustomerForOrder.tsx +++ b/src/components/hooks/order/useSetCustomerForOrder.tsx @@ -3,13 +3,13 @@ import { setCustomerForOrderMutation } from '@framework/utils/mutations/set-cust import { useState } from 'react' import { CommonError } from 'src/domains/interfaces/CommonError' import rawFetcher from 'src/utils/rawFetcher' -import { useGetActiveOrder } from '../cart' +import { useGetActiveOrderForCheckout } from '.' const useSetCustomerForOrder = () => { const [loading, setLoading] = useState(false) const [error, setError] = useState(null) - const { mutate } = useGetActiveOrder() + const { mutate } = useGetActiveOrderForCheckout() const setCustomerForOrder = (input: CreateCustomerInput, fCallBack: (isSuccess: boolean, message?: CommonError) => void diff --git a/src/components/hooks/order/useSetOrderShippingAddress.tsx b/src/components/hooks/order/useSetOrderShippingAddress.tsx index 353cb01c7..be020c48f 100644 --- a/src/components/hooks/order/useSetOrderShippingAddress.tsx +++ b/src/components/hooks/order/useSetOrderShippingAddress.tsx @@ -3,13 +3,13 @@ import { setOrderShippingAddressMutation } from '@framework/utils/mutations/set- import { useState } from 'react' import { CommonError } from 'src/domains/interfaces/CommonError' import rawFetcher from 'src/utils/rawFetcher' -import { useGetActiveOrder } from '../cart' +import { useGetActiveOrderForCheckout } from '.' const useSetOrderShippingAddress = () => { const [loading, setLoading] = useState(false) const [error, setError] = useState(null) - const { mutate } = useGetActiveOrder() + const { mutate } = useGetActiveOrderForCheckout() const setOrderShippingAddress = (input: CreateAddressInput, fCallBack: (isSuccess: boolean, message?: string) => void @@ -21,7 +21,6 @@ const useSetOrderShippingAddress = () => { variables: { input }, }) .then(({ data }) => { - console.log("data: ", data) if (data.setOrderShippingAddress.__typename === 'Order') { fCallBack(true) mutate() diff --git a/src/components/hooks/order/useSetOrderShippingMethod.tsx b/src/components/hooks/order/useSetOrderShippingMethod.tsx index bed63f72b..6c4f48f5a 100644 --- a/src/components/hooks/order/useSetOrderShippingMethod.tsx +++ b/src/components/hooks/order/useSetOrderShippingMethod.tsx @@ -3,13 +3,13 @@ import { setShippingMethodMutation } from '@framework/utils/mutations/set-order- import { useState } from 'react' import { CommonError } from 'src/domains/interfaces/CommonError' import rawFetcher from 'src/utils/rawFetcher' -import { useGetActiveOrder } from '../cart' +import { useGetActiveOrderForCheckout } from '.' const useSetOrderShippingMethod = () => { const [loading, setLoading] = useState(false) const [error, setError] = useState(null) - const { mutate } = useGetActiveOrder() + const { mutate } = useGetActiveOrderForCheckout() const setOrderShippingMethod = (id: string, fCallBack: (isSuccess: boolean, message?: string) => void diff --git a/src/components/modules/checkout/CheckoutBill/CheckoutBill.tsx b/src/components/modules/checkout/CheckoutBill/CheckoutBill.tsx index dc4462704..4dae3484b 100644 --- a/src/components/modules/checkout/CheckoutBill/CheckoutBill.tsx +++ b/src/components/modules/checkout/CheckoutBill/CheckoutBill.tsx @@ -8,7 +8,6 @@ import s from './CheckoutBill.module.scss' import FormPromotionCode from './FormPromotionCode/FormPromotionCode' interface CheckoutBillProps { - // data: CardItemCheckoutProps[] data: CartCheckout | null } diff --git a/src/components/modules/checkout/CheckoutInfo/CheckoutInfo.tsx b/src/components/modules/checkout/CheckoutInfo/CheckoutInfo.tsx index f48a41920..e96d3bda1 100644 --- a/src/components/modules/checkout/CheckoutInfo/CheckoutInfo.tsx +++ b/src/components/modules/checkout/CheckoutInfo/CheckoutInfo.tsx @@ -2,7 +2,7 @@ import React, { useEffect, useState } from 'react' import { Logo } from 'src/components/common' import CheckoutCollapse from 'src/components/common/CheckoutCollapse/CheckoutCollapse' import { useActiveCustomer } from 'src/components/hooks/auth' -import useGetActiveOrderForCheckout from 'src/components/hooks/order/useGetActiveOrderForCheckout' +import { useGetActiveOrderForCheckout } from 'src/components/hooks/order' import s from './CheckoutInfo.module.scss' import CustomerInfoForm from './components/CustomerInfoForm/CustomerInfoForm' import PaymentInfoForm from './components/PaymentInfoForm/PaymentInfoForm' @@ -25,7 +25,6 @@ const CheckoutInfo = ({ onViewCart, currency = "" }: CheckoutInfoProps) => { const [doneSteps, setDoneSteps] = useState([]) const { order } = useGetActiveOrderForCheckout() const { customer } = useActiveCustomer() - console.log("active order checkout: ", order) useEffect(() => { if (customer) { @@ -91,6 +90,9 @@ const CheckoutInfo = ({ onViewCart, currency = "" }: CheckoutInfoProps) => { return `${streetLine1}, ${city}, ${province}, ${postalCode}, ${countryCode}, ${phoneNumber}` } return '' + case CheckoutStep.ShippingMethodInfo: + console.log('oder here: ', order?.shippingLine) + return `${order?.shippingLine.shippingMethod.name}, ${order?.shippingLine.priceWithTax ? `${order?.shippingLine.priceWithTax} ${currency}`: 'Free'}` || '' default: return "" } @@ -105,7 +107,7 @@ const CheckoutInfo = ({ onViewCart, currency = "" }: CheckoutInfoProps) => { { id: CheckoutStep.ShippingAddressInfo, title: 'Shipping Address Information', - form: , + form: , }, { id: CheckoutStep.ShippingMethodInfo, diff --git a/src/components/modules/checkout/CheckoutInfo/components/ShippingMethod/ShippingMethod.module.scss b/src/components/modules/checkout/CheckoutInfo/components/ShippingMethod/ShippingMethod.module.scss index d078368e4..225f3282a 100644 --- a/src/components/modules/checkout/CheckoutInfo/components/ShippingMethod/ShippingMethod.module.scss +++ b/src/components/modules/checkout/CheckoutInfo/components/ShippingMethod/ShippingMethod.module.scss @@ -19,21 +19,10 @@ } .options { - @apply absolute transition-all duration-200 overflow-hidden; - transform: translateX(-100%); - opacity: 0; margin-top: 0.8rem; - top: 6rem; - left: 0; width: 100%; background: var(--white); border: 1px solid var(--border-line); border-radius: 0.8rem; - &.show { - z-index: 10; - opacity: 1; - transform: none; - position: initial; - } } } diff --git a/src/components/modules/checkout/CheckoutInfo/components/ShippingMethod/ShippingMethod.tsx b/src/components/modules/checkout/CheckoutInfo/components/ShippingMethod/ShippingMethod.tsx index 911650646..957df80d5 100644 --- a/src/components/modules/checkout/CheckoutInfo/components/ShippingMethod/ShippingMethod.tsx +++ b/src/components/modules/checkout/CheckoutInfo/components/ShippingMethod/ShippingMethod.tsx @@ -1,31 +1,12 @@ import { ShippingMethodQuote } from '@framework/schema' -import classNames from 'classnames' import React, { memo, useState } from 'react' import { useMessage } from 'src/components/contexts' -import { useSetOrderShippingMethod } from 'src/components/hooks/order' +import { useEligibleShippingMethods, useSetOrderShippingMethod } from 'src/components/hooks/order' import { Shipping } from 'src/components/icons' import { CheckoutStep } from '../../CheckoutInfo' import s from './ShippingMethod.module.scss' import ShippingMethodItem from './ShippingMethodItem/ShippingMethodItem' -const MOCKUP_DATA = [ - { - "id": "1", - "name": "Standard Shipping", - "description": "", - "price": 0, - "priceWithTax": 0, - "code": "standard-shipping" - }, - { - "id": "2", - "name": "Express Shipping", - "description": "", - "price": 1000, - "priceWithTax": 1000, - "code": "express-shipping" - } -] interface Props { currency: string onConfirm: (id: number) => void @@ -33,20 +14,19 @@ interface Props { } const ShippingMethod = memo(({ currency, onConfirm }: Props) => { + const { eligibleShippingMethods } = useEligibleShippingMethods() const { setOrderShippingMethod } = useSetOrderShippingMethod() - const [selectedValue, setSelectedValue] = useState(MOCKUP_DATA[0]) + const [selectedValue, setSelectedValue] = useState(eligibleShippingMethods ? eligibleShippingMethods[0] : undefined) const { showMessageError } = useMessage() - const [isShowOptions, setIsShowOptions] = useState(true) const onChange = (id: string) => { - const newValue = MOCKUP_DATA.find(item => item.id === id) + const newValue = eligibleShippingMethods?.find(item => item.id === id) if (newValue) { setSelectedValue(newValue) if (newValue?.id) { setOrderShippingMethod(newValue?.id, onSubmitCalBack) } } - setIsShowOptions(false) } const onSubmitCalBack = (isSuccess: boolean, msg?: string) => { @@ -57,31 +37,26 @@ const ShippingMethod = memo(({ currency, onConfirm }: Props) => { } } - const onCollapseOptions = () => { - setIsShowOptions(!isShowOptions) - } - - return (
    -
    +
    - {selectedValue.name} + {selectedValue?.name}
    - {selectedValue.price ? `${selectedValue.price / 100} ${currency}` : "Free"} + {selectedValue?.price ? `${selectedValue?.price / 100} ${currency}` : "Free"}
    -
    +
      - {MOCKUP_DATA.map(item => { return (
      -
      +
      From 93ddecbd0fbd180c40e7ff2347f1bfe003bcc80b Mon Sep 17 00:00:00 2001 From: lytrankieio123 Date: Thu, 21 Oct 2021 10:44:45 +0700 Subject: [PATCH 24/27] :art: styles: checkout page :%s --- .../CheckoutCollapse.module.scss | 29 ++++++++-------- .../CheckoutCollapse/CheckoutCollapse.tsx | 34 +++++++++---------- .../CustomerInfoForm.module.scss | 7 ++-- .../ShippingInfoForm.module.scss | 24 +++++-------- .../ShippingInfoForm/ShippingInfoForm.tsx | 2 +- 5 files changed, 44 insertions(+), 52 deletions(-) diff --git a/src/components/common/CheckoutCollapse/CheckoutCollapse.module.scss b/src/components/common/CheckoutCollapse/CheckoutCollapse.module.scss index 9e8e1f8e5..490797c75 100644 --- a/src/components/common/CheckoutCollapse/CheckoutCollapse.module.scss +++ b/src/components/common/CheckoutCollapse/CheckoutCollapse.module.scss @@ -1,51 +1,52 @@ -.warpper{ +.warpper { padding: 2.4rem 0; @apply border-b border-solid border-line; - .note{ + .note { + @apply cursor-pointer; font-size: 1.2rem; line-height: 2rem; letter-spacing: 0.01em; color: var(--text-label); padding: 0 5.6rem; } - .header{ - @apply flex justify-between; - .left{ + .header { + @apply flex justify-between cursor-pointer; + .left { @apply flex items-center; - .number{ + .number { width: 3.2rem; height: 3.2rem; border-radius: 100%; border: 1px solid var(--text-active); color: var(--text-active); @apply flex justify-center items-center font-bold; - &.visible{ + &.visible { background-color: var(--text-active); border: none; color: var(--white); } - &.done{ + &.done { @apply border-2 border-solid border-primary; } } - .title{ + .title { padding-left: 2.4rem; - @apply font-bold select-none cursor-pointer; + @apply font-bold select-none; color: var(--text-active); } } - .edit{ + .edit { @apply font-bold cursor-pointer; text-decoration-line: underline; margin-right: 5.6rem; } } - .body{ + .body { height: 0; @apply overflow-hidden; - &.show{ + &.show { margin-top: 3.2rem; height: initial; } } -} \ No newline at end of file +} diff --git a/src/components/common/CheckoutCollapse/CheckoutCollapse.tsx b/src/components/common/CheckoutCollapse/CheckoutCollapse.tsx index 9e6446ac3..0c9bcee9a 100644 --- a/src/components/common/CheckoutCollapse/CheckoutCollapse.tsx +++ b/src/components/common/CheckoutCollapse/CheckoutCollapse.tsx @@ -8,10 +8,10 @@ interface CheckoutCollapseProps { children: React.ReactNode title: string isEdit: boolean - onClose?: (id:number) => void - onOpen?: (id:number) => void - onEditClick?:(id:number) => void - note?:string + onClose?: (id: number) => void + onOpen?: (id: number) => void + onEditClick?: (id: number) => void + note?: string disableEdit?: boolean } @@ -23,34 +23,34 @@ const CheckoutCollapse = ({ visible, note, onOpen, - onClose, + onClose, onEditClick, disableEdit, }: CheckoutCollapseProps) => { - const handleTitleClick = () => { - if(visible){ - onClose && onClose(id) + const handleToggle = () => { + if (visible) { + onClose && onClose(id) } else if (!disableEdit) { - onOpen && onOpen(id) + isEdit && onEditClick && onEditClick(id) } - } + } const handleEdit = () => { - onEditClick && onEditClick(id) - } + onEditClick && onEditClick(id) + } return (
      -
      +
      -
      - {isEdit?:id} +
      + {isEdit ? : id}
      -
      +
      {title}
      {!disableEdit && isEdit &&
      {'Edit'}
      }
      - {(!visible && isEdit) && (
      {note}
      ) } + {(!visible && isEdit) && (
      {note}
      )}
      {children}
      ) diff --git a/src/components/modules/checkout/CheckoutInfo/components/CustomerInfoForm/CustomerInfoForm.module.scss b/src/components/modules/checkout/CheckoutInfo/components/CustomerInfoForm/CustomerInfoForm.module.scss index 10dd6ec36..cc415f373 100644 --- a/src/components/modules/checkout/CheckoutInfo/components/CustomerInfoForm/CustomerInfoForm.module.scss +++ b/src/components/modules/checkout/CheckoutInfo/components/CustomerInfoForm/CustomerInfoForm.module.scss @@ -8,11 +8,10 @@ } } .bottom{ + @apply flex flex-col items-start; margin-top: 2.4rem; - @apply flex justify-between items-center; - @screen sm-only { - @apply flex-col items-start; + button { + margin-left: auto; } - } } \ No newline at end of file diff --git a/src/components/modules/checkout/CheckoutInfo/components/ShippingInfoForm/ShippingInfoForm.module.scss b/src/components/modules/checkout/CheckoutInfo/components/ShippingInfoForm/ShippingInfoForm.module.scss index 5eaefab13..74d70da48 100644 --- a/src/components/modules/checkout/CheckoutInfo/components/ShippingInfoForm/ShippingInfoForm.module.scss +++ b/src/components/modules/checkout/CheckoutInfo/components/ShippingInfoForm/ShippingInfoForm.module.scss @@ -1,28 +1,20 @@ @import "../../../../../../styles/utilities"; -.warpper{ +.warpper { @apply u-form; @screen md { padding: 0 5.6rem; } - .bottom{ + .bottom { + @apply flex flex-col items-start; margin-top: 2.4rem; - @apply flex justify-between items-center; - .note{ - font-size: 1.2rem; - line-height: 2rem; - } - @screen sm-only { - @apply flex-col items-start; - .button { - padding-top: 2rem; - } + button { + margin-left: auto; } } - .line{ - >div{ + .line { + > div { width: 50%; } } - -} \ No newline at end of file +} diff --git a/src/components/modules/checkout/CheckoutInfo/components/ShippingInfoForm/ShippingInfoForm.tsx b/src/components/modules/checkout/CheckoutInfo/components/ShippingInfoForm/ShippingInfoForm.tsx index 63cde8385..f9ef80ce6 100644 --- a/src/components/modules/checkout/CheckoutInfo/components/ShippingInfoForm/ShippingInfoForm.tsx +++ b/src/components/modules/checkout/CheckoutInfo/components/ShippingInfoForm/ShippingInfoForm.tsx @@ -176,7 +176,7 @@ const ShippingInfoForm = ({ onConfirm, id, activeStep }: ShippingInfoFormProps)
      - Continue to Payment + Continue to Shipping method
      From 471d4e1aaf274b0d83e3b28028ca2156791c7db8 Mon Sep 17 00:00:00 2001 From: lytrankieio123 Date: Thu, 21 Oct 2021 10:53:14 +0700 Subject: [PATCH 25/27] :art: styles: shipping method :%s --- .../common/CheckoutCollapse/CheckoutCollapse.tsx | 4 ++-- .../FormPromotionCode/FormPromotionCode.tsx | 2 +- .../components/ShippingMethod/ShippingMethod.tsx | 1 + .../ShippingMethodItem.module.scss | 10 ++++++++-- .../ShippingMethodItem/ShippingMethodItem.tsx | 15 ++++++++++++--- 5 files changed, 24 insertions(+), 8 deletions(-) diff --git a/src/components/common/CheckoutCollapse/CheckoutCollapse.tsx b/src/components/common/CheckoutCollapse/CheckoutCollapse.tsx index 0c9bcee9a..38314c8cc 100644 --- a/src/components/common/CheckoutCollapse/CheckoutCollapse.tsx +++ b/src/components/common/CheckoutCollapse/CheckoutCollapse.tsx @@ -8,7 +8,7 @@ interface CheckoutCollapseProps { children: React.ReactNode title: string isEdit: boolean - onClose?: (id: number) => void + onClose: (id: number) => void onOpen?: (id: number) => void onEditClick?: (id: number) => void note?: string @@ -29,7 +29,7 @@ const CheckoutCollapse = ({ }: CheckoutCollapseProps) => { const handleToggle = () => { if (visible) { - onClose && onClose(id) + isEdit && onClose(id) } else if (!disableEdit) { isEdit && onEditClick && onEditClick(id) } diff --git a/src/components/modules/checkout/CheckoutBill/FormPromotionCode/FormPromotionCode.tsx b/src/components/modules/checkout/CheckoutBill/FormPromotionCode/FormPromotionCode.tsx index 5fc3c95ee..aaf8f6b32 100644 --- a/src/components/modules/checkout/CheckoutBill/FormPromotionCode/FormPromotionCode.tsx +++ b/src/components/modules/checkout/CheckoutBill/FormPromotionCode/FormPromotionCode.tsx @@ -66,7 +66,7 @@ const FormPromotionCode = () => { { name={item.name} price={item.price} currency={currency} + isActive={selectedValue?.id === item.id} onSelect={onChange} />)}
    diff --git a/src/components/modules/checkout/CheckoutInfo/components/ShippingMethod/ShippingMethodItem/ShippingMethodItem.module.scss b/src/components/modules/checkout/CheckoutInfo/components/ShippingMethod/ShippingMethodItem/ShippingMethodItem.module.scss index 4aa06484c..9d8526629 100644 --- a/src/components/modules/checkout/CheckoutInfo/components/ShippingMethod/ShippingMethodItem/ShippingMethodItem.module.scss +++ b/src/components/modules/checkout/CheckoutInfo/components/ShippingMethod/ShippingMethodItem/ShippingMethodItem.module.scss @@ -1,12 +1,18 @@ .shippingMethodItem { - @apply flex justify-between items-center cursor-pointer transition-all duration-200; - width: 100%; + @apply w-full flex justify-between items-center cursor-pointer transition-all duration-200; padding: 1.6rem; &:hover { @apply bg-gray; } .left { @apply flex; + .icon { + @apply transition-all duration-200; + opacity: 0; + &.show { + opacity: 1; + } + } .name { margin-left: 1.6rem; color: var(--text-active); diff --git a/src/components/modules/checkout/CheckoutInfo/components/ShippingMethod/ShippingMethodItem/ShippingMethodItem.tsx b/src/components/modules/checkout/CheckoutInfo/components/ShippingMethod/ShippingMethodItem/ShippingMethodItem.tsx index 43685e3db..30651168d 100644 --- a/src/components/modules/checkout/CheckoutInfo/components/ShippingMethod/ShippingMethodItem/ShippingMethodItem.tsx +++ b/src/components/modules/checkout/CheckoutInfo/components/ShippingMethod/ShippingMethodItem/ShippingMethodItem.tsx @@ -1,4 +1,6 @@ +import classNames from 'classnames' import React, { memo } from 'react' +import { IconCheck } from 'src/components/icons' import s from './ShippingMethodItem.module.scss' interface Props { @@ -7,16 +9,23 @@ interface Props { price: number currency: string onSelect: (id: string) => void + isActive: boolean + } -const ShippingMethodItem = memo(({ id, name, price, currency, onSelect }: Props) => { +const ShippingMethodItem = memo(({ id, name, price, currency, isActive, onSelect }: Props) => { const handleSelect = () => { onSelect(id) } return (
  • -
    - {name} +
    +
    + +
    +
    + {name} +
    {price ? `${price / 100} ${currency}` : "Free"} From e5f3952887a9f32b7a4fee90edd1b46488b31c49 Mon Sep 17 00:00:00 2001 From: lytrankieio123 Date: Thu, 21 Oct 2021 14:13:07 +0700 Subject: [PATCH 26/27] :bug: bug: shippingLine undefined :%s --- framework/commerce/types/cart.ts | 2 +- framework/vendure/api/operations/get-product.ts | 2 +- framework/vendure/utils/normalize.ts | 8 ++++---- .../modules/checkout/CheckoutBill/CheckoutBill.tsx | 2 +- .../modules/checkout/CheckoutInfo/CheckoutInfo.tsx | 6 ++++-- 5 files changed, 11 insertions(+), 9 deletions(-) diff --git a/framework/commerce/types/cart.ts b/framework/commerce/types/cart.ts index e0d56b3bb..9192436d0 100644 --- a/framework/commerce/types/cart.ts +++ b/framework/commerce/types/cart.ts @@ -122,7 +122,7 @@ export type CartCheckout = { // Discounts that have been applied on the cart. discounts?: Discount[] totalDiscount: number - shippingLine: { + shippingLine?: { priceWithTax: number shippingMethod: ShippingMethod } diff --git a/framework/vendure/api/operations/get-product.ts b/framework/vendure/api/operations/get-product.ts index 66f798ee1..c16041468 100644 --- a/framework/vendure/api/operations/get-product.ts +++ b/framework/vendure/api/operations/get-product.ts @@ -2,7 +2,7 @@ import { Product } from '@commerce/types/product' import { OperationContext } from '@commerce/api/operations' import { Provider, VendureConfig } from '../' import { GetProductQuery } from '../../schema' -import { getProductQuery, getProductDetailQuery } from '../../utils/queries/get-product-query' +import { getProductQuery } from '../../utils/queries/get-product-query' export default function getProductOperation({ commerce, diff --git a/framework/vendure/utils/normalize.ts b/framework/vendure/utils/normalize.ts index 7a2ab0d24..63444b45d 100644 --- a/framework/vendure/utils/normalize.ts +++ b/framework/vendure/utils/normalize.ts @@ -94,10 +94,10 @@ export function normalizeCartForCheckout(order: CartFragment): CartCheckout { countryCode: order.shippingAddress?.countryCode || '', phoneNumber: order.shippingAddress?.phoneNumber || '', }, - shippingLine: { - priceWithTax: order.shippingLines[0].priceWithTax / 100, - shippingMethod: order.shippingLines[0].shippingMethod as ShippingMethod - }, + shippingLine: order.shippingLines[0] ? { + priceWithTax: order.shippingLines[0]?.priceWithTax / 100, + shippingMethod: order.shippingLines[0]?.shippingMethod as ShippingMethod + }: undefined, totalDiscount: order.discounts?.reduce((total, item) => total + item.amountWithTax, 0) / 100 || 0, discounts: order.discounts.map(item => { return { value: item.amountWithTax, description: item.description } diff --git a/src/components/modules/checkout/CheckoutBill/CheckoutBill.tsx b/src/components/modules/checkout/CheckoutBill/CheckoutBill.tsx index 4dae3484b..3e3910c90 100644 --- a/src/components/modules/checkout/CheckoutBill/CheckoutBill.tsx +++ b/src/components/modules/checkout/CheckoutBill/CheckoutBill.tsx @@ -49,7 +49,7 @@ const CheckoutBill = ({ data }: CheckoutBillProps) => {
    Shipping -
    {data?.shippingLine.priceWithTax || 0} {data?.currency?.code}
    +
    {data?.shippingLine?.priceWithTax || 0} {data?.currency?.code}
    Estimated Total diff --git a/src/components/modules/checkout/CheckoutInfo/CheckoutInfo.tsx b/src/components/modules/checkout/CheckoutInfo/CheckoutInfo.tsx index e96d3bda1..32cfec5fd 100644 --- a/src/components/modules/checkout/CheckoutInfo/CheckoutInfo.tsx +++ b/src/components/modules/checkout/CheckoutInfo/CheckoutInfo.tsx @@ -91,8 +91,10 @@ const CheckoutInfo = ({ onViewCart, currency = "" }: CheckoutInfoProps) => { } return '' case CheckoutStep.ShippingMethodInfo: - console.log('oder here: ', order?.shippingLine) - return `${order?.shippingLine.shippingMethod.name}, ${order?.shippingLine.priceWithTax ? `${order?.shippingLine.priceWithTax} ${currency}`: 'Free'}` || '' + if (order?.shippingLine) { + return `${order?.shippingLine.shippingMethod.name}, ${order?.shippingLine.priceWithTax ? `${order?.shippingLine.priceWithTax} ${currency}` : 'Free'}` || '' + } + return '' default: return "" } From 5317c6bfde2846d4d66f09a57f39ea844a6bc4ba Mon Sep 17 00:00:00 2001 From: lytrankieio123 Date: Thu, 21 Oct 2021 14:30:14 +0700 Subject: [PATCH 27/27] :bug: bug: section FreshProducts position :%s --- pages/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pages/index.tsx b/pages/index.tsx index 51127909a..fbcecadef 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -30,8 +30,8 @@ export default function Home({ featuredAndDiscountFacetsValue, veggie, - + {spiceProducts.length>0 && }