+
);
diff --git a/components/form/combobox-button.tsx b/components/form/combobox-button.tsx
new file mode 100644
index 000000000..b6c3a90fb
--- /dev/null
+++ b/components/form/combobox-button.tsx
@@ -0,0 +1,18 @@
+import { ComboboxButtonProps, ComboboxButton as HeadlessComboboxButton } from '@headlessui/react';
+import { ChevronDownIcon } from '@heroicons/react/16/solid';
+import clsx from 'clsx';
+
+export default function ComboboxButton({ className, ...props }: ComboboxButtonProps) {
+ return (
+
+
+
+ );
+}
diff --git a/components/form/combobox-input.tsx b/components/form/combobox-input.tsx
new file mode 100644
index 000000000..33a34e1e2
--- /dev/null
+++ b/components/form/combobox-input.tsx
@@ -0,0 +1,21 @@
+import { ComboboxInputProps } from '@headlessui/react';
+import clsx from 'clsx';
+
+export default function ComboboxInput({ className, ...props }: ComboboxInputProps) {
+ return (
+
+ );
+}
diff --git a/components/form/combobox-option.tsx b/components/form/combobox-option.tsx
new file mode 100644
index 000000000..70413f31a
--- /dev/null
+++ b/components/form/combobox-option.tsx
@@ -0,0 +1,16 @@
+import { ComboboxOption as HeadlessCombobox, ComboboxOptionProps } from '@headlessui/react';
+import clsx from 'clsx';
+
+export default function ComboboxOption({ className, ...props }: ComboboxOptionProps) {
+ return (
+
+ );
+}
diff --git a/components/form/combobox-options.tsx b/components/form/combobox-options.tsx
new file mode 100644
index 000000000..0de5309c1
--- /dev/null
+++ b/components/form/combobox-options.tsx
@@ -0,0 +1,18 @@
+import {
+ ComboboxOptionsProps,
+ ComboboxOptions as HeadlessComboboxOptions
+} from '@headlessui/react';
+import clsx from 'clsx';
+
+export default function ComboboxOption({ className, ...props }: ComboboxOptionsProps) {
+ return (
+
+ );
+}
diff --git a/components/orders/actions.tsx b/components/orders/actions.tsx
index 56b2d3ca8..a7773bcf1 100644
--- a/components/orders/actions.tsx
+++ b/components/orders/actions.tsx
@@ -164,3 +164,63 @@ export const confirmOrder = async ({ order, content, formData }: ConfirmOrderOpt
console.log('activateWarranty action', error);
}
};
+
+export async function returnCore() {
+ // const rawFormData = [
+ // getMetafieldValue(
+ // 'coreReturnZip',
+ // {
+ // key: '',
+ // value: formData.get('name') as string | null,
+ // type: 'file_reference'
+ // },
+ // order
+ // ),
+ // getMetafieldValue(
+ // 'warrantyActivationInstallation',
+ // {
+ // key: 'warranty_activation_installation',
+ // value: installationFileId,
+ // type: 'file_reference'
+ // },
+ // order
+ // ),
+ // getMetafieldValue(
+ // 'warrantyActivationSelfInstall',
+ // {
+ // key: 'warranty_activation_self_install',
+ // value: formData.get('warranty_activation_self_install') === 'on' ? 'true' : 'false',
+ // type: 'boolean'
+ // },
+ // order
+ // ),
+ // getMetafieldValue(
+ // 'warrantyActivationMileage',
+ // {
+ // key: 'warranty_activation_mileage',
+ // value: formData.get('warranty_activation_mileage') as string | null,
+ // type: 'number_integer'
+ // },
+ // order
+ // ),
+ // getMetafieldValue(
+ // 'warrantyActivationVIN',
+ // {
+ // key: 'warranty_activation_vin',
+ // value: formData.get('warranty_activation_vin') as string | null,
+ // type: 'single_line_text_field'
+ // },
+ // order
+ // )
+ // ];
+ try {
+ // await updateOrderMetafields({
+ // orderId: order.id,
+ // metafields: rawFormData
+ // });
+
+ revalidateTag(TAGS.orderMetafields);
+ } catch (error) {
+ console.log('activateWarranty action', error);
+ }
+}
diff --git a/components/orders/activate-warranty.tsx b/components/orders/activate-warranty.tsx
index c894ea588..ac99c1b82 100644
--- a/components/orders/activate-warranty.tsx
+++ b/components/orders/activate-warranty.tsx
@@ -4,7 +4,6 @@ import { Order, WarrantyStatus } from 'lib/shopify/types';
import { isBeforeToday } from 'lib/utils';
import { useState } from 'react';
import ActivateWarrantyModal from './activate-warranty-modal';
-import WarrantyActivatedBadge from './warranty-activated-badge';
import { Button } from 'components/ui';
type ActivateWarrantyModalProps = {
@@ -13,7 +12,7 @@ type ActivateWarrantyModalProps = {
const ActivateWarranty = ({ order }: ActivateWarrantyModalProps) => {
const [isOpen, setIsOpen] = useState(false);
- const isWarrantyActivated = order?.warrantyStatus?.value === WarrantyStatus.Activated;
+ const isActivated = order?.warrantyStatus?.value === WarrantyStatus.Activated;
const isPassDeadline = isBeforeToday(order?.warrantyActivationDeadline?.value);
const isOrderConfirmed = order?.orderConfirmation?.value;
@@ -21,11 +20,7 @@ const ActivateWarranty = ({ order }: ActivateWarrantyModalProps) => {
return null;
}
- if (isWarrantyActivated) {
- return
;
- }
-
- if (isPassDeadline) {
+ if (isPassDeadline || isActivated) {
return null;
}
diff --git a/components/orders/core-return-modal.tsx b/components/orders/core-return-modal.tsx
new file mode 100644
index 000000000..c65aa1176
--- /dev/null
+++ b/components/orders/core-return-modal.tsx
@@ -0,0 +1,94 @@
+import { Dialog, DialogBackdrop, DialogPanel, Fieldset, Legend } from '@headlessui/react';
+import { Order } from 'lib/shopify/types';
+import { Button, Heading, Input } from 'components/ui';
+import StatesCombobox from 'components/states-combobox';
+import { useTransition } from 'react';
+// import { returnCore } from './actions';
+
+export function CoreReturnModal({
+ isOpen,
+ onClose,
+ order
+}: {
+ isOpen: boolean;
+ onClose: () => void;
+ order: Order;
+}) {
+ const [submitting, startTransition] = useTransition();
+
+ async function submitCoreReturn(formData: FormData) {
+ startTransition(async () => {
+ // returnCore(order, formData);
+ console.log(formData);
+ });
+ }
+
+ return (
+
+
+
+
+
+
+ Core Return
+
+ Order {order.name}
+
+
+
+
+
+
+
+ );
+}
diff --git a/components/orders/core-return-status.tsx b/components/orders/core-return-status.tsx
new file mode 100644
index 000000000..c969c6395
--- /dev/null
+++ b/components/orders/core-return-status.tsx
@@ -0,0 +1,8 @@
+import { Chip } from 'components/ui';
+import { Order } from 'lib/shopify/types';
+
+export default function CoreReturnStatus({ order }: { order: Order }) {
+ if (!order.coreReturnStatus?.value) return null;
+
+ return
Core Return: {order.coreReturnStatus.value} ;
+}
diff --git a/components/orders/core-return.tsx b/components/orders/core-return.tsx
new file mode 100644
index 000000000..da6dcfba6
--- /dev/null
+++ b/components/orders/core-return.tsx
@@ -0,0 +1,15 @@
+'use client';
+import { Button } from 'components/ui';
+import { Order } from 'lib/shopify/types';
+import { useState } from 'react';
+import { CoreReturnModal } from './core-return-modal';
+
+export function CoreReturn({ order }: { order: Order }) {
+ const [isOpen, setIsOpen] = useState(false);
+ return (
+ <>
+
setIsOpen(true)}>Core Return
+
setIsOpen(false)} />
+ >
+ );
+}
diff --git a/components/orders/order-confirmation-modal.tsx b/components/orders/order-confirmation-modal.tsx
index 892f17a1a..b94d9d48b 100644
--- a/components/orders/order-confirmation-modal.tsx
+++ b/components/orders/order-confirmation-modal.tsx
@@ -8,7 +8,7 @@ import Markdown from 'markdown-to-jsx';
import { Order, OrderConfirmationContent } from 'lib/shopify/types';
import { FormEventHandler, useEffect, useRef, useState, useTransition } from 'react';
import { confirmOrder, fetchOrderConfirmationContent } from 'components/orders/actions';
-import { Button, Heading, Text, Label, Input, Skeleton } from 'components/ui';
+import { Button, Heading, Text, Label, Input } from 'components/ui';
import LoadingDots from 'components/loading-dots';
function OrderConfirmationDetails({
@@ -228,7 +228,7 @@ export default function OrderConfirmationModal({
diff --git a/components/orders/order-confirmation-pdf.tsx b/components/orders/order-confirmation-pdf.tsx
index 88f53fd6e..bc834a259 100644
--- a/components/orders/order-confirmation-pdf.tsx
+++ b/components/orders/order-confirmation-pdf.tsx
@@ -156,7 +156,9 @@ export default function OrderConfirmationPdf({
Payment
- Ending with {order.transactions[0]!.paymentDetails.last4} -
+ {order.transactions[0]?.paymentDetails
+ ? `Ending with ${order.transactions[0]!.paymentDetails.last4} - `
+ : 'Manual - '}
Order Not Confirmed;
+}
diff --git a/components/orders/order-statuses.tsx b/components/orders/order-statuses.tsx
new file mode 100644
index 000000000..4620ebd84
--- /dev/null
+++ b/components/orders/order-statuses.tsx
@@ -0,0 +1,14 @@
+import { Order } from 'lib/shopify/types';
+import CoreReturnStatus from './core-return-status';
+import WarrantyActivatedStatus from './warranty-activated-status';
+import OrderConfirmedStatus from './order-confirmation-status';
+
+export default function OrderStatuses({ order, className }: { order: Order; className?: string }) {
+ return (
+
+
+
+
+
+ );
+}
diff --git a/components/orders/payment-details.tsx b/components/orders/payment-details.tsx
index 0284757c5..2f303212a 100644
--- a/components/orders/payment-details.tsx
+++ b/components/orders/payment-details.tsx
@@ -20,7 +20,9 @@ export default function PaymentsDetails({ order, hideIcon }: { order: Order; hid
- Ending with {transaction.paymentDetails.last4} -
+ {transaction?.paymentDetails
+ ? `Ending with ${transaction.paymentDetails.last4} - `
+ : 'Manual - '}
{
- return (
-
-
- Warranty Activated
-
- );
-};
-
-export default WarrantyActivatedBadge;
diff --git a/components/orders/warranty-activated-status.tsx b/components/orders/warranty-activated-status.tsx
new file mode 100644
index 000000000..4568ca3bb
--- /dev/null
+++ b/components/orders/warranty-activated-status.tsx
@@ -0,0 +1,21 @@
+import Chip, { ChipProps } from 'components/ui/chip';
+import { Order, WarrantyStatus } from 'lib/shopify/types';
+
+const WarrantyActivatedStatus = ({ order }: { order: Order }) => {
+ const warrantyStatus = order?.warrantyStatus?.value;
+ const isOrderConfirmed = order?.orderConfirmation?.value;
+
+ if (!isOrderConfirmed || !warrantyStatus) {
+ return null;
+ }
+
+ let level: ChipProps['level'] = 'success';
+
+ if (warrantyStatus === WarrantyStatus.NotActivated) {
+ level = 'warn';
+ }
+
+ return Warranty: {warrantyStatus} ;
+};
+
+export default WarrantyActivatedStatus;
diff --git a/components/states-combobox.tsx b/components/states-combobox.tsx
new file mode 100644
index 000000000..291deb8c1
--- /dev/null
+++ b/components/states-combobox.tsx
@@ -0,0 +1,73 @@
+import Combobox from './ui/combobox';
+
+const states = [
+ { name: 'Alabama', code: 'AL' },
+ { name: 'Alaska', code: 'AK' },
+ { name: 'Arizona', code: 'AZ' },
+ { name: 'Arkansas', code: 'AR' },
+ { name: 'California', code: 'CA' },
+ { name: 'Colorado', code: 'CO' },
+ { name: 'Connecticut', code: 'CT' },
+ { name: 'Delaware', code: 'DE' },
+ { name: 'Florida', code: 'FL' },
+ { name: 'Georgia', code: 'GA' },
+ { name: 'Hawaii', code: 'HI' },
+ { name: 'Idaho', code: 'ID' },
+ { name: 'Illinois', code: 'IL' },
+ { name: 'Indiana', code: 'IN' },
+ { name: 'Iowa', code: 'IA' },
+ { name: 'Kansas', code: 'KS' },
+ { name: 'Kentucky', code: 'KY' },
+ { name: 'Louisiana', code: 'LA' },
+ { name: 'Maine', code: 'ME' },
+ { name: 'Maryland', code: 'MD' },
+ { name: 'Massachusetts', code: 'MA' },
+ { name: 'Michigan', code: 'MI' },
+ { name: 'Minnesota', code: 'MN' },
+ { name: 'Mississippi', code: 'MS' },
+ { name: 'Missouri', code: 'MO' },
+ { name: 'Montana', code: 'MT' },
+ { name: 'Nebraska', code: 'NE' },
+ { name: 'Nevada', code: 'NV' },
+ { name: 'New Hampshire', code: 'NH' },
+ { name: 'New Jersey', code: 'NJ' },
+ { name: 'New Mexico', code: 'NM' },
+ { name: 'New York', code: 'NY' },
+ { name: 'North Carolina', code: 'NC' },
+ { name: 'North Dakota', code: 'ND' },
+ { name: 'Ohio', code: 'OH' },
+ { name: 'Oklahoma', code: 'OK' },
+ { name: 'Oregon', code: 'OR' },
+ { name: 'Pennsylvania', code: 'PA' },
+ { name: 'Rhode Island', code: 'RI' },
+ { name: 'South Carolina', code: 'SC' },
+ { name: 'South Dakota', code: 'SD' },
+ { name: 'Tennessee', code: 'TN' },
+ { name: 'Texas', code: 'TX' },
+ { name: 'Utah', code: 'UT' },
+ { name: 'Vermont', code: 'VT' },
+ { name: 'Virginia', code: 'VA' },
+ { name: 'Washington', code: 'WA' },
+ { name: 'West Virginia', code: 'WV' },
+ { name: 'Wisconsin', code: 'WI' },
+ { name: 'Wyoming', code: 'WY' }
+];
+
+function findState(code: string) {
+ return states.find((state) => state.code === code);
+}
+
+export default function StatesCombobox({ defaultStateCode }: { defaultStateCode: string }) {
+ return (
+
+ );
+}
diff --git a/components/ui/card.tsx b/components/ui/card.tsx
index bb65e3345..9b2275649 100644
--- a/components/ui/card.tsx
+++ b/components/ui/card.tsx
@@ -7,7 +7,7 @@ const cardStyles = tv({
base: 'rounded p-6 text-left w-full',
variants: {
outlined: {
- true: 'border bg-white',
+ true: 'border bg-white shadow-sm',
false: ''
},
elevated: {
diff --git a/components/ui/chip.tsx b/components/ui/chip.tsx
new file mode 100644
index 000000000..b7ba93d07
--- /dev/null
+++ b/components/ui/chip.tsx
@@ -0,0 +1,63 @@
+import { CheckCircleIcon, ExclamationCircleIcon, XCircleIcon } from '@heroicons/react/24/solid';
+import clsx from 'clsx';
+import { VariantProps, tv } from 'tailwind-variants';
+
+const chip = tv({
+ slots: {
+ root: 'inline-flex items-center gap-x-2 rounded-md px-2.5 py-2 text-sm font-medium ring-1 ring-inset',
+ leadingIcon: 'h-5 w-5'
+ },
+ variants: {
+ level: {
+ success: {
+ root: 'bg-green-50 text-green-700 ring-green-600/20'
+ },
+ warn: {
+ root: 'bg-yellow-50 text-yellow-700 ring-yellow-600/20'
+ },
+ info: {
+ root: 'bg-content/5 text-content-emphasis ring-content/20'
+ },
+ error: {
+ root: 'bg-red-50 text-red-700 ring-red-600/20'
+ }
+ }
+ }
+});
+
+export interface LevelLeadingProps extends VariantProps {
+ className?: string;
+}
+
+export interface ChipProps extends VariantProps {
+ children: React.ReactNode;
+ className?: string;
+}
+
+function LevelLeadingIcon({ level, className }: LevelLeadingProps) {
+ if (level === 'success') {
+ return ;
+ }
+
+ if (level === 'warn') {
+ return (
+
+ );
+ }
+
+ if (level === 'error') {
+ return ;
+ }
+
+ return null;
+}
+
+export default function Chip({ children, level, className }: ChipProps) {
+ const { root, leadingIcon } = chip();
+ return (
+
+
+ {children}
+
+ );
+}
diff --git a/components/ui/combobox.tsx b/components/ui/combobox.tsx
new file mode 100644
index 000000000..890b26b04
--- /dev/null
+++ b/components/ui/combobox.tsx
@@ -0,0 +1,163 @@
+'use client';
+
+import {
+ Combobox as HeadlessCombobox,
+ ComboboxProps as HeadlessComboboxProps,
+ ComboboxButton,
+ ComboboxInput,
+ ComboboxOption,
+ ComboboxOptions,
+ Field,
+ Label
+} from '@headlessui/react';
+import { AnchorProps } from '@headlessui/react/dist/internal/floating';
+import { ChevronDownIcon } from '@heroicons/react/16/solid';
+import { focusInput } from 'lib/utils';
+import get from 'lodash.get';
+import { useCallback, useState } from 'react';
+import { tv } from 'tailwind-variants';
+
+const combobox = tv({
+ slots: {
+ root: '',
+ label: [
+ 'text-sm leading-none',
+ 'text-content-strong font-medium',
+ 'data-[disabled]:text-gray-400'
+ ],
+ input: [
+ // base
+ 'w-full relative block rounded-md border-0 shadow-sm outline-none transition sm:text-sm sm:leading-6',
+ 'mt-2 px-2.5 py-1.5',
+ // border color
+ 'border-gray-300',
+ // text color
+ 'text-gray-900',
+ // ring
+ 'ring-1 ring-inset ring-gray-300',
+ // placeholder color
+ 'placeholder-gray-400',
+ // background color
+ 'bg-white',
+ // disabled
+ 'data-[disabled]:border-gray-300 data-[disabled]:bg-gray-100 data-[disabled]:text-gray-400',
+ // focus
+ focusInput,
+ // invalid
+ 'data-[invalid]:ring-2 data-[invalid]:ring-red-200 data-[invalid]:border-red-500'
+ ],
+ button: [
+ 'group absolute inset-y-0 right-0 px-2.5 data-[disabled]:cursor-not-allowed data-[disabled]:opacity-50'
+ ],
+ options: [
+ 'z-10 w-[var(--input-width)] rounded-xl border border-gray-200 bg-white p-1 [--anchor-gap:6px] empty:hidden'
+ ],
+ option: [
+ 'flex cursor-default select-none items-center gap-2 rounded-lg px-3 py-1.5 text-sm/6 data-[focus]:bg-secondary/10'
+ ]
+ }
+});
+
+interface ComboboxProps, TMultiple extends boolean | undefined>
+ extends HeadlessComboboxProps {
+ options: T[];
+ label: string;
+ labelHidden?: boolean;
+ autoFocus?: boolean;
+ displayKey: keyof T;
+ required?: boolean;
+ className?: string;
+ anchor?: AnchorProps;
+}
+
+const Combobox = , TMultiple extends boolean | undefined>({
+ options,
+ value,
+ onChange,
+ label,
+ labelHidden,
+ displayKey,
+ disabled,
+ autoFocus,
+ by,
+ className,
+ required,
+ anchor,
+ ...props
+}: ComboboxProps) => {
+ const {
+ root,
+ label: labelStyles,
+ input,
+ button,
+ options: optionsStyles,
+ option: optionStyles
+ } = combobox();
+
+ const [query, setQuery] = useState('');
+ const getDisplayValue = useCallback(
+ (option: T | null) => {
+ if (!option) return '';
+
+ if (typeof option[displayKey] === 'string') {
+ return option[displayKey] as string;
+ }
+
+ return get(option, `${displayKey as string}.value`) as string;
+ },
+ [displayKey]
+ );
+
+ const filteredOptions =
+ query === ''
+ ? options
+ : options.filter((option) => {
+ return getDisplayValue(option).toLocaleLowerCase().includes(query.toLowerCase());
+ });
+
+ return (
+
+ {!labelHidden && (
+
+ {label}
+ {required && * }
+
+ )}
+ setQuery('')}
+ disabled={disabled}
+ by={by}
+ {...props}
+ >
+
+ setQuery(event.target.value)}
+ className={input()}
+ autoFocus={autoFocus}
+ />
+
+
+
+
+
+ {filteredOptions.map((option) => (
+
+ {getDisplayValue(option)}
+
+ ))}
+
+
+
+ );
+};
+
+export default Combobox;
diff --git a/components/ui/heading.tsx b/components/ui/heading.tsx
index 79ca13f5d..a3fbde268 100644
--- a/components/ui/heading.tsx
+++ b/components/ui/heading.tsx
@@ -22,7 +22,7 @@ const heading = tv(
export interface HeadingProps extends VariantProps {
className?: string;
children: React.ReactNode;
- as?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'span' | 'p';
+ as?: React.ElementType;
}
export default function Heading({ children, className, size, as }: HeadingProps) {
diff --git a/components/ui/index.ts b/components/ui/index.ts
index 8c74eaab3..8a122e99a 100644
--- a/components/ui/index.ts
+++ b/components/ui/index.ts
@@ -12,3 +12,5 @@ export * from './skeleton';
export { default as Skeleton } from './skeleton';
export * from './text';
export { default as Text } from './text';
+export { default as Chip } from './chip';
+export * from './chip';
diff --git a/components/ui/input.tsx b/components/ui/input.tsx
index 781ab4b34..2d2ca0dbf 100644
--- a/components/ui/input.tsx
+++ b/components/ui/input.tsx
@@ -70,7 +70,12 @@ function Input({
const { root, label: labelStyles, input } = inputStyles({ hasError });
return (
- {label && {label} }
+ {label && (
+
+ {label}
+ {props.required && * }
+
+ )}
{
as?: 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'span' | 'p';
}
-export default function Text({ children, className, size, as }: TextProps) {
+export default function Text({ children, className, size, as, bold }: TextProps) {
const Component = as || 'p';
- return {children} ;
+ return {children} ;
}
diff --git a/lib/shopify/auth.ts b/lib/shopify/auth.ts
index 1269565f3..59fdd4213 100644
--- a/lib/shopify/auth.ts
+++ b/lib/shopify/auth.ts
@@ -203,7 +203,6 @@ export async function refreshToken({ request, origin }: { request: NextRequest;
return { success: false, message: `no_refresh_token` };
}
const data = await response.json();
- console.log('data response from initial fetch to refresh', data);
const { access_token, expires_in, refresh_token } = data;
const customerAccessToken = await exchangeAccessToken(
@@ -238,10 +237,7 @@ export async function checkExpires({
let isExpired = false;
if (parseInt(expiresAt, 10) - 1000 < new Date().getTime()) {
isExpired = true;
- console.log('Isexpired is true, we are running refresh token!');
const refresh = await refreshToken({ request, origin });
- console.log('refresh', refresh);
- //this will return success: true or success: false - depending on result of refresh
return { ranRefresh: isExpired, refresh };
}
return { ranRefresh: isExpired, success: true };
@@ -364,8 +360,6 @@ export async function isLoggedIn(request: NextRequest, origin: string) {
//return { success: false, message: `no_refresh_token` }
} else {
const refreshData = isExpired?.refresh?.data;
- //console.log ("refresh data", refreshData)
- console.log('We used the refresh token, so now going to reset the token and cookies');
const newCustomerAccessToken = refreshData?.customerAccessToken;
const expires_in = refreshData?.expires_in;
//const test_expires_in = 180 //to test to see if it expires in 60 seconds!
@@ -468,7 +462,6 @@ export async function authorize(request: NextRequest, origin: string) {
//sets an expires time 2 minutes before expiration which we can use in refresh strategy
//const test_expires_in = 180 //to test to see if it expires in 60 seconds!
const expiresAt = new Date(new Date().getTime() + (expires_in! - 120) * 1000).getTime() + '';
- console.log('expires at', expiresAt);
return await createAllCookies({
response: authResponse,
diff --git a/lib/shopify/fragments/order-metafields.ts b/lib/shopify/fragments/order-metafields.ts
index 2488b66d7..59916fdd1 100644
--- a/lib/shopify/fragments/order-metafields.ts
+++ b/lib/shopify/fragments/order-metafields.ts
@@ -50,6 +50,33 @@ const orderMetafieldsFragment = /* GraphQL */ `
orderConfirmation: metafield(namespace: "custom", key: "customer_confirmation") {
value
}
+ coreReturnStatus: metafield(namespace: "custom", key: "core_status") {
+ value
+ }
+ coreReturnDeadline: metafield(namespace: "custom", key: "core_return_deadline") {
+ value
+ }
+ coreReturnName: metafield(namespace: "custom", key: "core_return_name") {
+ value
+ }
+ coreReturnEmail: metafield(namespace: "custom", key: "core_return_email") {
+ value
+ }
+ coreReturnPhone: metafield(namespace: "custom", key: "core_return_phone") {
+ value
+ }
+ coreReturnAddress: metafield(namespace: "custom", key: "core_return_address") {
+ value
+ }
+ coreReturnCity: metafield(namespace: "custom", key: "core_return_city") {
+ value
+ }
+ coreReturnState: metafield(namespace: "custom", key: "core_return_state") {
+ value
+ }
+ coreReturnZip: metafield(namespace: "custom", key: "core_return_zip") {
+ value
+ }
}
`;
diff --git a/lib/shopify/index.ts b/lib/shopify/index.ts
index 7966b59bc..1b358657f 100644
--- a/lib/shopify/index.ts
+++ b/lib/shopify/index.ts
@@ -136,6 +136,9 @@ const userAgent = '*';
const placeholderProductImage =
'https://cdn.shopify.com/shopifycloud/customer-account-web/production/assets/8bc6556601c510713d76.svg';
+const placeholderPaymentIcon =
+ 'https://cdn.shopify.com/shopifycloud/customer-account-web/production/assets/7bea2f.svg';
+
const key = process.env.SHOPIFY_STOREFRONT_ACCESS_TOKEN!;
const adminAccessToken = process.env.SHOPIFY_ADMIN_API_ACCESS_TOKEN!;
@@ -601,15 +604,17 @@ function reshapeOrder(shopifyOrder: ShopifyOrder): Order {
const orderTransactions: Transaction[] = shopifyOrder.transactions?.map((transaction) => ({
processedAt: transaction.processedAt,
paymentIcon: {
- url: transaction.paymentIcon.url,
- altText: transaction.paymentIcon.altText,
+ url: transaction.paymentIcon?.url || placeholderPaymentIcon,
+ altText: transaction.paymentIcon?.altText || 'Payment Icon',
width: 100,
height: 100
},
- paymentDetails: {
- last4: transaction.paymentDetails.last4,
- cardBrand: transaction.paymentDetails.cardBrand
- },
+ paymentDetails: transaction.paymentDetails
+ ? {
+ last4: transaction.paymentDetails.last4,
+ cardBrand: transaction.paymentDetails.cardBrand
+ }
+ : undefined,
transactionAmount: reshapeMoney(transaction.transactionAmount.presentmentMoney)!
}));
@@ -646,7 +651,17 @@ function reshapeOrder(shopifyOrder: ShopifyOrder): Order {
warrantyActivationOdometer: shopifyOrder.warrantyActivationOdometer,
warrantyActivationSelfInstall: shopifyOrder.warrantyActivationSelfInstall,
warrantyActivationVIN: shopifyOrder.warrantyActivationVIN,
- orderConfirmation: shopifyOrder.orderConfirmation
+ orderConfirmation: shopifyOrder.orderConfirmation,
+ coreReturnStatus: shopifyOrder.coreReturnStatus,
+ coreReturnDeadline: shopifyOrder.coreReturnDeadline,
+ coreReturnName: shopifyOrder.coreReturnName,
+ coreReturnAddress: shopifyOrder.coreReturnAddress,
+ coreReturnEmail: shopifyOrder.coreReturnEmail,
+ coreReturnPhone: shopifyOrder.coreReturnPhone,
+ coreReturnCity: shopifyOrder.coreReturnCity,
+ coreReturnState: shopifyOrder.coreReturnState,
+ coreReturnZip: shopifyOrder.coreReturnZip,
+ coreReturnDescription: shopifyOrder.coreReturnDescription
};
if (shopifyOrder.customer) {
diff --git a/lib/shopify/types.ts b/lib/shopify/types.ts
index 3f182aedf..c46f4fd70 100644
--- a/lib/shopify/types.ts
+++ b/lib/shopify/types.ts
@@ -115,7 +115,7 @@ export type Fulfillment = {
export type Transaction = {
processedAt: string;
paymentIcon: Image;
- paymentDetails: {
+ paymentDetails?: {
last4: string;
cardBrand: string;
};
@@ -206,8 +206,8 @@ type ShopifyShippingLine = {
type ShopifyOrderTransaction = {
id: string;
processedAt: string;
- paymentIcon: ShopifyPaymentIconImage;
- paymentDetails: ShopifyCardPaymentDetails;
+ paymentIcon: ShopifyPaymentIconImage | null;
+ paymentDetails: ShopifyCardPaymentDetails | null;
transactionAmount: ShopifyMoneyBag;
giftCardDetails: ShopifyGiftCardDetails | null;
status: string;
@@ -901,6 +901,14 @@ export enum WarrantyStatus {
LimitedActivated = 'Limited Activation'
}
+export enum CoreReturnStatus {
+ CoreNeeded = 'Core Needed',
+ PickupRequested = 'Pickup Requested',
+ BOLCreated = 'BOL Created',
+ CoreReceived = 'Core Received',
+ CoreRefunded = 'Core Refunded'
+}
+
export type ShopifyOrderMetafield = {
orderConfirmation: ShopifyMetafield | null;
warrantyStatus: ShopifyMetafield | null;
@@ -910,6 +918,16 @@ export type ShopifyOrderMetafield = {
warrantyActivationSelfInstall: ShopifyMetafield | null;
warrantyActivationVIN: ShopifyMetafield | null;
warrantyActivationMileage: ShopifyMetafield | null;
+ coreReturnStatus: ShopifyMetafield | null;
+ coreReturnDeadline: ShopifyMetafield | null;
+ coreReturnName: ShopifyMetafield | null;
+ coreReturnAddress: ShopifyMetafield | null;
+ coreReturnEmail: ShopifyMetafield | null;
+ coreReturnPhone: ShopifyMetafield | null;
+ coreReturnCity: ShopifyMetafield | null;
+ coreReturnState: ShopifyMetafield | null;
+ coreReturnZip: ShopifyMetafield | null;
+ coreReturnDescription: ShopifyMetafield | null;
};
export type File = {
diff --git a/lib/utils.ts b/lib/utils.ts
index 586bf338b..8344d95a2 100644
--- a/lib/utils.ts
+++ b/lib/utils.ts
@@ -8,11 +8,7 @@ export function cx(...args: ClassValue[]) {
}
export const focusInput = [
// base
- 'focus:ring-2',
- // ring color
- 'focus:ring-blue-200 focus:dark:ring-blue-700/30',
- // border color
- 'focus:border-blue-500 focus:dark:border-blue-700'
+ 'focus:ring-2 focus:ring-offset-4'
];
export const hasErrorInput = [