Skip to content

Commit

Permalink
refactor: add constructMetadata() and update layouts
Browse files Browse the repository at this point in the history
  • Loading branch information
mickasmt committed May 29, 2024
1 parent 1d31d8f commit a9cd027
Show file tree
Hide file tree
Showing 10 changed files with 161 additions and 127 deletions.
13 changes: 7 additions & 6 deletions app/(dashboard)/dashboard/billing/page.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
import { redirect } from "next/navigation";

import { getCurrentUser } from "@/lib/session";
import { getUserSubscriptionPlan } from "@/lib/subscription";
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
import { BillingInfo } from "@/components/billing-info";
import { DashboardHeader } from "@/components/dashboard/header";
import { DashboardShell } from "@/components/dashboard/shell";
import { Icons } from "@/components/shared/icons";
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
import { getCurrentUser } from "@/lib/session";
import { getUserSubscriptionPlan } from "@/lib/subscription";
import { constructMetadata } from "@/lib/utils";

export const metadata = {
title: "Billing",
export const metadata = constructMetadata({
title: "Billing – SaaS Starter",
description: "Manage billing and your subscription plan.",
};
});

export default async function BillingPage() {
const user = await getCurrentUser();
Expand Down
19 changes: 11 additions & 8 deletions app/(dashboard)/dashboard/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { dashboardConfig } from "@/config/dashboard";
import { DashboardNav } from "@/components/layout/nav";
import { NavBar } from "@/components/layout/navbar";
import { SiteFooter } from "@/components/layout/site-footer";
import MaxWidthWrapper from "@/components/shared/max-width-wrapper";

interface DashboardLayoutProps {
children?: React.ReactNode;
Expand All @@ -12,14 +13,16 @@ export default function DashboardLayout({ children }: DashboardLayoutProps) {
<div className="flex min-h-screen flex-col space-y-6">
<NavBar items={dashboardConfig.mainNav} scroll={false} />

<div className="container grid flex-1 gap-12 md:grid-cols-[200px_1fr]">
<aside className="hidden w-[200px] flex-col md:flex">
<DashboardNav items={dashboardConfig.sidebarNav} />
</aside>
<main className="flex w-full flex-1 flex-col overflow-hidden">
{children}
</main>
</div>
<MaxWidthWrapper className="min-h-svh">
<div className="grid flex-1 gap-12 md:grid-cols-[200px_1fr]">
<aside className="hidden w-[200px] flex-col md:flex">
<DashboardNav items={dashboardConfig.sidebarNav} />
</aside>
<main className="flex w-full flex-1 flex-col overflow-hidden">
{children}
</main>
</div>
</MaxWidthWrapper>
<SiteFooter className="border-t" />
</div>
);
Expand Down
26 changes: 14 additions & 12 deletions app/(dashboard)/dashboard/page.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
import { redirect } from "next/navigation"
import { redirect } from "next/navigation";

import { getCurrentUser } from "@/lib/session"
import { EmptyPlaceholder } from "@/components/shared/empty-placeholder"
import { DashboardHeader } from "@/components/dashboard/header"
import { DashboardShell } from "@/components/dashboard/shell"
import { Button } from "@/components/ui/button"
import { DashboardHeader } from "@/components/dashboard/header";
import { DashboardShell } from "@/components/dashboard/shell";
import { EmptyPlaceholder } from "@/components/shared/empty-placeholder";
import { Button } from "@/components/ui/button";
import { getCurrentUser } from "@/lib/session";
import { constructMetadata } from "@/lib/utils";

export const metadata = {
title: "Dashboard",
}
export const metadata = constructMetadata({
title: "Settings – SaaS Starter",
description: "Overview of your account and activities.",
});

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

if (!user) {
redirect("/login")
redirect("/login");
}

return (
Expand All @@ -33,5 +35,5 @@ export default async function DashboardPage() {
</EmptyPlaceholder>
</div>
</DashboardShell>
)
);
}
25 changes: 13 additions & 12 deletions app/(dashboard)/dashboard/settings/page.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
import { redirect } from "next/navigation"
import { redirect } from "next/navigation";

import { getCurrentUser } from "@/lib/session"
import { DashboardHeader } from "@/components/dashboard/header"
import { DashboardShell } from "@/components/dashboard/shell"
import { UserNameForm } from "@/components/forms/user-name-form"
import { DashboardHeader } from "@/components/dashboard/header";
import { DashboardShell } from "@/components/dashboard/shell";
import { UserNameForm } from "@/components/forms/user-name-form";
import { getCurrentUser } from "@/lib/session";
import { constructMetadata } from "@/lib/utils";

export const metadata = {
title: "Settings",
description: "Manage account and website settings.",
}
export const metadata = constructMetadata({
title: "Settings – SaaS Starter",
description: "Configure your account and website settings.",
});

export default async function SettingsPage() {
const user = await getCurrentUser()
const user = await getCurrentUser();

if (!user) {
redirect("/login")
redirect("/login");
}

return (
Expand All @@ -27,5 +28,5 @@ export default async function SettingsPage() {
<UserNameForm user={{ id: user.id, name: user.name || "" }} />
</div>
</DashboardShell>
)
);
}
2 changes: 1 addition & 1 deletion app/(docs)/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ const rightHeader = () => (
export default function DocsLayout({ children }: DocsLayoutProps) {
return (
<div className="flex min-h-screen flex-col">
<NavBar items={docsConfig.mainNav} rightElements={rightHeader()}>
<NavBar items={docsConfig.mainNav} rightElements={rightHeader()} large={true}>
<DocsSidebarNav items={docsConfig.sidebarNav} />
</NavBar>
<div className="container flex-1">{children}</div>
Expand Down
20 changes: 11 additions & 9 deletions app/(marketing)/blog/page.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,24 @@
import { allPosts } from "contentlayer/generated"
import { compareDesc } from "date-fns"
import { allPosts } from "contentlayer/generated";
import { compareDesc } from "date-fns";

import { BlogPosts } from "@/components/blog-posts"
import { BlogPosts } from "@/components/blog-posts";
import { constructMetadata } from "@/lib/utils";

export const metadata = {
title: "Blog",
}
export const metadata = constructMetadata({
title: "Blog – SaaS Starter",
description: "Manage billing and your subscription plan.",
});

export default async function BlogPage() {
const posts = allPosts
.filter((post) => post.published)
.sort((a, b) => {
return compareDesc(new Date(a.date), new Date(b.date))
})
return compareDesc(new Date(a.date), new Date(b.date));
});

return (
<main>
<BlogPosts posts={posts} />
</main>
)
);
}
28 changes: 14 additions & 14 deletions app/(marketing)/pricing/page.tsx
Original file line number Diff line number Diff line change
@@ -1,27 +1,27 @@
import { PricingCards } from "@/components/pricing-cards";
import { PricingFaq } from "@/components/pricing-faq";
import { getCurrentUser } from "@/lib/session";
import { getUserSubscriptionPlan } from "@/lib/subscription";
import { constructMetadata } from "@/lib/utils";

import { PricingCards } from '@/components/pricing-cards';
import { PricingFaq } from '@/components/pricing-faq';
import { Skeleton } from '@/components/ui/skeleton';
import { getCurrentUser } from '@/lib/session';
import { getUserSubscriptionPlan } from '@/lib/subscription';

export const metadata = {
title: "Pricing",
}
export const metadata = constructMetadata({
title: "Pricing – SaaS Starter",
description: "Explore our subscription plans.",
});

export default async function PricingPage() {
const user = await getCurrentUser()
const user = await getCurrentUser();
let subscriptionPlan;

if (user) {
subscriptionPlan = await getUserSubscriptionPlan(user.id)
subscriptionPlan = await getUserSubscriptionPlan(user.id);
}

return (
<div className="flex w-full flex-col gap-16 py-8 md:py-8">
<PricingCards userId={user?.id} subscriptionPlan={subscriptionPlan} />
<hr className='container' />
<hr className="container" />
<PricingFaq />
</div>
)
}
);
}
50 changes: 2 additions & 48 deletions app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ import { fontHeading, fontSans, fontUrban } from "@/assets/fonts";
import { SessionProvider } from "next-auth/react";
import { ThemeProvider } from "next-themes";

