اعداد: عبدالرحمن محمود 👀❤
🎓 Qubedu — أكاديمية تطوير الويب الشاملة

تعلّم كل شيء تحتاجه
لتبني أي موقع

من أول وسم HTML حتى بناء مشروع مثل فيسبوك أو متجر إلكتروني — شرح عربي كامل مع كود جاهز للنسخ

60+
وسم HTML
80+
خاصية CSS
40+
مفهوم JS
4
مشاريع ضخمة
المرحلة الأولى

🏗️ HTML — هيكل كل صفحة ويب

كل وسم: لماذا يوجد؟ متى تستخدمه؟ مع كود جاهز للنسخ مباشرة

القالب الأساسي — انسخه لكل مشروع
📌 هذا القالب إلزامي — كل ملف HTML يبدأ هكذا. احفظه كـ snippet في VS Code.
HTML — القالب الكامل
<!-- السطر الأول دائماً -->
<!DOCTYPE html>
<html lang="ar" dir="rtl">
<head>
  <meta charset="UTF-8">                                    <!-- يدعم العربية -->
  <meta name="viewport" content="width=device-width, initial-scale=1.0"> <!-- موبايل -->
  <meta name="description" content="وصف الصفحة لجوجل">
  <title>اسم الصفحة | Qubedu</title>
  <link rel="icon" href="favicon.ico">
  <link rel="stylesheet" href="css/style.css">
</head>
<body>

  <!-- كل المحتوى هنا -->
  <header></header>
  <main></main>
  <footer></footer>

  <!-- JS في آخر body دائماً -->
  <script src="js/main.js"></script>
</body>
</html>
وسوم النصوص
<h1> → <h6>العناوين من الأكبر للأصغرblock
<h1> = العنوان الرئيسي — مرة واحدة فقط في الصفحة (SEO). <h2> للأقسام. <h3> للأقسام الفرعية... حتى h6.
HTML
<h1>العنوان الرئيسي للصفحة — مرة واحدة</h1>
<h2>عنوان قسم رئيسي</h2>
<h3>عنوان فرعي</h3>
<h4>أصغر منه</h4>
<p>الفقرة النصية — لكل نص طويل أو قصيرblock
كل فقرة مستقلة في <p>. المتصفح يضيف مسافة فوق وأسفل تلقائياً. لا تستخدم <br> بدلاً منها.
HTML
<p>هذه فقرة نصية عادية.</p>
<p>
  نص به <strong>غامق مهم</strong> و<em>مائل مؤكد</em>
  و<mark>مظلل</mark> و<del>محذوف</del>.
</p>
<strong> <em> <mark> <del> <span> <code>تنسيق النص inlineinline
HTML
<strong>غامق مهم — SEO يعرفه كمهم</strong>
<em>مائل مؤكد</em>
<mark>مظلل بالأصفر</mark>
<del>سعر قديم 200 ج</del> <ins>سعر جديد 150 ج</ins>
<small>ملاحظة صغيرة</small>
H<sub>2</sub>O   —   E=mc<sup>2</sup>
<code>console.log("كود برمجي")</code>
<span style="color:green">نص ملوّن</span>
<blockquote cite="المصدر">اقتباس مهم</blockquote>
<ul> <ol> <li> <dl>القوائم — نقاط وأرقام وتعريفاتblock
<ul> = نقاط (•). <ol> = أرقام (1,2,3). <li> = عنصر القائمة دائماً. <dl> = قائمة مصطلحات.
HTML
<ul>                                  <!-- قائمة بنقاط -->
  <li>HTML</li>
  <li>CSS</li>
  <li>JavaScript</li>
</ul>

<ol>                                  <!-- قائمة بأرقام -->
  <li>تنزيل VS Code</li>
  <li>إنشاء ملف index.html</li>
  <li>فتحه في المتصفح</li>
</ol>
<a href="">الرابط التشعبي — ينقل لمكان آخرinline
href = الوجهة. target="_blank" = تبويب جديد (أضف rel="noopener" معها). download = تنزيل ملف. يمكن أن يُحيط بصورة أو أي محتوى.
HTML
<!-- رابط خارجي في تبويب جديد -->
<a href="https://google.com" target="_blank" rel="noopener">جوجل</a>

<!-- رابط داخلي لصفحة في نفس الموقع -->
<a href="about.html">من نحن</a>
<a href="products/phone.html">الهاتف</a>

<!-- رابط لقسم في نفس الصفحة -->
<a href="#contact">تواصل معنا</a>
<section id="contact">...</section>

<!-- رابط بريد وهاتف -->
<a href="mailto:info@Qubedu.com">راسلنا</a>
<a href="tel:+201234567890">اتصل بنا</a>

<!-- تنزيل ملف -->
<a href="cv.pdf" download="سيرة-ذاتية.pdf">تنزيل CV</a>

<!-- صورة قابلة للنقر -->
<a href="/"><img src="logo.png" alt="الشعار"></a>
<img src="" alt="">الصورة — عرض أي صورةinline
src = مصدر الصورة. alt = نص بديل — إلزامي للـ SEO وإمكانية الوصول. loading="lazy" = تحميل كسول يسرّع الموقع.
HTML
<!-- صورة محلية -->
<img src="images/hero.jpg" alt="صورة رئيسية" width="800" height="450" loading="lazy">

<!-- صورة متجاوبة -->
<img src="photo.jpg" alt="وصف" style="width:100%;height:auto">

<!-- صورة من الإنترنت -->
<img src="https://picsum.photos/400/300" alt="صورة للتجربة">

<!-- صورة دائرية للأفاتار -->
<img src="user.jpg" alt="صورة المستخدم"
     style="width:48px;height:48px;border-radius:50%;object-fit:cover">

<!-- figure: صورة مع تعليق -->
<figure>
  <img src="product.jpg" alt="المنتج">
  <figcaption>وصف المنتج يظهر تحت الصورة</figcaption>
</figure>
النماذج — قلب كل موقع تفاعلي
⚠️ مهم: كل تسجيل دخول، شراء، تعليق، رسالة — يمر عبر نموذج HTML. إتقانها أساسي.
<form> + كل الحقولنموذج بيانات كامل جاهز للنسخform
HTML — نموذج تسجيل كامل
<form id="registerForm" action="/api/register" method="post">

  <!-- نص -- اسم الشخص -->
  <label for="name">الاسم الكامل</label>
  <input type="text" id="name" name="name"
         placeholder="أدخل اسمك" required minlength="3">

  <!-- بريد إلكتروني -- يتحقق من الشكل تلقائياً -->
  <label for="email">البريد الإلكتروني</label>
  <input type="email" id="email" name="email"
         placeholder="you@example.com" required>

  <!-- كلمة مرور -- تظهر نقاط -->
  <label for="pass">كلمة المرور</label>
  <input type="password" id="pass" name="password" minlength="8" required>

  <!-- رقم هاتف -->
  <input type="tel" name="phone" placeholder="01XXXXXXXXX">

  <!-- رفع صورة -->
  <input type="file" name="avatar" accept="image/*">

  <!-- نص طويل -->
  <textarea name="bio" rows="4" placeholder="اكتب نبذة عنك..."></textarea>

  <!-- قائمة منسدلة -->
  <select name="country">
    <option value="">اختر دولتك</option>
    <option value="eg">🇪🇬 مصر</option>
    <option value="sa">🇸🇦 السعودية</option>
    <option value="ae">🇦🇪 الإمارات</option>
  </select>

  <!-- خيار واحد (radio) -->
  <input type="radio" name="gender" value="male"   id="m"> <label for="m">ذكر</label>
  <input type="radio" name="gender" value="female" id="f"> <label for="f">أنثى</label>

  <!-- موافقة (checkbox) -->
  <input type="checkbox" name="terms" id="terms" required>
  <label for="terms">أوافق على الشروط والأحكام</label>

  <!-- الأزرار -->
  <button type="submit">إنشاء الحساب</button>
  <button type="reset">مسح الكل</button>
  <button type="button" onclick="doSomething()">زر JS</button>

