summaryrefslogtreecommitdiffhomepage
path: root/packages/console/mail/emails
diff options
context:
space:
mode:
authorFrank <[email protected]>2025-10-01 19:34:37 -0400
committerFrank <[email protected]>2025-10-01 19:34:37 -0400
commit70da3a9399d3385b53f7831beb08f716b972860d (patch)
tree6934fafb8558d426df88ca83d043eb3ac5910dcd /packages/console/mail/emails
parent1024537b471c341581826b39c360d34d6c32404f (diff)
downloadopencode-70da3a9399d3385b53f7831beb08f716b972860d.tar.gz
opencode-70da3a9399d3385b53f7831beb08f716b972860d.zip
wip: zen
Diffstat (limited to 'packages/console/mail/emails')
-rw-r--r--packages/console/mail/emails/components.tsx108
-rw-r--r--packages/console/mail/emails/styles.ts110
-rw-r--r--packages/console/mail/emails/templates/InviteEmail.tsx113
-rw-r--r--packages/console/mail/emails/templates/static/ibm-plex-mono-latin-400.woff2bin0 -> 10088 bytes
-rw-r--r--packages/console/mail/emails/templates/static/ibm-plex-mono-latin-500.woff2bin0 -> 10132 bytes
-rw-r--r--packages/console/mail/emails/templates/static/ibm-plex-mono-latin-600.woff2bin0 -> 10148 bytes
-rw-r--r--packages/console/mail/emails/templates/static/ibm-plex-mono-latin-700.woff2bin0 -> 10140 bytes
-rw-r--r--packages/console/mail/emails/templates/static/rubik-latin.woff2bin0 -> 35320 bytes
-rw-r--r--packages/console/mail/emails/templates/static/zen-logo.pngbin0 -> 8336 bytes
9 files changed, 331 insertions, 0 deletions
diff --git a/packages/console/mail/emails/components.tsx b/packages/console/mail/emails/components.tsx
new file mode 100644
index 000000000..d030b6cbf
--- /dev/null
+++ b/packages/console/mail/emails/components.tsx
@@ -0,0 +1,108 @@
+// @ts-nocheck
+import React from "react"
+import { Font, Hr as JEHr, Text as JEText, type HrProps, type TextProps } from "@jsx-email/all"
+import { DIVIDER_COLOR, SURFACE_DIVIDER_COLOR, textColor } from "./styles"
+
+export function Text(props: TextProps) {
+ return <JEText {...props} style={{ ...textColor, ...props.style }} />
+}
+
+export function Hr(props: HrProps) {
+ return <JEHr {...props} style={{ borderTop: `1px solid ${DIVIDER_COLOR}`, ...props.style }} />
+}
+
+export function SurfaceHr(props: HrProps) {
+ return (
+ <JEHr
+ {...props}
+ style={{
+ borderTop: `1px solid ${SURFACE_DIVIDER_COLOR}`,
+ ...props.style,
+ }}
+ />
+ )
+}
+
+export function Title({ children }: TitleProps) {
+ return React.createElement("title", null, children)
+}
+
+export function A({ children, ...props }: AProps) {
+ return React.createElement("a", props, children)
+}
+
+export function Span({ children, ...props }: SpanProps) {
+ return React.createElement("span", props, children)
+}
+
+export function Wbr({ children, ...props }: WbrProps) {
+ return React.createElement("wbr", props, children)
+}
+
+export function Fonts({ assetsUrl }: { assetsUrl: string }) {
+ return (
+ <>
+ <Font
+ fontFamily="IBM Plex Mono"
+ fallbackFontFamily="monospace"
+ webFont={{
+ url: `${assetsUrl}/ibm-plex-mono-latin-400.woff2`,
+ format: "woff2",
+ }}
+ fontWeight="400"
+ fontStyle="normal"
+ />
+ <Font
+ fontFamily="IBM Plex Mono"
+ fallbackFontFamily="monospace"
+ webFont={{
+ url: `${assetsUrl}/ibm-plex-mono-latin-500.woff2`,
+ format: "woff2",
+ }}
+ fontWeight="500"
+ fontStyle="normal"
+ />
+ <Font
+ fontFamily="IBM Plex Mono"
+ fallbackFontFamily="monospace"
+ webFont={{
+ url: `${assetsUrl}/ibm-plex-mono-latin-600.woff2`,
+ format: "woff2",
+ }}
+ fontWeight="600"
+ fontStyle="normal"
+ />
+ <Font
+ fontFamily="IBM Plex Mono"
+ fallbackFontFamily="monospace"
+ webFont={{
+ url: `${assetsUrl}/ibm-plex-mono-latin-700.woff2`,
+ format: "woff2",
+ }}
+ fontWeight="700"
+ fontStyle="normal"
+ />
+ <Font
+ fontFamily="Rubik"
+ fallbackFontFamily={["Helvetica", "Arial", "sans-serif"]}
+ webFont={{
+ url: `${assetsUrl}/rubik-latin.woff2`,
+ format: "woff2",
+ }}
+ fontWeight="400 500 600 700"
+ fontStyle="normal"
+ />
+ </>
+ )
+}
+
+export function SplitString({ text, split }: { text: string; split: number }) {
+ const segments: JSX.Element[] = []
+ for (let i = 0; i < text.length; i += split) {
+ segments.push(<>{text.slice(i, i + split)}</>)
+ if (i + split < text.length) {
+ segments.push(<Wbr key={`${i}wbr`} />)
+ }
+ }
+ return <>{segments}</>
+}
diff --git a/packages/console/mail/emails/styles.ts b/packages/console/mail/emails/styles.ts
new file mode 100644
index 000000000..f9b62a7cd
--- /dev/null
+++ b/packages/console/mail/emails/styles.ts
@@ -0,0 +1,110 @@
+export const unit = 16;
+
+export const GREY_COLOR = [
+ "#1A1A2E", //0
+ "#2F2F41", //1
+ "#444454", //2
+ "#585867", //3
+ "#6D6D7A", //4
+ "#82828D", //5
+ "#9797A0", //6
+ "#ACACB3", //7
+ "#C1C1C6", //8
+ "#D5D5D9", //9
+ "#EAEAEC", //10
+ "#FFFFFF", //11
+];
+
+export const BLUE_COLOR = "#395C6B";
+export const DANGER_COLOR = "#ED322C";
+export const TEXT_COLOR = GREY_COLOR[0];
+export const SECONDARY_COLOR = GREY_COLOR[5];
+export const DIMMED_COLOR = GREY_COLOR[7];
+export const DIVIDER_COLOR = GREY_COLOR[10];
+export const BACKGROUND_COLOR = "#F0F0F1";
+export const SURFACE_COLOR = DIVIDER_COLOR;
+export const SURFACE_DIVIDER_COLOR = GREY_COLOR[9];
+
+export const body = {
+ background: BACKGROUND_COLOR,
+};
+
+export const container = {
+ minWidth: "600px",
+};
+
+export const medium = {
+ fontWeight: 500,
+};
+
+export const danger = {
+ color: DANGER_COLOR,
+};
+
+export const frame = {
+ padding: `${unit * 1.5}px`,
+ border: `1px solid ${SURFACE_DIVIDER_COLOR}`,
+ background: "#FFF",
+ borderRadius: "6px",
+ boxShadow: `0 1px 2px rgba(0,0,0,0.03),
+ 0 2px 4px rgba(0,0,0,0.03),
+ 0 2px 6px rgba(0,0,0,0.03)`,
+};
+
+export const textColor = {
+ color: TEXT_COLOR,
+};
+
+export const code = {
+ fontFamily: "IBM Plex Mono, monospace",
+};
+
+export const headingHr = {
+ margin: `${unit}px 0`,
+};
+
+export const buttonPrimary = {
+ ...code,
+ padding: "12px 18px",
+ color: "#FFF",
+ borderRadius: "4px",
+ background: BLUE_COLOR,
+ fontSize: "12px",
+ fontWeight: 500,
+};
+
+export const compactText = {
+ margin: "0 0 2px",
+};
+
+export const breadcrumb = {
+ fontSize: "14px",
+ color: SECONDARY_COLOR,
+};
+
+export const breadcrumbColonSeparator = {
+ padding: " 0 4px",
+ color: DIMMED_COLOR,
+};
+
+export const breadcrumbSeparator = {
+ color: DIVIDER_COLOR,
+};
+
+export const heading = {
+ fontSize: "22px",
+ fontWeight: 500,
+};
+
+export const sectionLabel = {
+ ...code,
+ ...compactText,
+ letterSpacing: "0.5px",
+ fontSize: "13px",
+ fontWeight: 500,
+ color: DIMMED_COLOR,
+};
+
+export const footerLink = {
+ fontSize: "14px",
+};
diff --git a/packages/console/mail/emails/templates/InviteEmail.tsx b/packages/console/mail/emails/templates/InviteEmail.tsx
new file mode 100644
index 000000000..978080a9c
--- /dev/null
+++ b/packages/console/mail/emails/templates/InviteEmail.tsx
@@ -0,0 +1,113 @@
+// @ts-nocheck
+import React from "react"
+import { Img, Row, Html, Link, Body, Head, Button, Column, Preview, Section, Container } from "@jsx-email/all"
+import { Hr, Text, Fonts, SplitString, Title, A, Span } from "../components"
+import {
+ unit,
+ body,
+ code,
+ frame,
+ medium,
+ heading,
+ container,
+ headingHr,
+ footerLink,
+ breadcrumb,
+ compactText,
+ buttonPrimary,
+ breadcrumbColonSeparator,
+} from "../styles"
+
+const LOCAL_ASSETS_URL = "/static"
+const CONSOLE_URL = "https://opencode.ai/"
+const DOC_URL = "https://opencode.ai/docs/zen"
+
+interface InviteEmailProps {
+ workspace: string
+ assetsUrl: string
+}
+export const InviteEmail = ({ workspace, assetsUrl = LOCAL_ASSETS_URL }: InviteEmailProps) => {
+ const subject = `Join the ${workspace} workspace`
+ const messagePlain = `You've been invited to join the ${workspace} workspace in the OpenCode Zen Console.`
+ const url = `${CONSOLE_URL}workspace/${workspace}`
+ return (
+ <Html lang="en">
+ <Head>
+ <Title>{`OpenCode Zen — ${messagePlain}`}</Title>
+ </Head>
+ <Fonts assetsUrl={assetsUrl} />
+ <Preview>{messagePlain}</Preview>
+ <Body style={body} id={Math.random().toString()}>
+ <Container style={container}>
+ <Section style={frame}>
+ <Row>
+ <Column>
+ <A href={CONSOLE_URL}>
+ <Img height="32" alt="OpenCode Zen Logo" src={`${assetsUrl}/zen-logo.png`} />
+ </A>
+ </Column>
+ <Column align="right">
+ <Button style={buttonPrimary} href={url}>
+ <Span style={code}>Join Workspace</Span>
+ </Button>
+ </Column>
+ </Row>
+
+ <Row style={headingHr}>
+ <Column>
+ <Hr />
+ </Column>
+ </Row>
+
+ <Section>
+ <Text style={{ ...compactText, ...breadcrumb }}>
+ <Span>OpenCode Zen</Span>
+ <Span style={{ ...code, ...breadcrumbColonSeparator }}>:</Span>
+ <Span>{workspace}</Span>
+ </Text>
+ <Text style={{ ...heading, ...compactText }}>
+ <Link href={url}>
+ <SplitString text={subject} split={40} />
+ </Link>
+ </Text>
+ </Section>
+ <Section style={{ padding: `${unit}px 0 0 0` }}>
+ <Text style={{ ...compactText }}>
+ You've been invited to join the{" "}
+ <Link style={medium} href={url}>
+ {workspace}
+ </Link>{" "}
+ workspace in the{" "}
+ <Link style={medium} href={CONSOLE_URL}>
+ OpenCode Zen Console
+ </Link>
+ .
+ </Text>
+ </Section>
+
+ <Row style={headingHr}>
+ <Column>
+ <Hr />
+ </Column>
+ </Row>
+
+ <Row>
+ <Column>
+ <Link href={CONSOLE_URL} style={footerLink}>
+ Console
+ </Link>
+ </Column>
+ <Column align="right">
+ <Link style={footerLink} href={DOC_URL}>
+ About
+ </Link>
+ </Column>
+ </Row>
+ </Section>
+ </Container>
+ </Body>
+ </Html>
+ )
+}
+
+export default InviteEmail
diff --git a/packages/console/mail/emails/templates/static/ibm-plex-mono-latin-400.woff2 b/packages/console/mail/emails/templates/static/ibm-plex-mono-latin-400.woff2
new file mode 100644
index 000000000..89713fa9a
--- /dev/null
+++ b/packages/console/mail/emails/templates/static/ibm-plex-mono-latin-400.woff2
Binary files differ
diff --git a/packages/console/mail/emails/templates/static/ibm-plex-mono-latin-500.woff2 b/packages/console/mail/emails/templates/static/ibm-plex-mono-latin-500.woff2
new file mode 100644
index 000000000..21413e73f
--- /dev/null
+++ b/packages/console/mail/emails/templates/static/ibm-plex-mono-latin-500.woff2
Binary files differ
diff --git a/packages/console/mail/emails/templates/static/ibm-plex-mono-latin-600.woff2 b/packages/console/mail/emails/templates/static/ibm-plex-mono-latin-600.woff2
new file mode 100644
index 000000000..4a2ebd962
--- /dev/null
+++ b/packages/console/mail/emails/templates/static/ibm-plex-mono-latin-600.woff2
Binary files differ
diff --git a/packages/console/mail/emails/templates/static/ibm-plex-mono-latin-700.woff2 b/packages/console/mail/emails/templates/static/ibm-plex-mono-latin-700.woff2
new file mode 100644
index 000000000..624783be5
--- /dev/null
+++ b/packages/console/mail/emails/templates/static/ibm-plex-mono-latin-700.woff2
Binary files differ
diff --git a/packages/console/mail/emails/templates/static/rubik-latin.woff2 b/packages/console/mail/emails/templates/static/rubik-latin.woff2
new file mode 100644
index 000000000..c533eec64
--- /dev/null
+++ b/packages/console/mail/emails/templates/static/rubik-latin.woff2
Binary files differ
diff --git a/packages/console/mail/emails/templates/static/zen-logo.png b/packages/console/mail/emails/templates/static/zen-logo.png
new file mode 100644
index 000000000..382223627
--- /dev/null
+++ b/packages/console/mail/emails/templates/static/zen-logo.png
Binary files differ