Skip to content

Commit

Permalink
调整包的版本号,完成侧边栏
Browse files Browse the repository at this point in the history
  • Loading branch information
floatGray committed Nov 22, 2023
1 parent ebe60ab commit 06e9fa1
Show file tree
Hide file tree
Showing 12 changed files with 467 additions and 56 deletions.
14 changes: 14 additions & 0 deletions app/(main)/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { NavigationSidebar } from '@/components/navigation/navigation-sidebar';

const MainLayout = async ({ children }: { children: React.ReactNode }) => {
return (
<div className="h-full">
<div className="hidden md:flex h-full w-[72px] z-30 flex-col fixed inset-y-0">
<NavigationSidebar />
</div>
<main className="md:pl-[72px] h-full">{children}</main>
</div>
);
};

export default MainLayout;
35 changes: 35 additions & 0 deletions components/action-tooltip.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
'use client';

import {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger,
} from '@/components/ui/tooltip';

interface ActionTooltipProps {
label: string;
children: React.ReactNode;
side?: 'top' | 'right' | 'bottom' | 'left';
align?: 'start' | 'center' | 'end';
}

export const ActionTooltip = ({
label,
children,
side,
align,
}: ActionTooltipProps) => {
return (
<TooltipProvider>
<Tooltip delayDuration={50}>
<TooltipTrigger asChild>{children}</TooltipTrigger>
<TooltipContent side={side} align={align}>
<p className="font-semibold text-sm capitalize">
{label.toLowerCase()}
</p>
</TooltipContent>
</Tooltip>
</TooltipProvider>
);
};
25 changes: 25 additions & 0 deletions components/navigation/navigation-action.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
'use client';

import { Plus } from 'lucide-react';

import { ActionTooltip } from '@/components/action-tooltip';

export const NavigationAction = () => {
return (
<div>
<ActionTooltip side="right" align="center" label="增加一个服务器">
<button
onClick={() => console.log('增加一个服务器')}
className="group flex items-center"
>
<div className="flex mx-3 h-[48px] w-[48px] rounded-[24px] group-hover:rounded-[16px] transition-all overflow-hidden items-center justify-center bg-background dark:bg-neutral-700 group-hover:bg-emerald-500">
<Plus
className="group-hover:text-white transition text-emerald-500"
size={25}
/>
</div>
</button>
</ActionTooltip>
</div>
);
};
45 changes: 45 additions & 0 deletions components/navigation/navigation-item.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
'use client';

import Image from 'next/image';
import { useParams, useRouter } from 'next/navigation';

import { cn } from '@/lib/utils';
import { ActionTooltip } from '@/components/action-tooltip';

interface NavigationItemProps {
id: string;
imageUrl: string;
name: string;
}

export const NavigationItem = ({ id, imageUrl, name }: NavigationItemProps) => {
const params = useParams();
const router = useRouter();

const onClick = () => {
router.push(`/servers/${id}`);
};

return (
<ActionTooltip side="right" align="center" label={name}>
<button onClick={onClick} className="group relative flex items-center">
<div
className={cn(
'absolute left-0 bg-primary rounded-r-full transition-all w-[4px]',
params?.serverId !== id && 'group-hover:h-[20px]',
params?.serverId === id ? 'h-[36px]' : 'h-[8px]'
)}
/>
<div
className={cn(
'relative group flex mx-3 h-[48px] w-[48px] rounded-[24px] group-hover:rounded-[16px] transition-all overflow-hidden',
params?.serverId === id &&
'bg-primary/10 text-primary rounded-[16px]'
)}
>
<Image fill src={imageUrl} alt="Channel" />
</div>
</button>
</ActionTooltip>
);
};
58 changes: 58 additions & 0 deletions components/navigation/navigation-sidebar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { redirect } from 'next/navigation';
import { UserButton } from '@clerk/nextjs';

import { ScrollArea } from '@/components/ui/scroll-area';
import { ModeToggle } from '@/components/mode-toggle';
import { Separator } from '@/components/ui/separator';
import { currentProfile } from '@/lib/current-profile';
import { db } from '@/lib/db';

import { NavigationAction } from './navigation-action';
import { NavigationItem } from './navigation-item';

