Skip to content

Commit 25f1864

Browse files
committed
refactor: new dashboard layout (sidebar)
1 parent 576868e commit 25f1864

39 files changed

+1099
-449
lines changed

app/(protected)/admin/layout.tsx

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { notFound, redirect } from "next/navigation";
2+
3+
import { getCurrentUser } from "@/lib/session";
4+
5+
interface ProtectedLayoutProps {
6+
children: React.ReactNode;
7+
}
8+
9+
export default async function Dashboard({ children }: ProtectedLayoutProps) {
10+
const user = await getCurrentUser();
11+
if (!user || user.role !== "ADMIN") redirect("/login");
12+
13+
return <>{children}</>;
14+
}

app/(protected)/admin/loading.tsx

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { Skeleton } from "@/components/ui/skeleton";
2+
import { DashboardHeader } from "@/components/dashboard/header";
3+
4+
export default function AdminPanelLoading() {
5+
return (
6+
<>
7+
<DashboardHeader
8+
heading="Admin Panel"
9+
text="Access only for users with ADMIN role."
10+
/>
11+
<div className="flex flex-col gap-5">
12+
<div className="grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4">
13+
<Skeleton className="h-32 w-full rounded-lg" />
14+
<Skeleton className="h-32 w-full rounded-lg" />
15+
<Skeleton className="h-32 w-full rounded-lg" />
16+
<Skeleton className="h-32 w-full rounded-lg" />
17+
</div>
18+
<Skeleton className="h-[500px] w-full rounded-lg" />
19+
<Skeleton className="h-[500px] w-full rounded-lg" />
20+
</div>
21+
</>
22+
);
23+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { Skeleton } from "@/components/ui/skeleton";
2+
import { DashboardHeader } from "@/components/dashboard/header";
3+
4+
export default function OrdersLoading() {
5+
return (
6+
<>
7+
<DashboardHeader
8+
heading="Orders"
9+
text="Check and manage your latest orders."
10+
/>
11+
<Skeleton className="size-full rounded-lg" />
12+
</>
13+
);
14+
}

app/(protected)/admin/orders/page.tsx

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import { redirect } from "next/navigation";
2+
3+
import { getCurrentUser } from "@/lib/session";
4+
import { constructMetadata } from "@/lib/utils";
5+
import { Button } from "@/components/ui/button";
6+
import { DashboardHeader } from "@/components/dashboard/header";
7+
import { EmptyPlaceholder } from "@/components/shared/empty-placeholder";
8+
9+
export const metadata = constructMetadata({
10+
title: "Orders – SaaS Starter",
11+
description: "Check and manage your latest orders.",
12+
});
13+
14+
export default async function OrdersPage() {
15+
// const user = await getCurrentUser();
16+
// if (!user || user.role !== "ADMIN") redirect("/login");
17+
18+
return (
19+
<>
20+
<DashboardHeader
21+
heading="Orders"
22+
text="Check and manage your latest orders."
23+
/>
24+
<EmptyPlaceholder>
25+
<EmptyPlaceholder.Icon name="package" />
26+
<EmptyPlaceholder.Title>No orders listed</EmptyPlaceholder.Title>
27+
<EmptyPlaceholder.Description>
28+
You don&apos;t have any orders yet. Start ordering a product.
29+
</EmptyPlaceholder.Description>
30+
<Button>Buy Products</Button>
31+
</EmptyPlaceholder>
32+
</>
33+
);
34+
}

app/(protected)/admin/page.tsx

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import { getCurrentUser } from "@/lib/session";
44
import { constructMetadata } from "@/lib/utils";
55
import { DashboardHeader } from "@/components/dashboard/header";
66
import InfoCard from "@/components/dashboard/info-card";
7-
import { DashboardShell } from "@/components/dashboard/shell";
87
import TransactionsList from "@/components/dashboard/transactions-list";
98

109
export const metadata = constructMetadata({
@@ -17,16 +16,21 @@ export default async function AdminPage() {
1716
if (!user || user.role !== "ADMIN") redirect("/login");
1817

1918
return (
20-
<DashboardShell>
21-
<DashboardHeader heading="Admin" text="Access only for admin." />
19+
<>
20+
<DashboardHeader
21+
heading="Admin Panel"
22+
text="Access only for users with ADMIN role."
23+
/>
2224
<div className="flex flex-col gap-5">
23-
<div className="grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3">
25+
<div className="grid grid-cols-1 gap-4 sm:grid-cols-2 xl:grid-cols-4">
26+
<InfoCard />
2427
<InfoCard />
2528
<InfoCard />
2629
<InfoCard />
2730
</div>
2831
<TransactionsList />
32+
<TransactionsList />
2933
</div>
30-
</DashboardShell>
34+
</>
3135
);
3236
}
Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
import { Skeleton } from "@/components/ui/skeleton";
22
import { DashboardHeader } from "@/components/dashboard/header";
3-
import { DashboardShell } from "@/components/dashboard/shell";
43
import { CardSkeleton } from "@/components/shared/card-skeleton";
54

65
export default function DashboardBillingLoading() {
76
return (
8-
<DashboardShell>
7+
<>
98
<DashboardHeader
109
heading="Billing"
1110
text="Manage billing and your subscription plan."
@@ -14,6 +13,6 @@ export default function DashboardBillingLoading() {
1413
<Skeleton className="h-28 w-full rounded-lg md:h-24" />
1514
<CardSkeleton />
1615
</div>
17-
</DashboardShell>
16+
</>
1817
);
1918
}

app/(protected)/dashboard/billing/page.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import { getUserSubscriptionPlan } from "@/lib/subscription";
55
import { constructMetadata } from "@/lib/utils";
66
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
77
import { DashboardHeader } from "@/components/dashboard/header";
8-
import { DashboardShell } from "@/components/dashboard/shell";
98
import { BillingInfo } from "@/components/pricing/billing-info";
109
import { Icons } from "@/components/shared/icons";
1110

@@ -25,7 +24,7 @@ export default async function BillingPage() {
2524
}
2625

2726
return (
28-
<DashboardShell>
27+
<>
2928
<DashboardHeader
3029
heading="Billing"
3130
text="Manage billing and your subscription plan."
@@ -50,6 +49,6 @@ export default async function BillingPage() {
5049
</Alert>
5150
<BillingInfo userSubscriptionPlan={userSubscriptionPlan} />
5251
</div>
53-
</DashboardShell>
52+
</>
5453
);
5554
}

app/(protected)/dashboard/charts/loading.tsx

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,16 @@ export default function ChartsLoading() {
55
return (
66
<>
77
<DashboardHeader heading="Charts" text="List of charts by shadcn-ui." />
8-
<Skeleton className="size-full rounded-lg" />
8+
<div className="flex flex-col gap-5">
9+
<div className="grid grid-cols-1 gap-4 sm:grid-cols-2 2xl:grid-cols-4">
10+
<Skeleton className="h-80 w-full rounded-lg md:max-xl:h-[390px] xl:max-2xl:h-[420px]" />
11+
<Skeleton className="h-80 w-full rounded-lg md:max-xl:h-[390px] xl:max-2xl:h-[420px]" />
12+
<Skeleton className="h-80 w-full rounded-lg md:max-xl:h-[390px] xl:max-2xl:h-[420px]" />
13+
<Skeleton className="h-80 w-full rounded-lg md:max-xl:h-[390px] xl:max-2xl:h-[420px]" />
14+
</div>
15+
<Skeleton className="h-[500px] w-full rounded-lg" />
16+
<Skeleton className="h-[500px] w-full rounded-lg" />
17+
</div>
918
</>
1019
);
1120
}

app/(protected)/dashboard/charts/page.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { constructMetadata } from "@/lib/utils";
2+
import { Skeleton } from "@/components/ui/skeleton";
23
import { AreaChartStacked } from "@/components/charts/area-chart-stacked";
34
import { BarChartMixed } from "@/components/charts/bar-chart-mixed";
45
import { InteractiveBarChart } from "@/components/charts/interactive-bar-chart";
@@ -11,7 +12,7 @@ import { RadialTextChart } from "@/components/charts/radial-text-chart";
1112
import { DashboardHeader } from "@/components/dashboard/header";
1213

1314
export const metadata = constructMetadata({
14-
title: "Charts – Next Template",
15+
title: "Charts – SaaS Starter",
1516
description: "List of charts by shadcn-ui",
1617
});
1718

app/(protected)/dashboard/loading.tsx

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,11 @@
11
import { Skeleton } from "@/components/ui/skeleton";
22
import { DashboardHeader } from "@/components/dashboard/header";
3-
import { DashboardShell } from "@/components/dashboard/shell";
43

54
export default function DashboardLoading() {
65
return (
7-
<DashboardShell>
8-
<DashboardHeader
9-
heading="Panel"
10-
text="Current Role :"
11-
/>
12-
<div className="divide-border-200 divide-y rounded-md border">
13-
<Skeleton className="h-[400px] w-full rounded-lg" />
14-
</div>
15-
</DashboardShell>
6+
<>
7+
<DashboardHeader heading="Dashboard" text="Current Role :" />
8+
<Skeleton className="size-full rounded-lg" />
9+
</>
1610
);
1711
}

app/(protected)/dashboard/page.tsx

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,33 +2,30 @@ import { getCurrentUser } from "@/lib/session";
22
import { constructMetadata } from "@/lib/utils";
33
import { Button } from "@/components/ui/button";
44
import { DashboardHeader } from "@/components/dashboard/header";
5-
import { DashboardShell } from "@/components/dashboard/shell";
65
import { EmptyPlaceholder } from "@/components/shared/empty-placeholder";
76

87
export const metadata = constructMetadata({
9-
title: "Panel – SaaS Starter",
8+
title: "Dashboard – SaaS Starter",
109
description: "Create and manage content.",
1110
});
1211

1312
export default async function DashboardPage() {
1413
const user = await getCurrentUser();
1514

1615
return (
17-
<DashboardShell>
16+
<>
1817
<DashboardHeader
19-
heading="Panel"
18+
heading="Dashboard"
2019
text={`Current Role : ${user?.role} — Change your role in settings.`}
2120
/>
22-
<div>
23-
<EmptyPlaceholder>
24-
<EmptyPlaceholder.Icon name="post" />
25-
<EmptyPlaceholder.Title>No content created</EmptyPlaceholder.Title>
26-
<EmptyPlaceholder.Description>
27-
You don&apos;t have any content yet. Start creating content.
28-
</EmptyPlaceholder.Description>
29-
<Button variant="outline">Fake button</Button>
30-
</EmptyPlaceholder>
31-
</div>
32-
</DashboardShell>
21+
<EmptyPlaceholder>
22+
<EmptyPlaceholder.Icon name="post" />
23+
<EmptyPlaceholder.Title>No content created</EmptyPlaceholder.Title>
24+
<EmptyPlaceholder.Description>
25+
You don&apos;t have any content yet. Start creating content.
26+
</EmptyPlaceholder.Description>
27+
<Button>Add Content</Button>
28+
</EmptyPlaceholder>
29+
</>
3330
);
3431
}
Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,18 @@
11
import { DashboardHeader } from "@/components/dashboard/header";
2-
import { DashboardShell } from "@/components/dashboard/shell";
3-
import { CardSkeleton } from "@/components/shared/card-skeleton";
2+
import { SkeletonSection } from "@/components/shared/section-skeleton";
43

54
export default function DashboardSettingsLoading() {
65
return (
7-
<DashboardShell>
6+
<>
87
<DashboardHeader
98
heading="Settings"
109
text="Manage account and website settings."
1110
/>
12-
<div className="grid gap-6">
13-
<CardSkeleton />
14-
<CardSkeleton />
15-
<CardSkeleton />
11+
<div className="divide-y divide-muted pb-10">
12+
<SkeletonSection />
13+
<SkeletonSection />
14+
<SkeletonSection card />
1615
</div>
17-
</DashboardShell>
16+
</>
1817
);
1918
}

app/(protected)/dashboard/settings/page.tsx

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import { getCurrentUser } from "@/lib/session";
44
import { constructMetadata } from "@/lib/utils";
55
import { DeleteAccountSection } from "@/components/dashboard/delete-account";
66
import { DashboardHeader } from "@/components/dashboard/header";
7-
import { DashboardShell } from "@/components/dashboard/shell";
87
import { UserNameForm } from "@/components/forms/user-name-form";
98
import { UserRoleForm } from "@/components/forms/user-role-form";
109

@@ -19,16 +18,16 @@ export default async function SettingsPage() {
1918
if (!user?.id) redirect("/login");
2019

2120
return (
22-
<DashboardShell>
21+
<>
2322
<DashboardHeader
2423
heading="Settings"
2524
text="Manage account and website settings."
2625
/>
27-
<div className="grid gap-6">
26+
<div className="divide-y divide-muted pb-10">
2827
<UserNameForm user={{ id: user.id, name: user.name || "" }} />
2928
<UserRoleForm user={{ id: user.id, role: user.role }} />
3029
<DeleteAccountSection />
3130
</div>
32-
</DashboardShell>
31+
</>
3332
);
3433
}

0 commit comments

Comments
 (0)