Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions fullstack/.gitignore
Original file line number Diff line number Diff line change
@@ -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
5 changes: 5 additions & 0 deletions fullstack/AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<!-- BEGIN:nextjs-agent-rules -->
# This is NOT the Next.js you know

This version has breaking changes — APIs, conventions, and file structure may all differ from your training data. Read the relevant guide in `node_modules/next/dist/docs/` before writing any code. Heed deprecation notices.
<!-- END:nextjs-agent-rules -->
1 change: 1 addition & 0 deletions fullstack/CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@AGENTS.md
36 changes: 36 additions & 0 deletions fullstack/README.md
Original file line number Diff line number Diff line change
@@ -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.
16 changes: 16 additions & 0 deletions fullstack/app/api/posts/[id]/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { posts } from "@/data/posts";
import { NextResponse } from "next/server";

export async function GET(
_req: Request,
{ params }: { params: Promise<{ id: string }> }
) {
const { id } = await params;
const post = posts.find((p) => p.id === Number(id));

if (!post) {
return NextResponse.json({ error: "Post not found" }, { status: 404 });
}

return NextResponse.json(post);
}
6 changes: 6 additions & 0 deletions fullstack/app/api/posts/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { posts } from "@/data/posts";
import { NextResponse } from "next/server";

export async function GET() {
return NextResponse.json(posts);
}
Binary file added fullstack/app/favicon.ico
Binary file not shown.
26 changes: 26 additions & 0 deletions fullstack/app/globals.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
@import "tailwindcss";

:root {
--background: #ffffff;
--foreground: #171717;
}

@theme inline {
--color-background: var(--background);
--color-foreground: var(--foreground);
--font-sans: var(--font-geist-sans);
--font-mono: var(--font-geist-mono);
}

@media (prefers-color-scheme: dark) {
:root {
--background: #0a0a0a;
--foreground: #ededed;
}
}

body {
background: var(--background);
color: var(--foreground);
font-family: Arial, Helvetica, sans-serif;
}
23 changes: 23 additions & 0 deletions fullstack/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import type { Metadata } from "next";
import "./globals.css";

export const metadata: Metadata = {
title: "The Blog",
description: "Articles on Next.js, React, and modern web development",
};

export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en">
<body
style={{ margin: 0, padding: 0, WebkitFontSmoothing: "antialiased" }}
>
{children}
</body>
</html>
);
}
143 changes: 143 additions & 0 deletions fullstack/app/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
import Link from "next/link";
import { posts } from "@/data/posts";

function readingTime(content: string) {
const words = content.split(" ").length;
return Math.max(1, Math.ceil(words / 200));
}

