diff --git a/apps/blog/.gitignore b/apps/blog/.gitignore new file mode 100644 index 00000000..5ef6a520 --- /dev/null +++ b/apps/blog/.gitignore @@ -0,0 +1,41 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.* +.yarn/* +!.yarn/patches +!.yarn/plugins +!.yarn/releases +!.yarn/versions + +# 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* + +# env files (can opt-in for committing if needed) +.env* + +# vercel +.vercel + +# typescript +*.tsbuildinfo +next-env.d.ts diff --git a/apps/blog/README.md b/apps/blog/README.md new file mode 100644 index 00000000..e215bc4c --- /dev/null +++ b/apps/blog/README.md @@ -0,0 +1,36 @@ +This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://nextjs.org/docs/app/api-reference/cli/create-next-app). + +## Getting Started + +First, run the development server: + +```bash +npm run dev +# or +yarn dev +# or +pnpm dev +# or +bun dev +``` + +Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. + +You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file. + +This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel. + +## Learn More + +To learn more about Next.js, take a look at the following resources: + +- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API. +- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. + +You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js) - your feedback and contributions are welcome! + +## Deploy on Vercel + +The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js. + +Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details. diff --git a/apps/blog/components.json b/apps/blog/components.json new file mode 100644 index 00000000..d710b496 --- /dev/null +++ b/apps/blog/components.json @@ -0,0 +1,21 @@ +{ + "$schema": "https://ui.shadcn.com/schema.json", + "style": "default", + "rsc": true, + "tsx": true, + "tailwind": { + "config": "tailwind.config.ts", + "css": "src/app/globals.css", + "baseColor": "neutral", + "cssVariables": true, + "prefix": "" + }, + "aliases": { + "components": "@/components", + "utils": "@/lib/utils", + "ui": "@/components/ui", + "lib": "@/lib", + "hooks": "@/hooks" + }, + "iconLibrary": "lucide" +} \ No newline at end of file diff --git a/apps/blog/eslint.config.mjs b/apps/blog/eslint.config.mjs new file mode 100644 index 00000000..c85fb67c --- /dev/null +++ b/apps/blog/eslint.config.mjs @@ -0,0 +1,16 @@ +import { dirname } from "path"; +import { fileURLToPath } from "url"; +import { FlatCompat } from "@eslint/eslintrc"; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = dirname(__filename); + +const compat = new FlatCompat({ + baseDirectory: __dirname, +}); + +const eslintConfig = [ + ...compat.extends("next/core-web-vitals", "next/typescript"), +]; + +export default eslintConfig; diff --git a/apps/blog/next.config.mjs b/apps/blog/next.config.mjs new file mode 100644 index 00000000..b3fb6fae --- /dev/null +++ b/apps/blog/next.config.mjs @@ -0,0 +1,9 @@ +import { rewrites as getAnalyticsRewrites } from '@ds-project/services/analytics/rewrites.mjs'; + +/** @type {import('next').NextConfig} */ +const nextConfig = { + transpilePackages: ['next-mdx-remote'], + rewrites: getAnalyticsRewrites, +}; + +export default nextConfig; diff --git a/apps/blog/package.json b/apps/blog/package.json new file mode 100644 index 00000000..1b9f3316 --- /dev/null +++ b/apps/blog/package.json @@ -0,0 +1,41 @@ +{ + "name": "blog", + "version": "0.1.0", + "private": true, + "scripts": { + "dev": "next dev", + "build": "next build", + "start": "next start", + "lint": "eslint" + }, + "dependencies": { + "@ds-project/services": "workspace:*", + "@radix-ui/react-slot": "^1.1.0", + "@t3-oss/env-core": "catalog:", + "@t3-oss/env-nextjs": "catalog:", + "@tailwindcss/typography": "^0.5.15", + "class-variance-authority": "^0.7.0", + "clsx": "^2.1.1", + "lucide-react": "^0.408.0", + "next": "catalog:", + "next-mdx-remote": "^5.0.0", + "next-themes": "^0.4.4", + "react": "catalog:", + "react-dom": "catalog:", + "sonner": "^1.7.2", + "tailwind-merge": "^2.4.0", + "tailwindcss-animate": "^1.0.7", + "zod": "catalog:" + }, + "devDependencies": { + "@eslint/eslintrc": "^3", + "@types/node": "catalog:", + "@types/react": "catalog:", + "@types/react-dom": "catalog:", + "eslint": "catalog:", + "eslint-config-next": "15.1.5", + "postcss": "catalog:", + "tailwindcss": "catalog:", + "typescript": "catalog:" + } +} diff --git a/apps/blog/postcss.config.mjs b/apps/blog/postcss.config.mjs new file mode 100644 index 00000000..1a69fd2a --- /dev/null +++ b/apps/blog/postcss.config.mjs @@ -0,0 +1,8 @@ +/** @type {import('postcss-load-config').Config} */ +const config = { + plugins: { + tailwindcss: {}, + }, +}; + +export default config; diff --git a/apps/blog/public/file.svg b/apps/blog/public/file.svg new file mode 100644 index 00000000..004145cd --- /dev/null +++ b/apps/blog/public/file.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/blog/public/globe.svg b/apps/blog/public/globe.svg new file mode 100644 index 00000000..567f17b0 --- /dev/null +++ b/apps/blog/public/globe.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/blog/public/next.svg b/apps/blog/public/next.svg new file mode 100644 index 00000000..5174b28c --- /dev/null +++ b/apps/blog/public/next.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/blog/public/vercel.svg b/apps/blog/public/vercel.svg new file mode 100644 index 00000000..77053960 --- /dev/null +++ b/apps/blog/public/vercel.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/blog/public/window.svg b/apps/blog/public/window.svg new file mode 100644 index 00000000..b2b2a44f --- /dev/null +++ b/apps/blog/public/window.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/blog/src/app/blog/[slug]/page.tsx b/apps/blog/src/app/blog/[slug]/page.tsx new file mode 100644 index 00000000..c30db3b0 --- /dev/null +++ b/apps/blog/src/app/blog/[slug]/page.tsx @@ -0,0 +1,34 @@ +import { getPost, getAllPosts } from '@/utils/mdx'; + +export async function generateStaticParams() { + const posts = await getAllPosts(); + return posts.map((post) => ({ + slug: post.slug, + })); +} + +export default async function BlogPost({ + params, +}: { + params: { slug: string }; +}) { + const post = await getPost(params.slug); + + return ( + <> +
+
+

{post.title}

+
+ {new Date(post.date).toLocaleDateString('en-US', { + year: 'numeric', + month: 'long', + day: 'numeric', + })} +
+ {post.content} +
+
+ + ); +} diff --git a/apps/blog/src/app/favicon.ico b/apps/blog/src/app/favicon.ico new file mode 100644 index 00000000..718d6fea Binary files /dev/null and b/apps/blog/src/app/favicon.ico differ diff --git a/apps/blog/src/app/globals.css b/apps/blog/src/app/globals.css new file mode 100644 index 00000000..a23ac26b --- /dev/null +++ b/apps/blog/src/app/globals.css @@ -0,0 +1,72 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; + +body { + font-family: Arial, Helvetica, sans-serif; +} + +@layer base { + :root { + --background: 0 0% 100%; + --foreground: 0 0% 3.9%; + --card: 0 0% 100%; + --card-foreground: 0 0% 3.9%; + --popover: 0 0% 100%; + --popover-foreground: 0 0% 3.9%; + --primary: 0 0% 9%; + --primary-foreground: 0 0% 98%; + --secondary: 0 0% 96.1%; + --secondary-foreground: 0 0% 9%; + --muted: 0 0% 96.1%; + --muted-foreground: 0 0% 45.1%; + --accent: 0 0% 96.1%; + --accent-foreground: 0 0% 9%; + --destructive: 0 84.2% 60.2%; + --destructive-foreground: 0 0% 98%; + --border: 0 0% 89.8%; + --input: 0 0% 89.8%; + --ring: 0 0% 3.9%; + --chart-1: 12 76% 61%; + --chart-2: 173 58% 39%; + --chart-3: 197 37% 24%; + --chart-4: 43 74% 66%; + --chart-5: 27 87% 67%; + --radius: 0.5rem; + } + .dark { + --background: 0 0% 3.9%; + --foreground: 0 0% 98%; + --card: 0 0% 3.9%; + --card-foreground: 0 0% 98%; + --popover: 0 0% 3.9%; + --popover-foreground: 0 0% 98%; + --primary: 0 0% 98%; + --primary-foreground: 0 0% 9%; + --secondary: 0 0% 14.9%; + --secondary-foreground: 0 0% 98%; + --muted: 0 0% 14.9%; + --muted-foreground: 0 0% 63.9%; + --accent: 0 0% 14.9%; + --accent-foreground: 0 0% 98%; + --destructive: 0 62.8% 30.6%; + --destructive-foreground: 0 0% 98%; + --border: 0 0% 14.9%; + --input: 0 0% 14.9%; + --ring: 0 0% 83.1%; + --chart-1: 220 70% 50%; + --chart-2: 160 60% 45%; + --chart-3: 30 80% 55%; + --chart-4: 280 65% 60%; + --chart-5: 340 75% 55%; + } +} + +@layer base { + * { + @apply border-border; + } + body { + @apply bg-background text-foreground; + } +} diff --git a/apps/blog/src/app/layout.tsx b/apps/blog/src/app/layout.tsx new file mode 100644 index 00000000..236fe530 --- /dev/null +++ b/apps/blog/src/app/layout.tsx @@ -0,0 +1,44 @@ +import type { Metadata } from 'next'; +import { Fira_Sans, Fira_Mono } from 'next/font/google'; +import './globals.css'; +import { Footer } from '@/components/footer'; +import { Toaster } from '@/components/ui/sonner'; +import { AnalyticsProvider, PageTracker } from '@ds-project/services/analytics'; + +const fontSans = Fira_Sans({ + variable: '--font-sans', + subsets: ['latin'], + weight: ['400', '700'], +}); + +const fontMono = Fira_Mono({ + variable: '--font-mono', + subsets: ['latin'], + weight: ['400', '700'], +}); + +export const metadata: Metadata = { + title: 'DS Pro Blog', + description: 'Insights about Design Systems and Frontend Development', +}; + +export default function RootLayout({ + children, +}: Readonly<{ + children: React.ReactNode; +}>) { + return ( + + + +
{children}
+