{guide.title}
{guide.description && ({guide.description}
)}{formatDate(guide.date)}
)}Repository: shadcn-ui/taxonomy Branch: main Commit: 651f984e52ed Files: 166 Total size: 337.3 KB Directory structure: gitextract_6s0f8trj/ ├── .commitlintrc.json ├── .editorconfig ├── .eslintrc.json ├── .gitignore ├── .husky/ │ ├── commit-msg │ └── pre-commit ├── .nvmrc ├── .prettierignore ├── LICENSE.md ├── README.md ├── app/ │ ├── (auth)/ │ │ ├── layout.tsx │ │ ├── login/ │ │ │ └── page.tsx │ │ └── register/ │ │ └── page.tsx │ ├── (dashboard)/ │ │ └── dashboard/ │ │ ├── billing/ │ │ │ ├── loading.tsx │ │ │ └── page.tsx │ │ ├── layout.tsx │ │ ├── loading.tsx │ │ ├── page.tsx │ │ └── settings/ │ │ ├── loading.tsx │ │ └── page.tsx │ ├── (docs)/ │ │ ├── docs/ │ │ │ ├── [[...slug]]/ │ │ │ │ └── page.tsx │ │ │ └── layout.tsx │ │ ├── guides/ │ │ │ ├── [...slug]/ │ │ │ │ └── page.tsx │ │ │ ├── layout.tsx │ │ │ └── page.tsx │ │ └── layout.tsx │ ├── (editor)/ │ │ └── editor/ │ │ ├── [postId]/ │ │ │ ├── loading.tsx │ │ │ ├── not-found.tsx │ │ │ └── page.tsx │ │ └── layout.tsx │ ├── (marketing)/ │ │ ├── [...slug]/ │ │ │ └── page.tsx │ │ ├── blog/ │ │ │ ├── [...slug]/ │ │ │ │ └── page.tsx │ │ │ └── page.tsx │ │ ├── layout.tsx │ │ ├── page.tsx │ │ └── pricing/ │ │ └── page.tsx │ ├── api/ │ │ ├── auth/ │ │ │ └── [...nextauth]/ │ │ │ └── _route.ts │ │ ├── og/ │ │ │ └── route.tsx │ │ ├── posts/ │ │ │ ├── [postId]/ │ │ │ │ └── route.ts │ │ │ └── route.ts │ │ ├── users/ │ │ │ ├── [userId]/ │ │ │ │ └── route.ts │ │ │ └── stripe/ │ │ │ └── route.ts │ │ └── webhooks/ │ │ └── stripe/ │ │ └── route.ts │ ├── layout.tsx │ └── robots.ts ├── components/ │ ├── analytics.tsx │ ├── billing-form.tsx │ ├── callout.tsx │ ├── card-skeleton.tsx │ ├── editor.tsx │ ├── empty-placeholder.tsx │ ├── header.tsx │ ├── icons.tsx │ ├── main-nav.tsx │ ├── mdx-card.tsx │ ├── mdx-components.tsx │ ├── mobile-nav.tsx │ ├── mode-toggle.tsx │ ├── nav.tsx │ ├── page-header.tsx │ ├── pager.tsx │ ├── post-create-button.tsx │ ├── post-item.tsx │ ├── post-operations.tsx │ ├── search.tsx │ ├── shell.tsx │ ├── sidebar-nav.tsx │ ├── site-footer.tsx │ ├── tailwind-indicator.tsx │ ├── theme-provider.tsx │ ├── toc.tsx │ ├── ui/ │ │ ├── accordion.tsx │ │ ├── alert-dialog.tsx │ │ ├── alert.tsx │ │ ├── aspect-ratio.tsx │ │ ├── avatar.tsx │ │ ├── badge.tsx │ │ ├── button.tsx │ │ ├── calendar.tsx │ │ ├── card.tsx │ │ ├── checkbox.tsx │ │ ├── collapsible.tsx │ │ ├── command.tsx │ │ ├── context-menu.tsx │ │ ├── dialog.tsx │ │ ├── dropdown-menu.tsx │ │ ├── hover-card.tsx │ │ ├── input.tsx │ │ ├── label.tsx │ │ ├── menubar.tsx │ │ ├── navigation-menu.tsx │ │ ├── popover.tsx │ │ ├── progress.tsx │ │ ├── radio-group.tsx │ │ ├── scroll-area.tsx │ │ ├── select.tsx │ │ ├── separator.tsx │ │ ├── sheet.tsx │ │ ├── skeleton.tsx │ │ ├── slider.tsx │ │ ├── switch.tsx │ │ ├── tabs.tsx │ │ ├── textarea.tsx │ │ ├── toast.tsx │ │ ├── toaster.tsx │ │ ├── toggle.tsx │ │ ├── tooltip.tsx │ │ └── use-toast.ts │ ├── user-account-nav.tsx │ ├── user-auth-form.tsx │ ├── user-avatar.tsx │ └── user-name-form.tsx ├── config/ │ ├── dashboard.ts │ ├── docs.ts │ ├── marketing.ts │ ├── site.ts │ └── subscriptions.ts ├── content/ │ ├── authors/ │ │ └── shadcn.mdx │ ├── blog/ │ │ ├── deploying-next-apps.mdx │ │ ├── dynamic-routing-static-regeneration.mdx │ │ ├── preview-mode-headless-cms.mdx │ │ └── server-client-components.mdx │ ├── docs/ │ │ ├── documentation/ │ │ │ ├── code-blocks.mdx │ │ │ ├── components.mdx │ │ │ ├── index.mdx │ │ │ └── style-guide.mdx │ │ ├── in-progress.mdx │ │ └── index.mdx │ ├── guides/ │ │ ├── build-blog-using-contentlayer-mdx.mdx │ │ └── using-next-auth-next-13.mdx │ └── pages/ │ ├── privacy.mdx │ └── terms.mdx ├── contentlayer.config.js ├── env.mjs ├── hooks/ │ ├── use-lock-body.ts │ └── use-mounted.ts ├── lib/ │ ├── auth.ts │ ├── db.ts │ ├── exceptions.ts │ ├── session.ts │ ├── stripe.ts │ ├── subscription.ts │ ├── toc.ts │ ├── utils.ts │ └── validations/ │ ├── auth.ts │ ├── og.ts │ ├── post.ts │ └── user.ts ├── middleware.ts ├── next.config.mjs ├── package.json ├── pages/ │ └── api/ │ └── auth/ │ └── [...nextauth].ts ├── postcss.config.js ├── prettier.config.js ├── prisma/ │ ├── migrations/ │ │ ├── 20221021182747_init/ │ │ │ └── migration.sql │ │ ├── 20221118173244_add_stripe_columns/ │ │ │ └── migration.sql │ │ └── migration_lock.toml │ └── schema.prisma ├── public/ │ └── site.webmanifest ├── styles/ │ ├── editor.css │ ├── globals.css │ └── mdx.css ├── tailwind.config.js ├── tsconfig.json └── types/ ├── index.d.ts └── next-auth.d.ts ================================================ FILE CONTENTS ================================================ ================================================ FILE: .commitlintrc.json ================================================ { "extends": ["@commitlint/config-conventional"] } ================================================ FILE: .editorconfig ================================================ # editorconfig.org root = true [*] charset = utf-8 end_of_line = lf indent_size = 2 indent_style = space insert_final_newline = true trim_trailing_whitespace = true ================================================ FILE: .eslintrc.json ================================================ { "$schema": "https://json.schemastore.org/eslintrc", "root": true, "extends": [ "next/core-web-vitals", "prettier", "plugin:tailwindcss/recommended" ], "plugins": ["tailwindcss"], "rules": { "@next/next/no-html-link-for-pages": "off", "react/jsx-key": "off", "tailwindcss/no-custom-classname": "off", "tailwindcss/classnames-order": "error" }, "settings": { "tailwindcss": { "callees": ["cn"], "config": "tailwind.config.js" }, "next": { "rootDir": true } }, "overrides": [ { "files": ["*.ts", "*.tsx"], "parser": "@typescript-eslint/parser" } ] } ================================================ FILE: .gitignore ================================================ # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. # dependencies /node_modules /.pnp .pnp.js # testing /coverage # next.js /.next/ /out/ # production /build # misc .DS_Store *.pem # debug npm-debug.log* yarn-debug.log* yarn-error.log* .pnpm-debug.log* # local env files .env*.local .env # vercel .vercel # typescript *.tsbuildinfo next-env.d.ts .vscode .contentlayer ================================================ FILE: .husky/commit-msg ================================================ #!/usr/bin/env sh . "$(dirname -- "$0")/_/husky.sh" npx commitlint --edit $1 ================================================ FILE: .husky/pre-commit ================================================ #!/usr/bin/env sh . "$(dirname -- "$0")/_/husky.sh" npx pretty-quick --staged ================================================ FILE: .nvmrc ================================================ v16.18.0 ================================================ FILE: .prettierignore ================================================ dist node_modules .next build .contentlayer ================================================ FILE: LICENSE.md ================================================ MIT License Copyright (c) 2022 shadcn Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: README.md ================================================ # Taxonomy An open source application built using the new router, server components and everything new in Next.js 13. > **Warning** > This app is a work in progress. I'm building this in public. You can follow the progress on Twitter [@shadcn](https://twitter.com/shadcn). > See the roadmap below. ## About this project This project as an experiment to see how a modern app (with features like authentication, subscriptions, API routes, static pages for docs ...etc) would work in Next.js 13 and server components. **This is not a starter template.** A few people have asked me to turn this into a starter. I think we could do that once the new features are out of beta. ## Note on Performance > **Warning** > This app is using the unstable releases for Next.js 13 and React 18. The new router and app dir is still in beta and not production-ready. > **Expect some performance hits when testing the dashboard**. > If you see something broken, you can ping me [@shadcn](https://twitter.com/shadcn). ## Features - New `/app` dir, - Routing, Layouts, Nested Layouts and Layout Groups - Data Fetching, Caching and Mutation - Loading UI - Route handlers - Metadata files - Server and Client Components - API Routes and Middlewares - Authentication using **NextAuth.js** - ORM using **Prisma** - Database on **PlanetScale** - UI Components built using **Radix UI** - Documentation and blog using **MDX** and **Contentlayer** - Subscriptions using **Stripe** - Styled using **Tailwind CSS** - Validations using **Zod** - Written in **TypeScript** ## Roadmap - [x] ~Add MDX support for basic pages~ - [x] ~Build marketing pages~ - [x] ~Subscriptions using Stripe~ - [x] ~Responsive styles~ - [x] ~Add OG image for blog using @vercel/og~ - [x] Dark mode ## Known Issues A list of things not working right now: 1. ~GitHub authentication (use email)~ 2. ~[Prisma: Error: ENOENT: no such file or directory, open '/var/task/.next/server/chunks/schema.prisma'](https://github.com/prisma/prisma/issues/16117)~ 3. ~[Next.js 13: Client side navigation does not update head](https://github.com/vercel/next.js/issues/42414)~ 4. [Cannot use opengraph-image.tsx inside catch-all routes](https://github.com/vercel/next.js/issues/48162) ## Why not tRPC, Turborepo or X? I might add this later. For now, I want to see how far we can get using Next.js only. If you have some suggestions, feel free to create an issue. ## Running Locally 1. Install dependencies using pnpm: ```sh pnpm install ``` 2. Copy `.env.example` to `.env.local` and update the variables. ```sh cp .env.example .env.local ``` 3. Start the development server: ```sh pnpm dev ``` ## License Licensed under the [MIT license](https://github.com/shadcn/taxonomy/blob/main/LICENSE.md). ================================================ FILE: app/(auth)/layout.tsx ================================================ interface AuthLayoutProps { children: React.ReactNode } export default function AuthLayout({ children }: AuthLayoutProps) { return
Enter your email to sign in to your account
Don't have an account? Sign Up
Enter your email below to create your account
By clicking continue, you agree to our{" "} Terms of Service {" "} and{" "} Privacy Policy .
{guide.description}
)}{formatDate(guide.date)}
)}No guides published.
)}{page.description}
)}{author.title}
@{author.twitter}
A blog built using Contentlayer. Posts are written in MDX.
{post.description}
)} {post.date && ({formatDate(post.date)}
)} View ArticleNo posts published.
)}I'm building a web app with Next.js 13 and open sourcing everything. Follow along as we figure this out together.
This project is an experiment to see how a modern app, with features like auth, subscriptions, API routes, and static pages would work in Next.js 13 app dir.
App dir, Routing, Layouts, Loading UI and API routes.
Server and Client Components. Use hook.
ORM using Prisma and deployed on PlanetScale.
UI components built using Radix UI and styled with Tailwind CSS.
Authentication using NextAuth.js and middlewares.
Free and paid subscriptions using Stripe.
Taxonomy also includes a blog and a full-featured documentation site built using Contentlayer and MDX.
Taxonomy is open source and powered by open source software.
{" "}
The code is available on{" "}
GitHub
.{" "}
Unlock all features including unlimited posts for your blog.
Billed Monthly
Taxonomy is a demo app.{" "} You can test the upgrade and won't be charged.
{text}
}*]:text-muted-foreground", className )} {...props} /> ), img: ({ className, alt, ...props }: React.ImgHTMLAttributes) => ( // eslint-disable-next-line @next/next/no-img-element ), hr: ({ ...props }) =>
, table: ({ className, ...props }: React.HTMLAttributes) => ( ), tr: ({ className, ...props }: React.HTMLAttributes
) => ( ), th: ({ className, ...props }) => ( ), td: ({ className, ...props }) => ( ), pre: ({ className, ...props }) => ( ), code: ({ className, ...props }) => ( ), Image, Callout, Card: MdxCard, } interface MdxProps { code: string } export function Mdx({ code }: MdxProps) { const Component = useMDXComponent(code) return () } ================================================ FILE: components/mobile-nav.tsx ================================================ import * as React from "react" import Link from "next/link" import { MainNavItem } from "types" import { siteConfig } from "@/config/site" import { cn } from "@/lib/utils" import { useLockBody } from "@/hooks/use-lock-body" import { Icons } from "@/components/icons" interface MobileNavProps { items: MainNavItem[] children?: React.ReactNode } export function MobileNav({ items, children }: MobileNavProps) { useLockBody() return ( ) } ================================================ FILE: components/mode-toggle.tsx ================================================ "use client" import * as React from "react" import { useTheme } from "next-themes" import { Button } from "@/components/ui/button" import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu" import { Icons } from "@/components/icons" export function ModeToggle() { const { setTheme } = useTheme() return ({siteConfig.name} {children} ) } ================================================ FILE: components/nav.tsx ================================================ "use client" import Link from "next/link" import { usePathname } from "next/navigation" import { SidebarNavItem } from "types" import { cn } from "@/lib/utils" import { Icons } from "@/components/icons" interface DashboardNavProps { items: SidebarNavItem[] } export function DashboardNav({ items }: DashboardNavProps) { const path = usePathname() if (!items?.length) { return null } return ( ) } ================================================ FILE: components/page-header.tsx ================================================ import { cn } from "@/lib/utils" interface DocsPageHeaderProps extends React.HTMLAttributes setTheme("light")}> Light setTheme("dark")}> Dark setTheme("system")}> System { heading: string text?: string } export function DocsPageHeader({ heading, text, className, ...props }: DocsPageHeaderProps) { return ( <> {heading}
{text &&{text}
}
> ) } ================================================ FILE: components/pager.tsx ================================================ import Link from "next/link" import { Doc } from "contentlayer/generated" import { docsConfig } from "@/config/docs" import { cn } from "@/lib/utils" import { buttonVariants } from "@/components/ui/button" import { Icons } from "@/components/icons" interface DocsPagerProps { doc: Doc } export function DocsPager({ doc }: DocsPagerProps) { const pager = getPagerForDoc(doc) if (!pager) { return null } return ({pager?.prev && () } export function getPagerForDoc(doc: Doc) { const flattenedLinks = [null, ...flatten(docsConfig.sidebarNav), null] const activeIndex = flattenedLinks.findIndex( (link) => doc.slug === link?.href ) const prev = activeIndex !== 0 ? flattenedLinks[activeIndex - 1] : null const next = activeIndex !== flattenedLinks.length - 1 ? flattenedLinks[activeIndex + 1] : null return { prev, next, } } export function flatten(links: { items? }[]) { return links.reduce((flat, link) => { return flat.concat(link.items ? flatten(link.items) : link) }, []) } ================================================ FILE: components/post-create-button.tsx ================================================ "use client" import * as React from "react" import { useRouter } from "next/navigation" import { cn } from "@/lib/utils" import { ButtonProps, buttonVariants } from "@/components/ui/button" import { toast } from "@/components/ui/use-toast" import { Icons } from "@/components/icons" interface PostCreateButtonProps extends ButtonProps {} export function PostCreateButton({ className, variant, ...props }: PostCreateButtonProps) { const router = useRouter() const [isLoading, setIsLoading] = React.useState{pager.prev.title} )} {pager?.next && ( {pager.next.title} )} (false) async function onClick() { setIsLoading(true) const response = await fetch("/api/posts", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ title: "Untitled Post", }), }) setIsLoading(false) if (!response?.ok) { if (response.status === 402) { return toast({ title: "Limit of 3 posts reached.", description: "Please upgrade to the PRO plan.", variant: "destructive", }) } return toast({ title: "Something went wrong.", description: "Your post was not created. Please try again.", variant: "destructive", }) } const post = await response.json() // This forces a cache invalidation. router.refresh() router.push(`/editor/${post.id}`) } return ( ) } ================================================ FILE: components/post-item.tsx ================================================ import Link from "next/link" import { Post } from "@prisma/client" import { formatDate } from "@/lib/utils" import { Skeleton } from "@/components/ui/skeleton" import { PostOperations } from "@/components/post-operations" interface PostItemProps { post: Pick } export function PostItem({ post }: PostItemProps) { return ( ) } PostItem.Skeleton = function PostItemSkeleton() { return ({post.title}{formatDate(post.createdAt?.toDateString())}
) } ================================================ FILE: components/post-operations.tsx ================================================ "use client" import * as React from "react" import Link from "next/link" import { useRouter } from "next/navigation" import { Post } from "@prisma/client" import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, } from "@/components/ui/alert-dialog" import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu" import { toast } from "@/components/ui/use-toast" import { Icons } from "@/components/icons" async function deletePost(postId: string) { const response = await fetch(`/api/posts/${postId}`, { method: "DELETE", }) if (!response?.ok) { toast({ title: "Something went wrong.", description: "Your post was not deleted. Please try again.", variant: "destructive", }) } return true } interface PostOperationsProps { post: Pick} export function PostOperations({ post }: PostOperationsProps) { const router = useRouter() const [showDeleteAlert, setShowDeleteAlert] = React.useState (false) const [isDeleteLoading, setIsDeleteLoading] = React.useState (false) return ( <> Open Edit setShowDeleteAlert(true)} > Delete > ) } ================================================ FILE: components/search.tsx ================================================ "use client" import * as React from "react" import { cn } from "@/lib/utils" import { Input } from "@/components/ui/input" import { toast } from "@/components/ui/use-toast" interface DocsSearchProps extends React.HTMLAttributes Are you sure you want to delete this post? This action cannot be undone. Cancel { event.preventDefault() setIsDeleteLoading(true) const deleted = await deletePost(post.id) if (deleted) { setIsDeleteLoading(false) setShowDeleteAlert(false) router.refresh() } }} className="bg-red-600 focus:ring-red-600" > {isDeleteLoading ? ( ) : ( )} Delete {} export function DocsSearch({ className, ...props }: DocsSearchProps) { function onSubmit(event: React.SyntheticEvent) { event.preventDefault() return toast({ title: "Not implemented", description: "We're still working on the search.", }) } return ( ) } ================================================ FILE: components/shell.tsx ================================================ import * as React from "react" import { cn } from "@/lib/utils" interface DashboardShellProps extends React.HTMLAttributes {} export function DashboardShell({ children, className, ...props }: DashboardShellProps) { return ( {children}) } ================================================ FILE: components/sidebar-nav.tsx ================================================ "use client" import Link from "next/link" import { usePathname } from "next/navigation" import { SidebarNavItem } from "types" import { cn } from "@/lib/utils" export interface DocsSidebarNavProps { items: SidebarNavItem[] } export function DocsSidebarNav({ items }: DocsSidebarNavProps) { const pathname = usePathname() return items.length ? ({items.map((item, index) => () : null } interface DocsSidebarNavItemsProps { items: SidebarNavItem[] pathname: string | null } export function DocsSidebarNavItems({ items, pathname, }: DocsSidebarNavItemsProps) { return items?.length ? ())}{item.title}
{item.items ? () : null} {items.map((item, index) => !item.disabled && item.href ? ( {item.title} ) : ( {item.title} ) )}) : null } ================================================ FILE: components/site-footer.tsx ================================================ import * as React from "react" import { siteConfig } from "@/config/site" import { cn } from "@/lib/utils" import { Icons } from "@/components/icons" import { ModeToggle } from "@/components/mode-toggle" export function SiteFooter({ className }: React.HTMLAttributes) { return ( ) } ================================================ FILE: components/tailwind-indicator.tsx ================================================ export function TailwindIndicator() { if (process.env.NODE_ENV === "production") return null return ( ) } ================================================ FILE: components/theme-provider.tsx ================================================ "use client" import * as React from "react" import { ThemeProvider as NextThemesProvider } from "next-themes" import { ThemeProviderProps } from "next-themes/dist/types" export function ThemeProvider({ children, ...props }: ThemeProviderProps) { returnxssmmdlgxl2xl{children} } ================================================ FILE: components/toc.tsx ================================================ "use client" import * as React from "react" import { TableOfContents } from "@/lib/toc" import { cn } from "@/lib/utils" import { useMounted } from "@/hooks/use-mounted" interface TocProps { toc: TableOfContents } export function DashboardTableOfContents({ toc }: TocProps) { const itemIds = React.useMemo( () => toc.items ? toc.items .flatMap((item) => [item.url, item?.items?.map((item) => item.url)]) .flat() .filter(Boolean) .map((id) => id?.split("#")[1]) : [], [toc] ) const activeHeading = useActiveItem(itemIds) const mounted = useMounted() if (!toc?.items) { return null } return mounted ? () : null } function useActiveItem(itemIds: (string | undefined)[]) { const [activeId, setActiveId] = React.useStateOn This Page
("") React.useEffect(() => { const observer = new IntersectionObserver( (entries) => { entries.forEach((entry) => { if (entry.isIntersecting) { setActiveId(entry.target.id) } }) }, { rootMargin: `0% 0% -80% 0%` } ) itemIds?.forEach((id) => { if (!id) { return } const element = document.getElementById(id) if (element) { observer.observe(element) } }) return () => { itemIds?.forEach((id) => { if (!id) { return } const element = document.getElementById(id) if (element) { observer.unobserve(element) } }) } }, [itemIds]) return activeId } interface TreeProps { tree: TableOfContents level?: number activeItem?: string | null } function Tree({ tree, level = 1, activeItem }: TreeProps) { return tree?.items?.length && level < 3 ? ( {tree.items.map((item, index) => { return (
) : null } ================================================ FILE: components/ui/accordion.tsx ================================================ "use client" import * as React from "react" import * as AccordionPrimitive from "@radix-ui/react-accordion" import { ChevronDown } from "lucide-react" import { cn } from "@/lib/utils" const Accordion = AccordionPrimitive.Root const AccordionItem = React.forwardRef< React.ElementRef- {item.title} {item.items?.length ? (
) })}) : null} , React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( )) AccordionItem.displayName = "AccordionItem" const AccordionTrigger = React.forwardRef< React.ElementRef , React.ComponentPropsWithoutRef >(({ className, children, ...props }, ref) => ( )) AccordionTrigger.displayName = AccordionPrimitive.Trigger.displayName const AccordionContent = React.forwardRef< React.ElementRef svg]:rotate-180", className )} {...props} > {children} , React.ComponentPropsWithoutRef >(({ className, children, ...props }, ref) => ( )) AccordionContent.displayName = AccordionPrimitive.Content.displayName export { Accordion, AccordionItem, AccordionTrigger, AccordionContent } ================================================ FILE: components/ui/alert-dialog.tsx ================================================ "use client" import * as React from "react" import * as AlertDialogPrimitive from "@radix-ui/react-alert-dialog" import { cn } from "@/lib/utils" import { buttonVariants } from "@/components/ui/button" const AlertDialog = AlertDialogPrimitive.Root const AlertDialogTrigger = AlertDialogPrimitive.Trigger const AlertDialogPortal = ({ className, children, ...props }: AlertDialogPrimitive.AlertDialogPortalProps) => ( {children}) AlertDialogPortal.displayName = AlertDialogPrimitive.Portal.displayName const AlertDialogOverlay = React.forwardRef< React.ElementRef {children}, React.ComponentPropsWithoutRef >(({ className, children, ...props }, ref) => ( )) AlertDialogOverlay.displayName = AlertDialogPrimitive.Overlay.displayName const AlertDialogContent = React.forwardRef< React.ElementRef , React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( )) AlertDialogContent.displayName = AlertDialogPrimitive.Content.displayName const AlertDialogHeader = ({ className, ...props }: React.HTMLAttributes ) => ( ) AlertDialogHeader.displayName = "AlertDialogHeader" const AlertDialogFooter = ({ className, ...props }: React.HTMLAttributes ) => ( ) AlertDialogFooter.displayName = "AlertDialogFooter" const AlertDialogTitle = React.forwardRef< React.ElementRef , React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( )) AlertDialogTitle.displayName = AlertDialogPrimitive.Title.displayName const AlertDialogDescription = React.forwardRef< React.ElementRef , React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( )) AlertDialogDescription.displayName = AlertDialogPrimitive.Description.displayName const AlertDialogAction = React.forwardRef< React.ElementRef , React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( )) AlertDialogAction.displayName = AlertDialogPrimitive.Action.displayName const AlertDialogCancel = React.forwardRef< React.ElementRef , React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( )) AlertDialogCancel.displayName = AlertDialogPrimitive.Cancel.displayName export { AlertDialog, AlertDialogTrigger, AlertDialogContent, AlertDialogHeader, AlertDialogFooter, AlertDialogTitle, AlertDialogDescription, AlertDialogAction, AlertDialogCancel, } ================================================ FILE: components/ui/alert.tsx ================================================ import * as React from "react" import { VariantProps, cva } from "class-variance-authority" import { cn } from "@/lib/utils" const alertVariants = cva( "relative w-full rounded-lg border p-4 [&>svg]:absolute [&>svg]:text-foreground [&>svg]:left-4 [&>svg]:top-4 [&>svg+div]:translate-y-[-3px] [&:has(svg)]:pl-11", { variants: { variant: { default: "bg-background text-foreground", destructive: "text-destructive border-destructive/50 dark:border-destructive [&>svg]:text-destructive text-destructive", }, }, defaultVariants: { variant: "default", }, } ) const Alert = React.forwardRef< HTMLDivElement, React.HTMLAttributes & VariantProps >(({ className, variant, ...props }, ref) => ( )) Alert.displayName = "Alert" const AlertTitle = React.forwardRef< HTMLParagraphElement, React.HTMLAttributes >(({ className, ...props }, ref) => ( )) AlertTitle.displayName = "AlertTitle" const AlertDescription = React.forwardRef< HTMLParagraphElement, React.HTMLAttributes >(({ className, ...props }, ref) => ( )) AlertDescription.displayName = "AlertDescription" export { Alert, AlertTitle, AlertDescription } ================================================ FILE: components/ui/aspect-ratio.tsx ================================================ "use client" import * as AspectRatioPrimitive from "@radix-ui/react-aspect-ratio" const AspectRatio = AspectRatioPrimitive.Root export { AspectRatio } ================================================ FILE: components/ui/avatar.tsx ================================================ "use client" import * as React from "react" import * as AvatarPrimitive from "@radix-ui/react-avatar" import { cn } from "@/lib/utils" const Avatar = React.forwardRef< React.ElementRef , React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( )) Avatar.displayName = AvatarPrimitive.Root.displayName const AvatarImage = React.forwardRef< React.ElementRef , React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( )) AvatarImage.displayName = AvatarPrimitive.Image.displayName const AvatarFallback = React.forwardRef< React.ElementRef , React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( )) AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName export { Avatar, AvatarImage, AvatarFallback } ================================================ FILE: components/ui/badge.tsx ================================================ import * as React from "react" import { VariantProps, cva } from "class-variance-authority" import { cn } from "@/lib/utils" const badgeVariants = cva( "inline-flex items-center border rounded-full px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2", { variants: { variant: { default: "bg-primary hover:bg-primary/80 border-transparent text-primary-foreground", secondary: "bg-secondary hover:bg-secondary/80 border-transparent text-secondary-foreground", destructive: "bg-destructive hover:bg-destructive/80 border-transparent text-destructive-foreground", outline: "text-foreground", }, }, defaultVariants: { variant: "default", }, } ) export interface BadgeProps extends React.HTMLAttributes , VariantProps {} function Badge({ className, variant, ...props }: BadgeProps) { return ( ) } export { Badge, badgeVariants } ================================================ FILE: components/ui/button.tsx ================================================ import * as React from "react" import { VariantProps, cva } from "class-variance-authority" import { cn } from "@/lib/utils" const buttonVariants = cva( "inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:opacity-50 disabled:pointer-events-none ring-offset-background", { variants: { variant: { default: "bg-primary text-primary-foreground hover:bg-primary/90", destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90", outline: "border border-input hover:bg-accent hover:text-accent-foreground", secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80", ghost: "hover:bg-accent hover:text-accent-foreground", link: "underline-offset-4 hover:underline text-primary", }, size: { default: "h-10 py-2 px-4", sm: "h-9 px-3 rounded-md", lg: "h-11 px-8 rounded-md", }, }, defaultVariants: { variant: "default", size: "default", }, } ) export interface ButtonProps extends React.ButtonHTMLAttributes , VariantProps {} const Button = React.forwardRef ( ({ className, variant, size, ...props }, ref) => { return ( ) } ) Button.displayName = "Button" export { Button, buttonVariants } ================================================ FILE: components/ui/calendar.tsx ================================================ "use client" import * as React from "react" import { ChevronLeft, ChevronRight } from "lucide-react" import { DayPicker } from "react-day-picker" import { cn } from "@/lib/utils" import { buttonVariants } from "@/components/ui/button" export type CalendarProps = React.ComponentProps function Calendar({ className, classNames, showOutsideDays = true, ...props }: CalendarProps) { return ( , IconRight: ({ ...props }) => , }} {...props} /> ) } Calendar.displayName = "Calendar" export { Calendar } ================================================ FILE: components/ui/card.tsx ================================================ import * as React from "react" import { cn } from "@/lib/utils" const Card = React.forwardRef< HTMLDivElement, React.HTMLAttributes >(({ className, ...props }, ref) => ( )) Card.displayName = "Card" const CardHeader = React.forwardRef< HTMLDivElement, React.HTMLAttributes >(({ className, ...props }, ref) => ( )) CardHeader.displayName = "CardHeader" const CardTitle = React.forwardRef< HTMLParagraphElement, React.HTMLAttributes >(({ className, ...props }, ref) => ( )) CardTitle.displayName = "CardTitle" const CardDescription = React.forwardRef< HTMLParagraphElement, React.HTMLAttributes >(({ className, ...props }, ref) => ( )) CardDescription.displayName = "CardDescription" const CardContent = React.forwardRef< HTMLDivElement, React.HTMLAttributes >(({ className, ...props }, ref) => ( )) CardContent.displayName = "CardContent" const CardFooter = React.forwardRef< HTMLDivElement, React.HTMLAttributes >(({ className, ...props }, ref) => ( )) CardFooter.displayName = "CardFooter" export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent } ================================================ FILE: components/ui/checkbox.tsx ================================================ "use client" import * as React from "react" import * as CheckboxPrimitive from "@radix-ui/react-checkbox" import { Check } from "lucide-react" import { cn } from "@/lib/utils" const Checkbox = React.forwardRef< React.ElementRef , React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( )) Checkbox.displayName = CheckboxPrimitive.Root.displayName export { Checkbox } ================================================ FILE: components/ui/collapsible.tsx ================================================ "use client" import * as CollapsiblePrimitive from "@radix-ui/react-collapsible" const Collapsible = CollapsiblePrimitive.Root const CollapsibleTrigger = CollapsiblePrimitive.CollapsibleTrigger const CollapsibleContent = CollapsiblePrimitive.CollapsibleContent export { Collapsible, CollapsibleTrigger, CollapsibleContent } ================================================ FILE: components/ui/command.tsx ================================================ "use client" import * as React from "react" import { DialogProps } from "@radix-ui/react-dialog" import { Command as CommandPrimitive } from "cmdk" import { Search } from "lucide-react" import { cn } from "@/lib/utils" import { Dialog, DialogContent } from "@/components/ui/dialog" const Command = React.forwardRef< React.ElementRef , React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( )) Command.displayName = CommandPrimitive.displayName interface CommandDialogProps extends DialogProps {} const CommandDialog = ({ children, ...props }: CommandDialogProps) => { return ( ) } const CommandInput = React.forwardRef< React.ElementRef , React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( )) CommandInput.displayName = CommandPrimitive.Input.displayName const CommandList = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( )) CommandList.displayName = CommandPrimitive.List.displayName const CommandEmpty = React.forwardRef< React.ElementRef , React.ComponentPropsWithoutRef >((props, ref) => ( )) CommandEmpty.displayName = CommandPrimitive.Empty.displayName const CommandGroup = React.forwardRef< React.ElementRef , React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( )) CommandGroup.displayName = CommandPrimitive.Group.displayName const CommandSeparator = React.forwardRef< React.ElementRef , React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( )) CommandSeparator.displayName = CommandPrimitive.Separator.displayName const CommandItem = React.forwardRef< React.ElementRef , React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( )) CommandItem.displayName = CommandPrimitive.Item.displayName const CommandShortcut = ({ className, ...props }: React.HTMLAttributes ) => { return ( ) } CommandShortcut.displayName = "CommandShortcut" export { Command, CommandDialog, CommandInput, CommandList, CommandEmpty, CommandGroup, CommandItem, CommandShortcut, CommandSeparator, } ================================================ FILE: components/ui/context-menu.tsx ================================================ "use client" import * as React from "react" import * as ContextMenuPrimitive from "@radix-ui/react-context-menu" import { Check, ChevronRight, Circle } from "lucide-react" import { cn } from "@/lib/utils" const ContextMenu = ContextMenuPrimitive.Root const ContextMenuTrigger = ContextMenuPrimitive.Trigger const ContextMenuGroup = ContextMenuPrimitive.Group const ContextMenuPortal = ContextMenuPrimitive.Portal const ContextMenuSub = ContextMenuPrimitive.Sub const ContextMenuRadioGroup = ContextMenuPrimitive.RadioGroup const ContextMenuSubTrigger = React.forwardRef< React.ElementRef , React.ComponentPropsWithoutRef & { inset?: boolean } >(({ className, inset, children, ...props }, ref) => ( {children} )) ContextMenuSubTrigger.displayName = ContextMenuPrimitive.SubTrigger.displayName const ContextMenuSubContent = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( )) ContextMenuSubContent.displayName = ContextMenuPrimitive.SubContent.displayName const ContextMenuContent = React.forwardRef< React.ElementRef , React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( )) ContextMenuContent.displayName = ContextMenuPrimitive.Content.displayName const ContextMenuItem = React.forwardRef< React.ElementRef , React.ComponentPropsWithoutRef & { inset?: boolean } >(({ className, inset, ...props }, ref) => ( )) ContextMenuItem.displayName = ContextMenuPrimitive.Item.displayName const ContextMenuCheckboxItem = React.forwardRef< React.ElementRef , React.ComponentPropsWithoutRef >(({ className, children, checked, ...props }, ref) => ( )) ContextMenuCheckboxItem.displayName = ContextMenuPrimitive.CheckboxItem.displayName const ContextMenuRadioItem = React.forwardRef< React.ElementRef {children} , React.ComponentPropsWithoutRef >(({ className, children, ...props }, ref) => ( )) ContextMenuRadioItem.displayName = ContextMenuPrimitive.RadioItem.displayName const ContextMenuLabel = React.forwardRef< React.ElementRef {children} , React.ComponentPropsWithoutRef & { inset?: boolean } >(({ className, inset, ...props }, ref) => ( )) ContextMenuLabel.displayName = ContextMenuPrimitive.Label.displayName const ContextMenuSeparator = React.forwardRef< React.ElementRef , React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( )) ContextMenuSeparator.displayName = ContextMenuPrimitive.Separator.displayName const ContextMenuShortcut = ({ className, ...props }: React.HTMLAttributes ) => { return ( ) } ContextMenuShortcut.displayName = "ContextMenuShortcut" export { ContextMenu, ContextMenuTrigger, ContextMenuContent, ContextMenuItem, ContextMenuCheckboxItem, ContextMenuRadioItem, ContextMenuLabel, ContextMenuSeparator, ContextMenuShortcut, ContextMenuGroup, ContextMenuPortal, ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger, ContextMenuRadioGroup, } ================================================ FILE: components/ui/dialog.tsx ================================================ "use client" import * as React from "react" import * as DialogPrimitive from "@radix-ui/react-dialog" import { X } from "lucide-react" import { cn } from "@/lib/utils" const Dialog = DialogPrimitive.Root const DialogTrigger = DialogPrimitive.Trigger const DialogPortal = ({ className, children, ...props }: DialogPrimitive.DialogPortalProps) => ( ) DialogPortal.displayName = DialogPrimitive.Portal.displayName const DialogOverlay = React.forwardRef< React.ElementRef {children}, React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( )) DialogOverlay.displayName = DialogPrimitive.Overlay.displayName const DialogContent = React.forwardRef< React.ElementRef , React.ComponentPropsWithoutRef >(({ className, children, ...props }, ref) => ( )) DialogContent.displayName = DialogPrimitive.Content.displayName const DialogHeader = ({ className, ...props }: React.HTMLAttributes {children} Close ) => ( ) DialogHeader.displayName = "DialogHeader" const DialogFooter = ({ className, ...props }: React.HTMLAttributes ) => ( ) DialogFooter.displayName = "DialogFooter" const DialogTitle = React.forwardRef< React.ElementRef , React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( )) DialogTitle.displayName = DialogPrimitive.Title.displayName const DialogDescription = React.forwardRef< React.ElementRef , React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( )) DialogDescription.displayName = DialogPrimitive.Description.displayName export { Dialog, DialogTrigger, DialogContent, DialogHeader, DialogFooter, DialogTitle, DialogDescription, } ================================================ FILE: components/ui/dropdown-menu.tsx ================================================ "use client" import * as React from "react" import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu" import { Check, ChevronRight, Circle } from "lucide-react" import { cn } from "@/lib/utils" const DropdownMenu = DropdownMenuPrimitive.Root const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger const DropdownMenuGroup = DropdownMenuPrimitive.Group const DropdownMenuPortal = DropdownMenuPrimitive.Portal const DropdownMenuSub = DropdownMenuPrimitive.Sub const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup const DropdownMenuSubTrigger = React.forwardRef< React.ElementRef , React.ComponentPropsWithoutRef & { inset?: boolean } >(({ className, inset, children, ...props }, ref) => ( {children} )) DropdownMenuSubTrigger.displayName = DropdownMenuPrimitive.SubTrigger.displayName const DropdownMenuSubContent = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( )) DropdownMenuSubContent.displayName = DropdownMenuPrimitive.SubContent.displayName const DropdownMenuContent = React.forwardRef< React.ElementRef , React.ComponentPropsWithoutRef >(({ className, sideOffset = 4, ...props }, ref) => ( )) DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName const DropdownMenuItem = React.forwardRef< React.ElementRef , React.ComponentPropsWithoutRef & { inset?: boolean } >(({ className, inset, ...props }, ref) => ( )) DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName const DropdownMenuCheckboxItem = React.forwardRef< React.ElementRef , React.ComponentPropsWithoutRef >(({ className, children, checked, ...props }, ref) => ( )) DropdownMenuCheckboxItem.displayName = DropdownMenuPrimitive.CheckboxItem.displayName const DropdownMenuRadioItem = React.forwardRef< React.ElementRef {children} , React.ComponentPropsWithoutRef >(({ className, children, ...props }, ref) => ( )) DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName const DropdownMenuLabel = React.forwardRef< React.ElementRef {children} , React.ComponentPropsWithoutRef & { inset?: boolean } >(({ className, inset, ...props }, ref) => ( )) DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName const DropdownMenuSeparator = React.forwardRef< React.ElementRef , React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( )) DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName const DropdownMenuShortcut = ({ className, ...props }: React.HTMLAttributes ) => { return ( ) } DropdownMenuShortcut.displayName = "DropdownMenuShortcut" export { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem, DropdownMenuCheckboxItem, DropdownMenuRadioItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuGroup, DropdownMenuPortal, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuRadioGroup, } ================================================ FILE: components/ui/hover-card.tsx ================================================ "use client" import * as React from "react" import * as HoverCardPrimitive from "@radix-ui/react-hover-card" import { cn } from "@/lib/utils" const HoverCard = HoverCardPrimitive.Root const HoverCardTrigger = HoverCardPrimitive.Trigger const HoverCardContent = React.forwardRef< React.ElementRef , React.ComponentPropsWithoutRef >(({ className, align = "center", sideOffset = 4, ...props }, ref) => ( )) HoverCardContent.displayName = HoverCardPrimitive.Content.displayName export { HoverCard, HoverCardTrigger, HoverCardContent } ================================================ FILE: components/ui/input.tsx ================================================ import * as React from "react" import { cn } from "@/lib/utils" export interface InputProps extends React.InputHTMLAttributes {} const Input = React.forwardRef ( ({ className, type, ...props }, ref) => { return ( ) } ) Input.displayName = "Input" export { Input } ================================================ FILE: components/ui/label.tsx ================================================ "use client" import * as React from "react" import * as LabelPrimitive from "@radix-ui/react-label" import { VariantProps, cva } from "class-variance-authority" import { cn } from "@/lib/utils" const labelVariants = cva( "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70" ) const Label = React.forwardRef< React.ElementRef , React.ComponentPropsWithoutRef & VariantProps >(({ className, ...props }, ref) => ( )) Label.displayName = LabelPrimitive.Root.displayName export { Label } ================================================ FILE: components/ui/menubar.tsx ================================================ "use client" import * as React from "react" import * as MenubarPrimitive from "@radix-ui/react-menubar" import { Check, ChevronRight, Circle } from "lucide-react" import { cn } from "@/lib/utils" const MenubarMenu = MenubarPrimitive.Menu const MenubarGroup = MenubarPrimitive.Group const MenubarPortal = MenubarPrimitive.Portal const MenubarSub = MenubarPrimitive.Sub const MenubarRadioGroup = MenubarPrimitive.RadioGroup const Menubar = React.forwardRef< React.ElementRef , React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( )) Menubar.displayName = MenubarPrimitive.Root.displayName const MenubarTrigger = React.forwardRef< React.ElementRef , React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( )) MenubarTrigger.displayName = MenubarPrimitive.Trigger.displayName const MenubarSubTrigger = React.forwardRef< React.ElementRef , React.ComponentPropsWithoutRef & { inset?: boolean } >(({ className, inset, children, ...props }, ref) => ( {children} )) MenubarSubTrigger.displayName = MenubarPrimitive.SubTrigger.displayName const MenubarSubContent = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( )) MenubarSubContent.displayName = MenubarPrimitive.SubContent.displayName const MenubarContent = React.forwardRef< React.ElementRef , React.ComponentPropsWithoutRef >( ( { className, align = "start", alignOffset = -4, sideOffset = 8, ...props }, ref ) => ( ) ) MenubarContent.displayName = MenubarPrimitive.Content.displayName const MenubarItem = React.forwardRef< React.ElementRef , React.ComponentPropsWithoutRef & { inset?: boolean } >(({ className, inset, ...props }, ref) => ( )) MenubarItem.displayName = MenubarPrimitive.Item.displayName const MenubarCheckboxItem = React.forwardRef< React.ElementRef , React.ComponentPropsWithoutRef >(({ className, children, checked, ...props }, ref) => ( )) MenubarCheckboxItem.displayName = MenubarPrimitive.CheckboxItem.displayName const MenubarRadioItem = React.forwardRef< React.ElementRef {children} , React.ComponentPropsWithoutRef >(({ className, children, ...props }, ref) => ( )) MenubarRadioItem.displayName = MenubarPrimitive.RadioItem.displayName const MenubarLabel = React.forwardRef< React.ElementRef {children} , React.ComponentPropsWithoutRef & { inset?: boolean } >(({ className, inset, ...props }, ref) => ( )) MenubarLabel.displayName = MenubarPrimitive.Label.displayName const MenubarSeparator = React.forwardRef< React.ElementRef , React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( )) MenubarSeparator.displayName = MenubarPrimitive.Separator.displayName const MenubarShortcut = ({ className, ...props }: React.HTMLAttributes ) => { return ( ) } MenubarShortcut.displayname = "MenubarShortcut" export { Menubar, MenubarMenu, MenubarTrigger, MenubarContent, MenubarItem, MenubarSeparator, MenubarLabel, MenubarCheckboxItem, MenubarRadioGroup, MenubarRadioItem, MenubarPortal, MenubarSubContent, MenubarSubTrigger, MenubarGroup, MenubarSub, MenubarShortcut, } ================================================ FILE: components/ui/navigation-menu.tsx ================================================ import * as React from "react" import * as NavigationMenuPrimitive from "@radix-ui/react-navigation-menu" import { cva } from "class-variance-authority" import { ChevronDown } from "lucide-react" import { cn } from "@/lib/utils" const NavigationMenu = React.forwardRef< React.ElementRef , React.ComponentPropsWithoutRef >(({ className, children, ...props }, ref) => ( {children} )) NavigationMenu.displayName = NavigationMenuPrimitive.Root.displayName const NavigationMenuList = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( )) NavigationMenuList.displayName = NavigationMenuPrimitive.List.displayName const NavigationMenuItem = NavigationMenuPrimitive.Item const navigationMenuTriggerStyle = cva( "inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors focus:outline-none focus:bg-accent focus:text-accent-foreground disabled:opacity-50 disabled:pointer-events-none bg-background hover:bg-accent hover:text-accent-foreground data-[state=open]:bg-accent/50 data-[active]:bg-accent/50 h-10 py-2 px-4 group w-max" ) const NavigationMenuTrigger = React.forwardRef< React.ElementRef , React.ComponentPropsWithoutRef >(({ className, children, ...props }, ref) => ( {children}{" "} )) NavigationMenuTrigger.displayName = NavigationMenuPrimitive.Trigger.displayName const NavigationMenuContent = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( )) NavigationMenuContent.displayName = NavigationMenuPrimitive.Content.displayName const NavigationMenuLink = NavigationMenuPrimitive.Link const NavigationMenuViewport = React.forwardRef< React.ElementRef , React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( )) NavigationMenuViewport.displayName = NavigationMenuPrimitive.Viewport.displayName const NavigationMenuIndicator = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( )) NavigationMenuIndicator.displayName = NavigationMenuPrimitive.Indicator.displayName export { navigationMenuTriggerStyle, NavigationMenu, NavigationMenuList, NavigationMenuItem, NavigationMenuContent, NavigationMenuTrigger, NavigationMenuLink, NavigationMenuIndicator, NavigationMenuViewport, } ================================================ FILE: components/ui/popover.tsx ================================================ "use client" import * as React from "react" import * as PopoverPrimitive from "@radix-ui/react-popover" import { cn } from "@/lib/utils" const Popover = PopoverPrimitive.Root const PopoverTrigger = PopoverPrimitive.Trigger const PopoverContent = React.forwardRef< React.ElementRef , React.ComponentPropsWithoutRef >(({ className, align = "center", sideOffset = 4, ...props }, ref) => ( )) PopoverContent.displayName = PopoverPrimitive.Content.displayName export { Popover, PopoverTrigger, PopoverContent } ================================================ FILE: components/ui/progress.tsx ================================================ "use client" import * as React from "react" import * as ProgressPrimitive from "@radix-ui/react-progress" import { cn } from "@/lib/utils" const Progress = React.forwardRef< React.ElementRef , React.ComponentPropsWithoutRef >(({ className, value, ...props }, ref) => ( )) Progress.displayName = ProgressPrimitive.Root.displayName export { Progress } ================================================ FILE: components/ui/radio-group.tsx ================================================ "use client" import * as React from "react" import * as RadioGroupPrimitive from "@radix-ui/react-radio-group" import { Circle } from "lucide-react" import { cn } from "@/lib/utils" const RadioGroup = React.forwardRef< React.ElementRef , React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => { return ( ) }) RadioGroup.displayName = RadioGroupPrimitive.Root.displayName const RadioGroupItem = React.forwardRef< React.ElementRef , React.ComponentPropsWithoutRef >(({ className, children, ...props }, ref) => { return ( ) }) RadioGroupItem.displayName = RadioGroupPrimitive.Item.displayName export { RadioGroup, RadioGroupItem } ================================================ FILE: components/ui/scroll-area.tsx ================================================ "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 , React.ComponentPropsWithoutRef >(({ className, children, ...props }, ref) => ( )) ScrollArea.displayName = ScrollAreaPrimitive.Root.displayName const ScrollBar = React.forwardRef< React.ElementRef {children} , React.ComponentPropsWithoutRef >(({ className, orientation = "vertical", ...props }, ref) => ( )) ScrollBar.displayName = ScrollAreaPrimitive.ScrollAreaScrollbar.displayName export { ScrollArea, ScrollBar } ================================================ FILE: components/ui/select.tsx ================================================ "use client" import * as React from "react" import * as SelectPrimitive from "@radix-ui/react-select" import { Check, ChevronDown } from "lucide-react" import { cn } from "@/lib/utils" const Select = SelectPrimitive.Root const SelectGroup = SelectPrimitive.Group const SelectValue = SelectPrimitive.Value const SelectTrigger = React.forwardRef< React.ElementRef , React.ComponentPropsWithoutRef >(({ className, children, ...props }, ref) => ( {children} )) SelectTrigger.displayName = SelectPrimitive.Trigger.displayName const SelectContent = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, children, position = "popper", ...props }, ref) => ( )) SelectContent.displayName = SelectPrimitive.Content.displayName const SelectLabel = React.forwardRef< React.ElementRef {children} , React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( )) SelectLabel.displayName = SelectPrimitive.Label.displayName const SelectItem = React.forwardRef< React.ElementRef , React.ComponentPropsWithoutRef >(({ className, children, ...props }, ref) => ( )) SelectItem.displayName = SelectPrimitive.Item.displayName const SelectSeparator = React.forwardRef< React.ElementRef {children} , React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( )) SelectSeparator.displayName = SelectPrimitive.Separator.displayName export { Select, SelectGroup, SelectValue, SelectTrigger, SelectContent, SelectLabel, SelectItem, SelectSeparator, } ================================================ FILE: components/ui/separator.tsx ================================================ "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 , React.ComponentPropsWithoutRef >( ( { className, orientation = "horizontal", decorative = true, ...props }, ref ) => ( ) ) Separator.displayName = SeparatorPrimitive.Root.displayName export { Separator } ================================================ FILE: components/ui/sheet.tsx ================================================ "use client" import * as React from "react" import * as SheetPrimitive from "@radix-ui/react-dialog" import { VariantProps, cva } from "class-variance-authority" import { X } from "lucide-react" import { cn } from "@/lib/utils" const Sheet = SheetPrimitive.Root const SheetTrigger = SheetPrimitive.Trigger const portalVariants = cva("fixed inset-0 z-50 flex", { variants: { position: { top: "items-start", bottom: "items-end", left: "justify-start", right: "justify-end", }, }, defaultVariants: { position: "right" }, }) interface SheetPortalProps extends SheetPrimitive.DialogPortalProps, VariantProps {} const SheetPortal = ({ position, className, children, ...props }: SheetPortalProps) => ( ) SheetPortal.displayName = SheetPrimitive.Portal.displayName const SheetOverlay = React.forwardRef< React.ElementRef {children}, React.ComponentPropsWithoutRef >(({ className, children, ...props }, ref) => ( )) SheetOverlay.displayName = SheetPrimitive.Overlay.displayName const sheetVariants = cva( "fixed z-50 scale-100 gap-4 bg-background p-6 opacity-100 shadow-lg border", { variants: { position: { top: "animate-in slide-in-from-top w-full duration-300", bottom: "animate-in slide-in-from-bottom w-full duration-300", left: "animate-in slide-in-from-left h-full duration-300", right: "animate-in slide-in-from-right h-full duration-300", }, size: { content: "", default: "", sm: "", lg: "", xl: "", full: "", }, }, compoundVariants: [ { position: ["top", "bottom"], size: "content", class: "max-h-screen", }, { position: ["top", "bottom"], size: "default", class: "h-1/3", }, { position: ["top", "bottom"], size: "sm", class: "h-1/4", }, { position: ["top", "bottom"], size: "lg", class: "h-1/2", }, { position: ["top", "bottom"], size: "xl", class: "h-5/6", }, { position: ["top", "bottom"], size: "full", class: "h-screen", }, { position: ["right", "left"], size: "content", class: "max-w-screen", }, { position: ["right", "left"], size: "default", class: "w-1/3", }, { position: ["right", "left"], size: "sm", class: "w-1/4", }, { position: ["right", "left"], size: "lg", class: "w-1/2", }, { position: ["right", "left"], size: "xl", class: "w-5/6", }, { position: ["right", "left"], size: "full", class: "w-screen", }, ], defaultVariants: { position: "right", size: "default", }, } ) export interface DialogContentProps extends React.ComponentPropsWithoutRef , VariantProps {} const SheetContent = React.forwardRef< React.ElementRef , DialogContentProps >(({ position, size, className, children, ...props }, ref) => ( )) SheetContent.displayName = SheetPrimitive.Content.displayName const SheetHeader = ({ className, ...props }: React.HTMLAttributes {children} Close ) => ( ) SheetHeader.displayName = "SheetHeader" const SheetFooter = ({ className, ...props }: React.HTMLAttributes ) => ( ) SheetFooter.displayName = "SheetFooter" const SheetTitle = React.forwardRef< React.ElementRef , React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( )) SheetTitle.displayName = SheetPrimitive.Title.displayName const SheetDescription = React.forwardRef< React.ElementRef , React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( )) SheetDescription.displayName = SheetPrimitive.Description.displayName export { Sheet, SheetTrigger, SheetContent, SheetHeader, SheetFooter, SheetTitle, SheetDescription, } ================================================ FILE: components/ui/skeleton.tsx ================================================ import { cn } from "@/lib/utils" function Skeleton({ className, ...props }: React.HTMLAttributes ) { return ( ) } export { Skeleton } ================================================ FILE: components/ui/slider.tsx ================================================ "use client" import * as React from "react" import * as SliderPrimitive from "@radix-ui/react-slider" import { cn } from "@/lib/utils" const Slider = React.forwardRef< React.ElementRef , React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( )) Slider.displayName = SliderPrimitive.Root.displayName export { Slider } ================================================ FILE: components/ui/switch.tsx ================================================ "use client" import * as React from "react" import * as SwitchPrimitives from "@radix-ui/react-switch" import { cn } from "@/lib/utils" const Switch = React.forwardRef< React.ElementRef , React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( )) Switch.displayName = SwitchPrimitives.Root.displayName export { Switch } ================================================ FILE: components/ui/tabs.tsx ================================================ "use client" import * as React from "react" import * as TabsPrimitive from "@radix-ui/react-tabs" import { cn } from "@/lib/utils" const Tabs = TabsPrimitive.Root const TabsList = React.forwardRef< React.ElementRef , React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( )) TabsList.displayName = TabsPrimitive.List.displayName const TabsTrigger = React.forwardRef< React.ElementRef , React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( )) TabsTrigger.displayName = TabsPrimitive.Trigger.displayName const TabsContent = React.forwardRef< React.ElementRef , React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( )) TabsContent.displayName = TabsPrimitive.Content.displayName export { Tabs, TabsList, TabsTrigger, TabsContent } ================================================ FILE: components/ui/textarea.tsx ================================================ import * as React from "react" import { cn } from "@/lib/utils" export interface TextareaProps extends React.TextareaHTMLAttributes {} const Textarea = React.forwardRef ( ({ className, ...props }, ref) => { return ( ) } ) Textarea.displayName = "Textarea" export { Textarea } ================================================ FILE: components/ui/toast.tsx ================================================ import * as React from "react" import * as ToastPrimitives from "@radix-ui/react-toast" import { VariantProps, cva } from "class-variance-authority" import { X } from "lucide-react" import { cn } from "@/lib/utils" const ToastProvider = ToastPrimitives.Provider const ToastViewport = React.forwardRef< React.ElementRef , React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( )) ToastViewport.displayName = ToastPrimitives.Viewport.displayName const toastVariants = cva( "data-[swipe=move]:transition-none group relative pointer-events-auto flex w-full items-center justify-between space-x-4 overflow-hidden rounded-md border p-6 pr-8 shadow-lg transition-all data-[swipe=move]:translate-x-[var(--radix-toast-swipe-move-x)] data-[swipe=cancel]:translate-x-0 data-[swipe=end]:translate-x-[var(--radix-toast-swipe-end-x)] data-[state=open]:animate-in data-[state=closed]:animate-out data-[swipe=end]:animate-out data-[state=closed]:fade-out-80 data-[state=open]:slide-in-from-top-full data-[state=open]:sm:slide-in-from-bottom-full data-[state=closed]:slide-out-to-right-full", { variants: { variant: { default: "bg-background border", destructive: "group destructive border-destructive bg-destructive text-destructive-foreground", }, }, defaultVariants: { variant: "default", }, } ) const Toast = React.forwardRef< React.ElementRef , React.ComponentPropsWithoutRef & VariantProps >(({ className, variant, ...props }, ref) => { return ( ) }) Toast.displayName = ToastPrimitives.Root.displayName const ToastAction = React.forwardRef< React.ElementRef , React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( )) ToastAction.displayName = ToastPrimitives.Action.displayName const ToastClose = React.forwardRef< React.ElementRef , React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( )) ToastClose.displayName = ToastPrimitives.Close.displayName const ToastTitle = React.forwardRef< React.ElementRef , React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( )) ToastTitle.displayName = ToastPrimitives.Title.displayName const ToastDescription = React.forwardRef< React.ElementRef , React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( )) ToastDescription.displayName = ToastPrimitives.Description.displayName type ToastProps = React.ComponentPropsWithoutRef type ToastActionElement = React.ReactElement export { type ToastProps, type ToastActionElement, ToastProvider, ToastViewport, Toast, ToastTitle, ToastDescription, ToastClose, ToastAction, } ================================================ FILE: components/ui/toaster.tsx ================================================ "use client" import { Toast, ToastClose, ToastDescription, ToastProvider, ToastTitle, ToastViewport, } from "@/components/ui/toast" import { useToast } from "@/components/ui/use-toast" export function Toaster() { const { toasts } = useToast() return ( {toasts.map(function ({ id, title, description, action, ...props }) { return ( ) } ================================================ FILE: components/ui/toggle.tsx ================================================ "use client" import * as React from "react" import * as TogglePrimitive from "@radix-ui/react-toggle" import { VariantProps, cva } from "class-variance-authority" import { cn } from "@/lib/utils" const toggleVariants = cva( "inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors data-[state=on]:bg-accent data-[state=on]:text-accent-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 ring-offset-background hover:bg-muted hover:text-muted-foreground", { variants: { variant: { default: "bg-transparent", outline: "bg-transparent border border-input hover:bg-accent hover:text-accent-foreground", }, size: { default: "h-10 px-3", sm: "h-9 px-2.5", lg: "h-11 px-5", }, }, defaultVariants: { variant: "default", size: "default", }, } ) const Toggle = React.forwardRef< React.ElementRef) })} {title &&{action}{title} } {description && ({description} )}, React.ComponentPropsWithoutRef & VariantProps >(({ className, variant, size, ...props }, ref) => ( )) Toggle.displayName = TogglePrimitive.Root.displayName export { Toggle, toggleVariants } ================================================ FILE: components/ui/tooltip.tsx ================================================ "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 , React.ComponentPropsWithoutRef >(({ className, sideOffset = 4, ...props }, ref) => ( )) TooltipContent.displayName = TooltipPrimitive.Content.displayName export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider } ================================================ FILE: components/ui/use-toast.ts ================================================ // Inspired by react-hot-toast library import * as React from "react" import { ToastActionElement, type ToastProps } from "@/components/ui/toast" const TOAST_LIMIT = 1 const TOAST_REMOVE_DELAY = 1000000 type ToasterToast = ToastProps & { id: string title?: React.ReactNode description?: React.ReactNode action?: ToastActionElement } const actionTypes = { ADD_TOAST: "ADD_TOAST", UPDATE_TOAST: "UPDATE_TOAST", DISMISS_TOAST: "DISMISS_TOAST", REMOVE_TOAST: "REMOVE_TOAST", } as const let count = 0 function genId() { count = (count + 1) % Number.MAX_VALUE return count.toString() } type ActionType = typeof actionTypes type Action = | { type: ActionType["ADD_TOAST"] toast: ToasterToast } | { type: ActionType["UPDATE_TOAST"] toast: Partial } | { type: ActionType["DISMISS_TOAST"] toastId?: ToasterToast["id"] } | { type: ActionType["REMOVE_TOAST"] toastId?: ToasterToast["id"] } interface State { toasts: ToasterToast[] } const toastTimeouts = new Map >() const addToRemoveQueue = (toastId: string) => { if (toastTimeouts.has(toastId)) { return } const timeout = setTimeout(() => { toastTimeouts.delete(toastId) dispatch({ type: "REMOVE_TOAST", toastId: toastId, }) }, TOAST_REMOVE_DELAY) toastTimeouts.set(toastId, timeout) } export const reducer = (state: State, action: Action): State => { switch (action.type) { case "ADD_TOAST": return { ...state, toasts: [action.toast, ...state.toasts].slice(0, TOAST_LIMIT), } case "UPDATE_TOAST": return { ...state, toasts: state.toasts.map((t) => t.id === action.toast.id ? { ...t, ...action.toast } : t ), } case "DISMISS_TOAST": { const { toastId } = action // ! Side effects ! - This could be extracted into a dismissToast() action, // but I'll keep it here for simplicity if (toastId) { addToRemoveQueue(toastId) } else { state.toasts.forEach((toast) => { addToRemoveQueue(toast.id) }) } return { ...state, toasts: state.toasts.map((t) => t.id === toastId || toastId === undefined ? { ...t, open: false, } : t ), } } case "REMOVE_TOAST": if (action.toastId === undefined) { return { ...state, toasts: [], } } return { ...state, toasts: state.toasts.filter((t) => t.id !== action.toastId), } } } const listeners: Array<(state: State) => void> = [] let memoryState: State = { toasts: [] } function dispatch(action: Action) { memoryState = reducer(memoryState, action) listeners.forEach((listener) => { listener(memoryState) }) } interface Toast extends Omit {} function toast({ ...props }: Toast) { const id = genId() const update = (props: ToasterToast) => dispatch({ type: "UPDATE_TOAST", toast: { ...props, id }, }) const dismiss = () => dispatch({ type: "DISMISS_TOAST", toastId: id }) dispatch({ type: "ADD_TOAST", toast: { ...props, id, open: true, onOpenChange: (open) => { if (!open) dismiss() }, }, }) return { id: id, dismiss, update, } } function useToast() { const [state, setState] = React.useState (memoryState) React.useEffect(() => { listeners.push(setState) return () => { const index = listeners.indexOf(setState) if (index > -1) { listeners.splice(index, 1) } } }, [state]) return { ...state, toast, dismiss: (toastId?: string) => dispatch({ type: "DISMISS_TOAST", toastId }), } } export { useToast, toast } ================================================ FILE: components/user-account-nav.tsx ================================================ "use client" import Link from "next/link" import { User } from "next-auth" import { signOut } from "next-auth/react" import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu" import { UserAvatar } from "@/components/user-avatar" interface UserAccountNavProps extends React.HTMLAttributes { user: Pick } export function UserAccountNav({ user }: UserAccountNavProps) { return (