Skip to content

Commit

Permalink
Merge branch 'feat/myaccountvtex' of https://github.com/deco-cx/apps
Browse files Browse the repository at this point in the history
…into feat/myaccountvtex
  • Loading branch information
vitoUwu committed Oct 3, 2024
2 parents 0cdc0c2 + 9245e39 commit 904ad6c
Show file tree
Hide file tree
Showing 8 changed files with 372 additions and 50 deletions.
22 changes: 22 additions & 0 deletions commerce/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -409,7 +409,29 @@ export interface Person extends Omit<Thing, "@type"> {
image?: ImageObject[] | null;
/** The Tax / Fiscal ID of the organization or person, e.g. the TIN in the US or the CIF/NIF in Spain. */
taxID?: string;
/** The telephone number. */
telephone?: string;
/** The birth date of the person. */
birthDate?: string;
/** User's corporate name */
corporateName?: string;
/** User's corporate document */
corporateDocument?: string;
/** User's corporate trade name */
tradeName?: string;
/** User's business phone */
businessPhone?: string;
/** Whether the user is a corporation or not */
isCorporate?: boolean;
/** Custom fields */
customFields?: CustomFields[];
}

interface CustomFields {
key: string;
value: string;
}

// NON SCHEMA.ORG Compliant. Should be removed ASAP
export interface Author extends Omit<Thing, "@type"> {
"@type": "Author";
Expand Down
60 changes: 60 additions & 0 deletions vtex/actions/profile/newsletterProfile.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { AppContext } from "../../mod.ts";
import { parseCookie } from "../../utils/vtexId.ts";

interface NewsletterInput {
email: string;
isNewsletterOptIn: boolean;
}

const newsletterProfile = async (
props: NewsletterInput,
req: Request,
ctx: AppContext,
): Promise<boolean | null> => {
const { io } = ctx;
const { cookie } = parseCookie(req.headers, ctx.account);

if (!props?.email) {
console.error("User profile not found or email is missing:", props.email);
return null;
}

const mutation = `
mutation SubscribeNewsletter($email: String!, $isNewsletterOptIn: Boolean!) {
subscribeNewsletter(email: $email, isNewsletterOptIn: $isNewsletterOptIn)
@context(provider: "[email protected]")
}
`;

const variables = {
email: props.email,
isNewsletterOptIn: props.isNewsletterOptIn,
};

try {
await io.query<{ subscribeNewsletter: boolean }, unknown>(
{
query: mutation,
operationName: "SubscribeNewsletter",
variables,
},
{
headers: {
cookie,
},
},
);

const result = await ctx.invoke("vtex/loaders/user.ts");
const newsletterField = result?.customFields?.find((field) =>
field.key === "isNewsletterOptIn"
);

return newsletterField?.value === "true";
} catch (error) {
console.error("Error subscribing to newsletter:", error);
return null;
}
};

export default newsletterProfile;
93 changes: 93 additions & 0 deletions vtex/actions/profile/updateProfile.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import { AppContext } from "../../mod.ts";
import { parseCookie } from "../../utils/vtexId.ts";
import { Person } from "../../../commerce/types.ts";
import type { User } from "../../loaders/user.ts";

export interface UserMutation {
firstName?: string;
lastName?: string;
email?: string;
homePhone?: string | null;
gender?: string | null;
birthDate?: string | null;
corporateName?: string | null;
tradeName?: string | null;
businessPhone?: string | null;
isCorporate?: boolean;
}

const updateProfile = async (
props: UserMutation,
req: Request,
ctx: AppContext,
): Promise<Person | null> => {
const { io } = ctx;
const { cookie } = parseCookie(req.headers, ctx.account);

if (!props?.email) {
console.error("User profile not found or email is missing:", props.email);
return null;
}
const mutation = `
mutation UpdateProfile($input: ProfileInput!) {
updateProfile(fields: $input) @context(provider: "vtex.store-graphql") {
cacheId
firstName
lastName
birthDate
gender
homePhone
businessPhone
document
email
tradeName
corporateName
corporateDocument
stateRegistration
isCorporate
}
}
`;

try {
const { updateProfile: updatedUser } = await io.query<
{ updateProfile: User },
{ input: UserMutation }
>(
{
query: mutation,
operationName: "UpdateProfile",
variables: {
input: {
...props,
email: props.email,
},
},
},
{ headers: { cookie } },
);

return {
"@id": updatedUser?.userId ?? updatedUser.id,
email: updatedUser.email,
givenName: updatedUser?.firstName,
familyName: updatedUser?.lastName,
taxID: updatedUser?.document?.replace(/[^\d]/g, ""),
gender: updatedUser?.gender === "female"
? "https://schema.org/Female"
: "https://schema.org/Male",
telephone: updatedUser?.homePhone,
birthDate: updatedUser?.birthDate,
corporateName: updatedUser?.tradeName,
corporateDocument: updatedUser?.corporateDocument,
businessPhone: updatedUser?.businessPhone,
isCorporate: updatedUser?.isCorporate,
customFields: updatedUser?.customFields,
};
} catch (error) {
console.error("Error updating user profile:", error);
return null;
}
};

export default updateProfile;
35 changes: 35 additions & 0 deletions vtex/loaders/orders/order.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { RequestURLParam } from "../../../website/functions/requestToParam.ts";
import { AppContext } from "../../mod.ts";
import { Order } from "../../utils/types.ts";
import { parseCookie } from "../../utils/vtexId.ts";

export interface Props {
slug: RequestURLParam;
}

export default async function loader(
props: Props,
req: Request,
ctx: AppContext,
): Promise<Order | null> {
const { vcsDeprecated } = ctx;
const { cookie } = parseCookie(req.headers, ctx.account);

const { slug } = props;

const response = await vcsDeprecated["GET /api/oms/user/orders/:orderId"](
{ orderId: slug },
{
headers: {
cookie,
},
},
);

if (response.ok) {
const order = await response.json();
return order;
}

return null;
}
26 changes: 20 additions & 6 deletions vtex/loaders/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Person } from "../../commerce/types.ts";
import { AppContext } from "../mod.ts";
import { parseCookie } from "../utils/vtexId.ts";

