Skip to content

Commit

Permalink
Merge pull request sadmann7#135 from sadmann7/update-sidebar
Browse files Browse the repository at this point in the history
feat: update sidebar and cards
  • Loading branch information
sadmann7 authored May 5, 2024
2 parents 6d79ab8 + 2bcdf46 commit a656d64
Show file tree
Hide file tree
Showing 50 changed files with 468 additions and 397 deletions.
2 changes: 1 addition & 1 deletion src/app/(auth)/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export default function AuthLayout({ children }: React.PropsWithChildren) {
<div className="relative aspect-video size-full">
<Image
src="/images/auth-layout.webp"
alt="A skateboarder doing a high drop"
alt="A skateboarder dropping into a bowl"
fill
className="absolute inset-0 object-cover"
priority
Expand Down
2 changes: 1 addition & 1 deletion src/app/(checkout)/checkout/[storeId]/error.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// Error components must be Client Components
import * as React from "react"

import { ErrorCard } from "@/components/cards/error-card"
import { ErrorCard } from "@/components/error-card"
import { Shell } from "@/components/shell"

export default function StoreCheckoutError({
Expand Down
14 changes: 2 additions & 12 deletions src/app/(dashboard)/dashboard/_components/dashboard-header.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
import Link from "next/link"
import type { User } from "@clerk/nextjs/server"

import { siteConfig } from "@/config/site"
import { Icons } from "@/components/icons"
import { AuthDropdown } from "@/components/layouts/auth-dropdown"

interface DashboardHeaderProps {
Expand All @@ -12,15 +9,8 @@ interface DashboardHeaderProps {

export function DashboardHeader({ user, children }: DashboardHeaderProps) {
return (
<header className="sticky top-0 z-50 w-full border-b bg-background">
<div className="container flex h-16 items-center">
<Link href="/" className="hidden items-center space-x-2 lg:flex">
<Icons.logo className="size-6" aria-hidden="true" />
<span className="hidden font-bold lg:inline-block">
{siteConfig.name}
</span>
<span className="sr-only">Home</span>
</Link>
<header className="sticky top-0 z-50 w-full border-b border-border/60 bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60">
<div className="flex h-14 items-center px-6">
{children}
<div className="flex flex-1 items-center justify-end space-x-4">
<nav className="flex items-center space-x-2">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,15 @@

import Link from "next/link"

import { siteConfig } from "@/config/site"
import { cn } from "@/lib/utils"
import { useMediaQuery } from "@/hooks/use-media-query"
import { Button, type ButtonProps } from "@/components/ui/button"
import { Sheet, SheetContent, SheetTrigger } from "@/components/ui/sheet"
import {
Sheet,
SheetClose,
SheetContent,
SheetTrigger,
} from "@/components/ui/sheet"
import { Icons } from "@/components/icons"

import { useSidebar } from "./sidebar-provider"
Expand Down Expand Up @@ -41,19 +45,16 @@ export function DashboardSidebarSheet({
</SheetTrigger>
<SheetContent
side="left"
className="inset-y-0 flex h-auto w-[300px] flex-col items-center px-0 pt-9"
className="inset-y-0 flex h-auto w-[18.75rem] flex-col items-center gap-4 px-0 py-4"
>
<div className="w-full self-start px-7">
<SheetClose asChild>
<Link
href="/"
className="flex items-center"
onClick={() => setOpen(false)}
className="mx-6 flex items-center self-start font-heading tracking-wider text-foreground/90 transition-colors hover:text-foreground"
>
<Icons.logo className="mr-2 size-4" aria-hidden="true" />
<span className="font-bold">{siteConfig.name}</span>
<span className="sr-only">Home</span>
<Icons.logo className="size-6" aria-hidden="true" />
</Link>
</div>
</SheetClose>
{children}
</SheetContent>
</Sheet>
Expand Down
20 changes: 17 additions & 3 deletions src/app/(dashboard)/dashboard/_components/dashboard-sidebar.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import * as React from "react"
import Link from "next/link"

import { dashboardConfig } from "@/config/dashboard"
import { siteConfig } from "@/config/site"
import { cn } from "@/lib/utils"
import { ScrollArea } from "@/components/ui/scroll-area"
import { Icons } from "@/components/icons"
import { SidebarNav } from "@/components/layouts/sidebar-nav"

interface DashboardSidebarProps extends React.HTMLAttributes<HTMLElement> {
Expand All @@ -15,9 +18,20 @@ export function DashboardSidebar({
...props
}: DashboardSidebarProps) {
return (
<aside className={cn("w-full", className)} {...props}>
<div className="pr-6 pt-4 lg:pt-6">{children}</div>
<ScrollArea className="h-[calc(100vh-8rem)] py-2.5 pr-6">
<aside className={cn("h-screen w-full", className)} {...props}>
<div className="hidden h-[3.55rem] items-center border-b border-border/60 px-6 lg:flex">
<Link
href="/"
className="flex w-fit items-center font-heading tracking-wider text-foreground/90 transition-colors hover:text-foreground"
>
<Icons.logo className="mb-1 mr-2 size-6" aria-hidden="true" />
{siteConfig.name}
</Link>
</div>
<div className="flex flex-col gap-2.5 px-4 pt-2 lg:px-6 lg:pt-4">
{children}
</div>
<ScrollArea className="h-[calc(100vh-8rem)] px-3 py-2.5 lg:px-5">
<SidebarNav items={dashboardConfig.sidebarNav} className="p-1 pt-4" />
</ScrollArea>
</aside>
Expand Down
32 changes: 26 additions & 6 deletions src/app/(dashboard)/dashboard/_components/store-switcher.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@

import * as React from "react"
import { useParams, usePathname, useRouter } from "next/navigation"
import { DialogTitle } from "@radix-ui/react-dialog"
import {
CaretSortIcon,
CheckIcon,
FrameIcon,
PlusCircledIcon,
ShadowIcon,
} from "@radix-ui/react-icons"

import { type getStoresByUserId } from "@/lib/actions/store"
Expand All @@ -22,11 +23,13 @@ import {
CommandList,
CommandSeparator,
} from "@/components/ui/command"
import { Dialog, DialogContent, DialogHeader } from "@/components/ui/dialog"
import {
Popover,
PopoverContent,
PopoverTrigger,
} from "@/components/ui/popover"
import { RateLimitAlert } from "@/components/rate-limit-alert"

import { CreateStoreDialog } from "../stores/_components/create-store-dialog"

Expand All @@ -49,9 +52,12 @@ export function StoreSwitcher({
const pathname = usePathname()
const [open, setOpen] = React.useState(false)
const [showNewStoreDialog, setShowNewStoreDialog] = React.useState(false)
const [showRateLimitDialog, setShowRateLimitDialog] = React.useState(false)

const stores = React.use(storesPromise)
const planMetrics = React.use(planMetricsPromise)
const rateLimitExceeded =
planMetrics.storeLimitExceeded || planMetrics.productLimitExceeded

const selectedStore = stores.find((store) => store.id === storeId)

Expand All @@ -62,8 +68,15 @@ export function StoreSwitcher({
planMetricsPromise={planMetricsPromise}
open={showNewStoreDialog}
onOpenChange={setShowNewStoreDialog}
showTrigger={false}
/>
<Dialog open={showRateLimitDialog} onOpenChange={setShowRateLimitDialog}>
<DialogContent className="gap-0">
<DialogHeader className="text-left">
<DialogTitle>Rate limit exceeded</DialogTitle>
</DialogHeader>
<RateLimitAlert planMetrics={planMetrics} />
</DialogContent>
</Dialog>
<Popover open={open} onOpenChange={setOpen}>
<PopoverTrigger asChild>
<Button
Expand All @@ -76,7 +89,7 @@ export function StoreSwitcher({
>
{selectedStore?.name ?? "Select a store"}
<CaretSortIcon
className="ml-auto size-3.5 shrink-0 opacity-50"
className="ml-auto size-4 shrink-0 opacity-50"
aria-hidden="true"
/>
</Button>
Expand All @@ -98,7 +111,10 @@ export function StoreSwitcher({
}}
className="text-sm"
>
<ShadowIcon className="mr-2 size-5" aria-hidden="true" />
<FrameIcon
className="mr-2 size-4 text-muted-foreground"
aria-hidden="true"
/>
{store.name}
<CheckIcon
className={cn(
Expand All @@ -118,12 +134,16 @@ export function StoreSwitcher({
<CommandGroup>
<CommandItem
onSelect={() => {
if (rateLimitExceeded) {
setShowRateLimitDialog(true)
return
}

setOpen(false)
setShowNewStoreDialog(true)
}}
disabled={planMetrics.storeLimitExceeded}
>
<PlusCircledIcon className="mr-2 size-5" aria-hidden="true" />
<PlusCircledIcon className="mr-2 size-4" aria-hidden="true" />
Create store
</CommandItem>
</CommandGroup>
Expand Down
4 changes: 2 additions & 2 deletions src/app/(dashboard)/dashboard/billing/_components/billing.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ import {
CardHeader,
CardTitle,
} from "@/components/ui/card"
import { UsageCard } from "@/components/cards/usage-card"
import { ManageSubscriptionForm } from "@/components/manage-subscription-form"
import { UsageCard } from "@/components/usage-card"

interface BillingProps {
subscriptionPlanPromise: Promise<UserSubscriptionPlan | null>
Expand Down Expand Up @@ -121,7 +121,7 @@ export async function Billing({
stripePriceId={plan.stripePriceId}
stripeCustomerId={subscriptionPlan?.stripeCustomerId}
stripeSubscriptionId={subscriptionPlan?.stripeSubscriptionId}
isSubscribed={subscriptionPlan?.isSubscribed ?? false}
isSubscribed={subscriptionPlan?.isSubscribed}
isCurrentPlan={subscriptionPlan?.title === plan.title}
/>
)}
Expand Down
49 changes: 21 additions & 28 deletions src/app/(dashboard)/dashboard/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { redirect } from "next/navigation"

import { getStoresByUserId } from "@/lib/actions/store"
import { getCachedUser, getUserPlanMetrics } from "@/lib/queries/user"
import { SiteFooter } from "@/components/layouts/site-footer"

import { DashboardHeader } from "./_components/dashboard-header"
import { DashboardSidebar } from "./_components/dashboard-sidebar"
Expand All @@ -24,34 +23,28 @@ export default async function DashboardLayout({

return (
<SidebarProvider>
<div className="flex min-h-screen flex-col">
<DashboardHeader user={user}>
<DashboardSidebarSheet className="lg:hidden">
<DashboardSidebar className="pl-4">
<StoreSwitcher
userId={user.id}
storesPromise={storesPromise}
planMetricsPromise={planMetricsPromise}
/>
</DashboardSidebar>
</DashboardSidebarSheet>
</DashboardHeader>
<div className="container flex-1 items-start lg:grid lg:grid-cols-[240px_minmax(0,1fr)] lg:gap-10">
<DashboardSidebar
// the top-16 class is used for the dashboard-header of h-16, added extra 0.1rem to fix the sticky layout shift issue
className="top-[calc(theme('spacing.16')_+_0.1rem)] z-30 hidden border-r lg:sticky lg:block"
>
<StoreSwitcher
userId={user.id}
storesPromise={storesPromise}
planMetricsPromise={planMetricsPromise}
/>
</DashboardSidebar>
<main className="flex w-full flex-col overflow-hidden">
{children}
</main>
<div className="grid min-h-screen w-full lg:grid-cols-[17.5rem_1fr]">
<DashboardSidebar className="top-0 z-30 hidden flex-col gap-4 border-r border-border/60 lg:sticky lg:block">
<StoreSwitcher
userId={user.id}
storesPromise={storesPromise}
planMetricsPromise={planMetricsPromise}
/>
</DashboardSidebar>
<div className="flex flex-col">
<DashboardHeader user={user}>
<DashboardSidebarSheet className="lg:hidden">
<DashboardSidebar>
<StoreSwitcher
userId={user.id}
storesPromise={storesPromise}
planMetricsPromise={planMetricsPromise}
/>
</DashboardSidebar>
</DashboardSidebarSheet>
</DashboardHeader>
<main className="flex-1 overflow-hidden px-6">{children}</main>
</div>
<SiteFooter />
</div>
</SidebarProvider>
)
Expand Down
2 changes: 1 addition & 1 deletion src/app/(dashboard)/dashboard/stores/[storeId]/error.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// Error components must be Client Components
import * as React from "react"

import { ErrorCard } from "@/components/cards/error-card"
import { ErrorCard } from "@/components/error-card"

export default function UpdateStoreError({
error,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ErrorCard } from "@/components/cards/error-card"
import { ErrorCard } from "@/components/error-card"
import { Shell } from "@/components/shell"

export default function StoreNotFound() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ import {
SelectValue,
} from "@/components/ui/select"
import { Textarea } from "@/components/ui/textarea"
import { FilesCard } from "@/components/cards/FilesCard"
import { FileUploader } from "@/components/file-uploader"
import { Files } from "@/components/files"
import { Icons } from "@/components/icons"

interface UpdateProductFormProps {
Expand Down Expand Up @@ -279,7 +279,7 @@ export function UpdateProductForm({
<FormMessage />
</FormItem>
{uploadedFiles.length > 0 ? (
<FilesCard files={uploadedFiles} />
<Files files={uploadedFiles} />
) : null}
</div>
)}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ErrorCard } from "@/components/cards/error-card"
import { ErrorCard } from "@/components/error-card"
import { Shell } from "@/components/shell"

interface ProductNotFoundProps {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ import {
SelectValue,
} from "@/components/ui/select"
import { Textarea } from "@/components/ui/textarea"
import { FilesCard } from "@/components/cards/FilesCard"
import { FileUploader } from "@/components/file-uploader"
import { Files } from "@/components/files"
import { Icons } from "@/components/icons"

interface CreateProductFormProps {
Expand Down Expand Up @@ -307,7 +307,7 @@ export function CreateProductForm({
<FormMessage />
</FormItem>
{uploadedFiles.length > 0 ? (
<FilesCard files={uploadedFiles} />
<Files files={uploadedFiles} />
) : null}
</div>
)}
Expand Down
Loading

0 comments on commit a656d64

Please sign in to comment.