Skip to content

Commit 58a4fb7

Browse files
committed
refactor: some nav
1 parent 1e5e826 commit 58a4fb7

8 files changed

Lines changed: 77 additions & 60 deletions

File tree

apps/website/src/app/dashboard/[id]/ama/amas/_components/AMASessionCard.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,13 @@ import Link from 'next/link';
33

44
interface AMASessionCardProps {
55
readonly data: AMASessionWithCount;
6-
readonly guildId: string;
76
}
87

9-
export function AMASessionCard({ data, guildId }: AMASessionCardProps) {
8+
export function AMASessionCard({ data }: AMASessionCardProps) {
109
return (
1110
<Link
1211
className="flex h-36 w-[80vw] flex-col gap-3 rounded-lg border border-on-secondary bg-card p-4 hover:border-misc-accent dark:border-on-secondary-dark dark:bg-card-dark md:w-52"
13-
href={`/dashboard/${guildId}/ama/amas/${data.id}`}
12+
href={`/dashboard/${data.guildId}/ama/amas/${data.id}`}
1413
>
1514
<div className="flex flex-col gap-1">
1615
<h3 className="overflow-hidden overflow-ellipsis whitespace-nowrap text-lg font-medium text-primary dark:text-primary-dark">

apps/website/src/app/dashboard/[id]/ama/amas/_components/AMASessionsList.tsx

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,14 @@
11
'use client';
22

3-
import { useSearchParams } from 'next/navigation';
3+
import { useParams, useSearchParams } from 'next/navigation';
44
import { useMemo } from 'react';
55
import { AMASessionCard } from './AMASessionCard';
66
import { CreateAMACard } from './CreateAMACard';
77
import { client } from '@/data/client';
88

9-
interface AMASessionsListProps {
10-
readonly guildId: string;
11-
}
12-
13-
export function AMASessionsList({ guildId }: AMASessionsListProps) {
14-
const { data: sessions } = client.guilds.ama.useAMAs(guildId, { include_ended: false });
9+
export function AMASessionsList() {
10+
const params = useParams<{ id: string }>();
11+
const { data: sessions } = client.guilds.ama.useAMAs(params.id, { include_ended: false });
1512
const searchParams = useSearchParams();
1613

1714
const searchQuery = searchParams.get('search') ?? '';
@@ -28,11 +25,11 @@ export function AMASessionsList({ guildId }: AMASessionsListProps) {
2825
return (
2926
<ul className="grid grid-cols-1 gap-4 md:grid-cols-3 lg:grid-cols-4">
3027
<li>
31-
<CreateAMACard guildId={guildId} />
28+
<CreateAMACard />
3229
</li>
3330
{filtered.map((session) => (
3431
<li key={session.id}>
35-
<AMASessionCard data={session} guildId={guildId} />
32+
<AMASessionCard data={session} />
3633
</li>
3734
))}
3835
</ul>

apps/website/src/app/dashboard/[id]/ama/amas/_components/CreateAMACard.tsx

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
1+
'use client';
2+
13
import Link from 'next/link';
4+
import { useParams } from 'next/navigation';
25
import { SvgPlus } from '@/components/icons/SvgPlus';
36

4-
interface CreateAMACardProps {
5-
readonly guildId: string;
6-
}
7+
export function CreateAMACard() {
8+
const params = useParams<{ id: string }>();
79

8-
export function CreateAMACard({ guildId }: CreateAMACardProps) {
910
return (
1011
<Link
1112
className="flex h-36 w-[80vw] flex-col items-center justify-center gap-2 rounded-lg border-2 border-dashed border-on-secondary bg-card p-4 hover:border-misc-accent dark:border-on-secondary-dark dark:bg-card-dark md:w-52"
12-
href={`/dashboard/${guildId}/ama/amas/new`}
13+
href={`/dashboard/${params.id}/ama/amas/new`}
1314
>
1415
<SvgPlus />
1516
<span className="text-lg font-medium text-primary dark:text-primary-dark">Create AMA</span>

apps/website/src/app/dashboard/[id]/ama/amas/new/page.tsx

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,10 @@
11
import { DashboardCrumbs } from '../../../../_components/DashboardCrumbs';
22
import { Heading } from '@/components/common/Heading';
33

4-
export default async function AMAMangementPage({ params }: PageProps<'/dashboard/[id]/ama/amas/new'>) {
5-
const { id } = await params;
6-
4+
export default function AMAMangementPage() {
75
return (
86
<div className="flex flex-col [&:not]:first-of-type:mt-8 [&>*]:first-of-type:mb-4">
9-
<DashboardCrumbs
10-
segments={[
11-
{ label: 'AMA Bot', href: `/dashboard/${id}/ama` },
12-
{ label: 'AMA Sessions', href: `/dashboard/${id}/ama/amas` },
13-
{ label: 'New' },
14-
]}
15-
/>
7+
<DashboardCrumbs />
168
<Heading subtitle="Create a new AMA session" title="AMA sessions" />
179
</div>
1810
);

apps/website/src/app/dashboard/[id]/ama/amas/page.tsx

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,16 @@ import { AMASessionsList } from './_components/AMASessionsList';
33
import { Heading } from '@/components/common/Heading';
44
import { SearchBar } from '@/components/common/SearchBar';
55

6-
export default async function AMAMangementPage({ params }: PageProps<'/dashboard/[id]/ama/amas'>) {
7-
const { id } = await params;
8-
6+
export default function AMAMangementPage() {
97
return (
108
<>
119
<div className="flex flex-col [&:not]:first-of-type:mt-8 [&>*]:first-of-type:mb-4">
12-
<DashboardCrumbs segments={[{ label: 'AMA Bot', href: `/dashboard/${id}/ama` }, { label: 'AMA Sessions' }]} />
13-
<Heading subtitle="Create, edit, and manage AMAs in your community" title="AMA sessions" />
10+
<DashboardCrumbs />
11+
<Heading subtitle="Create and manage AMAs in your community" title="AMA sessions" />
1412
<SearchBar placeholder="Search AMA sessions..." />
1513
</div>
1614

17-
<AMASessionsList guildId={id} />
15+
<AMASessionsList />
1816
</>
1917
);
2018
}

apps/website/src/app/dashboard/[id]/ama/page.tsx

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ export default async function AMAPage({ params }: PageProps<'/dashboard/[id]/ama
88
return (
99
<div className="space-y-8">
1010
<div className="flex flex-col gap-4">
11-
<DashboardCrumbs segments={[{ label: 'AMA Bot' }]} />
11+
<DashboardCrumbs />
1212
<Heading subtitle="Configure AMA for your server" title="AMA Settings" />
1313
<Link
1414
className="flex items-center gap-4 rounded-lg border-[1px] border-on-secondary bg-card p-4 hover:bg-on-tertiary dark:border-on-secondary-dark dark:bg-card-dark dark:hover:bg-on-tertiary-dark"
@@ -20,9 +20,7 @@ export default async function AMAPage({ params }: PageProps<'/dashboard/[id]/ama
2020
</div>
2121
<div className="flex flex-col">
2222
<p className="text-lg font-medium text-primary dark:text-primary-dark">Manage AMAs</p>
23-
<p className="text-sm text-secondary dark:text-secondary-dark">
24-
Create, edit, and manage AMAs in your community
25-
</p>
23+
<p className="text-sm text-secondary dark:text-secondary-dark">Create, and manage AMAs in your community</p>
2624
</div>
2725
</Link>
2826
</div>

apps/website/src/app/dashboard/[id]/page.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import { BOTS } from '@chatsift/core';
44
import Link from 'next/link';
55
import { notFound, useParams } from 'next/navigation';
66
import { DashboardCrumbs } from '../_components/DashboardCrumbs';
7-
import GuildCard from '../_components/GuildCard';
87
import { Heading } from '@/components/common/Heading';
98
import { Skeleton } from '@/components/common/Skeleton';
109
import { client } from '@/data/client';
@@ -28,7 +27,7 @@ export default function GuildPage() {
2827
return (
2928
<div className="space-y-8">
3029
<div className="space-y-4">
31-
<DashboardCrumbs segments={[]} />
30+
<DashboardCrumbs />
3231
<Heading subtitle="Configure the bots installed in your server" title="Bots" />
3332
<div className="flex flex-col gap-3">
3433
{BOTS.map((bot, index) => {

apps/website/src/app/dashboard/_components/DashboardCrumbs.tsx

Lines changed: 54 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,66 @@
11
'use client';
22

3-
import { useParams } from 'next/navigation';
3+
import { useParams, usePathname } from 'next/navigation';
4+
import { useMemo } from 'react';
45
import { Breadcrumb } from '@/components/common/Breadcrumb';
56
import { GuildIcon } from '@/components/common/GuildIcon';
67
import { client } from '@/data/client';
78
import { sortGuilds } from '@/utils/util';
89

9-
export interface DashboardCrumbSegment {
10-
readonly href?: string;
11-
readonly icon?: React.ReactNode;
12-
readonly label: string;
13-
}
14-
15-
interface DashboardCrumbProps {
16-
readonly segments: DashboardCrumbSegment[];
17-
}
10+
const SEGMENT_LABELS: Record<string, string> = {
11+
ama: 'AMA Bot',
12+
amas: 'AMA Sessions',
13+
new: 'New',
14+
} as const;
1815

19-
export function DashboardCrumbs({ segments }: DashboardCrumbProps) {
16+
export function DashboardCrumbs() {
2017
const { data: me } = client.auth.useMe();
2118
const params = useParams<{ id?: string }>();
19+
const pathname = usePathname();
20+
21+
const segments = useMemo(() => {
22+
if (!params.id || !pathname) {
23+
return [];
24+
}
25+
26+
// Split the pathname and remove empty strings
27+
const pathParts = pathname.split('/').filter(Boolean);
28+
29+
// Find where the guild ID is in the path
30+
const guildIdIndex = pathParts.indexOf(params.id);
31+
if (guildIdIndex === -1) {
32+
return [];
33+
}
34+
35+
// Get all segments after the guild ID
36+
const relevantParts = pathParts.slice(guildIdIndex + 1);
37+
38+
// Build segments with proper hrefs
39+
const result = [];
40+
for (let i = 0; i < relevantParts.length; i++) {
41+
const part = relevantParts[i];
42+
if (!part) {
43+
continue;
44+
}
45+
46+
const label = SEGMENT_LABELS[part] ?? part;
47+
48+
// Don't create an href for the last segment (current page)
49+
const isLastSegment = i === relevantParts.length - 1;
50+
if (isLastSegment) {
51+
result.push({ label });
52+
} else {
53+
// Build the href up to this segment
54+
const pathUpToHere = pathParts.slice(0, guildIdIndex + 2 + i).join('/');
55+
result.push({
56+
label,
57+
href: `/${pathUpToHere}`,
58+
});
59+
}
60+
}
61+
62+
return result;
63+
}, [params.id, pathname]);
2264

2365
if (!params.id) {
2466
throw new Error('id param not found, should not be rendering this component');
@@ -48,16 +90,7 @@ export function DashboardCrumbs({ segments }: DashboardCrumbProps) {
4890
icon: <GuildIcon data={guild} disableLink hasBots />,
4991
options: guildOptions,
5092
},
51-
...segments.map(({ href, ...rest }) => {
52-
if (href) {
53-
return {
54-
href: href.replace('[id]', guild.id),
55-
...rest,
56-
};
57-
}
58-
59-
return rest;
60-
}),
93+
...segments,
6194
]}
6295
/>
6396
);

0 commit comments

Comments
 (0)