mirror of
https://github.com/vercel/commerce.git
synced 2025-05-18 23:46:58 +00:00
set up admin api
Signed-off-by: Chloe <pinkcloudvnn@gmail.com>
This commit is contained in:
parent
b2efb59f5c
commit
0bf01447f6
@ -1,5 +1,5 @@
|
|||||||
import { PhotoIcon } from '@heroicons/react/24/outline';
|
import { PhotoIcon } from '@heroicons/react/24/outline';
|
||||||
import { useId } from 'react';
|
import { ChangeEvent, useId, useState } from 'react';
|
||||||
|
|
||||||
type FileInputProps = {
|
type FileInputProps = {
|
||||||
name: string;
|
name: string;
|
||||||
@ -8,6 +8,14 @@ type FileInputProps = {
|
|||||||
|
|
||||||
const FileInput = ({ name, label }: FileInputProps) => {
|
const FileInput = ({ name, label }: FileInputProps) => {
|
||||||
const id = useId();
|
const id = useId();
|
||||||
|
const [file, setFile] = useState<File | undefined>();
|
||||||
|
|
||||||
|
const onFileChange = (e: ChangeEvent<HTMLInputElement>) => {
|
||||||
|
if (e.target.files && e.target.files.length > 0) {
|
||||||
|
setFile(e.target.files[0]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-sm font-medium leading-6 text-gray-900">{label}</label>
|
<label className="block text-sm font-medium leading-6 text-gray-900">{label}</label>
|
||||||
@ -17,15 +25,16 @@ const FileInput = ({ name, label }: FileInputProps) => {
|
|||||||
<div className="mt-2 flex text-sm leading-6 text-gray-600">
|
<div className="mt-2 flex text-sm leading-6 text-gray-600">
|
||||||
<label
|
<label
|
||||||
htmlFor={id}
|
htmlFor={id}
|
||||||
className="relative cursor-pointer rounded-md bg-white font-semibold text-primary focus-within:outline-none focus-within:ring-2 focus-within:ring-indigo-600 focus-within:ring-offset-2"
|
className="relative cursor-pointer rounded-md bg-white font-semibold text-primary focus-within:outline-none focus-within:ring-2 focus-within:ring-primary/70 focus-within:ring-offset-2"
|
||||||
>
|
>
|
||||||
<span>Upload a file</span>
|
<span>Upload a file</span>
|
||||||
<input id={id} name={name} type="file" className="sr-only" />
|
<input id={id} name={name} type="file" className="sr-only" onChange={onFileChange} />
|
||||||
</label>
|
</label>
|
||||||
<p className="pl-1">or drag and drop</p>
|
<p className="pl-1">or drag and drop</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{file && <p className="mt-2 text-sm text-gray-500">{file.name}</p>}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -44,8 +44,9 @@ const MobileOrderActions = ({ order }: { order: Order }) => {
|
|||||||
<Button
|
<Button
|
||||||
className={clsx(
|
className={clsx(
|
||||||
focus ? 'bg-gray-100 text-gray-900' : 'text-gray-700',
|
focus ? 'bg-gray-100 text-gray-900' : 'text-gray-700',
|
||||||
'block px-4 py-2 text-sm'
|
'flex w-full px-4 py-2 text-sm'
|
||||||
)}
|
)}
|
||||||
|
onClick={() => setIsOpen(true)}
|
||||||
>
|
>
|
||||||
Activate Warranty
|
Activate Warranty
|
||||||
</Button>
|
</Button>
|
||||||
|
@ -36,6 +36,7 @@ export const HIDDEN_PRODUCT_TAG = 'nextjs-frontend-hidden';
|
|||||||
export const DEFAULT_OPTION = 'Default Title';
|
export const DEFAULT_OPTION = 'Default Title';
|
||||||
export const SHOPIFY_GRAPHQL_API_ENDPOINT = '/api/2024-04/graphql.json';
|
export const SHOPIFY_GRAPHQL_API_ENDPOINT = '/api/2024-04/graphql.json';
|
||||||
export const SHOPIFY_GRAPHQL_CUSTOMER_API_ENDPOINT = '/account/customer/api/2024-07/graphql';
|
export const SHOPIFY_GRAPHQL_CUSTOMER_API_ENDPOINT = '/account/customer/api/2024-07/graphql';
|
||||||
|
export const SHOPIFY_GRAPHQL_ADMIN_ADMIN_API_ENDPOINT = '/admin/api/2024-04/graphql.json';
|
||||||
|
|
||||||
export const CORE_WAIVER = 'core-waiver';
|
export const CORE_WAIVER = 'core-waiver';
|
||||||
export const CORE_VARIANT_ID_KEY = 'coreVariantId';
|
export const CORE_VARIANT_ID_KEY = 'coreVariantId';
|
||||||
|
@ -6,6 +6,7 @@ import {
|
|||||||
MODEL_FILTER_ID,
|
MODEL_FILTER_ID,
|
||||||
PRICE_FILTER_ID,
|
PRICE_FILTER_ID,
|
||||||
PRODUCT_METAFIELD_PREFIX,
|
PRODUCT_METAFIELD_PREFIX,
|
||||||
|
SHOPIFY_GRAPHQL_ADMIN_ADMIN_API_ENDPOINT,
|
||||||
SHOPIFY_GRAPHQL_API_ENDPOINT,
|
SHOPIFY_GRAPHQL_API_ENDPOINT,
|
||||||
SHOPIFY_GRAPHQL_CUSTOMER_API_ENDPOINT,
|
SHOPIFY_GRAPHQL_CUSTOMER_API_ENDPOINT,
|
||||||
TAGS,
|
TAGS,
|
||||||
@ -104,12 +105,14 @@ const customerApiUrl = process.env.SHOPIFY_CUSTOMER_ACCOUNT_API_URL;
|
|||||||
|
|
||||||
const storefrontEndpoint = `${domain}${SHOPIFY_GRAPHQL_API_ENDPOINT}`;
|
const storefrontEndpoint = `${domain}${SHOPIFY_GRAPHQL_API_ENDPOINT}`;
|
||||||
const customerEndpoint = `${customerApiUrl}/${SHOPIFY_GRAPHQL_CUSTOMER_API_ENDPOINT}`;
|
const customerEndpoint = `${customerApiUrl}/${SHOPIFY_GRAPHQL_CUSTOMER_API_ENDPOINT}`;
|
||||||
|
const adminEndpoint = `${domain}${SHOPIFY_GRAPHQL_ADMIN_ADMIN_API_ENDPOINT}`;
|
||||||
|
|
||||||
const userAgent = '*';
|
const userAgent = '*';
|
||||||
const placeholderProductImage =
|
const placeholderProductImage =
|
||||||
'https://cdn.shopify.com/shopifycloud/customer-account-web/production/assets/8bc6556601c510713d76.svg';
|
'https://cdn.shopify.com/shopifycloud/customer-account-web/production/assets/8bc6556601c510713d76.svg';
|
||||||
|
|
||||||
const key = process.env.SHOPIFY_STOREFRONT_ACCESS_TOKEN!;
|
const key = process.env.SHOPIFY_STOREFRONT_ACCESS_TOKEN!;
|
||||||
|
const adminAccessToken = process.env.SHOPIFY_ADMIN_API_ACCESS_TOKEN!;
|
||||||
|
|
||||||
type ExtractVariables<T> = T extends { variables: object } ? T['variables'] : never;
|
type ExtractVariables<T> = T extends { variables: object } ? T['variables'] : never;
|
||||||
|
|
||||||
@ -169,6 +172,56 @@ export async function shopifyFetch<T>({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function adminFetch<T>({
|
||||||
|
headers,
|
||||||
|
query,
|
||||||
|
variables
|
||||||
|
}: {
|
||||||
|
headers?: HeadersInit;
|
||||||
|
query: string;
|
||||||
|
variables?: ExtractVariables<T>;
|
||||||
|
}): Promise<{ status: number; body: T } | never> {
|
||||||
|
try {
|
||||||
|
const result = await fetch(adminEndpoint, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'X-Shopify-Access-Token': adminAccessToken,
|
||||||
|
...headers
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
...(query && { query }),
|
||||||
|
...(variables && { variables })
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
const body = await result.json();
|
||||||
|
|
||||||
|
if (body.errors) {
|
||||||
|
throw body.errors[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
status: result.status,
|
||||||
|
body
|
||||||
|
};
|
||||||
|
} catch (e) {
|
||||||
|
if (isShopifyError(e)) {
|
||||||
|
throw {
|
||||||
|
cause: e.cause?.toString() || 'unknown',
|
||||||
|
status: e.status || 500,
|
||||||
|
message: e.message,
|
||||||
|
query
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
throw {
|
||||||
|
error: e,
|
||||||
|
query
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export async function shopifyCustomerFetch<T>({
|
export async function shopifyCustomerFetch<T>({
|
||||||
query,
|
query,
|
||||||
variables
|
variables
|
||||||
|
@ -20,7 +20,8 @@ export const validateEnvironmentVariables = () => {
|
|||||||
'SHOPIFY_CUSTOMER_ACCOUNT_API_CLIENT_ID',
|
'SHOPIFY_CUSTOMER_ACCOUNT_API_CLIENT_ID',
|
||||||
'SHOPIFY_CUSTOMER_ACCOUNT_API_URL',
|
'SHOPIFY_CUSTOMER_ACCOUNT_API_URL',
|
||||||
'SHOPIFY_CUSTOMER_API_VERSION',
|
'SHOPIFY_CUSTOMER_API_VERSION',
|
||||||
'SHOPIFY_ORIGIN_URL'
|
'SHOPIFY_ORIGIN_URL',
|
||||||
|
'SHOPIFY_ADMIN_API_ACCESS_TOKEN'
|
||||||
];
|
];
|
||||||
const missingEnvironmentVariables = [] as string[];
|
const missingEnvironmentVariables = [] as string[];
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user