Spaces:
Running
Running
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, ListFlowable, ListItem from reportlab.lib.styles import getSampleStyleSheet from reportlab.lib.pagesizes import A4 # إعداد ملف PDF file_path = "/mnt/data/دورة_Remix_للمبتدئين.pdf" doc = SimpleDocTemplate(file_path, pagesize=A4) styles = getSampleStyleSheet() story = [] # عنوان رئيسي story.append(Paragraph("📘 دورة مبسطة: إطار عمل Remix للمبتدئين", styles['Title'])) story.append(Spacer(1, 20)) # المحتوى content = [ ("مقدمة عن Remix", [ "Remix هو إطار عمل حديث مبني على React لتطوير تطبيقات الويب.", "مميزاته: سرعة، تنظيم الكود، تجربة مستخدم أفضل." ]), ("تجهيز بيئة العمل", [ "ثبّت Node.js على جهازك.", "أنشئ مشروع جديد باستخدام الأمر:", "npx create-remix@latest" ]), ("بنية المشروع", [ "يوجد مجلدات رئيسية مثل: app، routes، public.", "app: يحتوي الأكواد الأساسية.", "routes: يحتوي الصفحات.", "public: يحتوي الصور والملفات الثابتة." ]), ("الصفحات والتنقل", [ "لإضافة صفحة جديدة، أنشئ ملف داخل routes مثلاً about.jsx.", "الصفحة تعرض تلقائيًا في الرابط /about." ]), ("تحميل البيانات (Loaders)", [ "يمكنك جلب بيانات من السيرفر باستخدام دالة loader.", "مثال:", "export async function loader() { return json({message: 'أهلاً بك'}); }" ]), ("إرسال البيانات (Actions)", [ "تستخدم لإرسال بيانات من النماذج (Forms).", "مثال: إرسال مهمة جديدة في To-Do App." ]), ("إضافة التصميم (CSS)", [ "يمكنك إضافة CSS في المجلد app/styles.", "أو استخدام مكتبات مثل Tailwind CSS." ]), ("معالجة الأخطاء", [ "يمكنك إنشاء ErrorBoundary لعرض رسالة خطأ مخصصة.", "صفحة 404 تظهر عند إدخال رابط غير صحيح." ]), ("نشر التطبيق", [ "يمكنك نشر التطبيق على منصات مثل Vercel أو Netlify.", "الأوامر سهلة ومباشرة بعد تجهيز المشروع." ]), ("مشروع تطبيقي", [ "سننشئ تطبيق مهام (To-Do App).", "المستخدم يضيف مهمة، يعرضها النظام، ويمكنه حذفها.", "يعتمد على Loaders وActions للتعامل مع البيانات." ]) ] # إضافة المحتوى للملف for title, points in content: story.append(Paragraph(f"🔹 {title}", styles['Heading2'])) story.append(Spacer(1, 10)) items = [ListItem(Paragraph(p, styles['Normal'])) for p in points] story.append(ListFlowable(items, bulletType="bullet")) story.append(Spacer(1, 15)) # حفظ الملف doc.build(story) file_path - Initial Deployment
a9edf78 verified | <html lang="ar" dir="rtl"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>دورة مبسطة: إطار عمل Remix للمبتدئين</title> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> | |
| <style> | |
| @import url('https://fonts.googleapis.com/css2?family=Tajawal:wght@400;500;700;900&display=swap'); | |
| body { | |
| font-family: 'Tajawal', sans-serif; | |
| } | |
| .gradient-bg { | |
| background: linear-gradient(135deg, #6B46C1 0%, #4299E1 100%); | |
| } | |
| .section-card { | |
| transition: transform 0.3s ease, box-shadow 0.3s ease; | |
| } | |
| .section-card:hover { | |
| transform: translateY(-5px); | |
| box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04); | |
| } | |
| .code-block { | |
| font-family: 'Courier New', Courier, monospace; | |
| direction: ltr; | |
| } | |
| </style> | |
| </head> | |
| <body class="bg-gray-50 text-gray-800"> | |
| <!-- Header --> | |
| <header class="gradient-bg text-white py-12 px-4"> | |
| <div class="container mx-auto text-center"> | |
| <h1 class="text-3xl md:text-4xl lg:text-5xl font-bold mb-4"> | |
| <i class="fas fa-book-open mr-2"></i> دورة مبسطة: إطار عمل Remix للمبتدئين | |
| </h1> | |
| <p class="text-xl md:text-2xl opacity-90">تعلم أساسيات إطار Remix خطوة بخطوة للمبتدئين</p> | |
| </div> | |
| </header> | |
| <!-- Main Content --> | |
| <main class="container mx-auto py-8 px-4"> | |
| <!-- Introduction Section --> | |
| <section class="mb-12 bg-white rounded-xl shadow-md overflow-hidden section-card"> | |
| <div class="p-6"> | |
| <h2 class="text-2xl font-bold text-purple-800 mb-4 flex items-center"> | |
| <i class="fas fa-star mr-2"></i> مقدمة عن Remix | |
| </h2> | |
| <ul class="list-disc pr-5 space-y-2 text-gray-700"> | |
| <li>Remix هو إطار عمل حديث مبني على React لتطوير تطبيقات الويب.</li> | |
| <li>مميزاته: سرعة، تنظيم الكود، تجربة مستخدم أفضل.</li> | |
| </ul> | |
| </div> | |
| </section> | |
| <!-- Setup Section --> | |
| <section class="mb-12 bg-white rounded-xl shadow-md overflow-hidden section-card"> | |
| <div class="p-6"> | |
| <h2 class="text-2xl font-bold text-purple-800 mb-4 flex items-center"> | |
| <i class="fas fa-tools mr-2"></i> تجهيز بيئة العمل | |
| </h2> | |
| <ul class="list-disc pr-5 space-y-2 text-gray-700"> | |
| <li>ثبّت Node.js على جهازك.</li> | |
| <li>أنشئ مشروع جديد باستخدام الأمر:</li> | |
| <li class="bg-gray-100 p-3 rounded-lg code-block text-sm md:text-base"> | |
| npx create-remix@latest | |
| </li> | |
| </ul> | |
| </div> | |
| </section> | |
| <!-- Project Structure --> | |
| <section class="mb-12 bg-white rounded-xl shadow-md overflow-hidden section-card"> | |
| <div class="p-6"> | |
| <h2 class="text-2xl font-bold text-purple-800 mb-4 flex items-center"> | |
| <i class="fas fa-folder-tree mr-2"></i> بنية المشروع | |
| </h2> | |
| <ul class="list-disc pr-5 space-y-2 text-gray-700"> | |
| <li>يوجد مجلدات رئيسية مثل: app، routes، public.</li> | |
| <li><span class="font-semibold">app:</span> يحتوي الأكواد الأساسية.</li> | |
| <li><span class="font-semibold">routes:</span> يحتوي الصفحات.</li> | |
| <li><span class="font-semibold">public:</span> يحتوي الصور والملفات الثابتة.</li> | |
| </ul> | |
| </div> | |
| </section> | |
| <!-- Pages & Navigation --> | |
| <section class="mb-12 bg-white rounded-xl shadow-md overflow-hidden section-card"> | |
| <div class="p-6"> | |
| <h2 class="text-2xl font-bold text-purple-800 mb-4 flex items-center"> | |
| <i class="fas fa-sitemap mr-2"></i> الصفحات والتنقل | |
| </h2> | |
| <ul class="list-disc pr-5 space-y-2 text-gray-700"> | |
| <li>لإضافة صفحة جديدة، أنشئ ملف داخل routes مثلاً about.jsx.</li> | |
| <li>الصفحة تعرض تلقائيًا في الرابط /about.</li> | |
| </ul> | |
| </div> | |
| </section> | |
| <!-- Data Loading --> | |
| <section class="mb-12 bg-white rounded-xl shadow-md overflow-hidden section-card"> | |
| <div class="p-6"> | |
| <h2 class="text-2xl font-bold text-purple-800 mb-4 flex items-center"> | |
| <i class="fas fa-database mr-2"></i> تحميل البيانات (Loaders) | |
| </h2> | |
| <ul class="list-disc pr-5 space-y-2 text-gray-700"> | |
| <li>يمكنك جلب بيانات من السيرفر باستخدام دالة loader.</li> | |
| <li>مثال:</li> | |
| <li class="bg-gray-100 p-3 rounded-lg code-block text-sm md:text-base"> | |
| export async function loader() { return json({message: 'أهلاً بك'}); } | |
| </li> | |
| </ul> | |
| </div> | |
| </section> | |
| <!-- Data Submission --> | |
| <section class="mb-12 bg-white rounded-xl shadow-md overflow-hidden section-card"> | |
| <div class="p-6"> | |
| <h2 class="text-2xl font-bold text-purple-800 mb-4 flex items-center"> | |
| <i class="fas fa-paper-plane mr-2"></i> إرسال البيانات (Actions) | |
| </h2> | |
| <ul class="list-disc pr-5 space-y-2 text-gray-700"> | |
| <li>تستخدم لإرسال بيانات من النماذج (Forms).</li> | |
| <li>مثال: إرسال مهمة جديدة في To-Do App.</li> | |
| </ul> | |
| </div> | |
| </section> | |
| <!-- Styling --> | |
| <section class="mb-12 bg-white rounded-xl shadow-md overflow-hidden section-card"> | |
| <div class="p-6"> | |
| <h2 class="text-2xl font-bold text-purple-800 mb-4 flex items-center"> | |
| <i class="fas fa-paint-brush mr-2"></i> إضافة التصميم (CSS) | |
| </h2> | |
| <ul class="list-disc pr-5 space-y-2 text-gray-700"> | |
| <li>يمكنك إضافة CSS في المجلد app/styles.</li> | |
| <li>أو استخدام مكتبات مثل Tailwind CSS.</li> | |
| </ul> | |
| </div> | |
| </section> | |
| <!-- Error Handling --> | |
| <section class="mb-12 bg-white rounded-xl shadow-md overflow-hidden section-card"> | |
| <div class="p-6"> | |
| <h2 class="text-2xl font-bold text-purple-800 mb-4 flex items-center"> | |
| <i class="fas fa-exclamation-triangle mr-2"></i> معالجة الأخطاء | |
| </h2> | |
| <ul class="list-disc pr-5 space-y-2 text-gray-700"> | |
| <li>يمكنك إنشاء ErrorBoundary لعرض رسالة خطأ مخصصة.</li> | |
| <li>صفحة 404 تظهر عند إدخال رابط غير صحيح.</li> | |
| </ul> | |
| </div> | |
| </section> | |
| <!-- Deployment --> | |
| <section class="mb-12 bg-white rounded-xl shadow-md overflow-hidden section-card"> | |
| <div class="p-6"> | |
| <h2 class="text-2xl font-bold text-purple-800 mb-4 flex items-center"> | |
| <i class="fas fa-rocket mr-2"></i> نشر التطبيق | |
| </h2> | |
| <ul class="list-disc pr-5 space-y-2 text-gray-700"> | |
| <li>يمكنك نشر التطبيق على منصات مثل Vercel أو Netlify.</li> | |
| <li>الأوامر سهلة ومباشرة بعد تجهيز المشروع.</li> | |
| </ul> | |
| </div> | |
| </section> | |
| <!-- Practical Project --> | |
| <section class="mb-12 bg-white rounded-xl shadow-md overflow-hidden section-card"> | |
| <div class="p-6"> | |
| <h2 class="text-2xl font-bold text-purple-800 mb-4 flex items-center"> | |
| <i class="fas fa-laptop-code mr-2"></i> مشروع تطبيقي | |
| </h2> | |
| <ul class="list-disc pr-5 space-y-2 text-gray-700"> | |
| <li>سننشئ تطبيق مهام (To-Do App).</li> | |
| <li>المستخدم يضيف مهمة، يعرضها النظام، ويمكنه حذفها.</li> | |
| <li>يعتمد على Loaders وActions للتعامل مع البيانات.</li> | |
| </ul> | |
| </div> | |
| </section> | |
| </main> | |
| <!-- Footer --> | |
| <footer class="gradient-bg text-white py-8 px-4"> | |
| <div class="container mx-auto text-center"> | |
| <h3 class="text-xl font-bold mb-4">هل أنت مستعد لبدء رحلتك مع Remix؟</h3> | |
| <div class="flex justify-center space-x-4 space-x-reverse"> | |
| <a href="#" class="bg-white text-purple-800 px-6 py-2 rounded-full font-semibold hover:bg-gray-100 transition"> | |
| ابدأ التعلم الآن | |
| </a> | |
| <a href="#" class="border border-white text-white px-6 py-2 rounded-full font-semibold hover:bg-white hover:bg-opacity-10 transition"> | |
| تواصل معنا | |
| </a> | |
| </div> | |
| <div class="mt-6 pt-6 border-t border-white border-opacity-20"> | |
| <p class="text-sm opacity-80">© 2023 دورة Remix للمبتدئين. جميع الحقوق محفوظة.</p> | |
| </div> | |
| </div> | |
| </footer> | |
| <script> | |
| // Simple animation for section cards when they come into view | |
| const observer = new IntersectionObserver((entries) => { | |
| entries.forEach(entry => { | |
| if (entry.isIntersecting) { | |
| entry.target.style.opacity = 1; | |
| entry.target.style.transform = 'translateY(0)'; | |
| } | |
| }); | |
| }, { threshold: 0.1 }); | |
| document.querySelectorAll('.section-card').forEach(card => { | |
| card.style.opacity = 0; | |
| card.style.transform = 'translateY(20px)'; | |
| card.style.transition = 'opacity 0.5s ease, transform 0.5s ease'; | |
| observer.observe(card); | |
| }); | |
| </script> | |
| <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=Rayan545454/z3333333333" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> | |
| </html> |