diff options
| author | Frank <[email protected]> | 2025-10-01 19:34:37 -0400 |
|---|---|---|
| committer | Frank <[email protected]> | 2025-10-01 19:34:37 -0400 |
| commit | 70da3a9399d3385b53f7831beb08f716b972860d (patch) | |
| tree | 6934fafb8558d426df88ca83d043eb3ac5910dcd /packages/console/mail/emails | |
| parent | 1024537b471c341581826b39c360d34d6c32404f (diff) | |
| download | opencode-70da3a9399d3385b53f7831beb08f716b972860d.tar.gz opencode-70da3a9399d3385b53f7831beb08f716b972860d.zip | |
wip: zen
Diffstat (limited to 'packages/console/mail/emails')
| -rw-r--r-- | packages/console/mail/emails/components.tsx | 108 | ||||
| -rw-r--r-- | packages/console/mail/emails/styles.ts | 110 | ||||
| -rw-r--r-- | packages/console/mail/emails/templates/InviteEmail.tsx | 113 | ||||
| -rw-r--r-- | packages/console/mail/emails/templates/static/ibm-plex-mono-latin-400.woff2 | bin | 0 -> 10088 bytes | |||
| -rw-r--r-- | packages/console/mail/emails/templates/static/ibm-plex-mono-latin-500.woff2 | bin | 0 -> 10132 bytes | |||
| -rw-r--r-- | packages/console/mail/emails/templates/static/ibm-plex-mono-latin-600.woff2 | bin | 0 -> 10148 bytes | |||
| -rw-r--r-- | packages/console/mail/emails/templates/static/ibm-plex-mono-latin-700.woff2 | bin | 0 -> 10140 bytes | |||
| -rw-r--r-- | packages/console/mail/emails/templates/static/rubik-latin.woff2 | bin | 0 -> 35320 bytes | |||
| -rw-r--r-- | packages/console/mail/emails/templates/static/zen-logo.png | bin | 0 -> 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 Binary files differnew file mode 100644 index 000000000..89713fa9a --- /dev/null +++ b/packages/console/mail/emails/templates/static/ibm-plex-mono-latin-400.woff2 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 Binary files differnew file mode 100644 index 000000000..21413e73f --- /dev/null +++ b/packages/console/mail/emails/templates/static/ibm-plex-mono-latin-500.woff2 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 Binary files differnew file mode 100644 index 000000000..4a2ebd962 --- /dev/null +++ b/packages/console/mail/emails/templates/static/ibm-plex-mono-latin-600.woff2 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 Binary files differnew file mode 100644 index 000000000..624783be5 --- /dev/null +++ b/packages/console/mail/emails/templates/static/ibm-plex-mono-latin-700.woff2 diff --git a/packages/console/mail/emails/templates/static/rubik-latin.woff2 b/packages/console/mail/emails/templates/static/rubik-latin.woff2 Binary files differnew file mode 100644 index 000000000..c533eec64 --- /dev/null +++ b/packages/console/mail/emails/templates/static/rubik-latin.woff2 diff --git a/packages/console/mail/emails/templates/static/zen-logo.png b/packages/console/mail/emails/templates/static/zen-logo.png Binary files differnew file mode 100644 index 000000000..382223627 --- /dev/null +++ b/packages/console/mail/emails/templates/static/zen-logo.png |
