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

Mustafa Mahmoud7

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

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

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

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

    1

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

  1. ستجد أسفل فيديو الدرس صندوق للتعليقات كما هنا يرجى طرح سؤالك أسفل الدرس وليس هنا حيث هنا قسم الأسئلة العامة ولا نقوم بإجابة الأسئلة الخاصة بمحتوى الدورة أو الدرس، وذلك لمعرفة الدرس الذي توجد به مشكلتك و لمساعدتك بشكل أفضل.
  2. شعورك بأنك سوف لا تتذكر شئ عند مجئ الإختبار شئ عادي وطبيعي ولكي تتخلص من هذا الشعور أثناء مشاهدتك للدروس عليك بالتالي: مشاهدة المسارات بترتيبهم الطبيعي كما هو في الدورة حيث الدورة تتدرج في مستوى الصعوبة فحاول ألا تتجاوز أي مسار أو أي درس فالدروس والمسارات مترتبة على بعضها البعض. لا تتجاوز أي درس بدون الفهم الجيد له والقيام بسؤال نفسك أسئلة والإجابة عليها لتأكيد فهمك. التطبيق بعد نهاية مشاهدتك للدرس ومحاولة كتابة الأكواد بنفسك والتأكد من فهمك لهذه الأكواد التطبيق مهم جدا فلا تكتفي بالمشاهدة فالبرمجة ليست فيلم مهم جدا التطبيق على كل درس. بعد نهاية مجموعة من الدروس محاول عمل مشروع بسيط على هذه الدروس لترسيخ فهمك لهذه الدروس وتجميع ما تعلمته في هذه الدروس. كل فترة حاول عمل تطبيقات صغيرة على المسارات التي أنهيتها حتى لاتنساها أو مراجعة ما بها على الأقل بشكل سريع. بالتأكيد لا تتردد في طرح أي سؤال في التعليقات أسفل الدرس مع توضيح استفسارك بشكل واضح وما هي المشكلة التي تواجهها وسيجيب عليك أحد المدربين بالأكاديمية بأسرع وقت ممكن. بهذه الطريقة والخطوات عند الوصول لمرحلة الاختبار سيكون من السهل عليك تجاوزه بإذن الله. ويمكنك مراجعة بعض الموضوعات بشكل نص من خلال موسوعة حسوب فبها العديد من الشروحات تساعدك في المراجعة السريعة. يمكنك الإطلاع على هذه الإجابات أيضا
  3. برنامج Apidog نعم هو مهم وهو من الأدوات الحديثة اللي بتغير طريقة شغل المطورين مع الـ API فهو ليس مجرد بديل لـ Postman لكنه برنامج متكامل بتجمع بين تصميم الـ API واختباره ووتوثيقه وكل ده في مكان واحد وواجهة رسومية سهلة الاستخدام. Apidog بيقدم تجربة مرئية لتصميم الـ API بتقدري من خلالها تبني الـ endpoints وتحددي الطلبات والاستجابات بسهولة. كمان بيوفر خاصية التوثيق التلقائي بشكل احترافي ويجعلكي تشغلي Mock Server لتجربة الـ API حتى قبل ما الكود يجهز وده بيساعدك تشتغلي بسرعة ومن غير ما تستني التيم التاني يخلص. أيضا Apidog بيدعم توليد أكواد جاهزة بعدة لغات وده بيوفر وقت كبير للمبرمجين في دمج الـ API ولو كنتي شغالة في فريق خاصية التعاون (Collaboration) هتخلي الفريق كله يشتغل في نفس المشروع بسهولة ويشارك التغييرات لحظيا. فلو مشروعك بسيط Postman ممكن يفي بالغرض لكن لو محتاجة تنظيم وتوثيق وتجربة متكاملة فـ Apidog هو الخيار الأنسب والمفيد فعلا في الوقت الحالي.
  4. ستجد أسفل فيديو الدرس صندوق للتعليقات كما هنا يرجى طرح سؤالك أسفل الدرس وليس هنا حيث هنا قسم الأسئلة العامة ولا نقوم بإجابة الأسئلة الخاصة بمحتوى الدورة أو الدرس، وذلك لمعرفة الدرس الذي توجد به مشكلتك و لمساعدتك بشكل أفضل.
  5. هذا الخطأ سببه أن كل ما يوضع داخل <Routes> لابد أن يكون <Route> فقط أو <React.Fragment> يحتوي فقط على <Route> لكن لاحظ أنك وضعت داخله <Background /> ، <Hero /> بشكل مباشر وهذا غير مسموح. لهذا قم بنقل <Background /> خارج <Routes> لأنه ليس مسار (Routes) بل مكون أعتقد تريد أن يظهر دائما في كل الصفحات ولاحظ عند استخدام المكون Hero لابد من إرسال الخواص التي يريدها heroData ، heroCount، playStatus، setHeroCount ، setPlayStatus فهي ضرورية لكي يظهر المكون Hero بصورة صحيحة. ليصبح الكود بعد التعديل كالتالي <> <div> <BrowserRouter> <Navbar /> <Routes> <Route path="/Hero" element={ <Hero heroData={heroData[heroCount]} heroCount={heroCount} playStatus={playStatus} setHeroCount={setHeroCount} setPlayStatus={setPlayStatus} /> } /> </Routes> {/* هذا العنصر يجب أن يكون خارج <Routes> */} <Background playStatus={playStatus} heroCount={heroCount} /> </BrowserRouter> </div> </>
  6. يمكنك عمل مكون خاص AppRouter بهذه العملية ليكون مستقل بذاته لهذا الأمر كالتالي import { BrowserRouter, Routes, Route } from "react-router"; import Home from "./pages/Home"; import About from "./pages/About"; import Contact from "./pages/Contact"; export default function AppRouter() { return ( <BrowserRouter> <Routes> <Route path="/" element={<Home />} /> <Route path="/about" element={<About />} /> <Route path="/contact" element={<Contact />} /> </Routes> </BrowserRouter> ); } ثم استخدامه بداخل App.js كالتالي import { Link } from "react-router"; import AppRouter from "./router"; export default function App() { return ( <> <nav> <Link to="/">Home</Link> <Link to="/about">About</Link> <Link to="/contact">Contact</Link> </nav> <AppRouter /> </> ); } أو يوجد طريقة أخرى متاحة يمكنك استخدامه أيضا ليكون المكون AppRouter كالتالي mport { createBrowserRouter, RouterProvider } from "react-router"; import Home from "./pages"; import About from "./pages/about"; import Contact from "./pages/Contact"; const router = createBrowserRouter([ { path: "/", element: <Home />, }, { path: "/about", element: <About />, }, { path: "/contact", element: <Contact />, }, ]); export default function AppRouter() { return <RouterProvider router={router} />; } واستخدام المكون AppRouter بداخل App.js كالتالي import { Link } from "react-router"; import AppRouter from "./router"; export default function App() { return ( <> <nav> <Link to="/">Home</Link> <Link to="/about">About</Link> <Link to="/contact">Contact</Link> </nav> <AppRouter /> </> ); } الطريقتان متاحتان يمكنك اختيار أي منهم.
  7. لعمل صفحات أخرى وتحويل التطبيق إلى SPA سنقوم باستخدام مكتبة react-router وهي المسؤولة عن إدارة التوجيه بداخل التطبيق. تثبيت المكتبة عن طريق الأمر npm i react-router وفي المكون App لديك نقوم باستخدام المكتبة كالتالي import { BrowserRouter, Routes, Route,Link } from "react-router"; import Home from "./pages/Home"; import About from "./pages/About"; import Contact from "./pages/Contact"; function App() { return ( <BrowserRouter> <nav> <Link to="/">Home</Link> <Link to="/about">About</Link> <Link to="/contact">Contact</Link> </nav> <Routes> <Route path="/" element={<Home />} /> <Route path="/about" element={<About />} /> <Route path="/contact" element={<Contact />} /> </Routes> </BrowserRouter> ); } سيتطلب الأمر منك بالطبع إنشاء المكونات التي هي عبارة عن صفحة وهي Home ،ِ About , Contact. صفحة Home.jsx export default function Home() { return <h1>Home Page</h1>; } صفحة About.jsx export default function About() { return <h1>About Page</h1>; } صفحة Contact.jsx export default function Contact() { return <h1>Contact Page</h1>; } سيظهر لديك في الصفحة navbar وبه الروابط للصفحات واستخدام المكون Link هذا بديل محسن من anchor tag (<a>) مع استخدام to بدلا من href للإنتقال للصفحة بدون عمل إعادة تحميل للصفحة فقط الإنتقال للصفحة. لابد أن يكون المسار الذي تريد الذهاب له "to="/about يجب أن يكون مطابق حرفيا لـ "path="/about في <Route> حتى يتم تحميل الصفحة about بنجاح. يمكن قراءة المزيد حول react-router
  8. أولا بما أنك تعمل على مشروع عبارة عن صفحة واحدة هل هناك هدف لتغيير العنوان حيث تذكر بعد ذلك أنه لديك أكثر من صفحة. أفترض انك لديك مشروع رياكت عبارة عن SPA وقمت بتثبيت مكتبة react-router من خلالها تستطيع التنقل بين الصفحات. في تطبيقات React التي هي عبارة عن صفحة واحدة (Single Page Application) فعلا بيكون عندك ملف index.html واحد فقط وذلك معناه إن عنوان الصفحة (<title>) لا يتغير تلقائي عندما تنتقل بين الصفحات (Routes) لأنه لا يوجد reload بيحصل للصفحة. لذلك الحل هو إنك تغير العنوان يدويا من داخل React. تستطيع كل صفحة تغير عنوانها بنفسها كالتالي import { useEffect } from "react"; function Page1() { useEffect(() => { document.title = "Page 1"; }, []); return ( <div> <h1>Page 1</h1> {/* باقي المكونات */} </div> ) } وهكذا في باقي الصفحات كل واحدة منهم تقوم بكتابة العنوان الخاص بها في useEffect. تستطيع أيضا تحديد العنوان تلقائيا حسب الرابط (URL) لو الروابط عندك واضحة مثل (about أو contact/) يمكن عمل مكون صغير مسؤول عن تحديث العنوان تلقائي حسب الصفحة كالتالي 1. ملف فيه العناوين: // pageTitles.js const pageTitles = { "/": "الصفحة الرئيسية", "/about": "من نحن", "/contact": "اتصل بنا", }; export default pageTitles; 2. مكون PageTitleUpdater: import { useEffect } from "react"; import { useLocation } from "react-router-dom"; import pageTitles from "./pageTitles"; function PageTitleUpdater() { const location = useLocation(); useEffect(() => { const title = pageTitles[location.pathname] || "تطبيقي"; document.title = title; }, [location.pathname]); return null; } useLocation هو hook من React Router يعطي لك المعلومات عن الرابط الحالي في المتصفح. 2. تستخدم المكون PageTitleUpdater في ملف App: import { BrowserRouter, Routes, Route } from "react-router-dom"; import Home from "./pages/Home"; import About from "./pages/About"; import Contact from "./pages/Contact"; import PageTitleUpdater from "./PageTitleUpdater"; function App() { return ( <BrowserRouter> <PageTitleUpdater /> <Routes> <Route path="/" element={<Home />} /> <Route path="/about" element={<About />} /> <Route path="/contact" element={<Contact />} /> </Routes> </BrowserRouter> ); } بالإضافة لذلك طبعا يمكنك استخدام مكتبة react-helmet كما ذكر لك محمد في التعليق السابق لهذا الأمر.
  9. هذا الخطأ يخبرك أنك تقوم بمحاول الوصول للثابت todos في سطر 15 وهذا الثابت قبل ما يتم تعريفه أو تهيئته (initialization). لذلك يرجى نقل عملية استخدام الـ todos ومحاولة الوصول لقيمته أسفل عملية التعريف له. فمثلا في هذا الكود const handelButtonClick = () => { const text = inpRef.current.value; const newTodos = {complelted: false ,text} setTodos([...todos, newTodos]) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ inpRef.current.value = ''; } const [todos , setTodos] = useState([]); ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ هذا الكود ليس بالظبط في أكوادك التي أرسلتها سابقا فقط لبيان كيف يمكن أن يحدث هذا الخطأ سيظهر معك هذا الخطأ Cannot access 'todos' before initialization لأنك بتحاول تستخدم حاجة لسه ما اتعرفتش. وتصحيح هذا الكود يكون كالأتي const [todos , setTodos] = useState([]); const handelButtonClick = () => { const text = inpRef.current.value; const newTodos = {complelted: false ,text} setTodos([...todos, newTodos]) inpRef.current.value = ''; } لذلك قم بالبحث عن السطر الذي قم فيه بتعريف todos وانقله قبل السطر رقم 15 والتجربة مرة أخرى.
  10. خطأ غريب حيث قمت باختبار الكود عدة مرات سواء بإعادة التحميل للتطبيق أو الإضافة أو الحذف ولا يظهر هذا الخطأ لدي. أرجو أيضا تفريغ الـ localStorage من البيانات الموجودة به ربما هناك بيانات قديمة مخزنة به تحت المفتاح todos أيضا. من الممكن أن يكون هناك إضافة لديك في المتصفح تؤدي إلى ذلك الخطأ لذا يرجى تشغيل التطبيق في المتصفح الخفي وإعادة المحاولة. وأرجو أيضا استبدال هذا السطر return <div className="item"><li className={complelted ? "done" : ""} onClick={() => handelItemClick(i)}>{text}</li><span onClick={() => handelDeleteItem(i)}>❌</span></div> بالتالي return ( <div className="item" key={i}> <li className={complelted ? "done" : ""} onClick={() => handelItemClick(i)} > {text} </li> <span onClick={() => handelDeleteItem(i)}>❌</span> </div> ); قمنا بإضافة الـ key للـ div وهو مهم عند العمل مع map في react. من المفترض ألا تظهر معك أي أخطاء في الـ console أو تحذيرات ويعمل معك التطبيق بدون مشكلة.
  11. إذا كان هذا التطبيق خاص بأحد دروس الدورة ستجد أسفل فيديو الدرس في نهاية الصفحة صندوق تعليقات كما هنا، أرجو طرح الأسئلة أسفل الدرس وليس هنا في قسم أسئلة البرمجة حيث نطرح الأسئلة العامة الغير متعلقة بمحتوى الدورة أو الدرس، وذلك لمساعدتك بشكل أفضل. لكي يتم حفظ البيانات في التخزين المحلي (localStorage) وتستمر بعد ما يتم إعادة تحميل الصفحة، لابد أن نستخدم localStorage مع useEffect فالمطلوب كالأتي عند تشغيل التطبيق لأول مرة: نقرأ المهام من localStorage. عند تغيير المهام (todos): نقوم بتحديث localStorage ونضيف المهام المحدثة به. لهذا الأمر عليك بإضافة التالي إلى الكود الخاص بك // قراءة البيانات من التخزين المحلي عند تحميل الصفحة أول مرة useEffect(() => { const storedTodos = localStorage.getItem("todos"); if (storedTodos) { setTodos(JSON.parse(storedTodos)); } }, []); // حفظ المهام في التخزين المحلي عند كل تغيير في القائمة useEffect(() => { localStorage.setItem("todos", JSON.stringify(todos)); }, [todos]); في الـ useEffect الأولي يتم التالي هذا الكود بداخل useEffect يعمل مرة واحدة فقط عند تحميل المكون APP بسبب [] في النهاية. يقوم بالبحث في localStorage عن شيء محفوظ باسم المفتاح todos. إذا وجده نحوله من نص إلى مصفوفة باستخدام ()JSON.parse ثم نخزنها داخل todos باستخدام ()setTodos. في الـ useEffect الثانية يتم التالي هذا الكود بداخل useEffect يعمل في كل مرة تتغير فيها المهام todos بسبب [todos]. يقوم بتحويل المهام إلى نص باستخدام ()JSON.stringify ثم يقوم بحفظ هذا النص داخل localStorage باسم المفتاح todos.
  12. نعم لا يزال استخدام الـ Dom أساسيا في تطوير تطبيقات الويب حتى وإن لم يتعامل المطور معه بشكل مباشر في أطر العمل الحديثة مثل React أو Angular أو Vue فإن هذه الأطر تعتمد عليه داخليا للتفاعل مع الصفحة وعرض المحتوى. فهم كيفية عمل الـ DOM يظل مهما لأي مطور لأنه يمثل الأساس الذي تبنى عليه واجهات المستخدم في الويب. في المشاريع البسيطة ذات صفحة واحدة (Single Page) أو التي لا تتطلب تفاعلات كثيرة يمكن استخدام DOM مباشر بدون الحاجة إلى إطار عمل ثقيل لتقليل حجم الملفات وتحسين الأداء. أما في المشاريع الكبيرة والتي تحتوي على العديد من الصفحات وتحتاج إلى تفاعل ديناميكي كبير مع الواجهة وإدارة حالة معقدة يصبح من العملي استخدام أطر العمل الحديثة التي تسهل التحكم في DOM بطريقة منظمة وسريعة. لذلك استخدام DOM ليس قديما بل هو جزء لا يتجزأ من كل تطبيق ويب ولكن طريقة التعامل معه تطورت فمعرفتك لكيفية التعامل مع الـ Dom وما يتم داخليا يسهل عليك الكثير وتفهم ما يدور داخليا في أطر العمل.
  13. من الأفضل لك في الوقت الحالي التركيز على ريأكت و JSX وكيفية إدارة الحالة بها ومعرفة دورة حياة المكون في رياكت وعمل تطبيق بسيط ثم محاولة تعلم MUI حتى لا يصيبك التشتت والكثير من المعلومات التركيز الأكبر على إطار العمل React واستخدام CSS معه كافي جدا للتطبيق على مفاهيم رياكت.
  14. MUI هي مكتبة واجهات مستخدم (UI) مبنية باستخدام React وتستند إلى تصميم Material Design من Google. توفر مجموعة من المكونات الجاهزة مثل الأزرار، حقول الإدخال، الجداول، النوافذ المنبثقة وغيرها. استخدام MUI يوفر الكثير من الوقت والجهد بدلًا من بناء كل المكونات من الصفر، كما أنه يساعدك على تصميم واجهات أنيقة ومتناسقة بسرعة. كما أن هذه المكونات قابلة للتخصيص حسب الحاجة وتوفر دعما قويا للتصميم المتجاوب (Responsive Design) وإمكانيات التخصيص عبر الـ Themes. MUI ليست مجرد تنسيق CSS فقط بل هي مكتبة كاملة للمكونات التفاعلية أي ليست مكونات تم تنسيقها عن طريق CSS ولكن بها بها تنسيق ومنطق برمجي، فهي توفر لك كل ما تحتاجه لبناء واجهات احترافية بسرعة في مشاريع React وتشمل تصميم، منطق تفاعل، تخصيص.
  15. ستجد أسفل فيديو الدرس صندوق للتعليقات كما هنا يرجى طرح سؤالك أسفل الدرس وليس هنا حيث هنا قسم الأسئلة العامة ولا نقوم بإجابة الأسئلة الخاصة بمحتوى الدورة أو الدرس، وذلك لمعرفة الدرس الذي توجد به مشكلتك و لمساعدتك بشكل أفضل. عند تثبيت بايثون على نظام ويندوز يتم تثبيت برنامج IDLE وهو يشمل بداخله ما يُعرف بـ Python Shell. Python Shell هو نفسه النافذة التفاعلية التي تظهر عند فتح IDLE وتبدأ بالسطر: Python 3.x.x (...) on win32 Type "help", "copyright", ... >>> إذا ظهرت لك هذه النافذة عند فتح IDLE فاعلم أن Python Shell مثبت ويعمل بشكل صحيح. يمكنك تجربة كتابة أمر بسيط مثل: print("Hello, Python!") ثم Enter وستظهر لك النتيجة فورا وهذا دليل على أن كل شيء يعمل بدون مشكلة. إذا واجهتك مشكلة معينة فيرجى توضيحها أكثر تحت الفيديو الذي تقصده لمساعدتك بشكل أفضل.
  16. سبب ظهور هذا الأمر يرجع إلى أن الـ navbar المساحة له في الشاشات الصغيرة لم تعد كافية للمحتوى لذلك في هذه الشاشات نقوم بجعل قائمة الروابط أسفل شعار الموقع لذلك في ملف components\GymNav.vue نقوم بتعديل ترتيب العناصر لتصبح عمودية لجعل قائمة الروابط أسفل شعار الموقع لتصبح الأكواد الخاص بالشاشة الصغيرة التي أقل من 768px كالتالي @media(max-width: 778px){ .logo{ display: none; } .links{ margin-left: 30px; } .navbar{ flex-direction:column; } } أضفنا ;flex-direction:column للعنصر الذي لديه الصنف navabar. لجعل إتجاه العناصر عموديا أي تحت بعضهم البعض حيث السلوك الافتراضي لـ ;display:flex هو جعل اتجاه ترتيب العناصر أفقيا أي بجانب بعضهم البعض لذلك قمنا بتعديله.
  17. الدورات لا يتم تحديثها بالكامل دفعة واحدة، بل يتم تحديثها بشكل تدريجي من خلال: إضافة مسارات جديدة لمواكبة سوق العمل وما به من متطلبات جديدة. استبدال مسارات قديمة بمسارات أحدث حسب الحاجة. لذلك يمكنك البدء بمشاهدة المحتوى الحالي مباشرة فهو يمثل آخر تحديث متاح للدورة حتى الآن. بخصوص التحديثات القادمة على الدورة دورة تطوير واجهات المستخدم يتم تحديثها بشكل دوري وفقا لمتطلبات سوق العمل وتطور التقنيات الحديثة لكن لا يوجد موعد محدد للتحديثات. يمكنك دائما متابعة التحديثات الجديدة لجميع الدورات من خلال صفحة آخر التحديثات على الرابط التالي: https://academy.hsoub.com/release-notes
  18. لتنسيق المشروع في الشاشات الصغيرة من المهم جدا استخدام الـ media queries لكي تستطيع تطبيق بعض الخصائص والتسيقات في أحجام شاشة معينة لذلك يرجى الإطلاع على هذه المقالة تبين لك كيفية تنفيذ ذلك بعد ذلك لجعل التطبيق الخاص بك متجاوب في الشاشات التي أقل من 768px أولا علينا إضافة تغليف للجدول في ملف index.html فهو ما يخرب الصفحة فبدلا من <table> <tr> <th>id</th> <th>title</th> <th>price</th> <th>taxes</th> <th>ads</th> <th>discount</th> <th>total</th> <th>category</th> <th>update</th> <th>delete</th> </tr> <tbody id="tbody"> </tbody> </table> نضيف التغليف ليصبح <div class="table-responsive"> <table> <tr> <th>id</th> <th>title</th> <th>price</th> <th>taxes</th> <th>ads</th> <th>discount</th> <th>total</th> <th>category</th> <th>update</th> <th>delete</th> </tr> <tbody id="tbody"> </tbody> </table> </div> بعد ذلك في ملف style.css سطر 78 .searchBlock { width: 90%; margin-left: 60px; ^^^^^^^^^^^^^^^^^^^^^^^^ } نعدل هذا العنصر ليتوسط أفقيا بالعرض %90 كالتالي .searchBlock { width: 90%; margin:0 auto; } وفي نفس الملف أيضا نضيف هذه التنسيقات /* 1. غلف الجدول بحاوية متجاوبة */ .table-responsive { overflow-x: auto; /* اجعل الحاوية قابلة للتمرير أفقيًا عند ضيق الشاشة */ margin: 10px 0; /* مسافة رأسية بسيطة فوق وتحت الجدول */ } /* 2. اجعل عرض الجدول يملأ الحاوية */ .table-responsive table { width: 100%; /* الجدول يملأ عرض الحاوية بالكامل */ min-width: 600px; /* الحد الأدنى لعرض الجدول حتى لا ينهار */ } /* 3. تخصيص عناصر البحث والشكل العام تحت 768px */ @media (max-width: 768px) { .price { text-align: center; /* يوسّط النصوص والعناصر داخل حاوية السعر أفقياً */ } .price input { width: 48%; /* مدخلات السعر تظهر اثنين في كل صف */ } #total { margin: 6px 0; /* يضيف مسافة رأسية بسيطة فوق وتحت عرض الإجمالي */ display: inline-block; /* يجعل صندوق الإجمالي يتصرف كعنصر سطري مع الحفاظ على خصائص الكتلة */ } .btnSearch { flex-direction: column; /* ترتيب أزرار البحث بشكل عمودي */ } .btnSearch button { width: 100%; /* الأزرار تملأ العرض بالكامل */ margin-bottom: 6px; /* مسافة تحت كل زر */ } /* تصغير الحشو وحجم الخط في الجدول */ table th, table td { padding: 4px; /* تقليل الحشو لجعل الجدول أكثر اختصارًا */ font-size: 0.9em; /* تصغير حجم الخط قليلًا */ } } ودور هذه الأكواد هو table-responsive. يضيف حاوية قابلة للتمرير الأفقي مع مسافات علوية وسفلية وكود table-responsive table. يجعل الجدول يملأ عرض الحاوية بالكامل ويمنع انضغاطه لأقل من 600px، وأخيراً في @media (max-width: 768px) تجد تعديلات على مدخلات السعر لتظهر اثنين في الصف، وترتيب أزرار البحث عموديا مع ملء العرض لكل زر وإضافة مسافة رأسية بسيطة فوق وتحت عرض الإجمالي وترتيب الحشو وحجم الخط في خلايا الجدول وكل سطر مكتوب أمامه تعليق يفسر وظيفته. وهذه هي الملفات بعد التعديل index.html style.css
  19. Electron.js هو إطار عمل برمجي يُستخدم في تطوير تطبيقات سطح المكتب التي تعمل على مختلف أنظمة التشغيل وتبدو وكأنها تطبيقات أصلية (native-feeling) لكنها في الأساس تعتمد على تقنيات الويب المعروفة مثل HTML وCSS وJavaScript. الإطار يستفيد من متصفح Chromium المفتوح المصدر لعرض واجهات المستخدم بحيث تظهر وكأنها صفحة ويب داخل نافذة التطبيق وفي نفس الوقت يستخدم Node.js للتعامل مع نظام الملفات المحلي والنظام بشكل عام. وبفضل هذا الدمج يمكن تشغيل التطبيقات بسلاسة على جميع أنظمة التشغيل مثل ويندوز، لينكس، وماك. ومن أشهر الأمثلة على تطبيقات سطح المكتب التي تم تطويرها باستخدام Electron: تطبيق Slack للتواصل بين فرق العمل. تطبيق Figma لتصميم واجهات المستخدم. أما مدى احتياجك لـ Electron.js من عدمه يعتمد هل في المستقبل سوف تحتاج إلى تطوير تطبيقات سطح مكتب أم لا وبالنسبة للشركات تعلمك له بالطبع يعتبر مهارة إضافية تعزز من فرصك للقبول في الوظائف التي تحتاج استخدامه أو بتشتغل على تطبيقات سطح مكتب مبنية بتقنيات الويب. في النهاية هو إطار مبني يستخدم HTML وCSS وJavaScript فلو أنت بالفعل متقن لهذه الأساسيات ستجد تعلمه بسيط وسهل عليك بإذن الله.
  20. لرفع المشروع على netify في البداية عليك بالقيام بعملية البناء للمشروع عن طريق فتح الـ terminal ووضع الأمر npm run build ثم enter ستلاحظ إنشاء مجلد جديد باسم dist هذا المجلد يحتوي على نسخة المشروع الجاهزة للنشر. بعد ذلك نريد رفع إلى netlify الخطوات: افتح موقع https://app.netlify.com سجل دخول بحسابك أو أنشئ حساب جديد. من لوحة التحكم، اضغط على زر Add new site → ثم Deploy manually. اسحب مجلد dist من جهازك وافلته داخل المربع. انتظر لحظات وسيتم رفع المجلد ونشر المشروع. بعد النشر Netlify تستطيع فتح الموقع من خلال الضغط على الزر Open production deploy ستلاحظ فتح الموقع في تبويب جديد. ويوجد مقالة أيضا تتحدث عن رفع مشاريع vue ولكن عن طريق ربط المستودع للمشروع على github بموقع netlify تستطيع الإطلاع عليها
  21. في ملف MyMain.vue يجب تضمين جميع التنسيقات الخاصة بالشاشات الصغيرة داخل البلوك الخاص بـ media@ لاحظ أنك قمت بإغلاق القوس { للبلوك media@ مبكرا في سطر 322 @media(max-width: 778px){ .my-main{ display: flex; flex-direction: column; text-align: center; justify-content: center; } } ^^^^^^^^ .cards{ display: flex; flex-wrap: wrap; .card{ width: 100%; } } لذلك باقي التنسيقات (cards, .skills, .prog.) لا تحتسب ضمن الشاشات الصغيرة وتم تطبيقها على جميع الشاشات بدلا من الشاشات الصغيرة فقط. لذلك يجب حذف هذا القوس { ووضعه في نهاية التنسيقات ليصبح الكود ب الخاص بـ media@ بعد التعديل كالتالي @media(max-width: 778px){ .my-main { display: flex; flex-direction: column; text-align: center; justify-content: center; } .cards { display: flex; flex-wrap: wrap; .card { width: 100%; } } .skills { display: flex; flex-direction: column; text-align: center; .icons { display: flex; flex-wrap: wrap; margin-top: 10px; gap: 10px; } div { width: 100%; } } .prog { display: flex; flex-wrap: wrap; text-align: center; img { width: 500px; } } }
  22. وظيفة هذا الكود هو إعادة ناتج جمع كل العناصر اللي موجودة في المصفوفة myArr ولنفترض لدينا المصفوفة [1, 2, 3, 4] عند استخدام الدالة reduce كالتالي this.myArr.reduce((num1, num2) => num1 + num2) فكرة reduce إنها بتمر على كل عنصر في المصفوفة،وتنفذ عليه عملية (زي الجمع أو الضرب أو أي حاجة) مع ناتج العملية السابقة، وبتفضل تكرر كده لحد ما تختصر المصفوفة لقيمة واحدة بس. في هذا الكود أنت تريد الجمع لو myArr = [1, 2, 3, 4] فـ reduce هتشتغل كالتالي: أول خطوة: 1 + 2 = 3 ثاني خطوة: 3 + 3 = 6 ثالث خطوة: 6 + 4 = 10 وفي الأخر بيرجع 10. يعني السطر ده كله return this.myArr.reduce((num1,num2) => num1 + num2) وظيفته يحسب مجموع كل الأرقام اللي موجودة جوّا المصفوفة myArr ويرجع الناتج. تُستخدم أيضا الدالة ()reduce مع النصوص وأنواع البيانات الأخرى وتكون القيمة المرجعة منها إما رقم أو نص أو أي نوع بيانات أخر. تستطيع المعرفة أكثر عن هذه الدالة في موسوعة حسوب https://wiki.hsoub.com/JavaScript/Array/reduce
  23. هذا عبارة عن كائن اسمه methods وتكون بداخله كل الدوال الخاصة بالمكون في Vue.js فلدينا الآن دالة تدعى getProducts وهي دالة غير متزامنة -أي أنها يمكن أن تنتظر أوامر تأخذ وقتا في التنفيذ، مثل جلب البيانات من الإنترنت - وقمنا بجعلها غير متزامنة عن طريقة إضافة async أمام تعريفها لنستطيع بعد ذلك بداخل هذه الدالة استخدام await مع fetch تقوم الدالة fetch بإرسال طلب إلى https://dummyjson.com/products بعد ذلك نقوم باستخدام then لمعرفة الرد الذي حصلنا عليه وبداخل then نقوم بتحويل الرد إلى صيغة نستطيع التعامل معاها بواسطة الدالة ()json لتحويل الرد إلى صيغة JSON (وهي صيغة يمكننا التعامل معها في JavaScript) ثم قمنا باستخدام then مرة أخري واستخدام البيانات العائدة من الطلب واسنادها إلى الخاصية this.products ليتم عرضها بالمكون.
  24. يوجد خطأ في اسم الملف عليك بتعديل اسم الملف ليصبح index.html وليس index.htmi حيث الامتداد الصحيح هو html. وليس htmi. بعد ذلك قم بفتح المجلد الذي به هذا الملف ثم اضغط بزر الفأرة الأيمن على index.html واختر Open with Live Server.
  25. وعليكم السلام، استخدام النماذج الذكاء الاصطناعي يعتبر مهم في الوقت الحالي لمعظم المطورين ولكن في مرحلة التعلم وبناء أساس قوي لك في أي لغة أو اطار عمل يفضل الابتعاد عن هذه النماذج، على الأقل لابد من حلك للتاسكات بنفسك ثم إعادة تحسينها بذلك قد تكون استفدت من عملية التعلم وتطوير فهمك ومنطقك البرمجي، وستجد القدرة على حل المشكلات بعد ذلك تتطور مع كثرة حلك لهذه للمشكلات بنفسك. تستطيع بعدها سؤال نماذج الذكاء الاصطناعي على حلول أفضل لنفس المشكلة أو تقييم الحل الخاص بك أو تحسيينه. ولكن إذا قمت بالاعتماد على هذه النماذج في الحل مع الوقت ستجد نفسك غارق في أكواد كثيرة لا تفهمها وما هي نتائجاها على تطبيقاتك قد تؤدي لمشاكل أمنية أو مشاكل في الأداء في تطبيقك وسيكون عليك من الصعب إدارة العديد والعديد من الملفات والأكواد وأنت لا تفهمها بشكل جيد وفي بعض الأوقات هذه النماذج تعطي حلول معقدة والمشكلة لا تحتاج لهذا التعقيد للحل. لذلك عليك التركيز على عملية التعلم وحل التاسكات بنفسك ويمكنك الاستعانة بهذه النماذج لشرح موضوع جديد عليك لا تفهمه من التوثيق الرسمي أو تبسيط للمعلومة وليس حل المشكلات لك. بهذه الطريقة ستستفيد بشكل جيد من هذه النماذج وستكون فاهم بنسبة كبيرة الأكواد التي يقدمها لك وتستطيع تقييم الجيد منها والغير جيد وتأثيره في حل المشكلة أو التطبيق وليس استخدامها بدون فهم جيد لها.
×
×
  • أضف...