This commit is contained in:
Frank
2025-10-14 22:52:35 -04:00
parent 83655a3b09
commit 182949dee4
4 changed files with 104 additions and 161 deletions

View File

@@ -134,7 +134,7 @@ export namespace User {
const { InviteEmail } = await import("@opencode-ai/console-mail/InviteEmail.jsx") const { InviteEmail } = await import("@opencode-ai/console-mail/InviteEmail.jsx")
await AWS.sendEmail({ await AWS.sendEmail({
to: email, to: email,
subject: `You've been invited to join the ${emailInfo.workspaceName} workspace on OpenCode Console`, subject: `You've been invited to join the ${emailInfo.workspaceName} workspace on OpenCode`,
body: render( body: render(
// @ts-ignore // @ts-ignore
InviteEmail({ InviteEmail({

View File

@@ -1,26 +1,10 @@
// @ts-nocheck // @ts-nocheck
import React from "react" import React from "react"
import { Font, Hr as JEHr, Text as JEText, type HrProps, type TextProps } from "@jsx-email/all" import { Font, Text as JEText, type TextProps } from "@jsx-email/all"
import { DIVIDER_COLOR, SURFACE_DIVIDER_COLOR, textColor } from "./styles" import { baseText } from "./styles"
export function Text(props: TextProps) { export function Text(props: TextProps) {
return <JEText {...props} style={{ ...textColor, ...props.style }} /> return <JEText {...props} style={{ ...baseText, ...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) { export function Title({ children }: TitleProps) {

View File

@@ -1,110 +1,90 @@
export const unit = 16; export const unit = 12
export const PRIMARY_COLOR = "#211E1E"
export const GREY_COLOR = [ export const TEXT_COLOR = "#656363"
"#1A1A2E", //0 export const LINK_COLOR = "#007AFF"
"#2F2F41", //1 export const LINK_BACKGROUND_COLOR = "#F9F8F8"
"#444454", //2 export const BACKGROUND_COLOR = "#F0F0F1"
"#585867", //3 export const SURFACE_DIVIDER_COLOR = "#D5D5D9"
"#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 = { export const body = {
background: BACKGROUND_COLOR, background: BACKGROUND_COLOR,
}; }
export const container = { export const container = {
minWidth: "600px", minWidth: "600px",
}; padding: "64px 0px",
}
export const medium = {
fontWeight: 500,
};
export const danger = {
color: DANGER_COLOR,
};
export const frame = { export const frame = {
padding: `${unit * 1.5}px`, padding: `${unit * 2}px`,
border: `1px solid ${SURFACE_DIVIDER_COLOR}`, border: `1px solid ${SURFACE_DIVIDER_COLOR}`,
background: "#FFF", background: "#FFF",
borderRadius: "6px", borderRadius: "6px",
boxShadow: `0 1px 2px rgba(0,0,0,0.03), boxShadow: `0 1px 2px rgba(0,0,0,0.03),
0 2px 4px rgba(0,0,0,0.03), 0 2px 4px rgba(0,0,0,0.03),
0 2px 6px rgba(0,0,0,0.03)`, 0 2px 6px rgba(0,0,0,0.03)`,
}; }
export const textColor = { export const baseText = {
fontFamily: "JetBrains Mono, monospace",
}
export const headingText = {
color: PRIMARY_COLOR,
fontSize: "16px",
fontStyle: "normal",
fontWeight: 500,
lineHeight: "normal",
}
export const contentText = {
color: TEXT_COLOR, color: TEXT_COLOR,
}; fontSize: "14px",
fontStyle: "normal",
fontWeight: 400,
lineHeight: "180%",
}
export const code = { export const buttonText = {
fontFamily: "IBM Plex Mono, monospace", color: "#FDFCFC",
}; fontSize: "16px",
fontWeight: 500,
margin: 0,
padding: 0,
display: "inline-flex",
alignItems: "center",
gap: "8px",
}
export const headingHr = { export const linkText = {
margin: `${unit}px 0`, color: LINK_COLOR,
}; fontSize: "14px",
fontStyle: "normal",
export const buttonPrimary = { fontWeight: 400,
...code, lineHeight: "150%",
padding: "12px 18px", textDecorationLine: "underline",
color: "#FFF", textDecorationStyle: "solid" as const,
textDecorationSkipInk: "auto" as const,
textDecorationThickness: "auto",
textUnderlineOffset: "auto",
textUnderlinePosition: "from-font",
borderRadius: "4px", borderRadius: "4px",
background: BLUE_COLOR, background: LINK_BACKGROUND_COLOR,
fontSize: "12px", padding: "8px 12px",
fontWeight: 500, textAlign: "center" as const,
}; }
export const compactText = { export const contentHighlightText = {
margin: "0 0 2px", color: PRIMARY_COLOR,
}; }
export const breadcrumb = { export const button = {
fontSize: "14px", display: "inline-grid",
color: SECONDARY_COLOR, padding: "8px 12px 8px 20px",
}; justifyContent: "center",
alignItems: "center",
export const breadcrumbColonSeparator = { gap: "8px",
padding: " 0 4px", flexShrink: "0",
color: DIMMED_COLOR, borderRadius: "4px",
}; backgroundColor: PRIMARY_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",
};

View File

@@ -1,26 +1,20 @@
// @ts-nocheck
import React from "react" import React from "react"
import { Img, Row, Html, Link, Body, Head, Button, Column, Preview, Section, Container } from "@jsx-email/all" import { Img, Row, Html, Link, Body, Head, Button, Column, Preview, Section, Container } from "@jsx-email/all"
import { Hr, Text, Fonts, SplitString, Title, A, Span, B } from "../components" import { Text, Fonts, Title, A, Span } from "../components"
import { import {
unit, unit,
body, body,
code,
frame, frame,
medium, headingText,
heading,
container, container,
headingHr, contentText,
footerLink, button,
breadcrumb, contentHighlightText,
compactText, linkText,
buttonPrimary, buttonText,
breadcrumbColonSeparator,
} from "../styles" } from "../styles"
const LOCAL_ASSETS_URL = "/static"
const CONSOLE_URL = "https://opencode.ai/" const CONSOLE_URL = "https://opencode.ai/"
const DOC_URL = "https://opencode.ai/docs/zen"
interface InviteEmailProps { interface InviteEmailProps {
inviter: string inviter: string
@@ -32,9 +26,8 @@ export const InviteEmail = ({
inviter = "test@anoma.ly", inviter = "test@anoma.ly",
workspaceID = "wrk_01K6XFY7V53T8XN0A7X8G9BTN3", workspaceID = "wrk_01K6XFY7V53T8XN0A7X8G9BTN3",
workspaceName = "anomaly", workspaceName = "anomaly",
assetsUrl = LOCAL_ASSETS_URL, assetsUrl = `${CONSOLE_URL}email`,
}: InviteEmailProps) => { }: InviteEmailProps) => {
const subject = `You've been invited to join the ${workspaceName} workspace on OpenCode Console`
const messagePlain = `${inviter} invited you to join the ${workspaceName} workspace.` const messagePlain = `${inviter} invited you to join the ${workspaceName} workspace.`
const url = `${CONSOLE_URL}workspace/${workspaceID}` const url = `${CONSOLE_URL}workspace/${workspaceID}`
return ( return (
@@ -55,50 +48,36 @@ export const InviteEmail = ({
</Column> </Column>
</Row> </Row>
<Row style={headingHr}> <Section style={{ padding: `${unit * 2}px 0 0 0` }}>
<Column> <Text style={headingText}>Join your team's OpenCode workspace</Text>
<Hr /> <Text style={contentText}>
</Column> You have been invited by <Span style={contentHighlightText}>{inviter}</Span> to join the{" "}
</Row> <Span style={contentHighlightText}>{workspaceName}</Span> workspace on OpenCode.
<Section style={{ padding: `${unit}px 0 0 0` }}>
<Text style={{ ...compactText }}>
<B>{inviter}</B> invited you to join the{" "}
<Link style={medium} href={url}>
<B>{workspaceName}</B>
</Link>{" "}
workspace in the{" "}
<Link style={medium} href={`${CONSOLE_URL}zen`}>
OpenCode Console
</Link>
.
</Text> </Text>
</Section> </Section>
<Section style={{ padding: `${unit}px 0 0 0` }}> <Section style={{ padding: `${unit}px 0 0 0` }}>
<Button style={buttonPrimary} href={url}> <Button style={button} href={url}>
<Span style={code}>Join Workspace</Span> <Text style={buttonText}>
Join workspace
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none">
<path
d="M6.5 12L17 12M13 16.5L17.5 12L13 7.5"
stroke="#FDFCFC"
strokeWidth="1.5"
strokeLinecap="square"
/>
</svg>
</Text>
</Button> </Button>
</Section> </Section>
<Row style={headingHr}> <Section style={{ padding: `${unit}px 0 0 0` }}>
<Column> <Text style={contentText}>Button not working? Copy the following link...</Text>
<Hr /> <Link href={url}>
</Column> <Text style={linkText}>{url}</Text>
</Row> </Link>
</Section>
<Row>
<Column>
<Link href={`${CONSOLE_URL}zen`} style={footerLink}>
Console
</Link>
</Column>
<Column align="right">
<Link style={footerLink} href={DOC_URL}>
About
</Link>
</Column>
</Row>
</Section> </Section>
</Container> </Container>
</Body> </Body>