diff --git a/src/app/dashboard/page.tsx b/src/app/dashboard/page.tsx index caa8889..a6876ff 100644 --- a/src/app/dashboard/page.tsx +++ b/src/app/dashboard/page.tsx @@ -1,4 +1,4 @@ -import { AppSidebar } from "@/components/app-sidebar" +import { AppSidebar } from "@/components/sidebar/app-sidebar" import { Breadcrumb, BreadcrumbItem, diff --git a/src/components/UncompletedProject/sharedialog.tsx b/src/components/UncompletedProject/sharedialog.tsx new file mode 100644 index 0000000..f3fc891 --- /dev/null +++ b/src/components/UncompletedProject/sharedialog.tsx @@ -0,0 +1,39 @@ +import { Button } from "@/components/ui/button" +import { + DialogContent, + DialogDescription, + DialogFooter, + DialogHeader, + DialogTitle, + DialogClose, +} from "@/components/ui/dialog" +import { Input } from "@/components/ui/input" +import { Label } from "@/components/ui/label" + +export function ShareDialogContent({ link }: { link: string }) { + return ( + + + Share link + + Anyone who has this link will be able to view this. + + +
+
+ + +
+
+ + + + + +
+ ) +} diff --git a/src/components/UncompletedProject/wrongbook-dialog.tsx b/src/components/UncompletedProject/wrongbook-dialog.tsx new file mode 100644 index 0000000..c7edcc7 --- /dev/null +++ b/src/components/UncompletedProject/wrongbook-dialog.tsx @@ -0,0 +1,84 @@ +"use client" + +import * as React from "react" +import { + Dialog, + DialogTrigger, + DialogContent, + DialogHeader, + DialogTitle, +} from "@/components/ui/dialog" +import { Check, X, Info, AlertTriangle } from "lucide-react" +import { Badge } from "@/components/ui/badge" +import Link from "next/link" + +export function WrongbookDialog({ problems, children }: { problems: { id: string; name: string; status: string }[]; children?: React.ReactNode }) { + return ( + + + {children ? children : ( + + )} + + + + 全部错题集 + +
+
+ + + + + + + + + + {problems.map((item) => ( + + + + + + ))} + +
ID题目名称状态
{item.id} + + {item.name} + + + {(() => { + if (item.status === "AC") { + return ( + + {item.status} + + ) + } else if (item.status === "WA") { + return ( + + {item.status} + + ) + } else if (["RE", "CE", "MLE", "TLE"].includes(item.status)) { + return ( + + {item.status} + + ) + } else { + return ( + + {item.status} + + ) + } + })()} +
+
+
+
+
+ ) +} diff --git a/src/components/admin/sidebar.tsx b/src/components/admin/sidebar.tsx deleted file mode 100644 index 7b62f44..0000000 --- a/src/components/admin/sidebar.tsx +++ /dev/null @@ -1,122 +0,0 @@ -"use client" -import { useSession } from "next-auth/react"; -import { - Sidebar, - SidebarContent, - SidebarFooter, - SidebarRail, -} from "@/components/ui/sidebar"; -import { NavMain } from "@/components/nav-main"; -import { NavProjects } from "@/components/nav-projects"; -import { NavUser } from "@/components/nav-user"; -import { - Command, - House, - PieChart, - Settings2, -} from "lucide-react"; - -import { useEffect, useState } from "react"; -import { PrismaClient } from "@prisma/client"; - -// 如果 adminData.teams 没有在别处定义,请取消注释下面的代码并提供实际值 -/* -const teams = [ - // 在这里放置你的团队数据 -]; -*/ - - -const adminData = { - // teams: [ - // { - // name: "Admin Team", - // logo: GalleryVerticalEnd, - // plan: "Enterprise", - // }, - // ], - navMain: [ - { - title: "OverView", - url: "/", - icon: House, - }, - { - title: "Dashboard", - url: "/admin", - icon: Settings2, - items: [ - { - title: "User", - url: "/admin/users", - }, - { - title: "Teacher", - url: "/admin/problems", - }, - ], - }, - ], - projects: [ - { - name: "System Monitoring", - url: "/admin/monitoring", - icon: PieChart, - }, - { - name: "Admin Tools", - url: "/admin/tools", - icon: Command, - }, - ] -}; - -export const AdminSidebar = ({ ...props }: React.ComponentProps) => { - const { data: session } = useSession(); - const [userAvatar, setUserAvatar] = useState(""); - - useEffect(() => { - const fetchUserAvatar = async () => { - if (session?.user?.email) { - const prisma = new PrismaClient(); - try { - const user = await prisma.user.findUnique({ - where: { email: session.user.email }, - select: { image: true } - }); - setUserAvatar(user?.image || ""); - } catch (error) { - console.error("Failed to fetch user avatar:", error); - } finally { - await prisma.$disconnect(); - } - } - }; - - fetchUserAvatar(); - }, [session?.user?.email]); - - - - const user = { - name: session?.user?.name || "Admin", - email: session?.user?.email || "admin@example.com", - avatar: userAvatar - }; - - return ( - - {/**/} - {/* */} - {/**/} - - - - - - - - - - ); -}; \ No newline at end of file diff --git a/src/components/nav-projects.tsx b/src/components/nav-projects.tsx index ae5867b..b5df78e 100644 --- a/src/components/nav-projects.tsx +++ b/src/components/nav-projects.tsx @@ -1,12 +1,25 @@ "use client" import { + BookX, Folder, MoreHorizontal, Share, Trash2, + Check, + X, + Info, + AlertTriangle, type LucideIcon, } from "lucide-react" +import React, { useState } from "react" +import { + Dialog, + DialogTrigger, + DialogContent, + DialogHeader, + DialogTitle, +} from "@/components/ui/dialog" import { DropdownMenu, @@ -24,66 +37,122 @@ import { SidebarMenuItem, useSidebar, } from "@/components/ui/sidebar" +import { Badge } from "@/components/ui/badge" +import { WrongbookDialog } from "@/components/UncompletedProject/wrongbook-dialog" +import { ShareDialogContent } from "@/components/UncompletedProject/sharedialog" export function NavProjects({ projects, }: { projects: { + id: string name: string - url: string - icon: LucideIcon + status: string }[] }) { const { isMobile } = useSidebar() + const [shareOpen, setShareOpen] = useState(false) + const [shareLink, setShareLink] = useState("") return ( - - Recent programming topics - - {projects.map((item) => ( - - - - - {item.name} - - - - - - - More - - - - - - View Project - - - - Share Project - - - - - Delete Project - - - + <> + + 待完成项目 + + {projects.slice(0, 1).map((item) => ( + + + + + + + {item.name} + + {(() => { + if (item.status === "AC") { + return ( + + + {item.status} + + ) + } else if (item.status === "WA") { + return ( + + + {item.status} + + ) + } else if (["RE", "CE", "MLE", "TLE"].includes(item.status)) { + return ( + + + {item.status} + + ) + } else { + return ( + + + {item.status} + + ) + } + })()} + + + + + + + + More + + + + + + 查看 + + { + e.stopPropagation() + setShareLink(`${window.location.origin}/problem/${item.id}`) + setShareOpen(true) + }} + > + + 复制链接 + + + + + 移除 + + + + + ))} + + + + + 更多 + + - ))} - - - - More - - - - + + + + + + ) } diff --git a/src/components/app-sidebar.tsx b/src/components/sidebar/app-sidebar.tsx similarity index 80% rename from src/components/app-sidebar.tsx rename to src/components/sidebar/app-sidebar.tsx index c32996a..24b2d7c 100644 --- a/src/components/app-sidebar.tsx +++ b/src/components/sidebar/app-sidebar.tsx @@ -35,56 +35,56 @@ const data = { }, navMain: [ { - title: "Dashboard", + title: "页面", url: "#", icon: SquareTerminal, isActive: true, items: [ { - title: "Home", - url: "/", + title: "主页", + url: "/dashboard", }, { - title: "Personal interface", + title: "历史记录", url: "#", }, { - title: "Problems", + title: "题目集", url: "/problemset", }, ], }, { - title: "Done Topics", + title: "已完成事项", url: "#", icon: BookOpen, items: [ { - title: "All Coding", + title: "全部编程集", url: "#", }, { - title: "Correct Codingset", + title: "错题集", url: "#", }, - { - title: "Wrong Codingset", + { + title: "收藏集", url: "#", }, ], }, { - title: "Settings", + title: "设置", url: "#", icon: Settings2, items: [ { - title: "General", + title: "一般设置", url: "#", }, { - title: "Language", + title: "语言", url: "#", }, ], @@ -102,21 +102,21 @@ const data = { icon: Send, }, ], - projects: [ + wrongProblems: [ { - name: "Design Engineering", - url: "#", - icon: Frame, + id: "abc123", + name: "Two Sum", + status: "WA", }, { - name: "Sales & Marketing", - url: "#", - icon: PieChart, + id: "def456", + name: "Reverse Linked List", + status: "RE", }, { - name: "Travel", - url: "#", - icon: Map, + id: "ghi789", + name: "Binary Tree Paths", + status: "TLE", }, ], } @@ -143,7 +143,7 @@ export function AppSidebar({ ...props }: React.ComponentProps) { - +