</form>
الوسائط — فيديو وصوت وiframe
<video> <audio> <iframe>تضمين وسائط في الصفحةوسائط
HTML
<!-- فيديو محلي -->
<video src="video.mp4" controls autoplay muted loop
       poster="thumb.jpg" width="100%">
</video>

<!-- صوت -->
<audio src="audio.mp3" controls></audio>

<!-- يوتيوب embed -->
<iframe src="https://www.youtube.com/embed/VIDEO_ID"
        width="100%" height="400" frameborder="0" allowfullscreen></iframe>

<!-- خريطة جوجل -->
<iframe src="https://maps.google.com/maps?q=Cairo&output=embed"
        width="100%" height="350" style="border:0"></iframe>
الجداول
<table> <thead> <tbody> <tr> <th> <td>جدول بيانات منظم في صفوف وأعمدةblock
HTML
<table>
  <thead>
    <tr><th>المنتج</th><th>السعر</th><th>الحالة</th></tr>
  </thead>
  <tbody>
    <tr><td>هاتف</td><td>3500 ج</td><td></td></tr>
    <tr>
      <td colspan="2">لابتوب (نفد)</td>  <!-- يمتد عمودين -->
      <td></td>
    </tr>
  </tbody>
</table>
الوسوم الدلالية والـ SEO
<header> <nav> <main> <section> <article> <aside> <footer>هيكل جوجل يفهمهSEO
HTML — هيكل صفحة كاملة دلالية
<body>
  <header>              <!-- رأس الموقع: شعار + قائمة -->
    <a href="/"><img src="logo.png" alt="Qubedu"></a>
    <nav>               <!-- شريط التنقل -->
      <a href="/">الرئيسية</a>
      <a href="/courses">الدورات</a>
    </nav>
  </header>

  <main>                <!-- المحتوى الرئيسي -- عنصر واحد فقط -->
    <section id="hero">
      <h1>تعلم البرمجة مع Qubedu</h1>
    </section>
    <article>            <!-- مقالة مستقلة / بوست -->
      <h2>ما هو HTML؟</h2>
      <p>HTML هي...</p>
    </article>
  </main>

  <aside>               <!-- عمود جانبي -->
    <h3>مقالات ذات صلة</h3>
  </aside>

  <footer>              <!-- تذييل الصفحة -->
    <p>© 2025 Qubedu</p>
  </footer>
</body>
HTML — meta للـ SEO والسوشيال
<head>
  <!-- SEO أساسي -->
  <title>صفحتك | Qubedu</title>
  <meta name="description" content="ما يظهر في نتائج جوجل — 150 حرف">
  <meta name="keywords"    content="برمجة, HTML, تطوير مواقع">

  <!-- Open Graph: صورة مشاركة السوشيال ميديا -->
  <meta property="og:title"       content="Qubedu">
  <meta property="og:description"  content="أكاديمية تطوير الويب">
  <meta property="og:image"        content="https://Qubedu.com/og.jpg">
  <meta property="og:url"          content="https://Qubedu.com">
</head>
<div> <details> <dialog>حاويات تجميع العناصرblock
HTML
<!-- div: الحاوية الأكثر استخداماً -->
<div class="card">
  <h3>عنوان البطاقة</h3>
  <p>محتوى البطاقة</p>
</div>

<!-- details+summary: accordion بدون JS -->
<details>
  <summary>اضغط لعرض التفاصيل ▼</summary>
  <p>المحتوى المخفي يظهر هنا</p>
</details>

<!-- dialog: modal نيتيف بدون JS -->
<dialog id="modal">
  <h2>هل أنت متأكد؟</h2>
  <button onclick="document.getElementById('modal').close()">إغلاق</button>
</dialog>
<button onclick="document.getElementById('modal').showModal()">فتح</button>
المرحلة الثانية

🎨 CSS — التصميم من الصفر للاحتراف

كل خاصية مع مثال — من الألوان والخطوط لـ Flexbox لـ Grid للأنيميشن

