wip: make less shit

This commit is contained in:
Dax Raad
2025-09-03 13:10:57 -04:00
parent 59e550271d
commit 48a79b1173
6 changed files with 38 additions and 48 deletions

View File

@@ -7,7 +7,7 @@ import IMG_SPLASH from "../asset/lander/screenshot-splash.png"
import IMG_VSCODE from "../asset/lander/screenshot-vscode.png"
import IMG_GITHUB from "../asset/lander/screenshot-github.png"
import { IconCopy, IconCheck } from "../component/icon"
import { createAsync, query, redirect } from "@solidjs/router"
import { createAsync, query, redirect, A } from "@solidjs/router"
import { getActor } from "~/context/auth"
import { withActor } from "~/context/auth.withActor"
import { Account } from "@opencode/cloud-core/account.js"
@@ -21,20 +21,17 @@ function CopyStatus() {
)
}
const isLoggedIn = query(async () => {
const defaultWorkspace = query(async () => {
"use server"
const actor = await getActor()
if (actor.type === "account") {
const workspaces = await withActor(() => Account.workspaces())
return workspaces[0].id
// throw redirect(`/workspace/${workspaces[0].id}`)
}
}, "isLoggedIn")
}, "defaultWorkspace")
export default function Home() {
const auth = createAsync(() => isLoggedIn(), {
deferStream: true,
})
const workspace = createAsync(() => defaultWorkspace())
onMount(() => {
const commands = document.querySelectorAll("[data-copy]")
for (const button of commands) {
@@ -90,9 +87,9 @@ export default function Home() {
</a>
<span data-slot="description">, a curated list of models provided by opencode</span>
<span data-slot="divider">&nbsp;/&nbsp;</span>
<a target="_self" data-slot="cta" href="/auth">
{auth() ? "Dashboard" : "Sign in"}
</a>
<A href={workspace() ? "/workspace/" + workspace() : "/auth/authorize"}>
{workspace() ? "Dashboard" : "Sign in"}
</A>
</section>
<section data-component="features">

View File

@@ -3,17 +3,17 @@ import { useAuthSession } from "~/context/auth.session"
import { IconLogo } from "../component/icon"
import { withActor } from "~/context/auth.withActor"
import "./workspace.css"
import { query, action, redirect, createAsync, RouteSectionProps } from "@solidjs/router"
import { query, action, redirect, createAsync, RouteSectionProps, Navigate, useNavigate, useParams, A } from "@solidjs/router"
import { User } from "@opencode/cloud-core/user.js"
import { Actor } from "@opencode/cloud-core/actor.js"
const getUserInfo = query(async () => {
const getUserInfo = query(async (workspaceID: string) => {
"use server"
return withActor(async () => {
const actor = Actor.assert("user")
const user = await User.fromID(actor.properties.userID)
return { user }
})
}, workspaceID)
}, "userInfo")
const logout = action(async () => {
@@ -30,16 +30,15 @@ const logout = action(async () => {
})
export default function WorkspaceLayout(props: RouteSectionProps) {
const userInfo = createAsync(() => getUserInfo(), {
deferStream: true,
})
const params = useParams()
const userInfo = createAsync(() => getUserInfo(params.id))
return (
<main data-page="workspace">
<header data-component="workspace-header">
<div data-slot="header-brand">
<a href="/" data-component="site-title">
<A href="/" data-component="site-title">
<IconLogo />
</a>
</A>
</div>
<div data-slot="header-actions">
<span>{userInfo()?.user.email}</span>

View File

@@ -1,7 +1,7 @@
import "./[id].css"
import { Billing } from "@opencode/cloud-core/billing.js"
import { Key } from "@opencode/cloud-core/key.js"
import { action, createAsync, query, useAction, useSubmission, json } from "@solidjs/router"
import { action, createAsync, query, useAction, useSubmission, json, useParams } from "@solidjs/router"
import { createSignal, For, Show } from "solid-js"
import { withActor } from "~/context/auth.withActor"
import { IconCopy, IconCheck } from "~/component/icon"
@@ -13,23 +13,23 @@ import { Actor } from "@opencode/cloud-core/actor.js"
/////////////////////////////////////
const listKeys = query(async () => {
const listKeys = query(async (workspaceID: string) => {
"use server"
return withActor(() => Key.list())
return withActor(() => Key.list(), workspaceID)
}, "key.list")
const createKey = action(async (name: string) => {
const createKey = action(async (workspaceID: string, name: string) => {
"use server"
return json(
withActor(() => Key.create({ name })),
withActor(() => Key.create({ name }), workspaceID),
{ revalidate: listKeys.key },
)
}, "key.create")
const removeKey = action(async (id: string) => {
const removeKey = action(async (workspaceID: string, id: string) => {
"use server"
return json(
withActor(() => Key.remove({ id })),
withActor(() => Key.remove({ id }), workspaceID),
{ revalidate: listKeys.key },
)
}, "key.remove")
@@ -38,7 +38,7 @@ const removeKey = action(async (id: string) => {
// Billing related queries and actions
/////////////////////////////////////
const getBillingInfo = query(async () => {
const getBillingInfo = query(async (workspaceID: string) => {
"use server"
return withActor(async () => {
const actor = Actor.assert("user")
@@ -51,25 +51,26 @@ const getBillingInfo = query(async () => {
])
console.log("duration", Date.now() - now)
return { user, billing, payments, usage }
})
}, workspaceID)
}, "billingInfo")
const createCheckoutUrl = action(async (successUrl: string, cancelUrl: string) => {
const createCheckoutUrl = action(async (workspaceID: string, successUrl: string, cancelUrl: string) => {
"use server"
return withActor(() => Billing.generateCheckoutUrl({ successUrl, cancelUrl }))
return withActor(() => Billing.generateCheckoutUrl({ successUrl, cancelUrl }), workspaceID)
}, "checkoutUrl")
const createPortalUrl = action(async (returnUrl: string) => {
const createPortalUrl = action(async (workspaceID: string, returnUrl: string) => {
"use server"
return withActor(() => Billing.generatePortalUrl({ returnUrl }))
return withActor(() => Billing.generatePortalUrl({ returnUrl }), workspaceID)
}, "portalUrl")
export default function () {
const params = useParams()
/////////////////
// Keys section
/////////////////
const keys = createAsync(() => listKeys())
const keys = createAsync(() => listKeys(params.id))
const createKeyAction = useAction(createKey)
const removeKeyAction = useAction(removeKey)
const createKeySubmission = useSubmission(createKey)
@@ -134,7 +135,7 @@ export default function () {
if (!keyName().trim()) return
try {
await createKeyAction(keyName().trim())
await createKeyAction(params.id, keyName().trim())
setKeyName("")
setShowCreateForm(false)
} catch (error) {
@@ -148,7 +149,7 @@ export default function () {
}
try {
await removeKeyAction(keyId)
await removeKeyAction(params.id, keyId)
} catch (error) {
console.error("Failed to delete API key:", error)
}
@@ -157,16 +158,14 @@ export default function () {
/////////////////
// Billing section
/////////////////
const billingInfo = createAsync(() => getBillingInfo(), {
deferStream: true,
})
const billingInfo = createAsync(() => getBillingInfo(params.id))
const createCheckoutUrlAction = useAction(createCheckoutUrl)
const createCheckoutUrlSubmission = useSubmission(createCheckoutUrl)
const handleBuyCredits = async () => {
try {
const baseUrl = window.location.href
const checkoutUrl = await createCheckoutUrlAction(baseUrl, baseUrl)
const checkoutUrl = await createCheckoutUrlAction(params.id, baseUrl, baseUrl)
if (checkoutUrl) {
window.location.href = checkoutUrl
}

View File