Skip to content

Commit

Permalink
refactor,feat: update better-auth, add audio toggle to view
Browse files Browse the repository at this point in the history
add audio toggle and tooltips to view, prefetch data, and other improvements

refactor other functions, use better-auth func for admin reset pw
  • Loading branch information
IncognitoTGT committed Feb 17, 2025
1 parent 4461bfe commit 74030d4
Show file tree
Hide file tree
Showing 14 changed files with 207 additions and 94 deletions.
22 changes: 11 additions & 11 deletions apps/web/src/app/(main)/admin/users/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,10 @@
import { check } from "@/lib/admin-check";
import { deleteSession } from "@/lib/session/manage";
import auth from "@stardust/common/auth";
import { hashPassword } from "@stardust/common/auth/lib";
import db, { account, session, user } from "@stardust/db";
import { and, eq } from "@stardust/db/utils";
import { revalidatePath } from "next/cache";
import { headers } from "next/headers";
import { headers as getHeaders } from "next/headers";
export const revalidateHandler = async () => revalidatePath("/admin/users");
export async function deleteUserSessions(id: string) {
await db.transaction(async (tx) => {
Expand Down Expand Up @@ -41,16 +40,16 @@ export async function safeDeleteUser(id: string) {
body: {
userId: id,
},
headers: await headers(),
headers: await getHeaders(),
});
if (res.success) {
revalidateHandler();
return res;
}
}
export async function resetPassword(id: string, data: FormData) {
await check();
try {
const headers = await getHeaders();
const where = and(eq(account.userId, id), eq(account.providerId, "credential"));
const [dbEntry] = await db.select().from(account).where(where);
if (!dbEntry) throw new Error("credentials signin not enabled for user");
Expand All @@ -61,15 +60,16 @@ export async function resetPassword(id: string, data: FormData) {
body: {
userId: id,
},
headers: await headers(),
headers,
});
}
await db
.update(account)
.set({
password: await hashPassword(newPassword),
})
.where(where);
await auth.api.setUserPassword({
body: {
newPassword,
userId: id,
},
headers,
});
} catch (e) {
return { error: (e as Error).message };
}
Expand Down
47 changes: 36 additions & 11 deletions apps/web/src/app/(main)/admin/workspaces/columns.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,14 @@
"use client";
import {
AlertDialog,
AlertDialogAction,
AlertDialogCancel,
AlertDialogContent,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogTitle,
} from "@/components/ui/alert-dialog";
import { Button } from "@/components/ui/button";
import {
DropdownMenu,
Expand Down Expand Up @@ -45,10 +55,35 @@ export const columns: ColumnDef<SelectWorkspace & { nodes: string[] }>[] = [
cell: ({ row: { original: workspace } }) => {
const [updateDialogOpen, setUpdateDialogOpen] = useState(false);
const [nodeDialogOpen, setNodeDialogOpen] = useState(false);
const [deleteDialogOpen, setDeleteDialogOpen] = useState(false);
return (
<>
<UpdateDialog workspace={workspace} open={updateDialogOpen} setOpen={setUpdateDialogOpen} />
<NodeDialog workspace={workspace} open={nodeDialogOpen} setOpen={setNodeDialogOpen} />
<AlertDialog open={deleteDialogOpen} onOpenChange={setDeleteDialogOpen}>
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle>Delete Workspace</AlertDialogTitle>
<AlertDialogDescription>
Are you sure you want to delete {workspace.friendlyName}?
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel>Nevermind</AlertDialogCancel>
<AlertDialogAction
onClick={() =>
toast.promise(() => deleteWorkspace(workspace), {
loading: "Deleting workspace...",
success: "Workspace deleted",
error: "Failed to delete workspace",
})
}
>
Yes, delete
</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="ghost" className="h-8 w-8 p-0">
Expand All @@ -60,17 +95,7 @@ export const columns: ColumnDef<SelectWorkspace & { nodes: string[] }>[] = [
<DropdownMenuLabel>Actions</DropdownMenuLabel>
<DropdownMenuItem onClick={() => setUpdateDialogOpen(true)}>Edit metadata</DropdownMenuItem>
<DropdownMenuItem onClick={() => setNodeDialogOpen(true)}>Edit nodes</DropdownMenuItem>
<DropdownMenuItem
onClick={() =>
toast.promise(() => deleteWorkspace(workspace), {
loading: "Deleting workspace...",
success: "Workspace deleted",
error: "Failed to delete workspace",
})
}
>
Delete from database
</DropdownMenuItem>
<DropdownMenuItem onClick={() => setDeleteDialogOpen(true)}>Delete from database</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</>
Expand Down
2 changes: 1 addition & 1 deletion apps/web/src/app/(main)/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export default async function Dashboard() {
return (
<div className="m-auto flex w-full flex-col p-4">
<h1 className="text-3xl font-bold mb-6">Workspaces</h1>
<section className="flex flex-wrap gap-4 justify-between">
<section className="flex flex-wrap gap-4">
<Suspense fallback={<Loader2 size={64} className="animate-spin" />}>
{workspaces.length ? (
workspaces.map((workspace) => (
Expand Down
2 changes: 2 additions & 0 deletions apps/web/src/app/api/session/[slug]/addscreen/route.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { getNode } from "@/lib/session/client";
import getSession from "@/lib/session/get-session";
import { notFound } from "next/navigation";
import type { NextRequest } from "next/server";

export async function POST(_req: NextRequest, props: { params: Promise<{ slug: string }> }) {
const params = await props.params;
const session = await getSession(params.slug);
if (!session) notFound();
const nodeSession = getNode(session).sessions({ id: session.id });
await nodeSession.addscreen.put();
console.log("hi");
Expand Down
3 changes: 3 additions & 0 deletions apps/web/src/app/api/session/[slug]/files/route.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import { getNode } from "@/lib/session/client";
import getSession from "@/lib/session/get-session";
import { getConfig } from "@stardust/config";
import { notFound } from "next/navigation";
import type { NextRequest } from "next/server";

export async function GET(req: NextRequest, props: { params: Promise<{ slug: string }> }) {
const params = await props.params;
const name = req.nextUrl.searchParams.get("name");
const session = await getSession(params.slug);
if (!session) notFound();
const nodeSession = getNode(session).sessions({ id: session.id });
if (name) {
const { data, error } = await nodeSession.files.download({ name }).get();
Expand All @@ -27,6 +29,7 @@ export async function PUT(req: NextRequest, props: { params: Promise<{ slug: str
const name = req.nextUrl.searchParams.get("name");
if (!name) return Response.json({ error: "no file name or file specified" }, { status: 400 });
const session = await getSession(params.slug);
if (!session) notFound();
// eden being stupid
const sessionNode = getConfig().nodes.find(({ id }) => id === session.node);
const data = await (
Expand Down
2 changes: 2 additions & 0 deletions apps/web/src/app/api/session/[slug]/preview/route.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { getNode } from "@/lib/session/client";
import getSession from "@/lib/session/get-session";
import { notFound } from "next/navigation";
import type { NextRequest } from "next/server";
export async function GET(_req: NextRequest, props: { params: Promise<{ slug: string }> }) {
const params = await props.params;
const session = await getSession(params.slug);
if (!session) notFound();
const nodeSession = getNode(session).sessions({ id: session.id });
const { data, error } = await nodeSession.screenshot.get();
if (error) return Response.json({ error }, { status: 500 });
Expand Down
2 changes: 1 addition & 1 deletion apps/web/src/app/api/session/[slug]/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import type { NextRequest } from "next/server";

export async function GET(_req: NextRequest, props: { params: Promise<{ slug: string }> }) {
const params = await props.params;
const session = await getSession(params.slug).catch(() => {});
const session = await getSession(params.slug);
if (!session) {
return Response.json({ exists: false, error: "Container not found" }, { status: 404 });
}
Expand Down
36 changes: 33 additions & 3 deletions apps/web/src/app/view/[slug]/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,44 @@
import { getNode } from "@/lib/session/client";
import getSession from "@/lib/session/get-session";
import type { Metadata } from "next";
import { notFound } from "next/navigation";
import { SWRConfig } from "swr";
export async function generateMetadata(props: { params: Promise<{ slug: string }> }): Promise<Metadata> {
const params = await props.params;
const session = await getSession(params.slug);
return {
title: `Session ${params.slug.slice(0, 6)}`,
title: session ? `Session ${params.slug.slice(0, 6)}` : "Invalid Session",
};
}
export default function ViewLayout({
export default async function ViewLayout({
children,
params,
}: {
children: React.ReactNode;
params: Promise<{ slug: string }>;
}) {
return children;
const { slug } = await params;
const session = await getSession(slug);
if (!session) notFound();
const nodeSession = getNode(session).sessions({ id: session.id });
const { data: info, error: infoError } = await nodeSession.get();
const { data: files, error: filesError } = await nodeSession.files.list.get();
if (!info?.State.Running) await nodeSession.patch({ action: "start" });
if (info?.State.Paused) await nodeSession.patch({ action: "unpause" });
return (
<SWRConfig
value={{
fallback: {
[`/api/session/${slug}`]: {
exists: true,
error: infoError,
password: info?.password,
},
[`/api/session/${slug}/files`]: filesError || !files.success ? filesError : files.list,
},
}}
>
{children}
</SWRConfig>
);
}
Loading

0 comments on commit 74030d4

Please sign in to comment.