mirror of
https://github.com/aljazceru/opencode.git
synced 2025-12-19 08:44:22 +01:00
wip: zen
This commit is contained in:
@@ -11,6 +11,7 @@ import { Account } from "./account"
|
|||||||
import { AccountTable } from "./schema/account.sql"
|
import { AccountTable } from "./schema/account.sql"
|
||||||
import { Key } from "./key"
|
import { Key } from "./key"
|
||||||
import { KeyTable } from "./schema/key.sql"
|
import { KeyTable } from "./schema/key.sql"
|
||||||
|
import { WorkspaceTable } from "./schema/workspace.sql"
|
||||||
|
|
||||||
export namespace User {
|
export namespace User {
|
||||||
const assertNotSelf = (id: string) => {
|
const assertNotSelf = (id: string) => {
|
||||||
@@ -115,6 +116,21 @@ export namespace User {
|
|||||||
|
|
||||||
// send email, ignore errors
|
// send email, ignore errors
|
||||||
try {
|
try {
|
||||||
|
const emailInfo = await Database.use((tx) =>
|
||||||
|
tx
|
||||||
|
.select({
|
||||||
|
email: AccountTable.email,
|
||||||
|
workspaceName: WorkspaceTable.name,
|
||||||
|
})
|
||||||
|
.from(UserTable)
|
||||||
|
.innerJoin(AccountTable, eq(UserTable.accountID, AccountTable.id))
|
||||||
|
.innerJoin(WorkspaceTable, eq(WorkspaceTable.id, workspaceID))
|
||||||
|
.where(
|
||||||
|
and(eq(UserTable.workspaceID, workspaceID), eq(UserTable.id, Actor.assert("user").properties.userID)),
|
||||||
|
)
|
||||||
|
.then((rows) => rows[0]),
|
||||||
|
)
|
||||||
|
|
||||||
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,
|
||||||
@@ -122,8 +138,10 @@ export namespace User {
|
|||||||
body: render(
|
body: render(
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
InviteEmail({
|
InviteEmail({
|
||||||
|
inviter: emailInfo.email,
|
||||||
assetsUrl: `https://opencode.ai/email`,
|
assetsUrl: `https://opencode.ai/email`,
|
||||||
workspace: workspaceID,
|
workspaceID: workspaceID,
|
||||||
|
workspaceName: emailInfo.workspaceName,
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -31,6 +31,10 @@ export function A({ children, ...props }: AProps) {
|
|||||||
return React.createElement("a", props, children)
|
return React.createElement("a", props, children)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function B({ children, ...props }: AProps) {
|
||||||
|
return React.createElement("b", props, children)
|
||||||
|
}
|
||||||
|
|
||||||
export function Span({ children, ...props }: SpanProps) {
|
export function Span({ children, ...props }: SpanProps) {
|
||||||
return React.createElement("span", props, children)
|
return React.createElement("span", props, children)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// @ts-nocheck
|
// @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 } from "../components"
|
import { Hr, Text, Fonts, SplitString, Title, A, Span, B } from "../components"
|
||||||
import {
|
import {
|
||||||
unit,
|
unit,
|
||||||
body,
|
body,
|
||||||
@@ -23,17 +23,24 @@ const CONSOLE_URL = "https://opencode.ai/"
|
|||||||
const DOC_URL = "https://opencode.ai/docs/zen"
|
const DOC_URL = "https://opencode.ai/docs/zen"
|
||||||
|
|
||||||
interface InviteEmailProps {
|
interface InviteEmailProps {
|
||||||
workspace: string
|
inviter: string
|
||||||
|
workspaceID: string
|
||||||
|
workspaceName: string
|
||||||
assetsUrl: string
|
assetsUrl: string
|
||||||
}
|
}
|
||||||
export const InviteEmail = ({ workspace, assetsUrl = LOCAL_ASSETS_URL }: InviteEmailProps) => {
|
export const InviteEmail = ({
|
||||||
const subject = `Join the ${workspace} workspace`
|
inviter = "test@anoma.ly",
|
||||||
const messagePlain = `You've been invited to join the ${workspace} workspace in the OpenCode Zen Console.`
|
workspaceID = "wrk_01K6XFY7V53T8XN0A7X8G9BTN3",
|
||||||
const url = `${CONSOLE_URL}workspace/${workspace}`
|
workspaceName = "anomaly",
|
||||||
|
assetsUrl = LOCAL_ASSETS_URL,
|
||||||
|
}: InviteEmailProps) => {
|
||||||
|
const subject = `You were invited to the OpenCode Console`
|
||||||
|
const messagePlain = `${inviter} invited you to join the ${workspaceName} workspace (${workspaceID}).`
|
||||||
|
const url = `${CONSOLE_URL}workspace/${workspaceID}`
|
||||||
return (
|
return (
|
||||||
<Html lang="en">
|
<Html lang="en">
|
||||||
<Head>
|
<Head>
|
||||||
<Title>{`OpenCode Zen — ${messagePlain}`}</Title>
|
<Title>{`OpenCode — ${messagePlain}`}</Title>
|
||||||
</Head>
|
</Head>
|
||||||
<Fonts assetsUrl={assetsUrl} />
|
<Fonts assetsUrl={assetsUrl} />
|
||||||
<Preview>{messagePlain}</Preview>
|
<Preview>{messagePlain}</Preview>
|
||||||
@@ -42,15 +49,10 @@ export const InviteEmail = ({ workspace, assetsUrl = LOCAL_ASSETS_URL }: InviteE
|
|||||||
<Section style={frame}>
|
<Section style={frame}>
|
||||||
<Row>
|
<Row>
|
||||||
<Column>
|
<Column>
|
||||||
<A href={CONSOLE_URL}>
|
<A href={`${CONSOLE_URL}zen`}>
|
||||||
<Img height="32" alt="OpenCode Zen Logo" src={`${assetsUrl}/zen-logo.png`} />
|
<Img height="32" alt="OpenCode Logo" src={`${assetsUrl}/logo.png`} />
|
||||||
</A>
|
</A>
|
||||||
</Column>
|
</Column>
|
||||||
<Column align="right">
|
|
||||||
<Button style={buttonPrimary} href={url}>
|
|
||||||
<Span style={code}>Join Workspace</Span>
|
|
||||||
</Button>
|
|
||||||
</Column>
|
|
||||||
</Row>
|
</Row>
|
||||||
|
|
||||||
<Row style={headingHr}>
|
<Row style={headingHr}>
|
||||||
@@ -59,32 +61,26 @@ export const InviteEmail = ({ workspace, assetsUrl = LOCAL_ASSETS_URL }: InviteE
|
|||||||
</Column>
|
</Column>
|
||||||
</Row>
|
</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` }}>
|
<Section style={{ padding: `${unit}px 0 0 0` }}>
|
||||||
<Text style={{ ...compactText }}>
|
<Text style={{ ...compactText }}>
|
||||||
You've been invited to join the{" "}
|
<B>{inviter}</B> invited you to join the{" "}
|
||||||
<Link style={medium} href={url}>
|
<Link style={medium} href={url}>
|
||||||
{workspace}
|
<B>{workspaceName}</B>
|
||||||
</Link>{" "}
|
</Link>{" "}
|
||||||
workspace in the{" "}
|
workspace ({workspaceID}) in the{" "}
|
||||||
<Link style={medium} href={CONSOLE_URL}>
|
<Link style={medium} href={`${CONSOLE_URL}zen`}>
|
||||||
OpenCode Zen Console
|
OpenCode Console
|
||||||
</Link>
|
</Link>
|
||||||
.
|
.
|
||||||
</Text>
|
</Text>
|
||||||
</Section>
|
</Section>
|
||||||
|
|
||||||
|
<Section style={{ padding: `${unit}px 0 0 0` }}>
|
||||||
|
<Button style={buttonPrimary} href={url}>
|
||||||
|
<Span style={code}>Join Workspace</Span>
|
||||||
|
</Button>
|
||||||
|
</Section>
|
||||||
|
|
||||||
<Row style={headingHr}>
|
<Row style={headingHr}>
|
||||||
<Column>
|
<Column>
|
||||||
<Hr />
|
<Hr />
|
||||||
@@ -93,7 +89,7 @@ export const InviteEmail = ({ workspace, assetsUrl = LOCAL_ASSETS_URL }: InviteE
|
|||||||
|
|
||||||
<Row>
|
<Row>
|
||||||
<Column>
|
<Column>
|
||||||
<Link href={CONSOLE_URL} style={footerLink}>
|
<Link href={`${CONSOLE_URL}zen`} style={footerLink}>
|
||||||
Console
|
Console
|
||||||
</Link>
|
</Link>
|
||||||
</Column>
|
</Column>
|
||||||
|
|||||||
BIN
packages/console/mail/emails/templates/static/logo.png
Normal file
BIN
packages/console/mail/emails/templates/static/logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.7 KiB |
Reference in New Issue
Block a user