Refactor Next.js configuration and remove Sentry integration

- Updated `serverExternalPackages` in the Next.js configuration to exclude `@sentry/node`, improving compatibility with React's RSC/client boundary.
- Removed the `instrumentation.ts` file and refactored Sentry-related code to a no-op, ensuring it does not interfere with the Next.js build process.
- Simplified the dashboard page by integrating `DashboardGuildGrid`, enhancing the user interface and reducing complexity in the component structure.
This commit is contained in:
smueller
2026-07-23 10:16:40 +02:00
parent c14c2ddaa2
commit 629e89f380
7 changed files with 117 additions and 107 deletions

View File

@@ -0,0 +1,86 @@
'use client';
import type { DashboardGuild } from '@nexumi/shared';
import Link from 'next/link';
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar';
import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import { Card, CardContent } from '@/components/ui/card';
function guildIconUrl(guild: Pick<DashboardGuild, 'id' | 'icon'>): string | undefined {
return guild.icon
? `https://cdn.discordapp.com/icons/${guild.id}/${guild.icon}.png?size=64`
: undefined;
}
function initials(name: string): string {
return (
name
.split(' ')
.filter(Boolean)
.slice(0, 2)
.map((part) => part[0]?.toUpperCase())
.join('') || '?'
);
}
export function DashboardGuildGrid({
guilds,
inviteUrls,
labels
}: {
guilds: DashboardGuild[];
inviteUrls: Record<string, string>;
labels: {
empty: string;
botMissing: string;
manage: string;
invite: string;
};
}) {
if (guilds.length === 0) {
return (
<Card>
<CardContent className="py-10 text-center text-sm text-muted-foreground">
{labels.empty}
</CardContent>
</Card>
);
}
return (
<div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-3">
{guilds.map((guild) => (
<Card key={guild.id}>
<CardContent className="flex flex-col gap-4 p-5">
<div className="flex items-center gap-3">
<Avatar className="size-10">
<AvatarImage src={guildIconUrl(guild)} alt={guild.name} />
<AvatarFallback>{initials(guild.name)}</AvatarFallback>
</Avatar>
<div className="min-w-0">
<p className="truncate font-medium">{guild.name}</p>
{!guild.botPresent && (
<Badge variant="outline" className="mt-1">
{labels.botMissing}
</Badge>
)}
</div>
</div>
{guild.botPresent ? (
<Button asChild>
<Link href={`/dashboard/${guild.id}`}>{labels.manage}</Link>
</Button>
) : (
<Button asChild variant="outline">
<a href={inviteUrls[guild.id]} target="_blank" rel="noreferrer">
{labels.invite}
</a>
</Button>
)}
</CardContent>
</Card>
))}
</div>
);
}

View File

@@ -1,3 +1,5 @@
'use client';
import { Slot } from '@radix-ui/react-slot';
import { cva, type VariantProps } from 'class-variance-authority';
import * as React from 'react';