Skip to content

Commit d501114

Browse files
committed
refactor: breadcrumb icon
1 parent 014c622 commit d501114

4 files changed

Lines changed: 29 additions & 7 deletions

File tree

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,13 @@
22

33
import { useParams } from 'next/navigation';
44
import { Breadcrumb } from '@/components/common/Breadcrumb';
5+
import { GuildIcon } from '@/components/common/GuildIcon';
56
import { client } from '@/data/client';
67
import { sortGuilds } from '@/utils/util';
78

89
export interface DashboardCrumbSegment {
910
readonly href?: string;
11+
readonly icon?: React.ReactNode;
1012
readonly label: string;
1113
}
1214

@@ -43,8 +45,8 @@ export function DashboardCrumbs({ segments }: DashboardCrumbProps) {
4345
{
4446
label: guild.name,
4547
href: segments.length === 0 ? undefined : `/dashboard/${guild.id}`,
46-
highlight: true,
47-
...(guildOptions.length > 0 && { options: guildOptions }),
48+
icon: <GuildIcon data={guild} disableLink hasBots />,
49+
options: guildOptions,
4850
},
4951
...segments.map(({ href, ...rest }) => {
5052
if (href) {

apps/website/src/components/common/Breadcrumb.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ export interface BreadcrumbOption {
1212
export interface BreadcrumbSegment {
1313
readonly highlight?: boolean;
1414
readonly href?: string | undefined;
15+
readonly icon?: React.ReactNode;
1516
readonly label: string;
1617
readonly options?: readonly BreadcrumbOption[];
1718
}
@@ -32,14 +33,15 @@ export function Breadcrumb({ segments }: BreadcrumbProps) {
3233
{hasOptions ? (
3334
<BreadcrumbDropdown
3435
highlight={segment.highlight}
36+
icon={segment.icon}
3537
isLast={isLast}
3638
label={segment.label}
3739
options={segment.options}
3840
/>
3941
) : segment.href ? (
4042
<Link
4143
className={cn(
42-
'hover:text-primary dark:hover:text-primary-dark',
44+
'flex items-center gap-2 hover:text-primary dark:hover:text-primary-dark',
4345
isLast
4446
? 'text-primary dark:text-primary-dark font-medium'
4547
: 'text-secondary dark:text-secondary-dark',
@@ -49,6 +51,7 @@ export function Breadcrumb({ segments }: BreadcrumbProps) {
4951
href={segment.href}
5052
prefetch
5153
>
54+
{segment.icon}
5255
{segment.label}
5356
</Link>
5457
) : (
@@ -60,6 +63,7 @@ export function Breadcrumb({ segments }: BreadcrumbProps) {
6063
segment.highlight && 'italic',
6164
)}
6265
>
66+
{segment.icon}
6367
{segment.label}
6468
</span>
6569
)}

apps/website/src/components/common/BreadcrumbDropdown.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,13 @@ import { cn, getGuildAcronym } from '@/utils/util';
1010

1111
interface BreadcrumbDropdownProps {
1212
readonly highlight?: boolean | undefined;
13+
readonly icon?: React.ReactNode;
1314
readonly isLast: boolean;
1415
readonly label: string;
1516
readonly options: readonly BreadcrumbOption[];
1617
}
1718

18-
export function BreadcrumbDropdown({ label, options, isLast, highlight }: BreadcrumbDropdownProps) {
19+
export function BreadcrumbDropdown({ label, icon, options, isLast, highlight }: BreadcrumbDropdownProps) {
1920
return (
2021
<DropdownMenu.Root>
2122
<DropdownMenu.Trigger asChild>
@@ -26,6 +27,7 @@ export function BreadcrumbDropdown({ label, options, isLast, highlight }: Breadc
2627
highlight && 'italic',
2728
)}
2829
>
30+
{icon}
2931
{label}
3032
<SvgChevronDown />
3133
</Button>

apps/website/src/components/common/GuildIcon.tsx

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,35 @@
11
import type { MeGuild } from '@chatsift/api';
22
import Image from 'next/image';
33
import Link from 'next/link';
4-
import { cn, getGuildAcronym } from '@/utils/util';
4+
import type { PropsWithChildren } from 'react';
5+
import { getGuildAcronym } from '@/utils/util';
56

67
export interface GuildIconProps {
78
readonly data: MeGuild;
89
readonly disableLink?: boolean;
910
readonly hasBots: boolean;
1011
}
1112

13+
interface ParentProps extends PropsWithChildren {
14+
readonly disableLink: boolean | undefined;
15+
readonly url: string | undefined;
16+
}
17+
18+
function Parent({ children, disableLink, url }: ParentProps) {
19+
if (disableLink || !url) {
20+
return <>{children}</>;
21+
}
22+
23+
return <Link href={url}>{children}</Link>;
24+
}
25+
1226
export function GuildIcon({ data, hasBots, disableLink }: GuildIconProps) {
1327
const icon = data?.icon ? `https://cdn.discordapp.com/icons/${data.id}/${data.icon}.png` : null;
1428
const url = hasBots ? `/dashboard/${data.id}` : undefined;
1529

1630
return (
1731
<div className="flex flex-row items-center">
18-
<Link className={cn((disableLink || !url) && 'pointer-events-none')} href={url ?? '#'}>
32+
<Parent disableLink={disableLink} url={url}>
1933
{icon ? (
2034
<Image
2135
alt="Guild icon"
@@ -29,7 +43,7 @@ export function GuildIcon({ data, hasBots, disableLink }: GuildIconProps) {
2943
{getGuildAcronym(data.name)}
3044
</p>
3145
)}
32-
</Link>
46+
</Parent>
3347
</div>
3448
);
3549
}

0 commit comments

Comments
 (0)