From 6c4b88cff7f17c3003915a53224d3ad40e600dff Mon Sep 17 00:00:00 2001 From: Bart van der Braak Date: Thu, 8 Jun 2023 00:39:28 +0200 Subject: [PATCH] feat: Add pages/components for authenticated flow --- app/(authenticated)/(app)/DesktopSidebar.tsx | 84 +++++++++++++ app/(authenticated)/(app)/MobileSidebar.tsx | 107 ++++++++++++++++ app/(authenticated)/(app)/TeamSwitcher.tsx | 99 +++++++++++++++ app/(authenticated)/(app)/channelLink.tsx | 28 +++++ app/(authenticated)/(app)/layout.tsx | 32 +++++ .../(app)/overview/loading.tsx | 9 ++ app/(authenticated)/(app)/overview/page.tsx | 119 ++++++++++++++++++ 7 files changed, 478 insertions(+) create mode 100644 app/(authenticated)/(app)/DesktopSidebar.tsx create mode 100644 app/(authenticated)/(app)/MobileSidebar.tsx create mode 100644 app/(authenticated)/(app)/TeamSwitcher.tsx create mode 100644 app/(authenticated)/(app)/channelLink.tsx create mode 100644 app/(authenticated)/(app)/layout.tsx create mode 100644 app/(authenticated)/(app)/overview/loading.tsx create mode 100644 app/(authenticated)/(app)/overview/page.tsx diff --git a/app/(authenticated)/(app)/DesktopSidebar.tsx b/app/(authenticated)/(app)/DesktopSidebar.tsx new file mode 100644 index 0000000..f5291ab --- /dev/null +++ b/app/(authenticated)/(app)/DesktopSidebar.tsx @@ -0,0 +1,84 @@ +import { Logo } from "@/components/logo"; +import { Button } from "@/components/ui/button"; +import { ScrollArea } from "@/components/ui/scroll-area"; +import { BarChart, Database, FileKey, Filter, FormInput, Home } from "lucide-react"; +import { ChannelLink } from "./channelLink"; +import { TeamSwitcher } from "./TeamSwitcher"; +import Link from "next/link"; +type Props = { + navigation: { + href: string; + external?: boolean; + label: string; + }[]; + + channels: { + name: string; + }[]; +}; + +export const DesktopSidebar: React.FC = ({ navigation, channels }) => { + return ( + + ); +}; diff --git a/app/(authenticated)/(app)/MobileSidebar.tsx b/app/(authenticated)/(app)/MobileSidebar.tsx new file mode 100644 index 0000000..122af63 --- /dev/null +++ b/app/(authenticated)/(app)/MobileSidebar.tsx @@ -0,0 +1,107 @@ +"use client"; + +import { Logo } from "@/components/logo"; +import { Button } from "@/components/ui/button"; +import { ScrollArea } from "@/components/ui/scroll-area"; +import { BarChart, Database, FileKey, Filter, FormInput, Home, Menu } from "lucide-react"; +import { ChannelLink } from "./channelLink"; +import { TeamSwitcher } from "./TeamSwitcher"; +import Link from "next/link"; +import { + Sheet, + SheetContent, + SheetDescription, + SheetFooter, + SheetHeader, + SheetTitle, + SheetTrigger, +} from "@/components/ui/sheet"; +import { Label } from "@/components/ui/label"; +import { Input } from "@/components/ui/input"; +type Props = { + navigation: { + href: string; + external?: boolean; + label: string; + }[]; + + channels: { + name: string; + }[]; +}; + +export const MobileSidebar: React.FC = ({ navigation, channels }) => { + return ( +
+ +
+ + + +
+ + + + {" "} + + Omnidash + + {/* + Make changes to your profile here. Click save when you're done. + */} + +
+
+

{/* Events */}

+
+ + + + + + + + + + + +
+
+
+

Events

+ +
+ {channels.map((channel) => ( + + ))} +
+
+
+
+ + + +
+
+
+ ); +}; diff --git a/app/(authenticated)/(app)/TeamSwitcher.tsx b/app/(authenticated)/(app)/TeamSwitcher.tsx new file mode 100644 index 0000000..91c6520 --- /dev/null +++ b/app/(authenticated)/(app)/TeamSwitcher.tsx @@ -0,0 +1,99 @@ +"use client"; + +import { + DropdownMenuTrigger, + DropdownMenu, + DropdownMenuContent, + DropdownMenuCheckboxItem, + DropdownMenuGroup, + DropdownMenuItem, + DropdownMenuLabel, + DropdownMenuPortal, + DropdownMenuRadioGroup, + DropdownMenuRadioItem, + DropdownMenuSeparator, + DropdownMenuShortcut, + DropdownMenuSub, + DropdownMenuSubContent, + DropdownMenuSubTrigger, +} from "@/components/ui/dropdown-menu"; +import { Check, ChevronsUpDown, Plus, Key, Book, LogOut, Rocket } from "lucide-react"; +import Link from "next/link"; +import { useRouter } from "next/navigation"; +import { useEffect, useState } from "react"; +import { Button } from "@/components/ui/button"; +import { Input } from "@/components/ui/input"; +import { Label } from "@/components/ui/label"; +import { Loading } from "@/components/loading"; + +import { cn } from "@/lib/utils"; +import { useAuth, useOrganization, useOrganizationList, useUser } from "@clerk/clerk-react"; +import { Avatar, AvatarImage } from "@/components/ui/avatar"; +import { AvatarFallback } from "@radix-ui/react-avatar"; + +type Props = {}; + +export const TeamSwitcher: React.FC = (): JSX.Element => { + const { setActive, organizationList } = useOrganizationList(); + const { organization: currentOrg } = useOrganization(); + + const { signOut } = useAuth(); + const { user } = useUser(); + + const router = useRouter(); + + const [loading, setLoading] = useState(false); + + async function changeOrg(id: string | null) { + if (!setActive) { + return; + } + try { + setLoading(true); + await setActive({ organization: id }); + router.refresh(); + } finally { + setLoading(false); + } + } + + return ( + + {loading ? ( + + ) : ( + +
+ + {user?.profileImageUrl ? ( + + ) : null} + + {(currentOrg?.slug ?? user?.username ?? "").slice(0, 2).toUpperCase() ?? "P"} + + + {currentOrg?.name ?? "Personal"} +
+ {/* */} + +
+ )} + + + + + + + +
+ ); +}; diff --git a/app/(authenticated)/(app)/channelLink.tsx b/app/(authenticated)/(app)/channelLink.tsx new file mode 100644 index 0000000..d1ac988 --- /dev/null +++ b/app/(authenticated)/(app)/channelLink.tsx @@ -0,0 +1,28 @@ +"use client"; + +import Link from "next/link"; +import { useSelectedLayoutSegments } from "next/navigation"; +import { Hash } from "lucide-react"; + +import { Button } from "@/components/ui/button"; + +type Props = { + href: string; + channelName: string | null; +}; + +export const ChannelLink: React.FC = ({ href, channelName }) => { + const isActive = channelName === useSelectedLayoutSegments().at(1); + return ( + + + + ); +}; diff --git a/app/(authenticated)/(app)/layout.tsx b/app/(authenticated)/(app)/layout.tsx new file mode 100644 index 0000000..6c83cdb --- /dev/null +++ b/app/(authenticated)/(app)/layout.tsx @@ -0,0 +1,32 @@ +import Link from "next/link"; +import { BarChart, FileKey, Filter, FormInput, Keyboard, Menu, Tornado } from "lucide-react"; +import { Button } from "@/components/ui/button"; +import { ScrollArea } from "@/components/ui/scroll-area"; +import { TeamSwitcher } from "./TeamSwitcher"; +import { auth } from "@clerk/nextjs/app-beta"; +import { notFound } from "next/navigation"; +import { ChannelLink } from "./channelLink"; +import { Logo } from "@/components/logo"; +import { DesktopSidebar } from "./DesktopSidebar"; +import { MobileNav } from "@/components/mobile-nav"; +import { MobileSidebar } from "./MobileSidebar"; +import { getTenantId } from "@/lib/auth"; +import { Fragment } from "react"; + +interface LayoutProps { + children: React.ReactNode; +} + +export default async function Layout({ children }: LayoutProps) { + const tenantId = getTenantId(); + + return ( + + + + + +
{children}
+
+ ); +} diff --git a/app/(authenticated)/(app)/overview/loading.tsx b/app/(authenticated)/(app)/overview/loading.tsx new file mode 100644 index 0000000..f37ff65 --- /dev/null +++ b/app/(authenticated)/(app)/overview/loading.tsx @@ -0,0 +1,9 @@ +import { Loading as Spinner } from "@/components/loading"; + +export default function Loading() { + return ( +
+ +
+ ); +} diff --git a/app/(authenticated)/(app)/overview/page.tsx b/app/(authenticated)/(app)/overview/page.tsx new file mode 100644 index 0000000..3cfd61f --- /dev/null +++ b/app/(authenticated)/(app)/overview/page.tsx @@ -0,0 +1,119 @@ +import Link from "next/link"; +import { notFound, redirect } from "next/navigation"; + +import { auth } from "@clerk/nextjs/app-beta"; +import { PageHeader } from "@/components/page-header"; +import { useUser } from "@clerk/clerk-react"; +import { Fragment } from "react"; +import { cn } from "@/lib/utils"; +import { getTenantId } from "@/lib/auth"; + +export default async function Page(_props: { + params: { tenantSlug: string }; +}) { + const tenantId = getTenantId(); + + const stats: { + label: string; + value: string; + }[] = [ + { + label: "Total Channels", + value: '0', + }, + { + label: "Total Events (7 days)", + value: '0', + }, + ]; + return ( +
+
+ {/* Stats */} +
+
+
+
+ {/*
+
+
*/} +

+ + {"Personal Account"} + +

+
+ {/*

{channel.description}

*/} +
+
+ test +
+
+
= 4, + }, + )} + > + {" "} + {stats.map((stat, statIdx) => ( +
+
{stat.label}
+ {/*
+ {stat.change} +
*/} +
+ {stat.value} +
+
+ ))} +
+
+
+ +
+ {/* Recent activity table */} +
+
+

+ Recent events +

+
+
+
+
+ + + + + + + + + + + +
EventContentMore details
+
+
+
+
+
+
+ ); +}