import { siteConfig } from "@/config/site";
import { cn } from "@/lib/utils";
import { cn, constructMetadata } from "@/lib/utils";
import { Toaster } from "@/components/ui/toaster";
import { Analytics } from "@/components/analytics";
import { ModalProvider } from "@/components/modal-provider";
Expand All @@ -15,52 +14,7 @@ interface RootLayoutProps {
children: React.ReactNode;
}

export const metadata = {
title: {
default: siteConfig.name,
template: `%s | ${siteConfig.name}`,
},
description: siteConfig.description,
keywords: [
"Next.js",
"React",
"Prisma",
"Neon",
"Auth.js",
"shadcn ui",
"Resend",
"React Email",
"Stripe",
],
authors: [
{
name: "mickasmt",
},
],
creator: "mickasmt",
metadataBase: new URL(siteConfig.url),
openGraph: {
type: "website",
locale: "en_US",
url: siteConfig.url,
title: siteConfig.name,
description: siteConfig.description,
siteName: siteConfig.name,
},
twitter: {
card: "summary_large_image",
title: siteConfig.name,
description: siteConfig.description,
images: [siteConfig.ogImage],
creator: "@miickasmt",
},
icons: {
icon: "/favicon.ico",
shortcut: "/favicon-16x16.png",
apple: "/apple-touch-icon.png",
},
manifest: `${siteConfig.url}/site.webmanifest`,
};
export const metadata = constructMetadata();