export const NavigationSidebar = async () => {
const profile = await currentProfile();

if (!profile) {
return redirect('/');
}

const servers = await db.server.findMany({
where: {
members: {
some: {
profileId: profile.id,
},
},
},
});

return (
<div className="space-y-4 flex flex-col items-center h-full text-primary w-full dark:bg-[#1E1F22] bg-[#E3E5E8] py-3">
<NavigationAction />
<Separator className="h-[2px] bg-zinc-300 dark:bg-zinc-700 rounded-md w-10 mx-auto" />
<ScrollArea className="flex-1 w-full">
{servers.map((server) => (
<div key={server.id} className="mb-4">
<NavigationItem
id={server.id}
name={server.name}
imageUrl={server.imageUrl}
/>
</div>
))}
</ScrollArea>
<div className="pb-3 mt-auto flex items-center flex-col gap-y-4">
<ModeToggle />
<UserButton
afterSignOutUrl="/"
appearance={{
elements: {
avatarBox: 'h-[48px] w-[48px]',
},
}}
/>
</div>
</div>
);
};
48 changes: 48 additions & 0 deletions components/ui/scroll-area.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
"use client"

import * as React from "react"
import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area"

import { cn } from "@/lib/utils"

const ScrollArea = React.forwardRef<
React.ElementRef<typeof ScrollAreaPrimitive.Root>,
React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.Root>
>(({ className, children, ...props }, ref) => (
<ScrollAreaPrimitive.Root
ref={ref}
className={cn("relative overflow-hidden", className)}
{...props}
>
<ScrollAreaPrimitive.Viewport className="h-full w-full rounded-[inherit]">
{children}
</ScrollAreaPrimitive.Viewport>
<ScrollBar />
<ScrollAreaPrimitive.Corner />
</ScrollAreaPrimitive.Root>
))
ScrollArea.displayName = ScrollAreaPrimitive.Root.displayName

const ScrollBar = React.forwardRef<
React.ElementRef<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>,
React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>
>(({ className, orientation = "vertical", ...props }, ref) => (
<ScrollAreaPrimitive.ScrollAreaScrollbar
ref={ref}
orientation={orientation}
className={cn(
"flex touch-none select-none transition-colors",
orientation === "vertical" &&
"h-full w-2.5 border-l border-l-transparent p-[1px]",
orientation === "horizontal" &&
"h-2.5 flex-col border-t border-t-transparent p-[1px]",
className
)}
{...props}
>
<ScrollAreaPrimitive.ScrollAreaThumb className="relative flex-1 rounded-full bg-border" />
</ScrollAreaPrimitive.ScrollAreaScrollbar>
))
ScrollBar.displayName = ScrollAreaPrimitive.ScrollAreaScrollbar.displayName

export { ScrollArea, ScrollBar }
31 changes: 31 additions & 0 deletions components/ui/separator.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
"use client"

import * as React from "react"
import * as SeparatorPrimitive from "@radix-ui/react-separator"

import { cn } from "@/lib/utils"

const Separator = React.forwardRef<
React.ElementRef<typeof SeparatorPrimitive.Root>,
React.ComponentPropsWithoutRef<typeof SeparatorPrimitive.Root>
>(
(
{ className, orientation = "horizontal", decorative = true, ...props },
ref
) => (
<SeparatorPrimitive.Root
ref={ref}
decorative={decorative}
orientation={orientation}
className={cn(
"shrink-0 bg-border",
orientation === "horizontal" ? "h-[1px] w-full" : "h-full w-[1px]",
className
)}
{...props}
/>
)
)
Separator.displayName = SeparatorPrimitive.Root.displayName

export { Separator }
30 changes: 30 additions & 0 deletions components/ui/tooltip.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
"use client"

import * as React from "react"
import * as TooltipPrimitive from "@radix-ui/react-tooltip"

import { cn } from "@/lib/utils"

const TooltipProvider = TooltipPrimitive.Provider

const Tooltip = TooltipPrimitive.Root

const TooltipTrigger = TooltipPrimitive.Trigger

const TooltipContent = React.forwardRef<
React.ElementRef<typeof TooltipPrimitive.Content>,
React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Content>
>(({ className, sideOffset = 4, ...props }, ref) => (
<TooltipPrimitive.Content
ref={ref}
sideOffset={sideOffset}
className={cn(
"z-50 overflow-hidden rounded-md border bg-popover px-3 py-1.5 text-sm text-popover-foreground shadow-md animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
className
)}
{...props}
/>
))
TooltipContent.displayName = TooltipPrimitive.Content.displayName

export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider }
2 changes: 1 addition & 1 deletion middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { authMiddleware } from '@clerk/nextjs';
// Please edit this to allow other routes to be public as needed.
// See https://clerk.com/docs/references/nextjs/auth-middleware for more information about configuring your Middleware
export default authMiddleware({
publicRoutes: ['api/uploadthing'],
publicRoutes: ['/api/uploadthing'],
});

export const config = {
Expand Down
2 changes: 1 addition & 1 deletion next.config.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/** @type {import('next').NextConfig} */
const nextConfig = {
images: {
domains: ['uploadthing.com'],
domains: ['uploadthing.com','utfs.io'],
},
};

Expand Down
Loading

0 comments on commit 06e9fa1

Please sign in to comment.