diff --git a/.changeset/cold-bugs-remember.md b/.changeset/cold-bugs-remember.md new file mode 100644 index 0000000..dbbf52f --- /dev/null +++ b/.changeset/cold-bugs-remember.md @@ -0,0 +1,5 @@ +--- +"saleor-app-emails-and-messages": patch +--- + +Improve instructions for the app configuration diff --git a/apps/emails-and-messages/src/lib/generate-random-id.ts b/apps/emails-and-messages/src/lib/generate-random-id.ts new file mode 100644 index 0000000..68d63fa --- /dev/null +++ b/apps/emails-and-messages/src/lib/generate-random-id.ts @@ -0,0 +1,10 @@ +/** + * Generates a random id containing current time and random string. + */ +export const generateRandomId = () => { + const date = new Date(); + const offsetInMinutes = date.getTimezoneOffset(); + const randomDate = date.setMinutes(date.getMinutes() + offsetInMinutes).valueOf(); + const randomString = (Math.random() + 1).toString(36).substring(7); + return `${randomDate}${randomString}`; +}; diff --git a/apps/emails-and-messages/src/modules/app-configuration/ui/channels-configuration-tab.tsx b/apps/emails-and-messages/src/modules/app-configuration/ui/channels-configuration-tab.tsx index 7da16bf..329e48a 100644 --- a/apps/emails-and-messages/src/modules/app-configuration/ui/channels-configuration-tab.tsx +++ b/apps/emails-and-messages/src/modules/app-configuration/ui/channels-configuration-tab.tsx @@ -6,6 +6,7 @@ import { AppColumnsLayout } from "../../ui/app-columns-layout"; import { trpcClient } from "../../trpc/trpc-client"; import SideMenu from "./side-menu"; import { LoadingIndicator } from "../../ui/loading-indicator"; +import { Instructions } from "./instructions"; const useStyles = makeStyles((theme) => { return { @@ -142,6 +143,7 @@ export const ChannelsConfigurationTab = () => { )} + ); }; diff --git a/apps/emails-and-messages/src/modules/app-configuration/ui/instructions.tsx b/apps/emails-and-messages/src/modules/app-configuration/ui/instructions.tsx new file mode 100644 index 0000000..87c9702 --- /dev/null +++ b/apps/emails-and-messages/src/modules/app-configuration/ui/instructions.tsx @@ -0,0 +1,34 @@ +import { Paper, Typography } from "@material-ui/core"; +import { makeStyles } from "@saleor/macaw-ui"; + +const useStyles = makeStyles((theme) => { + return { + instructionsContainer: { + padding: 15, + }, + }; +}); + +export const Instructions = () => { + const styles = useStyles(); + + return ( + + + Welcome to Emails and Messages App! + + + The application will allow you to send emails and messages to your customers using different + services. + + + + How to configure the app + + + Start by creating a new configuration for provider of your choice. You can create multiple + configurations and then assign them to channels. Navigate to the relevant tab to configure the provider. + + + ); +}; diff --git a/apps/emails-and-messages/src/modules/mjml/configuration/mjml-config-container.ts b/apps/emails-and-messages/src/modules/mjml/configuration/mjml-config-container.ts index 22a98a5..c42bb83 100644 --- a/apps/emails-and-messages/src/modules/mjml/configuration/mjml-config-container.ts +++ b/apps/emails-and-messages/src/modules/mjml/configuration/mjml-config-container.ts @@ -1,8 +1,7 @@ import { messageEventTypes } from "../../event-handlers/message-event-types"; import { MjmlConfig as MjmlConfigurationRoot, MjmlConfiguration } from "./mjml-config"; import { defaultMjmlTemplates, defaultMjmlSubjectTemplates } from "../default-templates"; - -export const generateMjmlConfigurationId = () => Date.now().toString(); +import { generateRandomId } from "../../../lib/generate-random-id"; export const getDefaultEventsConfiguration = (): MjmlConfiguration["events"] => messageEventTypes.map((eventType) => ({ @@ -77,7 +76,7 @@ const createConfiguration = // for creating a new configurations, the ID has to be generated const newConfiguration = { ...mjmlConfiguration, - id: generateMjmlConfigurationId(), + id: generateRandomId(), events: getDefaultEventsConfiguration(), }; mjmlConfigNormalized.configurations.push(newConfiguration); diff --git a/apps/emails-and-messages/src/modules/mjml/configuration/ui/mjml-configuration-form.tsx b/apps/emails-and-messages/src/modules/mjml/configuration/ui/mjml-configuration-form.tsx index 12137f9..d2e62fe 100644 --- a/apps/emails-and-messages/src/modules/mjml/configuration/ui/mjml-configuration-form.tsx +++ b/apps/emails-and-messages/src/modules/mjml/configuration/ui/mjml-configuration-form.tsx @@ -136,7 +136,9 @@ export const MjmlConfigurationForm = (props: Props) => { value={value} onChange={onChange} error={!!error} - helperText={error?.message} + helperText={ + error?.message || "Name of the configuration, for example 'Production' or 'Test'" + } {...CommonFieldProps} /> )} @@ -182,7 +184,7 @@ export const MjmlConfigurationForm = (props: Props) => { { { label="SMTP server host" value={value} onChange={onChange} - helperText={error?.message} + helperText={ + error?.message || + "Address of the SMTP server, without the protocol. For example 'smtp.example.com'" + } error={!!error} {...CommonFieldProps} /> diff --git a/apps/emails-and-messages/src/modules/mjml/configuration/ui/mjml-configuration-tab.tsx b/apps/emails-and-messages/src/modules/mjml/configuration/ui/mjml-configuration-tab.tsx index cc3ed6e..9dbad8f 100644 --- a/apps/emails-and-messages/src/modules/mjml/configuration/ui/mjml-configuration-tab.tsx +++ b/apps/emails-and-messages/src/modules/mjml/configuration/ui/mjml-configuration-tab.tsx @@ -13,6 +13,7 @@ import { MjmlConfiguration } from "../mjml-config"; import { LoadingIndicator } from "../../../ui/loading-indicator"; import { Add } from "@material-ui/icons"; import { useQueryClient } from "@tanstack/react-query"; +import { MjmlInstructions } from "./mjml-instructions"; const useStyles = makeStyles((theme) => { return { @@ -165,6 +166,7 @@ export const MjmlConfigurationTab = ({ configurationId }: MjmlConfigurationTabPr )} + ); }; diff --git a/apps/emails-and-messages/src/modules/mjml/configuration/ui/mjml-instructions.tsx b/apps/emails-and-messages/src/modules/mjml/configuration/ui/mjml-instructions.tsx new file mode 100644 index 0000000..c63b3ec --- /dev/null +++ b/apps/emails-and-messages/src/modules/mjml/configuration/ui/mjml-instructions.tsx @@ -0,0 +1,53 @@ +import { Link, Paper, Typography } from "@material-ui/core"; +import { actions, useAppBridge } from "@saleor/app-sdk/app-bridge"; +import { makeStyles } from "@saleor/macaw-ui"; + +const useStyles = makeStyles((theme) => { + return { + instructionsContainer: { + padding: 15, + }, + }; +}); + +export const MjmlInstructions = () => { + const styles = useStyles(); + + const { appBridge } = useAppBridge(); + + return ( + + + MJML Provider + + + You can use this provider to send emails using MJML as a template language. The emails are + then sent using the SMTP. + + + + { + event.preventDefault(); + appBridge?.dispatch( + actions.Redirect({ + to: "https://mjml.io/", + newContext: true, + }) + ); + }} + > + Visit the MJML Homepage + + + + How to configure + + + Create a new configuration and fill in the required fields. After the configuration is + saved, you will be able to modify the email templates. + + + ); +}; diff --git a/apps/emails-and-messages/src/modules/sendgrid/configuration/sendgrid-config-container.ts b/apps/emails-and-messages/src/modules/sendgrid/configuration/sendgrid-config-container.ts index f9d90ed..cd91782 100644 --- a/apps/emails-and-messages/src/modules/sendgrid/configuration/sendgrid-config-container.ts +++ b/apps/emails-and-messages/src/modules/sendgrid/configuration/sendgrid-config-container.ts @@ -1,11 +1,10 @@ +import { generateRandomId } from "../../../lib/generate-random-id"; import { messageEventTypes } from "../../event-handlers/message-event-types"; import { SendgridConfig as SendgridConfigurationRoot, SendgridConfiguration, } from "./sendgrid-config"; -export const generateSendgridConfigurationId = () => Date.now().toString(); - export const getDefaultEventsConfiguration = (): SendgridConfiguration["events"] => messageEventTypes.map((eventType) => ({ active: true, @@ -75,7 +74,7 @@ const createConfiguration = // for creating a new configurations, the ID has to be generated const newConfiguration = { ...sendgridConfiguration, - id: generateSendgridConfigurationId(), + id: generateRandomId(), events: getDefaultEventsConfiguration(), }; sendgridConfigNormalized.configurations.push(newConfiguration); diff --git a/apps/emails-and-messages/src/modules/sendgrid/configuration/ui/sendgrid-configuration-form.tsx b/apps/emails-and-messages/src/modules/sendgrid/configuration/ui/sendgrid-configuration-form.tsx index 37cbb62..d21aa76 100644 --- a/apps/emails-and-messages/src/modules/sendgrid/configuration/ui/sendgrid-configuration-form.tsx +++ b/apps/emails-and-messages/src/modules/sendgrid/configuration/ui/sendgrid-configuration-form.tsx @@ -177,7 +177,9 @@ export const SendgridConfigurationForm = (props: Props) => { value={value} onChange={onChange} error={!!error} - helperText={error?.message} + helperText={ + error?.message || "Name of the configuration, for example 'Production' or 'Test'" + } {...CommonFieldProps} /> )} @@ -224,7 +226,10 @@ export const SendgridConfigurationForm = (props: Props) => { label="Sendgrid API key" value={value} onChange={onChange} - helperText={error?.message} + helperText={ + error?.message || + "The API key can be generated at Sendgrid dashboard, in the Settings / API Keys section" + } error={!!error} {...CommonFieldProps} /> diff --git a/apps/emails-and-messages/src/modules/sendgrid/configuration/ui/sendgrid-configuration-tab.tsx b/apps/emails-and-messages/src/modules/sendgrid/configuration/ui/sendgrid-configuration-tab.tsx index 6db83c8..6374e20 100644 --- a/apps/emails-and-messages/src/modules/sendgrid/configuration/ui/sendgrid-configuration-tab.tsx +++ b/apps/emails-and-messages/src/modules/sendgrid/configuration/ui/sendgrid-configuration-tab.tsx @@ -13,6 +13,7 @@ import { Add } from "@material-ui/icons"; import { useQueryClient } from "@tanstack/react-query"; import { sendgridUrls } from "../../urls"; import { SendgridTemplatesCard } from "./sendgrid-templates-card"; +import { SendgridInstructions } from "./sendgrid-instructions"; const useStyles = makeStyles((theme) => { return { @@ -170,6 +171,7 @@ export const SendgridConfigurationTab = ({ configurationId }: SendgridConfigurat )} + ); }; diff --git a/apps/emails-and-messages/src/modules/sendgrid/configuration/ui/sendgrid-instructions.tsx b/apps/emails-and-messages/src/modules/sendgrid/configuration/ui/sendgrid-instructions.tsx new file mode 100644 index 0000000..bfcb643 --- /dev/null +++ b/apps/emails-and-messages/src/modules/sendgrid/configuration/ui/sendgrid-instructions.tsx @@ -0,0 +1,103 @@ +import { Link, Paper, Typography } from "@material-ui/core"; +import { actions, useAppBridge } from "@saleor/app-sdk/app-bridge"; +import { makeStyles } from "@saleor/macaw-ui"; + +const useStyles = makeStyles((theme) => { + return { + instructionsContainer: { + padding: 15, + }, + }; +}); + +export const SendgridInstructions = () => { + const styles = useStyles(); + + const { appBridge } = useAppBridge(); + + return ( + + + Sendgrid Provider + + + The integration uses dynamic email templates to send the messages to your customers. + + + + { + event.preventDefault(); + appBridge?.dispatch( + actions.Redirect({ + to: "https://sendgrid.com/", + newContext: true, + }) + ); + }} + > + Visit the Sendgrid Homepage + + + + How to configure + + + + Before configuring the app, make sure you have a Sendgrid account set up. To proceed you + will need: +
+ { + event.preventDefault(); + appBridge?.dispatch( + actions.Redirect({ + to: "https://app.sendgrid.com/settings/api_keys", + newContext: true, + }) + ); + }} + > + API key which can be generated in the Sendgrid dashboard + +
+ { + event.preventDefault(); + appBridge?.dispatch( + actions.Redirect({ + to: "https://app.sendgrid.com/settings/sender_auth", + newContext: true, + }) + ); + }} + > + Verified sender account + +
+ { + event.preventDefault(); + appBridge?.dispatch( + actions.Redirect({ + to: "https://mc.sendgrid.com/dynamic-templates", + newContext: true, + }) + ); + }} + > + Created dynamic email templates + +
+ + + Create a new configuration and fill in the required fields. After the configuration is + saved, you will be able to assign the email template to each of the events. + +
+ ); +}; diff --git a/apps/emails-and-messages/src/modules/ui/app-columns-layout.tsx b/apps/emails-and-messages/src/modules/ui/app-columns-layout.tsx index 0422a67..e4ad9d8 100644 --- a/apps/emails-and-messages/src/modules/ui/app-columns-layout.tsx +++ b/apps/emails-and-messages/src/modules/ui/app-columns-layout.tsx @@ -4,7 +4,7 @@ import { PropsWithChildren } from "react"; const useStyles = makeStyles((theme) => ({ root: { display: "grid", - gridTemplateColumns: "280px auto", + gridTemplateColumns: "280px auto 400px", alignItems: "start", gap: theme.spacing(3), padding: "20px 0",