From d5a5072ff344863be6659e962f96855f24c12194 Mon Sep 17 00:00:00 2001 From: Guilherme da Silva Benevides Date: Mon, 28 Oct 2024 13:31:28 -0300 Subject: [PATCH] feat: setup linter --- .vscode/extensions.json | 8 + .vscode/settings.json | 16 ++ actions/minicart/submit.ts | 30 ++- apps/site.ts | 19 +- components/Icons/IconChevronsDown.tsx | 29 ++- components/Icons/IconChevronsUp.tsx | 29 ++- components/Icons/IconMenuDrawerOpen.tsx | 32 ++- components/Icons/IconMinus.tsx | 17 +- components/Icons/IconPlus.tsx | 25 ++- components/Icons/IconUser.tsx | 25 ++- components/Session.tsx | 128 ++++++++--- components/header/Bag.tsx | 15 +- components/header/BenefitBar.tsx | 15 +- components/header/GeolocationOffers/index.tsx | 146 ++++++++---- components/header/HeaderDesktop.tsx | 18 +- components/header/HeaderMobile.tsx | 26 ++- components/header/Links.tsx | 6 +- components/header/MenuMobile.tsx | 63 +++--- components/header/MenuMobileDetails.tsx | 17 +- components/header/NavItem.tsx | 49 +++- components/header/Search.tsx | 48 ++-- components/header/SignIn.tsx | 28 ++- components/minicart/Coupon.tsx | 98 ++++++-- .../minicart/FreeShippingProgressBar.tsx | 27 ++- components/minicart/Item.tsx | 40 +++- components/minicart/Minicart.tsx | 163 +++++++++----- components/minicart/MinicartEmpty.tsx | 19 +- components/minicart/MinicartFooter.tsx | 71 +++++- components/minicart/Seller.tsx | 46 +++- components/minicart/Shipping.tsx | 107 ++++++--- components/search/SearchResult.tsx | 211 +++++++++++------- components/search/Searchbar/Form.tsx | 61 ++++- .../search/Searchbar/ProductCardSearch.tsx | 74 +++++- .../search/Searchbar/RenderProductsResult.tsx | 29 ++- components/search/Searchbar/Suggestions.tsx | 47 +++- components/search/Searchbar/TopSearchs.tsx | 51 ++++- components/ui/Button.tsx | 114 ++++++++-- components/ui/Drawer/index.tsx | 39 +++- components/ui/Drawer/islands.tsx | 39 +++- components/ui/Icon.tsx | 20 +- components/ui/Input.tsx | 16 +- components/ui/Modal.tsx | 5 +- components/ui/QuantitySelector.tsx | 61 ++++- deno.json | 9 +- loaders/geolocation.ts | 15 +- sdk/cart/vtex/loader.ts | 9 +- sdk/cart/vtex/submit.ts | 63 ++++-- sdk/cart/vtex/utils/cartFrom.ts | 15 +- sdk/cart/vtex/utils/loadSizes.ts | 18 +- sections/Header/Header.tsx | 48 +++- 50 files changed, 1769 insertions(+), 535 deletions(-) create mode 100644 .vscode/extensions.json create mode 100644 .vscode/settings.json diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..6a33f51 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,8 @@ +{ + "recommendations": [ + "ecmel.vscode-html-css", + "tobermory.es6-string-html", + "denoland.vscode-deno", + "bradlc.vscode-tailwindcss" + ] +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..3ca03b1 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,16 @@ +{ + "deno.enable": true, + "editor.quickSuggestions": { + "strings": true + }, + "editor.defaultFormatter": "denoland.vscode-deno", + "[json]": { + "editor.defaultFormatter": "denoland.vscode-deno" + }, + "[typescriptreact]": { + "editor.defaultFormatter": "denoland.vscode-deno" + }, + "[typescript]": { + "editor.defaultFormatter": "denoland.vscode-deno" + } +} diff --git a/actions/minicart/submit.ts b/actions/minicart/submit.ts index 7134ab1..fb3e12d 100644 --- a/actions/minicart/submit.ts +++ b/actions/minicart/submit.ts @@ -30,10 +30,22 @@ interface CartFormData { export interface CartSubmitActions { addToCart?: (props: CartFormData, req: Request, ctx: AC) => Promise; - setQuantity?: (props: CartFormData, req: Request, ctx: AC) => Promise; + setQuantity?: ( + props: CartFormData, + req: Request, + ctx: AC, + ) => Promise; setCoupon?: (props: CartFormData, req: Request, ctx: AC) => Promise; - setSellerCode?: (props: CartFormData, req: Request, ctx: AC) => Promise; - setShipping?: (props: CartFormData, req: Request, ctx: AC) => Promise; + setSellerCode?: ( + props: CartFormData, + req: Request, + ctx: AC, + ) => Promise; + setShipping?: ( + props: CartFormData, + req: Request, + ctx: AC, + ) => Promise; } const safeParse = (payload: string | null) => { @@ -90,13 +102,21 @@ const formActionsToCartActions: Record = { "set-shipping": "setShipping", }; -async function action(_props: unknown, req: Request, ctx: AppContext): Promise { +async function action( + _props: unknown, + req: Request, + ctx: AppContext, +): Promise { const platformActions = actions[usePlatform()] as CartSubmitActions; const form = cartFrom((await req.formData()) as unknown as FormData); const action = form.action as string | null; - const decoActionName = action === null ? "setQuantity" : action in formActionsToCartActions ? formActionsToCartActions[action] : "setQuantity"; + const decoActionName = action === null + ? "setQuantity" + : action in formActionsToCartActions + ? formActionsToCartActions[action] + : "setQuantity"; const handler = platformActions[decoActionName]; if (!handler) { diff --git a/apps/site.ts b/apps/site.ts index 63ed5d0..2650dac 100644 --- a/apps/site.ts +++ b/apps/site.ts @@ -19,7 +19,14 @@ export interface Props extends WebsiteProps { platform: Platform; theme?: Section; } -export type Platform = "vtex" | "vnda" | "shopify" | "wake" | "linx" | "nuvemshop" | "custom"; +export type Platform = + | "vtex" + | "vnda" + | "shopify" + | "wake" + | "linx" + | "nuvemshop" + | "custom"; export let _platform: Platform = "vtex"; export type App = ReturnType; // @ts-ignore somehow deno task check breaks, I have no idea why @@ -51,12 +58,18 @@ let firstRun = true; * @category Tool * @logo https://ozksgdmyrqcxcwhnbepg.supabase.co/storage/v1/object/public/assets/1/0ac02239-61e6-4289-8a36-e78c0975bcc8 */ -export default function Site({ ...state }: Props): A]> { +export default function Site( + { ...state }: Props, +): A]> { _platform = state.platform || "custom"; // Prevent console.logging twice if (firstRun) { firstRun = false; - console.info(` ${rgb24("Storefront", color("deco"))} | ${rgb24(_platform, color(_platform))} \n`); + console.info( + ` ${rgb24("Storefront", color("deco"))} | ${ + rgb24(_platform, color(_platform)) + } \n`, + ); } return { state, diff --git a/components/Icons/IconChevronsDown.tsx b/components/Icons/IconChevronsDown.tsx index 4d5b646..0eaa778 100644 --- a/components/Icons/IconChevronsDown.tsx +++ b/components/Icons/IconChevronsDown.tsx @@ -4,11 +4,32 @@ interface Props { strokeWidth?: number; } -export function IconCheveronsDown({ className, strokeClassName, strokeWidth }: Props) { +export function IconCheveronsDown( + { className, strokeClassName, strokeWidth }: Props, +) { return ( - - - + + + ); } diff --git a/components/Icons/IconChevronsUp.tsx b/components/Icons/IconChevronsUp.tsx index 447907a..fa52a8f 100644 --- a/components/Icons/IconChevronsUp.tsx +++ b/components/Icons/IconChevronsUp.tsx @@ -4,11 +4,32 @@ interface Props { strokeWidth?: number; } -export function IconCheveronsUp({ className, strokeClassName, strokeWidth }: Props) { +export function IconCheveronsUp( + { className, strokeClassName, strokeWidth }: Props, +) { return ( - - - + + + ); } diff --git a/components/Icons/IconMenuDrawerOpen.tsx b/components/Icons/IconMenuDrawerOpen.tsx index 45d7195..3338b86 100644 --- a/components/Icons/IconMenuDrawerOpen.tsx +++ b/components/Icons/IconMenuDrawerOpen.tsx @@ -1,9 +1,33 @@ export function IconMenuDrawerOpen() { return ( - - - - + + + + ); } diff --git a/components/Icons/IconMinus.tsx b/components/Icons/IconMinus.tsx index b8f5ad2..49be4d1 100644 --- a/components/Icons/IconMinus.tsx +++ b/components/Icons/IconMinus.tsx @@ -5,8 +5,21 @@ interface Props { } export function IconMinus({ className, strokeClassName, strokeWidth }: Props) { return ( - - + + ); } diff --git a/components/Icons/IconPlus.tsx b/components/Icons/IconPlus.tsx index 3db1d6b..83db2be 100644 --- a/components/Icons/IconPlus.tsx +++ b/components/Icons/IconPlus.tsx @@ -5,9 +5,28 @@ interface Props { } export function IconPlus({ className, strokeClassName, strokeWidth }: Props) { return ( - - - + + + ); } diff --git a/components/Icons/IconUser.tsx b/components/Icons/IconUser.tsx index bf56cbf..fcf9f6b 100644 --- a/components/Icons/IconUser.tsx +++ b/components/Icons/IconUser.tsx @@ -6,9 +6,28 @@ interface Props { export function IconUser({ className = "" }: Props) { return ( - - - + + + ); } diff --git a/components/Session.tsx b/components/Session.tsx index 88980b5..79b5792 100644 --- a/components/Session.tsx +++ b/components/Session.tsx @@ -6,7 +6,10 @@ import { MINICART_DRAWER_ID } from "site/constants.ts"; import { type AppContext } from "../apps/site.ts"; import { useComponent } from "../sections/Component.tsx"; import { type Item } from "./minicart/Item.tsx"; -import CartProvider, { type Minicart, MinicartSettings } from "./minicart/Minicart.tsx"; +import CartProvider, { + type Minicart, + MinicartSettings, +} from "./minicart/Minicart.tsx"; import Drawer from "./ui/Drawer/index.tsx"; import UserProvider from "./user/Provider.tsx"; import WishlistProvider, { type Wishlist } from "./wishlist/Provider.tsx"; @@ -31,18 +34,27 @@ export interface SDK { getQuantity: (itemId: string) => number | undefined; setQuantity: (itemId: string, quantity: number) => boolean; addToCart: (item: Item, platformProps: unknown) => boolean; - subscribe: (cb: (sdk: SDK["CART"]) => void, opts?: boolean | AddEventListenerOptions) => void; + subscribe: ( + cb: (sdk: SDK["CART"]) => void, + opts?: boolean | AddEventListenerOptions, + ) => void; dispatch: (form: HTMLFormElement) => void; }; USER: { getUser: () => Person | null; - subscribe: (cb: (sdk: SDK["USER"]) => void, opts?: boolean | AddEventListenerOptions) => void; + subscribe: ( + cb: (sdk: SDK["USER"]) => void, + opts?: boolean | AddEventListenerOptions, + ) => void; dispatch: (person: Person) => void; }; WISHLIST: { toggle: (productID: string, productGroupID: string) => boolean; inWishlist: (productID: string) => boolean; - subscribe: (cb: (sdk: SDK["WISHLIST"]) => void, opts?: boolean | AddEventListenerOptions) => void; + subscribe: ( + cb: (sdk: SDK["WISHLIST"]) => void, + opts?: boolean | AddEventListenerOptions, + ) => void; dispatch: (form: HTMLFormElement) => void; }; } @@ -51,16 +63,28 @@ const sdk = () => { const target = new EventTarget(); const createCartSDK = (): SDK["CART"] => { let form: HTMLFormElement | null = null; - const getCart = (): Cart => form && JSON.parse(decodeURIComponent(form.querySelector('input[name="storefront-cart"]')?.value || "[]")); + const getCart = (): Cart => + form && + JSON.parse( + decodeURIComponent( + form.querySelector('input[name="storefront-cart"]') + ?.value || "[]", + ), + ); const sdk: SDK["CART"] = { getCart, - getQuantity: (itemId) => form?.querySelector(`[data-item-id="${itemId}"] input[type="number"]`)?.valueAsNumber, + getQuantity: (itemId) => + form?.querySelector( + `[data-item-id="${itemId}"] input[type="number"]`, + )?.valueAsNumber, setQuantity: (itemId, quantity) => { - const input = form?.querySelector(`[data-item-id="${itemId}"] input[type="number"]`); + const input = form?.querySelector( + `[data-item-id="${itemId}"] input[type="number"]`, + ); const item = getCart()?.items.find( (item) => // deno-lint-ignore no-explicit-any - (item as any).item_id === itemId + (item as any).item_id === itemId, ); if (!input || !item) { return false; @@ -68,7 +92,9 @@ const sdk = () => { input.value = quantity.toString(); if (input.validity.valid) { window.DECO.events.dispatch({ - name: item.quantity < input.valueAsNumber ? "add_to_cart" : "remove_from_cart", + name: item.quantity < input.valueAsNumber + ? "add_to_cart" + : "remove_from_cart", params: { items: [{ ...item, quantity }] }, }); input.dispatchEvent(new Event("change", { bubbles: true })); @@ -76,8 +102,12 @@ const sdk = () => { return true; }, addToCart: (item, platformProps) => { - const input = form?.querySelector('input[name="add-to-cart"]'); - const button = form?.querySelector(`button[name="action"][value="add-to-cart"]`); + const input = form?.querySelector( + 'input[name="add-to-cart"]', + ); + const button = form?.querySelector( + `button[name="action"][value="add-to-cart"]`, + ); if (!input || !button) { return false; } @@ -117,19 +147,18 @@ const sdk = () => { sendEvent(e.currentTarget as HTMLElement | null); } // Only available on newer safari versions - const handleView = - typeof IntersectionObserver !== "undefined" - ? new IntersectionObserver((items) => { - for (const item of items) { - const { isIntersecting, target } = item; - if (!isIntersecting) { - continue; - } - handleView!.unobserve(target); - sendEvent(target); - } - }) - : null; + const handleView = typeof IntersectionObserver !== "undefined" + ? new IntersectionObserver((items) => { + for (const item of items) { + const { isIntersecting, target } = item; + if (!isIntersecting) { + continue; + } + handleView!.unobserve(target); + sendEvent(target); + } + }) + : null; document.body.addEventListener("htmx:load", (e) => ( e as unknown as { @@ -152,8 +181,7 @@ const sdk = () => { handleView?.observe(node); return; } - }) - ); + })); }); }; const createUserSDK = () => { @@ -180,8 +208,10 @@ const sdk = () => { console.error("Missing wishlist Provider"); return false; } - form.querySelector('input[name="product-id"]')!.value = productID; - form.querySelector('input[name="product-group-id"]')!.value = productGroupID; + form.querySelector('input[name="product-id"]')! + .value = productID; + form.querySelector('input[name="product-group-id"]')! + .value = productGroupID; form.querySelector("button")?.click(); return true; }, @@ -192,8 +222,12 @@ const sdk = () => { }, dispatch: (f: HTMLFormElement) => { form = f; - const script = f.querySelector('script[type="application/json"]'); - const wishlist: Wishlist | null = script ? JSON.parse(script.innerText) : null; + const script = f.querySelector( + 'script[type="application/json"]', + ); + const wishlist: Wishlist | null = script + ? JSON.parse(script.innerText) + : null; productIDs = new Set(wishlist?.productIDs); target.dispatchEvent(new Event("wishlist")); }, @@ -213,9 +247,13 @@ export const action = async ( minicartSettings: MinicartSettings; }, _req: Request, - ctx: AppContext + ctx: AppContext, ) => { - const [minicart, wishlist, user] = await Promise.all([ctx.invoke("site/loaders/minicart.ts"), ctx.invoke("site/loaders/wishlist.ts"), ctx.invoke("site/loaders/user.ts")]); + const [minicart, wishlist, user] = await Promise.all([ + ctx.invoke("site/loaders/minicart.ts"), + ctx.invoke("site/loaders/wishlist.ts"), + ctx.invoke("site/loaders/user.ts"), + ]); return { mode: "eager", minicart, @@ -225,7 +263,11 @@ export const action = async ( }; }; -export const loader = ({ minicartEmpty, freeShippingBarSettings, ...otherProps }: MinicartSettings, _req: Request, _ctx: AppContext) => { +export const loader = ( + { minicartEmpty, freeShippingBarSettings, ...otherProps }: MinicartSettings, + _req: Request, + _ctx: AppContext, +) => { return { ...otherProps, minicartClientSettings: { @@ -244,12 +286,17 @@ export interface Props { mode?: "eager" | "lazy"; } -export default function Session({ minicart, wishlist, user, mode = "lazy", ...props }: Props) { +export default function Session( + { minicart, wishlist, user, mode = "lazy", ...props }: Props, +) { if (mode === "lazy") { return ( <> -