Add unsend campaign feature (#45)
* Add unsend email editor Add email editor Add more email editor Add renderer partial Add more marketing email features * Add more campaign feature * Add variables * Getting there * campaign is there mfs * Add migration
This commit is contained in:
111
packages/email-editor/src/editor.tsx
Normal file
111
packages/email-editor/src/editor.tsx
Normal file
@@ -0,0 +1,111 @@
|
||||
"use client";
|
||||
|
||||
import {
|
||||
BubbleMenu,
|
||||
EditorContent,
|
||||
EditorProvider,
|
||||
FloatingMenu,
|
||||
useEditor,
|
||||
} from "@tiptap/react";
|
||||
import StarterKit from "@tiptap/starter-kit";
|
||||
import React, { useRef } from "react";
|
||||
import { TextMenu } from "./menus/TextMenu";
|
||||
import { cn } from "@unsend/ui/lib/utils";
|
||||
|
||||
import { extensions } from "./extensions";
|
||||
import LinkMenu from "./menus/LinkMenu";
|
||||
import { Content, Editor as TipTapEditor } from "@tiptap/core";
|
||||
|
||||
const content = `<h2>Hello World!</h2>
|
||||
|
||||
<h3>Unsend is the best open source resend alternative.</h3>
|
||||
|
||||
<p>Use markdown (<code># </code>, <code>## </code>, <code>### </code>, <code>\`\`</code>, <code>* *</code>, <code>** **</code>) to write your email. </p>
|
||||
<p>You can <b>Bold</b> text.
|
||||
You can <i>Italic</i> text.
|
||||
You can <u>Underline</u> text.
|
||||
You can <del>Delete</del> text.
|
||||
You can <code>Code</code> text.
|
||||
you can change <span style="color: #dc2626;"> color</span> of text. Add <a href="https://unsend.dev" target="_blank">link</a> to text
|
||||
</p>
|
||||
<br>
|
||||
You can create ordered list
|
||||
<ol>
|
||||
<li>Ordered list item</li>
|
||||
<li>Ordered list item</li>
|
||||
<li>Ordered list item</li>
|
||||
</ol>
|
||||
|
||||
<br>
|
||||
You can create unordered list
|
||||
<ul>
|
||||
<li>Unordered list item</li>
|
||||
<li>Unordered list item</li>
|
||||
<li>Unordered list item</li>
|
||||
</ul>
|
||||
|
||||
<p></p>
|
||||
<p>Add code by typing \`\`\` and enter</p>
|
||||
<pre>
|
||||
<code>
|
||||
const unsend = new Unsend({ apiKey: "us_12345" });
|
||||
|
||||
unsend.emails.send({
|
||||
to: "john@doe.com",
|
||||
from: "john@doe.com",
|
||||
subject: "Hello World!",
|
||||
html: "<p>Hello World!</p>",
|
||||
text: "Hello World!",
|
||||
});
|
||||
</code>
|
||||
</pre>
|
||||
`;
|
||||
|
||||
export type EditorProps = {
|
||||
onUpdate?: (content: TipTapEditor) => void;
|
||||
initialContent?: Content;
|
||||
variables?: Array<string>;
|
||||
};
|
||||
|
||||
export const Editor: React.FC<EditorProps> = ({
|
||||
onUpdate,
|
||||
initialContent,
|
||||
variables,
|
||||
}) => {
|
||||
const menuContainerRef = useRef(null);
|
||||
|
||||
const editor = useEditor({
|
||||
editorProps: {
|
||||
attributes: {
|
||||
class: cn("unsend-prose w-full"),
|
||||
},
|
||||
handleDOMEvents: {
|
||||
keydown: (_view, event) => {
|
||||
// prevent default event listeners from firing when slash command is active
|
||||
if (["ArrowUp", "ArrowDown", "Enter"].includes(event.key)) {
|
||||
const slashCommand = document.querySelector("#slash-command");
|
||||
if (slashCommand) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
extensions: extensions({ variables }),
|
||||
onUpdate: ({ editor }) => {
|
||||
onUpdate?.(editor);
|
||||
},
|
||||
content: initialContent,
|
||||
});
|
||||
|
||||
return (
|
||||
<div
|
||||
className="bg-white rounded-md text-black p-8 unsend-editor light"
|
||||
ref={menuContainerRef}
|
||||
>
|
||||
<EditorContent editor={editor} className="min-h-[50vh]" />
|
||||
{editor ? <TextMenu editor={editor} /> : null}
|
||||
{editor ? <LinkMenu editor={editor} appendTo={menuContainerRef} /> : null}
|
||||
</div>
|
||||
);
|
||||
};
|
Reference in New Issue
Block a user