جاري التحميل...
جاري التحميل...
بناء تطبيق ويب كامل يجمع كل المفاهيم
تهانينا! لقد وصلت إلى الدرس الأخير من مرحلة Next.js. دعنا نلخص كل ما تعلمناه في الدروس التسعة السابقة.
في هذا المشروع، سنبني تطبيق مدونة كامل مع مصادقة، باستخدام جميع المفاهيم التي تعلمناها خلال المرحلة.
بعد إكمال هذه المرحلة، لديك أساس متين في Next.js. يمكنك الآن الانتقال إلى Supabase لخدمات الخادم، أو Clerk للمصادقة، أو البدء في بناء مشاريعك الخاصة.
ما هو الترتيب الصحيح للعرض في Next.js؟
أيهم ليس اتفاقية ملف صحيحة في Next.js؟
اجمع جميع المفاهيم لبناء مدونة مع مصادقة وعمليات CRUD ومعالجة أخطاء وصور محسّنة.
الحل:
// صفحة تصنيف في /blog/category/[name]
import { notFound } from "next/navigation";
import PostCard from "@/components/PostCard";
async function getPostsByCategory(categoryName) {
const res = await fetch(
`https://api.example.com/posts?category=${categoryName}`,
{ next: { revalidate: 3600 } }
);
if (!res.ok) return [];
return res.json();
}
export default async function CategoryPage({ params }) {
const { name } = await params;
const displayName = decodeURIComponent(name);
const posts = await getPostsByCategory(name);
return (
<main className="max-w-6xl mx-auto px-4 py-12">
<h1 className="text-4xl font-extrabold mb-2 text-gray-900">
تصنيف: {displayName}
</h1>
<p className="text-gray-500 mb-8">{posts.length} مقال</p>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
{posts.map((post) => (
<PostCard key={post.id} post={post} />
))}
</div>
</main>
);
}
// Route Handler لإضافة تعليق
// app/api/comments/route.js
import { NextResponse } from "next/server";
export async function POST(request) {
try {
const body = await request.json();
const { postId, author, content } = body;
if (!author || author.length < 2) {
return NextResponse.json(
{ success: false, error: "الاسم مطلوب" },
{ status: 400 }
);
}
if (!content || content.length < 10) {
return NextResponse.json(
{ success: false, error: "التعليق قصير جداً" },
{ status: 400 }
);
}
// حفظ التعليق في قاعدة البيانات
const comment = await db.comments.create({
data: { postId, author, content },
});
return NextResponse.json({ success: true, data: comment }, { status: 201 });
} catch (error) {
return NextResponse.json(
{ success: false, error: "خطأ داخلي" },
{ status: 500 }
);
}
}البدء السريع:
npx create-next-app@latest my-app
cd my-app
npm run devالتوجيه الأساسي:
app/page.js → /
app/about/page.js → /about
app/blog/[slug]/page.js → /blog/:slug
app/(auth)/login/page.js → /loginالتخطيطات:
// app/layout.js
export default function RootLayout({ children }) {
return (
<html lang="ar" dir="rtl">
<body>{children}</body>
</html>
);
}مكونات الخادم:
// بدون "use client" = Server Component
async function MyComponent() {
const data = await fetch("https://api.example.com/data");
const json = await data.json();
return <div>{json.title}</div>;
}كيف تبني مشروع Next.js كامل؟
الإجابة:
ابدأ بالتخطيط، ثم الإعداد، ثم قاعدة البيانات، ثم المصادقة، ثم CRUD.