export default function HomePage() {
return (
<main className="min-h-screen" style={{ background: "#0A0F1E" }}>
{/* Header */}
<header className="border-b" style={{ borderColor: "#1E2A3A" }}>
<div className="max-w-4xl mx-auto px-6 py-6 flex items-center justify-between">
<div>
<span
className="text-xs font-mono tracking-widest uppercase"
style={{ color: "#4F8EF7" }}
>
The Blog
</span>
</div>
<span className="text-xs font-mono" style={{ color: "#8B99B5" }}>
{posts.length} posts
</span>
</div>
</header>

<section className="max-w-4xl mx-auto px-6 py-20">
<p
className="text-xs font-mono tracking-widest uppercase mb-4"
style={{ color: "#4F8EF7" }}
>
Latest Writing
</p>
<h1
className="text-5xl font-bold leading-tight mb-4"
style={{ color: "#F0F4FF", fontFamily: "Georgia, serif" }}
>
Ideas worth
<br />
<span style={{ color: "#4F8EF7" }}>reading.</span>
</h1>
<p className="text-base" style={{ color: "#8B99B5" }}>
A collection of articles on Next.js, React, and modern web
development.
</p>
</section>

<div className="max-w-4xl mx-auto px-6">
<div className="h-px w-full" style={{ background: "#1E2A3A" }} />
</div>

<section className="max-w-4xl mx-auto px-6 py-12">
<ul className="flex flex-col gap-4">
{posts.map((post, i) => (
<li key={post.id}>
<Link href={`/posts/${post.id}`} className="block group">
<div
className="rounded-xl p-6 border transition-all duration-300 relative overflow-hidden"
style={{
background: "#111827",
borderColor: "#1E2A3A",
}}
>
<div
className="absolute left-0 top-0 bottom-0 w-0 group-hover:w-1 transition-all duration-300 rounded-l-xl"
style={{ background: "#4F8EF7" }}
/>

<div className="flex items-start justify-between gap-4">
<div className="flex-1 min-w-0">
<div className="flex items-center gap-3 mb-3">
<span
className="text-xs font-mono"
style={{ color: "#8B99B5" }}
>
{post.date}
</span>
<span style={{ color: "#1E2A3A" }}>·</span>
<span
className="text-xs font-mono"
style={{ color: "#8B99B5" }}
>
{post.author}
</span>
<span style={{ color: "#1E2A3A" }}>·</span>
<span
className="text-xs font-mono"
style={{ color: "#4F8EF7" }}
>
{readingTime(post.content)} min read
</span>
</div>

<h2
className="text-xl font-semibold mb-2 group-hover:text-blue-400 transition-colors duration-200"
style={{ color: "#F0F4FF" }}
>
{post.title}
</h2>
<p
className="text-sm leading-relaxed"
style={{ color: "#8B99B5" }}
>
{post.excerpt}
</p>
</div>

<div
className="text-2xl font-mono font-bold shrink-0 opacity-20 group-hover:opacity-40 transition-opacity"
style={{ color: "#4F8EF7" }}
>
{String(i + 1).padStart(2, "0")}
</div>
</div>

<div className="mt-4 flex items-center gap-2">
<span
className="text-xs font-medium group-hover:gap-2 transition-all"
style={{ color: "#4F8EF7" }}
>
Read blog →
</span>
</div>
</div>
</Link>
</li>
))}
</ul>
</section>

<footer className="border-t mt-12" style={{ borderColor: "#1E2A3A" }}>
<div
className="max-w-4xl mx-auto px-6 py-8 text-center text-xs font-mono"
style={{ color: "#8B99B5" }}
>
Built with Next.js · {new Date().getFullYear()}
</div>
</footer>
</main>
);
}
86 changes: 86 additions & 0 deletions fullstack/app/posts/[id]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import Link from "next/link";
import { posts } from "@/data/posts";
import { notFound } from "next/navigation";

interface Props {
params: Promise<{ id: string }>;
}

export function generateStaticParams() {
return posts.map((post) => ({ id: String(post.id) }));
}

function readingTime(content: string) {
return Math.max(1, Math.ceil(content.split(" ").length / 200));
}

export default async function PostPage({ params }: Props) {
const { id } = await params;
const post = posts.find((p) => p.id === Number(id));

if (!post) notFound();

return (
<main className="min-h-screen" style={{ background: "#0A0F1E" }}>
<header className="border-b" style={{ borderColor: "#1E2A3A" }}>
<div className="max-w-3xl mx-auto px-6 py-6">
<Link
href="/"
className="inline-flex items-center gap-2 text-xs font-mono tracking-widest uppercase transition-colors duration-200 hover:opacity-70"
style={{ color: "#4F8EF7" }}
>
← Back to posts
</Link>
</div>
</header>

<article className="max-w-3xl mx-auto px-6 py-16">
<div className="flex items-center gap-3 mb-8">
<span className="text-xs font-mono" style={{ color: "#8B99B5" }}>
{post.date}
</span>
<span style={{ color: "#1E2A3A" }}>·</span>
<span className="text-xs font-mono" style={{ color: "#8B99B5" }}>
{post.author}
</span>
<span style={{ color: "#1E2A3A" }}>·</span>
<span className="text-xs font-mono" style={{ color: "#4F8EF7" }}>
{readingTime(post.content)} min read
</span>
</div>

<h1
className="text-4xl font-bold leading-tight mb-10"
style={{
color: "#F0F4FF",
fontFamily: "Georgia, serif",
}}
>
{post.title}
</h1>

<div
className="h-px mb-10"
style={{ background: "linear-gradient(to right, #4F8EF7, transparent)" }}
/>

<p
className="text-base leading-8"
style={{ color: "#C4CFDF" }}
>
{post.content}
</p>

<div className="mt-16 pt-8 border-t" style={{ borderColor: "#1E2A3A" }}>
<Link
href="/"
className="inline-flex items-center gap-2 text-sm font-medium transition-opacity hover:opacity-70"
style={{ color: "#4F8EF7" }}
>
← Back to all posts
</Link>
</div>
</article>
</main>
);
}
Loading