first commit
Some checks failed
Test examples / Test Examples (20) (push) Has been cancelled
Test examples / Test Examples (22) (push) Has been cancelled
Lock Threads / action (push) Has been cancelled
Trigger Release / start (push) Has been cancelled
Stale issue handler / stale (push) Has been cancelled
Update Font Data / create-pull-request (push) Has been cancelled
build-and-deploy / deploy-target (push) Has been cancelled
build-and-deploy / build (push) Has been cancelled
build-and-deploy / stable - aarch64-unknown-linux-musl - node@16 (push) Has been cancelled
build-and-deploy / stable - x86_64-unknown-linux-musl - node@16 (push) Has been cancelled
build-and-deploy / stable - aarch64-unknown-linux-gnu - node@16 (push) Has been cancelled
build-and-deploy / stable - x86_64-unknown-linux-gnu - node@16 (push) Has been cancelled
build-and-deploy / stable - aarch64-pc-windows-msvc - node@16 (push) Has been cancelled
build-and-deploy / stable - x86_64-pc-windows-msvc - node@16 (push) Has been cancelled
build-and-deploy / stable - aarch64-apple-darwin - node@16 (push) Has been cancelled
build-and-deploy / stable - x86_64-apple-darwin - node@16 (push) Has been cancelled
build-and-deploy / build-wasm (nodejs) (push) Has been cancelled
build-and-deploy / build-wasm (web) (push) Has been cancelled
build-and-deploy / Deploy preview tarball (push) Has been cancelled
build-and-deploy / Potentially publish release (push) Has been cancelled
build-and-deploy / publish-turbopack-npm-packages (push) Has been cancelled
build-and-deploy / Deploy examples (push) Has been cancelled
build-and-deploy / thank you, build (push) Has been cancelled
build-and-deploy / Upload Turbopack Bytesize metrics to Datadog (push) Has been cancelled
Rspack Next.js development integration tests / Rspack integration tests (push) Has been cancelled
Rspack Next.js production integration tests / Rspack integration tests (push) Has been cancelled
Turbopack Next.js development integration tests / Next.js integration tests (push) Has been cancelled
Turbopack Next.js production integration tests / Next.js integration tests (push) Has been cancelled
Update Rspack test manifest / Update and upload Rspack development test manifest (push) Has been cancelled
Update Rspack test manifest / Update and upload Rspack production test manifest (push) Has been cancelled
Upload bundler test manifests to areweturboyet.com / Upload test results (push) Has been cancelled
Update React / create-pull-request (push) Has been cancelled
test-e2e-project-reset-cron / reset-test-project (push) Has been cancelled
Notify about the top 15 issues/PRs/feature requests (most reacted) in the last 90 days / run (push) Has been cancelled

This commit is contained in:
Arian Tron
2026-03-10 19:37:31 +03:30
commit 61f56f997c
27684 changed files with 2784175 additions and 0 deletions

View File

@@ -0,0 +1,77 @@
export const dynamic = "force-dynamic"; // This disables SSG and ISR
import prisma from "@/lib/prisma";
import { notFound, redirect } from "next/navigation";
export default async function Post({
params,
}: {
params: Promise<{ id: string }>;
}) {
const { id } = await params;
const postId = parseInt(id);
const post = await prisma.post.findUnique({
where: { id: postId },
include: {
author: true,
},
});
if (!post) {
notFound();
}
// Server action to delete the post
async function deletePost() {
"use server";
await prisma.post.delete({
where: {
id: postId,
},
});
redirect("/posts");
}
return (
<div className="min-h-screen bg-gray-50 flex flex-col items-center justify-center p-8">
<article className="max-w-3xl w-full bg-white shadow-lg rounded-lg p-8">
{/* Post Title */}
<h1 className="text-5xl font-extrabold text-blue-600 mb-4">
{post.title}
</h1>
{/* Author Information */}
<p className="text-lg text-gray-600 mb-4">
by{" "}
<span className="font-medium text-gray-800">
{post.author?.name || "Anonymous"}
</span>
</p>
{/* Content Section */}
<div className="text-lg text-gray-800 leading-relaxed space-y-6 border-t pt-6">
{post.content ? (
<p>{post.content}</p>
) : (
<p className="italic text-gray-500">
No content available for this post.
</p>
)}
</div>
</article>
{/* Delete Button */}
<form action={deletePost} className="mt-6">
<button
type="submit"
className="px-6 py-3 bg-red-500 text-white font-semibold rounded-lg hover:bg-red-600 transition-colors"
>
Delete Post
</button>
</form>
</div>
);
}

View File

