![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* ها وجود ندارد و صرفا جهت زیبا تر شدن پروژه میتوانید از آنها استفاده کنید.
ارسال پاسخ برای این سؤال
در حال حاضر شما دسترسی ندارید.