# عنوان![sample](https://quera.org/qbox/view/R96pCjCHG8/photo_2022-08-04_18-00-10.jpg)
# پروژه اولیه
پروژه اولیه را از [این لینک](/contest/assignments/44747/download_problem_initial_project/150242/) دانلود کنید. ساختار فایلهای این پروژه به صورت زیر است.
<details class="blue">
<summary>
ساختار فایلهای پروژه
</summary>
```
fifa22-quera
├── App.js
├── app.json
├── assets
│ ├── adaptive-icon.png
│ ├── favicon.png
│ ├── icon.png
│ └── splash.png
├── babel.config.js
├── package.json
├── package-lock.json
└── src
├── Components
│ ├── <mark>Player.jsx</mark>
│ └── <mark>Row.jsx</mark>
└── __tests__
└── App.sample.test.js
```
</details>
<details class="green">
<summary>
راهاندازی پروژه
</summary>
- ابتدا پروژهی اولیه را دانلود و از حالت فشرده خارج کنید.
- در پوشهی `fifa22-quera` ، دستور `npm install` را برای نصب نیازمندیها اجرا کنید.
- در همین پوشه، دستور `npm start` را برای راهاندازی پروژه اجرا کنید.
- سپس بسته به سلیقه برنامه را درون مرورگر یا به وسیله برنامه *Expo* درون تلفن همراه خود اجر نمایید.
</details>
# جزئیات
مهیار و سلیب به تازگی تصمیم گرفته اند که برای افزایش در آمدشان *React Native* را برای توسعه برنامههای موبایلی فرا بگیرند. اما از آنجا که این دو تجربه چندانی با این کتابخانه ندارند بعضی از مسائل آن برای آنها عجبیب است من جمله شیوه استایل دهی و عدم امکان استفاده از *CSS*.
آن ها میخواهند برنامهای را توسعه دهند که نتایج بازیهای *FIFA 22* که درون کوئرا برگزار میشود را نمایش دهد. همواره دو فردی که باید با یکدیگر مسابقه دهند یا پرسپولیسی هستند یا استقلالی.
## کامپوننت `<Player />`
برای نمایش اطلاعات هر فرد نیاز است که یک کامپوننت تحت عنوان `<Player />` طراحی و استایل دهی شود که موارد زیر را نمایش دهد:
+ نام فرد مسابقه دهنده در قالب رشته که بوسیله پراپسی تحت عنوان `name` دریافت میشود.
+ تعداد گلهای زده شده که در قالب عدد صحیح بوسیله پراپسی تحت عنوان `goal` دریافت میشود.
+ پرسپولیسی/استقلالی بودن که با رنگ `red` یا `blue` نمایش داده خواهد شد و در قالب یک پراپس با مقدار بولین تحت عنوان `isRed` پاس داده خواهد شد در صورتی که این مقدار برابر `true` بود به این معنا است که فرد مسابقه دهنده پرسپولیسی است و در صورتی که `false` بود و یا مقدار آن تنظیم نشده بود به این معنا است که فرد مسابقه دهنده استقلالی است.
همچنین این کامپوننت باید عرضی معادل `350px` داشته باشد و نباید بیشتر از `40%` از عرض صفحه را در حالت حداکثر اشغال نماید و باید ارتفاعی معادل `600px` و حداکثر `70%` ارتفاع صفحه را داشته باشد. همچنین باید حاشیهای به عرض `5px` و رنگ `#eebc1d` و انحنای `20px` ای داشته باشد. موارد مذکور موارد باید درون کلاسی تحت عنوان `player` نوشته شوند. همچنین باید به اندازه یک واحد *Grid* را اشغال کند.
همچنین دو کلاس با نامهای `red` و `blue` که به ترتیب رنگ پس زمینه قرمز و آبی با کد `#cc0000` و `#0000cc` هستند را اعمال نمایند.
هر دو تگی که برای نمایش اسم و گل استفاده میشوند باید کلاسی تحت عنوان `text` که رنگ `white` را به همراه فاصله از المان بالایی به اندازه `50px` و وسط چین نمودن متن اعمال نماید،. و همچنین برای تگ مربوطه به نمایش گل کلاس دیکری با نام `goal` که اندازه .متن آن برابر `50px` و به صورت *italic* و __ـBold__ باشد.
## کامپوننت `<Row />`
همچنین کامپوننت دیگری نیاز است که وظیفه آن قرار دادن المانهای فرزندش به صورت افقی و با فاصله بین همدیگر با استفاده از مفاهیم *Flex* میباشد و همچنین باید المانهایش را در وسط خود با استفاده از `alignItems` قرار دهد. همچنین باید حداقل نصف ارتفاع صفحه و `80%` عرض صفحه را اشغال کند و به اندازه `50px` نسبت به المان بالایی فاصله داشته باشد و در نهایت باید خود را با `alignSelf` در وسط صفحه قرار دهد. نام استایل این کلاس باید `row` باشد.
از آنجایی که مهیار و سلیب در این امر تازه کار هستند و تصمیم گرفته اند خود نیز در این رقابلت جذاب شرکت کنند از شما درخواست کمک کرده اند تا این بخش برنامه را تکمیل نمایید.
# نکات
- شما تنها مجاز به اعمال تغییرات درون فایلهای فولدر `src/Components` هستید.
- پس از تمکیل پوشه `src` را زیپ و ارسال کرده
![sample](https://quera.org/qbox/view/tBTu7CxIKk/ezgif-4-c014e0670d.gif)
# پروژه اولیه
پروژه اولیه را از [این لینک](/contest/assignments/44747/download_problem_initial_project/150240/) دانلود کنید. ساختار فایلهای این پروژه به صورت زیر است.
<details class="blue">
<summary>
ساختار فایلهای پروژه
</summary>
```
CounterApp
├── <mark>App.js</mark>
├── app.json
├── assets
│ ├── adaptive-icon.png
│ ├── favicon.png
│ ├── icon.png
│ └── splash.png
├── babel.config.js
├── package.json
├── package-lock.json
└── src
└── __tests__
└── App.sample.test.js
```
</details>
<details class="green">
<summary>
راهاندازی پروژه
</summary>
- ابتدا پروژهی اولیه را دانلود و از حالت فشرده خارج کنید.
- در پوشهی `CounterApp` ، دستور `npm install` را برای نصب نیازمندیها اجرا کنید.
- در همین پوشه، دستور `npm start` را برای راهاندازی پروژه اجرا کنید.
- سپس بسته به سلیقه برنامه را درون مرورگر یا به وسیله برنامه *Expo* درون تلفن همراه خود اجر نمایید.
</details>
# جزئیات
مهیار و سلیب در گام دوم مسابقات دوم کوئرا تصمیم گرفتند یک بازی بسیار جذاب دیگر در قالب یک برنامه تدارک ببینید این بازی دارای دو دکمه که وظیفه آن شمارش و نمایش شمارنده میباشد:
- دکمه `+` که با کلیک بر روی آن یک واحد به مقدار شمارنده افزایش پیدا میکند
- دکمه `-` که با کلیک بر روی آن یک واحز از مقدار شمارنده کاسته میشود.
**نکته**: مقدار شمارنده فقط میتواند عددی بزرگتر یا مساوی صفر باشد.
**نکته**: مقدار اولیه برابر صفر میباشد.
# نکات
- شما تنها مجاز به اعمال تغییرات درون فایل `App.js` هستید پس از تکیل این فایل را به صورت مستقیم و یا *ZIP* شده ارسال نمایید.
![sample](https://quera.org/qbox/view/ohLksKA815/ezgif-2-14be439639.gif)
# پروژه اولیه
پروژه اولیه را از [این لینک](/contest/assignments/44747/download_problem_initial_project/150241/) دانلود کنید. ساختار فایلهای این پروژه به صورت زیر است.
<details class="blue">
<summary>
ساختار فایلهای پروژه
</summary>
```
todo_list_simple_mobile
├── <mark>App.js</mark>
├── app.json
├── assets
│ ├── adaptive-icon.png
│ ├── favicon.png
│ ├── icon.png
│ └── splash.png
├── babel.config.js
├── package.json
├── package-lock.json
└── src
└── Components
├── <mark>AddTask.jsx</mark>
├── <mark>SelectPress.jsx</mark>
├── <mark>Task.jsx</mark>
└── <mark>TaskList.jsx</mark>
```
</details>
<details class="green">
<summary>
راهاندازی پروژه
</summary>
- ابتدا پروژهی اولیه را دانلود و از حالت فشرده خارج کنید.
- در پوشهی `todo_list_simple_mobile` ، دستور `npm install` را برای نصب نیازمندیها اجرا کنید.
- در همین پوشه، دستور `npm start` را برای راهاندازی پروژه اجرا کنید.
- سپس بسته به سلیقه برنامه را درون مرورگر یا به وسیله برنامه *Expo* درون تلفن همراه خود اجر نمایید.
</details>
# جزئیات
مهیار به شدت آدم فراموش کاری است به همین جهت او تصمیم به توسعه یک اپلیکیشن برای موبایل خود کرده است که لیست کارهایش را در آن یادداشت کند این برنامه فقط امکان اضافه کردن کار را دارد و نه حذف آن را. مهیار اندکی به مبانی توسعه نرم افزار و *React* مسلط بود به همین جهت او توانست یک شمای کلی برای توسعه این برنامه استخراج کند که در ادامه به شرح آن می پردازیم. اما به علت اینکه هیچ تسلطی به *React Native* نداشت و با چالشهای متعددی رو به رو شد از شما خواست که به او کمک کنید.
## کامپوننت `<SelectPress />`
مهیار در کمال ناباوری متوجه شد که دراپ لیستهای *HTML* مشابهش در *React Native* وجود ندارد فلذا ایدهای به ذهنش برای نمایش لیستها خطور کرد او تصمیم گرفت یک دکمه طراحی شود که با هر بار کلیک شدن بر روی آن آیتم بعدی نمایش داده شود و اگر به آیتم آخر رسید و روی آن کلیک شد به آیتم اول بازگردد. همچنین برای دسترسی به مقدار آن تصمیم گرفت که یک تابع تحت عنوان `setValue` به عنوان پراپس بگیرد و در صورت تغییر لیست از این تابع استفاده شود.
- این کامپوننت مقادیر مختلف لیست را در قالب پراپس `items` دریافت میکند.
- هر عضو این آرایه یک `title` دارد که بیانگر متنی است که باید نمایش دهد.
- مقدار اولیه این دکمه برابر عضو اول این لیست میباشد.
## کامپوننت `<AddTask />`
این کامپوننت وظیفه نمایش و اضافه کردن تسک جدید را به لیست تسکها دارد.
+ در این کامپوننت باید از `<SelectPress />` برای نمایش آیتمها مختلف استفاده شود.
+ آیتمها در قالب آرایهای تحت عنوان `TIME` درون فایل کامپوننت قرار داده شده اند که بیانگر مدت زمانی است که طول میکشد مهیار آن کار را انجام دهد هر چقدر این کار مدت بیشتری طول بکشد افسردگی و ناراحتی مهیار نیز بیشتر میشود.
+ یک تگ مناسب ورودی برای دریافت نام تسک از کاربر باید نمایش داده شود که مقدار *Task Name* را به عنوان `placeholder` نمایش دهد.
+ برای اضافه و ذخیره کردن تسک جدید این کامپوننت یک تابع `addTask` دریافت میکند که باید تسک جدید به این صورت به آن داده شود:
```js
const task = {
task: "Very Very Hard Task",
time: {
title: "😢",
value: 2
}
};
addTask(task);
```
+ یک دکمه با متن `➕` باید قرار داشته باشد که وقتی روی آن فشار داده شد اطلاعات تسک را ذخیره نماید.
## کامپوننت `<TaskList />`
+ این کامپوننت لیست کارها را در قالب یک پراپس تحت عنوان `tasks` دریافت میکند و به نحو بهینه با استفاده از یکی از کامپوننتهای جادویی *React Native* که قابلیت *Scroll* نیز دارد آن ها را رندر میکند.
+ هر کار باید درون کامپوننت `<Task />` نمایش داده شود.
### کامپوننت `<Task />`
+ این کامپوننت وظیفه انجام یک کار بر عهده دارد.
+ این کامپوننت باید به ترتیب موارد زیر را نمایش دهد.
۱. شماره اولویت کار که برابر جایگاه آن در لیست میباشد.
۲. نام تسک.
۳. مدت زمان آن.
دقت کنید که باید دو مورد آخر باید در قالب `item` دریافت شوند و اندیس هم بر پایه صفر میباشد
## کامپوننت `<App />`
پس از نکمیل بخشهای قبلی شما باید با ترکیب این کامپوننتها این برنامه را راه اندازی کنید. مهیار از شما خواسته است که کارها در ابتدا بر اساس مدت زمان آنها بر اساس متغیر `value` مرتب شوند و کارهایی که عذاب بیشتری دارند بالای لیست نمایش داده شوند در صورتی که دو کار اولویت یکسانی داشت باید بر اساس نام آنها مرتب شوند.
# نکات
- برای ارسال پوشه `src` و فایل `App.js` را بدون پوشه `node_modules` *ZIP* کرده و ارسال کنید.
- در صورتی که توضیحاتی برای شما نامفهوم بود پیشنهاد میشود به گیف صورت سوال نگاه کنید.
- اجباری به استفاده از *Style* ها وجود ندارد و صرفا جهت زیبا تر شدن پروژه میتوانید از آنها استفاده کنید.
- برای دکمههای میتوان از رنگ `#EEEEEE` استفاده کنید.
![sample](https://quera.org/qbox/view/ElTMRcTWrq/ezgif-2-309163c014.gif)
# پروژه اولیه
پروژه اولیه را از [این لینک](/contest/assignments/44747/download_problem_initial_project/150239/) دانلود کنید. ساختار فایلهای این پروژه به صورت زیر است.
<details class="blue">
<summary>
ساختار فایلهای پروژه
</summary>
```
todo_list_simple_mobile
├── <mark>App.js</mark>
├── app.json
├── assets
│ ├── adaptive-icon.png
│ ├── favicon.png
│ ├── icon.png
│ └── splash.png
├── babel.config.js
├── package.json
├── package-lock.json
└── src
└── Components
├── <mark>AddTask.jsx</mark>
├── <mark>SelectPress.jsx</mark>
├── <mark>Task.jsx</mark>
└── <mark>TaskList.jsx</mark>
```
</details>
<details class="green">
<summary>
راهاندازی پروژه
</summary>
- ابتدا پروژهی اولیه را دانلود و از حالت فشرده خارج کنید.
- در پوشهی `todo_list_simple_mobile` ، دستور `npm install` را برای نصب نیازمندیها اجرا کنید.
- در همین پوشه، دستور `npm start` را برای راهاندازی پروژه اجرا کنید.
- سپس بسته به سلیقه برنامه را درون مرورگر یا به وسیله برنامه *Expo* درون تلفن همراه خود اجر نمایید.
</details>
<details class="red">
<summary>
راهاندازی سرور پروژه
</summary>
- در گام بعدی اطمینان حاصل کنید که تلفن همراه شما و کامپیوترتان هر دو به یک شبکه و هر دو بر روی یک بستر ارتباطی قرار دارند یعنی هر دو یا به یک *WIFI* یا به وسیله کابل در یک شبکه قرار داشته باشند.
- پس از نصب وابستگیها سرور را با اجرا کردن دستور `node server` درون پوشه پروژه اجرا نمایید:
```
Local IP Address: <mark title="IP کامپیوتر در شبکه LAN" class="green">192.168.236.146</mark>
Server Running on: http://192.168.236.146:3001
Happy Hacking ;)
```
- سپس آدرس فوق را کپی کرده و درون پوشه `src/API/index.js` در مقدار متغیر `IP` ذخیره نمایید.
- حال هرجا نیاز به آدرس خاصی از سرور داشتید میتوانید از تابع `URL` استفاده کنید برای مثال:
```js
console.log(URL("product"));
"http://192.168.236.146:3001/product"
```
</details>
# جزئیات
پس از افزایش محبوبیت تیشرتهای برنامه نویسی کوئرا که به مناسبت رویدادهای برنامه نویسی مختلف به دست شرکت کنندگان مسابقات میرسید حال کوئرا تصمیم گرفته برنامه فروشگاه مرچنت (*Merchant Shop*) خود را راه بیاندازد.
در همین اول کار آنها با چالش مواجه شده اند و از شما درخواست کمک کردهاند.
این برنامه باید محصولات موجود را از یک *API* دریافت نماید و به کاربر آنها در قالب یک لیست قابل اسکرول شدن نمایش دهد. به علاوه کاربر باید بتواند در یک صفحه مجزا لیست سبد خرید خود را مشاهد نماید.
به همین جهت پس از مشاوره کوئرا با مهیار آنها به یک معماری مناسب و ساده برای این کار دست پیدا کردند که به شرح زیر است:
## فایل `Context/index.js`
در این فایل شما باید یک *Context* جهت مدیریت استیتهای سبد خرید یا همان *Shopping Cart* را پیاده سازی کتید که موارد مورد نیاز آن به شرح زیر است:
### هوک `useCartContext`
این هوک باید مقادیری که درون *Context* وجود دارد را برای کامپوننتی که به عنوان فرزند این *Context* قرار دارد تدارک ببینید.
### کامپوننت `CartProvider`
این هوک یک *Wrapper* کاربردی جهت مدیریت استیتها و پاس دادن متغیرها و توابع ضروری میباشد. در گام اول این کامپوننت باید یک درخواست از نوع *GET* به آدرس زیر ارسال نماید و در صورتی که کاربر از قبل سبد خریدی داشت آن را درون استیت مناسب خود ذخیره نماید که نمونه پاسخ آن را میتوانید در بلوک زیر مشاهده نمایید:
```js
"SERVER_ADDRESS/cart"
const RESPONSE = [
{ id: "1", name: "Apple", price: "1" },
{ id: "2", name: "Lenovo Laptop", price: "1000" },
{ id: "3", name: "Banana", price: "2" },
{ id: "4", name: "IPhone", price: "32000" },
{ id: "5", name: "Casio Watch", price: "60" },
{ id: "6", name: "Naruto Manga Chapter 60", price: "30" },
{ id: "7", name: "Luffy Straw Hat", price: "35" },
]
```
همچنین این کامپونن باید مقادیر و توابع زیر را تدارک دهد:
- استیت *cart* که بیانگر سبد خرید کاربر میباشد
- تابع `addCart` که برای اضافه کردن یک محصول به سبد خرید کاربر استفاده میشود. هر محصول در قالب یک آبجکت به این تابع پاس داده میشود که مشخصات آن محصول به شرح زیر است:
- شناسه یا همان `id`
- نام محصول یا همان `name`
- قیمت محصول یا همان `price`
در صورتی که این محصول در سبد خرید وجود نداشت کلید مربوط به `count` را برابر یک قرار دهد و در صورتی که در سبد خرید موجود بود به تعداد آن یکی اضافه کند.
- تابع `increaseItem` که با گرفتن شناسه محصول یک عدد به تعداد آن یعنی `count` اضافه کند.
- تابع `decreaseItem` که با گرفتن شناسه محصول یک عدد از تعداد آن یعنی `count` کم میکند و در صورتی که مقدار آن برابر صفر شد آن را از سبد خرید حذف کند.
- تابع `removeItem` که با گرفتن شناسه محصول آن را از سبد خرید حذف میکند.
- تابع `getTotal` که قیمت کل محصولات موجود در سبد خرید را محاسبه و برمیگرداند.
- تابع `checkOut` که سبد خرید کاربر را به آدرس `/cart` به صورت *POST* ارسال میکند و سپس سبد خرید کاربر را خالی میکند.
تمامی موارد زیر باید در قالب یک شی تدارک دیده شوند.
## کامپوننت `src/Pages/Shop.jsx`
در این صفحه باید لیست محصولات موجود در فروشگاه را ابتدا از *API* دریافت نماید و باید با استفاده از کامپوننت `<ListRenderer />` و `<ShopItem />` به نحو مطلوب نمایش دهد
### کامپوننت `src/Components/ShopItem`
این کامپوننت با دریافت نام، شناسه و قیمت محصول به همراه مقادیر مربوط به استیت منیجر `cart` در قالب پراپس موارد زیر را پیاده کند:
- نام محصول
- قیمت محصول.
- دکمه خرید که وقتی بر روی آن کلیک شد با استفاده از تابع مناسب محصول را به سبد خرید کاربر اضافه کند.
برخی از موارد در این بخش پیاده سازی شده است و شما باید باقی بخشهای ناقص را پیاده سازی کنید.
## کامپوننت `src/Pages/Cart.jsx`
این کامپوننت وظیفه نمایش محصولات موجود در سبد خرید کاربر را بر عهده دارد که و باید با استفاده از کامپوننت `<ListRenderer />` و `<CartItem/>` در صورتی که سبد خرید خالی نبود به نحو مطلوب نمایش دهد. این کامپوننت باید موارد زیر را پیاده سازی نماید.
- یک متن شامل قیمت کل محصول را به صورت زیر برای مثال نمایش دهد:
```
Total: $5
```
و یک دکمه با متن *Checkout* که در صورتی که بر روی آن کلیک شد سبد خرید کاربر با تابع مناسب موجود در *Context* پردازش کند.
- در صورتی که سبد خرید از ابتدا خالی بود پیغام `MESSAGES.EMPTY` را به کاربر نمایش دهد
- در صورتی که بر اثر *Checkout* شدن خالی شده بود پیغام `MESSAGES.CHECKOUT` را به کاربر نمایش دهد.
### کامپوننت `src/Components/CartItem`
این کامپوننت وظیفه آن نمایش قیمت، نام و قیت کل محصول مذکور میباشد همچنین دارای سه دکمه میباشد که به شرح زیر است:
- دکمه `PLUS` که وظیفه آن اضافه کردن یک واحد به آن محصول میباشد.
- دکمه `MINUS` که وظیفه آن کم کرد یک واحد از آن محصول میباشد.
- دکمه `DELETE` که وظیفه آن حذف آن محصول از سبد خرید کاربر میباشد.
## کامپوننت `App.js`
این فایل و کامپوننت بخش اصلی برنامه ما را تشکیل میدهد و وظیفه آن برقرار کردن راهبری یا همان *Navigation* میان صفحات با استفاده از کتابخانه `react navigation` میباشد برنامه ما دارای دو صفحه اصلی است:
- صفحه ای با اسم `Shop` که باید کامپوننت `Shop` را به کاربر نمایش دهد.
- صفحه ای با اسم `Cart` که باید کامپوننت `Cart` را به کاربر نمایش دهد.
تمامی این صفحات باید در گوشه راست بالا دکمه `NavigationButton` را نمایش دهند که در ادامه به بررسی آن خواهیم پرداخت.
### کامپوننت `src/Components/NavigationButton.jsx`
این کامپوننت با دریافت پراپس های مناسب باید موارد زیر را تکمیل نماید.
- در صورتی که در صفحه `Shop` بودیم متن آن باید `Cart` باشد و بالعکس.
- در صورتی که در صفحه `Shop` بودیم و بر روی آن فشار داده شد باید به صفحه `Cart` منتقل شود و بالعکس.
# نکات
- برای ارسال پوشه `src` و فایل `App.js` را بدون پوشه `node_modules` *ZIP* کرده و ارسال کنید.
- در صورتی که توضیحاتی برای شما نامفهوم بود پیشنهاد میشود به گیف صورت سوال نگاه کنید.
- اجباری به استفاده از *Style* ها وجود ندارد و صرفا جهت زیبا تر شدن پروژه میتوانید از آنها استفاده کنید.