interface User {
export interface User {
id: string;
userId: string;
email: string;
Expand All @@ -11,6 +11,13 @@ interface User {
profilePicture?: string;
gender?: string;
document?: string;
homePhone?: string;
birthDate?: string;
corporateDocument?: string;
tradeName?: string;
businessPhone?: string;
isCorporate?: boolean;
customFields?: { key: string; value: string }[];
}

async function loader(
Expand All @@ -26,7 +33,7 @@ async function loader(
}

const query =
"query getUserProfile { profile { id userId email firstName lastName profilePicture gender document }}";
`query getUserProfile { profile(customFields: "isNewsletterOptIn") { id userId email firstName lastName profilePicture gender document homePhone birthDate corporateDocument tradeName businessPhone isCorporate customFields { key value } }}`;

try {
const { profile: user } = await io.query<{ profile: User }, null>(
Expand All @@ -35,14 +42,21 @@ async function loader(
);

return {
"@id": user.userId ?? user.id,
"@id": user?.userId ?? user.id,
email: user.email,
givenName: user.firstName,
familyName: user.lastName,
givenName: user?.firstName,
familyName: user?.lastName,
taxID: user?.document?.replace(/[^\d]/g, ""),
gender: user.gender === "f"
gender: user?.gender === "female"
? "https://schema.org/Female"
: "https://schema.org/Male",
telephone: user?.homePhone,
birthDate: user?.birthDate,
corporateName: user?.tradeName,
corporateDocument: user?.corporateDocument,
businessPhone: user?.businessPhone,
isCorporate: user?.isCorporate,
customFields: user?.customFields,
};
} catch (_) {
return null;
Expand Down
90 changes: 48 additions & 42 deletions vtex/manifest.gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,13 @@ import * as $$$$$$$$$17 from "./actions/masterdata/createDocument.ts";
import * as $$$$$$$$$18 from "./actions/newsletter/subscribe.ts";
import * as $$$$$$$$$19 from "./actions/notifyme.ts";
import * as $$$$$$$$$20 from "./actions/payments/delete.ts";
import * as $$$$$$$$$21 from "./actions/review/submit.ts";
import * as $$$$$$$$$22 from "./actions/sessions/delete.ts";
import * as $$$$$$$$$23 from "./actions/trigger.ts";
import * as $$$$$$$$$24 from "./actions/wishlist/addItem.ts";
import * as $$$$$$$$$25 from "./actions/wishlist/removeItem.ts";
import * as $$$$$$$$$21 from "./actions/profile/newsletterProfile.ts";
import * as $$$$$$$$$22 from "./actions/profile/updateProfile.ts";
import * as $$$$$$$$$23 from "./actions/review/submit.ts";
import * as $$$$$$$$$24 from "./actions/sessions/delete.ts";
import * as $$$$$$$$$25 from "./actions/trigger.ts";
import * as $$$$$$$$$26 from "./actions/wishlist/addItem.ts";
import * as $$$$$$$$$27 from "./actions/wishlist/removeItem.ts";
import * as $$$$0 from "./handlers/sitemap.ts";
import * as $$$0 from "./loaders/cart.ts";
import * as $$$1 from "./loaders/categories/tree.ts";
Expand All @@ -52,22 +54,23 @@ import * as $$$19 from "./loaders/masterdata/searchDocuments.ts";
import * as $$$20 from "./loaders/navbar.ts";
import * as $$$21 from "./loaders/options/productIdByTerm.ts";
import * as $$$22 from "./loaders/orders/list.ts";
import * as $$$23 from "./loaders/paths/PDPDefaultPath.ts";
import * as $$$24 from "./loaders/paths/PLPDefaultPath.ts";
import * as $$$25 from "./loaders/payments/info.ts";
import * as $$$26 from "./loaders/payments/userPayments.ts";
import * as $$$27 from "./loaders/product/extend.ts";
import * as $$$28 from "./loaders/product/extensions/detailsPage.ts";
import * as $$$29 from "./loaders/product/extensions/list.ts";
import * as $$$30 from "./loaders/product/extensions/listingPage.ts";
import * as $$$31 from "./loaders/product/extensions/suggestions.ts";
import * as $$$32 from "./loaders/product/wishlist.ts";
import * as $$$33 from "./loaders/proxy.ts";
import * as $$$34 from "./loaders/sessions/info.ts";
import * as $$$35 from "./loaders/user.ts";
import * as $$$36 from "./loaders/wishlist.ts";
import * as $$$37 from "./loaders/workflow/product.ts";
import * as $$$38 from "./loaders/workflow/products.ts";
import * as $$$23 from "./loaders/orders/order.ts";
import * as $$$24 from "./loaders/paths/PDPDefaultPath.ts";
import * as $$$25 from "./loaders/paths/PLPDefaultPath.ts";
import * as $$$26 from "./loaders/payments/info.ts";
import * as $$$27 from "./loaders/payments/userPayments.ts";
import * as $$$28 from "./loaders/product/extend.ts";
import * as $$$29 from "./loaders/product/extensions/detailsPage.ts";
import * as $$$30 from "./loaders/product/extensions/list.ts";
import * as $$$31 from "./loaders/product/extensions/listingPage.ts";
import * as $$$32 from "./loaders/product/extensions/suggestions.ts";
import * as $$$33 from "./loaders/product/wishlist.ts";
import * as $$$34 from "./loaders/proxy.ts";
import * as $$$35 from "./loaders/sessions/info.ts";
import * as $$$36 from "./loaders/user.ts";
import * as $$$37 from "./loaders/wishlist.ts";
import * as $$$38 from "./loaders/workflow/product.ts";
import * as $$$39 from "./loaders/workflow/products.ts";
import * as $$$$$$0 from "./sections/Analytics/Vtex.tsx";
import * as $$$$$$$$$$0 from "./workflows/events.ts";
import * as $$$$$$$$$$1 from "./workflows/product/index.ts";
Expand Down Expand Up @@ -97,22 +100,23 @@ const manifest = {
"vtex/loaders/navbar.ts": $$$20,
"vtex/loaders/options/productIdByTerm.ts": $$$21,
"vtex/loaders/orders/list.ts": $$$22,
"vtex/loaders/paths/PDPDefaultPath.ts": $$$23,
"vtex/loaders/paths/PLPDefaultPath.ts": $$$24,
"vtex/loaders/payments/info.ts": $$$25,
"vtex/loaders/payments/userPayments.ts": $$$26,
"vtex/loaders/product/extend.ts": $$$27,
"vtex/loaders/product/extensions/detailsPage.ts": $$$28,
"vtex/loaders/product/extensions/list.ts": $$$29,
"vtex/loaders/product/extensions/listingPage.ts": $$$30,
"vtex/loaders/product/extensions/suggestions.ts": $$$31,
"vtex/loaders/product/wishlist.ts": $$$32,
"vtex/loaders/proxy.ts": $$$33,
"vtex/loaders/sessions/info.ts": $$$34,
"vtex/loaders/user.ts": $$$35,
"vtex/loaders/wishlist.ts": $$$36,
"vtex/loaders/workflow/product.ts": $$$37,
"vtex/loaders/workflow/products.ts": $$$38,
"vtex/loaders/orders/order.ts": $$$23,
"vtex/loaders/paths/PDPDefaultPath.ts": $$$24,
"vtex/loaders/paths/PLPDefaultPath.ts": $$$25,
"vtex/loaders/payments/info.ts": $$$26,
"vtex/loaders/payments/userPayments.ts": $$$27,
"vtex/loaders/product/extend.ts": $$$28,
"vtex/loaders/product/extensions/detailsPage.ts": $$$29,
"vtex/loaders/product/extensions/list.ts": $$$30,
"vtex/loaders/product/extensions/listingPage.ts": $$$31,
"vtex/loaders/product/extensions/suggestions.ts": $$$32,
"vtex/loaders/product/wishlist.ts": $$$33,
"vtex/loaders/proxy.ts": $$$34,
"vtex/loaders/sessions/info.ts": $$$35,
"vtex/loaders/user.ts": $$$36,
"vtex/loaders/wishlist.ts": $$$37,
"vtex/loaders/workflow/product.ts": $$$38,
"vtex/loaders/workflow/products.ts": $$$39,
},
"handlers": {
"vtex/handlers/sitemap.ts": $$$$0,
Expand Down Expand Up @@ -142,11 +146,13 @@ const manifest = {
"vtex/actions/newsletter/subscribe.ts": $$$$$$$$$18,
"vtex/actions/notifyme.ts": $$$$$$$$$19,
"vtex/actions/payments/delete.ts": $$$$$$$$$20,
"vtex/actions/review/submit.ts": $$$$$$$$$21,
"vtex/actions/sessions/delete.ts": $$$$$$$$$22,
"vtex/actions/trigger.ts": $$$$$$$$$23,
"vtex/actions/wishlist/addItem.ts": $$$$$$$$$24,
"vtex/actions/wishlist/removeItem.ts": $$$$$$$$$25,
"vtex/actions/profile/newsletterProfile.ts": $$$$$$$$$21,
"vtex/actions/profile/updateProfile.ts": $$$$$$$$$22,
"vtex/actions/review/submit.ts": $$$$$$$$$23,
"vtex/actions/sessions/delete.ts": $$$$$$$$$24,
"vtex/actions/trigger.ts": $$$$$$$$$25,
"vtex/actions/wishlist/addItem.ts": $$$$$$$$$26,
"vtex/actions/wishlist/removeItem.ts": $$$$$$$$$27,
},
"workflows": {
"vtex/workflows/events.ts": $$$$$$$$$$0,
Expand Down
Loading

0 comments on commit 904ad6c

Please sign in to comment.