mirror of
https://github.com/vercel/commerce.git
synced 2025-05-12 20:57:51 +00:00
Fix sos page
This commit is contained in:
parent
95a77f1cb8
commit
f571d7fab3
83
app/sos/NewProductHelpComponent.tsx
Normal file
83
app/sos/NewProductHelpComponent.tsx
Normal file
@ -0,0 +1,83 @@
|
||||
"use client"
|
||||
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Combox } from "components/combox";
|
||||
import { ProductSKUs } from "components/product/sku-generator";
|
||||
import { collectionsSKUs, garmentHandleKeys } from "constants/sku";
|
||||
import { capitalizeFirstLetter, copyText } from "lib/helpers/actions";
|
||||
import { useMemo, useState } from "react";
|
||||
|
||||
|
||||
|
||||
// type SKUSelectorState = {
|
||||
// garment?: keyof typeof garmentHandleKeys,
|
||||
// collection?: keyof typeof collectionsSKUs,
|
||||
// };
|
||||
|
||||
export function NewProductHelpComponent() {
|
||||
// const [open, setOpen] = useState(false)
|
||||
const [collection, setCollection] = useState<keyof typeof collectionsSKUs | null>(null);
|
||||
// TODO: preselect tshirt
|
||||
const [garment, setGarment] = useState<keyof typeof garmentHandleKeys | null>(null);
|
||||
// const [title, setTitle] = useState<string | null>(null);
|
||||
const [number, setNumber] = useState<string | null>(null);
|
||||
|
||||
const title = useMemo(() => {
|
||||
const title = collection && garment && `${capitalizeFirstLetter(collection)}scape No.${number} ${garment}`;
|
||||
console.log("🍓🍋🍊 title", title);
|
||||
return title;
|
||||
}, [collection, garment, number]);
|
||||
|
||||
const garmentOptions = Object.entries(garmentHandleKeys).map(([fullGarmentName, garmentHandle]) => ({
|
||||
label: fullGarmentName as keyof typeof garmentHandleKeys,
|
||||
key: fullGarmentName as keyof typeof garmentHandleKeys,
|
||||
}))
|
||||
const collectionOptions = Object.entries(collectionsSKUs).map(([scape, scapeNumber]) => ({
|
||||
label: scape as keyof typeof collectionsSKUs,
|
||||
key: scape as keyof typeof collectionsSKUs
|
||||
}))
|
||||
|
||||
return (
|
||||
<div className="m-20">
|
||||
<div className="grid grid-cols-5">
|
||||
<div className="py-6 col-span-4 col-start-2">
|
||||
<p className="title">New Product Creator</p>
|
||||
</div>
|
||||
<div className="py-6 col-span-1 col-start-2">
|
||||
<Combox
|
||||
options={collectionOptions}
|
||||
onShow={(key: string): void => setCollection(key as keyof typeof collectionsSKUs)}
|
||||
currentKey={collection || null} />
|
||||
</div>
|
||||
<div className="pt-6 mx-30 col-span-1 col-start-3 flex justify-center items-start">
|
||||
<Input
|
||||
className="w-2/3"
|
||||
type="number"
|
||||
placeholder="No."
|
||||
onChange={(e) => setNumber(e.target.value)} />
|
||||
</div>
|
||||
<div className="pt-6 col-span-1 col-start-4">
|
||||
<Combox
|
||||
options={garmentOptions}
|
||||
onShow={(key: string): void => setGarment(key as keyof typeof garmentHandleKeys)}
|
||||
currentKey={garment || null} />
|
||||
</div>
|
||||
|
||||
{garment && collection && number && title &&
|
||||
<>
|
||||
<div className="pb-6 col-span-3 col-start-2">
|
||||
<div
|
||||
className="border p-2 px-4 cursor-pointer"
|
||||
onClick={() => copyText(title)}
|
||||
>
|
||||
{title}
|
||||
</div>
|
||||
</div>
|
||||
<div className="my-5 col-span-5">
|
||||
<ProductSKUs productTitle={title} noTitle={true} />
|
||||
</div>
|
||||
</>}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
@ -1,97 +1,6 @@
|
||||
// make a page where you can select from garment types, collection types and numbers to create a copyable name
|
||||
"use client"
|
||||
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Combox } from "components/combox";
|
||||
import { ProductSKUs } from "components/product/sku-generator";
|
||||
import { collectionsSKUs, garmentHandleKeys } from "constants/sku";
|
||||
import { capitalizeFirstLetter, copyText } from "lib/helpers/actions";
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
// type SKUSelectorState = {
|
||||
// garment?: keyof typeof garmentHandleKeys,
|
||||
// collection?: keyof typeof collectionsSKUs,
|
||||
// };
|
||||
import { NewProductHelpComponent } from "./NewProductHelpComponent"
|
||||
|
||||
export default async function NewProductHelpPage() {
|
||||
// const [open, setOpen] = useState(false)
|
||||
const [collection, setCollection] = useState<keyof typeof collectionsSKUs | null>(null)
|
||||
const [garment, setGarment] = useState<keyof typeof garmentHandleKeys | null>(null)
|
||||
const [title, setTitle] = useState<string | null>(null)
|
||||
const [number, setNumber] = useState<string | null>(null)
|
||||
return <NewProductHelpComponent/>
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
const title = createTitle()
|
||||
console.log("🍓🍋🍊 title", title);
|
||||
|
||||
}, [collection, garment])
|
||||
|
||||
const garmentValues = Object.keys(garmentHandleKeys)
|
||||
const collectionValues = Object.keys(collectionsSKUs)
|
||||
|
||||
const optionsMapper = (keys: {}, values: string[]) => {
|
||||
return values.map(value => {
|
||||
return {
|
||||
key: keys[value as keyof typeof keys],
|
||||
label: value,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const garmentOptions = optionsMapper(garmentHandleKeys, garmentValues);
|
||||
const collectionOptions = optionsMapper(collectionsSKUs, collectionValues);
|
||||
|
||||
const createTitle = () => {
|
||||
setTitle(collection && garment && `${capitalizeFirstLetter(collection)}scape No.${number} ${garment}`)
|
||||
}
|
||||
|
||||
|
||||
|
||||
return (
|
||||
<div className="m-20">
|
||||
<div className="grid grid-cols-5">
|
||||
<div className="py-6 col-span-4 col-start-2">
|
||||
<p className="title">New Product Creator</p>
|
||||
</div>
|
||||
<div className="py-6 col-span-1 col-start-2">
|
||||
<Combox
|
||||
options={collectionOptions}
|
||||
onShow={(key: string): void => setCollection(key as keyof typeof collectionsSKUs)}
|
||||
currentKey={collection || null}
|
||||
/>
|
||||
</div>
|
||||
<div className="pt-6 mx-30 col-span-1 col-start-3 flex justify-center items-start">
|
||||
<Input
|
||||
className="w-2/3"
|
||||
type="number"
|
||||
placeholder="No."
|
||||
onChange={(e) => setNumber(e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
<div className="pt-6 col-span-1 col-start-4">
|
||||
<Combox
|
||||
options={garmentOptions}
|
||||
onShow={(key: string): void => setGarment(key as keyof typeof garmentHandleKeys)}
|
||||
currentKey={garment || null}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{garment && collection && number && title &&
|
||||
<>
|
||||
<div className="pb-6 col-span-3 col-start-2">
|
||||
<div
|
||||
className="border p-2 px-4 cursor-pointer"
|
||||
onClick={() => copyText(title)}
|
||||
>
|
||||
{title}
|
||||
</div>
|
||||
</div>
|
||||
<div className="my-5 col-span-5">
|
||||
<ProductSKUs productTitle={title} noTitle={true} />
|
||||
</div>
|
||||
</>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
@ -49,16 +49,16 @@ export default async function Footer() {
|
||||
</div> */}
|
||||
</div>
|
||||
<div className="border-t border-neutral-200 py-6 text-sm dark:border-neutral-700">
|
||||
<div className="mx-auto flex w-full max-w-7xl flex-col items-center gap-1 md:flex-row md:gap-0">
|
||||
<div className="mx-auto flex w-full max-w-7xl flex-col items-center gap-1 md:flex-row md:gap-0 pl-4">
|
||||
<p>
|
||||
© {copyrightDate} {copyrightName}
|
||||
{copyrightName.length && !copyrightName.endsWith('.') ? '.' : ''} All rights reserved.
|
||||
</p>
|
||||
<hr className="mx-4 hidden h-4 w-[1px] border-l border-neutral-400 md:inline-block" />
|
||||
<p>Designed in England</p>
|
||||
{/* <hr className="mx-4 hidden h-4 w-[1px] border-l border-neutral-400 md:inline-block" /> */}
|
||||
{/* <p>Designed in England</p> */}
|
||||
<p className="md:ml-auto">
|
||||
Crafted by{' '}
|
||||
<Link href="https://www.instagram.com/sammiisparkle" className="text-black dark:text-white" target="_blank">
|
||||
<Link href="https://www.instagram.com/sammiisparkle" className="text-black dark:text-white pr-2" target="_blank">
|
||||
Sammii Sparkle
|
||||
</Link>
|
||||
</p>
|
||||
|
62
components/store/themeContext.tsx
Normal file
62
components/store/themeContext.tsx
Normal file
@ -0,0 +1,62 @@
|
||||
import { createContext, ReactElement, useEffect, useState } from "react";
|
||||
|
||||
const ThemeContext = createContext({
|
||||
isDarkTheme: true,
|
||||
toggleThemeHandler: () => {},
|
||||
});
|
||||
|
||||
interface ThemePropsInterface {
|
||||
children?: JSX.Element | Array<JSX.Element>;
|
||||
}
|
||||
|
||||
export function MyThemeContextProvider(
|
||||
props: ThemePropsInterface
|
||||
): ReactElement {
|
||||
const [isDarkTheme, setIsDarkTheme] = useState(true);
|
||||
useEffect(() => initialThemeHandler());
|
||||
|
||||
function isLocalStorageEmpty(): boolean {
|
||||
return !localStorage.getItem("isDarkTheme");
|
||||
}
|
||||
|
||||
function initialThemeHandler(): void {
|
||||
if (isLocalStorageEmpty()) {
|
||||
localStorage.setItem("isDarkTheme", `true`);
|
||||
document!.querySelector("body")!.classList.add("dark");
|
||||
setIsDarkTheme(true);
|
||||
} else {
|
||||
const isDarkTheme: boolean = JSON.parse(
|
||||
localStorage.getItem("isDarkTheme")!
|
||||
);
|
||||
isDarkTheme && document!.querySelector("body")!.classList.add("dark");
|
||||
setIsDarkTheme(() => {
|
||||
return isDarkTheme;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function toggleThemeHandler(): void {
|
||||
const isDarkTheme: boolean = JSON.parse(
|
||||
localStorage.getItem("isDarkTheme")!
|
||||
);
|
||||
setIsDarkTheme(!isDarkTheme);
|
||||
toggleDarkClassToBody();
|
||||
setValueToLocalStorage();
|
||||
}
|
||||
|
||||
function toggleDarkClassToBody(): void {
|
||||
document!.querySelector("body")!.classList.toggle("dark");
|
||||
}
|
||||
|
||||
function setValueToLocalStorage(): void {
|
||||
localStorage.setItem("isDarkTheme", `${!isDarkTheme}`);
|
||||
}
|
||||
|
||||
return (
|
||||
<ThemeContext.Provider value={{ isDarkTheme: true, toggleThemeHandler }}>
|
||||
{props.children}
|
||||
</ThemeContext.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
export default ThemeContext;
|
@ -3,12 +3,12 @@ export const baseArtworkNumber = '000';
|
||||
export const sizes = [ 'xxs', 'xs', 's', 'm', 'l', 'xl', 'xxl', 'xxxl' ];
|
||||
|
||||
export const garmentTypes = {
|
||||
tshirt: 'tshirt',
|
||||
cropT: 'cropT',
|
||||
hoodie: 'hoodie',
|
||||
zipHood: 'zipHood',
|
||||
crew: 'crew',
|
||||
cropCrew: 'cropCrew',
|
||||
tshirt: 'tshirt' as const,
|
||||
cropT: 'cropT' as const,
|
||||
hoodie: 'hoodie' as const,
|
||||
zipHood: 'zipHood' as const,
|
||||
crew: 'crew' as const,
|
||||
cropCrew: 'cropCrew' as const,
|
||||
};
|
||||
|
||||
export const garmentHandleKeys = {
|
||||
|
@ -25,6 +25,6 @@ export const TAGS = {
|
||||
products: 'products'
|
||||
};
|
||||
|
||||
export const HIDDEN_PRODUCT_TAG = 'nextjs-frontend-hidden';
|
||||
export const HIDDEN_PRODUCT_TAG = 'hidden-product';
|
||||
export const DEFAULT_OPTION = 'Default Title';
|
||||
export const SHOPIFY_GRAPHQL_API_ENDPOINT = '/api/2023-01/graphql.json';
|
||||
|
@ -1,13 +1,7 @@
|
||||
import { baseArtworkNumber, collectionsSKUs, colorSKUs, customisationSKUs, garmentHandleKeys, garmentSKUs, garmentSizes, sizeSKUs } from "constants/sku";
|
||||
import { collectionsSKUs, colorSKUs, customisationSKUs, garmentHandleKeys, garmentSKUs, garmentSizes, sizeSKUs } from "constants/sku";
|
||||
|
||||
type TitleInfo = Awaited<ReturnType<typeof extractInfoFromTitle>>;
|
||||
|
||||
const artworkNumberCompiler = (artworkNumber: string) => {
|
||||
const length = artworkNumber.length
|
||||
const slice = baseArtworkNumber.slice(0, length + 1)
|
||||
return slice + artworkNumber
|
||||
}
|
||||
|
||||
const garmentHandleKeyMapper = (garmentKeys: string[]) => {
|
||||
const garmentTitle = garmentKeys.join(' ');
|
||||
const garmentKey = garmentHandleKeys[garmentTitle as keyof typeof garmentHandleKeys]
|
||||
@ -30,7 +24,7 @@ const extractInfoFromTitle = (productTitle: string) => {
|
||||
|
||||
const collectionSKUMapper = (titleInfo: TitleInfo) => {
|
||||
const collectionSKU = collectionsSKUs[titleInfo.collectionKey as keyof typeof collectionsSKUs];
|
||||
const artworkSKU = artworkNumberCompiler(titleInfo.artworkNumber!);
|
||||
const artworkSKU = titleInfo.artworkNumber!.padStart(4, "0");
|
||||
const garmentSKU = garmentHandleKeyMapper(titleInfo.garmentKeys);
|
||||
|
||||
return `SCSQ${collectionSKU}${artworkSKU}_${garmentSKU}`;
|
||||
|
Loading…
x
Reference in New Issue
Block a user