المحددات — كيف تختار العنصر
CSS — كل أنواع المحددات
/* باسم الوسم — يطبق على كل العناصر من هذا النوع */
p      { color: #333; }
h1     { font-size: 2.5rem; }
button { cursor: pointer; }

/* بالكلاس — الأكثر استخداماً */
.card        { background: white; border-radius: 12px; }
.btn-primary { background: #007bff; color: white; }

/* بالـ id — لعنصر واحد */
#header  { position: fixed; top: 0; }

/* محددات متقدمة */
nav a              { color: white; }          /* <a> داخل <nav> فقط */
.card .title       { font-weight: 700; }    /* .title داخل .card */
input[type="email"]{ border-color: blue; }  /* input نوعه email */
.item:nth-child(2) { background: #f0f0f0; } /* العنصر الثاني */
.item:nth-child(odd){ background: #fafafa; }/* الأفرادي */
li:last-child      { border: none; }

/* Pseudo-classes: حالات العنصر */
a:hover       { color: #0056b3; }
button:active { transform: scale(.97); }
input:focus   { outline: 2px solid #007bff; }
input:valid   { border-color: green; }
input:invalid { border-color: red; }
button:disabled{ opacity: .5; cursor: not-allowed; }

/* ::before و ::after — عناصر وهمية بدون HTML */
.card::before {
  content: "";             /* مطلوب دائماً */
  display: block;
  height: 3px;
  background: linear-gradient(90deg, #007bff, #9c27b0);
}
.required::after{ content: " *"; color: red; }
Box Model — الحجم والمسافات والحدود
CSS — Box Model
/* القاعدة الذهبية — ضعها في كل مشروع */
*, *::before, *::after { box-sizing: border-box; }

.element {
  /* الحجم */
  width:      300px;
  height:     200px;
  max-width:  100%;           /* لا يتجاوز الأب */
  min-height: 50px;
  width:      50vw;           /* نسبة من عرض الشاشة */
  height:     100vh;          /* ارتفاع الشاشة كاملاً */

  /* Padding: داخلي */
  padding:         20px;       /* كل الجهات */
  padding:         10px 20px; /* أعلى/أسفل | يمين/يسار */
  padding:         5px 10px 15px 20px; /* أعلى يمين أسفل يسار */
  padding-top:     16px;
  padding-inline:  24px;      /* يمين ويسار فقط */
  padding-block:   12px;      /* أعلى وأسفل فقط */

  /* Margin: خارجي */
  margin:       0 auto;       /* توسيط أفقي */
  margin-bottom:24px;

  /* Border */
  border:        1px solid #ddd;
  border-top:    3px solid #007bff;
  border-radius: 8px;          /* تدوير */
  border-radius: 50%;           /* دائرة */
  outline:       2px solid #007bff; /* بدون تأثير على layout */

  /* الظل */
  box-shadow: 0 4px 16px rgba(0,0,0,.12);
  box-shadow: 0 0 0 3px rgba(0,123,255,.3);  /* حلقة focus */
  box-shadow: inset 0 2px 8px rgba(0,0,0,.1); /* ظل داخلي */

  /* الخلفية */
  background-color:    #ffffff;
  background: linear-gradient(135deg, #667eea, #764ba2);
  background-image:    url('bg.jpg');
  background-size:     cover;
  background-position: center;
  background-repeat:   no-repeat;
  background-attachment: fixed;  /* Parallax */

  /* أخرى */
  overflow: hidden;           /* يقطع ما يخرج */
  overflow-x: auto;           /* scroll أفقي */
  opacity: .8;
  cursor: pointer;
  visibility: hidden;        /* مخفي لكن يحتفظ بمكانه */
  display: none;             /* مخفي ومكانه اختفى */
}
النص والخط
CSS — Typography
body {
  font-family:    'Cairo', sans-serif;
  font-size:      16px;
  font-weight:    400;           /* 100-900 | normal=400 | bold=700 */
  line-height:    1.6;
  color:          #333;
  text-align:     right;         /* للعربية */
  direction:      rtl;
}

h1 { font-size: clamp(1.8rem, 5vw, 4rem); } /* مرن بين حدين */

.text-center  { text-align: center; }
.text-muted   { color: #6c757d; }
.font-bold    { font-weight: 700; }
.no-underline { text-decoration: none; }
.uppercase    { text-transform: uppercase; }
.tracking-wide{ letter-spacing: 2px; }

/* قطع النص بـ ... */
.truncate {
  white-space:   nowrap;
  overflow:      hidden;
  text-overflow: ellipsis;
}

/* نص بتدرج لوني */
.gradient-text {
  background: linear-gradient(135deg, #00d9ff, #7c3aed);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
}
Flexbox — توزيع العناصر في صف أو عمود
CSS — Flexbox
/* على الحاوية الأم */
.container {
  display:         flex;
  flex-direction:  row;              /* row | column | row-reverse */
  justify-content: space-between;   /* flex-start|center|space-between|space-around */
  align-items:     center;          /* flex-start|center|stretch|baseline */
  gap:             16px;            /* المسافة بين العناصر */
  flex-wrap:       wrap;            /* ينتقل للسطر التالي لو ضاق */
}
/* على الأبناء */
.child    { flex: 1; }              /* يتوسع بالتساوي */
.fixed    { flex: 0 0 200px; }     /* 200px ثابت */
.big      { flex-grow: 2; }        /* ينمو ضعف غيره */
.first    { order: -1; }           /* يظهر أول */
.self     { align-self: flex-end; }

/* ═══ وصفات جاهزة ═══ */

/* توسيط في منتصف الشاشة */
.center-screen {
  display: flex; justify-content: center;
  align-items: center; min-height: 100vh;
}
/* Navbar احترافي */
.navbar {
  display:flex; align-items:center; justify-content:space-between;
  padding:0 24px; height:60px; position:fixed; top:0; left:0; right:0;
}
/* بطاقات في صف يلفوا تلقائياً */
.cards-row { display:flex; flex-wrap:wrap; gap:20px; }
.cards-row .card { flex: 1 1 280px; } /* حد أدنى 280px */
CSS Grid — لتصاميم الشبكة
CSS — Grid
.grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);      /* 3 أعمدة متساوية */
  grid-template-columns: 250px 1fr 1fr;       /* sidebar + محتوى */
  grid-template-columns: repeat(auto-fit, minmax(250px,1fr)); /* سحري! */
  gap: 20px;
}
/* عنصر يمتد على كل العرض */
.full    { grid-column: 1 / -1; }
.span-2  { grid-column: span 2; }
.row-2   { grid-row:    span 2; }

/* تصميم صفحة كاملة */
.page-layout {
  display: grid;
  grid-template-areas:
    "header header"
    "sidebar main"
    "footer footer";
  grid-template-columns: 250px 1fr;
  min-height: 100vh;
}
.site-header  { grid-area: header; }
.site-sidebar { grid-area: sidebar; }
.site-main    { grid-area: main; }
.site-footer  { grid-area: footer; }
Position — تحكم دقيق في المواضع
CSS — Position
/* relative: يتحرك نسبياً ويصبح مرجعاً */
.parent    { position: relative; }

/* absolute: موضع دقيق داخل أقرب أب relative */
.badge     { position: absolute; top: -8px; right: -8px; }

/* fixed: ثابت في الشاشة عند التمرير */
.topbar    { position: fixed; top:0; left:0; right:0; z-index:1000; }

/* sticky: عادي ثم يلتصق لما تصل إليه */
.sticky-head{ position: sticky; top: 60px; }

/* Modal overlay كامل */
.overlay {
  position: fixed; inset: 0;      /* = top:0 right:0 bottom:0 left:0 */
  background: rgba(0,0,0,.6); z-index: 999;
  display:flex; align-items:center; justify-content:center;
}
الأنيميشن والحركة
CSS — Transitions وAnimations
/* Transition: انتقال سلس */
.btn {
  transition: all 0.25s ease;      /* الخاصية | المدة | المنحنى */
}
.btn:hover {
  background: #0056b3;
  transform: translateY(-2px);
  box-shadow: 0 8px 20px rgba(0,123,255,.4);
}

/* Transform */
.card:hover { transform: scale(1.03) translateY(-4px); }
.icon       { transform: rotate(45deg); }

/* Keyframes: حركة كاملة بمراحل */
@keyframes fadeInUp {
  from { opacity:0; transform:translateY(30px); }
  to   { opacity:1; transform:translateY(0); }
}
.hero-text { animation: fadeInUp .6s ease forwards; }
.hero-btn  { animation: fadeInUp .6s ease .2s forwards; opacity:0; }

/* Loading Spinner */
@keyframes spin { to{ transform:rotate(360deg); } }
.spinner {
  width:40px; height:40px; border-radius:50%;
  border:4px solid #eee; border-top-color:#007bff;
  animation: spin .8s linear infinite;
}

/* Skeleton Loading */
@keyframes shimmer {
  from { background-position: -200% 0; }
  to   { background-position: 200% 0; }
}
.skeleton {
  background: linear-gradient(90deg, #f0f0f0 25%, #e8e8e8 50%, #f0f0f0 75%);
  background-size: 200%;
  animation: shimmer 1.5s infinite;
}
الـ Responsive — موقعك على كل الأجهزة
CSS — Responsive Design
/* Mobile First: ابدأ بالموبايل */
.grid { grid-template-columns: 1fr; }

@media (min-width: 640px)  { .grid { grid-template-columns: repeat(2,1fr); } }
@media (min-width: 768px)  { .sidebar { display: block; } }
@media (min-width: 1024px) { .grid { grid-template-columns: repeat(3,1fr); } }
@media (min-width: 1280px) { .grid { grid-template-columns: repeat(4,1fr); } }

/* إخفاء على الموبايل */
@media (max-width: 767px)  { .desktop-only { display: none; } }
@media (min-width: 768px)  { .mobile-only  { display: none; } }

/* Dark Mode تلقائي */
@media (prefers-color-scheme: dark) {
  :root { --bg: #121212; --text: #e0e0e0; }
}

/* وحدات مرنة */
h1          { font-size: clamp(1.5rem, 5vw, 4rem); }
.container  { width: min(100%, 1200px); margin: 0 auto; padding: 0 16px; }
CSS Variables — ثيم احترافي
CSS Variables + Dark Mode
:root {
  --primary:   #007bff;   --secondary: #6c757d;
  --success:   #28a745;   --danger:    #dc3545;
  --bg:        #ffffff;   --text:      #212529;
  --border:    #dee2e6;   --radius:    8px;
  --shadow:    0 4px 16px rgba(0,0,0,.1);
}
.btn    { background: var(--primary); border-radius: var(--radius); }
.card   { box-shadow: var(--shadow); }
.error  { color: var(--danger); }

/* Dark Mode بـ JS: document.documentElement.setAttribute('data-theme','dark') */
[data-theme="dark"] {
  --bg:    #0d1117;   --text:   #c9d1d9;
  --border:#30363d;
}
المرحلة الثالثة

⚡ JavaScript — التفاعل والمنطق

من المتغيرات حتى async/await — كل ما تحتاجه لبناء تطبيقات حقيقية

المتغيرات والأنواع والعمليات
JavaScript — Variables & Types
// المتغيرات
const siteName = "Qubedu";        // ثابت لا يتغير — استخدمه دائماً
let   counter  = 0;               // متغير يتغير لاحقاً
// var — قديم، تجنبه تماماً

// الأنواع الأساسية
const name   = "أحمد";            // String
const age    = 25;               // Number
const price  = 3.14;             // Float
const active = true;             // Boolean
const data   = null;             // فارغ مقصود
let   undef;                      // undefined: لم يُعطَ قيمة

// العمليات الحسابية
10 + 5   // 15
10 - 3   // 7
4  * 3   // 12
10 / 4   // 2.5
10 % 3   // 1 (باقي القسمة)
2  ** 3  // 8 (2 أس 3)
counter++;   // زيادة بمقدار 1
counter--;   // نقصان بمقدار 1
counter += 5; // زيادة بمقدار 5

// التحقق من النوع
typeof "hello"  // "string"
typeof 42       // "number"
typeof true     // "boolean"
typeof {}       // "object"
typeof []       // "object" (مصفوفة!)
Array.isArray([]) // true — الأصح للمصفوفات

// التعامل مع النصوص
`مرحباً يا ${name}! عمرك ${age} سنة` // Template Literal
name.length              // 4
name.toUpperCase()       // "أحمد" (يؤثر على الإنجليزية)
"  hello  ".trim()     // "hello"
"hello".includes("ell") // true
"a,b,c".split(",")      // ["a","b","c"]
"hello".replace("hello","مرحبا") // "مرحبا"
"hello".slice(0, 3)    // "hel"
["أ","ب"].join(" - ")  // "أ - ب"

// Math
Math.round(4.6)   // 5
Math.floor(4.9)   // 4
Math.ceil(4.1)    // 5
Math.abs(-5)      // 5
Math.max(3,7,2)  // 7
Math.random()     // 0 إلى 0.99
Math.floor(Math.random()*100) // رقم عشوائي 0-99
الدوال والشروط والحلقات
JavaScript — Functions, Conditions, Loops
// ══ الدوال ══
function greet(name) {
  return `مرحباً يا ${name}!`;
}

const add    = (a, b) => a + b;              // Arrow مختصر
const square = n => n * n;                  // معامل واحد بدون أقواس
const sayHi  = () => console.log("مرحبا"); // بدون معاملات

// Default Parameters
function createUser(name, role = "user", active = true) {
  return { name, role, active };
}

// ══ الشروط ══
if (score >= 90)      { console.log("ممتاز"); }
else if (score >= 70) { console.log("جيد جداً"); }
else                   { console.log("راجع"); }

// Ternary — شرط مختصر في سطر
const label = score >= 50 ? "ناجح" : "راسب";

// Nullish Coalescing
const username = user?.name ?? "زائر";  // لو null أو undefined
const avatar   = user?.profile?.image;   // Optional Chaining

// Switch
switch(day) {
  case "الجمعة": case "السبت": console.log("عطلة!"); break;
  default: console.log("يوم عمل");
}

// ══ الحلقات ══
for (let i = 0; i < 5; i++) { console.log(i); }

for (const item of ["HTML","CSS","JS"]) {
  console.log(item);
}

for (const [key, val] of Object.entries(user)) {
  console.log(`${key}: ${val}`);
}

while (queue.length > 0) {
  const task = queue.shift();
  task.execute();
}
DOM — التحكم في HTML بـ JavaScript
JavaScript — DOM
// ══ اختيار عناصر ══
const el   = document.querySelector("#id");          // بالـ id
const card = document.querySelector(".card");         // أول عنصر بالكلاس
const all  = document.querySelectorAll(".card");      // كلهم
const first= document.querySelector("nav a:first-child");

// ══ قراءة وكتابة ══
el.textContent  = "نص جديد";           // كتابة آمنة
el.innerHTML    = "<b>HTML</b>";       // HTML داخله
const val       = el.textContent;       // قراءة
const inputVal  = document.querySelector("#email").value;

// ══ الخصائص ══
el.setAttribute("href", "https://Qubedu.com");
el.removeAttribute("disabled");
el.dataset.id     = "123";               // data-id="123"
el.style.color   = "red";
el.style.display = "none";
el.style.display = "";                   // إزالة inline

// ══ الكلاسات ══
el.classList.add("active");
el.classList.remove("hidden");
el.classList.toggle("dark");           // يضيف أو يحذف
el.classList.contains("active");      // true/false
el.classList.replace("old", "new");

// ══ إنشاء وإضافة ══
const card = document.createElement("div");
card.className = "product-card";
card.innerHTML = `
  <img src="${p.image}" alt="${p.name}">
  <h3>${p.name}</h3>
  <p>${p.price} ج</p>
  <button data-id="${p.id}" class="add-btn">أضف للسلة</button>
`;
document.querySelector("#grid").appendChild(card);
card.remove();                            // حذف

// ══ التمرير ══
document.querySelector("#section").scrollIntoView({ behavior: 'smooth' });
window.scrollTo({ top: 0, behavior: 'smooth' });
الأحداث — استجب لتصرفات المستخدم
JavaScript — Events
// ══ إضافة حدث ══
btn.addEventListener("click", (e) => {
  e.preventDefault();   // منع السلوك الافتراضي
  e.stopPropagation(); // منع تصاعد الحدث
  console.log(e.target);  // العنصر الذي تم النقر عليه
});

// كل أنواع الأحداث:
// click / dblclick — نقر
// mouseenter / mouseleave — دخول/خروج الماوس
// keydown / keyup — لوحة المفاتيح
// input — تغيير قيمة حقل (كل حرف)
// change — بعد انتهاء التغيير
// submit — إرسال نموذج
// scroll — تمرير الصفحة
// resize — تغيير حجم النافذة
// DOMContentLoaded — HTML جاهز

// ══ نموذج كامل ══
document.querySelector("#loginForm").addEventListener("submit", async (e) => {
  e.preventDefault();
  const email = e.target.querySelector("#email").value.trim();
  const pass  = e.target.querySelector("#pass").value;
  if (!email || !pass) { showError("أملأ كل الحقول"); return; }
  await login(email, pass);
});

// ══ تفويض الأحداث (لعناصر تُنشأ لاحقاً) ══
document.querySelector("#feed").addEventListener("click", (e) => {
  if (e.target.matches(".like-btn"))
    likePost(e.target.dataset.id);
  if (e.target.matches(".delete-btn"))
    deletePost(e.target.dataset.id);
});

// ══ LocalStorage — حفظ محلي ══
localStorage.setItem("token", "abc123");
const token = localStorage.getItem("token");
localStorage.removeItem("token");
localStorage.setItem("cart", JSON.stringify(items));
const cart  = JSON.parse(localStorage.getItem("cart") || "[]");
المصفوفات — أساس كل قائمة
JavaScript — Arrays
const products = [
  { id:1, name:"هاتف",  price:3200, cat:"تقنية",   stock:15 },
  { id:2, name:"حذاء",  price:350,  cat:"ملابس",   stock:30 },
  { id:3, name:"كتاب",  price:80,   cat:"تعليم",   stock:0  },
  { id:4, name:"سماعة", price:650,  cat:"تقنية",   stock:8  },
];

// map: حوّل كل عنصر
const names    = products.map(p => p.name);
const disc     = products.map(p => ({...p, price: p.price * .9}));
const cards    = products.map(p => `<div class="card">${p.name}</div>`).join("");

// filter: صفّي بشرط
const inStock  = products.filter(p => p.stock > 0);
const tech     = products.filter(p => p.cat === "تقنية");
const cheap    = products.filter(p => p.price < 500);

// find: أول عنصر يطابق
const phone    = products.find(p => p.id === 1);
const idx      = products.findIndex(p => p.id === 1); // الرقم التسلسلي

// some / every
const anyOut   = products.some(p => p.stock === 0);  // true
const allIn    = products.every(p => p.stock > 0);   // false

// reduce: جمع / تجميع
const total    = products.reduce((sum,p) => sum + p.price, 0);
const maxPrice = products.reduce((max,p) => p.price>max ? p.price : max, 0);

// sort
const byPrice  = [...products].sort((a,b) => a.price - b.price);
const byName   = [...products].sort((a,b) => a.name.localeCompare(b.name));

// إضافة / حذف
products.push({id:5});          // أضف للنهاية
products.unshift({id:0});       // أضف للبداية
products.pop();                  // احذف الأخير
products.splice(2, 1);          // احذف index 2
const merged = [...arr1, ...arr2];// دمج
const unique  = [...new Set(arr)]; // حذف المكرر
الكائنات وJSON
JavaScript — Objects & JSON
const user = {
  id: 1, name: "أحمد", email: "ahmed@Qubedu.com",
  address: { city: "القاهرة", country: "مصر" },
  skills: ["HTML", "CSS", "JS"],
  greet() { return `مرحباً، أنا ${this.name}`; }
};

// الوصول
user.name                       // "أحمد"
user["email"]                    // نفس الشيء
user?.address?.city             // "القاهرة" بأمان
user.skills[0]                  // "HTML"

// Destructuring: استخراج مختصر
const { name, email, role = "user" } = user;
const { city } = user.address;
const [first, second] = user.skills;

// Spread: نسخ ودمج
const updated = { ...user, name: "علي" };        // نسخة محدّثة
const merged  = { ...defaults, ...userPrefs };    // دمج

// JSON
const json    = JSON.stringify(user, null, 2);    // كائن → نص جميل
const parsed  = JSON.parse(json);                 // نص → كائن

// دوال الكائن
Object.keys(user)     // ["id","name","email",...]
Object.values(user)   // [1,"أحمد","ahmed@...",...]
Object.entries(user)  // [["id",1],["name","أحمد"],...]
Async / Fetch — التواصل مع السيرفر
JavaScript — Fetch API
// ══ GET: جلب بيانات ══
async function loadProducts() {
  const grid = document.querySelector("#grid");
  grid.innerHTML = `<div class="spinner"></div>`;

  try {
    const res  = await fetch("/api/products");
    if (!res.ok) throw new Error(`خطأ ${res.status}`);
    const data = await res.json();

    grid.innerHTML = data.map(p => `
      <div class="card">
        <img src="${p.image}" alt="${p.name}">
        <h3>${p.name}</h3>
        <p>${p.price} ج</p>
        <button data-id="${p.id}" class="add-btn">أضف للسلة</button>
      </div>
    `).join("");
  } catch(err) {
    grid.innerHTML = `<p class="error">⚠️ ${err.message}</p>`;
  }
}

// ══ POST: إرسال بيانات ══
async function register(email, password, name) {
  const res = await fetch("/api/auth/register", {
    method:  "POST",
    headers: { "Content-Type": "application/json" },
    body:    JSON.stringify({ email, password, name })
  });
  const data = await res.json();
  if (data.token) localStorage.setItem("token", data.token);
  return data;
}

// ══ طلب مع توكن المصادقة ══
async function getProfile() {
  const token = localStorage.getItem("token");
  const res = await fetch("/api/me", {
    headers: { "Authorization": `Bearer ${token}` }
  });
  return res.json();
}

// ══ رفع صورة ══
async function uploadImage(file) {
  const form = new FormData();
  form.append("image", file);
  const res = await fetch("/api/upload", { method:"POST", body: form });
  return (await res.json()).url;
}

// ══ طلبات متوازية ══
const [user, posts, products] = await Promise.all([
  fetch("/api/me").then(r => r.json()),
  fetch("/api/posts").then(r => r.json()),
  fetch("/api/products").then(r => r.json()),
]);
المرحلة الرابعة — Backend

🖥️ Node.js + Express — بناء السيرفر والـ API

هنا تعيش البيانات — السيرفر يستقبل الطلبات ويرد عليها بـ JSON

🔄 كيف يعمل Backend؟
المتصفح يرسل طلب ← السيرفر يستقبله ← يتحقق من هوية المستخدم ← يجلب البيانات من قاعدة البيانات ← يرد بـ JSON ← المتصفح يعرضها.
إعداد المشروع — هيكل الملفات
Terminal — تهيئة مشروع Node
# إنشاء مشروع جديد
mkdir my-backend && cd my-backend
npm init -y

# تنزيل المكتبات الأساسية
npm install express          # سيرفر الويب
npm install mongoose         # MongoDB
npm install jsonwebtoken     # JWT
npm install bcryptjs         # تشفير كلمات المرور
npm install dotenv           # متغيرات البيئة
npm install cors             # السماح للمتصفح بالتواصل
npm install multer           # رفع الملفات
npm install -D nodemon       # إعادة تشغيل تلقائي أثناء التطوير

# هيكل المجلدات المثالي
📁 backend/
├── 📄 server.js            ← نقطة البداية
├── 📄 .env                 ← أسرار لا ترفعها على GitHub!
├── 📄 .gitignore           ← node_modules و .env
├── 📁 config/
│   └── database.js         ← إعداد قاعدة البيانات
├── 📁 models/
│   ├── User.js             ← نموذج المستخدم
│   ├── Post.js             ← نموذج المنشور
│   └── Product.js          ← نموذج المنتج
├── 📁 routes/
│   ├── auth.js             ← تسجيل الدخول
│   ├── users.js
│   └── posts.js
├── 📁 controllers/
│   ├── authController.js
│   └── postController.js
└── 📁 middleware/
    ├── authMiddleware.js    ← التحقق من التوكن
    └── upload.js
Express — السيرفر الكامل + CRUD
server.js — السيرفر الرئيسي
const express   = require('express');
const cors      = require('cors');
const dotenv    = require('dotenv');
const connectDB = require('./config/database');
dotenv.config();

const app = express();

// Middleware
app.use(cors({ origin: process.env.CLIENT_URL }));
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use('/uploads', express.static('uploads'));

// Routes
app.use('/api/auth',     require('./routes/auth'));
app.use('/api/users',    require('./routes/users'));
app.use('/api/posts',    require('./routes/posts'));
app.use('/api/products', require('./routes/products'));

// معالجة الأخطاء العامة
app.use((err, req, res, next) => {
  console.error(err.stack);
  res.status(err.status || 500).json({ message: err.message });
});

const PORT = process.env.PORT || 5000;
app.listen(PORT, async () => {
  await connectDB();
  console.log(`✅ السيرفر يعمل على http://localhost:${PORT}`);
});
routes/posts.js — CRUD كامل
const router = require('express').Router();
const Post   = require('../models/Post');
const auth   = require('../middleware/authMiddleware');

// GET /api/posts — كل المنشورات مع Pagination
router.get('/', async (req, res) => {
  try {
    const { page=1, limit=10 } = req.query;
    const posts = await Post
      .find()
      .populate('author', 'name avatar')
      .sort({ createdAt: -1 })
      .skip((page-1) * limit)
      .limit(Number(limit));
    res.json(posts);
  } catch(err) { res.status(500).json({ message: err.message }); }
});

// GET /api/posts/:id — منشور واحد
router.get('/:id', async (req, res) => {
  const post = await Post.findById(req.params.id).populate('author');
  if (!post) return res.status(404).json({ message: "غير موجود" });
  res.json(post);
});

// POST /api/posts — إنشاء منشور (مسجل فقط)
router.post('/', auth, async (req, res) => {
  const { content, image } = req.body;
  const post = await Post.create({ content, image, author: req.userId });
  await post.populate('author', 'name avatar');
  res.status(201).json(post);
});

// PUT /api/posts/:id/like — إعجاب / إلغاء
router.put('/:id/like', auth, async (req, res) => {
  const post  = await Post.findById(req.params.id);
  const liked = post.likes.includes(req.userId);
  liked ? post.likes.pull(req.userId) : post.likes.push(req.userId);
  await post.save();
  res.json({ likes: post.likes.length, liked: !liked });
});

// DELETE /api/posts/:id
router.delete('/:id', auth, async (req, res) => {
  const post = await Post.findById(req.params.id);
  if (post.author.toString() !== req.userId)
    return res.status(403).json({ message: "غير مصرح" });
  await post.deleteOne();
  res.json({ message: "تم الحذف" });
});

module.exports = router;
JWT — نظام تسجيل الدخول والمصادقة
authController.js + authMiddleware.js
// ═══ controllers/authController.js ═══
const bcrypt = require('bcryptjs');
const jwt    = require('jsonwebtoken');
const User   = require('../models/User');

exports.register = async (req, res) => {
  const { name, email, password } = req.body;
  if (await User.findOne({ email }))
    return res.status(400).json({ message: "البريد مستخدم" });
  const hashed = await bcrypt.hash(password, 12);
  const user   = await User.create({ name, email, password: hashed });
  const token  = jwt.sign({ userId: user._id }, process.env.JWT_SECRET, { expiresIn: '7d' });
  res.status(201).json({ token, user: { id: user._id, name, email } });
};

exports.login = async (req, res) => {
  const { email, password } = req.body;
  const user = await User.findOne({ email });
  if (!user || !(await bcrypt.compare(password, user.password)))
    return res.status(401).json({ message: "بيانات غير صحيحة" });
  const token = jwt.sign({ userId: user._id }, process.env.JWT_SECRET, { expiresIn: '7d' });
  res.json({ token, user: { id: user._id, name: user.name, role: user.role } });
};

// ═══ middleware/authMiddleware.js ═══
module.exports = async (req, res, next) => {
  try {
    const token   = req.headers.authorization?.split(' ')[1];  // Bearer TOKEN
    if (!token) return res.status(401).json({ message: "سجّل دخولك أولاً" });
    const decoded = jwt.verify(token, process.env.JWT_SECRET);
    req.userId = decoded.userId;
    next();
  } catch { res.status(401).json({ message: "توكن غير صالح" }); }
};
المرحلة الخامسة

🗄️ قواعد البيانات — أين تعيش بياناتك

MongoDB للبيانات المرنة — PostgreSQL للبيانات العلاقية

MongoDB + Mongoose
models/User.js + Post.js
const mongoose = require('mongoose');

// ═══ User Schema ═══
const userSchema = new mongoose.Schema({
  name:       { type: String,  required: true, trim: true },
  email:      { type: String,  required: true, unique: true, lowercase: true },
  password:   { type: String,  required: true, minlength: 8, select: false },
  avatar:     { type: String,  default: 'default.jpg' },
  bio:        { type: String,  maxlength: 500 },
  role:       { type: String,  enum: ['user','admin'], default: 'user' },
  followers:  [{ type: mongoose.Types.ObjectId, ref: 'User' }],
  following:  [{ type: mongoose.Types.ObjectId, ref: 'User' }],
  isVerified: { type: Boolean, default: false }
}, { timestamps: true });  // يضيف createdAt وupdatedAt تلقائياً

module.exports = mongoose.model('User', userSchema);

// ═══ Post Schema ═══
const postSchema = new mongoose.Schema({
  author:   { type: mongoose.Types.ObjectId, ref: 'User', required: true },
  content:  { type: String, required: true, maxlength: 2000 },
  image:    String,
  likes:    [{ type: mongoose.Types.ObjectId, ref: 'User' }],
  comments: [{
    user:      { type: mongoose.Types.ObjectId, ref: 'User' },
    text:      { type: String, required: true },
    createdAt: { type: Date, default: Date.now }
  }],
  views:    { type: Number, default: 0 },
  tags:     [String]
}, { timestamps: true });
postSchema.index({ content: 'text' }); // بحث نصي

module.exports = mongoose.model('Post', postSchema);
MongoDB Queries — الاستعلامات
// جلب كل المنشورات
const posts = await Post.find();

// جلب بشرط
const myPosts = await Post.find({ author: userId });

// جلب مع populate (بيانات مرتبطة)
const post = await Post.findById(id).populate('author', 'name avatar');

// فرز + pagination
const data = await Post
  .find({ views: { $gt: 100 } })  // أكثر من 100 مشاهدة
  .sort({ createdAt: -1 })
  .skip((page-1) * 10)
  .limit(10);

// إنشاء
const user = await User.create({ name, email, password });

// تحديث
await User.findByIdAndUpdate(id, { name: "اسم جديد" }, { new: true });

// حذف
await Post.findByIdAndDelete(id);

// عدد
const count = await Post.countDocuments({ author: userId });

// بحث نصي
const results = await Post.find({ $text: { $search: "برمجة" } });

// Operators مهمة
// $gt / $lt / $gte / $lte — أكبر / أصغر
// $in — داخل مصفوفة
// $or / $and — شروط متعددة
// $push / $pull — إضافة/حذف من مصفوفة
// $inc — زيادة رقم
await Post.findByIdAndUpdate(id, { $inc: { views: 1 } });
PostgreSQL — SQL
SQL — الجداول والاستعلامات
-- إنشاء الجداول
CREATE TABLE users (
  id         SERIAL PRIMARY KEY,
  name       VARCHAR(100) NOT NULL,
  email      VARCHAR(255) UNIQUE NOT NULL,
  password   TEXT NOT NULL,
  role       VARCHAR(20) DEFAULT 'user',
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

CREATE TABLE products (
  id          SERIAL PRIMARY KEY,
  name        VARCHAR(255) NOT NULL,
  price       DECIMAL(10,2) NOT NULL,
  stock       INTEGER DEFAULT 0,
  category_id INTEGER REFERENCES categories(id),
  image_url   TEXT,
  created_at  TIMESTAMP DEFAULT NOW()
);

CREATE TABLE orders (
  id         SERIAL PRIMARY KEY,
  user_id    INTEGER REFERENCES users(id) ON DELETE CASCADE,
  total      DECIMAL(10,2),
  status     VARCHAR(50) DEFAULT 'pending',
  created_at TIMESTAMP DEFAULT NOW()
);

-- CRUD
SELECT * FROM products WHERE price < 500 ORDER BY price ASC LIMIT 10;

SELECT p.name, c.name AS category
FROM products p
JOIN categories c ON p.category_id = c.id
WHERE p.stock > 0;

INSERT INTO users (name, email, password) VALUES ($1, $2, $3);
UPDATE products SET stock = stock - 1 WHERE id = $1;
DELETE FROM products WHERE id = $1;
التطبيق الحقيقي

🚀 كيف تبني مواقع ضخمة؟

معمارية + خطوات + كود حقيقي لكل مشروع — فيسبوك، يوتيوب، واتساب، متجر

📘
موقع تواصل اجتماعي — مثل فيسبوك وإنستجرام
نشر محتوى، إعجاب، تعليق، متابعة، رسائل مباشرة
React.js
REST API
Node.js
MongoDB
+
Socket.io
+
Cloudinary
React.jsNode.jsMongoDB JWTSocket.ioCloudinaryRedis
  • 1
    المصادقة: تسجيل وتسجيل دخول بـ JWT — الـ token يُحفظ في localStorage ويُرسل مع كل طلب في Header.
  • 2
    الملف الشخصي: صورة، اسم، بيو — رفع الصور عبر Cloudinary مجاناً (10GB في الخطة المجانية).
  • 3
    الجدار الزمني (Feed): جلب منشورات الأصدقاء مرتبة بالتاريخ — Pagination لتحميل المزيد عند التمرير للأسفل.
  • 4
    الإعجاب والتعليق: مصفوفة likes[] داخل Post Schema — Toggle بضغطة واحدة. التعليقات في comments[].
  • 5
    المتابعة: مصفوفتا followers و following في User Schema — قائمة مقترحات من خلال المتابَعين المشتركين.
  • 6
    الإشعارات اللحظية: Socket.io — كل مستخدم له غرفة خاصة. يُرسل إشعار فور الإعجاب أو التعليق أو المتابعة.
  • 7
    الرسائل المباشرة: غرف محادثة بـ Socket.io — الرسائل تُحفظ في MongoDB للتاريخ.
Socket.io — إشعارات لحظية
const { Server } = require('socket.io');
const io = new Server(server, { cors: { origin: '*' } });
const online = {};

io.on('connection', socket => {
  // المستخدم ينضم لغرفته الخاصة
  socket.on('join', userId => {
    online[userId] = socket.id;
    socket.join(userId);
  });
  // إرسال رسالة
  socket.on('sendMessage', ({ to, message }) => {
    io.to(to).emit('newMessage', { from: socket.userId, message, time: new Date() });
  });
  socket.on('disconnect', () => delete online[socket.userId]);
});

// من أي route: أرسل إشعار بعد الإعجاب
io.to(post.author.toString()).emit('notification', {
  type: 'like', from: likerName, postId: post._id
});
🎥
منصة مشاركة فيديو — مثل يوتيوب وتيك توك
رفع وضغط وتشغيل الفيديوهات + نظام القنوات والتوصيات
React.js
Node.js
FFmpeg
AWS S3
+
PostgreSQL
+
Redis
React.jsNode.jsFFmpeg AWS S3PostgreSQLRedisVideo.js
  • 1
    رفع الفيديو: المستخدم يرفع الملف عبر multipart/form-data — يُحفظ مؤقتاً على السيرفر ثم يُعالج.
  • 2
    المعالجة بـ FFmpeg: يحوّل لجودات متعددة (1080p, 720p, 480p) في Background Job بـ Bull Queue.
  • 3
    التخزين على AWS S3: كل جودة ترفع كملف منفصل — رابط CDN يُعطى للمستخدم. البديل المجاني: Cloudinary.
  • 4
    مشغل الفيديو: Video.js أو HLS.js — يغير الجودة تلقائياً حسب سرعة الإنترنت.
  • 5
    عداد المشاهدات: Redis يعدّ سريعاً ثم يحدّث قاعدة البيانات كل دقيقة دفعةً واحدة.
  • 6
    التوصيات: بناءً على تصنيفات الفيديو، تاريخ المشاهدة، والكلمات المفتاحية — يمكن البدء بـ Collaborative Filtering.
FFmpeg — ضغط وتحويل الفيديو
const ffmpeg = require('fluent-ffmpeg');

async function processVideo(inputPath, videoId) {
  const qualities = [
    { label:'1080p', height:1080, bitrate:'4000k' },
    { label:'720p',  height:720,  bitrate:'2500k' },
    { label:'480p',  height:480,  bitrate:'1000k' },
  ];
  for (const q of qualities) {
    await new Promise((res, rej) => {
      ffmpeg(inputPath)
        .outputOptions([`-vf scale=-2:${q.height}`, `-b:v ${q.bitrate}`])
        .output(`uploads/${videoId}_${q.label}.mp4`)
        .on('end', res).on('error', rej).run();
    });
  }
}
💬
تطبيق تراسل فوري — مثل واتساب وتيليجرام
رسائل لحظية مشفرة، حالة القراءة، إشعارات Push
React/RN
↕ WS
Socket.io
Node.js
PostgreSQL
+
Redis
+
Firebase FCM
Socket.ioReact Native PostgreSQLRedisE2E EncryptionFirebase FCM
  • 1
    WebSocket: خلافاً لـ HTTP، يفتح قناة مستمرة ثنائية الاتجاه — السيرفر يرسل للعميل بدون طلب منه.
  • 2
    غرف المحادثة: كل محادثة لها room_id فريد — Socket.io يوجه الرسائل للغرفة الصحيحة فقط.
  • 3
    حالة القراءة ✓✓: عند فتح المحادثة يُرسل markAsRead event — يغير لون العلامة في جانب المرسل.
  • 4
    التشفير E2E: المفاتيح تُولّد على جهاز المستخدم — السيرفر يرى الرسائل مشفرة فقط ولا يعرف محتواها.
  • 5
    الإشعارات Push: Firebase Cloud Messaging يرسل إشعار لما يكون التطبيق مغلقاً أو الجهاز في وضع السكون.
  • 6
    الرسائل الصوتية: تسجيل بـ MediaRecorder API في المتصفح — رفع الـ blob — تشغيل بمشغل مخصص.
🛒
متجر إلكتروني — مثل أمازون ونون
منتجات، سلة، دفع إلكتروني، إدارة طلبات
Next.js
Node.js API
PostgreSQL
+
Stripe
+
Redis Cache
Next.jsNode.jsPostgreSQL StripePaymob (مصر)RedisPrisma
  • 1
    صفحات المنتجات بـ SSR: Next.js يُنشئ HTML على السيرفر — جوجل يراه كاملاً (SEO ممتاز).
  • 2
    سلة التسوق: تُحفظ في localStorage للزوار — وفي قاعدة البيانات للمسجلين — تُدمجان عند تسجيل الدخول.
  • 3
    الدفع بـ Stripe: ينشئ Payment Intent على السيرفر — يرسل clientSecret للمتصفح — المتصفح يكمل الدفع.
  • 4
    Webhook للتأكيد: Stripe يرسل تأكيد الدفع لسيرفرك — هنا تُنشئ الطلب وتُرسل إيميل التأكيد للعميل.
  • 5
    لوحة التحكم: إضافة منتجات، إدارة الطلبات، تغيير حالة الشحن، تقارير المبيعات اليومية.
  • 6
    كوبونات الخصم: جدول coupons في قاعدة البيانات — تحقق من الصلاحية وتطبيق الخصم قبل الدفع.
Stripe — بوابة الدفع
// السيرفر: إنشاء نية الدفع
const stripe = require('stripe')(process.env.STRIPE_SECRET);

router.post('/payment-intent', auth, async (req, res) => {
  const amount = req.body.items.reduce((s,i) => s + i.price * i.qty, 0);
  const intent = await stripe.paymentIntents.create({
    amount:   Math.round(amount * 100),
    currency: 'egp',
    metadata: { userId: req.userId }
  });
  res.json({ clientSecret: intent.client_secret });
});

// المتصفح: تأكيد الدفع
const { error } = await stripe.confirmCardPayment(clientSecret, {
  payment_method: { card: cardElement, billing_details: { name, email } }
});
if (!error) confirmOrder();
مرجع سريع

📋 قوائم النسخ الفورية

كل ما تحتاجه جاهزاً للنسخ بضغطة واحدة — ابدأ مشروعك الآن

🏗️ كل وسوم HTML التي ستستخدمها
<!DOCTYPE html>إلزامي — السطر الأول دائماً يخبر المتصفح أن هذا HTML5
<html lang="ar" dir="rtl">جذر الصفحة مع اللغة العربية والاتجاه
<meta charset="UTF-8">دعم العربية والحروف الخاصة — إلزامي
<meta name="viewport">موقع يعمل صح على الموبايل — إلزامي
<title>اسم الصفحة</title>عنوان تبويب المتصفح ونتائج جوجل
<link rel="stylesheet" href="">ربط ملف CSS خارجي
<h1> إلى <h6>العناوين — h1 مرة واحدة فقط في الصفحة
<p>فقرة</p>فقرة نصية — الأكثر استخداماً
<a href="" target="_blank">رابط — href الوجهة، target="_blank" تبويب جديد
<img src="" alt="">صورة — alt إلزامي للـ SEO وإمكانية الوصول
<div class="">حاوية block — لتجميع العناصر
<span class="">حاوية inline — داخل النص
<ul> <ol> <li>قوائم — ul نقاط، ol أرقام
<strong> <em> <mark>غامق، مائل، مظلل — تنسيق النص
<form action="" method="post">نموذج — action الوجهة، method طريقة الإرسال
<input type="text">أنواع: text, email, password, number, tel, date, file, checkbox, radio
<textarea rows="4">نص متعدد الأسطر
<select> <option>قائمة منسدلة
<button type="submit">زر — submit إرسال، reset مسح، button برمجي
<label for="">تسمية الحقل — for يربطها بـ id الحقل
<table> <thead> <tbody> <tr> <th> <td>جدول كامل
<video src="" controls>فيديو — controls, autoplay, muted, loop, poster
<audio src="" controls>مشغل صوت
<iframe src="">تضمين — يوتيوب، خرائط جوجل، مواقع
<header> <nav> <main> <section> <article> <aside> <footer>الوسوم الدلالية — لـ SEO وجوجل
<details> <summary>Accordion بدون JavaScript
<script src=""></script>ربط ملف JavaScript — في آخر body دائماً
🎨 CSS — الخصائص الأكثر استخداماً
color: #333لون النص
background: #fffلون الخلفية أو تدرج
font-size: 1remحجم الخط — rem, px, clamp()
font-weight: 700وزن الخط — 100 إلى 900
padding: 16pxمسافة داخلية
margin: 0 autoتوسيط أفقي
border-radius: 8pxتدوير الزوايا — 50% للدائرة
box-shadow: 0 4px 16px...ظل العنصر
display: flexتفعيل Flexbox
display: gridتفعيل Grid
position: fixedثابت في الشاشة عند التمرير
transition: all .3s easeانتقال سلس عند hover
transform: translateY(-4px)تحريك عند hover
@media (min-width: 768px)Responsive — تغيير حسب الشاشة
:root { --color: #007bff }CSS Variables للثيم
width: min(100%, 1200px)Container متجاوب
⚡ JavaScript — الأوامر اليومية
querySelector("#id")اختيار عنصر بالـ id أو الكلاس
querySelectorAll(".cls")اختيار كل العناصر
el.textContent = "نص"تغيير النص
el.innerHTML = "<b>"تغيير HTML داخل العنصر
el.classList.toggle("cls")يضيف أو يحذف كلاس
addEventListener("click", fn)استماع للأحداث
arr.map(x => ...)تحويل كل عنصر في المصفوفة
arr.filter(x => cond)تصفية المصفوفة بشرط
arr.find(x => cond)البحث عن أول عنصر
JSON.stringify / parseتحويل بين كائن ونص JSON
localStorage.setItemحفظ بيانات محلياً
async / await / fetchجلب بيانات من API
خطتك

🗺️ خارطة الطريق — من الصفر للاحتراف

خطوات مرتبة بالتسلسل الصح مع وقت تقديري

📌 القاعدة الذهبية: تعلم شيئاً صغيراً ثم طبّقه فوراً. لا تقرأ ساعات بدون تطبيق. كل درس = مشروع صغير تبنيه.
المرحلة 1 — أساس
HTML + CSS — بناء الواجهة
وسوم HTML، CSS الأساسي، Flexbox، Grid، التصميم المتجاوب.
مشاريع: صفحة Landing Page، CV رقمي، موقع مطعم بسيط.
⏱️ 4–6 أسابيع (ساعتان يومياً)
🏗️
المرحلة 2 — تفاعل
JavaScript الأساسي
المتغيرات، الدوال، DOM، الأحداث، LocalStorage.
مشاريع: قائمة مهام (Todo App)، آلة حاسبة، ساعة رقمية.
⏱️ 6–8 أسابيع
المرحلة 3 — بيانات حقيقية
JS المتقدم + Fetch APIs + Git
Fetch API، async/await، JSON، REST APIs، Git وGitHub.
مشاريع: تطبيق طقس، قائمة أفلام من API حقيقي، موقع أخبار.
⏱️ 4–6 أسابيع
🌐
المرحلة 4 — Framework
React.js
Components، Props، State، Hooks، React Router، Context API.
مشاريع: متجر بسيط، لوحة إدارة، تطبيق ملاحظات.
⏱️ 8–10 أسابيع
⚛️
المرحلة 5 — Backend
Node.js + قاعدة بيانات
Node.js، Express، MongoDB أو PostgreSQL، JWT، REST API.
مشاريع: API كاملة للمدونة، نظام تسجيل وتسجيل دخول.
⏱️ 10–12 أسبوع
🗄️
المرحلة 6 — احتراف
Full Stack + النشر على الإنترنت
Next.js، Docker، CI/CD، استضافة مجانية Vercel وRailway.
المشروع النهائي: تطبيق كامل منشور على الإنترنت = Portfolio حقيقي!
⏱️ مستمر
🚀
✅ افعل دائماً:
ابنِ مشروعاً بعد كل درس. شارك كودك على GitHub. اسأل جوجل عن كل خطأ. الخطأ أفضل من مشاهدة الحل.
❌ تجنب:
تعلم لغتين في نفس الوقت. نسخ الكود بدون فهم. الانتظار حتى "تجهز" قبل التطبيق. إهمال الأساسيات.
💡 تذكر:
فيسبوك بدأت بـ PHP بسيط. جوجل كانت مشروع بحث. كل مطور محترف كان يوماً مبتدئاً مثلك تماماً.