export default function RootLayout({ children }: RootLayoutProps) {
return (
Expand Down
27 changes: 18 additions & 9 deletions components/blog-posts.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import { formatDate } from '@/lib/utils';
import Image from 'next/image';
import Link from 'next/link';
import Image from "next/image";
import Link from "next/link";

import { formatDate } from "@/lib/utils";

import MaxWidthWrapper from "./shared/max-width-wrapper";

export function BlogPosts({ posts }) {
return (
<div className="container space-y-10 py-6 md:py-10">
<MaxWidthWrapper className="space-y-10 py-6 md:py-10">
<section>
<h2 className="mb-4 font-heading text-3xl">Last Post</h2>
<article className="relative grid grid-cols-1 gap-6 md:grid-cols-2">
Expand Down Expand Up @@ -39,7 +42,10 @@ export function BlogPosts({ posts }) {
<h2 className="mb-4 font-heading text-3xl">Blog Posts</h2>
<div className="grid gap-6 sm:grid-cols-2 lg:grid-cols-3">
{posts.slice(1).map((post) => (
<article key={post._id} className="group relative flex flex-col space-y-2">
<article
key={post._id}
className="group relative flex flex-col space-y-2"
>
{post.image && (
<Image
alt={post.title}
Expand All @@ -49,9 +55,13 @@ export function BlogPosts({ posts }) {
className="rounded-md border bg-muted transition-colors"
/>
)}
<h2 className="line-clamp-1 font-heading text-2xl">{post.title}</h2>
<h2 className="line-clamp-1 font-heading text-2xl">
{post.title}
</h2>
{post.description && (
<p className="line-clamp-1 text-muted-foreground">{post.description}</p>
<p className="line-clamp-1 text-muted-foreground">
{post.description}
</p>
)}
{post.date && (
<p className="text-sm text-muted-foreground">
Expand All @@ -65,7 +75,6 @@ export function BlogPosts({ posts }) {
))}
</div>
</section>
</div>
</MaxWidthWrapper>
);
}

Loading

0 comments on commit a9cd027

Please sign in to comment.