Skip to content

Commit

Permalink
bot demo
Browse files Browse the repository at this point in the history
  • Loading branch information
eduardozgz committed Oct 15, 2024
1 parent 9104985 commit 87c67e4
Show file tree
Hide file tree
Showing 8 changed files with 535 additions and 3 deletions.
10 changes: 8 additions & 2 deletions apps/website/src/app/components/DSelector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,13 @@ const Item = (props: ItemProps) => {
if (notSelectable) isSelected = false;

const itemImageStyle: React.CSSProperties =
typeof icon === "string" ? { backgroundImage: `url('${icon}')`, backgroundRepeat: 'no-repeat', backgroundSize: 'cover' } : {};
typeof icon === "string"
? {
backgroundImage: `url('${icon}')`,
backgroundRepeat: "no-repeat",
backgroundSize: "cover",
}
: {};

return (
<>
Expand Down Expand Up @@ -90,7 +96,7 @@ const Item = (props: ItemProps) => {
};

interface Props {
className: string;
className?: string;
classNameForItem?: string;
pre: ItemProps[];
guilds: ItemProps[];
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import type { LucideIcon } from "lucide-react";
import { useMemo } from "react";
import { ChannelType } from "discord-api-types/v10";
import { HelpCircleIcon, LockKeyholeIcon } from "lucide-react";

import { cn } from "@mc/ui";
import { Skeleton } from "@mc/ui/skeleton";

import { ChannelIconMap } from "~/app/dashboard/servers/[guildId]/ChannelMaps";
import { selectedChannelInChannelListColor } from "./colors";

export function ChannelNavItem({
type,
name,
isSelected,
onClick,
}: {
type: ChannelType;
name: string;
isSelected: boolean;
onClick?: () => void;
}) {
let Icon: LucideIcon | undefined = ChannelIconMap[type];
if (type === ChannelType.GuildVoice) Icon = LockKeyholeIcon;
Icon ??= HelpCircleIcon;

const isCategory = type === ChannelType.GuildCategory;
const isTextBased =
type === ChannelType.GuildText || type === ChannelType.GuildAnnouncement;
return (
<div
className={cn("group block select-none", "flex flex-row items-center", {
"mb-1 mt-4 pr-2 text-xs text-muted-foreground": isCategory,
"rounded-sm px-2 py-1.5 text-sm": !isCategory,
"text-foreground": isSelected,
[`cursor-pointer hover:bg-[#3f4248]`]: isTextBased,
})}
style={{
backgroundColor: isSelected ? selectedChannelInChannelListColor : "",
}}
onClick={() => isTextBased && onClick?.()}
>
<span
className={cn(
isCategory && "uppercase",
"flex-shrink overflow-hidden text-ellipsis whitespace-nowrap",
)}
>
<Icon
className={cn("mr-2 mt-[-2px] inline h-5 w-5 text-muted-foreground", {
"mr-1 h-4 w-4": isCategory,
})}
aria-hidden
/>
{name}
</span>
</div>
);
}

export const ChannelNavItemSkeleton = () => {
const random = useMemo(() => Math.floor(Math.random() * 100), []);
return (
<div className="flex h-[32px] w-full flex-shrink-0 items-center">
<Skeleton
className="ml-2 h-[20px] animate-none rounded-full"
style={{
width: 100 + random + "px",
backgroundColor: selectedChannelInChannelListColor,
}}
/>
</div>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import type { ChannelType } from "discord-api-types/v10";

export interface DemoServer {
name: string;
channels: {
name: string;
type: ChannelType;
topic?: string;
}[];
description: string;
links?: { href: string; label: string }[];
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import type { DemoServer } from "./DemoServer";
import { messageListColor } from "./colors";
import { DescriptionAreaTitle } from "./DescriptionAreaTitle";

export function DescriptionArea({
demoServer,
selectedChannelIndex,
}: {
demoServer: DemoServer;
selectedChannelIndex: number;
}) {
return (
<div
className="flex h-full grow flex-col"
style={{ backgroundColor: messageListColor }}
>
<DescriptionAreaTitle
demoServer={demoServer}
selectedChannelIndex={selectedChannelIndex}
/>
<div className="grow overflow-hidden">
<div className="w-fulll flex h-full items-center justify-center">
<div
className="w-[320px]"
dangerouslySetInnerHTML={{ __html: demoServer.description }}
></div>
{/* // TODO show links */}
</div>
</div>
</div>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import type { LucideIcon } from "lucide-react";
import { HelpCircleIcon } from "lucide-react";

import type { DemoServer } from "./DemoServer";
import { ChannelIconMap } from "~/app/dashboard/servers/[guildId]/ChannelMaps";

export function DescriptionAreaTitle({
demoServer,
selectedChannelIndex,
}: {
demoServer: DemoServer;
selectedChannelIndex: number;
}) {
const selectedChannel = demoServer.channels[selectedChannelIndex];

if (!selectedChannel) return null;

const Icon: LucideIcon =
ChannelIconMap[selectedChannel.type] ?? HelpCircleIcon;

return (
<div className="flex h-[48px] w-full flex-shrink-0 flex-row items-center pl-3 pr-1 font-semibold shadow-[0_1px_0_rgba(4,4,5,.2),0_1.5px_0_rgba(6,6,7,.05),0_2px_0_rgba(4,4,5,.05)]">
<Icon className="mr-3 h-5 w-5" />
<h1>{selectedChannel.name}</h1>
{selectedChannel.topic && (
<>
<div className="mx-[14px] h-[25px] border-l-[1px] border-l-[#4f5155]"></div>
<div className="text-[0.9rem] font-normal text-[#b4b4b4]">
{selectedChannel.topic}
</div>
</>
)}
</div>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { useTranslation } from "react-i18next";

import { cn } from "@mc/ui";
import { Separator } from "@mc/ui/separator";

import type { DemoServer } from "./DemoServer";
import { ChannelNavItem, ChannelNavItemSkeleton } from "./ChannelNavItem";
import { channelListColor } from "./colors";

export function ServerNavMenu({
className,
selectedChannelIndex,
setSelectedChannelIndex,
demoServer,
}: {
className?: string;
selectedChannelIndex: number;
setSelectedChannelIndex: (selectedChannelIndex: number) => void;
demoServer: DemoServer;
}) {
const { t } = useTranslation();

return (
<nav
className={cn(
"flex max-h-full w-[240px] min-w-[240px] flex-col overflow-hidden",
className,
)}
aria-label={`${demoServer.name} ${t("pages.dashboard.servers.ServerNavMenu.channelList")}`}
style={{ backgroundColor: channelListColor }}
>
<div className="flex h-[48px] min-h-[48px] min-w-0 items-center font-semibold shadow-[0_1px_0_rgba(4,4,5,.2),0_1.5px_0_rgba(6,6,7,.05),0_2px_0_rgba(4,4,5,.05)]">
<div
className={
"flex-shrink overflow-hidden text-ellipsis whitespace-nowrap pl-4"
}
>
{demoServer.name}
</div>
</div>

<Separator tabIndex={-1} />
<div className="flex max-h-full grow flex-col gap-1 p-[8px]">
{demoServer.channels.map((channel, i) => (
<ChannelNavItem
isSelected={selectedChannelIndex === i}
onClick={() => setSelectedChannelIndex(i)}
{...channel}
key={channel.name}
/>
))}
{new Array(15).fill(null).map((_, i) => (
<ChannelNavItemSkeleton key={i} />
))}
</div>
</nav>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export const serverListColor = "#1e1f22";
export const channelListColor = "#2b2d31";
export const selectedChannelInChannelListColor = "#3f4248";
export const messageListColor = "#313338";
Loading

0 comments on commit 87c67e4

Please sign in to comment.