**مهارتهای لازم:**
- آشنایی با `CSS`
--------------------------------------------------
در این سوال قصد داریم یک نقشه مارپیچ را با استفاده از _CSS_ طراحی کنیم. المان های این نقشه از قبل طراحی شدهاند اما نه از رنگبندی برخوردار هستند نه از طرح بندی! ظاهر کلی برنامه به شکل زیر می باشد:
![توضیح تصویر](https://quera.ir/qbox/view/k4GfZi9iwo/simple_maze_map.jpg)
# پروژه اولیه
پروژه اولیه را از [این لینک](/contest/assignments/21630/download_problem_initial_project/77478/) دانلود کنید.
ساختار فایلهای این پروژه به صورت زیر است.
```
Flex-box-layout-styling
├── cypress
│ ├── fixtures
│ │ └── example.json
│ ├── integration
│ │ └── sample.spec.js
│ ├── plugins
│ │ └── index.js
│ └── support
│ ├── commands.js
│ └── index.js
├── .qsampletest
├── cypress.json
├── index.html
├── package-lock.json
├── package.json
└── styles.css
```
# جزئیات
پروژه را با توجه به تصویری که در ابتدای صورت سوال قرار داده شده است تکمیل کنید. نکات زیر را در حین پیادهسازی مد نظر داشته باشید :
- بلوک ها عناصری هستند که کلاس `block` بر روی آنها اعمال شده است.
- اندازه هر بلوک ۴۰*۴۰ می باشد.
- بلوک های ستون اول، ستون آخر، سطر اول و سطر آخر به عنوان دیوار در نقشه قرار دارند.
- رنگ بلوکهایی که به عنوان دیوار در نقشه قرار دارند باید به رنگ سبز (`#05b37b`) در بیاید.
- توجه داشته باشید رنگ مورد نظر باید به بلوک ها اعمال شود.
توضیحات فایل _index.html_ :
- نقشه از تعداد زیادی ردیف تشکیل شده است و در هر ردیف ۱۲ بلوک قرار دارد. مجموعا ۱۲ ردیف هم وجود دارد.
- برای راحتی کار توصیه می شود برای طرح بندی از _flexbox_ استفاده کنید.
- شما نیازی به ایجاد تغییر در فایل _index.html_ ندارید.
# نکات
- تغییرات را تنها در فایل `styles.css` اعمال کنید. تغییرات در بقیه فایلها نادیده گرفته میشوند.
- توجه کنید که داوری خودکار بر مبنای نام کلاسها انجام میشود.
- پروژه را با ساختار زیر ارسال کنید.
```
[your-zip-file-name].zip
└── styles.css
```
CSS - مارپیچ
**مهارتهای لازم**:
+ آشنایی با `ReactJS`
+ آشنایی با `React Context`
+ کدخوانی
--------------------------------------------------
# پروژه اولیه
پروژه اولیه را از
[این لینک](/contest/assignments/21630/download_problem_initial_project/77477/)
دانلود کنید.
ساختار فایلهای این پروژه به صورت زیر است.
```
theme-switcher
├── public
│ ├── favicon.ico
│ └── index.html
├── src
│ ├── components
│ │ ├── NameBox.jsx
│ │ └── ThemeSwitcher.jsx
│ ├── constants
│ │ └── index.js
│ ├── data
│ │ └── Styles.js
│ ├── providers
│ │ └── ThemeProvider.jsx
│ ├── App.jsx
│ ├── index.css
│ ├── index.js
│ └── setupTests.js
├── package-lock.json
└── package.json
```
<details class="brown">
<summary>
راهاندازی پروژه
</summary>
**برای اجرای پروژه، باید `NodeJS` و `npm` را از قبل نصب کرده باشید.**
- ابتدا پروژهی اولیه را دانلود و از حالت فشرده خارج کنید.
- در پوشهی `theme-switcher` ، دستور `npm install` را برای نصب نیازمندیها اجرا کنید.
- در همین پوشه، دستور `npm start` را برای راهاندازی پروژه اجرا کنید.
- پس از انجام موفق این مراحل، با مراجعه به آدرس `http://localhost:3000/`
میتوانید نتیجه را ببینید.
</details>
# جزئیات
ظاهر کلی برنامه بدین صورت است:
![ظاهر برنامه](https://quera.ir/qbox/view/ZDRVVVcWM4/theme-switcher.gif)
در این سوال میخواهیم با استفاده از *context* در ریاکت برنامهای بنویسیم که بتوانیم بین دو تم *dark* و *light* سوییچ کنیم.
#### مواردی که باید در این سوال رعایت کنید:
- تم برنامه با فعال کردن گزینه *Dark mode* باید *dark* و با غیرفعال کردن آن باید *light* شود.
#### تغییرات لازم برای هر فایل:
- فایل `ThemeProvider.jsx`: کد قسمت *context* را باید در این فایل بنویسید. مقدار اولیه تم باید *light* باشد.
- فایل `ThemeSwitcher.jsx`: در این فایل باید کد مربوط به تغییر تم را بزنید. در این فایل نیازی به تغییری قسمت *return* نیست.
- فایل `App.jsx`: در این فایل شما باید مقدار کنونی تم را از *context* بخوانید و به تابع *Styles* بدهید. در این فایل نیازی به ایجاد تغییرات در کامپوننت *App* و بخش *return* هر دو کامپوننت نیست.
# نکات
- نام متغیر *context* خود را **ThemeContext** و برای تم، **themeMode** بگذارید.
- شما تنها مجاز به اعمال تغییرات در فایلهای `ThemeProvider.jsx` و `ThemeSwitcher.jsx` و `App.jsx` هستید.
- دقت کنید فقط بخش *return* کامپوننت `ThemeProvider.jsx` نیاز به اعمال تغییرات دارد و برای مابقی کامپوننتها نیازی به تغییری *return* آنها نیست.
- پس از اعمال تغییرات، پروژه را zip کرده و ارسال کنید.دقت کنید که پوشهی node_modules در فایل ارسالی نباشد.
React - تم سوییچر
**مهارتهای لازم**:
+ آشنایی با جاوااسکریپت
--------------------------------------------------
# پروژه اولیه
پروژه اولیه را از
[این لینک](/contest/assignments/21630/download_problem_initial_project/77479/)
دانلود کنید.
ساختار فایلهای این پروژه به صورت زیر است.
```
moving-array
├── cypress
│ ├── fixtures
│ │ └── example.json
│ ├── integration
│ │ └── sample.spec.js
│ ├── plugins
│ │ └── index.js
│ └── support
│ ├── commands.js
│ └── index.js
├── cypress.json
├── index.html
├── package-lock.json
├── package.json
├── script.js
└── styles.css
```
# جزئیات
ظاهر کلی برنامه بدین صورت است:
![ظاهر برنامه](https://quera.ir/qbox/view/Ih6ePXMOer/moving-array.gif)
در این سوال میخواهیم برنامه بنویسیم که اعداد داخل یک آرایه را بتوانیم جابهجا کنیم (آرایه شامل اعداد یکتا می باشد). بدین صورت که در فیلد *item* عدد مورد نظر و در فیلد *count* مقدار جابهجایی آن عدد وارد میشود و براساس این مقادیر آرایه اولیه تغییر میکند. همچنین میتوان انتخاب کرد که عدد مورد نظر به سمت پایین یا بالا جابهجا شود.
در برنامه سه نوع خطا وجود دارد:
- **خطای INVALID_INPUT:** این خطا زمانی اتفاق میافتد که یکی از فیلدها پر نشده باشد.
- **خطای NOT_FOUND:** این خطا زمانی اتفاق میافتد که عدد وارد شده در آرایه وجود نداشته باشد.
- **خطای NOT_POSSIBLE:** این خطا زمانی اتفاق میافتد که جابهجایی عدد مورد نظر امکانپذیر نباشد. برای مثال جابهجایی عدد ایندکس اول به سه واحد عقب امکانپذیر نیست. این مورد برای جابهجایی به جلو نیز صادق است.
#### مواردی که باید در این تمرین رعایت کنید:
- در ابتدا آرایه اولیه باید در المان با ایدی `numbers-container` نمایش داده شود. هر عدد باید داخل یک تگ `span` باشند.
- هنگام کلیک برروی دکمه *submit* باید براساس ورودیها آرایه تغییر کند و اعداد جدید براساس مورد قبل نمایش داده شوند.
- اگر یکی از خطاهای بالا در هنگام کلیک برروی دکمه رخ داد، باید در المان با ایدی `error-container` یک تگ `p` با ایدی `error` نوع خطا نمایش داده شود. (منظور از نوع خطا همان کلمه انگلیسی است.)
- در هر لحظه فقط یک خطا نمایش داده شود و ترتیب نمایش باید براساس ترتیت خطاهای گفته شده باشد.
- در هنگام کلیک برروی دکمه باید خطا قبلی (منظور همان تگ `p` با ایدی `error` است.) پاک شود.
# نکات
- شما تنها مجاز به اعمال تغییرات در فایل `script.js` هستید.
- فقط فایل `script.js` را ارسال کنید.
JavaScript - جابهجایی آرایه
**مهارتهای لازم**:
+ آشنایی با مفاهیم جاوااسکریپت
+ آشنایی با `CSS`
+ آشنایی با `ReactJS`
--------------------------------------------------
ظاهر کلی برنامه بدین صورت است:
![ظاهر برنامه](https://quera.ir/qbox/view/ECrtM43pbW/bourse.gif)
# پروژه اولیه
پروژه اولیه را از
[این لینک](/contest/assignments/21630/download_problem_initial_project/77476/)
دانلود کنید.
<details class="green">
<summary>
ساختار فایلهای این پروژه به این صورت است
</summary>
```
bourse
├── public
│ ├── favicon.ico
│ └── index.html
├── server
│ └── server.js
├── src
│ ├── __tests__
│ │ └── sample.test.js
│ ├── components
│ │ ├── chart
│ │ │ └── Charts.jsx
│ │ └── stockCard
│ │ └── StockCard.jsx
│ ├── App.js
│ ├── index.css
│ └── index.js
├── package-lock.json
└── package.json
```
</details>
<details class="brown">
<summary>
راهاندازی پروژه
</summary>
برای اجرای پروژه، باید` NodeJS` و `npm` را از قبل نصب کرده باشید.
- ابتدا پروژهی اولیه را دانلود و از حالت فشرده خارج کنید.
- در پوشهی `bourse` ، دستور `npm install` را برای نصب نیازمندیها اجرا کنید.
- در همین پوشه، دستور `npm run server` را برای راهاندازی سرور پروژه اجرا کنید.
- سپس با اجرای دستور `npm start` در ترمینالی دیگر پروژه ریاکت را اجرا کنید.
</details>
## هدف سوال
در این سوال شما باید صفحهای را تکمیل کنید که در آن اطلاعات مورد نیاز در فاصلهزمانیهای مشخص باید از سرور درخواست شود و به کمک پاسخی که دریافت میکنید به نمایش آن اطلاعات و رسم نموداری برای نمایش بهتر آنها در صفحه بپردازید.
# جزئیات
شما باید ابتدا در فایل `App.js` اطلاعات مورد نیاز خود را با ریکوئست *GET* زدن به آدرس زیر دریافت کنید.
```
http://localhost:3001/stock
```
در ساختار response دو مقدارِ *value* و *name* قرار دارد، که به صورت مثال به شکل زیر خواهد بود:
```json
{
value: 158020,
name: "CodeCup Stock"
}
```
در ادامه شما باید دو کامپوننت `<StockCard />` و `<Chart />` را به همین ترتیب در فایلِ `App.js` استفاده کنید و سپس باید به تکمیل آنها بپردازید.
در این سوال شما در بازههای زمانی که به کمک متغیر ***intervalTime*** تعیین میشود (به صورت مثال هر یک ثانیه) باید به سرور درخواست *GET* بزنید و تاریخچهای از *response*هایی که دریافت میکنید را نگهداری کنید؛ چون برای «رسم نمودار» و همچنین «نمایش اطلاعات آخرین قیمت» به آنها نیاز خواهید داشت.
#### ۱- برای کامل کردنِ کامپوننتِ `<StockCard />` شما باید موارد زیر را رعایت کنید:
+ **نام سهام** را که در ریکوئست بالا دریافت کردید در المان با کلاسِ `title` نشان دهید.
+ همچنین **آخرین قیمت** دریافتی را نیز در المان با کلاسِ `price` نشان دهید.
+ درصد تغییر سهم را - به کمک دو قیمت آخر آن - محاسبه کنید و در المان با آیدیِ `percentage` نشان دهید.
- توجه کنید که باید آن را دقیقاً همانند تصویری که در صورت سوال آمده، با قرار دادنِ **+** و یا **-** در ابتدای آن و تنها با نمایش **۲ رقم اعشار** و علامت **٪** (درصد) در انتهای آن نشان دهید.
- همچنین دقت کنید که بین آنها هیچ فاصلهای وجود ندارد.
+ کلاسها را به صورتی تکمیل کنید که اگر ارزش کنونی سهام نسبت به ارزش قبلی آن رشد داشته باشد، باید نشانگر رو به بالا را نمایش دهیم؛ یعنی به المان با آیدیِ `arrow` کلاسِ `up` داده شود و اگر ارزش آن کاهش یافته باشد به آن کلاسِ `down` اختصاص داده شود.
- همچنین بالطبع رنگ درصد محاسبه شده، در صورتی که سهم رشد داشته باشد کلاسِ `percentage_up` و در صورت کاهش یافتن ارزش سهم، کلاسِ `percentage_down` را میگیرد.
- دقت کنید اگر در ارزش سهام، تغییری صورت نگرفت آن را همانند زمانی که مثبت میشود با رنگ سبز و نشانگر رو به بالا نشان دهید. همچنین در ابتدا که هنوز قیمتی ارسال نشده به جای عدد در آن سه نقطه (**...**) قرار دهید.
**نکته:** دقت کنید که در این سوال باید «به محض لود شدن صفحه» اولین درخواست *GET* زده شود و قیمت و نام سهام را در صفحه داشته باشید (برای درصد تغییرات هم سه نقطه نمایش دهید)
#### ۲- برای کامل کردنِ کامپوننتِ `<Chart />` شما باید موارد زیر را رعایت کنید:
+ تنها ۵۰ قیمت آخر سهم نمایش داده شود.
- همچنین اگر کمتر از ۵۰ قیمت تاکنون دریافت شده، طبیعتاً همان تعداد نمایش داده شود.
+ شما باید در داخل المان با کلاسِ `chartContainer` پس از هربار اضافه شدن قیمت جدید در سهم، یک `<div/>` اضافه کنید.
- برای تبدیل شدن آن `<div/>` به میلههای نمودار باید ابتدا کلاسِ `chart` را به آن اضافه کنید و سپس همانند کامپوننت بالا، با توجه به رشد و یا کاهش قیمت سهم یکی از دو کلاسِ `chart_down` و یا `chart_up` را نیز به آن بیفزایید.
- همچنین باید ارتفاع میله متناسب با قیمت سهم باشد، به این صورت که ارتفاع را بین ۰ تا ۳۰۰ پیکسل در نظر بگیرید و ارزش سهم را بین ۰ تا ۷۹۰۰۰۰۰.
<details class="blue">
<summary>
**راهنمایی**
</summary>
اگر ارزش سهم ۶۵۰۰ بود ارتفاع میله آن بدین شکل محاسبه میگردد:
```
height: (6500 / 7900000) * 300
```
</details>
# نکات
+ فاصله زمانی ریکوئستها در کامپوننت `App.js` به کمک متغیر ***intervalTime*** تعیین میشود، شما نیز باید در حل سوال باید حتما از همین متغیر به عنوان فاصله زمانی استفاده کنید و عدد را به صورت هاردکد ننویسید.
+ لطفاً از حذف کردن اطلاعات دیگر سوال خودداری کنید و تنها در قسمتهای مشخص شده با اضافه کردن پاسخ خود به حل سوال بپردازید.
+ پس از اعمال تغییرات، پروژه را *zip* کرده و ارسال کنید. دقت کنید که پوشهی *node_modules* در فایل ارسالی نباشد.
شما تنها مجاز به اعمال تغییرات در فایلهای زیر هستید.
`src/App.js`
`src/components/chart/Charts.jsx`
`src/components/stockCard/StockCard.jsx`
React - بورس
**مهارتهای لازم**:
+ مدیریت state ها
+ تسلط به هوک ها
+ هندل کردن درخواست ها
--------------------------------------------------
ظاهر کلی برنامه بدین صورت است:
![ظاهر برنامه](https://quera.ir/qbox/view/cMIvpxd0Gc/Peek%202020-12-04%2004-17.gif)
# پروژه اولیه
پروژه اولیه را از
[این لینک](/contest/assignments/21630/download_problem_initial_project/77475/)
دانلود کنید.
<details class="green">
<summary>
ساختار فایلهای این پروژه به این صورت است
</summary>
```
issues-page
├── public
│ ├── favicon.ico
│ └── index.html
├── server
│ ├── issues.js
│ └── server.js
├── src
│ ├── __tests__
│ │ └── sample.test.js
│ ├── assets
│ │ ├── index.css
│ │ └── loading.gif
│ ├── components
│ │ ├── App.js
│ │ ├── CloseIssueIcon.js
│ │ ├── IssueItem.js
│ │ ├── IssueList.js
│ │ ├── Loading.js
│ │ └── OpenIssueIcon.js
│ ├── hooks
│ │ └── useInfiniteScroll.js
│ └── index.js
├── package-lock.json
└── package.json
```
</details>
<details class="brown">
<summary>
راهاندازی پروژه
</summary>
برای اجرای پروژه، باید` NodeJS` و `npm` را از قبل نصب کرده باشید.
- ابتدا پروژهی اولیه را دانلود و از حالت فشرده خارج کنید.
- در پوشهی `issues-page` ، دستور `npm install` را برای نصب نیازمندیها اجرا کنید.
- در همین پوشه، دستور `npm run server` را برای راهاندازی سرور پروژه اجرا کنید.
- سپس با اجرای دستور `npm start` در ترمینالی دیگر پروژه ریاکت را اجرا کنید.
</details>
# جزئیات
در این سوال قصد داریم صفحه issues سایت github را بسازیم.
برای گرفتن لیست issue ها از سرور باید درخواست GET به
http://localhost:9000/issues
این آدرس دوتا query دارد.
http://localhost:9000/issues?page=1&issuesFilter=0
**پارامتر page:** برای صفحه بندی استفاده میشود. فرض کنید اگر اندازه هر صفحه ۱۵ باشد صفحه اول ۱۵ تای اول و صفحه دوم ۱۵ تای بعدی و ... . مقدار پیشفرض آن برابر ۱ است.
**پارامتر issuesFilter:** مقدار 0 برای هیچ فیلتر، مقدار 1 برای گرفتن issue های open و مقدار 2 برای issue های closed. مقدار پیشفرض آن 0 است.
اطلاعات دریافتی شامل ارایهای از issue ها به صورت json است:
```json
[
{
"title": "Bind to a Map() Object not possible",
"status": "open"
}
]
```
مواردی که باید در این پروژه ایجاد کنید:
- وقتی صفحه لود میشود، باید لیست issue های صفحه اول بدون فیلتر از سرور گرفته و در تگ div با کلاس issues با استفاده از کامپوننت IssueItem نمایش داده شود.
- وقتی اسکرول صفحه به اخر صفحه رسید باید درخواست برای گرفتن issue های صفحه بعد فرستاده و این issue ها باید به آخر لیست قبلی اضافه شوند.
- در هنگام اسکرول آخرین درخواست زمانی اتفاق میفتد که دیتایی که از سرور گرفته میشود، لیست خالی باشد.
- وقتی روی Open یا Closed بالای جدول کلیک شود issue های قبلی باید پاک شوند و issue ها با فیلتر مورد نظر گرفته و نمایش داده شوند. (باید ویژگی اسکرول با این فیلتر جدید هم کار کند)
- بعداز هر درخواستی (گرفتن issue ها موقع لود شدن صفحه، تغییر فیلتر و لود کردن بیشتر موقع اسکرول) باید کامپوننت Loading نمایش داده شود.
**نکته:** فرض کنید تعداد کل issue هایی که در سرور وجود دارد، ۲۲ تا و اندازه هر صفحه ۱۵ است. در هنگام لود شدن صفحه یک درخواست و ۱۵ تا issue اول گرفته میشود، وقتی اسکرول میشود یک درخواست دیگر برای صفحه بعد ۷ تای باقیمانده رو میگیرد. با اسکرول بیشتر یک درخواست دیگر فرستاده میشود که لیست خالی میگیرد. وقتی به لیست خالی رسیدیم دیگر نباید درخواست دیگری با اسکرول کردن ارسال شود.
**توجه:** اگر ۱۵ تا issue داخل یک صفحه اسکرین شما جا میگیرد با زوم کردن کاری کنید که کمتر از ۱۵ تا issue بتواند دیده شود و اسکرول بار وجود داشته باشد.
# نکات
شما تنها مجاز به اعمال تغییر در فایلهای زیر هستید:
src/hooks/useInfiniteScroll.js
src/components/IssueList.js
src/components/App.js
- پس از اعمال تغییرات، پروژه را *zip* کرده و ارسال کنید.دقت کنید که پوشهی *node_modules* در فایل ارسالی نباشد.