diff --git a/app/dashboard/layout.tsx b/app/dashboard/layout.tsx new file mode 100644 index 0000000..2581950 --- /dev/null +++ b/app/dashboard/layout.tsx @@ -0,0 +1,21 @@ +import { AppSidebar } from "@/components/dashboardComponents/AppSidebar"; +import { SidebarProvider, SidebarTrigger } from "@/components/ui/sidebar"; +import type { Metadata } from "next"; + +export const metadata: Metadata = { + title: "LeetCode Journal", + description: "Track your LeetCode progress and boost your coding skills", +}; + +export default function RootLayout({ + children, +}: { + children: React.ReactNode; +}) { + return ( + + +
{children}
+
+ ); +} diff --git a/app/dashboard/page.tsx b/app/dashboard/page.tsx index 5a5cbfa..650de14 100644 --- a/app/dashboard/page.tsx +++ b/app/dashboard/page.tsx @@ -1,97 +1,59 @@ "use client"; import { useEffect } from "react"; -import { useRouter } from "next/navigation"; -import { useAuthStore } from "@/store/AuthStore/useAuthStore"; -import Navbar from "@/components/header"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Skeleton } from "@/components/ui/skeleton"; +import { useAuthStore } from "@/store/AuthStore/useAuthStore"; +import DashboardNavbar from "@/components/dashboardComponents/DashboardNavbar"; +import { DashboardContentSkeleton } from "@/components/dashboardComponents/DashboardContentSkeleton"; + +function DashboardContent({ authUser }: any) { + return ( +
+

Welcome, {authUser?.fullName}

+ + + Your Profile + + +

+ LeetCode Username:{" "} + {authUser?.leetcodeUsername} +

+

+ Gender: {authUser?.gender} +

+
+
+ + + + LeetCode Stats + + +

+ LeetCode stats are coming soon! +

+
+
+
+ ); +} export default function Dashboard() { - const router = useRouter(); const { authUser, fetchAuthUser, authUserLoading } = useAuthStore(); useEffect(() => { fetchAuthUser(); }, [fetchAuthUser]); - - useEffect(() => { - if (!authUserLoading && !authUser) { - router.push("/auth/signin"); - } - }, [authUserLoading, authUser, router]); - - if (authUserLoading) { - return ; - } - - if (!authUser) { - return null; - } - - return ( -
- -
-

Welcome, {authUser.fullName}

- - - - Your Profile - - -

- LeetCode Username:{" "} - {authUser.leetcodeUsername} -

-

- Gender: {authUser.gender} -

-
-
- - - - LeetCode Stats - - - {/* LeetCode stats component will go here */} -

- LeetCode stats are coming soon! -

-
-
-
-
- ); -} - -function DashboardSkeleton() { return ( -
- {/* */} -
- - - - - - - - - - - - - - - - - - - - -
+
+ + {authUserLoading ? ( + + ) : ( + + )}
); } diff --git a/app/globals.css b/app/globals.css index 2ea59e0..581d725 100644 --- a/app/globals.css +++ b/app/globals.css @@ -92,5 +92,4 @@ body { @apply bg-background text-foreground; } -} - +} \ No newline at end of file diff --git a/components/dashboardComponents/AppSidebar.tsx b/components/dashboardComponents/AppSidebar.tsx new file mode 100644 index 0000000..68f6a20 --- /dev/null +++ b/components/dashboardComponents/AppSidebar.tsx @@ -0,0 +1,150 @@ +"use client"; + +import { + Calendar, + ChevronUp, + Search, + Settings, + User, + User2, +} from "lucide-react"; +import { useState } from "react"; + +import { + Sidebar, + SidebarContent, + SidebarFooter, + SidebarGroup, + SidebarGroupContent, + SidebarGroupLabel, + SidebarMenu, + SidebarMenuButton, + SidebarMenuItem, + SidebarTrigger, +} from "@/components/ui/sidebar"; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuTrigger, +} from "@/components/ui/dropdown-menu"; +import { cn } from "@/lib/utils"; +import { signout } from "@/app/actions/action"; +import Dashboard from "@/app/dashboard/page"; + +// Menu items. +const items = [ + { + title: "profile", + url: "#", + icon: User, + }, + { + title: "Problems", + url: "#", + icon: Dashboard, + }, + { + title: "Calendar", + url: "#", + icon: Calendar, + }, + { + title: "Search", + url: "#", + icon: Search, + }, + { + title: "Settings", + url: "#", + icon: Settings, + }, +]; + +export function AppSidebar() { + const [isCollapsed, setIsCollapsed] = useState(false); + return ( + + setIsCollapsed(!isCollapsed)} + className="absolute right-[-12px] top-4 z-20 flex h-6 w-6 items-center justify-center rounded-full border bg-background text-foreground shadow-sm" + > + {isCollapsed ? "→" : "←"} + + + + + Leetcode Journal + + + + {items.map((item) => ( + + + + + + {item.title} + + {isCollapsed && ( + + {item.title} + + )} + + + + ))} + + + + + + + + + + + + + Username + + + + + + + Account + + + Billing + + + Sign out + + + + + + + + ); +} diff --git a/components/dashboardComponents/DashboardContentSkeleton.tsx b/components/dashboardComponents/DashboardContentSkeleton.tsx new file mode 100644 index 0000000..4626674 --- /dev/null +++ b/components/dashboardComponents/DashboardContentSkeleton.tsx @@ -0,0 +1,29 @@ +import { Card, CardContent, CardHeader } from "../ui/card"; +import { Skeleton } from "../ui/skeleton"; + +export function DashboardContentSkeleton() { + return ( +
+ + + + + + + + + + + + + + + + + + + + +
+ ); +} diff --git a/components/header.tsx b/components/dashboardComponents/DashboardNavbar.tsx similarity index 77% rename from components/header.tsx rename to components/dashboardComponents/DashboardNavbar.tsx index 4f55f73..3915746 100644 --- a/components/header.tsx +++ b/components/dashboardComponents/DashboardNavbar.tsx @@ -4,21 +4,24 @@ import { useState } from "react"; import Link from "next/link"; import { Button } from "@/components/ui/button"; import { ThemeToggle } from "@/components/theme-toggle"; -import { supabase } from "@/lib/supabaseClient"; -import { useRouter } from "next/navigation"; import { signout } from "@/app/actions/action"; -const Navbar = ({ userId }: { userId?: string }) => { +const Navbar = ({ + userId, + isLoading, +}: { + userId?: string; + isLoading: boolean; +}) => { const [isMenuOpen, setIsMenuOpen] = useState(false); - const router = useRouter(); return ( -
-