اذهب إلى المحتوى

Mustafa Mahmoud7

الأعضاء
  • المساهمات

    676
  • تاريخ الانضمام

  • تاريخ آخر زيارة

  • عدد الأيام التي تصدر بها

    1

كل منشورات العضو Mustafa Mahmoud7

  1. يمكنك التحكم في مستوى التقريب لمحتوي للموقع بالكامل عن طريق الضغط في لوحة المفاتيح على:- للوضع الافتراضي Ctrl + 0 لتكبير الحجم (zoom in) + + Ctrl لتصغير الحجم (zoom out) - + Ctrl عن طريق التحكم في مستوى التقريب تستطيع اختيار الوضع المناسب لك.
  2. تأكد من قيامك برفع الملفات الصحيحة للإستضافة وعملية الإعدادت للإستضافة تكون صحيحة حيث هذه الرسالة تشير إلى أن ملفات المشروع غير موجودة بالأساس حيث يجب عليك رفع الملفات الناتجة من عملية البناء فقط، أي الملفات بداخل مجلد الـ build أو dist النهائي فقط، وهو المجلد الذي يتم به تجميع الكود النهائي للمشروع ليصبح جاهز للنشر.
  3. الأكاديمية تعمل دائماً على تحديث وتطوير دوراتها لتتوافق مع احتياجات سوق العمل وأحدث التقنيات المتاحة. الدورات الحالية يتم مراجعتها وتحديثها بشكل منتظم عند الضرورة لضمان أنها تعكس آخر المستجدات. بالنسبة لإضافة دورات جديدة، فإن ذلك يعتمد على عدة عوامل مثل حجم الطلب عليها ومدى حاجة السوق لها، بالإضافة إلى فرص التوظيف المتاحة سواء في الشركات أو في العمل الحر. القرار في هذا الأمر يعود إلى إدارة الأكاديمية، ويمكنك متابعة أي جديد من العمل على أي دورات جديدة أو يتم تحديث دورات حالية عن طريق التحدث إلي مركز المساعدة من هنا. وعند نزول أي دورات جديدة تظهر في دورات تعليمية.
  4. نقوم بتتبع سبب الخطأ نلاحظ أن هذه الرسالة تأتي من ملف middleware\auth.js حيث يوجد خطأ في الكتلة try بسبب فشل في عملية فك التشفير للـ token حيث يوجد خطأ إملائي في كتابة مفتاح التشفير const decoded = jwt.verify(token, process.env.JWT_SECRET); ^^^^^^^^^^ فهو غير موجود في ملف env. والموجود هو JWT_SECURT نقوم بالتعديل ليصبح هذا السطر كالأتي const decoded = jwt.verify(token, process.env.JWT_SECURT); بعد ذلك سيعطي الرسالة Access denied. You do not have the required role لأنه عند عملية تسجيل الدخول يتم إنشاء الرمز المميز في ملف controllers\authcontoller.js سطر 48 const token = jwtHelpers.sign({ id: user._id, email: user.email }); ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ يتكون الرمز من الـ id ، email ولكن الـ role غير موجودة فعند فك هذا الرمز لا يوجد role إذا نقوم بتعديل هذا السطر ليصبح كالأتي const token = jwtHelpers.sign({ id: user._id, email: user.email, role: user.role }); الآن عند عملية تسجيل الدخول يتم إنشاء الرمز المميز يتكون الرمز من الـ id ، email ، role. بعد ذلك في برنامج بوست مان قومي بتسجيل الدخول من جديد ونسخ token ووضعه في headers تحت مفتاح authorization وسيتم إنشاء الإعلان.
  5. ستجد أسفل فيديو الدرس في نهاية الصفحة صندوق تعليقات كما هنا، أرجو طرح الأسئلة أسفل الدرس وليس هنا في قسم الأسئلة البرمجة حيث نطرح الأسئلة العامة الغير متعلقة بمحتوى الدورة أو الدرس، وذلك لمساعدتك بشكل أفضل.
  6. يمكنك إرسال الصورة التي تظهر معك أو الخطأ لمعرفة النتيجة أو يمكنك إرسال عنوان AnyDesk على الرسائل للدخول على جهازك وإنجاز هذا الأمر.
  7. كيف اعرفها ؟ ليس لدي خبرة بها بالنسبة لهذا الأمر يوجد ثلاث معايير يتم التركيز عليهم ويتم ذكر مواصفات الشاشة ضمن المواصفات أن يكون النوع IPS وفي حالة كان الجهاز الذي ستقوم بشراءه اصدار حديث ستكون الشاشة من هذا النوع وتعتبر لوحات IPS (In-Plane Switching) من أفضل اللوحات من حيث الألوان وزوايا المشاهدة، وهي خيار ممتاز لمصممي الجرافيك. sRGB Coverage: هذه النسبة تشير إلى مدى قدرة الشاشة على عرض نطاق الألوان القياسي (sRGB). إذا كانت الشاشة تغطي 100% من sRGB، فهذا يعني أن الألوان ستكون دقيقة وزاهية ويوجد أنواع أقل من %100 مثل 62.5% وهي ليست سيئة بالطبع بل جيدة جدا ولكن الأفضل بالنسبة للتصميم أن تكون %100. التردد HZ هو مقياس لعدد المرات التي يتم فيها تحديث الصورة على الشاشة في الثانية الواحدة، ويُقاس بالهرتز (Hz). التردد يؤثر على سلاسة العرض وتجربة المشاهدة، وله تأثير كبير على الراحة البصرية، خاصة إذا كنتِ تعملين أو تلعبين على الشاشة لفترات طويلة . التردد 60Hz هو الحد الأدنى لمعظم الشاشات. يوفر سلاسة كافية للمهام اليومية مثل التصفح ومشاهدة الفيديو. التردد 120Hz أو 144Hz: يوفر تجربة عرض أكثر سلاسة، مما يمكن أن يكون مفيدًا في الألعاب والأعمال التي تتطلب حركة سلسة وسريعة. يقلل من التقطيع والاهتزازات يكون التردد 120HZ كافي جدا جدا في حالة لا تستخدمى اللاب توب في الألعاب التي بها حركة سريعة أو تشاهدي فيديوهات بها حركات سريعة جدا . تقنية "Flicker-Free" تعني أن الشاشة خالية من الوميض الذي قد يكون غير مرئي بالعين المجردة ولكنه قد يتسبب في إجهاد العين والصداع، خاصة للأشخاص الذين يعانون من حساسية للضوء. عند البحث عن شاشةاللابتوب، يمكنك العثور على هذه المعلومة في قسم المواصفات تحت مسمى "Flicker-Free" أو "Anti-Flicker Technology" وأحيانا لا يتم ذكرها بشكل مباشر، فعليك بالبحث عن المراجعات عنها على الانترنت بعض المراجعين يختبرون هذا الأمر ويذكرونه. ولكن يجب أخذ فترات راحة 5 دقائق على الأقل كل ساعة لا تزيدي عن ساعة أمام الشاشة لإراحة عينيك والتمشية داخل الأوضة مثلا والنظر إلى أشياء بعيدة مع فتح العينين و إغماضها بشكل متكرر حتى لا يحدث لكي جفاف للعينين.
  8. التكلفة ماك: أجهزة ماك أغلى من أجهزة ويندوز المطابقة معها في المواصفات. ويندوز: متوفر بمجموعة متنوعة من الأسعار من الأجهزة متوسطة التكلفة إلى الأجهزة باهظة الثمن. الأداء والاستقرار ماك: مستقر ويقدم أداءً ممتازًا خاصة في المهام المتعلقة بتحرير الفيديو والتصميم الجرافيكي. ويندوز: أكثر انتشارًا ويعتمد الأداء على مواصفات الجهاز. التطبيقات المتاحة ماك: عدد التطبيقات المتاحة أقل من ويندوز، لكنها تحتوي على تطبيقات عالية الجودة للتصميم والإبداع. ويندوز: عدد التطبيقات المتاحة أكبر بكثير بما في ذلك الألعاب والبرامج التجارية بما في ذلك برنامج السوني فيغاس. هذا البرنامج بالخصوص يعمل مع نظام ويندوز فقط ،إذا كنتِ تعتمدين بشكل كبير على سوني فيغاس، فقد تحتاجين إلى البقاء على نظام Windows أو البحث له عن بدائل في ماك. لإختيارك لجهاز ذو إمكانيات ممتازة يمكنك البحث على الإمكانيات الموصى بها لأكثر برنامج الآن تعملين عليه وتحتاجينه بشكل يومي. في حالة تنوين الإستكمال بهذا الجهاز لعدد سنين قادمة وتستخدميه في عملك الإحترافي يمكنك إختيار الأتي: معالج من شركة Intel ويكون core i5 من الأصدارات الحديثة من الجيل 11 فما فوق ذلك مع التدقيق على ألا يكون الحرف في نهاية الاسم النوع u فهذا المعالج موفر للطاقة ولا يعطي أفضل أداء أو ما يعادل هذا المعالج من شركات أخرى مثل AMD. كارت شاشة من نيفيديا من سلسلة 2000 فما فوق مع أن تكون المساحة لا تقل عن 4 جيجبايت وكلما زادت المساحة يكون أفضل أو ما يعادلها من شركات أخرى مثل AMD. رام 16 جيجابايت لتستطيعى إدارة الكثير من المهام المتعددة في نفس الوقت ويستحسن أن تكون من النوع السريع DDR5. هذا في حالة استعدادك من الناحية المالية يمكنك التخفيض من الناحية المالية مع التخفيض من الإمكانيات طبعا الإختيارات عديدة جدا ولكن أنا قمت بالإرشاد لجهاز تعتمدين عليه أقل شئ 5 سنوات للعمل في مجال التصميم و البرمجة. أهم شئ التركيز على القطع التي لا تستطيعي استبدالها مثل المعالج وكارت الشاشة والشاشة نفسها من ناحية الألوان وتشبعها، أما من ناحية الرامات ووحدة التخزين في معظم الأحيان يمكنك الترقية لها بعد ذلك واحرصي على اختيار لابتوب يدعم هذا الأمر حيث يوجد بعض الأجهزة لا يمكنك ترقية الرامات فيها.
  9. اضغط على المساحة الغير مخصصة بزر الفأرة الأيمن وقم بإتباع الخطوات كما في التعليق الأول. إذا لم ينجح الأمر معك يمكنك إرسال عنوان AnyDesk على الرسائل للدخول على جهازك وإنجاز هذا الأمر.
  10. المساحة التي باللون الأحمر هي المساحة الغير مخصصة يرجى اتباع الخطوات الموجودة في التعليق الأول وستظهر لك
  11. الظاهر في الصورة أن كل المساحة الموجودة في القرص 1 هي مساحة C ولا توجد مساحة أخرى بالاسم D هل تريد أن تخصص جزء جديد أم ماذا ؟
  12. شرائك للابتوب بعينه يخضع لإحتياجات وتفضيلاتك الشخصية وهل أنت في بداية تعلم للبرمجة أم أنك تعملي في هذا المجال بالفعل، إذا كنتِ في بداية تعلمك للبرمجة المواصفات المطلوبة ليعمل اللاب توب على عدة برامج وبيئات مختلفة بسلاسة وشكل سريع ليست مرتفعة يمكنك البداية بهذه المعالج (CPU): يفضل أن يكون من الجيل الأحدث والمتطورة وبعدد أنوية كافٍ لتعدد المهام (مثل Intel i5 أو AMD Ryzen 5 وما فوق) والتي توفر أداءً سريعًا وفعالا لتشغيل البرامج. الذاكرة العشوائية (RAM): لا تقل عن 8 جيجابايت لتشغيل بعض الأدوات في ذات الوقت ويفضل 16 جيجابايت لكي تعمل الأدوات الثقيلة وتعدد المهام بسلاسة. التخزين: استخدام SSD بدلاً من HDD لزيادة سرعة قراءة وكتابة البيانات. سعة 512 جيجابايت أو أكثر تكون جيدة. كرت الشاشة (GPU): إذا كنتِ تعملي على التصميم الجرافيكي وذلك في حال التعامل مع برامج مثل الفوتوشوب بشكل مكثف أو تطوير الألعاب، فإن وجود كرت شاشة منفصل بدلا من الكارت المدمج بالمعالج به مساحة خاصة به هو الأفضل، لكن ليس ضرورياً النسبة للبرمجة. حجم الشاشة : شاشة بحجم 15.6 بوصة تعتبر مناسبة لمعظم الأعمال، ولكن إذا كنت تفضل شاشة أكبر للعمل على التصميمات، يمكنك اختيار شاشة أكبر. يمكنك الإطلاع أيضا على هذه النقاشات به بعض المعلومات أيضا
  13. الأمر لا يختلف في النهاية سيتم فتح حسابك بأي ايميل منهم والدخول لحسابك في حسوب ومنه إلي أي حساب أخر مثل حسابك في الأكاديمية أو مستقل أو خمسات أو أي موقع أخر تابع لحسوب أي يصبح حساب واحد ولكن له أكثر من ايميل للدخول به.
  14. بالنسبة للوحدة الأولى للتخزين منفصلة تمامًا عن الوحدة الثانية فلا تستطيع دمج أي مساحة مع الأخرى. لكن يمكنك دمج المساحة 8 جيجا مع الـ C مع ملاحظة أن هذه العملية تأخذ بعضا من الوقت للإكتمال يرجى التأكد من اتصال الجهاز الخاص بك بالكهرباء حتى لا تتلف الملفات بالـ C والنظام بالكامل سيحصل به عطل وتحتاج لتثبيت النظام من جديد في حالة انقطاع الكهرباء عن الجهاز. يمكنك دمج المساحة 8 جيجا مع الـ C عن طريق الضغط بزرة الفأرة الأيمن على الـ C ستظهر لك هذه القائمة اختر منها Extend Volume أي تمديد للحجم ستظهر لك نافذة اضغط على next ستظهر لك نافذة جديدة ومحدد بها الحجم المتاح للتمديد اضغط next ثم finish وستتم العملية.
  15. لنقوم بتتبع هذا الخطأ { "error": "jwtHelpers.sign is not a function" } يخبرنا أن الدالة ()jwtHelpers.sign هي غير دالة أو لا يستطيع التعرف عليها لماذا ذلك نذهب لملف jwtHelpers.js ونرى ما بداخله هل sign هذه عبارة عن دالة أم ماذا exports.sign = (payload) => { return jwt.sign(payload,secret,{expiresIn}) } هي بالفعل دالة ولا مشكلة فيها إذا الخطأ أين لاحظي باقي الأكواد في الملف ولاحظي عملية التصدير const jwt = require('jsonwebtoken') const { token } = require('morgan') const secret = process.env.JWT_SECURT const expiresIn = process.env.JWT_EXPIRES_IN const generateToken = (payload) => { return jwt.sign(payload, secret, { expiresIn }); }; exports.sign = (payload) => { ^^^^^^^^^^^^ return jwt.sign(payload,secret,{expiresIn}) } exports.verify = (token) => { ^^^^^^^^^^^^^^ try { return jwt.verify(token,secret,) } catch (e) { return false } } module.exports = { ^^^^^^^^^^^^^^ generateToken, }; هناك تداخل بين طريقتين للتصدير في الكود في ملف واحد، يتم استخدام module.exports و exports، وهذا يسبب مشاكل لتجنب الأخطاء، يُفضّل استخدام طريقة واحدة فقط للتصدير وأيضا الدالة generateToken تؤدي نفس وظيفة الدالة sign يمكنك إزالتها. نقوم بالتعديل ونستخدم أول طريقة للتصدير كالتالي const jwt = require('jsonwebtoken'); const secret = process.env.JWT_SECRET; const expiresIn = process.env.JWT_EXPIRES_IN; const generateToken = (payload) => { return jwt.sign(payload, secret, { expiresIn }); }; const sign = (payload) => { return jwt.sign(payload, secret, { expiresIn }); }; const verify = (token) => { try { return jwt.verify(token, secret); } catch (e) { return false; } }; module.exports = { generateToken, sign, verify }; قمنا بالتعديل وتجميع كل الدوال وتصديرها دفعة واحدة. أو يمكنك استخدام الطريقة الثانية كالتالي const jwt = require('jsonwebtoken'); const secret = process.env.JWT_SECRET; const expiresIn = process.env.JWT_EXPIRES_IN; exports.generateToken = (payload) => { return jwt.sign(payload, secret, { expiresIn }); }; exports.sign = (payload) => { return jwt.sign(payload, secret, { expiresIn }); }; exports.verify = (token) => { try { return jwt.verify(token, secret); } catch (e) { return false; } }; قمنا باستخدام exports لكل دالة تريدي تصديرها. يمكنك الإختيار بين الطريقتين أي طريقة منهم متاحة للاستخدام.
  16. يوجد لديك وحدتين للتخزين متصلة بالجهاز الوحدة الأولى غير مخصصة بالكامل والوحدة الثانية يوجدة بها 8 جيجا غير مخصصين يمكنك التخصيص لأي مساحة تريد كما ذكرت في التعليق السابق بالخطوات.
  17. في البحث الخاص بك في ويندوز قم بالبحث عن Disk Mangement واختر منها الاختيار create and format hard disk partitions بعد الفتح ستجد أقراص غير مخصصة unallocate نقوم بتخصيصها قم بالضغط عليها بزر الفأرة الأيسر ثم أختر new simple volume ستفتح نافذة معك اختر next بعد ذلك ستظهر نافذة جديدة لتحديد حجم القرص الجديد الذي تريده من المساحة المتبقية يمكنك كتابته بالميجابايت حيث الجيجابايت تساوى ألف ميجابايت ثم اضغط next بعد ذلك ستظهر لك نافذة يمكنك اختيار حرف مميز للقرص يمكنك الإختيار من المتاح منهم ثم اضغط next ستظهر لك هذه النافذة يمكنك الإختيار مابين نوع الملفات NTFS وأنواع أخرى يمكنك تركها NTFS ويمكنك كتابة اسم القرص (Volume label) ثم اضغط next شتظهر لك هذه النافذة بها كل المعلومات حول تخصيصاتك لهذا القرص اضغط Finish ستجد أنه تم إنشاء القرص الجديد بالتخصيصات التي حددتها.
  18. يمكنك عمل حاوية parent وبها العنصر p الخاص بالنص <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <link href="style.css" rel="stylesheet" /> </head> <body> <div class="parent"> <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Sequi, obcaecati nam. Adipisci quo at reprehenderit,dolorum inventore magni et quibusdam corporis esse commodi, consectetur molestiae, illo similique eos iste sunt. </p> </div> </body> </html> ثم للحاوية الأب لكل العناصر التي بها الصنف parent نقوم بإعطائها خاصية الـ flex و justify-content: center و align-items: center ليتم توسيط العناصر داخل الحاوية رأسيًا وأفقيا لتكون التنسيقات كالأتي .parent { display: flex; justify-content: center; /* محاذاة العناصر أفقيًا في المتتصف */ align-items: center; /* محاذاة العناصر رأسيًا في المتتصف */ height: 100vh; } p { padding: 30px; width: 800px; background-color: rgb(227, 179, 147); } ويكون للعنصر p الخاص بالنصوص عرض معين لا يتجاوزه وستكون النتيجة كالأتي لاحظ تم توسيط العناصر رأسيا وأفقيا بداخل عنصر الأب والذي إرتفاعه كامل إرتفاع الصفحة. يمكنك الإطلاع على هذا المقال حول خاصية Flexbox والاستخدام الصحيح لها في المرات القادمة إذا كان هذا السؤال تابع للدورات ستجد أسفل الدرس صندوق للتعليقات كما هنا، من فضلك يرجي طرح الأسئلة هناك حيث هنا هو قسم الأسئلة العامة ولا نقوم بالإجابة بالأسئلة الخاصة بالدورات هنا وذلك لمعرفة الدرس الذي تريد الإستفسار عنه و مساعدتك بشكل أفضل.
  19. في المرات القادمة ستجد أسفل فيديو الدرس في نهاية الصفحة صندوق تعليقات كما هنا، أرجو طرح الأسئلة أسفل الدرس وليس هنا في قسم الأسئلة البرمجة حيث نطرح الأسئلة العامة الغير متعلقة بمحتوى الدورة أو الدرس، وذلك لمساعدتك بشكل أفضل. لإنشاء مشروع جديد قم بفتح شريط الأوامر على مجلد المشروع ثم ضع الأمر npm init وضع الأسماء التي تريدها من اسم المشروع والإصدار وصاحب المشروع ثم اضغط Enter بعد كتابتك لهم أو يمكنك عدم كتابة أي شئ اضغط Enter لكل الخيارات ستجد أنه تم إنشاء الملف package.json. ثم لتثبيت الحزمة express استخدم الأمر npm i express
  20. في المتحكم register بتشفير كلمة المرور عن طريق هذا السطر // تشفير كلمة المرور const hashedPassword = await bcrypt.hash(password, 10); ولكن أيضا في models\user.js في هذه الدالة ()userSchema.pre userSchema.pre('save', async function (next) { if (!this.isModified('password')) return next(); const salt = await bcrypt.genSalt(10); this.password = await bcrypt.hash(this.password, salt); next(); }); تقومي بالتشفير مرة أخري لكلمة المرور قبل الحفظ في قاعدة البيانات وعند تعديل كلمة المرور، أي يتم تشفير كلمة المرور مرتين عند عملية التسجيل لذا نقوم بتعديل المتحكم register ليكون بهذا الشكل exports.register = async (req, res) => { try { // استخراج البيانات من الطلب const { name, email, password, role } = req.body; // إنشاء مستخدم جديد const newUser = new User({ name, email, password, role, }); // حفظ المستخدم في قاعدة البيانات await newUser.save(); res.status(201).json(newUser); } catch (err) { res.status(400).json({ error: err.message }); } }; قمنا بإزالة عملية التشفير في المتحكم وسيتم التشفير مرة واحدة فقط من خلال الدالة ()userSchema.pre الموجودة في models\user.js. بعد ذلك في المتحكم login تقومي بإستدعاء الدالة generateToken من jwtHelpers وهي غير موجودة في هذا الملف const token = jwtHelpers.generateToken(user._id); نقوم بتعديل هذا السطر const token = jwtHelpers.sign({ id: user._id, email: user._email }); واستخدام الدالة ()sign وهي الموجودة في jwtHelpers ليتم إنشاء رموز JWT من خلال إرسال الإيميل والـ id للمستخدم وحفظ الرمز في token، بعد ذلك عليكي بتسجيل المستخدم من جديد وتسجيل الدخول بنفس المستخدم وستكون النتيجة في بوست مان كالأتي { "success": true, "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjY2YmI3N2U3NzFkZGE0NTI0NjY3YzFiMCIsImlhdCI6MTcyMzU2MjgzNSwiZXhwIjoxNzIzNTcwMDM1fQ.kgqAcpEGjtGPmSX4aiCQHwHI3-UGTrbVZyOdGDLAAEY" } تم تسجيل الدخول بنجاح وإرسال الرمز.
  21. توجه إلى مركز المساعدة والتحدث معهم من هنا . وطلب التقدم للإمتحان مع تقديم المشاريع لهم وسيتم تحديد موعد للإمتحان بعد مراجعة المشاريع الخاصة بك.
  22. هذا الخطأ يشير أنه عند الإتصال لا يوجد رابط قاعدة بيانات للإتصال بها في الدالة ()mongoose.connect من الممكن أن يكون السبب أنه تقومي بتشغيل ملف app.js عن طريق nodemon ولا يتم قراء المتغيرات من الملف env. بصورة صحيحة mongoose.connect(process.env.DB_URL) لذا قومي بتشغيل المشروع من خلال الملف bin\www كالأتي nodemon ./bin/www وإذا لم يكن nodemon مثبت يمكنك تثبيته علي الجهاز كالأتي npm install -g nodemon ثم التشغيل من جديد nodemon ./bin/www وسيعمل الخادم معك. ويمكنك وضع سكربت في في ملف package.json وتعديل هذا الأمر "scripts": { "start": "node ./bin/www" }, ليصبح كالأتي "scripts": { "start": "nodemon ./bin/www" }, وتشغيل المشروع عبر الأمر npm start
  23. الصورة من بوست مان تشير أن الخادم لا يعمل قومي بتشغيله عن طريق الأمر npm start ويوجد مشكلة في ملف routes\auth.js حيث كل المسارات توجه إلى المتحكم login router.post('/login', authController.login) ^^^^^ router.post('/register', authController.login) ^^^^^ router.post('/logout', authController.login) ^^^^^ نقوم بالتعديل ليكن كل مسار يوجه للمتحكم الخاص به ليصبح كالأتي router.post('/login', authController.login) router.post('/register', authController.register) router.post('/logout', authController.logout) يوجد أيضا تكرار في ملف controllers\authcontoller.js للمتحكم register exports.register = async (req, res) => { try { const newUser = new User(req.body); await newUser.save(); res.status(201).json(newUser); } catch (err) { res.status(400).json({ error: err.message }); } } exports.register =async (req, res) => { res.json({ success:true }) }; نقوم بمسح المتحكم الثاني المكرر ليتم إنشاء المستخدم بصورة صحيحة. بعد هذه التعديلات قومي بعملية الحفظ للملفات عن طريق الضغط علي Ctrl + s في لوحة المفاتيح، وإعادة تشغيل الخادم من جديد عن طريق الأمر npm start ويمكنك إرسال الطلبات من بوست مان سيتم إنشاء المستخدم.
  24. ما قمتي به بمفردك مجهود جيد جدا من طريقة التقسيم والهيكلية للمجلدات وفصل كل شئ لكي تقوم كل مجموعة من الملفات بالقيام بشئ مخصص بها من أن يكون تعريف مجموعة النماذج في مجلد خاص بها والمسارات أيضا نفس الشئ. قمت بالإختبار لإنشاء مستخدم جديد في ملف models\user.js يبدو أنه نسيتي الإستيراد للحزمة bcrypt بالإضافة أنه وضعتي في تعريف النموذج أن يكون الاسم unique : true أي لا يتم تكرار نفس الاسم لأي مستخدم أخر في مجموعة المستخدمين ولكن الأفضل أن يتم تكرار الاسم لا مشكلة في ذلك فقط نريد الاميل أن يكون مميز وفريد غير قابل للتكرار ليكون ملف models\user.js نقوم بإضافة تعريف المكتبة أعلي الملف كالأتي ونمسح ,unique: true من الاسم const bcrypt = require('bcrypt'); أيضا عند عملية التسجيل نريد أن نضع مسار له ليصبح في ملف routes\users.js بداية سطر 10 كالأتي router.post('/register', async (req, res) => { try { const newUser = new User(req.body); await newUser.save(); res.status(201).json(newUser); } catch (err) { res.status(400).json({ error: err.message }); } }); لأنه سوف نقوم بعمل متحكم أخر لتسجيل الدخول بعد هذه التعديلات يمكنك إرسال طلب من برنامج بوست مات لتسجيل مستخدم جديد يكون نوع الطلب POST والمسار له. http://localhost:3000/api/users/register وجسم الطلب في بوست مان يكون كالأتي { "name": "mostafa", "email": "mostafa@gmail.com", "password": "123456", "role":"customer" } ستجدي أنه تم تسجيل مستخدم جديد بدون مشكلة يمكنك تجربة طريقة أفضل ولكن سنقوم ببعض التعديلات، الأفضل بدلا من تعريف المتحكم مباشرة بعد المسار يمكنك نقل كود المتحكم داخل المتحكم reigister بداخل ملف المتحكمات controllers\authcontoller.js ليصبح المتحكم register كالأتي exports.register = async (req, res) => { try { const newUser = new User(req.body); await newUser.save(); res.status(201).json(newUser); } catch (err) { res.status(400).json({ error: err.message }); } } إذا اخترتي الاستمرار في هذه الطريقة يمكنك المتابعة بعد ذلك في ملف routes\auth.js يوجد خطأ في التوجيه وكتبتي نقطة ( . )بدلا ( , ) وتم كتابة أسماء المتحكمات في كل الحالات login // مسارات التسجيل وتسجيل الدخول router.post('/login'.authController.login) ^ ^^^^^^ router.post('/register'.authController.login) ^ ^^^^^ router.post('/logout'.authController.login) ^ ^^^^^ نقوم بالتعديل ليصبح بهذا الشكل // مسارات التسجيل وتسجيل الدخول router.post('/login', authController.login) router.post('/register', authController.register) router.post('/logout', authController.logout) وفي ملف app.js نقوم بتعريف authRouter وطلب الملف const authRouter = require('./routes/auth'); ثم التوجيه له في سطر 27 بدلا من التوجيه إلي usersRouter نقوم بالتوجيه إلى authRouter كالأتي app.use('/api/users', authRouter); كلا الطريقتين متاحتين يمكنك إنشاء متحكمات منفصلة لكل مسار له متحكمات خاصة به أو بعد كتابة المسار كتابة كود المتحكم بصورة مباشرة كما في الطريقة الأولى. إذا واجهتك أي مشكلة أخرى يمكنك السؤال بها مع توضيحها بشكل مفصل لكي يتم مساعدتك بصورة أسرع وأفضل.
  25. إذا كان هذا السؤال خاصة بأحد دروس الأكاديمية، في المرات القادمة ستجد أسفل فيديو الدرس في نهاية الصفحة صندوق تعليقات كما هنا، أرجو طرح الأسئلة أسفل الدرس وليس هنا في قسم الأسئلة البرمجة حيث نطرح الأسئلة العامة الغير متعلقة بمحتوى الدورة أو الدرس، وذلك لمساعدتك بشكل أفضل. وضعك لفاصلة منقوطة نهاية شرط while يقوم بإيقاف هذه الحلقة ولا يتم تنفيذ ما بداخلها إلا مرة واحدة فقط وتتوقف عن التكرار let i = 1; while (i <= 10); ^ { if (102 === 0) { console.log(i); } i++; } لابد أن تكون بهذا الشكل بدون هذه الفاصلة المنقوطة ليتم التكرار let i = 1; while (i <= 10) { if (102 === 0) { console.log(i); } i++; } أيضا هذا الشرط if (102 === 0) مستحيل تحقيق هذا الشرط فلا يتم ما بداخله أبدًا فـ 102 مستحيل أن تساوي 0 ، أعتقد أنك تريد طباعة الأرقام الزوجية فقط ليصبح هذا الشرط متغير بناءا علي تغيير قيمة i في كل مرة ويكون الشرط كالأتي if (i % 2 === 0) أي أن باقي قسمة الرقم علي 2 تساوي صفر ليكون الكود بالكامل كالأتي let i = 1; while (i <= 10) { if (i % 2 === 0) { console.log(i); } i++; } والنتيجة له طباعة الأرقام الزوجية مابين 1 و 10 2 4 6 8 10 تأكد أيضا من ربط لملف جافا سكربت مع html بصورة صحيحة <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <script src="index.js"></script> </body> </html>
×
×
  • أضف...