feat: implement initial fullstack portfolio application including dashboard, CMS, and analytics features.
This commit is contained in:
119
src/app/layout.tsx
Normal file
119
src/app/layout.tsx
Normal file
@@ -0,0 +1,119 @@
|
||||
import type { Metadata } from "next";
|
||||
import { Syne, DM_Sans, DM_Mono } from "next/font/google";
|
||||
import "./globals.css";
|
||||
import { Navbar } from "@/components/sections/portfolio/Navbar";
|
||||
import { Footer } from "@/components/sections/portfolio/Footer";
|
||||
import { ThemeProvider } from "@/components/ThemeProvider";
|
||||
import { Analytics } from "@vercel/analytics/react";
|
||||
|
||||
const syne = Syne({
|
||||
subsets: ["latin"],
|
||||
weight: ["400", "500", "600", "700", "800"],
|
||||
variable: "--font-display",
|
||||
display: "swap",
|
||||
});
|
||||
|
||||
const dmSans = DM_Sans({
|
||||
subsets: ["latin"],
|
||||
weight: ["300", "400", "500", "600"],
|
||||
style: ["normal", "italic"],
|
||||
variable: "--font-sans",
|
||||
display: "swap",
|
||||
});
|
||||
|
||||
const dmMono = DM_Mono({
|
||||
subsets: ["latin"],
|
||||
weight: ["300", "400", "500"],
|
||||
variable: "--font-mono",
|
||||
display: "swap",
|
||||
});
|
||||
|
||||
export const metadata: Metadata = {
|
||||
metadataBase: new URL(
|
||||
process.env.NEXT_PUBLIC_APP_URL || "http://localhost:3000",
|
||||
),
|
||||
title: {
|
||||
default: "Fikri — Fullstack Developer",
|
||||
template: "%s | Fikri",
|
||||
},
|
||||
description:
|
||||
"Fullstack Developer with 3+ years of experience building scalable and production-ready web applications using Next.js, NestJS, and PostgreSQL. Focused on clean architecture, performance, and maintainable systems.",
|
||||
keywords: [
|
||||
"Fikri",
|
||||
"Fullstack Developer",
|
||||
"Next.js Developer",
|
||||
"NestJS Developer",
|
||||
"TypeScript",
|
||||
"React",
|
||||
"Node.js",
|
||||
"PostgreSQL",
|
||||
"Prisma",
|
||||
"Clean Architecture",
|
||||
"Web Application Development",
|
||||
],
|
||||
authors: [{ name: "Fikri" }],
|
||||
creator: "Fikri",
|
||||
openGraph: {
|
||||
type: "website",
|
||||
locale: "en_US",
|
||||
url: "https://yourportfolio.dev", // ganti dengan domain kamu
|
||||
siteName: "Fikri — Fullstack Developer",
|
||||
title: "Fikri — Fullstack Developer",
|
||||
description:
|
||||
"Fullstack Developer specializing in Next.js & NestJS with 3+ years of experience building scalable and production-ready web applications.",
|
||||
images: [
|
||||
{
|
||||
url: "/og-image.png",
|
||||
width: 1200,
|
||||
height: 630,
|
||||
alt: "Fikri — Fullstack Developer",
|
||||
},
|
||||
],
|
||||
},
|
||||
twitter: {
|
||||
card: "summary_large_image",
|
||||
title: "Fikri — Fullstack Developer",
|
||||
description:
|
||||
"Next.js & NestJS Specialist | Clean Architecture | Scalable Systems",
|
||||
images: ["/og-image.png"],
|
||||
},
|
||||
robots: {
|
||||
index: true,
|
||||
follow: true,
|
||||
googleBot: {
|
||||
index: true,
|
||||
follow: true,
|
||||
"max-video-preview": -1,
|
||||
"max-image-preview": "large",
|
||||
"max-snippet": -1,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export default function RootLayout({
|
||||
children,
|
||||
}: Readonly<{
|
||||
children: React.ReactNode;
|
||||
}>) {
|
||||
return (
|
||||
<html
|
||||
lang="en"
|
||||
className={`${syne.variable} ${dmSans.variable} ${dmMono.variable} dark`}
|
||||
suppressHydrationWarning
|
||||
>
|
||||
<body className="bg-background text-foreground antialiased">
|
||||
<ThemeProvider
|
||||
attribute="class"
|
||||
defaultTheme="dark"
|
||||
enableSystem
|
||||
disableTransitionOnChange={false}
|
||||
>
|
||||
<Navbar />
|
||||
<main>{children}</main>
|
||||
<Footer />
|
||||
<Analytics />
|
||||
</ThemeProvider>
|
||||
</body>
|
||||
</html>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user