@@ -0,0 +1,98 @@
export const dynamic = "force-dynamic"; // This disables SSG and ISR
import Form from "next/form";
import prisma from "@/lib/prisma";
import { revalidatePath } from "next/cache";
import { redirect } from "next/navigation";
export default function NewPost() {
async function createPost(formData: FormData) {
"use server";
const authorEmail = (formData.get("authorEmail") as string) || undefined;
const title = formData.get("title") as string;
const content = formData.get("content") as string;
const postData = authorEmail
? {
title,
content,
author: {
connect: {
email: authorEmail,
},
},
}
: {
title,
content,
};
await prisma.post.create({
data: postData,
});
revalidatePath("/posts");
redirect("/posts");
}
return (
<div className="max-w-2xl mx-auto p-4">
<h1 className="text-2xl font-bold mb-6">Create New Post</h1>
<Form action={createPost} className="space-y-6">
<div>
<label
htmlFor="title"
className="flex text-lg font-medium mb-2 items-center"
>
Title
<span className="ml-2 px-2 py-1 text-xs font-semibold text-white bg-gray-500 rounded-lg">
Required
</span>
</label>
<input
type="text"
id="title"
name="title"
required
placeholder="Enter your post title ..."
className="w-full px-4 py-2 border rounded-lg"
/>
</div>
<div>
<label htmlFor="content" className="block text-lg font-medium mb-2">
Content
</label>
<textarea
id="content"
name="content"
placeholder="Write your post content here ..."
rows={6}
className="w-full px-4 py-2 border rounded-lg"
/>
</div>
<div>
<label
htmlFor="authorEmail"
className="block text-lg font-medium mb-2"
>
Author
</label>
<input
type="text"
id="authorEmail"
name="authorEmail"
placeholder="Enter the email of the author here ..."
className="w-full px-4 py-2 border rounded-lg"
/>
</div>
<button
type="submit"
className="w-full bg-blue-500 text-white py-3 rounded-lg hover:bg-blue-600"
>
Create Post
</button>
</Form>
</div>
);
}

View File

@@ -0,0 +1,126 @@
"use client";
import { useSearchParams } from "next/navigation";
import { useEffect, useState, Suspense } from "react";
import Link from "next/link";
interface Post {
id: number;
title: string;
content?: string;
createdAt: string;
author?: {
name: string;
};
}
// Disable static generation
export const dynamic = "force-dynamic";
function PostsList() {
const searchParams = useSearchParams();
const page = parseInt(searchParams.get("page") || "1");
const [posts, setPosts] = useState<Post[]>([]);
const [totalPages, setTotalPages] = useState(1);
const [isLoading, setIsLoading] = useState(true);
useEffect(() => {
async function fetchPosts() {
setIsLoading(true);
try {
const res = await fetch(`/api/posts?page=${page}`);
if (!res.ok) {
throw new Error("Failed to fetch posts");
}
const data = await res.json();
setPosts(data.posts);
setTotalPages(data.totalPages);
} catch (error) {
console.error("Error fetching posts:", error);
} finally {
setIsLoading(false);
}
}
fetchPosts();
}, [page]);
return (
<>
{isLoading ? (
<div className="flex items-center justify-center space-x-2 min-h-[200px]">
<div className="w-6 h-6 border-4 border-blue-500 border-t-transparent rounded-full animate-spin"></div>
<p className="text-gray-600">Loading...</p>
</div>
) : (
<>
{posts.length === 0 ? (
<p className="text-gray-600">No posts available.</p>
) : (
<ul className="space-y-6 w-full max-w-4xl mx-auto">
{posts.map((post) => (
<li
key={post.id}
className="border p-6 rounded-lg shadow-md bg-white"
>
<Link
href={`/posts/${post.id}`}
className="text-2xl font-semibold text-blue-600 hover:underline"
>
{post.title}
</Link>
<p className="text-sm text-gray-500">
by {post.author?.name || "Anonymous"}
</p>
<p className="text-xs text-gray-400">
{new Date(post.createdAt).toLocaleDateString("en-US", {
year: "numeric",
month: "long",
day: "numeric",
})}
</p>
</li>
))}
</ul>
)}
{/* Pagination Controls */}
<div className="flex justify-center space-x-4 mt-8">
{page > 1 && (
<Link href={`/posts?page=${page - 1}`}>
<button className="px-4 py-2 bg-gray-200 rounded hover:bg-gray-300">
Previous
</button>
</Link>
)}
{page < totalPages && (
<Link href={`/posts?page=${page + 1}`}>
<button className="px-4 py-2 bg-gray-200 rounded hover:bg-gray-300">
Next
</button>
</Link>
)}
</div>
</>
)}
</>
);
}
export default function PostsPage() {
return (
<div className="min-h-screen bg-gray-50 flex flex-col items-center justify-start p-8">
<Suspense
fallback={
<div className="flex items-center justify-center min-h-screen">
<div className="w-10 h-10 border-4 border-blue-500 border-t-transparent rounded-full animate-spin"></div>
<p className="ml-3 text-gray-600">Loading page...</p>
</div>
}
>
<PostsList />
</Suspense>
</div>
);
}