diff --git a/apps/client/components.json b/apps/client/components.json index fc9f93ae..b6232ec4 100644 --- a/apps/client/components.json +++ b/apps/client/components.json @@ -11,11 +11,10 @@ }, "iconLibrary": "lucide", "aliases": { - "components": "@/common/components", - "utils": "@/libs/utils", - "ui": "@/libs/ui", - "lib": "@/libs", - "hooks": "@/common/hooks" + "ui": "@/libs/ui/components", + "components": "@/libs/ui/components", + "hooks": "@/libs/ui/hooks", + "utils": "@/libs/ui/utils.ts" }, "registries": {}, "$schema": "https://ui.shadcn.com/schema.json" diff --git a/apps/client/package-lock.json b/apps/client/package-lock.json index fcfa52a1..d07aecbd 100644 --- a/apps/client/package-lock.json +++ b/apps/client/package-lock.json @@ -10,8 +10,13 @@ "dependencies": { "@clerk/clerk-react": "^5.35.3", "@clerk/types": "^4.90.0", + "@radix-ui/react-avatar": "^1.1.10", + "@radix-ui/react-dialog": "^1.1.15", + "@radix-ui/react-dropdown-menu": "^2.1.16", + "@radix-ui/react-scroll-area": "^1.2.10", "@radix-ui/react-separator": "^1.1.7", "@radix-ui/react-slot": "^1.2.3", + "@radix-ui/react-tooltip": "^1.2.8", "@tailwindcss/vite": "^4.1.11", "@tanstack/react-form": "^1.15.0", "@tanstack/react-query": "^5.90.2", diff --git a/apps/client/package.json b/apps/client/package.json index f56068a4..071852cd 100644 --- a/apps/client/package.json +++ b/apps/client/package.json @@ -17,8 +17,13 @@ "dependencies": { "@clerk/clerk-react": "^5.35.3", "@clerk/types": "^4.90.0", + "@radix-ui/react-avatar": "^1.1.10", + "@radix-ui/react-dialog": "^1.1.15", + "@radix-ui/react-dropdown-menu": "^2.1.16", + "@radix-ui/react-scroll-area": "^1.2.10", "@radix-ui/react-separator": "^1.1.7", "@radix-ui/react-slot": "^1.2.3", + "@radix-ui/react-tooltip": "^1.2.8", "@tailwindcss/vite": "^4.1.11", "@tanstack/react-form": "^1.15.0", "@tanstack/react-query": "^5.90.2", diff --git a/apps/client/src/app/app.tsx b/apps/client/src/app/app.tsx index b1aa7aa5..a8a815c6 100644 --- a/apps/client/src/app/app.tsx +++ b/apps/client/src/app/app.tsx @@ -16,6 +16,8 @@ export function App() { ) } +// TODO: refactor loading to better handle changing auth states --> multiple loading screens encountered during login/logout + function EntryPoint() { const [isReady, setIsReady] = useState(false) const auth = useAuth() diff --git a/apps/client/src/app/loading.tsx b/apps/client/src/app/loading.tsx index c557951d..804f8eb1 100644 --- a/apps/client/src/app/loading.tsx +++ b/apps/client/src/app/loading.tsx @@ -3,8 +3,8 @@ import { useEffect, useState } from "react" import { AnimatePresence, motion } from "motion/react" import { EchoLogo } from "@/common/components/logos/echo-logo" -import { MotionContainer } from "@/libs/ui/container" -import { Page } from "@/libs/ui/page" +import { MotionContainer } from "@/libs/ui/components/container" +import { Page } from "@/libs/ui/components/page" interface Props { isReady: boolean diff --git a/apps/client/src/common/components/sidebar/sidebar-footer.tsx b/apps/client/src/common/components/sidebar/sidebar-footer.tsx new file mode 100644 index 00000000..9a7a2b1c --- /dev/null +++ b/apps/client/src/common/components/sidebar/sidebar-footer.tsx @@ -0,0 +1,32 @@ +import { useUser } from "@clerk/clerk-react" +import { ChevronsUpDown, UserRound } from "lucide-react" + +import { Avatar, AvatarFallback, AvatarImage } from "@/libs/ui/components/avatar" +import { SidebarMenuButton } from "@/libs/ui/components/sidebar" + +export function Footer() { + const { user } = useUser() + + return ( + + + + + + + +
+ {user?.username} + {user?.primaryEmailAddress?.emailAddress} +
+ +
+ ) +} diff --git a/apps/client/src/common/components/sidebar/sidebar-header.tsx b/apps/client/src/common/components/sidebar/sidebar-header.tsx new file mode 100644 index 00000000..ee6a7fb1 --- /dev/null +++ b/apps/client/src/common/components/sidebar/sidebar-header.tsx @@ -0,0 +1,16 @@ +import { Separator } from "@/libs/ui/components/separator" +import { SidebarTrigger } from "@/libs/ui/components/sidebar" +import Large from "@/libs/ui/components/typography/large" + +export function Header() { + return ( +
+ + + Navigation +
+ ) +} diff --git a/apps/client/src/common/components/sidebar/sidebar-nav.config.ts b/apps/client/src/common/components/sidebar/sidebar-nav.config.ts new file mode 100644 index 00000000..f736f190 --- /dev/null +++ b/apps/client/src/common/components/sidebar/sidebar-nav.config.ts @@ -0,0 +1,27 @@ +import { linkOptions } from "@tanstack/react-router" +import { House, MessageSquare, Search, UserRound } from "lucide-react" + +const options = linkOptions([ + { + icon: House, + label: "Home", + to: "/home" + }, + { + icon: Search, + label: "Search", + to: "/onboarding" // TODO: temporary avoid type error + }, + { + icon: UserRound, + label: "Profile", + to: "/onboarding" // TODO: temporary avoid type error + }, + { + icon: MessageSquare, + label: "Chat", + to: "/onboarding" // TODO: temporary avoid type error + } +]) + +export { options } diff --git a/apps/client/src/common/components/sidebar/sidebar-nav.tsx b/apps/client/src/common/components/sidebar/sidebar-nav.tsx new file mode 100644 index 00000000..6373007c --- /dev/null +++ b/apps/client/src/common/components/sidebar/sidebar-nav.tsx @@ -0,0 +1,38 @@ +import { Link } from "@tanstack/react-router" + +import { + SidebarGroup, + SidebarGroupContent, + SidebarMenu, + SidebarMenuButton, + SidebarMenuItem +} from "@/libs/ui/components/sidebar" + +import { options } from "./sidebar-nav.config" + +export function Navigation() { + return ( + + + + {options.map((option) => ( + + + + + {option.label} + + + + ))} + + + + ) +} diff --git a/apps/client/src/common/components/sidebar/sidebar.tsx b/apps/client/src/common/components/sidebar/sidebar.tsx new file mode 100644 index 00000000..7ad7b620 --- /dev/null +++ b/apps/client/src/common/components/sidebar/sidebar.tsx @@ -0,0 +1,24 @@ +import { Sidebar, SidebarContent, SidebarFooter, SidebarHeader } from "@/libs/ui/components/sidebar" + +import { Footer } from "./sidebar-footer" +import { Header } from "./sidebar-header" +import { Navigation } from "./sidebar-nav" + +export function AppSidebar() { + return ( + + +
+ + + + + +