Vytvoříme webovou aplikaci, která vám umožní rychle vytvářet odběratele a jednoduchým způsobem odesílat e-maily odběratelům. Ke snadnému vývoji frontendu použijeme nástroj zpřesnit a pro backendová řešení použijeme příkaz.
Začněme tím, že vytvoříme naše strapi a vylepšíme projekty.
Vytváření API pomocí Strapi
npx create-strapi-app strapi-email-subscription-api --quickstart
Po načtení projektu se v prohlížeči automaticky otevře administrátorský panel. Potřebujeme vytvořit administrátora, abychom se mohli přihlásit do strapi.
S informacemi, které zde vytvoříme, můžeme nyní vstoupit do strapi a začít utvářet náš backend.
Po přihlášení do rozhraní Strapi máme dva modely kolekce, které musíme vytvořit pro náš projekt předplatného e-mailu.
Tyto kolekce vytvoříme z části strai Collection-Types Builder.
S těmito kolekcemi a funkcemi, které jsme vytvořili, můžeme nyní vytvářet odběratele, mazat je a provádět v nich změny.
Vytváření panelu pomocí refine
Nyní upřesníme panel předplatného. Pomocí superplate můžeme rychle vytvořit rafinovaný projekt
npx superplate-cli email-subscription-panel
Chcete-li dokončit průvodce CLI, vyberte následující možnosti:
? Select your project type:
> refine
? Package manager:
> Npm
? Do you want to customize the theme?:
> No (Ant Design default theme)
? Data Provider:
> Strapi
? Do you want to customize layout?:
> Yes, I want
? i18n - Internationalization:
> No
Po dokončení nahrávání pojďme do našeho projektu a podívejme se, jak to vypadá.
cd email-subscription-panel
npm run dev
Toto je příklad projektu Refine:
Uveďme seznam našich zpráv a odběratelů s upřesněním. Zde jsou změny, které musíme provést:
- Změňte adresu URL Strapi API z upřesnění
- Přidávání zdrojů podle názvu kolekce, který jsme vytvořili ve Strapi
/App.tsx
import { Refine, Resource } from "@pankod/refine";
import "@pankod/refine/dist/styles.min.css";
import { DataProvider } from "@pankod/refine-strapi";
import strapiAuthProvider from "authProvider";
import { Header, Layout, OffLayoutArea } from "components";
function App() {
- const API_URL = "your-strapi-api-url";
+ const API_URL = "http://localhost:1337";
const { authProvider, axiosInstance } = strapiAuthProvider(API_URL);
const dataProvider = DataProvider(API_URL, axiosInstance);
return (
<Refine
dataProvider={dataProvider}
authProvider={authProvider}
Header={Header}
Layout={Layout}
OffLayoutArea={OffLayoutArea}
>
<Resource
name="subscribers"/>
<Resource
name="messages"/>
</Refine>
);
}
export default App;
Po přidání zdrojů musíme definovat uživatele v strapi, abychom se mohli přihlásit do zpřesnění.
Pojďme se přihlásit s tímto uživatelem, kterého jsme vytvořili
Nyní můžeme uvést odběratele a zprávy a provádět změny v našem seznamu. Než to uděláte, vytvořte testovací uživatele a zprávy na straně strapi.
Ve složce stránek vytvořte soubor SubscriberList.tsx a MessagesList.tsx. Poté vytvořte naši komponentu následovně s komponentami a háčky, které přicházejí s upřesněním.
/src/pages/subscriber/SubscriberList.tsx
import React from "react";
import {
useTable,
List,
Table,
DateField,
DeleteButton,
IResourceComponentsProps,
} from "@pankod/refine";
import { ISubscriber } from "interfaces";
export const SubscriberList: React.FC<IResourceComponentsProps> = () => {
const { tableProps } = useTable<ISubscriber>();
return (
<List>
<Table {...tableProps} rowKey="id">
<Table.Column dataIndex="id" title="Id" />
<Table.Column dataIndex="name" title="Name" />
<Table.Column dataIndex="email" title="E-mail" />
<Table.Column
dataIndex="created_at"
title="createdAt"
render={(value) => <DateField format="LLL" value={value} />}
/>
<Table.Column<ISubscriber>
title="Unsubscribe"
dataIndex="actions"
render={(_, record): React.ReactNode => {
return (
<DeleteButton size="small" recordItemId={record.id} hideText />
);
}}
/>
</Table>
</List>
);
};
/src/pages/mail/MessageList.tsx
import React from "react";
import {
useTable,
List,
Table,
DateField,
IResourceComponentsProps,
} from "@pankod/refine";
import { IMail } from "interfaces";
export const MessageList: React.FC<IResourceComponentsProps> = () => {
const { tableProps } = useTable<IMail>();
return (
<List>
<Table {...tableProps} rowKey="id">
<Table.Column dataIndex="id" title="Id" />
<Table.Column dataIndex="subject" title="Subject" />
<Table.Column dataIndex="text" title="Body" />
<Table.Column
dataIndex="created_at"
title="createdAt"
render={(value) => <DateField format="LLL" value={value} />}
/>
</Table>
</List>
);
};
/src/interfaces/intex.d.ts
export interface ISubscriber {
id: any;
name: string;
email: string;
created_at: string;
}
export interface IMail {
subject: string;
text: string;
to: string;
create_at: string;
}
V této komponentě:
K zobrazení našich odběratelů a zpráv jsme použili upřesňující seznam a tabulku.
Nyní se podívejme, jak náš panel odběratelů vypadá:
Subscriber:
Messages:
Jak můžete vidět, byli jsme schopni uvést naše odběratele a e-maily velmi jednoduše s upřesněním. Nyní se podívejme, jak můžeme vytvářet odběratele a zprávy z našeho rozhraní.
/src/pages/subscriber/create.tsx
import {
Create,
Form,
Input,
useForm,
IResourceComponentsProps,
} from "@pankod/refine";
import { ICreateSubscriber } from "interfaces";
export const CreateSubscriber: React.FC<IResourceComponentsProps> = () => {
const { formProps, saveButtonProps } = useForm<ICreateSubscriber>();
return (
<Create saveButtonProps={saveButtonProps}>
<Form {...formProps} layout="vertical">
<Form.Item label="Name" name="name">
<Input />
</Form.Item>
<Form.Item
label="E-mail"
name="email"
rules={[
{
required: true,
},
]}
>
<Input />
</Form.Item>
</Form>
</Create>
);
};
/src/pages/mail/create.tsx
import React, { useState } from "react";
import {
Create,
Form,
Input,
useForm,
IResourceComponentsProps,
} from "@pankod/refine";
import ReactMarkdown from "react-markdown";
import ReactMde from "react-mde";
import "react-mde/lib/styles/css/react-mde-all.css";
import { IMail } from "interfaces";
export const MailCreate: React.FC<IResourceComponentsProps> = () => {
const { formProps, saveButtonProps } = useForm<IMail>();
const [selectedTab, setSelectedTab] = useState<"write" | "preview">("write");
return (
<Create saveButtonProps={saveButtonProps}>
{console.log("create")}
<Form {...formProps} layout="vertical">
<Form.Item
label="Subject"
name="subject"
rules={[
{
required: true,
},
]}
>
<Input />
</Form.Item>
<Form.Item
label="Body"
name="text"
rules={[
{
required: true,
},
]}
>
<ReactMde
selectedTab={selectedTab}
onTabChange={setSelectedTab}
generateMarkdownPreview={(markdown: any) =>
Promise.resolve(<ReactMarkdown>{markdown}</ReactMarkdown>)
}
/>
</Form.Item>
<Form.Item
label="To"
name="to"
rules={[
{
required: true,
},
]}
>
<Input />
</Form.Item>
</Form>
</Create>
);
};
Pomocí upřesnění formuláře a vytvoření komponent nyní můžeme vytvářet odběratele a zprávy s upřesněním.
S naším panelem jsme skončili. Nyní můžeme vypisovat, vytvářet a mazat odběratele. Nakonec zbývá krok odesílání skutečných e-mailů pomocí našeho panelu a strapi. Pojďme se podívat, jak to uděláme.
E-mailový plugin Strapi
Abychom mohli posílat poštu přes Strapi, musíme nainstalovat plugin strapi-email do našeho projektu API, který jsme vytvořili výše.
Otevřete náš projekt API, který jsme vytvořili, a stáhněte si e-mailový plugin.
cd strapi-email-subscription-api
npm install strapi-provider-email-sendgrid --save
Po instalaci pluginu budete muset přidat některá nastavení do souboru config/plugins.js. Pokud tento soubor neexistuje, budete jej muset vytvořit.
Nakonfigurujte svého poskytovatele
Path — ./config/plugins.js
module.exports = ({ env }) => ({
email: {
provider: 'sendgrid',
providerOptions: {
apiKey: env('SENDGRID_API_KEY'),
},
settings: {
defaultFrom: 'your-email-adress',
defaultReplyTo: 'your-email-adress',
testAddress: 'your-email-adress',
},
},
});
💡 TIP :Strapi odesílá e-maily přes sendgrid. Proto si musíte vytvořit účet SendGrid a získat api-klíč.
Nyní odešleme text a předmět z kolekce zpráv, které jsme vytvořili přes strapi, jako parametry do funkce send() e-mailového pluginu.
api/messages/controllers/messages.js
const { parseMultipartData, sanitizeEntity } = require("strapi-utils");
module.exports = {
async create(ctx) {
let entity;
if (ctx.is("multipart")) {
const { data, files } = parseMultipartData(ctx);
entity = await strapi.services.messages.create(data, { files });
} else {
entity = await strapi.services.messages.create(ctx.request.body);
}
entity = sanitizeEntity(entity, { model: strapi.models.messages });
const { subject, text } = entity;
const worker = (await strapi.services.subscribers.find()).map(
(subscriber) => {
let to = subscriber.email;
return strapi.plugins["email"].services.email.send({
subject,
text,
to,
});
}
);
await Promise.all(worker);
return entity;
},
};
Náš projekt je dokončen. Zkusme to teď.
Odešleme najednou stejný e-mail našim odběratelům zobrazeným na obrázku.
Odeslání pošty bylo úspěšné. Jak můžete vidět, byli jsme schopni poslat stejný e-mail všem odběratelům odesláním jediného e-mailu.
Zde je repo
Další informace o Refine:https://refine.dev/