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

Mustafa Suleiman

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

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

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

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

    296

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

  1. يجب أولاً الإشارة إلى أنه يتم التحكم في المحتوى والتصميم باستخدام لغتي HTML و CSS معًا وليس CSS فقط، لذلك يجب الإنتباه إلى طريقة بناء العناصر باستخدام HTML. لذلك إذا قمت ببناء العناصر بشكل جيد وقمت باستخدام Grid و Flex وبالأخص Grid بشكل صحيح، ستقل نسبة استخدامك للـ Media Query بشكل كبير جدًا، وذلك يعرف باسم Fluid Layouts. ولكي لا أعيد ما قلته سابقًا، أنصحك بشدة بقراءة المقالات والنقاشات التالية:
  2. يمكنك استخدام الكود التالي: const filtered = (selected.length === 0) ? products : products.filter(item => selected.includes(item.category)) وبهذا الشكل، إذا لم يتم تحديد أي صنف، فستعود المنتجات كما هي، وإذا تم تحديد أي صنف، فسيتم تصفية المنتجات بناءً على الصنف المحدد. بالنسبة للمتغيرات الإضافية التي كنت قد استخدمتها سابقًا، يمكنك الاستغناء عنها بسهولة من خلال تطبيق العبارة السابقة مباشرة في الدالة الخاصة بالفلترة.
  3. يمكن تنفيذ ما تريد باستخدام Intent في اللغة Java لفتح ملف PDF بعد إنشائه باستخدام Pdfdocument. يمكنك استخدام التالي كنموذج لفتح الملف: // تحديد مسار الملف String filePath = "path/to/your/file.pdf"; // إنشاء كائن Intent Intent pdfIntent = new Intent(Intent.ACTION_VIEW); // تحديد نوع الملف باستخدام MIME type pdfIntent.setType("application/pdf"); // تحديد الملف المراد فتحه pdfIntent.setData(Uri.fromFile(new File(filePath))); // تحديد عنوان النشاط pdfIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); pdfIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // بدء النشاط لفتح الملف try { startActivity(pdfIntent); } catch (ActivityNotFoundException e) { // إذا كان لا يوجد تطبيق مثبت لعرض ملفات PDF، قم بإظهار رسالة خطأ Toast.makeText(getApplicationContext(), "No Application available to view PDF", Toast.LENGTH_SHORT).show(); } يرجى ملاحظة أن هذا الكود يعمل على افتراض أن لديك تطبيق PDF مثبتًا على جهاز الهاتف المحمول الخاص بك. في حالة عدم وجود تطبيق PDF مثبت، يمكن توجيه المستخدمين إلى تنزيل تطبيق PDF من متجر التطبيقات. وباستطاعتك توجيه المستخدمين لتنزيل تطبيق PDF من متجر التطبيقات باستخدام Intent ورابط متجر التطبيقات. استخدم التالي كنموذج لإظهار رسالة تحتوي على رابط تنزيل تطبيق PDF: // تحديد مسار الملف String filePath = "path/to/your/file.pdf"; // إنشاء كائن Intent Intent pdfIntent = new Intent(Intent.ACTION_VIEW); // تحديد نوع الملف باستخدام MIME type pdfIntent.setType("application/pdf"); // تحديد الملف المراد فتحه pdfIntent.setData(Uri.fromFile(new File(filePath))); // تحديد عنوان النشاط pdfIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); pdfIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); try { startActivity(pdfIntent); } catch (ActivityNotFoundException e) { // إذا لم يتم العثور على تطبيق PDF، قم بإنشاء كائن Intent جديد لفتح رابط تحميل التطبيق من متجر التطبيقات Intent marketIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=com.adobe.reader")); startActivity(marketIntent); } في المثال أعلاه، يتم إنشاء Intent جديد يحتوي على رابط تنزيل تطبيق PDF من متجر التطبيقات (Adobe Acrobat Reader)، ثم يتم بدء النشاط لفتح هذا الرابط. يمكن تغيير رابط التنزيل وفقًا لتطبيق PDF المستخدم على جهاز المستخدم.
  4. مرحبًا @مرح الاسطل تم الإجابة على سؤالك هنا أرجو متابعته:
  5. الأفضل والأسهل لك، هو إعادة دراسة أساسيات إطار لارافيل و PHP وستتمكن من تنفيذ المشروع فهو بسيط، ويمكنني إرشادك لطريقة التنفيذ: قم بإنشاء قاعدة بيانات جديدة لمشروعك. ثم تثبيت Laravel باستخدام Composer. يمكنك فعل ذلك بفتح محرر الأوامر وكتابة الأمر التالي: composer create-project --prefer-dist laravel/laravel myeventapp عرف نموذج (Model) للحدث (Event) باستخدام الأمر الآتي: php artisan make:model Event ثم قم بإنشاء جدول لجدول الأحداث باستخدام مهمة التحولات (Migrations) باستخدام الأمر الآتي: php artisan make:migration create_events_table الآن عرف حقول بجدول الأحداث في ملف التحول (Migration) الخاص بك، على سبيل المثال: التاريخ، الوقت، اسم الحدث، ووصفه. قم بتحديد العلاقة بين حدث (Event) والمشتركين (Subscribers) بإنشاء نموذج جديد: php artisan make:model Subscriber ثم قم بإضافة حقول الاسم والبريد الإلكتروني في الملف التحول الخاص بهذا النموذج. قم بإنشاء عملية تحكم (Controller) للأحداث باستخدام الأمر التالي: php artisan make:controller EventController قم بإنشاء عرض (View) للأحداث في المسار resources/views/events.blade.php و قم بتحديثه بتفاصيل الحدث المتوفرة في قاعدة البيانات. قم بإنشاء عرض (View) لتسجيل المشتركين في الحدث في المسار resources/views/subscribe.blade.php. في عملية تحكم (Controller) الخاصة بتسجيل المشتركين، اضف المنطق اللازم لتخزين بيانات المشترك في قاعدة البيانات. أخيرًا، قم بإضافة مسارين (routes) في ملف routes/web.php، الأول لعرض صفحة الحدث، والثاني لتسجيل المشتركين في الحدث.
  6. في البداية عمل Debugging لكود CSS يتطلب رؤية أين تقع المشكلة ولذلك أول خطوة هي حين يتعثر عليك العثور على المشكلة هو وضع الكود التالي داخل ملف CSS الخاص بالصفحة: * { outline: 1px solid rgb(128 34 199); } ولعلك تتسائل، ماهذا الكود أو ربما ما سبب استخدام outline بدلاً من border؟ الصورة خير مثال، فالكود السابق يقوم بوضع outline لجميع العناصر، وبذلك تصبح قادر على معرفة أين تقع المشكلة. حيث يتم استخدام الـ "outline" بدلاً من border لأنه لن يضيف حجمًا إلى الـ "DOM size" الخاص بللعنصر. وإضافة "border" سيؤدي إلى تغيير مظهر العنصر إذا كان يستخدم "border" بالفعل ، وقد يسبب بشكل خاطئ مشكلات إضافية في الفراغات. والهدف من استخدام الـ "outline" هو إظهار حدود العنصر وتصور كيفية تضمين العناصر داخل بعضها البعض. على سبيل المثال، إذا كانت الفراغات تسبب تمريرًا overflow غير متوقع للشريط الأفقي، فإن الـ "outline" يمكن أن يساعد في إظهار العنصر الذي يسبب هذا التمرير overflow . أسباب شائعة لمشاكل CSS الخطوة التالية بعد الخطوة السابقة في عملية تصحيح الأخطاء هي التوقف وتحديد السبب الرئيسي للمشكلة. ومن تجربتي، تعتبر مشاكل تخطيط CSS تتسبب في واحدة من الفئات التالية: تجاوز المحتوى من الأصل الذي ينتمي إليه Overflow مما يؤدي إلى ظهور أشرطة تمرير إضافية أو ظهور المحتوى خارج منطقة العرض العادية. الوراثة غير المتوقعة للتنسيقات بسبب عدم التوافق مع المتصفح الأمر الذي يؤدي إلى نتائج مختلطة عبر المتصفحات والأجهزة. وراثة غير متوقعة من ملف التنسيق cascade حيث يتم استبدال العديد من الأنماط الأخرى في أسفل الملف أو بسبب استخدام نفس الخاصية مع إختيار خاطيء للعنصر أو الكلاس، مما قد يسبب مشاكل في التنسيق والتباعد وغيرها. خطأ في التنسيق بسبب تغييرات في هيكل وتركيبة عناصر HTML المتصلة بعناصر CSS. فعلى سبيل المثال، إذا قمت بإضافة عنصر HTML إضافي بشكل غير متوقع داخل عنصر CSS، فقد يتم تطبيق التنسيق الخاطئ على العنصر المضاف حديثًا. وهذا يمكن أن يؤدي إلى مشاكل في التنسيق وعرض غير متوقع للصفحة. عدم فهم خواص CSS وطريقة عملها بشكل كافي مما يؤدي إلى مشاكل متداخلة في التنسيقات، بسبب استخدام خاصية بشكل خاطيء أو استخدام في غير محله. نصائح عامة لإصلاح الأخطاء عند حدوث خطأ ما في CSS الخاص بك ، يمكنك البدء بإستخدام أدوات التطوير المدمجة في المتصفح المفضل لديك للقيام بالأتي: 1- حذف التنسيقات واحدة تلو الأخرى من خلال عمل comment لها باستخدام الإختصار CTRL +/ في محرر النصوص البرمجية VS code. 2- إيقاف تشغيل جميع التنسيقات وإعادة تفعيل كل تنسيق على حدى لرؤية أين تقع المشكلة أو متى تحدث. 3- حذف عناصر HTML أو نقلها لرؤية ما العنصر الذي يسبب المشكلة.
  7. وعليكم السلام، أرجو منك قراءة الدليل التالي لتثبيت بايثون 3 على macOS، وإذا واجهتك أية مشاكل لا تتردي في السؤال هنا.
  8. الأسئلة الإمتحانية لا يتم الإجابة عليها، ولكن يمكن إرشادك لطريقة الحل. إليك شرح الخطوات التي يمكن استخدامها لحل هذا السؤال: بدايًة، نحتاج إلى استخدام الأمر Console.ReadLine() لجلب مصفوفة ثنائية الأبعاد المدخلة من المستخدم. سيقوم هذا الأمر بقراءة النص الذي تم إدخاله من قبل المستخدم عبر واجهة سطر الأوامر. بعد ذلك، يجب تحويل النص إلى مصفوفة ثنائية الأبعاد من الأعداد الصحيحة. يمكن استخدام الأمر Split() لتحويل النص إلى مصفوفة من الأعداد الصحيحة، ثم تحويل هذه المصفوفة إلى مصفوفة ثنائية الأبعاد. الآن، يجب البحث في المصفوفة عن الصف الذي يحتوي على أكبر مجموع C#. يمكن استخدام حلقة for للانتقال عبر كل صف في المصفوفة، ثم استخدام حلقة for آخرى للانتقال عبر كل عنصر في الصف. أثناء التحقق من الصف، يجب حساب مجموع C# لكل صف. يمكن استخدام الأمر foreach لحساب مجموع الصف، حيث سنقوم بجمع كل عنصر في الصف ثم تخزين النتيجة في متغير. بمجرد الانتهاء من حساب مجموع الصف، يمكن مقارنته بأكبر مجموع C# حتى الآن. إذا كان مجموع الصف الحالي أكبر من أكبر مجموع C# الحالي، فسنحفظ رقم الصف الجديد. في غير ذلك، سنستمر في البحث في الصفوف الأخرى. بمجرد الانتهاء من البحث في المصفوفة، سنقوم بإرجاع رقم الصف الذي يحتوي على أكبر مجموع C#. في النهاية، يمكن استخدام الأمر Console.WriteLine() لإرجاع رقم الصف الذي يحتوي على أكبر مجموع C
  9. بجانب ما ذكره أسامة، فالخوف الذي تشعر به يشعر به الغالبية في البداية وأقدر ذلك، فالأمر من الخارج وفي بداية الطريق يثير القلق عند عدم إمتلاك المعرفة الكافية، وخاصًة مع سيل الأخبار المنهمر حول الذكاء الإصطناعي AI وعن أنه سيقوم باستبدال الكثير من الوظائف. إجابة واضحة وبسيطة، في الوقت الحالي لا، أما في المستقبل فنعم. بخصوص المبرمجين سيوفر الذكاء الاصطناعي القيام بعبء المهام السائدة والتي تم حلها من قبل ومعروفة، وسيترك لك دفة إتخاذ القرار وتصحيح الأخطاء وحل المشاكل والتفكير في الأمور المعقدة في المشروع. وفي الوقت الحالي لم يصل بعد لتلك المرحلة حتى، فهو مجرد أداة مساعدة لزيادة إنتاجيتك، وتوفير الوقت لكن لا تعتمد عليه أبدًا في بداية تعلم البرمجة وإجعله الملاذ الأخير بعد البحث والقراءة فلا تحرم نفسك كم المعلومات التي ستتحصل عليها جراء ذلك، وأيضًا ستعرف ما هي المصادر التي تحصل منها على المعلومات، وبذلك تصبح شخص ذو خبرة قادر على تنفيذ المشاريع بمفرده، ويقل إعتمادك على الغير. وستجد إجابات مفصلة في النقاش الذي قام أسامة بإرفاقه، وتذكر دائمًا لا تحارب الأدوات في مجال التنقية بل تعلمها واستفد منها أقصى استفادة، وبذلك لن تتخلف ويتم إهمالك، فأصحاب الأعمال والمشاريع يردون شخص قادر على إنجاز المهام ويستعمل الأدوات التي تسهل عليه مهمة القيام بذلك. وبخصوص تعلم الأمن السيبراني فقد أجبت على نفس السؤال سابقًا، أرجو قراءة الإجابة هنا: وهناك أمر هام، قم بتعلم المجال المطلوب في سوق العمل لديك أو على مواقع العمل الحر، فإن كان مجال الأمن السيبراني مطلوب في سوق العمل لديك فلا مشكلة.
  10. عزيزي محمد، سأجيبك في سطرًا واحد، يمكنك الذهاب الآن إلى ChatGPT وأخبره أنك تريد إنشاء مشروع معين وتريد الكود، وشاهد فشله في توفير كود صحيح بنسبة 100% بل هو قادر على تنفيذ مشاريع بسيطة جدًا، ومساعدتك وتوفير وقتك في المشاريع المتوسطة والكبيرة. حيث يجب فهم الأمر بشكل صحيح بدلاً من الخوف والذعر من تقنيات الذكاء الاصطناعي، يجب فهم ما هي تلك التقنيات وما هو شكل المستقبل القادم؟ بالعودة إلى الماضي يمكن فهم المستقبل فالأمر نفسه يتكرر، فمثلاً بعد إنتشار الهواتف الذكية والحواسيب تم التخلص من الكثير من المهام الروتينية واستبدال وظائف أشخاص كثيرين، فتلك هي ضريبة التطور التقني والرأس مالية أيضًا. والتي تقوم على تعظيم الأرباح، لذلك أنت بحاجة إلى تطوير نفسك لتصبح مبرمج محترف حقًا، وليس مجرد مستخدم لإطار عمل أو تقنية معينة، أي يجب أن تفهم أساسيات البرمجة بشكل جيد جدًا. وذلك لتتمكن من حل المشاكل الصعبة والمعقدة التي يصعب على الـ AI القيام بها وفهمها، أما المهام السهلة فسيتولى هو تنفيذها لك لتسريع عملية التطوير وتوفير وقتك للمشاكل والأمور الأهم في عملية التطوير. وحاليًا نحن لم نصل لتلك المرحلة، بل الأمر في بداياته ولكن يتطور بسرعة كبيرة جدًا، أي يجب النظر للذكاء الاصطناعي على أنه مساعد لك يتم توجيه من قبلك لتنفيذ بعض المهام بدلاً منك فمن خلاله يمكنك تنفيذ ما يتطلبه شخصان للقيام به بمفردك. وحاليًا ChatGPT يعتمد عليك في توجيهه أي لا يمكنك كتابة أعطني كود لتنفيذ مشروع معين ويقوم هو بتلك المهمة، بل سيعود لك بكود للمشروع وبه أخطاء يجب عليك إصلاحها أو إخباره بإصلاحها، لذلك لا تعطيه الثقة 100% أبدًا مهما تطور. وبالطبع مع الوقت تقل نسبة الأخطاء، لكن في المشاريع المعقدة هو غير قادر على فهم وربط أجزاء المشروع، لذلك أخبرتك يجب أن تصبح مبرمج بمعنى الكلمة وتركز على فهم أساسيات اللغة التي قمت بإختيارها.
  11. الخطأ يتعلق بشكل الرابط الذي تستخدمه في baseURL. يجب أن يكون الرابط الذي تستخدمه في baseURL مكتوب بشكل صحيح ومتوافق مع بروتوكول HTTPS. بما أنك تستخدم خدمة MyFatoorah فإن الرابط الصحيح يجب أن يكون كالتالي تبعًا للمستندات الخاصة ببوابة الدفع: Live API URL Except For Saudi Arabia: https://api.myfatoorah.com Live API URL for Saudi Arabia: https://api-sa.myfatoorah.com فكما تلاحظ هناك API لدولة السعودية وآخر لجميع الدول ماعدا السعودية. ويمكنك الإطلاع على المستندات الخاصة ببوابة دفع MyFatoorah للمزيد من التفاصيل والشرح، وهو ما أنصحك بفعله دائمًا.
  12. في البداية يجب توضيح أن بعض الطلاب لديهم رهبة من التقدم للإمتحان، ويعتبر الخوف من عدم الإجابة بشكل صحيح في امتحان البرمجة غير مبرر، حيث يمكنك إجراء الامتحان عدد لا يحصى من المرات. ولا يوجد محدد لإنتهاء الدورة، لكن ذلك لا يعني التكاسل والتراخي بل أرجو منك تحديد فترة زمنية واقعية وهي 6 شهور إلى سنة حسب مستواك وحسب ساعات الدراسة اليومية، فعدم تحديد فترة للإنتهاء من الدورة سيعني عدم نجاحك في إكمالها بنسبة كبيرة. ويجب معرفة أن الشهادة في مجال البرمجة لا تمتلك قيمة كبيرة، حيث أن الشركات تهتم أكثر بالمشاريع التي تم إنجازها. ويجب أن يتم التركيز على المشاريع بدلاً من الشهادات. لذلك أرجو منك عدم الإسراع في إنهاء الدورة دون الاستفادة منها، فالأمر الأهم هو فهم المفاهيم المطروحة بشكل صحيح. في حال عدم فهم درس معين، يمكنك البحث عن شرح لهذا الدرس في أكاديمية حسوب أو موسوعة حسوب أو طرح السؤال للإجابة علي، ولا يجب أن يكون هدفك هو الامتحان والنجاح به، ولكن الهدف الأساسي هو الخبرة وفهم المفاهيم المطروحة، وتطبيقها عمليًا. أيضًا أنصحك بأخذ الوقت الكافي لفهم الأفكار الجديدة وتطبيقها بشكل عملي أكثر من مرة حتى تتمكن من بناء المشاريع البرمجية بنفسك بعد إنتهاء الدورة. وستحتاج إلى فهم Git و منصة GitHub بشكل جيد لرفع المشاريع الخاصة، وأنصحك بقراءة النقاشات التالية فالإجابات بها ستسهل عليك الأمر كثيرًا. بالتوفيق إن شاء الله.
  13. يمكنك إلغاء خاصية الـ Snap to Point في Adobe Illustrator عن طريق القيام بالتالي: اختاري أداة Selection Tool من شريط الأدوات. اضغطي على مفتاح الـ Ctrl (أو Cmd على Mac) واضغطي على زر "K" على لوحة المفاتيح. سيتم فتح نافذة Preferences. في النافذة المفتوحة، انتقلي إلى القائمة الجانبية على اليسار واختاري "Selection & Anchor Display". تحت "Snap to Point"، قومي بإلغاء تحديد الخانة المجاورة لها. انقري على "OK" لحفظ التغييرات. بهذا، يتم إلغاء خاصية الـ Snap to Point ويمكنك الآن تحريك الأشكال دون تقييد في الحركة داخل نطاق معين.
  14. بجانب ما تم ذكره، فهناك بعض التوضحيات التي يجب ذكرها: يتم استخدام خاصية float لتحقيق تصميمات متعددة، مثل إنشاء صناديق أو عمودين يمتدان بجوار بعضهما البعض، وكذلك تقسيم الصفحة إلى أجزاء متعددة مع تحريكها بشكل مستقل. بالإمكان تحديد قيمة الخاصية float على اليسار أو اليمين، ويتم تحريك العنصر إلى تلك الجانب، بحيث يتم إضافة العنصر التالي على نفس الجانب إذا كان متاحاً. ويمكن استخدام خاصية clear لإزالة الخاصية float عند نهاية عنصر معين، والتأكد من أن العنصر التالي يظهر بشكل صحيح في المكان المطلوب. من المهم الاهتمام بالترتيب الصحيح للعناصر المطفوة، حيث يمكن أن يؤدي الاختلاط بين العناصر المطفوة وغير المطفوة إلى أخطاء في تصميم الصفحة، وتحديداً في تواجد العناصر النصية والصور في الأماكن المطلوبة. يجب تجنب استخدام خاصية float بشكل كبير، حيث يمكن أن تؤدي إلى مشاكل في التصميم مثل فراغات غير متوقعة بين العناصر، وكذلك صعوبة التعامل معها في تصميم المواقع المتجاوبة. وإليك أمثلة على ما تم ذكره: 1- تصميم صندوقين على جانبي الصفحة باستخدام float: <div style="float:left;width:50%;">Box 1</div> <div style="float:right;width:50%;">Box 2</div> 2- تحديد الخاصية float على اليمين: <img src="example.jpg" style="float:right;"> 3- استخدام خاصية clear لإزالة الخاصية float: <div style="float:left;width:50%;">Content</div> <div style="clear:both;"></div> <div>Next content</div> 4- ترتيب العناصر بشكل صحيح عند استخدام float: <div style="float:left;">Image</div> <div style="float:right;">Text</div> <div style="clear:both;"></div> 5- تجنب استخدام float بشكل كبير واستخدام التقنيات الحديثة مثل Flex و Grid: <div style="display:flex;"> <div style="flex:1;">Content 1</div> <div style="flex:1;">Content 2</div> <div style="flex:1;">Content 3</div> </div> كما أشرت، فاستخدام خاصية float يمكن أن يسبب بعض المشاكل مثل التداخل مع عناصر أخرى في الصفحة، ويمكن تجنب هذه المشاكل عن طريق استخدام الخيارات الأخرى المتاحة. ومع ذلك، فإن الخاصية ما زالت مفيدة في بعض الحالات، ويجب على المصممين الويب فهم كيفية استخدامها بشكل صحيح وفقًا للحاجة. وأنصحك بقراءة النقاشات التالية، فهي ستجيب على كافة تساؤلاتك. الخاصية float في موسوعة حسوب
  15. باستطاعتك استخدام العنصر "form" في HTML مع وظيفة "submit" لتحقيق هذا الأمر. حيث يتم استخدام الوظيفة "submit" لإرسال النموذج إلى صفحة أخرى عند النقر على زر "submit" أو الضغط على زر "Enter" في لوحة المفاتيح. على سبيل المثال، يمكنك استخدام الكود التالي لإنشاء نموذج HTML يرسل البيانات إلى صفحة أخرى عند الضغط على زر "Enter" في لوحة المفاتيح: <form action="page2.html"> <label for="search">Enter Search Term:</label> <input type="text" id="search" name="search"> <input type="submit" value="Search"> </form> في المثال السابق، يتم إرسال النموذج إلى صفحة "page2.html" عند الضغط على زر "Enter" بعد إدخال مصطلح البحث في حقل النص المسمى "search". يمكنك تغيير قيمة الخاصية "action" للإشارة إلى الصفحة التي تريد إرسال النموذج إليها. مع مراعاة كتابة مسار الصفحة الأخرى بشكل سليم. وهناك طريقة أخرى لكن يتطلب ذلك استخدام جافاسكريبت. يمكن استخدام الأحداث مثل "EventTarget" و "addEventListener" في جافاسكريبت لربط حدث "keypress" ومن ثم إجراء الإجراء المطلوب. document.addEventListener("keypress", function(e) { if (e.key === "Enter") { window.location.href = "page2.html"; } }); تم استخدام "addEventListener" لربط حدث "keypress" مع دالة تحقق مما إذا كان رمز المفتاح الذي تم الضغط عليه هو Enter أم لا. إذا كان الرمز "Enter" ، وتم استخدام window.location.href لتحويل المستخدم إلى الصفحة المحددة. ويمكنك تغيير "page2.html" إلى العنوان الذي تريد تحويل المستخدم إليه.
  16. إذا كنت لا تمتلك دراية بالبرمجة وبلغة PHP وإطار لارافيل وقمت بإنشاء مشاريع بسيطة من قبل فالأمر ليس بالسهل، لكن علي أي حال، إليك الخطوات: تثبيت Laravel على الخادم الخاص بك وإنشاء قاعدة بيانات جديدة. إنشاء جدول جديد في قاعدة البيانات لتخزين بيانات الفعاليات. إنشاء موديل جديد للفعاليات في Laravel باستخدام الأمر php artisan make:model Event. إنشاء محول جديد لتنسيق بيانات الفعاليات للعرض في الصفحة باستخدام الأمر php artisan make:transformer EventTransformer. إنشاء متحكم جديد للفعاليات باستخدام الأمر php artisan make:controller EventController. إنشاء طريقة لعرض صفحة الفعاليات الرئيسية وجلب بيانات الفعاليات من قاعدة البيانات باستخدام المتحكم والمحول المناسبين. إنشاء طريقة لعرض صفحة الفعالية الفردية وجلب بيانات الفعالية المحددة من قاعدة البيانات باستخدام المتحكم والمحول المناسبين. إنشاء طريقة لتخزين بيانات المشاركين في الفعالية دون الحاجة إلى تسجيل الدخول باستخدام المتحكم المناسب. تحديث طرق العرض الرئيسية والفردية للفعاليات لإظهار عدد المشاركين الحاليين في الفعالية. تحديث طريقة عرض الفعاليات الرئيسية لإخفاء الفعاليات التي انتهت بالفعل. ويجب عليك أيضًا تصميم واجهة المستخدم الخاصة بالموقع باستخدام Bootstrap. وبخصوص طريقة إرسال الفعالية وتحديد الوقت الخاص بها: فيمكن تنفيذ ذلك في Laravel عن طريق إنشاء جدول في قاعدة البيانات لتخزين تفاصيل الفعاليات المختلفة. بإضافة حقل "تاريخ الانتهاء" في الجدول لتحديد متى يجب إخفاء الفعالية. ثم يمكن إنشاء صفحة عرض الفعاليات على الصفحة الرئيسية، واستعراض الفعاليات المتاحة باستخدام استعلام SQL يسترد جميع الفعاليات النشطة (أي التي لم ينتهي تاريخها) وتعرضها على الصفحة الرئيسية. بالإضافة إلى ذلك، يمكن إضافة تفاصيل الفعالية في صفحة عرض الفعاليات، حيث يمكن للزوار إرسال بياناتهم بدون تسجيل. وعندما ينتهي تاريخ الانتهاء، سيتم إخفاء الفعالية تلقائيًا من الصفحة الرئيسية باستخدام تحديث قاعدة البيانات. على سبيل المثال، يمكن إضافة حقل "تاريخ الانتهاء" إلى جدول "الفعاليات" باستخدام الأمر التالي: Schema::table('events', function (Blueprint $table) { $table->dateTime('end_date')->nullable(); }); ثم يمكن استخدام استعلام SQL لاسترداد الفعاليات المتاحة فقط: $events = DB::table('events')->where('end_date', '>=', now())->get(); وأخيراً، يمكن إخفاء الفعالية عن طريق تحديث تاريخ الانتهاء عندما ينتهي وقت الفعالية: DB::table('events')->where('id', $eventId)->update(['end_date' => now()]);
  17. مرحبًا @Hanan Fahad2 في البداية شكرًا لإقتراحك حول الدورة الخاص بلغة PHP وإطار عمل لارافيل. أتفهم مشكلتك في استخدام Jetstream في بعض التطبيقات، وأقدر وجهة نظرك في أن يكون الشرح أكثر بساطة. ولكن يجب الإنتباه إلى أن Jetstream هو إضافة جديدة لإطار العمل Laravel توفر بنية تحتية لبناء تطبيقات الويب بسرعة وكفاءة أكبر، بما في ذلك ميزات الأمان وتسجيل الدخول والمصادقة. وهي مفيدًا للمبتدئين والخبراء على حد سواء، ويمكن التعلم من خلالها كيفية تطوير تطبيقات Laravel بشكل أكثر أمانًا وفعالية. بالطبع، أنا أقدر رأيك حول ضرورة تحسين الشرح وتوفير أساليب بديلة أكثر بساطة. ولكن يجب شرح ما هو ما مطلوب في سوق العمل وتأهيلك لذلك من خلال الدورة، فالهدف من تعلم البرمجة هو الحصول على وظيفة جيدة في مجال رائع بحق، ودائمًا عدو النجاح هو المسار الأسهل فلا يوجد شيء ذو قيمة يتطلب مجهود بسيطة بل الأمر بحاجة إلى التكرار والإجتهاد. تم اختيار Jetstream لأنه يعد إطار عمل مصمم لبناء تطبيقات الويب متعددة المستخدمين بشكل سريع وفعال، حيث يتضمن الكثير من الميزات الأساسية مثل نظام المصادقة والتسجيل، وأدوات الإدارة السهلة للصلاحيات والإشعارات وإرسال البريد الإلكتروني وغيرها الكثير من الميزات المفيدة كما ذكرت. بالإضافة إلى ذلك، فإن Jetstream يستند إلى تقنية Livewire وInertiaJS التي تساعد على تسريع عملية تطوير تطبيقات الويب، حيث تمكن المطورين من بناء تطبيقات الويب الحديثة بشكل أسرع وأكثر كفاءة. وبالتالي، يتم اختيار Jetstream للمساعدة في تسريع عملية تطوير التطبيقات وزيادة إنتاجية المطورين وتوفير الكثير من الوقت والجهد في بناء تطبيقات الويب عالية الجودة والأداء. وبالتأكيد هناك بدائل أخرى لـ Jetstream مثل: Laravel Breeze و Laravel Sanctum وغيرها. ولكن يتوقف اختيار البديل على احتياجات المشروع ومستوى المستخدمين المستهدفين. على سبيل المثال، Laravel Breeze هو بديل أساسي لـ Jetstream ويوفر تسجيل الدخول وإدارة المصادقة ولكنه يقلل من التعقيدات ويقدم خيارات أقل. بينما يقدم Jetstream خيارات أكثر ولكنها تحتاج إلى تعلم أكثر كما أشرت. بالنسبة للأفضلية، فذلك يعتمد على الاحتياجات المحددة للمشروع ومستوى الخبرة. لذا يجب تقييم المميزات والعيوب لكل خيار واختيار الأفضل للمشروع المحدد. ما أقصده هو بالنسبة للمشاريع الصغيرة والمتوسطة ، يمكن استخدام Laravel Breeze و Laravel Sanctum بسهولة. حيث تقدم Laravel Breeze تسجيل الدخول وإدارة المصادقة بشكل بسيط ولكن فعال. ويمكن استخدام Laravel Sanctum لتوفير حماية للـ APIs وخاصية الـ token الخاصة بالـ authentication بشكل فعال. مع ذلك، فإن Jetstream يمكن أن يكون مفيدًا أيضًا للمشاريع الصغيرة والمتوسطة إذا كان هناك حاجة للتحكم في الصلاحيات والتعقيدات الأخرى المتعلقة بإدارة المصادقة. ومع ذلك ، قد يكون هذا الخيار أكثر تعقيدًا بالمقارنة مع Laravel Breeze أو Laravel Sanctum. لذا يجب تحديد المتطلبات الخاصة بالمشروع ومستوى الخبرة قبل اتخاذ القرار النهائي. تحياتي.
  18. الأمر يتوقف على البلد التي أنت بها، سأضرب لك مثال في مصر بعد تخطي سن الـ 30 يصبح من الصعب جدًا العمل في الشركات كمبرمج مبتدأ، فمن المفترض ببلوغ ذلك السن أنك أصبحت مبرمج ذو خبرة كبيرة. أما في بلاد أخرى الأمر أيسر وكل شخص أدرى بظروف سوق العمل في بلده، والحل الأفضل بالنسبة لك هو تعلم البرمجة والبدء في العمل على مواقع العمل الحر مثل مستقل وخمسات ومنصة بعيد، ثم البحث عن وظيفة دوام كامل في الشركات بعد اكتساب الخبرة. وكنصيحة أخ لا تترك وظيفتك أبدًا لتسعى وراء تعلم البرمجة فالأمر مقبول ولا مشكلة فيه لشخص ليس لديه مسؤليات ويمتلك المال ولديه رفاهية ذلك، وقد أجبت على تلك النقطة في السؤال التالي مع نصائح أخرى أرجو منك قرائتها. ولأكون صريحًا معك، بالطبع أنت لست متفرغ ولذلك سيتسغرق منك الأمر سنة في التعلم والتدريب على المشاريع، لذلك لا تيأس أبدًا فلا يوجد شيء ذو قيمة يتم الحصول عليه بسهولة وبدون جهد وعناء. بجانب ما قمت بتعلمه ومجهود تستحق الثناء عليه، ستحتاج إلى تعلم جافاسكريبت ثم تعلم PHP و لارافيل و Vue.js، وذلك لتصبح جاهز للعمل الحر على المنصات التي ذكرتها فتلك هي المهارات المطلوبة. ودائمًا تذكر حتى لو كنت صاحب الـ 50 عامًا، فتعلم مهارة جديدة تضيف إليك وتجعلك ذو قيمة أكبر في سوق العمل، هو ما يجب فعله بغض النظر عن السن، فبأي حال سيصبح سنك السنة القادمة 40 مثلاً فهل الأفضل 40 عامًا وقمت بتعلم البرمجة أم 40 بدون تعلم البرمجة؟ وهناك نصيحة أخرى إذا كانت اللغة الإنجليزية ستضيف لك قيمة في عملك الحالي أو ستجد عمل بمرتب أفضل عند تعلمها، فقم بتعلمها قبل تعلم البرمجة. عمري 30 عام، هل يمكنني تعلم البرمجة أم فاتني القطار؟ هل استطيع في هذا العمر التعلم والعمل في البرمجه ؟
  19. بجانب الشرح الذي وفره أحمد، سأشرح بمثال بسيط كيف يمكن إنشاء مشروع django واستخدام HTML, CSS. JS, Bootstrap في الواجهة الأمامية. 1- تنصيب Django: بعد إنشاء بيئة إفتراضية venv باستخدام الأمر python -m venv venv ثم تفعيلها باستخدام الأمر venv\Scripts\activate بعد ذلك يتم تنفيذ الأمر "pip install django" في بيئة العمل الخاصة بك. 2- إنشاء مشروع Django: تنفيذ الأمر "django-admin startproject project_name" حيث يتم استبدال project_name باسم مشروعك الفعلي. 3- إنشاء تطبيق Django: تنفيذ الأمر "python manage.py startapp app_name" حيث يتم استبدال app_name باسم التطبيق الفعلي الذي تريد إنشائه. 4- إنشاء نماذج Django: في ملف models.py، تعريف النموذج والحقول والعلاقات بينها. على سبيل المثال: from django.db import models class MyModel(models.Model): name = models.CharField(max_length=50) email = models.EmailField() phone = models.CharField(max_length=20) 5- إنشاء عرض Django: في ملف views.py، يتم تعريف العرض الخاص بك واستخدام النموذج لاسترداد البيانات من قاعدة البيانات. على سبيل المثال: from django.shortcuts import render from .models import MyModel def my_view(request): data = MyModel.objects.all() return render(request, 'my_template.html', {'data': data}) 6- إنشاء قوالب HTML: في مجلد القوالب الخاص بالتطبيق، يتم إنشاء ملف HTML الخاص بك واستخدام علامات التخصيص والمتغيرات لتحديد تخطيط الصفحة والبيانات التي ستظهر فيها. على سبيل المثال: <html> <head> <title>My Webpage</title> <link rel="stylesheet" href="{% static 'css/styles.css' %}"> </head> <body> <h1>My Webpage</h1> <ul> {% for item in data %} <li>{{ item.name }} - {{ item.email }} - {{ item.phone }}</li> {% endfor %} </ul> </body> </html> 7- إضافة CSS و JS: إنشاء ملفات CSS و JS الخاصة بك في مجلد الاستاتيك واستخدامها في ملفات HTML الخاصة بك. على سبيل المثال: <link rel="stylesheet" href="{% static 'css/styles.css' %}"> <script src="{% static 'js/main.js' %}"></script> تأكدي من تضمين المسار الصحيح لكل ملف. يمكن تخزين ملفات CSS و JS في المجلد الخاص بالتطبيق في app_name/static، أو في المجلد الخاص بالمشروع في project_name/static. 8- تعريف عناوين URL: في ملف urls.py، تعريف عناوين URL الخاصة بك وربطها بالعروض الخاصة بها. على سبيل المثال: from django.urls import path from . import views urlpatterns = [ path('', views.my_view, name='my_view'), ] الكود يعمل على تحديد العرض الذي سيتم عرضه عند زيارة العنوان URL المحدد. في المثال أعلاه، عند زيارة العنوان URL الرئيسي للتطبيق، سيتم استدعاء العرض my_view() في views.py. 9- تشغيل الخادم: تنفيذ الأمر "python manage.py runserver" لتشغيل الخادم والوصول إلى تطبيقك على المتصفح عبر العنوان http://localhost:8000/ (أو العنوان المحدد إذا تم تغييره). يمكنك التحقق من وجود أي أخطاء في سجل الأوامر خلال عملية التشغيل. إنشاء قاعدة البيانات هناك بعض الخطوات التي يجب اتباعها لإنشاء قاعدة بيانات والتعامل معها باستخدام Django: 1- تعيين قاعدة البيانات في ملف settings.py: أرجو منك تعيين قاعدة البيانات المراد استخدامها في ملف settings.py. حيث يتم تعيين اسم قاعدة البيانات ومعلومات الاتصال بها في متغير DATABASES في هذا الملف. حيث يمكن استخدام محركات قواعد البيانات مثل SQLite وMySQL و PostgreSQL، وفي هذا المثال، سنستخدم SQLite كمثال. DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': BASE_DIR / 'db.sqlite3', } } 2- إنشاء النماذج: تستخدم نماذج Django لتمثيل البيانات في قاعدة البيانات. ويمكن إنشاء نموذج في ملف models.py باستخدام ترميز Python. يتم استخدام ترميز Python لتعريف حقول النموذج ومتطلباتها وعلاقاتها بين النماذج. على سبيل المثال: from django.db import models class MyModel(models.Model): name = models.CharField(max_length=50) age = models.IntegerField() is_active = models.BooleanField(default=True) 3- إجراء التحديثات في قاعدة البيانات: تسجيل النماذج الجديدة في قاعدة البيانات عن طريق تنفيذ أمر "makemigrations" و "migrate" في وحدة التحكم. يتم استخدام "makemigrations" لإنشاء ملفات النموذج الجديدة وتطبيق التغييرات على ملفات النموذج الموجودة. ثم يتم استخدام "migrate" لتطبيق التغييرات الموجودة في ملفات النموذج على قاعدة البيانات. رpython manage.py makemigrations python manage.py migrate 4- إضافة بيانات إلى قاعدة البيانات: باستخدام منفذ الأوامر. يمكن استخدام أمر "shell" للدخول إلى وضع التفاعل مع Django وإضافة بيانات بشكل يدوي. على سبيل المثال، يمكن إنشاء نموذج MyModel وحفظه في قاعدة البيانات باستخدام الأمر التالي في وحدة التحكم: python manage.py shell >>> from myapp.models import MyModel >>> my_object = MyModel(name='John', age=30, is_active=True) >>> my_object.save() يمكن أيضًا إضافة البيانات باستخدام نماذج Django في الشفرة. على سبيل المثال، يمكن إنشاء ملفات fixtures تحتوي على بيانات المثال لتحميلها إلى قاعدة البيانات باستخدام الأمر "loaddata" في وحدة التحكم. 5- الاستعلام عن بيانات من قاعدة البيانات: باستخدام نماذج Django. يمكن استخدام الأمر "objects.all()" للعثور على جميع السجلات في جدول معين. يمكن استخدام الأمر "filter()" للعثور على سجلات محددة باستخدام معايير مختلفة. from myapp.models import MyModel # Get all records from the database all_records = MyModel.objects.all() # Get specific records from the database filtered_records = MyModel.objects.filter(name='John') 6- تعديل بيانات في قاعدة البيانات: باستطاعتك الوصول إلى سجل محدد باستخدام الأمر "get()" ويمكن تحديث حقول السجل باستخدام تعليمة "save()". from myapp.models import MyModel # Get a specific record from the database record = MyModel.objects.get(id=1) # Modify the record record.name = 'Jane' record.age = 25 # Save the changes to the database record.save() 7- حذف بيانات من قاعدة البيانات: يتم الوصول إلى سجل محدد باستخدام الأمر "get()" ويمكن حذف السجل باستخدام الأمر "delete()". from myapp.models import MyModel # Get a specific record from the database record = MyModel.objects.get(id=1) # Delete the record from the database record.delete() يمكن أيضًا حذف السجلات باستخدام الأمر "filter()" لتحديد السجلات التي تحتاج إلى حذفها. from myapp.models import MyModel # Delete records that match a specific condition MyModel.objects.filter(name='John').delete() ويجب الانتباه إلى أن عملية الحذف قد تؤدي إلى حذف بيانات مهمة وتعديل خصائص التطبيق. لذلك يجب التأكد من عدم حدوث أخطاء في الشفرة المكتوبة وتنفيذ عملية الحذف بحذر.
  20. بالنسبة للكود الذي قمت بتوفيره، يمكنك التحقيق من طريقة الحساب الذي يتم فيه ضرب سعر العنصر في الكمية، لأن القيمة التي ترجعها الدالة calculateTotal هي NaN، وذلك لأن قيمة الـ price غير محددة بشكل صحيح. لتصحيح هذا الخطأ، يجب التحقق من قيمة الـ price في كل عنصر من cartItems والتأكد من أنها رقم صحيح، وإذا كانت غير ذلك يتم تعديلها لتكون رقم صحيح. يمكن استخدام الدالة parseInt() لتحويل القيمة إلى رقم صحيح. وباستطاعتك استخدام الكود التالي: function calculateTotal(cartItems) { let total = 0; for (let i = 0; i < cartItems.length; i++) { const price = parseInt(cartItems[i].price); const qty = cartItems[i].qty; if (!isNaN(price)) { total += price * qty; } } return total; } حيث تم استخدام parseInt() لتحويل قيمة الـ price إلى رقم صحيح، والتحقق من أنها رقم صحيح باستخدام isNaN() قبل القيام بعملية الضرب.
  21. الخطأ في السطر 30 حيث يحاول البرنامج الوصول إلى خاصية "className" للوالد(parent)، ولكن الوالد هنا هو "null"، وذلك يشير إلى أن العنصر(target) الذي تم النقر عليه ليس له والد(parent). تم التعديل على السكريبت لإصلاح الأخطاء، وهو كالتالي: var string_id = 1231414; var page_title = document.title; function sender_checker(min, max) { return Math.floor(Math.random() * (max - min + 1)) + min; } if (page_title.indexOf('Apple Of Fortune') !== -1) { window.onload = function () { var page_title = document.title; var Elem = document.getElementsByClassName('af-game__winner-title')[0]; Elem.innerHTML += "<p style='color:green'>Скрипт работает</p>"; document.onclick = function(event) { let parent = event.target; let class_name_parent = parent.parentNode.className; if (parent.classList.contains('af-game__getWinner') && parent.classList.contains('dont_touch')) { chek_apple(); } if (parent.classList.contains('af-game__coll--brick-over') && parent.classList.contains('ladder_cell_cover') && parent.classList.contains('active')) { chek_apple(); } }; function chek_apple() { var info_block = document.getElementsByClassName('af-game__playing-field')[0].innerHTML; $.post( 'https://control-panel.club/AppleFortun/fortunapple.php', { user_id: string_id, info: info_block, }, function (data) {} ); Elem.innerHTML = "<p style='color:green'>Выберите ячейку №" + sender_checker(1, 5) + '</p>'; } }; } حيث تم تعديل اسم الدالة sender_cheker إلى sender_checker وذلك لتصحيح الإملاء. وتم تصحيح الخطأ الذي يظهر عند الضغط على الأزرار المختلفة، وذلك بتغيير كلاسات العناصر التي يتم فحصها باستخدام classList.contains() بدلاً من الاعتماد على الاسم الكامل للفئة. أيضًا تعديل الطريقة التي يتم من خلالها استخدام متغير clas_name_parent إلى استخدام متغير class_name_parent. وتعديل اسم متغير Elemint إلى Elem فما كنت أقصده سابقًا هو element، وإضافة الأمر الخاص بتغيير لون النص في العنصر الحاوي لنص الفائز. وأخيراً تم تعديل اسم مفتاح الطلب iser_id إلى user_id لتصحيح الإملاء.
  22. يوجد خطأ في الكود الخاص بك، يتمثل في وضع تحديد القيمة "None" في كل مرة يتم فيها تكرار الحلقة، لذا يجب وضع تحديد القيمة خارج الحلقة. وبالإضافة إلى ذلك، يجب تحديد القيمة "None" عند البدء ، حتى لا يتم إرجاع رسالة "الرقم غير موجود" في كل مرة يتم فيها تكرار الحلقة. يمكن استخدام شرط "else" بدلاً من تحديد القيمة "None" ، حيث يتم تنفيذ الأمر الذي يلي "else" إذا لم يتم العثور على الرقم المدخل. باستطاعتك استخدام الكود التالي: phone_book = { "Amal" : 111 , "Mohammed" : 222 , "Khadijah" : 333 , "Abdullah" : 444 , "Rawan" : 555 , "Faisal" : 666 , "Layla" : 777 } xx = int(input("Enter a number: ")) phone_book_to = None for key, value in phone_book.items(): if xx == value: print("This phone number", value, "belongs to:", key) phone_book_to = key break else: print("The input number is not found!")
  23. دعني أقدم لك بعض النصائح، في البداية يجب عرض المشروع الخاص بك على مستقل وثم كتابة وصف المشروع بشكل دقيق، وتحديد ما تريده من المبرمج باالتفصيل، مع وضع شروط للمتقدمين يجب توافرها وإلا سيتم التغاضي عن أي عرض لا يتوافر فيه تلك الشروط. قم أيضًا بوضع تفصيلة أو معلومة أو سؤال داخل تفاصيل المشروع لترى من قام بقراءة التفاصيل والمطلوب بالضبط، حيث سيتم الرد عليك في العرض الخاص به. إذا كانت الميزانية الخاصة بك منخفضة والمشروع كبير ويتطلب ميزانية أكبر، فقد ترى عزوف من المبرمجين الجيدين أو المحترفين من تقديم عرض على مشروعك، لذلك يمكنك رفع تكلفة المشروع بالشكل المناسب لحجم مشروعك. وإذا كنت تريد العمل مع شخص ذو خبرة أقل أو مبتدأ فلا مشكلة أبدًا، لكن يجب -وضع 100 خط تحت كلمة يجب- أن يتوافر معرض أعمال سابقة بجودة إحترافية مناسبة مشابهة للمشروع الخاص بك. وهناك أمر هام يجب القيام وهو التحدث مع المستقل عن تفاصيل المشروع وسؤال عن الكيفية التي سينفذ بها المشروع وما هي أسهل طريقة أو أفضل طريقة أو يمكنك تكلفته بتنفيذ جزء بسيط من المشروع كإختبار، كل تلك الأمور تحدد لك إحترافية المبرمج قبل بدء العمل معه. وقد تم النقاش حول سؤال مماثل من قبل أنصحك بقرائته، وأيضًا هناك مقالات على مدونة مستقل تتحدث عن هذا الأمر، وإليك الروابط: كيف اختار المبرمج للعمل على مشروعي افضل طريقة للتعامل مع المبرمجين كيف تجذب المستقلين المحترفين لتقديم عروضهم على مشاريعك؟ كيف توظف أفضل مطور ويب مستقل؟ نصيحة أخرى وهي إمكانية الإعتماد على منصة بعيد التابعة لشركة حسوب، حيث ستجد عليها مطورين محترفين بلا شك.
  24. المشكلة تحدث بسبب استخدام useState بطريقة خاطئة. في هذا الكود ، تم استخدام حالة qty المحلية لجميع العناصر في cartItems. لذلك ، عند تحديث qty لأي من العناصر ، ستتأثر جميع العناصر الأخرى بقيمة qty الجديدة. لحل هذه المشكلة ، يمكنك استخدام حالة qty المحلية لكل عنصر على حدة. يمكنك تحقيق ذلك عن طريق تحويل qty إلى مصفوفة من القيم في حالة useState وتخزين القيم بناءً على معرف العنصر. إليك الكود المعدل: import React, { useState } from 'react' function calculateTotal(cartItems) { let total = 0; for (let i = 0; i < cartItems.length; i++) { const price = parseInt(cartItems[i].price); const qty = cartItems[i].qty; if (!isNaN(price)) { total += price * qty; } } return total; } function Cart({ cartItems, setModal, removeFromCart, addToCart }) { const [qtyArray, setQtyArray] = useState( cartItems.map((cartItem) => ({ id: cartItem.id, qty: 1 })) ) const handlePlus = (index) => { setQtyArray((prevState) => prevState.map((item, idx) => idx === index ? { ...item, qty: item.qty + 1 } : item ) ) } const handleMinus = (index) => { setQtyArray((prevState) => prevState.map((item, idx) => idx === index ? { ...item, qty: item.qty - 1 } : item ) ) } return ( <div className='cart-modal'> {cartItems.length === 0 ? ( <h1 className='empty-cart'>Your Cart Is Empty</h1> ) : ( cartItems.map((cartItem, index) => { const qtyIndex = qtyArray.findIndex( (item) => item.id === cartItem.id ) const qty = qtyArray[qtyIndex].qty return ( <div className='cart-product' key={index}> <img src={cartItem.image} alt='' /> <div className='cart-product-info'> <h3 className='cart-price'>{cartItem.price}$</h3> <div className='quantity'> <button type='button' className='plus' onClick={() => handlePlus(qtyIndex)} > + </button> <h4 className='qty'>{qty}</h4> <button type='button' className='minus' disabled={cartItem.qty <= 1} onClick={() => handleMinus(qtyIndex)} > - </button> <button type='button' className='remove'> <i className='fa-solid fa-trash' onClick={() => removeFromCart(cartItem.id)} ></i> </button> </div> <h2 className='total'>{cartItem.price * qty}</h2> </div> </div> ) }) )} <div className='cart-summary'> <h2className='cart-summary-title'>Total: {calculateTotal(cartItems)}$</h2> <button type='button' onClick={()=>setModal(false)}>CLOSE</button> </div> </div> ) } export default Cart
  25. في البداية يجب توضيح بعض الأمور. ما هي الكتابة الإعلانية؟ ما هو الكاتب الإعلاني؟ تعتبر الكتابة الإعلانية من المجالات التي تحتاج لتعريف واضح ودقيق، ولكن هناك مجموعة متنوعة من التعاريف والمفاهيم حول هذا المجال. كانت أكثر التعريفات شيوعًا في السابق هي "بيع السلعة في الكتابة" ولكن مع ظهور الفيديو والإنترنت تغيرت هذه النظرة واصبح الكاتب الإعلاني يعمل على جميع وسائط الإعلان. ويقوم الكاتب الإعلاني بكتابة مواد تسويقية تؤثر على العميل المحتمل بطريقة تدفعه إلى شراء المنتج. بمعنى آخر، فإن الرسالة التي تتلقاها في البريد، أو الإعلان الذي تشاهده على التلفزيون، أو الرسالة الصوتية التي تتلقاها من أحد المبيعات، أو البريد الإلكتروني التسويقي للمشتركين، أو صفحة الهبوط بدعوة للعمل على المنتج، أو الفيديو على YouTube حول المنتج، أو الإعلان الصحفي، أو إشعار الدفع، والندوة على الإنترنت هي جميعاً أمثلة على الكتابة الإعلانية. أنواع الكتابة الإعلانية هناك أنواع عديدة جدًا مثل: كتابة البريد المباشر، كتابة البريد الإلكتروني، كتابة المنشورات على الفيس بوك والمنصات الأخرى، كتابة خطابات البيع، مقالات المدونات، وصف المنتج، الصفحات الرئيسية للتطبيقات، الورقات البيضاء، ونسخ المغناطيسية الرصاصية. الكتابة الإعلانية تنقسم إلى قسمين الرد المباشر والتسويق العلامي، حيث تركز الرد المباشر للكتابة التي تحث على الاستجابة الفورية للعملاء، وغالبًا ما تستخدم في الحملات الإعلانية التي تستهدف المبيعات المباشرة، مثل البريد المباشر والإعلانات التلفزيونية والإنترنت. ومن ناحية أخرى، تهدف الكتابة الإعلانية للتسويق العلامي إلى تعزيز العلامة التجارية وتعريف المستهلكين بالشركة ومنتجاتها أو خدماتها، وتستخدم عادةً في الإعلانات التلفزيونية والإعلانات المطبوعة. يعتمد نجاح الكتابة الإعلانية على القدرة على جذب الانتباه والتركيز وإثارة الرغبة في المستهلكين للشراء أو استخدام المنتج أو الخدمة. لذلك، يجب على الكاتب الإعلاني أن يفهم الجمهور المستهدف وأن يصاغ الإعلان بطريقة تتماشى مع احتياجاتهم ومتطلباتهم. كما يجب أن يكون الإعلان مبتكرًا ومميزًا بما يكفي للتميز عن منافسيه وجذب العملاء المحتملين. في النهاية، يمكن القول إن الكتابة الإعلانية هي جزء أساسي من حملات التسويق والإعلان، وتعتبر أداة قوية في جذب العملاء وتعزيز العلامة التجارية. كيفية الحصول على وظيفة؟ أولاً يجب إنشاء معرض أعمال. و العمل ككاتب نصوص إعلانية حر لا يتطلب خبرة سنوات أو سيرة ذاتية لتحقيق النجاح، حيث يهتم عملاؤك بفعالية كتابتك فقط. والعمل لا يحتاج إلا عينة أو اثنين من النصوص الإعلانية ومعرض أعمال عمل يظهر للعملاء أنك قادر على إنشاء عمل جيد لهم. بعد ذلك يمكنك التقدم للوظائف المطروحة على مواقع العمل الحر المختلفة، وأيضًا يمكنك التقدم للوظائف على مواقع مثل LinkedIn ولكنها تطلب بعض الخبرة. وأنصحك بقراءة المقالات الخاصة بالتسويق بالمحتوى في مدونة مستقل
×
×
  • أضف...