Board setup.

This commit is contained in:
Mike Cao 2026-01-16 19:52:16 -08:00
parent f97c840825
commit e08907d998
9 changed files with 141 additions and 23 deletions

View file

@ -13,9 +13,5 @@ export function BoardProvider({ boardId, children }: { boardId: string; children
return <Loading placement="absolute" />;
}
if (!board) {
return null;
}
return <BoardContext.Provider value={board}>{children}</BoardContext.Provider>;
}

View file

@ -1,21 +1,48 @@
import { Button, Column, Grid, Heading, Row, TextField } from '@umami/react-zen';
import { useMessages } from '@/components/hooks';
import { Column, Grid, Heading, LoadingButton, Row, TextField, useToast } from '@umami/react-zen';
import { useState } from 'react';
import { useApi, useBoard, useMessages, useModified, useNavigation } from '@/components/hooks';
export function BoardHeader() {
const { formatMessage, labels } = useMessages();
const board = useBoard();
const { formatMessage, labels, messages } = useMessages();
const { post, useMutation } = useApi();
const { touch } = useModified();
const { router, renderUrl } = useNavigation();
const { toast } = useToast();
const defaultName = formatMessage(labels.untitled);
const name = '';
const description = '';
const handleNameChange = (name: string) => {
//updateReport({ name: name || defaultName });
const [name, setName] = useState(board?.name ?? '');
const [description, setDescription] = useState(board?.description ?? '');
const { mutateAsync, isPending } = useMutation({
mutationFn: (data: { name: string; description: string }) => {
if (board) {
return post(`/boards/${board.id}`, data);
}
return post('/boards', { ...data, type: 'dashboard', slug: '' });
},
});
const handleNameChange = (value: string) => {
setName(value);
};
const handleDescriptionChange = (description: string) => {
//updateReport({ description });
const handleDescriptionChange = (value: string) => {
setDescription(value);
};
return <h1>asdgfviybiyu8oaero8g9873qrgb875qh0g8</h1>;
const handleSave = async () => {
const result = await mutateAsync({ name: name || defaultName, description });
toast(formatMessage(messages.saved));
touch('boards');
if (board) {
touch(`board:${board.id}`);
} else if (result?.id) {
router.push(renderUrl(`/boards/${result.id}`));
}
};
return (
<Grid
@ -25,14 +52,12 @@ export function BoardHeader() {
border="bottom"
gapX="6"
>
asdfasdfds
<Column>
<Row>
<TextField
variant="quiet"
name="name"
value={name}
defaultValue={name}
placeholder={defaultName}
onChange={handleNameChange}
autoComplete="off"
@ -46,7 +71,6 @@ export function BoardHeader() {
variant="quiet"
name="description"
value={description}
defaultValue={description}
placeholder={`+ ${formatMessage(labels.addDescription)}`}
autoComplete="off"
onChange={handleDescriptionChange}
@ -57,7 +81,9 @@ export function BoardHeader() {
</Row>
</Column>
<Column justifyContent="center" alignItems="flex-end">
<Button variant="primary">{formatMessage(labels.save)}</Button>
<LoadingButton variant="primary" onPress={handleSave} isLoading={isPending}>
{formatMessage(labels.save)}
</LoadingButton>
</Column>
</Grid>
);

View file

@ -1,5 +1,6 @@
'use client';
import { Column } from '@umami/react-zen';
import { BoardBody } from '@/app/(main)/boards/[boardId]/BoardBody';
import { BoardHeader } from '@/app/(main)/boards/[boardId]/BoardHeader';
import { BoardProvider } from '@/app/(main)/boards/BoardProvider';
import { PageBody } from '@/components/common/PageBody';
@ -10,6 +11,7 @@ export function BoardPage({ boardId }: { boardId: string }) {
<PageBody>
<Column>
<BoardHeader />
<BoardBody />
</Column>
</PageBody>
</BoardProvider>

View file

@ -4,7 +4,7 @@ import { BoardPage } from './BoardPage';
export default async function ({ params }: { params: Promise<{ boardId: string }> }) {
const { boardId } = await params;
return <BoardPage boardId={boardId} />;
return <BoardPage boardId={boardId !== 'create' ? boardId : undefined} />;
}
export const metadata: Metadata = {

View file

@ -26,7 +26,7 @@ export async function GET(request: Request, { params }: { params: Promise<{ boar
export async function POST(request: Request, { params }: { params: Promise<{ boardId: string }> }) {
const schema = z.object({
name: z.string().optional(),
domain: z.string().optional(),
description: z.string().optional(),
shareId: z.string().regex(SHARE_ID_REGEX).nullable().optional(),
});
@ -37,14 +37,14 @@ export async function POST(request: Request, { params }: { params: Promise<{ boa
}
const { boardId } = await params;
const { name, domain, shareId } = body;
const { name, description, shareId } = body;
if (!(await canUpdateBoard(auth, boardId))) {
return unauthorized();
}
try {
const board = await updateBoard(boardId, { name, domain, shareId });
const board = await updateBoard(boardId, { name, description, shareId });
return Response.json(board);
} catch (e: any) {