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

كل الأنشطة

تحدث تلقائيًا

  1. الساعة الماضية
  2. أعمل على مشروع تجارة الكترونى ب Next.js واستخدم strapi فى الواجهه الخلفية وقمت بربط strapi بـ cloudinary لتخزين الصور والى ما شابه ولكن بعد ذلك بعد رفع الصور من strapi يقول ان هنا هناك خطأ فى السيرفر كما هو موضح بالصور ومرفق ايضا الخطأ الذى يظهر فى ال terminal أرجو الافادة اثابكم الله كل خير شكرا مقدما front-end.rar back-end.rar
  3. اليوم
  4. هل يمكنك توضيح سؤالك أكثر ؟ ماذا تقصد بعدم معرفة اللغة الإنجليزية أتقصد في الدورات المقدمة هنا على الأكاديمية أم شئ أخر
  5. عادي اكون ماعرف اللغه الانجليزيه
  6. شكرن لك ان مبتدى في علم لينكس ليستومحترف توجهني بعط المشكل فتحمبل الفديو واطفه الميستوداعت والمخنزن يزيد هبلي وحده تخص العب تخصى العب لي كول وحد تخص الترمنال في الومر الربط النسخ
  7. مرحباً عبد السلام , اختيار أفضل نسخة لينكس يعتمد على احتياجاتك وتفضيلاتك الشخصية، ولكن هناك بعض التوزيعات الشهيرة والمحبوبة التي تتميز بتوفر عدد كبير من المستودعات ودعم واسع من المجتمع: Ubuntu واحدة من أكثر التوزيعات شهرة وسهولة في الاستخدام. مستودعات كبيرة مع دعم واسع للتطبيقات. تحديثات منتظمة ودعم طويل الأجل للإصدارات LTS. Debian: الأساس للعديد من التوزيعات الأخرى، بما في ذلك Ubuntu. مستودعات ضخمة تحتوي على آلاف الحزم. معروفة باستقرارها وموثوقيتها. Fedora: تقدم أحدث التقنيات والابتكارات في عالم لينكس. مستودعات جيدة ودعم متقدم للتطبيقات الحديثة. مدعومة من Red Hat، مما يجعلها خيارا قويًا لمطوري البرمجيات. Arch Linux: مثالية للمستخدمين المتقدمين الذين يريدون تخصيص نظامهم من الألف إلى الياء. مستودعات AUR (Arch User Repository) تحتوي على آلاف الحزم التي يتم صيانتها بواسطة المجتمع. توفر تحديثات مستمرة (rolling release). أيضاً كل من هذه التوزيعات تتمتع بدعم مجتمعي قوي، وتوفر مستودعاتها كمية كبيرة من البرمجيات والتطبيقات المختلفة.
  8. ابي ان اكون محترف في لينكس في البرمج
  9. السلام عليكم. بعد تقييم منتج محدد أريد إظهار التقييم على الواجهة البرمجية. Slice import { createSlice } from "@reduxjs/toolkit"; const bookSlice = createSlice({ name: "book", initialState: { books: [], reviews: [], error: false, loading: false, }, reducers: { addReviews(state, action) { state.books = action.payload }, getReviews(state, action) { state.reviews = action.payload; }, setLoading(state) { state.loading = true; }, clearLoading(state) { state.loading = false; }, } }) const bookReducer = bookSlice.reducer; const bookActions = bookSlice.actions; export {bookActions, bookReducer} apiCall // Get Book Reviews export function getBookReviews(bookId) { return async (dispatch, getState) => { try { dispatch(bookActions.setLoading()) const {data} = await axios.get(`${BOOK_URL}/${bookId}/reviews`, { headers: { "authorization": getState().auth.user.accessToken } }); dispatch(bookActions.getReviews(data)); dispatch(bookActions.clearLoading()); } catch (error) { toast.error(error?.response?.data.message); dispatch(bookActions.clearLoading()); } }; } // Post Review export function postReview(bookId, review) { return async (dispatch, getState) => { try { dispatch(bookActions.setLoading()) const {data} = await axios.post(`${BOOK_URL}/${bookId}/reviews`, review, { headers: { "authorization": getState().auth.user.accessToken } }); toast.success(data?.message) dispatch(bookActions.addReviews()) dispatch(bookActions.getReviews(review)); dispatch(bookActions.clearLoading()); } catch (error) { toast.error(error?.response?.data.message); dispatch(bookActions.clearLoading()); } }; } React Component // Get Book Reviews export function getBookReviews(bookId) { return async (dispatch, getState) => { try { dispatch(bookActions.setLoading()) const {data} = await axios.get(`${BOOK_URL}/${bookId}/reviews`, { headers: { "authorization": getState().auth.user.accessToken } }); dispatch(bookActions.getReviews(data)); dispatch(bookActions.clearLoading()); } catch (error) { toast.error(error?.response?.data.message); dispatch(bookActions.clearLoading()); } }; } // Post Review export function postReview(bookId, review) { return async (dispatch, getState) => { try { dispatch(bookActions.setLoading()) const {data} = await axios.post(`${BOOK_URL}/${bookId}/reviews`, review, { headers: { "authorization": getState().auth.user.accessToken } }); toast.success(data?.message) dispatch(bookActions.addReviews()) dispatch(bookActions.getReviews(review)); dispatch(bookActions.clearLoading()); } catch (error) { toast.error(error?.response?.data.message); dispatch(bookActions.clearLoading()); } }; } Review.jsx import moment from "moment"; import React from "react"; import Rating from "../rating/Rating"; import { Oval } from "react-loader-spinner"; import { useSelector } from "react-redux"; function Reviews() { const { loading, reviews } = useSelector((state) => state.book); return ( <div className="get-reviews"> <h2 className="get-reviews-title">Reviews ({reviews?.length})</h2> <div className="reviews"> {loading ? ( <Oval height={120} width={120} color="rgb(247, 96, 14)" wrapperStyle={{ height: "90vh", display: "flex", alignItems: "center", justifyContent: "center", }} wrapperClass="" visible={true} ariaLabel="oval-loading" secondaryColor="#E2E2E2" strokeWidth={3} strokeWidthSecondary={3} /> ) : ( Array.isArray(reviews) && reviews.map((el, key) => ( <div className="user-review" key={key}> <p> <span>{el?.username ? el?.username : "Unknown User"}</span>{" "} {`- `} {moment(el?.createdAt).format("DD MMM YYYY")} </p> <Rating rating={el?.rate} /> <p>{el?.comment}</p> </div> )) )} </div> </div> ); } export default Reviews; شكرا
  10. افضل نسخ مستقره في لينكس و مستودعاته كثير معى البرنامج الحرق usb
  11. كما تم التوضيح في التعليقات السابقة فتحديد المدة الزمنية اللازمة لإنشاء تطبيق يعتمد على العديد من العوامل، ولكن هناك بعض الخطوات والنصائح التي يمكن أن تفيدك كمايلي أولاً يجب عليك تحديد ومعرفة جميع المتطلبات والوظائف التي يجب أن يحتويها التطبيق. بعد ذلك ستقوم بتقسيم المشروع إلى مهام صغيرة مع تقدير الزمن اللازم لكل مهمة على حدة. ومع خبرتك السابقة في مشاريع مشابهة ستجد أنه لا يوجد مشكلة هنا. كما أنه دائمًا ما تكون هناك مهام غير متوقعة أو تأخيرات في المشاريع. لذلك، يفضل إضافة وقت احتياطي إلى تقديرك الكلي. ومع ذلك يجب معرفة المدة الزمنية التي يتوقع العميل أن تقوم بإنجاز العمل بها فإذا كان لا يهمه كثيراً الوقت يمكنك تنفيذه في مدة زمنيه مناسبة بالنسبة لك ولكن إذا كان مستعجلاً فيفضل إنجاز العمل سريعاً
  12. تُعد فكرة الوعود Promises أساسًا للغة جافا سكريبت غير المتزامنة. والوعد هو كائن يُعاد من الدالة غير المتزامنة ويمثّل الوضع الراهن للعملية. ولا تكون العملية قد انتهت بعد في الوقت الذي تعيد في الدالة الوعد إلى مستدعيها، لكن كائن الوعد المُعَاد يمتلك توابع لمعالجة التنفيذ الناجح أو المخفق للعملية. تحدثنا في المقال السابق عن استخدام الاستدعاءات لإنجاز الدوال غير المتزامنة. إذ نستدعي وفق هذا اﻷسلوب الدالة غير المتزامنة ممررين إليها دالة استدعاء أخرى تسمى دالة رد النداء callback، عندها تُعيد هذه الدالة قيمتها مباشرة، ثم تستدعي بعد ذلك دالة رد النداء التي مررناها عندما تنتهي العملية. وما يحدث في الواجهات البرمجية المبنية على الوعود، أن الدالة غير المتزامنة تبدأ عملية ما وتعيد كائن وعد Promise، وبإمكانك حينها ربط هذا الكائن بمعالجات أحداث ستُنفَّذ عند نجاح أو إخفاق هذه العملية. استخدام الواجهة البرمجية fetch ملاحظة: سنتعلم مفهوم الوعود في هذا المقال بنسخ عينات من الكود البرمجي من الصفحة إلى طرفية جافا سكريبت في المتصفح. وﻹعداد هذا اﻷمر: انتقل إلى الموقع: https://example.org افتح طرفية جافا سكريبت الموجودة ضمن أدوات مطوري الويب في نفس النافذة الفرعية. عندما نعرض مثالًا ما، انسخه إلى الطرفية، وعليك حينها إعادة تحميل الصفحة في كل مرة تُلصق فيها مثالًا جديدًا، وإلا تعترض الطرفية لأنك أعدت تصريح المتغير fetchPromise. سننزل في هذا المثال ملف JSON ونسجّل بعض المعلومات المتعلقة به، ولتنفيذ اﻷمر نرسل طلب HTTP إلى الخادم يتضمن رسالة مرسلة إليه وننتظر الاستجابة. ففي مثالنا سنطلب ملف JSON من الخادم. وكما أشرنا في المقال السابق، نستخدم الواجهة البرمجية XMLHttpRequest لتنفيذ طلبات HTTP، لكننا سنستخدم في هذا المقال الواجهة البرمجية ()fetch وهي بديل أحدث عن كائن XMLHttpRequest ومبنية على الوعود. انسخ اﻵن الشيفرة التالية إلى طرفية جافا سكريبت في متصفحك: const fetchPromise = fetch( "https://mdn.github.io/learning-area/javascript/apis/fetching-data/can-store/products.json", ); console.log(fetchPromise); fetchPromise.then((response) => { console.log(`Received response: ${response.status}`); }); console.log("Started request…"); ما فعلناه في هذه الشيفرة هو التالي: استدعينا الواجهة()fetchوأسندنا القيمة التي تعيدها إلى المتغير fetchPromise. سجلنا بعد ذلك مباشرة قيمة المتغير، ومن المفترض أن تشبه النتيجة ما يلي: Promise { <state>: "pending" }، لتخبرنا أنه لدينا كائن وعد Promise له حالة قيمتها "pending" ويعني ذلك أن عملية إحضار الملف لا تزال قيد التنفيذ. مررنا دالة معالجة إلى التابع ()then العائد لكائن الوعد، فإن نجحت العملية وعندما تنتهي، يستدعي الوعد دالة المعالجة التي نمرر إليها كائن الاستجابة Response الذي يضم استجابة الخادم. طبعنا الرسالة "…Started request" لتدل على أننا بدأنا تنفيذ الطلب. من المفترض أن يكون خرج الشيفرة السابقة كالتالي: Promise { <state>: "pending" } Started request… Received response: 200 لاحظ كيف ظهرت العبارة "Started request" على الشاشة قبل تلقي الاستجابة. فعلى خلاف الدوال المتزامنة، تعيد()fetch قيمتها قبل أن يكتمل الطلب، مما يسمح للبرنامج بمتابعة التنفيذ. ثم يعيد البرنامج بعد ذلك رمز الحالة 200 ويعني أن الطلب قد نُفِّذ بنجاح. قد يبدو هذا المثال مشابهًا للمثال في المقال السابق الذي استخدمنا فيه معالجات أحداث على الكائن XMLHttpRequest، لكننا مررنا هذه المرة دالة معالجة إلى التابع ()then العائد لكائن الوعد الذي تعيده الدالة()fetch. سلسلة من الوعود بمجرد حصولك على كائن استجابة Response باستخدام الواجهة()fetch، عليك استدعاء دالة أخرى للحصول على بيانات الاستجابة، ونريدها في هذه الحالة على هيئة بيانات JSON لهذا نستدعي التابع ()json العائد للكائن Respond. وكذلك الأمر، التابع ()json غير متزامن، هنا سنكون أمام حالة نستدعي فيها دالتين غير متزامنتين على التوالي. جرّب اﻵن ما يلي: const fetchPromise = fetch( "https://mdn.github.io/learning-area/javascript/apis/fetching-data/can-store/products.json", ); fetchPromise.then((response) => { const jsonPromise = response.json(); jsonPromise.then((data) => { console.log(data[0].name); }); }); أضفنا في هذا المثال أيضًا التابع ()then إلى الوعد الذي تعيده ()fetch. لكن المعالج سيستدعي هذه المرة()response.json ومن ثم يمرر معالج ()then جديد إلى الوعد الذي يعيده التابع ()response.json. يُفترض في هذه الحالة طباعة العبارة في الطرفية (وهو اسم أول منتج في القائمة التي يضمها الملف "products.json"). لكن مقارنة مع الاستدعاءات التي شرحناها في مقال سابق، سنجد أننا نستدعي التابع ()then ضمن تابع ()then آخر وهذا مشابهة لفكرة استدعاء دالة استدعاء ضمن دالة استدعاء بشكل متعاقب، وكنا قد قلنا بأن هذا اﻷمر سيزيد من صعوبة قراءة الشيفرة وفهمها، وأطلقنا عليه اسم "جحيم الاستدعاء callback hell"، وما يحدث هنا أمر مشابه لكن مع الدالة ()then! نعم، اﻷمر نفسه تمامًا، لكن الوعد يقدم ميزة خاصة وهي أن التابع ()then يعيد هو أيضًا وعدًا يكتمل بنتيجة الدالة التي مُرر إليها. لهذا من اﻷفضل إعادة كتابة المثال السابق كالتالي: const fetchPromise = fetch( "https://mdn.github.io/learning-area/javascript/apis/fetching-data/can-store/products.json", ); fetchPromise .then((response) => response.json()) .then((data) => { console.log(data[0].name); }); فبدلًا من استدعاء تابع ()then آخر ضمن معالج التابع ()then الأول، يمكننا إعادة الوعد الذي يعيده التابع ()json ثم نستدعي التابع ()then الثاني على القيمة المُعادة. يُدعى هذا اﻷمر بسلسلة الوعود Promise chaining، ونستطيع من خلال هذه الميزة تفادي زيادة مستوى التداخل عندما نضطر إلى استدعاء الدوال غير المتزامنة بشكل متتالٍ. قبل الانتقال إلى الخطوة التالية، علينا إضافة شيء آخر، وهو التأكد من قبول الخادم للطلب وقدرته على معالجته قبل أن نحاول قراءة الاستجابة، ولتنفيذ اﻷمر نتحقق من رمز حالة الطلب ونعرض خطأ إن لم يكن رمز الحالة 200 (أو OK) const fetchPromise = fetch( "https://mdn.github.io/learning-area/javascript/apis/fetching-data/can-store/products.json", ); fetchPromise .then((response) => { if (!response.ok) { throw new Error(`HTTP error: ${response.status}`); } return response.json(); }) .then((data) => { console.log(data[0].name); }); التقاط اﻷخطاء وصلنا حاليًا إلى الجزء اﻷخير المتعلق بمعالجة الأخطاء. إذ يمكن للواجهة البرمجية ()fetch رمي أخطاء لأسباب عديدة مثل عدم وجود اتصال بالشبكة أو تمرير عنوان URL غير صالح وغيرها من الأسباب، وبإمكاننا أيضًا رمي أخطاء بأنفسنا إن أعاد الخادم حالة خطأ. ورأينا في المقال السابق أن معالجة اﻷخطاء قد يغدو صعبًا عند تداخل الاستدعاءات ويدفعنا لمعالجة اﻷخطاء في كل مستوى على حدة. ولمعالجة اﻷخطاء، يقدّم الكائن Promise التابع ()catch الذي يشبه كثيرًا التابع ()then من حيث استدعاؤه وتمريره إلى دالة المعالجة. لكن ما يحدث أن استدعاء التابع ()catch يكون عند إخفاق العملية غير المتزامنة وليس نجاحها. فلو أضفت ()catch إلى نهاية سلسلة الوعود، سيُستدعى هذا التابع إن أخفقت أية دالة غير متزامنة في السلسلة. أي بإمكانك إنجاز أي عملية غير متزامنة على شكل سلسلة من الدوال غير المتزامنة المتتابعة التي تنتهي بتابع يعالج جميع اﻷخطاء. جرّب هذه النسخة التي تستخدم ()catch وتُعدّل عنوان URL حتى تُخفق العملية: const fetchPromise = fetch( "bad-scheme://mdn.github.io/learning-area/javascript/apis/fetching-data/can-store/products.json", ); fetchPromise .then((response) => { if (!response.ok) { throw new Error(`HTTP error: ${response.status}`); } return response.json(); }) .then((data) => { console.log(data[0].name); }) .catch((error) => { console.error(`Could not get products: ${error}`); }); نفّذ الشيفرة السابقة، ومن المفترض أن ترى الخطأ الذي يعرضه التابع ()catch. المصطلحات الخاصة بالوعود تستخدم الوعود مجموعة مخصصة من المصطلحات التي لا بد من توضيحها. بداية للوعد حالة من ثلاث حالات وهي كالتالي: قيد التنفيذ pending: يُنشأ كائن الوعد في هذه الحالة، لكن الدالة غير المتزامنة المرتبطة به لم تنجح أو تخفق بعد. وتوافق هذه الحالة إعادة الوعد إلى الدالة بعد استدعاء()fetch بينما لا يزال الطلب قيد التنفيذ. منجز fulfilled: وهي حالة نجاح العملية غير المتزامنة، ويُستدعى حينها التابع ()then. مرفوض rejected: وهي حالة إخفاق العملية غير المتزامنة، ويُستدعى عندها التابع ()catch. أما معنى "النجاح" أو "اﻹخفاق" فيعود للواجهة البرمجية المستخدمة. فالواجهة()fetch مثلًا ترفض الوعد المعاد لأسباب منها خطأ في الشبكة يمنع إرسال الطلب، وتنجزه عندما يعيد الخادم الاستجابة حتى لو كانت اﻹستجابة حالة خطأ مثل 404 Not Found. كما نستخدم أيضًا مصطلح "مسوّىً settled" ليشير إلى حالتي الرفض أو اﻹنجاز. ونقول عن الوعد أنه "مقضي resolved" إن جرت "تسويته settled" أو كان "مقفلًا locked in" بانتظار حالة وعد آخر. الجمع بين عدة وعود إن تكوّنت العملية غير المتزامنة من عدة دوال نستخدم حينها سلسلة من الوعود، ولا بد حينها من تسوية كل وعد قبل الانتقال إلى اﻵخر. لكنك قد تحتاج أحيانًا إلى الجمع بين عدة استدعاءات لدوال غير المتزامنة، لهذا تزوّدك الواجهة البرمجية ()Promis ببعض الدوال المساعدة. قد يتطلب الأمر في بعض التطبيقات إنجاز عدة وعود لا تتعلق ببعضها البعض. والطريقة اﻷكثر فعالية لتنفيذ هذا اﻷمر هي استدعاء جميع الدوال في نفس الوقت، ثم الحصول على تنبيه عندما تنجز جميعها، وهذا ما يقدمه التابع ()Promise.all فهو يُعيد مصفوفة من الوعود كما يعيد وعدًا واحدًا، ويكون هذا الوعد: منجزَا: عندما تُنجز كل الوعود في المصفوفة. ويُستدعى عند ذلك معالج التابع ()then وتُمرّر له مصفوفة من الاستجابات وبنفس ترتيب الوعود التي مُررت إلى التابع ()all. مرفوضًا: إن رٌفض أي من وعود المصفوفة، ويُستدعى عند ذلك معالج التابع ()catch ويُمرر له الخطأ الناتج عن الوعد الذي رُفض. إليك مثالًا: const fetchPromise1 = fetch( "https://mdn.github.io/learning-area/javascript/apis/fetching-data/can-store/products.json", ); const fetchPromise2 = fetch( "https://mdn.github.io/learning-area/javascript/apis/fetching-data/can-store/not-found", ); const fetchPromise3 = fetch( "https://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json", ); Promise.all([fetchPromise1, fetchPromise2, fetchPromise3]) .then((responses) => { for (const response of responses) { console.log(`${response.url}: ${response.status}`); } }) .catch((error) => { console.error(`Failed to fetch: ${error}`); }); نفّذنا في الشيفرة السابقة ثلاثة طلبات()fetchإلى ثلاثة عناوين URL مختلفة، فإن نجحت هذه الطلبات، نعرض حالة الاستجابة لكل طلب، وإن أخفقت إحداها، نطبع الخطأ. ينبغي أن تُنجز الطلبات جميعها لأن العناوين صحيحة، مع ملاحظة أن رقم الحالة للطلب الثاني سيكون 404 بدلًا من 200 لأن الملف الذي نطلبه غير موجود حقيقة. لهذا سيكون خرج الكود السابق على النحو التالي: https://mdn.github.io/learning-area/javascript/apis/fetching-data/can-store/products.json: 200 https://mdn.github.io/learning-area/javascript/apis/fetching-data/can-store/not-found: 404 https://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json: 200 جرّب أن تنفّذ الشيفرة السابقة بعد كتابة العناوين بشكل خاطئ: const fetchPromise1 = fetch( "https://mdn.github.io/learning-area/javascript/apis/fetching-data/can-store/products.json", ); const fetchPromise2 = fetch( "https://mdn.github.io/learning-area/javascript/apis/fetching-data/can-store/not-found", ); const fetchPromise3 = fetch( "bad-scheme://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json", ); Promise.all([fetchPromise1, fetchPromise2, fetchPromise3]) .then((responses) => { for (const response of responses) { console.log(`${response.url}: ${response.status}`); } }) .catch((error) => { console.error(`Failed to fetch: ${error}`); }); نتوقع اﻵن أن تُنفَّذ دالة المعالجة الخاصة بالتابع ()catch، ومن المفترض حينها أن يكون الخرج مشابهًا للتالي: Failed to fetch: TypeError: Failed to fetch وقد تريد في بعض الحالات أن يُنجز أحد الوعود ولا يهم أيها، عندها يمكنك الاستفادة من التابع ()Promise.any الذي يشابه ()Promise.all لكنه يُنجز بمجرد إنجاز أي وعد في مصفوفة الوعود، ويُرفض إن رُفضت جميع الوعود: const fetchPromise1 = fetch( "https://mdn.github.io/learning-area/javascript/apis/fetching-data/can-store/products.json", ); const fetchPromise2 = fetch( "https://mdn.github.io/learning-area/javascript/apis/fetching-data/can-store/not-found", ); const fetchPromise3 = fetch( "https://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json", ); Promise.any([fetchPromise1, fetchPromise2, fetchPromise3]) .then((response) => { console.log(`${response.url}: ${response.status}`); }) .catch((error) => { console.error(`Failed to fetch: ${error}`); }); ملاحظة: لا يُمكن في هذه الحالة توقّع أي وعد سيُنجز أولًا. للتعرف على بقية التوابع التي يمكن استخدامها للجمع بين الوعود راجع توثيق ()Promis. استخدام التعليمتين async و await تُسهّل التعليمة async عمل الشيفرة غير المتزامنة التي تعتمد على الوعود، فإضافة هذه التعليمة إلى بداية الدالة يجعلها دالة غير متزامنة: async function myFunction() { // This is an async function } وباﻹمكان استخدام التعليمة await قبل استدعاء الدالة التي تعيد وعدًا. وهذا ما يجعل الشيفرة تنتظر عند هذه النقطة حتى يسوّى الوعد وعندها تُعد قيمة الوعد المنجز هي القيمة المعادة من قبل الدالة أو ترمي الدالة قيمة الوعد المرفوض كخطأ. وهكذا ستتمكن من كتابة شيفرة غير متزامنة مع أنها تبدو كذلك. لهذا سنحاول كتابة مثال()fetch كالتالي: async function fetchProducts() { try { //`()fetch` تنتظر الدالة بعد هذا السطر حتى يسوّى الاستدعاء // الذي سيُعسد استجابة أو يرمي خطأ const response = await fetch( "https://mdn.github.io/learning-area/javascript/apis/fetching-data/can-store/products.json", ); if (!response.ok) { throw new Error(`HTTP error: ${response.status}`); } //`response.json()` تنتظر الدالة بعد هذا السطر حتى يسوّى الاستدعاء //أو يرمي خطأ JSON الذي يعيد كائن const data = await response.json(); console.log(data[0].name); } catch (error) { console.error(`Could not get products: ${error}`); } } fetchProducts(); نستدعي هنا الدالة ()await fetch وسنحصل على كائن استجابة Response مكتمل بدلًا من الوعد ()Promisوكأن()fetchدالة متزامنة. ونستطيع أيضًا استخدام الكتلة try...catch لمعالجة اﻷخطاء كما لو كنا نكتب شيفرة متزامنة. وتذكر أن الدوال غير المتزامنة تُعيد وعدًا دائمًا، لهذا لا يمكن أن نكتب شيفرة كهذه: async function fetchProducts() { try { const response = await fetch( "https://mdn.github.io/learning-area/javascript/apis/fetching-data/can-store/products.json", ); if (!response.ok) { throw new Error(`HTTP error: ${response.status}`); } const data = await response.json(); return data; } catch (error) { console.error(`Could not get products: ${error}`); } } const promise = fetchProducts(); console.log(promise[0].name); //هو كائن وعد فلن تعمل هذه الشيفرة "promise" ويجب عليك تصحيح الكود السابق على النحو التالي: async function fetchProducts() { try { const response = await fetch( "https://mdn.github.io/learning-area/javascript/apis/fetching-data/can-store/products.json", ); if (!response.ok) { throw new Error(`HTTP error: ${response.status}`); } const data = await response.json(); return data; } catch (error) { console.error(`Could not get products: ${error}`); } } const promise = fetchProducts(); promise.then((data) => console.log(data[0].name)); وتذكر أن استخدام await يكون ضمن دالة، إلا في الحالة التي تكون فيها الشيفرة ضمن وحدة JavaScript module وليس ضمن سكريبت نمطي: try { // using await outside an async function is only allowed in a module const response = await fetch( "https://mdn.github.io/learning-area/javascript/apis/fetching-data/can-store/products.json", ); if (!response.ok) { throw new Error(`HTTP error: ${response.status}`); } const data = await response.json(); console.log(data[0].name); } catch (error) { console.error(`Could not get products: ${error}`); } قد تستخدم دوال async كثيرًا مقارنة باستخدام سلسلة الوعود لكونها تجعل العمل مع الوعود أكثر وضوحًا. وتذكر أن await -كما هو حال سلسلة الوعود- تجبر العمليات المتزامنة على التنفيذ المتسلسل، وهذا أمر ضروري إن اعتمدت نتيجة العملية الثانية على سابقتها، أما إن لم يكن الوضع كذلك، ففكرّ في هذه الحالة باستخدام الدالة ()Promise.all. الخلاصة تُعرفنا في مقال اليوم على مفهوم الوعود التي تعد أساسًا للبرمجة غير المتزامنة في جافا سكريبت الحديثة. إذ تجعل تسلسل العمليات غير المتزامنة أكثر وضوحًا وإدراكًا بدلًا من التداخل المفرط للاستدعاءات، كما تدعم نمطًا من معالجة الأخطاء مشابهًا ﻵلية try...catch. وتسّهل التعليمتان async و await بناء عمليات باستدعاء سلسلة من الدوال غير المتزامنة المتتابعة دون الحاجة إلى سلاسل صريحة من الوعود وكتابة شيفرة شبيهة بالشيفرة المتزامنة. تعمل الوعود في النسخ اﻷخيرة من معظم المتصفحات الحديثة، وستكون المشكلة فقط مع متصفحي أوبرا ميني Opera mini وإنترنت إكسبلورر 11 والنسخ اﻷقدم. لم نناقش بالتأكيد كل ميزات الوعود في مقالنا الحالي، بل سلطنا الضوء على الميزات اﻷكثر أهمية واستخدامًا، وستتعلم خلال مسيرتك في تعلم جافا سكريبت الكثير من الميزات والتقنيات المفيدة الأخرى، ويجدر بالذكر أن الكثير من واجهات الويب البرمجية مبنية أساسًا على الوعود مثل WebRTC و Web Audio API Media Capture and Streams API وغيرها الكثير. ترجمة -وبتصرف- للمقال: How to use promises اقرأ أيضًا: المقال السابق: مدخل إلى جافا سكريبت غير المتزامنة اللاتزامن والانتظار async/await في جافاسكربت الوعود Promise في جافاسكربت البرمجة غير المتزامنة في جافاسكريبت
  13. هذي التقرير بي الخطى abud@abud-B460MDS3HV2:~$ sudo mv /etc/apt/preferences.d/nosnap.pref ~/Documents/nosnap.backup [sudo] password for abud: mv: cannot move '/etc/apt/preferences.d/nosnap.pref' to '/home/abud/Documents/nosnap.backup': No such file or directory abud@abud-B460MDS3HV2:~$ sudo apt update تجاهل:1 cdrom://Linux Mint 21.2 _Victoria_ - Release amd64 20230711 jammy InRelease خطأ:2 cdrom://Linux Mint 21.2 _Victoria_ - Release amd64 20230711 jammy Release الرجاء استخدام apt-cdrom لتعريف APT بهذا القرص المدمج. لا يمكن استخدام apt-get update لإضافة أقراص مدمجة جديدة. تجاهل:3 http://packages.linuxmint.com victoria InRelease Hit:4 https://mirrors.isu.net.sa/apt-mirror jammy InRelease جلب:5 http://security.ubuntu.com/ubuntu jammy-security InRelease [129 kB] Hit:6 http://packages.linuxmint.com victoria Release جلب:7 https://mirrors.isu.net.sa/apt-mirror jammy-updates InRelease [128 kB] جلب:9 http://dl.google.com/linux/earth/deb stable InRelease [1821 B] خطأ:9 http://dl.google.com/linux/earth/deb stable InRelease The following signatures couldn't be verified because the public key is not available: NO_PUBKEY E88979FB9B30ACF2 Hit:10 https://mirrors.isu.net.sa/apt-mirror jammy-backports InRelease Hit:11 https://debrepo.freedownloadmanager.org jammy InRelease قراءة قوائم الحزم... تمّ% E: The repository 'cdrom://Linux Mint 21.2 _Victoria_ - Release amd64 20230711 jammy Release' does not have a Release file. N: Updating from such a repository can't be done securely, and is therefore disabled by default. N: See apt-secure(8) manpage for repository creation and user configuration details. W: GPG error: http://dl.google.com/linux/earth/deb stable InRelease: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY E88979FB9B30ACF2 E: The repository 'http://dl.google.com/linux/earth/deb stable InRelease' is not signed. N: Updating from such a repository can't be done securely, and is therefore disabled by default. N: See apt-secure(8) manpage for repository creation and user configuration details. abud@abud-B460MDS3HV2:~$ sudo apt install snapd قراءة قوائم الحزم... تمّ0% Building dependency tree... تمّ% Reading state information... تمّ Package snapd is not available, but is referred to by another package. This may mean that the package is missing, has been obsoleted, or is only available from another source E: Package 'snapd' has no installation candidate abud@abud-B460MDS3HV2:~$ sudo snap install gabutdm sudo: snap: command not found abud@abud-B460MDS3HV2:~$ ^[[5~https://github.com/gabutakut/gabutdm.git~~ bash: https://github.com/gabutakut/gabutdm.git~~: No such file or directory abud@abud-B460MDS3HV2:~$ abud@abud-B460MDS3HV2:~$ sudo apt update [sudo] password for abud: Sorry, try again. [sudo] password for abud: تجاهل:1 cdrom://Linux Mint 21.2 _Victoria_ - Release amd64 20230711 jammy InRelease خطأ:2 cdrom://Linux Mint 21.2 _Victoria_ - Release amd64 20230711 jammy Release الرجاء استخدام apt-cdrom لتعريف APT بهذا القرص المدمج. لا يمكن استخدام apt-get update لإضافة أقراص مدمجة جديدة. Hit:3 https://mirrors.isu.net.sa/apt-mirror jammy InRelease تجاهل:4 http://packages.linuxmint.com victoria InRelease Hit:5 https://mirrors.isu.net.sa/apt-mirror jammy-updates InRelease Hit:6 https://mirrors.isu.net.sa/apt-mirror jammy-backports InRelease Hit:7 http://packages.linuxmint.com victoria Release جلب:9 http://dl.google.com/linux/earth/deb stable InRelease [1821 B] خطأ:9 http://dl.google.com/linux/earth/deb stable InRelease The following signatures couldn't be verified because the public key is not available: NO_PUBKEY E88979FB9B30ACF2 Hit:10 https://debrepo.freedownloadmanager.org jammy InRelease Hit:11 http://security.ubuntu.com/ubuntu jammy-security InRelease قراءة قوائم الحزم... تمّ% E: The repository 'cdrom://Linux Mint 21.2 _Victoria_ - Release amd64 20230711 jammy Release' does not have a Release file. N: Updating from such a repository can't be done securely, and is therefore disabled by default. N: See apt-secure(8) manpage for repository creation and user configuration details. W: GPG error: http://dl.google.com/linux/earth/deb stable InRelease: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY E88979FB9B30ACF2 E: The repository 'http://dl.google.com/linux/earth/deb stable InRelease' is not signed. N: Updating from such a repository can't be done securely, and is therefore disabled by default. N: See apt-secure(8) manpage for repository creation and user configuration details. abud@abud-B460MDS3HV2:~$ sudo apt install build-essential قراءة قوائم الحزم... تمّ0% Building dependency tree... تمّ% Reading state information... تمّ The following additional packages will be installed: g++ g++-11 libc-dev-bin libc-devtools libc6-dev libcrypt-dev libnsl-dev libstdc++-11-dev libtirpc-dev rpcsvc-proto الحزم المقترحة: g++-multilib g++-11-multilib gcc-11-doc glibc-doc libstdc++-11-doc سيتم تثبيت الحزم الجديدة التالية: build-essential g++ g++-11 libc-dev-bin libc-devtools libc6-dev libcrypt-dev libnsl-dev libstdc++-11-dev libtirpc-dev rpcsvc-proto 0 سيتم ترقيتها، 11 مثبتة حديثاً، 0 لإزالتها و 1 لم يتم ترقيتها. بحاجة إلى جلب 16.1 Mب من الأرشيف. After this operation, 64.5 MB of additional disk space will be used. هل تريد الاستمرار؟ [Y/n] y جلب:1 https://mirrors.isu.net.sa/apt-mirror jammy-updates/main amd64 libc-dev-bin amd64 2.35-0ubuntu3.8 [20.3 kB] جلب:2 https://mirrors.isu.net.sa/apt-mirror jammy/main amd64 libcrypt-dev amd64 1:4.4.27-1 [112 kB] جلب:3 https://mirrors.isu.net.sa/apt-mirror jammy/main amd64 rpcsvc-proto amd64 1.4.2-0ubuntu6 [68.5 kB] جلب:4 https://mirrors.isu.net.sa/apt-mirror jammy-updates/main amd64 libtirpc-dev amd64 1.3.2-2ubuntu0.1 [192 kB] جلب:5 https://mirrors.isu.net.sa/apt-mirror jammy/main amd64 libnsl-dev amd64 1.3.0-2build2 [71.3 kB] جلب:6 https://mirrors.isu.net.sa/apt-mirror jammy-updates/main amd64 libc6-dev amd64 2.35-0ubuntu3.8 [2100 kB] جلب:7 https://mirrors.isu.net.sa/apt-mirror jammy-updates/main amd64 libstdc++-11-dev amd64 11.4.0-1ubuntu1~22.04 [2101 kB] جلب:8 https://mirrors.isu.net.sa/apt-mirror jammy-updates/main amd64 g++-11 amd64 11.4.0-1ubuntu1~22.04 [11.4 MB] جلب:9 https://mirrors.isu.net.sa/apt-mirror jammy/main amd64 g++ amd64 4:11.2.0-1ubuntu1 [1412 B] جلب:10 https://mirrors.isu.net.sa/apt-mirror jammy/main amd64 build-essential amd64 12.9ubuntu3 [4744 B] جلب:11 https://mirrors.isu.net.sa/apt-mirror jammy-updates/main amd64 libc-devtools amd64 2.35-0ubuntu3.8 [28.9 kB] جلب 16.1 Mب في 6s (2534 kب/ث) Selecting previously unselected package libc-dev-bin. (Reading database ... 584439 files and directories currently installed.) Preparing to unpack .../00-libc-dev-bin_2.35-0ubuntu3.8_amd64.deb ... Unpacking libc-dev-bin (2.35-0ubuntu3.8) ... Selecting previously unselected package libcrypt-dev:amd64. Preparing to unpack .../01-libcrypt-dev_1%3a4.4.27-1_amd64.deb ... Unpacking libcrypt-dev:amd64 (1:4.4.27-1) ... Selecting previously unselected package rpcsvc-proto. Preparing to unpack .../02-rpcsvc-proto_1.4.2-0ubuntu6_amd64.deb ... Unpacking rpcsvc-proto (1.4.2-0ubuntu6) ... Selecting previously unselected package libtirpc-dev:amd64. Preparing to unpack .../03-libtirpc-dev_1.3.2-2ubuntu0.1_amd64.deb ... Unpacking libtirpc-dev:amd64 (1.3.2-2ubuntu0.1) ... Selecting previously unselected package libnsl-dev:amd64. Preparing to unpack .../04-libnsl-dev_1.3.0-2build2_amd64.deb ... Unpacking libnsl-dev:amd64 (1.3.0-2build2) ... Selecting previously unselected package libc6-dev:amd64. Preparing to unpack .../05-libc6-dev_2.35-0ubuntu3.8_amd64.deb ... Unpacking libc6-dev:amd64 (2.35-0ubuntu3.8) ... Selecting previously unselected package libstdc++-11-dev:amd64. Preparing to unpack .../06-libstdc++-11-dev_11.4.0-1ubuntu1~22.04_amd64.deb ... Unpacking libstdc++-11-dev:amd64 (11.4.0-1ubuntu1~22.04) ... Selecting previously unselected package g++-11. Preparing to unpack .../07-g++-11_11.4.0-1ubuntu1~22.04_amd64.deb ... Unpacking g++-11 (11.4.0-1ubuntu1~22.04) ... Selecting previously unselected package g++. Preparing to unpack .../08-g++_4%3a11.2.0-1ubuntu1_amd64.deb ... Unpacking g++ (4:11.2.0-1ubuntu1) ... Selecting previously unselected package build-essential. Preparing to unpack .../09-build-essential_12.9ubuntu3_amd64.deb ... Unpacking build-essential (12.9ubuntu3) ... Selecting previously unselected package libc-devtools. Preparing to unpack .../10-libc-devtools_2.35-0ubuntu3.8_amd64.deb ... Unpacking libc-devtools (2.35-0ubuntu3.8) ... Setting up libtirpc-dev:amd64 (1.3.2-2ubuntu0.1) ... Setting up rpcsvc-proto (1.4.2-0ubuntu6) ... Setting up libnsl-dev:amd64 (1.3.0-2build2) ... Setting up libcrypt-dev:amd64 (1:4.4.27-1) ... Setting up libc-dev-bin (2.35-0ubuntu3.8) ... Setting up libc-devtools (2.35-0ubuntu3.8) ... Setting up libc6-dev:amd64 (2.35-0ubuntu3.8) ... Setting up libstdc++-11-dev:amd64 (11.4.0-1ubuntu1~22.04) ... Setting up g++-11 (11.4.0-1ubuntu1~22.04) ... Setting up g++ (4:11.2.0-1ubuntu1) ... update-alternatives: using /usr/bin/g++ to provide /usr/bin/c++ (c++) in auto mo de Setting up build-essential (12.9ubuntu3) ... Processing triggers for man-db (2.10.2-1) ... abud@abud-B460MDS3HV2:~$ sudo apt install linux-headers-$(uname -r) قراءة قوائم الحزم... تمّ0% Building dependency tree... تمّ% Reading state information... تمّ linux-headers-5.15.0-76-generic is already the newest version (5.15.0-76.83). 0 سيتم ترقيتها، 0 مثبتة حديثاً، 0 لإزالتها و 1 لم يتم ترقيتها. abud@abud-B460MDS3HV2:~$ cd /path/to/your/file bash: cd: /path/to/your/file: No such file or directory abud@abud-B460MDS3HV2:~$ chmod +x VMware-Workstation-Full-17.5.2-23775571.x86_64.bundle chmod: cannot access 'VMware-Workstation-Full-17.5.2-23775571.x86_64.bundle': No such file or directory abud@abud-B460MDS3HV2:~$ sudo ./VMware-Workstation-Full-17.5.2-23775571.x86_64.bundle sudo: ./VMware-Workstation-Full-17.5.2-23775571.x86_64.bundle: command not found abud@abud-B460MDS3HV2:~$ sudo apt update تجاهل:1 cdrom://Linux Mint 21.2 _Victoria_ - Release amd64 20230711 jammy InRelease خطأ:2 cdrom://Linux Mint 21.2 _Victoria_ - Release amd64 20230711 jammy Release الرجاء استخدام apt-cdrom لتعريف APT بهذا القرص المدمج. لا يمكن استخدام apt-get update لإضافة أقراص مدمجة جديدة. Hit:3 http://security.ubuntu.com/ubuntu jammy-security InRelease جلب:4 http://dl.google.com/linux/earth/deb stable InRelease [1821 B] خطأ:4 http://dl.google.com/linux/earth/deb stable InRelease The following signatures couldn't be verified because the public key is not available: NO_PUBKEY E88979FB9B30ACF2 تجاهل:5 http://packages.linuxmint.com victoria InRelease Hit:6 https://mirrors.isu.net.sa/apt-mirror jammy InRelease Hit:7 https://mirrors.isu.net.sa/apt-mirror jammy-updates InRelease Hit:8 https://mirrors.isu.net.sa/apt-mirror jammy-backports InRelease Hit:9 http://packages.linuxmint.com victoria Release Hit:11 https://debrepo.freedownloadmanager.org jammy InRelease قراءة قوائم الحزم... تمّ% E: The repository 'cdrom://Linux Mint 21.2 _Victoria_ - Release amd64 20230711 jammy Release' does not have a Release file. N: Updating from such a repository can't be done securely, and is therefore disabled by default. N: See apt-secure(8) manpage for repository creation and user configuration details. W: GPG error: http://dl.google.com/linux/earth/deb stable InRelease: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY E88979FB9B30ACF2 E: The repository 'http://dl.google.com/linux/earth/deb stable InRelease' is not signed. N: Updating from such a repository can't be done securely, and is therefore disabled by default. N: See apt-secure(8) manpage for repository creation and user configuration details. abud@abud-B460MDS3HV2:~$ sudo apt install p7zip-full قراءة قوائم الحزم... تمّ0% Building dependency tree... تمّ% Reading state information... تمّ p7zip-full is already the newest version (16.02+dfsg-8). 0 سيتم ترقيتها، 0 مثبتة حديثاً، 0 لإزالتها و 1 لم يتم ترقيتها. abud@abud-B460MDS3HV2:~$ sudo apt install unetbootin قراءة قوائم الحزم... تمّ0% Building dependency tree... تمّ% Reading state information... تمّ E: تعذر العثور على الحزمة unetbootin
  14. هذي التقرير بي الخطى abud@abud-B460MDS3HV2:~$ sudo mv /etc/apt/preferences.d/nosnap.pref ~/Documents/nosnap.backup [sudo] password for abud: mv: cannot move '/etc/apt/preferences.d/nosnap.pref' to '/home/abud/Documents/nosnap.backup': No such file or directory abud@abud-B460MDS3HV2:~$ sudo apt update تجاهل:1 cdrom://Linux Mint 21.2 _Victoria_ - Release amd64 20230711 jammy InRelease خطأ:2 cdrom://Linux Mint 21.2 _Victoria_ - Release amd64 20230711 jammy Release الرجاء استخدام apt-cdrom لتعريف APT بهذا القرص المدمج. لا يمكن استخدام apt-get update لإضافة أقراص مدمجة جديدة. تجاهل:3 http://packages.linuxmint.com victoria InRelease Hit:4 https://mirrors.isu.net.sa/apt-mirror jammy InRelease جلب:5 http://security.ubuntu.com/ubuntu jammy-security InRelease [129 kB] Hit:6 http://packages.linuxmint.com victoria Release جلب:7 https://mirrors.isu.net.sa/apt-mirror jammy-updates InRelease [128 kB] جلب:9 http://dl.google.com/linux/earth/deb stable InRelease [1821 B] خطأ:9 http://dl.google.com/linux/earth/deb stable InRelease The following signatures couldn't be verified because the public key is not available: NO_PUBKEY E88979FB9B30ACF2 Hit:10 https://mirrors.isu.net.sa/apt-mirror jammy-backports InRelease Hit:11 https://debrepo.freedownloadmanager.org jammy InRelease قراءة قوائم الحزم... تمّ% E: The repository 'cdrom://Linux Mint 21.2 _Victoria_ - Release amd64 20230711 jammy Release' does not have a Release file. N: Updating from such a repository can't be done securely, and is therefore disabled by default. N: See apt-secure(8) manpage for repository creation and user configuration details. W: GPG error: http://dl.google.com/linux/earth/deb stable InRelease: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY E88979FB9B30ACF2 E: The repository 'http://dl.google.com/linux/earth/deb stable InRelease' is not signed. N: Updating from such a repository can't be done securely, and is therefore disabled by default. N: See apt-secure(8) manpage for repository creation and user configuration details. abud@abud-B460MDS3HV2:~$ sudo apt install snapd قراءة قوائم الحزم... تمّ0% Building dependency tree... تمّ% Reading state information... تمّ Package snapd is not available, but is referred to by another package. This may mean that the package is missing, has been obsoleted, or is only available from another source E: Package 'snapd' has no installation candidate abud@abud-B460MDS3HV2:~$ sudo snap install gabutdm sudo: snap: command not found abud@abud-B460MDS3HV2:~$ اطفه لي المتصفح Motrix تحمل من اليوتب مثلن كيف تثبيت JDownloader2Setup_unix_nojre.sh افطل نسخ مستقره في لينكس مستودعاته كثير
  15. لا يوجد جواب دقيق ولا يمكن أن يوجد. السبب أن الصفحة في تطبيق ويب ليست صفحة نصية مثل صفحات ملف PDF. الصفحة تتفاعل مع كود الواجهة الخلفية، وقد يكون فيها وظائف معقدة، وقد يكون فيها تحريكات (Animations) مميزة، وهذا كله يزيد في تعقيد الصفحة، كما أن الصفحات في كثير من الأحيان تكون مرتبطة ببعضها البعض، وتغيير في واحدة يؤثر على الصفحات الأخرى. لذلك هناك كثير من المتغيرات كما ترى. فلا يمكن أن نحسب "الزمن المتوسط للمبرمجين" في إنشاء الصفحات. إذا كنت تتوقع أنه بإمكانك إنجاز المطلوب بين يومين أو 7 أيام، فربما من الأحسن أن تقول 5 أيام، أو حتى 7 أيام، لكي تعطي لنفسك الوقت الكافي. وهذا في حالة ما لم يكن العميل مستعجلا. وإلا فحاول إنجاز العمل في أقرب الآجال.
  16. نعم إجابة واضحة مشكور. لكن لدي سؤال آخر، مثلا صفحة من تطبيق علي إنجازها في كم مدة؟ يعني ماهو الزمن المتوسط للمبرمجين؟ فبإمكاني إنشاءها في يومين كما يمكنني إنشاءها في أسبوع.
  17. ستجد أسفل فيديو الدرس في نهاية الصفحة صندوق تعليقات كما هنا، أرجو طرح الأسئلة أسفل الدرس وليس هنا في قسم الأسئلة البرمجة حيث نطرح الأسئلة العامة الغير متعلقة بمحتوى الدورة أو الدرس، وذلك لمساعدتك بشكل أفضل.
  18. بعد ما اكتب الأوامر في أدوات المطور كيف أحفظ الأكواد دون تخريب ما كتبت
  19. لا داعي لذكر مدة زمنية محددة وإلزام نفسك بها، بل اطرح ما تستطيع فعله وذكر المهارات التي تمتلكها وما الفائدة التي ستعود على العميل من تلك المهارات فهو لا يدري ما معنى Full-Stack. ويجب أن تظهر بمظهر إحترافي ومنظم وعدم الإنجراف وراء ما يطرحه الآخرين. مع ذكر شرط أنه يتم تحديد مدة المشروع بناءًا على المتطلبات ومدى تعقيد المشروع، وعند إعطاء مدة زمنية للعميل قم بمضاعفتها ففي البداية لن تكون لديك خبرة بتحديد المدة اللازمة، وفي حال قمت بإنجاز المشروع في أقل من ذلك فستكون تلك نقطة جيدة لصالحك وليس العكس. يمكنك ذكر مثلاً أن تطبيق بسيط مكون من 5 صفحات يستغرق مدة زمنية تساوي كذا
  20. السلام عليكم، في موقع خمسات مثلا، حين أود أن أقدم خدمة، كإنشاء تطبيق واب أو هاتف من الصفر، بإستعمال React و React Nativeو Node، أي أن التطبيق Fullstack. كيف يمكنني تحديد المدة اللازمة لإنشاء التطبيق؟ أعني بذلك كيف يمكنني تحديد المجال الزمني المناسب و اللازم لإنشاء التطبيق؟ أعلم أنه ليست هناك إجابة محددة، كون تواجد العديد من العوامل المتحكمة و المتغيرات، كالخبرة و درجة تعقيد التطبيق وماشابه. ولكن على الأقل هناك ما يساعدني على تحديد مجال زمني مناسب ؟ شكرا مسبقا.
  21. قم بتثبيت مديز الحزم snap من خلال تنفيذ الأوامر التالية بالترتيب: sudo mv /etc/apt/preferences.d/nosnap.pref ~/Documents/nosnap.backup sudo apt update sudo apt install snapd ثم قم بتسجيل الخروج من حسابك وتسجيل الدخول مجددًا في النظام أو أعد تشغيل النظام. ثم تثبيت البرنامج من خلال: sudo snap install gabutdm
  22. كيف اثبت Gabut Sownload manager كيف تثبيته ومنه على لينكس منت صيغا التثييتbad
  23. لا يوجد بديل مماثل تمامًا، لكن لتحميل الفيديوهات من اليوتيوب يوجد أداة stacher توجه إلى موقع stacher.io لتحميلها. أما بالنسبة لبرامج تحميل ملفات مشابهة لبرنامج IDM، فيوجد: Motrix Gabut Download Manager jdownloader2
  24. لا حاجة إلى ذلك، في حال لديك البيانات الخاصة بالحساب وتتذكريها جيدًا، تستطيعي استرجاع الحساب من خلال مراسلة الدعم، توجهي للصفحة التالية من خلال هاتفك: https://www.instagram.com/hacked/ ثم اختاري my account was hacked ثم اضغطي على next، بعد ذلك عليك إدخال اسم المستخدم أو رقم الهاتف أو البريد للبحث عن حسابك ثم اضغطي على next. وسيتم سؤالك عن رفع صور للتعرف عليك وإثبات أنك صاحبة الحساب عليك الضغط على yes i have photos ثم سيطلب منك بريد إلكتروني أدخليه للتواصل معك وإرسال رابط إليه. بعد ذلك سيطلب منك تصوير نفسك بالكاميرا الأمامية للتعرف عليك وإتباع تعليمات التصوير مثل تدوير الوجه وخلافه. والآن انتظري يوم إلى يومين وسيتم إرسال بريد على الإيميل الذي أدخلتيه به رابط لاسترجاع الحساب.
  25. مرحبا احتاج خبير استعداد حساب مهكر في الانستقرام. الهكر غير الايميل و رقم التلفون و حط F2A. احتاج استراجعه باسرع وقت، مستعدة ادفع المبلغ المطلوب، بس بدي يرجعلي حسابي ضروري. ارجو الرد بسرعة
  26. البارحة
  27. أولاً لديك خطأ في حساب متوسط التقييمات في السطر الذي يحسب فيه المتوسط النهائي finalRate. فالمتغير rate ربما يتم إرساله كقيمة غير صحيحة مثل قيمة نصية من الواجهة الأمامية، لذا لنتأكد من أن rate يتم تحويله إلى رقم صحيح قبل استخدامه في الحساب، وأيضًا التأكد من صحة قيم التقييم المرسلة من الواجهة الأمامية. أيضًا بعد إضافة المراجعة إلى قاعدة البيانات، عليك إعادة بيانات الكتاب المحدثة إلى الواجهة الأمامية، بما في ذلك التقييم الجديد، وبعد تلقي بيانات الكتاب المحدثة من الخادم، يجب تحديث حالة الكتاب في الواجهة الأمامية لتعكس التقييم الجديد. ثم استخدام البيانات المحدثة للكتاب في المكون لعرض التقييم الجديد. إليك التعديلات مع تعليقات لتوضيح أماكن التعديل. تعديل في bookController.js: const addReview = asyncHandler(async(req, res) => { const { id } = req.params const { comment, rate } = req.body const book = await Book.findById(id) const user = await User.findById(req.userId) // التحقق من وجود الكتاب if (!book) { return res.status(404).json({ message: "Book Not Found" }) } // التحقق من أن المستخدم لم يقيم الكتاب مسبقاً const isRated = book.reviews.findIndex(m => m.user == req.userId) if (isRated > -1){ return res.status(403).send({ message: "Review Is Already Added" }); } // تحويل تقييم المستخدم إلى رقم صحيح والتحقق من صحته const numericRate = parseInt(rate, 10); if (isNaN(numericRate) || numericRate < 1 || numericRate > 5) { return res.status(400).send({ message: "Invalid rating value" }); } // حساب التقييم النهائي const totalRate = book.reviews.reduce((sum, review) => sum + review.rate ,0) const finalRate = (totalRate + numericRate) / (book.reviews.length + 1) // تحديث بيانات الكتاب بإضافة المراجعة الجديدة وتحديث التقييم await Book.updateOne( { _id: id }, { $push: { reviews: { user: req.userId, username: user.name, comment, rate: numericRate } }, $set: { rate: finalRate } } ) // إعادة بيانات الكتاب المحدثة بعد الإضافة const updatedBook = await Book.findById(id); res.status(201).json(updatedBook) }) تحديث الدالة postReview في apiCall: export function postReview(bookId, review) { return async (dispatch, getState) => { try { dispatch(bookActions.setLoading()) const {data} = await axios.post(`${BOOK_URL}/${bookId}/reviews`, review, { headers: { "authorization": getState().auth.user.accessToken } }); // عرض رسالة نجاح باستخدام toast toast.success(data?.message) // تحديث بيانات الكتاب المحدثة في الحالة dispatch(bookActions.updateBook(data)); dispatch(bookActions.clearLoading()); } catch (error) { // عرض رسالة خطأ باستخدام toast toast.error(error?.response?.data.message); dispatch(bookActions.clearLoading()); } }; } تعديل في الواجهة الأمامية Modal.js const Modal = ({ showModal, handleClose, book }) => { const [rate, setRating] = useState(0); const [comment, setComment] = useState(""); const dispatch = useDispatch(); const navigate = useNavigate(); const submitReview = (e) => { e.preventDefault(); if (comment === "") { // التحقق من وجود تعليق وعرض رسالة خطأ في حال عدم وجوده return toast.error("Comment is required") } // تحويل تقييم المستخدم إلى رقم صحيح والتحقق من صحته const numericRate = parseInt(rate, 10); if (isNaN(numericRate) || numericRate < 1 || numericRate > 5) { return toast.error("Invalid rating value"); } // إرسال المراجعة باستخدام الدالة postReview dispatch(postReview(book._id, { rate: numericRate, comment })) }; return ( <div className={`modal ${showModal ? "show" : ""}`}> <div className="modal-content"> <span className="close" onClick={handleClose}>&times;</span> <h2>Submit Your Review</h2> <form onSubmit={submitReview}> <div className="rating-input"> <label>Rating:</label> <select value={rate} onChange={(e) => setRating(e.target.value)} required> <option value="" disabled>Select a rating</option> <option value="1">1</option> <option value="2">2</option> <option value="3">3</option> <option value="4">4</option> <option value="5">5</option> </select> </div> <div className="comment"> <label>Comment:</label> <textarea value={comment} onChange={(e) => setComment(e.target.value)} required /> </div> <button className='modal-btn' type="submit">Submit</button> </form> </div> </div> ); }; export default Modal; تحديث bookSlice لتضمين الدالة updateBook: const bookSlice = createSlice({ name: "book", initialState: { books: [], error: false, loading: false, }, reducers: { getBooks(state, action) { state.books = action.payload; }, findBook(state, action) { state.books = action.payload; }, addReviews(state, action) { state.books = action.payload; }, updateBook(state, action) { // البحث عن الكتاب المحدث وتحديثه const updatedBook = action.payload; const index = state.books.findIndex(book => book._id === updatedBook._id); if (index !== -1) { state.books[index] = updatedBook; } }, setLoading(state) { state.loading = true; }, clearLoading(state) { state.loading = false; }, setError(state) { state.error = true; }, clearError(state) { state.error = false; }, } }); export const bookActions = bookSlice.actions; export default bookSlice.reducer;
  1. عرض المزيد
×
×
  • أضف...