Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/28719/minicart #2

Merged
merged 10 commits into from
Oct 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 30 additions & 35 deletions .deco/blocks/Header.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,23 +18,39 @@
},
"__resolveType": "resolved"
},
"mostSellerTerms": [
"Vestidos Estampados",
"Conjuntinhos",
"Camisetas",
"Bonecas"
]
"mostSellerTerms": ["Vestidos Estampados", "Conjuntinhos", "Camisetas", "Bonecas"]
},
"alerts": [
"<p>Get 10% off today: <strong>NEW10</strong></p>"
],
"alerts": ["<p>Get 10% off today: <strong>NEW10</strong></p>"],
"logo": {
"src": "https://deco-sites-assets.s3.sa-east-1.amazonaws.com/alphabeto/e30a75c7-a480-4ecb-828e-e76c39805c71/svgviewer-output-(21).svg",
"alt": "Logo Alphabeto",
"width": 138,
"height": 42
},
"loading": "eager",
"links": [
{
"href": "/",
"title": "Fale com as fadinhas"
},
{
"title": "Troca fácil",
"href": "/"
},
{
"title": "Seja um franqueado",
"href": "/"
},
{
"title": "Seja um revendedor",
"href": " /"
}
],
"benefits": {
"alerts": [],
"benefits": ["<p>Frete fixo de R$ 9,90</p>", "<p>Item 2</p>"],
"interval": 5
},
"navItems": [
{
"submenu": [],
Expand Down Expand Up @@ -166,30 +182,9 @@
"menuItem": "Bazar"
}
],
"links": [
{
"href": "/",
"title": "Fale com as fadinhas"
},
{
"title": "Troca fácil",
"href": "/"
},
{
"title": "Seja um franqueado",
"href": "/"
},
{
"title": "Seja um revendedor",
"href": " /"
}
],
"benefits": {
"alerts": [],
"benefits": [
"<p>Frete fixo de R$ 9,90</p>",
"<p>Item 2</p>"
],
"interval": 5
"googleMapsApiKey": {
"__resolveType": "website/loaders/secret.ts",
"name": "GOOGLE_MAPS_API_KEY",
"encrypted": "6187760b6f56eccaa52720e22e451805632cc03d6aa6896a5dded87ccdaafc77c37cda5bfbd5ef05c358635ab0ba12fb"
}
}
}
24 changes: 11 additions & 13 deletions .deco/blocks/pages-home-c4bcbfb771e9.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,20 +47,18 @@
"preload": true
},
{
"__resolveType": "website/sections/Rendering/Lazy.tsx",
"section": {
"__resolveType": "site/sections/Product/ProductShelf.tsx",
"products": {
"__resolveType": "vtex/loaders/workflow/products.ts",
"page": 3,
"pagesize": 1,
"props": {
"sort": "OrderByPriceDESC",
"term": "vestido",
"count": 7
}
"__resolveType": "site/sections/Product/ProductShelf.tsx",
"products": {
"__resolveType": "vtex/loaders/intelligentSearch/productList.ts",
"page": 3,
"pagesize": 1,
"props": {
"sort": "price:desc",
"collection": "773",
"count": 16
}
}
},
"title": "Nossos Queridinhos"
},
{
"__resolveType": "website/sections/Rendering/Lazy.tsx",
Expand Down
38 changes: 29 additions & 9 deletions actions/minicart/submit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,22 @@ const actions: Record<string, CartSubmitActions> = {
nuvemshop: nuvemshop as CartSubmitActions,
};

interface CartForm {
interface CartFormData {
items: number[];
coupon: string | null;
action: string | null;
platformCart: unknown;
addToCart: unknown;
sellerCode: string | null;
cep: string | null;
}

export interface CartSubmitActions<AC = unknown> {
addToCart?: (props: CartForm, req: Request, ctx: AC) => Promise<Minicart>;
setQuantity?: (props: CartForm, req: Request, ctx: AC) => Promise<Minicart>;
setCoupon?: (props: CartForm, req: Request, ctx: AC) => Promise<Minicart>;
setSellerCode?: (props: CartForm, req: Request, ctx: AC) => Promise<Minicart>;
addToCart?: (props: CartFormData, req: Request, ctx: AC) => Promise<Minicart>;
setQuantity?: (props: CartFormData, req: Request, ctx: AC) => Promise<Minicart>;
setCoupon?: (props: CartFormData, req: Request, ctx: AC) => Promise<Minicart>;
setSellerCode?: (props: CartFormData, req: Request, ctx: AC) => Promise<Minicart>;
setShipping?: (props: CartFormData, req: Request, ctx: AC) => Promise<Minicart>;
}

const safeParse = (payload: string | null) => {
Expand All @@ -42,15 +44,20 @@ const safeParse = (payload: string | null) => {
}
};

interface FormData {
entries: () => IterableIterator<[string, string]>;
}

// Reconstruct the cart state from the received form data
const cartFrom = (form: FormData) => {
const cart: CartForm = {
const cart: CartFormData = {
items: [],
coupon: null,
platformCart: null,
action: null,
addToCart: null,
sellerCode: null,
cep: null,
};

for (const [name, value] of form.entries()) {
Expand All @@ -67,22 +74,35 @@ const cartFrom = (form: FormData) => {
cart.items[Number(it)] = Number(value);
} else if (name === "add-to-cart") {
cart.addToCart = safeParse(decodeURIComponent(value.toString()));
} else if (name === "cep") {
cart.cep = value.toString();
}
}

return cart;
};

const formActionsToCartActions: Record<string, keyof CartSubmitActions> = {
"set-coupon": "setCoupon",
"add-to-cart": "addToCart",
"set-seller-code": "setSellerCode",
"set-quantity": "setQuantity",
"set-shipping": "setShipping",
};

async function action(_props: unknown, req: Request, ctx: AppContext): Promise<Minicart> {
const { setQuantity, setCoupon, addToCart, setSellerCode } = actions[usePlatform()];
const platformActions = actions[usePlatform()] as CartSubmitActions;

const form = cartFrom(await req.formData());
const form = cartFrom((await req.formData()) as unknown as FormData);
const action = form.action as string | null;

const handler = form.action === "set-coupon" ? setCoupon : form.action === "add-to-cart" ? addToCart : form.action === "set-seller-code" ? setSellerCode : setQuantity;
const decoActionName = action === null ? "setQuantity" : action in formActionsToCartActions ? formActionsToCartActions[action] : "setQuantity";
const handler = platformActions[decoActionName];

if (!handler) {
throw new Error(`Unsupported action on platform ${usePlatform()}`);
}

return await handler(form, req, ctx);
}

Expand Down
29 changes: 7 additions & 22 deletions apps/site.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { type App as A, type AppContext as AC } from "@deco/deco";
import { type Section } from "@deco/deco/blocks";
import commerce from "apps/commerce/mod.ts";
import { color as linx } from "apps/linx/mod.ts";
import { color as nuvemshop } from "apps/nuvemshop/mod.ts";
Expand All @@ -8,8 +10,6 @@ import { color as wake } from "apps/wake/mod.ts";
import { Props as WebsiteProps } from "apps/website/mod.ts";
import { rgb24 } from "std/fmt/colors.ts";
import manifest, { Manifest } from "../manifest.gen.ts";
import { type Section } from "@deco/deco/blocks";
import { type App as A, type AppContext as AC } from "@deco/deco";
export interface Props extends WebsiteProps {
/**
* @title Active Commerce Platform
Expand All @@ -19,15 +19,8 @@ export interface Props extends WebsiteProps {
platform: Platform;
theme?: Section;
}
export type Platform =
| "vtex"
| "vnda"
| "shopify"
| "wake"
| "linx"
| "nuvemshop"
| "custom";
export let _platform: Platform = "custom";
export type Platform = "vtex" | "vnda" | "shopify" | "wake" | "linx" | "nuvemshop" | "custom";
export let _platform: Platform = "vtex";
export type App = ReturnType<typeof Site>;
// @ts-ignore somehow deno task check breaks, I have no idea why
export type AppContext = AC<App>;
Expand Down Expand Up @@ -58,25 +51,17 @@ 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<Manifest, Props, [
ReturnType<typeof commerce>,
]> {
export default function Site({ ...state }: Props): A<Manifest, Props, [ReturnType<typeof commerce>]> {
_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,
manifest,
dependencies: [
commerce(state),
],
dependencies: [commerce(state)],
};
}
export { onBeforeResolveProps, Preview } from "apps/website/mod.ts";
9 changes: 7 additions & 2 deletions components/Session.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,22 @@
import { Head } from "$fresh/runtime.ts";
import { useScript } from "@deco/deco/hooks";
import { type Person } from "apps/commerce/types.ts";
import * as Htmx from "npm:htmx.org";
import { MINICART_DRAWER_ID } from "site/constants.ts";
import { type AppContext } from "../apps/site.ts";
import { MINICART_DRAWER_ID } from "../constants.ts";
import { useComponent } from "../sections/Component.tsx";
import { type Item } from "./minicart/Item.tsx";
import CartProvider, { type Minicart, MinicartSettings } from "./minicart/Minicart.tsx";
import Drawer from "./ui/Drawer.tsx";
import Drawer from "./ui/Drawer/index.tsx";
import UserProvider from "./user/Provider.tsx";
import WishlistProvider, { type Wishlist } from "./wishlist/Provider.tsx";

declare global {
const htmx: typeof Htmx;

interface Window {
STOREFRONT: SDK;
htmx: typeof Htmx;
}
}
export interface Cart {
Expand Down
Loading
Loading