Compare commits

...
Author SHA1 Message Date
Meier Lukas 7251938294 feat: add board preview 2024-05-04 22:27:04 +02:00
3 changed files with 112 additions and 1 deletions

No files matched your search

@@ -0,0 +1,83 @@
"use client";
import { Box, Card, Center, Flex, Loader, Text } from "@mantine/core";
import { useElementSize } from "@mantine/hooks";
import dayjs from "dayjs";
import type { RouterOutputs } from "@homarr/api";
interface BoardPreviewProps {
board: RouterOutputs["board"]["getAllBoards"][number];
}
export const BoardPreview = ({ board }: BoardPreviewProps) => {
const { ref, width } = useElementSize();
return (
<Card
h="100%"
mah={width ? (width / 1920) * 1080 : undefined}
ref={ref}
styles={{
root: {
"--gridstack-column-count": board.columnCount,
"--gridstack-widget-width": width / board.columnCount,
},
}}
>
{width === 0 ? (
<Center h="100%">
<Loader size="sm" />
</Center>
) : (
<>
{board.sections.map((section) => (
<Section
key={section.id}
section={section}
itemWidth={width / board.columnCount}
/>
))}
</>
)}
</Card>
);
};
interface SectionProps {
section: RouterOutputs["board"]["getAllBoards"][number]["sections"][number];
itemWidth: number;
}
const Section = ({ section, itemWidth }: SectionProps) => {
const maxHeight = Math.max(
...section.items.map((item) => item.yOffset + item.height),
);
return (
<Card
withBorder={section.kind === "category"}
h={maxHeight * itemWidth}
key={section.id}
className="grid-stack"
>
{section.items.map((item) => (
<Box
className="grid-stack-item"
gs-h={item.height}
gs-w={item.width}
gs-x={item.xOffset}
gs-y={item.yOffset}
key={item.id}
p={4}
>
<Card withBorder h="100%" p={0}>
<Flex justify="center" align="center" h="100%" w="100%">
<Text fz={itemWidth / 4}>{dayjs().format("HH:mm")}</Text>
</Flex>
</Card>
</Box>
))}
</Card>
);
};
@@ -15,12 +15,16 @@ import {
} from "@mantine/core";
import { IconDotsVertical, IconLock, IconWorld } from "@tabler/icons-react";
import "~/styles/gridstack.scss";
import type { RouterOutputs } from "@homarr/api";
import { api } from "@homarr/api/server";
import { getScopedI18n } from "@homarr/translation/server";
import { UserAvatar } from "@homarr/ui";
import { getBoardPermissions } from "~/components/board/permissions/server";
import { BoardCardMenuDropdown } from "./_components/board-card-menu-dropdown";
import { BoardPreview } from "./_components/board-preview";
import { CreateBoardButton } from "./_components/create-board-button";
export default async function ManageBoardsPage() {
@@ -37,7 +41,7 @@ export default async function ManageBoardsPage() {
<Grid>
{boards.map((board) => (
<GridCol span={{ xs: 12, md: 4 }} key={board.id}>
<GridCol span={{ base: 12, md: 6, xl: 4 }} key={board.id}>
<BoardCard board={board} />
</GridCol>
))}
@@ -68,9 +72,22 @@ const BoardCard = async ({ board }: BoardCardProps) => {
{board.name}
</Text>
</Group>
{board.creator && (
<Group>
<Group gap="xs">
<UserAvatar user={board.creator} size="sm" />
<Text>{board.creator?.name}</Text>
</Group>
</Group>
)}
</Group>
</CardSection>
<CardSection p="sm" style={{ aspectRatio: 1920 / 1080 }}>
<BoardPreview board={board} />
</CardSection>
<CardSection p="sm">
<Group wrap="nowrap">
<Button
+11
View File
@@ -64,6 +64,7 @@ export const boardRouter = createTRPCRouter({
columns: {
id: true,
name: true,
columnCount: true,
isPublic: true,
},
with: {
@@ -77,6 +78,16 @@ export const boardRouter = createTRPCRouter({
userPermissions: {
where: eq(boardUserPermissions.userId, ctx.session?.user.id ?? ""),
},
sections: {
with: {
items: {
columns: {
options: false,
sectionId: false,
},
},
},
},
groupPermissions: {
where:
permissionsOfCurrentUserGroupsWhenPresent.length >= 1