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

Mustafa Suleiman

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

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

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

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

    495

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

  1. مكتبة جافاسكريبت خاصة بإنشاء عروض شرائح أي الـ sliders والشرائح الدوارة carousels بشكل تفاعلي ومتجاوبة، وتم تصميمها بشكل أساسي لتوفير أفضل تجربة على الأجهزة التي تعمل باللمس مالهواتف الذكية والأجهزة اللوحية. وهي مستخدمة في غالبية المواقع تقريبًا، لكونها خفيفة وبدون تبعيات، بمعنى أنها لا تعتمد على مكتبات أخرى مثل jQuery، وذلك يجعلها سريعة وخفيفة على أداء الموقع. وتوفر مجموعة واسعة من تأثيرات الانتقال بين الشرائح، وعناصر تحكم متعددة، بجانب ميزة مهمة لتحسين أداء الصفحة، حيث يتم تحميل الصور فقط عندما تقترب الشريحة من العرض، بدلاً من تحميلها كلها مرة واحدة. وباستطاعتك تعديل كل جانب من جوانب الـ Slider تقريبًا عبر الـ API الخاصة بها أو من خلال CSS. ستجد أمثلة هنا: https://swiperjs.com/demos
  2. بالضبط لتحديد الصفحة النشطة حاليًا وإضافة كلاس active إليها، حيث NavLinks.map() تقوم بالمرور على كل عنصر في مصفوفة NavLinks لإنشاء قائمة <li> لكل رابط. و className={ } لكل عنصر <li> في القائمة، لتحديد قيمة الكلاس className بشكل ديناميكي. والشرط location.pathname === item.link ? 'active' : '' هو الجزء الأهم هنا، فهو تعبير شرطي ثلاثي يقوم بالآتي: location.pathname === item.link تعني هل مسار URL الحالي الذي حصلت عليه من useLocation يطابق تمامًا رابط ذلك العنصر item.link الذي يتم عرضه حاليًا في الحلقة؟ ? 'active' ولو الإجابة نعم أي True فالمساران متطابقان، ويتم إعطاء العنصر <li> الكلاس active. وهنا ' ' : تعني كانت لو الإجابة لا False فالمساران غير متطابقين، ولن يتم إضافة أي كلاس بل سلسلة نصية فارغة.
  3. يجب توحيد المعايير بمعنى structure موحد للـ API كالتالي: /api/v1/users: get: summary: جلب قائمة المستخدمين parameters: - page - limit responses: 200: Success 401: Unauthorized وإعتماد API-First Designأي تصميم الـ API قبل البرمجة ومراجعة التصميم مع فريق العمل. كذلك استخدم Versioning واضح، بمعنى إدارة الإصدارات: /api/v1/ و /api/v2/ مع توثيف التغييرات بين الإصدارات لتوضيح ما تم تغييره، وتوفير أمثلة واقعية، و ربط التوثيق بـ CI/CD لتحديثه تلقائيًا مع كل تغيير. لو ما سبق موجود بالفعل، إذن يجب العمل على توفير Wiki مركزي، وتنفيذ مراجعة للكود تشمل مراجعة التوثيق بشكل دوري، وإنشاء API Style Guide موحد للفريق. كذلك إعتماد أداة حديثة مثل Apidog والتي تعتبر أداة شاملة بدلاً من استخدام أدوات متفرقة.
  4. حاليًا Apidog أفضل وعملي أكثر من Postman، فهو بمثابة أداة شاملة، لكونه يدمج تصميم وتوثيق واختبار ومحاكاة الـ API في منصة واحدة، وذلك يقلل من الحاجة للتنقل بين أدوات متعددة مثل Postman و Swagger و Mockoon. ويوفر محرر رسومي أيضًا وويدعم مواصفات OpenAPI لتصميم الـ API من البدايةن والتغييرات في التصميم تنعكس تلقائيًا على التوثيق والاختبار. كذلك واجهة رسومية سهلة لإضافة الاختبارات بدون الحاجة لكتابة كود، ويدعم سكربتات الاختبار المخصصة، ويوفر إنشاء Mock Server تلقائيًا بناءًا على تصميم الـ API، ثم توليد بيانات وهمية ذكية كأسماء وإيميلات إعتمادًا على نوع الحقل. ويتم إنشاء التوثيق مباشرًة أثناء تصميم الـ API، والتوثيق تفاعلي وبتصميم جيد وجاهز للمشاركة مع فريق الـ Frontend، حيث كل شيء مبني حول فكرة التعاون، فالتغييرات التي يجريها مصمم الـ API تظهر فورًا للمختبر ومطور الواجهة الأمامية.
  5. هناك أمر هام بجانب ما تم تفصيله وهو، عندما يتغير عنوان URL بسبب نقر المستخدم على <Link> أو استخدام useNavigate، فخطاف useLocation يتسبب في إعادة تصيير أي re-render للمكون الذي يستخدمه، لذا واجهة المستخدم سيتم تحديثها تلقائيًا لتعكس المسار الجديد. بمعنى لو يوجد Sidebar وتريد تظليل الرابط النشط حاليًا، فاستخدام useLocation().pathname سيضمن تحديث التظليل فورًا عند التنقل بين الصفحات. كذلك تستطيع استخدام كائن location.search لتحليل متغيرات البحث لاستخراج قيمة معينة، كالتالي: import { useLocation } from "react-router-dom"; const ProductPage = () => { const location = useLocation(); const queryParams = new URLSearchParams(location.search); const refValue = queryParams.get('ref'); if (refValue === 'google') { console.log("User came from Google!"); } return <div>Product Details</div>; }; أو في صفحة البحث عند النقر على المنتج: <Link to={`/products/${product.id}`} state={{ from: '/search?q=laptops' }} > View Product </Link> وفي صفحة المنتج: import { useLocation, Link } from "react-router-dom"; const ProductDetails = () => { const location = useLocation(); const fromPath = location.state?.from; return ( <div> <h1>Product Details</h1> {fromPath && <Link to={fromPath}>← Back to search results</Link>} </div> ); }; بالتالي لو المستخدم قادم من صفحة البحث، سيتم إظهار رابط العودة إلى البحث.
  6. يوجد أدوات أجنبية لكن تدعم العربية بشكل ممتاز، وهي Postman و Swagger، حيث توفر دعم باللغة العربية من ناحية البيانات والتوثيق، بالتالي الصعوبة لغير متحدثي العربية هو في التعود على الواجهة الإنجليزية، ولكن مع الاستخدام تصبح سهلة جداً. ففي Postman متاح كتابة أسماء الـ Collections والـ Requests باللغة العربية، كذلك إرسال بيانات JSON Body تحتوي على نصوص عربية بالكامل: { "userName": "أحمد ", "address": { "city": "الرياض", "street": "شارع الملك فهد" } } وكتابة توثيق كامل لكل endpoint باللغة العربية، يشمل وصف الـ API، وصف المتغيرات، والأمثلة. بالنسبة لـ Swagger فمتاح كتابة كل الأوصاف، الملخصات، والأمثلة باللغة العربية داخل ملف الـ swagger.yaml.
  7. المشروع لديك سليم لا مشكلة به، لكن المشكلة من المتصفح جوجل كروم نفسه، فهو يُضيف مساحة بيضاء زائدة ناحية اليسار أو اليمين أحيانًا، لذا لحل تلك المشكلة قم بوضع التالي أثناء التطوير في ملف app.css html, body { overflow-x:hidden; } أو تستطيع استخدام الإضافة التالية لإختبار التجاوبية: Pixefy - Responsive Design Checker المشكلة الوحيدة التي ستظهر خاصة بقسم contact US في أصغر مساحة شاشة، بسبب وجود padding لذا قم بحذفه عن طريق تطبيق التالي: @media (max-width: 320px) { .doctors { max-width: 1200px; margin: auto; /* padding: 0 3rem; */ margin-top: 28%; } }
  8. الجميع مر بتلك المرحلة، لكن هونًا على نفسك، كيف تقارن بمن حصد نتاج سنوات من الجد والإجتهاد والخبرة الناتجة عن مواجهة الكثير من الأخطاء والتجربة العملية، الأمر غير منطقي بالمرة. فكر بشكل مختلف، أي بعقلية إيجابية ومنطق سليم، بأن تطمح للوصول لما هم عليه الآن أو بنسبة 50% حتى بعد سنتين أو ثلاث من الآن، حسب مستوى الخبرة الذي تقارن نفسك به، بالتالي كن واقعي ولا تضع آمال ليست عملية كأن تصل لنفس مستوى شخص ذو خبرة 5 سنوات خلال السنة الأولى مثلاً. الأفضل أن تقارن نفسك بنفسك كل فترة وتفقد مستوى تقدمك، والتعلم من لهم خبرة في المجال وليس مقارنة نفسك بهم، لكن يجب التخطيط وليس ترك الأمر بشكل عبثي، بمعنى تلتزم بخارطة طريق roadmap خلال فترة زمنية محددة. وكن واثق بأنّ الصبر والاستمرار هما المفتاح للوصول ما تريده وتحقيق شيء ذو قيمة، بدونهم لن تصل حتى لو كنت الأذكى.
  9. اسم الملف ليس إلزامي تستطيع تسميته كما تريد، لكن الأفضل هو client.js ويتم به وضع الكود الذي يضيف التفاعلية لواجهة المستخدم بعد استلام كود HTML من الخادم أي السيرفر، وذلك في حال سيتم استخدام الـ SSR بالمشروع. أي باستخدام React مع Express.js، لكن لا حاجة إلى طالما Next.js يوفر ذلك وأفضل:
  10. تلك خاصية أي prop نمررها لمكون BrowserRouter في React Router، لإخباره بأن التطبيق لا يعمل على الدومين الرئيسي بل يعمل داخل مجلد فرعي، أي دومين فرعي. بمعنى لو أردت وضع التطبيق داخل مجلد فرعي اسمه my-app، فستصبح الروابط كالتالي: https://www.test.com/my-app/ (الصفحة الرئيسية) صحفات أخرى https://www.test.com/my-app/about https://www.test.com/my-app/contact بالتالي لو قمت باستخدام المسار كالتالي <Link to="/about">، فسيحاول المتصفح الذهاب إلى https://www.test.com/about ,`g; مسار خاطئ سيؤدي إلى صفحة خطأ 404 Not Found. لذا من خلال basename أنت تخبر React Router أن المسار الأساسي لجميع روابطك هو /my-app، وبالتالي سيعرف كيف يبني الروابط بشكل صحيح. import { BrowserRouter, Routes, Route, Link } from 'react-router-dom'; function HomePage() { return <h1>الصفحة الرئيسية</h1>; } function AboutPage() { return <h1>صفحة من نحن</h1>; } function App() { return ( <BrowserRouter basename="/my-app"> <nav> <Link to="/">الرئيسية</Link> | <Link to="/about">من نحن</Link> </nav> <Routes> <Route path="/" element={<HomePage />} /> <Route path="/about" element={<AboutPage />} /> </Routes> </BrowserRouter> ); } export default App;
  11. آلية الإختبار هي كالتالي: بعد إنهاء 4 مسارات من الدورة على الأقل حيث سيتم إختبارك في المسارات التي أنهيتها فقط، أو الدورة بالكامل عليك رفع المشاريع التي قمت بها بالدورة على حسابك في github، ثم التحدث لمركز المساعدة وإخبارهم أنك تريد التقدم للإختبار وتوفير روابط المشاريع على github. ثم الإنتظار لبعض الوقت لحين مراجعة المشاريع وسيتم الرد عليك، وتحديد موعد لإجراء مقابلة، وبها يتم: إجراء محادثة صوتيّة لمدة 30 دقيقة يطرح المدرّب عليك أسئلة متعلّقة بالدورة والأمور التي نفّذتها خلالها. يحدد لك المدرّب مشروعًا مرتبطًا بما قمت به أثناء الدورة لتنفيذه خلال فترة محددة تتراوح بين أسبوع إلى أسبوعين. إجراء محادثة صوتيّة أخرى لمدّة 30 دقيقة يناقش بها مشروعك وما نفذته وتطرح أسئلة خلالها. إن سارت جميع الخطوات السابقة بشكل صحيح، تحصل على الشهادة أو يرشدك المدرّب لأماكن القصور ويطلب منك تداركها ثم التواصل معنا من جديد. وبالطبع الأفضل دراسة الدورة بشكل كامل أو المسارات التي تريدها في مسارك البرمجي وليس الإكتفاء بـ 4 مسارات فقط، ففي النهاية أنت تريد تحقيق استفادة وتعلم المهارات اللازمة لدخول سوق العمل.
  12. ستجد أسفل فيديو الدرس في نهاية الصفحة صندوق تعليقات كما هنا، أرجو طرح الأسئلة أسفل الدرس وليس هنا في قسم أسئلة البرمجة حيث نطرح الأسئلة العامة الغير متعلقة بمحتوى الدورة أو الدرس، وذلك لمساعدتك بشكل أفضل.
  13. رفع مشاريع على المنصة ليس بتلك الصعوبة، ستحتاج أولاً إلى إنشاء حساب من خلال الرابط: https://github.com/signup بعد تسجيل الدخول عليك تثبيت git على حاسوبك: https://github.com/git-for-windows/git/releases/download/v2.50.0.windows.2/Git-2.50.0.2-64-bit.exe بعد إنتهاء التثبيت، توجه إلى مشروعك عن طريق منفذ الأوامر أو قم بتشغيل التيرمنال من خلال vscode وسيتم فتحه في مسار مجلد المشروع، وعليك تنفيذ الأوامر التالية لرفع المشروع: git init // ثم git add README.md // ثم git commit -m "first commit" // ثم git branch -M main // ثم git remote add origin https://github.com/ اسم المستخدم/repoName.git // ثم git push -u origin main ستجد تفصيل هنا:
  14. قمت بتهيئة تطبيق فلاسك مرتين، فهنا تقوم بإنشاء التطبيق وتحديد المسار الرئيسي له: app = Flask(__name__) @app.route('/') def hello_world(): return '<h1>Hello World!</h1>' ولكن بعد ذلك مباشرةً، تقوم بإنشاء نسخة جديدة تمامًا من التطبيق وتُسندها إلى نفس المتغير app: app = Flask(__name__) #هنا api = Api(app) بالتالي يتم مسح أو استبدال النسخة الأولى من التطبيق، والذي يتم تشغيله في النهاية app.run() هو النسخة الثانية التي لا تحتوي إلا على المسارات /predict و /health، ولكنها لا تعلم أي شيء عن المسار الرئيسي / عليك حذف التالي: app = Flask(__name__) #هنا
  15. المشكلة هي werkzeug.routing.exceptions.BuildError: Could not build url for endpoint 'register' وتعني أن دالة url_for() لم تتمكن من العثور على مسار باسم register. الفكرة هو أنه عند استخدام Blueprints، يتم إضافة اسم الـ Blueprint كبادئة لاسم المسار، لذا بدلاً من أن يكون اسم المسار register فقط، يصبح auth.register أي يجب تعديل السطر الموجود في ملف login.html ليصبح كالتالي: <a href="{{ url_for('auth.register' if 'login' in request.path else 'auth.login') }}"> تسجيل</a>
  16. عليك تثبيت بايثون على النظام لديك، من خلال الرابط التالي: https://www.python.org/ftp/python/3.12.8/python-3.12.8-amd64.exe وستجد هنا طريقة التثبيت: ثم قم بإغلاق محرر الأكواد وأعد تشغيله ليتم التعرف على أمر python
  17. لا مشكلة في تدريس الأساسيات النظرية أولاً أي التعلم العميق والشبكات العصبية، ثم الانتقال إلى البنى المتقدمة المبنية عليها كالـ Transformers. لكن الفكرة من إعادة الترتيب هو إتباع منهجية حديثة وهي من الأعلى إلى الأسفل أو التطبيق أولاً، وذلك بدلاً من المنهجية التقليدية من الأسفل إلى الأعلى أو النظرية أولاً. وذلك لتعلم كيفية قيادة السيارة وتحقيق بها نتائج ملموسة تطبيقات المحولات، ثم بعد أن يدرك الطلبة أهميتها وقوتها، سيتعلمون كيف يعمل محركها الداخلي أي التعلم العميق. بمعنى المحولات هي نوع من الشبكات العصبية، لكن استخدامها كأداة لا يتطلب بالضرورة فهم كل تفاصيلها النظرية المعقدة مسبقًا، تمامًا كما أنك تستخدم هاتفك الذكي كل يوم دون الحاجة لمعرفة تصميم أشباه الموصلات في معالجه. لذا الترتيب الجديد غرضه، تعليمك المهارات التطبيقية الأكثر طلبًا أولاً، وإبقائك متحفزة عبر بناء مشاريع حقيقية مبكرًا، وتأهيلك بشكل عملي لفهم النظرية لاحقًا بشكل أسهل وأكثر جدوى.
  18. المشكلة لديك هي ValueError: X has 13 features, but StandardScaler is expecting 15 features as input بسبب عدم تطابق عدد السمات التي يتوقعها الـ scaler حيث تم تدريبه على 5 سمات رقمية محددة فقط. أي عندما تستدعي الدالة scaler.transform(df)، يتوقع scaler أن تكون df لها نفس عدد الأعمدة 15 وبنفس الترتيب الذي تعلمه، لكن تمرر له DataFrame (df) يحتوي على 13 عمودًا فقط، وذلك يؤدي إلى الـ ValueError. بالتالي عليك محاكاة نفس خطوات المعالجة المسبقة التي تمت في الـ Notebook داخل دالة التنبؤ في Flask، من خلال استقبال الـ 13 ميزة من المستخدم. ثم إنشاء DataFrame من المدخلات، وافصله إلى جزأين: df_numerical: DataFrame يحتوي على الميزات الرقمية الخمس. df_categorical: DataFrame يحتوي على الميزات الفئوية الثمانية. ويجب أن تكون قد قمت بحفظ كائن الـ One-Hot Encoder في ملف مثل encoder.joblib وقم بتحميله، ثم استخدم الكائن المحمل لتحويل df_categorical، وسينتج عن ذلك مصفوفة NumPy أو DataFrame جديد يحتوي على 10 أعمدة. ثم قم بدمج بيانات الميزات الرقمية الخمس الأصلية مع بيانات الميزات الفئوية المحولة أي الـ 10 أعمدة، ويجب أن يكون ترتيب الأعمدة مطابق تمام للترتيب الذي تم استخدامه لتدريب الـ scaler. بعد ذلك تمرير المصفوفة الجديدة المكونة من 15 ميزة إلى scaler.transform()، ولن يحدث خطأ لأن الأبعاد متطابقة.
  19. حسب ما فهمت، ما تريده هو إعادة التوجيه بعد تسجيل الدخول أو التسجيل بتغيير الوجهة من لوحة التحكم dashboard إلى صفحة التنبؤ، وحفظ المعلومات في قاعدة البيانات أي نتائج التنبؤ يتم حفظها بشكل صحيح. أولاً في الملف الذي يحتوي على مسارات تسجيل الدخول والتسجيل، أي الدوال التي فوقها app.route('/login')@ و app.route('/register')@)، عليك تغيير الوسيط داخل دالة url_for() من نقطة نهاية لوحة التحكم إلى نقطة النهاية التي تعرض صفحة الـ HTML لنموذج التنبؤ، وذلك على افتراض أن لديك مسار يعرض صفحة التنبؤ، حيث ستقوم بتغيير أسطر دالة redirect والتي بداخلها url_for بالنسبة لقاعدة البيانات، فهل قمت بعمل تحديث في برنامج dbgate لقاعدة البيانات لرؤية الصفوف الجديدة؟ بمعنى عمل refresh، لكن لو حدث أي خطأ قبل تنفيذ db.session.commit()، فلن يتم حفظ البيانات، وستظهر رسالة الخطأ في منفذ الأوامر الخاص بخادم فلاسك. عامًة أنت بحاجة إلى دراسة أساسيات Flask:
  20. أين سلة المشتريات؟ حاول محاكاة ذلك، بمعنى سلة مشتريات عند الضغط عليها يتم عرض قائمة منسدلة توضح مُلخص مع زر للإنتقال لصفحة المشتريات لإتمام عملية الشراء. عند الضغط على زر order now حاول محاكاة عملية الإضافة للسلة، بزيادة عدد المنتجات فوق أيقونة السلة كما في المتاجر الحقيقية، أي عليك إنشاء state لذلك. حاول جعل التصاميم أقرب للواقع قدر الإمكان وليست مجرد تصاميم جامدة بدون وظيفة، عامًة أرى تحسن كبير في مستوى المشاريع، ممتاز، عليك الاستمرار في تنفيذ المشاريع مع زيادة مستوى الصعوبة والتعقيد تدريجيًا لحين الوصول للقدرة على على تنفيذ مشروع متجر إلكتروني يعمل بالكامل، وذلك من خلال رؤية شروحات في البداية ثم محاولة توظيف ما تعلمته في تحويل تصميم من الإنترنت لمشروع حقيقي، وستجد ذلك هنا: بعد ذلك تستطيع تعلم مكتبة خاصة بتأثيرات حركية عند التمرير في الصفحة نزولاً وصعودًا مثل AOS أو GSAP لكن قبل الاستمرار الأفضل دراسة أساسيات تصميم واجهة المستخدم، لتحسين مستوى التصميم في مشاريع وليس مجرد كتابة كود فقط بل عن علم بما تقوم به، فهيكل الصفحة والمساحات والخطوط لا يتم بشكل عشوائي، ستجد تفصيل هنا:
  21. بعد التثبيت ستحتاج إلى استيراد المكتبة ، وأفضل مكان لتهيئة المكتبة هو في المكون الرئيسي لمشروعك App.js أو أيًا يكن اسمه، بحيث يتم تشغيلها مرة واحدة فقط عند تحميل التطبيق. import { useEffect } from 'react'; import AOS from 'aos'; import 'aos/dist/aos.css'; ثم تهيئة المكتبة في App.js من خلال خُطاف useEffect: useEffect(() => { AOS.init({ duration: 1200, }); }, []); بعد ذلك كل ما عليك فعله هو إضافة السمة data-aos إلى أي عنصر JSX تريد تحريكه، وتستطيع اختيار نوع الحركة التي تريدها من موقع AOS الرسمي. <div className="section" data-aos="fade-up"> <h2> العنصر سيظهر بتأثير (fade-up)</h2> <p>أهلاً بالعالم</p> </div>
  22. UX يعني تجربة المستخدم، وهو الشعور والإدراك العام الذي يتكون لدى الشخص أثناء استخدامه لمنتج أو تطبيق، أي هي لا تتعلق فقط بالمظهر الجميل، بل بكل جوانب التفاعل بين المستخدم والتطبيق، فالمظهر والتصميم خاص بجزئية الـ UI. الفكرة هي جعل الموقع أو التطبيق سهل الاستخدام قدر الإمكان بما يتناسب مع نوعية المستخدمين، وكذلك مفيد، مرغوب، سريع وسهل الوصول. والأمر بحاجة إلى تفصيل كثير ستجده هنا: بينما مكتبة Pop-up كالتالي مثلاً: https://www.npmjs.com/package/reactjs-popup فهي لإنشاء مكون النافذة المنبثقة أو ما يسمى أيضًا بـ Modal أو Dialog كالتالي: أي الـ Pop-up نافذة صغيرة تظهر فوق محتوى الصفحة الرئيسي لجذب انتباه المستخدم لأمر معين، لعرض رسالة تنبيه أو تأكيد، كهل أنت متأكد من الحذف؟ أو لعرض نموذج لإدخال بيانات كنموذج تسجيل الدخول، أو عرض معلومات إضافية أو صور بشكل أكبر.
  23. لو كانت كذلك لتم تسجيل الدخول، قم إذن بإعادة تعيينها بالضغط على رابط forgot your password
  24. بسبب أنك قمت بإدخال كلمة المرور الغير صحيحة أكثر من مرة، بالتالي سيتعين عليك الإنتظار لمدة 30 دقيقة أو ساعة، ثم تستطيع تجربة تسجيل الدخول مرة أخرى. الأفضل في حال نسيت كلمة المرور قم بالضغط على رابط forgot your password؟ لإعادة تعيين كلمة المرور.
  25. عليك تعطيل خاصية once فالإعداد الافتراضي لـ once في مكتبة AOS هو true، بمعنى الأنيميشن يحدث مرة واحدة فقط عند أول ظهور للعنصر، وعند التمرير مرة أخرى لا يحدث شيء، قم بتعديل الكود للتالي: useEffect(() => { AOS.init({ duration: 1000, once: false, }); }, []); و duration: 1000 ستجعل الحركة أبطأ وسلسة أكثر.
×
×
  • أضف...