**مهارتهای لازم:**
- آشنایی با `map`، `filter` و `reduce`
--------------------------------------------------
ظاهر کلی برنامه بدین صورت است:
![ظاهر برنامه](https://quera.ir/qbox/view/OmMTw8Pk4X/overview.png)
# پروژه اولیه
پروژه اولیه را از
[اینجا](https://quera.ir/qbox/download/jt6U7GlfAK/read-json.zip)
دانلود کنید.
ساختار فایلهای این پروژه به صورت زیر است.
```
read-json
├── public
│ ├── favicon.ico
│ └── index.html
├── src
│ ├── __tests__
│ │ └── sample.test.js
│ ├── AverageAge.js
│ ├── UserItem.js
│ ├── UserList.js
│ ├── index.css
│ ├── index.js
│ └── users.json
├── package.json
└── yarn.lock
```
<details class="brown">
<summary>
راهاندازی پروژه
</summary>
**برای اجرای پروژه، باید `NodeJS` و `npm` را از قبل نصب کرده باشید.**
- ابتدا پروژهی اولیه را دانلود و از حالت فشرده خارج کنید.
- در پوشهی `read-json` ، دستور `npm install` را برای نصب نیازمندیها اجرا کنید.
- در همین پوشه، دستور `npm start` را برای راهاندازی پروژه اجرا کنید.
- پس از انجام موفق این مراحل، با مراجعه به آدرس `http://localhost:3000/`
میتوانید نتیجه را ببینید.
</details>
# جزئیات
دادههای کاربر در فایل `users.json` به این صورت هستند:
```js
[
{
"name": string,
"age": number,
"role": string
}
]
```
- `name`: اسم کاربر
- `age`: سن کاربر
- `role`: نقش کاربر که میتواند `user` یا `admin` باشد.
در این سوال شما باید ابتدا لیست کاربران را از فایل `users.json` بخوانید و سپس کاربرانی که دارای نقش `user` هستند را با استفاده از کامپوننت `UserItem` نمایش دهید و میانگین سنی کاربرانی که دارای نقش `admin` هستند را بدست آورید و با استفاده از کامپوننت `AverageAge` نشان دهید.
# نکات
- شما تنها مجاز به اعمال تغییرات در فایل `UserList.js` هستید.
- تعدادی تست نمونه در پروژه اولیه وجود دارد که با استفاده از آنها میتوانید کد خود را تست کنید.
- پس از اعمال تغییرات، پروژه را _ZIP_ کرده و ارسال کنید. دقت کنید که پوشهی `node_modules` در فایل ارسالی نباشد.
لیست کاربران
**مهارتهای لازم:**
- آشنایی با `hook`
--------------------------------------------------
ظاهر کلی برنامه بدین صورت است:
![ظاهر برنامه](https://quera.ir/qbox/view/oIep7LbarM/ezgif.com-video-to-gif.gif)
# پروژه اولیه
پروژه اولیه را از
[اینجا](https://quera.ir/qbox/download/AaetNQP3op/timer-hook.zip)
دانلود کنید.
ساختار فایلهای این پروژه به صورت زیر است.
```
timer-hook
├── public
│ ├── favicon.ico
│ └── index.html
├── src
│ ├── Timer.js
│ ├── index.css
│ ├── index.js
│ └── use-timer.js
├── package-lock.json
└── package.json
```
<details class="brown">
<summary>
راهاندازی پروژه
</summary>
**برای اجرای پروژه، باید `NodeJS` و `npm` را از قبل نصب کرده باشید.**
- ابتدا پروژهی اولیه را دانلود و از حالت فشرده خارج کنید.
- در پوشهی `timer-hook` ، دستور `npm install` را برای نصب نیازمندیها اجرا کنید.
- در همین پوشه، دستور `npm start` را برای راهاندازی پروژه اجرا کنید.
- پس از انجام موفق این مراحل، با مراجعه به آدرس `http://localhost:3000/`
میتوانید نتیجه را ببینید.
</details>
# جزئیات
در این سوال شما باید یک `hook` بسازید که یک تایمر را کنترل کند. این هوک باید قابلیتهای شروع، ادامه و ریست
داشته باشد.
هوک ساخته شده باید چهار خروجی داشته باشد:
```js
const {seconds, resume, stop, reset} = useTimer()
```
- `seconds`: ثانیه که الان در آن هستیم، از صفر شروع میشود و هر ثانیه یک واحد افزایش مییابد.
- `stop`: تابعی که باعث میشود تایمر متوقف شود.
- `resume`: تابعی که باعث میشود تایمر ادامه پیدا کند.
- `reset`: تابعی که تایمر را به حالت اولیه یعنی شروع از صفر میبرد.
# نکات
- شما تنها مجاز به اعمال تغییرات در فایل `use-timer.js` هستید.
- تعدادی تست نمونه در پروژه اولیه وجود دارد که با استفاده از آنها میتوانید کد خود را تست کنید.
- پس از اعمال تغییرات، پروژه را _ZIP_ کرده و ارسال کنید.دقت کنید که پوشهی `node_modules` در فایل ارسالی نباشد.
قلاب زمانسنج
**مهارتهای لازم:**
- `React`
- `Error Handling in React 16`
------
ریاکت ۱۶ یک استراتژی جدید را برای مواجهه با خطاهایی که ممکن است رخ بدهد، معرفی کرده است.
با استفاده از این استراتژی میتوان از موقعیتهایی که خطایی در داخل یک فرایند رندر کردن باعث بروز یک *State* غیر معتبر و در نتیجه رفتار تعریف نشده و خطاهای گیج کننده میشود جلوگیری کرد.
![توضیح تصویر](https://quera.ir/qbox/view/l05vDwAYWS/error.gif)
برای مطالعه بیشتر به [اینجا](https://reactjs.org/blog/2017/07/26/error-handling-in-react-16.html) مراجعه کنید.
در این سؤال از شما میخواهیم کد پروژه را به گونهای تغییر دهید که در صورت رخ دادن خطا، اپلیکیشن به کار خود ادامه دهد.
# پروژه اولیه
پروژه اولیه را از
[اینجا](https://quera.ir/qbox/download/TCStXQMZ7y/errors-boundary.zip)
دانلود کنید.
ساختار فایلهای این پروژه به صورت زیر است:
```
errors-boundary
├── public
│ ├── favicon.ico
│ ├── index.html
│ └── manifest.json
├── src
│ ├── __tests__
│ │ └── AppSample.test.js
│ ├── App.css
│ ├── App.js
│ ├── Error.js
│ ├── ErrorBoundary.js
│ ├── Form.js
│ ├── index.css
│ ├── index.js
│ └── serviceWorker.js
├── package.json
├── pnpm-lock.yaml
```
<details class="brown">
<summary>
راهاندازی پروژه
</summary>
**برای اجرای پروژه، باید `NodeJS` و `npm` را از قبل نصب کرده باشید.**
- ابتدا پروژهی اولیه را دانلود و از حالت فشرده خارج کنید.
- در پوشهی `errors-boundary` ، دستور `npm install` را برای نصب نیازمندیها اجرا کنید.
- در همین پوشه، دستور `npm start` را برای راهاندازی پروژه اجرا کنید.
- پس از انجام موفق این مراحل، با مراجعه به آدرس `http://localhost:3000/`
میتوانید نتیجه را ببینید.
</details>
# جزئیات
ساختار *state* فایل `App.js` به صورت زیر است
```javascript
state: {
person: {
year : ''
},
error:''
}
```
در صورت وارد کردن مقدار در `input`، مقدار آن در `state.person.year` ذخیره میشود.
در صورت وارد کردن مقدار غیر عددی `person`، خطایی اتفاق می افتد ولی برنامه به کار خود ادامه میدهد و محتویات فایل `Error.js` را نمایش میدهد. `error` مورد نظر باید در `state.error` ذخیره شود؛
همچنین در صورت کلیک بر روی دکمه "بارگذاری مجدد" برنامه باید به حالت اولیه خود برگردد.
# نکات
+ شما تنها مجاز به اعمال تغییر در فایلهای `App.js` و `ErrorBoundary.js` هستید.
+ تعدادی تست نمونه در پروژه اولیه وجود دارد که با استفاده از آنها میتوانید کد خود را تست کنید.
+ پس از اعمال تغییرات، پروژه را *ZIP* کرده و ارسال کنید. دقت کنید که فقط میتوانید فایلهای بالا را تغییر دهید.
خطایابی
در این سؤال باید یک مسابقه چند سوالی طراحی کنید؛ به این صورت که کاربر با هر بار پاسخ دادن به یک سوال، به سوال بعدی میرود و در نهایت امتیاز نهایی که کسب کرده، به او نشان داده میشود.
------
![Image 1](https://quera.ir/qbox/view/ZpXzUTEAiZ/demo.gif)
# پروژه اولیه
پروژه اولیه را از
[اینجا](https://quera.ir/qbox/download/EtkQkSv0AL/quiz.zip)
دانلود کنید.
ساختار فایلهای این پروژه به صورت زیر است.
```
quiz
├── public
│ ├── favicon.ico
│ ├── index.html
│ ├── logo192.png
│ ├── logo512.png
│ ├── manifest.json
│ └── robots.txt
├── src
│ ├── __tests__
│ │ └── AppSample.test.js
│ ├── actions
│ │ └── index.js
│ ├── constants
│ │ └── actionTypes.js
│ ├── reducers
│ │ ├── index.js
│ │ ├── level.js
│ │ ├── person.js
│ │ └── quiz.js
│ ├── App.css
│ ├── App.js
│ ├── counter.js
│ ├── index.css
│ ├── index.js
│ ├── logo.svg
│ ├── question.js
│ ├── questionDetails.js
│ ├── scoreDetails.js
│ └── serviceWorker.js
├── package-lock.json
├── package.json
└── pnpm-lock.yaml
```
<details class="brown">
<summary>
راهاندازی پروژه
</summary>
**برای اجرای پروژه، باید `NodeJS` و `npm` را از قبل نصب کرده باشید.**
- ابتدا پروژهی اولیه را دانلود و از حالت فشرده خارج کنید.
- در پوشهی `errors-boundary` ، دستور `npm install` را برای نصب نیازمندیها اجرا کنید.
- در همین پوشه، دستور `npm start` را برای راهاندازی پروژه اجرا کنید.
- پس از انجام موفق این مراحل، با مراجعه به آدرس `http://localhost:3000/`
میتوانید نتیجه را ببینید.
</details>
# جزئیات
طراحی *Redux* به صورت زیر است:
```javascript
quiz: {
questions: [
{
title: string,
options: [
{
key: number,
title: string
},
...
],
answerKey: number,
score: number
},
...
]
},
level: {
currentLevel: number,
isFinished: boolean,
levels: number
},
person: {
score: number,
rightAnswers: number,
wrongAnswers: number,
noAnswers: number
}
```
<details class="blue">
<summary>
توضیحات `quiz`
</summary>
+ ویژگی `questions`: آرایهای از سوالات که شامل موارد زیر است:
+ ویژگی `options`: آرایهای از گزینههای یک سوال که دارای یک کلید و متن گزینه میباشد.
+ ویژگی `answerKey`: کلید پاسخ صحیح
+ ویژگی `score`: امتیاز سوال
</details>
<details class="blue">
<summary>
توضیحات `level`
</summary>
- ویژگی `currentLevel`: مرحله جاری
- ویژگی `isFinished`: نشان دهنده اتمام بازی
- ویژگی `levels`: تعداد مراحل بازی
</details>
<details class="blue">
<summary>
توضیحات `person`
</summary>
- ویژگی `score`: امتیاز بازیکن
- ویژگی `rightAnswers`: تعداد پاسخ صحیح
- ویژگی `wrongAnswers`: تعداد پاسخ اشتباه
- ویژگی `noAnswers`: تعداد سوالات بیپاسخ
</details>
- بعد از کلیک روی هر گزینه، در صورت درست بودن پاسخ امتیاز سوال به کاربر اضافه و در صورت پاسخ اشتباه ۱۰ امتیاز از او کم میشود.
- در صورت پاسخ به یک سوال یا اتمام ۵ ثانیه، بازی به سوال بعدی میرود.
- بعد از لود شدن صفحه، کاربر ۵ ثانیه برای پاسخ به هر سوال فرصت دارد. در صورت جواب ندادن به سوال، بدون گرفتن امتیاز به سوال بعد میرود.
- بعد از اخرین مرحله، امتیاز نهایی و تعداد پاسخهای درست و غلط و تعداد سوالات بدون پاسخ سوالات به کاربر نمایش داده میشود.
# نکات
+ شما تنها مجاز به اعمال تغییر در فایلهای `question.js` ،`level.js`، `person.js` و `quiz.js` هستید.
+ تعدادی تست نمونه در پروژه اولیه وجود دارد که با استفاده از آنها میتوانید کد خود را تست کنید.
+ پس از اعمال تغییرات، پروژه را *ZIP* کرده و ارسال کنید. دقت کنید که فقط میتوانید فایلهای بالا را تغییر دهید.
کوییز
**مهارتهای لازم**:
+ آشنایی با توابع جاوااسکریپت
+ آشنایی با `ReactJS`
+ آشنایی با `Bootstrap`
+ کدخوانی
--------------------------------------------------
# پروژه اولیه
پروژه اولیه را از [اینجا](https://quera.ir/qbox/download/Qosp6qAvdB/fifabaz.zip) دانلود کنید.
ساختار فایلهای این پروژه به صورت زیر است.
```
fifabaz
├── public
│ ├── static
│ │ ├── css
│ │ │ └── bootstrap.css
│ │ └── js
│ │ ├── bootstrap.js
│ │ ├── jquery.js
│ │ └── popper.js
│ ├── favicon.ico
│ └── index.html
├── src
│ ├── __tests__
│ │ └── sample.test.js
│ ├── components
│ │ ├── FilterBox.js
│ │ ├── SortBox.js
│ │ └── Table.js
│ ├── containers
│ │ └── App.js
│ ├── data
│ │ ├── Clubs.js
│ │ ├── Nationality.js
│ │ ├── Players.js
│ │ ├── SortType.js
│ │ └── TeamPositions.js
│ ├── index.css
│ └── index.js
├── README.md
└── package.json
```
<details class="brown">
<summary>
راهاندازی پروژه
</summary>
**برای اجرای پروژه، باید `NodeJS` و `npm` را از قبل نصب کرده باشید.**
- ابتدا پروژهی اولیه را دانلود و از حالت فشرده خارج کنید.
- در پوشهی `fifabaz` ، دستور `npm install` را برای نصب نیازمندیها اجرا کنید.
- در همین پوشه، دستور `npm start` را برای راهاندازی پروژه اجرا کنید.
- پس از انجام موفق این مراحل، با مراجعه به آدرس `http://localhost:3000/`
میتوانید نتیجه را ببینید.
</details>
# جزئیات
در این پروژه ما میخواهیم ۲۰۰ بازیکن برتر بازی *FIFA 20* را در قالب یک جدول نمایش دهیم و کاربر باید بتواند بازیکنان را براساس ویژگیهای آنها فیلتر یا مرتب کند.
دیتاسِت مربوط به بازیکنان از سایت [`kaggle.com`](https://www.kaggle.com/stefanoleone992/fifa-20-complete-player-dataset#players_20.csv)، گرفته شده و در مسیر `data/Players.js` قرار داده شده است.
شما باید این اطلاعات را بخوانید و سپس براساس فیلترها و گزینه مرتبسازی که کاربر انتخاب کرده است آنها را در یک جدول نمایش دهید.
شکل کلی پروژه به صورت زیر میباشد:
![شکل کلی](https://quera.ir/qbox/view/ENwhXlPIWi/Fifabaz.gif)
اطلاعات بازیکنان در این فایل به صورت زیر میباشد:
```json
{
short_name: "L. Messi",
age: 32,
nationality: "Argentina",
club: "FC Barcelona",
overall: 94,
value: 95500000,
preferred_foot: "Left",
team_position: "RW"
}
```
در این پروژه چهار کامپوننت تعریف شده که شما باید هر یک از آنها را با توجه به قابلیتی که باید داشته باشد تغییر دهید.
<details class="blue">
<summary>
**۱) کامپوننت `App.js`**
</summary>
در این کامپوننت شما باید `state` مورد نیاز پروژه را تعریف کنید. خواندن از فایل `Players.js` در این بخش انجام میشود.
سه تابع در این فایل وجود دارد که شما باید آنها را براساس نیاز گفته شده تغییر دهید.
- تابع `changeSort(_selectedSort)`: این تابع وظیفه تغییر نحوه مرتب شدن جدول را دارد. پس از انتخاب یکی از موارد مرتب سازی این تابع باید فراخوانی شود.
- تابع `changeFilters`: این تابع وظیفه تغییر وضعیت نحوه فیلتر شدن دیتای جدول را دارد. پس از انتخاب فیلترها این تابع باید فراخوانی شود.
- تابع `renderTable`: این تابع وظیفه نمایش جدول را دارد. پس از هر تغییر در نحوه مرتب سازی یا فیلتر کردن این تابع جدول بروزرسانی شده را نمایش میدهد.
</details>
<details class="blue">
<summary>
**۲) کامپوننت`Table.js`**
</summary>
در این کامپوننت شما باید ابتدا `thead` جدول را براساس متغیر `fields` که در کامپوننت وجود دارد بسازید؛ سپس اطلاعات بازیکنان را در قسمت `tbody` جدول نشان دهید.
</details>
<details class="blue">
<summary>
**۳) کامپوننت `SortBox.js`**
</summary>
در این کامپوننت شما باید دکمههای مربوط به نحوه مرتب کردن جدول را بسازید. هر دکمه سه وضعیت دارد.
۱- غیرفعال: (در این حالت بازیکنان بدون تغییر و به صورت مرتب شده اولیه (براساس overall) نمایش داده میشود.)
۲- مرتب نزولی
۳- مرتب صعودی
کاربر میتواند روی هرکدام کلیک کند و وضعیت دکمه را تغییر دهد. حالت اولیه دکمه، غیرفعال است و پس کلیک بر روی آن دکمه به حالت مرتب نزولی میرود و دیتای جدول براساس آن فیلد به صورت نزولی مرتب میشود. پس از کلیک دوباره دیتای جدول براساس آن فیلد و این بار صعودی مرتب میشود و درنهایت پس از کلیک سوم، دکمه به حالت اولیه رفته و دیتا به همان شکل اولیه مرتب میشود.
هرکدام از حالات دارای یک کلاس html منحصر به فرد است که باید پیاده سازی شود.
براساس هر وضعیت که دکمه دارد یک کلاس منحصر به فرد به آن دکمه داده میشود. توضیح این کلاسها در خود کامپوننت داده شده است.
این کامپوننت دو تابع ناقص دارد که شما باید آنها را تکمیل کنید.
- تابع `changeSelectedSort` : این تابع وظیفه تغییر نحوه مرتب شدن را دارد. وقتی دکمهای کلیک شد، این تابع فراخوانی میشود و بر اساس فیلد مرتبسازی و وضعیت آن دکمه، اطلاعات جدول تغییر میکند.
- تابع `setClassName` : این تابع وظیفه نامگذاری کلاس دکمهها براساس وضعیت آن دکمه را دارد.
**نکات**
+ دکمههای این کامپوننت باید دارای `id` به شکل `sort-btn-FIELD_NAME` باشند، که `FIELD_NAME` از متغیر `fields` در این کامپوننت خوانده میشود.
+ شما باید کلاسهای گفته شده را به کلاسهای اولیه این دکمهها اضافه کنید.
+ مرتبسازی براساس نام *نباید* به حروف کوچک و بزرگ حساس باشد.
</details>
<details class="blue">
<summary>
**۴) کامپوننت `FilterBox.js`**
</summary>
در این کامپوننت ابتدا دیتا را از پوشه `data` بخوانید و سپس براساس متغیر `filters` آنها را نمایش دهید.
برای نمایش این قسمت، لازم است با نحوه عملکرد `Accordion` از کتابخانه `bootstrap` آشنایی داشته باشد.
برای آشنایی با این قسمت میتوانید به [این](https://getbootstrap.com/docs/4.3/components/collapse/#accordion-example) لینک مراجعه کنید.
این کامپوننت یک تابع ناقص دارد که باید آن را تکمیل کنید.
+ تابع `changeFilter` : این تابع وظیفه تغییر نحوه فیلتر شدن را دارد.
توجه کنید که کاربر میتواند چند فیلتر را همزمان انتخاب کند. برای مثل هم گزینه `Spain` از بخش `nationallity` و هم گزینه `FC Barcelona` از بخش `club` را انتخاب کند.
**نکات**
+ دکمه باز بسته کننده `Accordion` باید دارای `id` به شکل `btn-FILTER_NAME-collapse` باشد که `FILTER_NAME` از متغیر `filters` که در این کاپوننت وجود دارد خوانده میشود.
+ شما باید `div`هایی که `id`ای به یکی از سه شکل `collapseOne`, `collapseTwo`, `collapseThree` دارند را به شکل `collapse-FILTER_NAME` در بیاورید و تغییرات لازم را در کامپوننت ایجاد کنید.
+ برای بخش `checkbox`ها باید از `bootstrap` کمک بگیرید و به همان شکلی که در داکیومنت این کتابخانه وجود دارد عمل کنید. برای اطلاعات بیشتر میتواند به [لینک](https://getbootstrap.com/docs/4.3/components/forms/#inline) مراجعه کنید.
+ `checkbox`های این قسمت باید دارای `id` به شکل `FILTER_TYPE-ITEM_NAME` باشند. مانند `nationality-Egypt`
+ برای تغییر `checkbox` از `event` `onChange` استفاده شود.
+ قسمت `nationality` در ابتدای اجرای پروژه *باید* باز باشد و در هر لحظه فقط یک قسمت از `Accordion` *باید* باز است.
</details>
# نکات تکمیلی
- به نحوه نمایش تگها و `attributes` و اطلاعات توضیح داده شده در هر کامپوننت توجه شود.
- مدت زمان `render` شدن کامپوننتها و جدول دارای اهمیت میباشد.
- تعدادی تست نمونه در پروژه اولیه وجود دارد که با استفاده از آنها میتوانید کد خود را تست کنید.
- شما تنها مجاز به اعمال تغییر در فایلهای `containers`، `components` هستید.
- پس از اعمال تغییرات، پروژه را zip کرده و ارسال کنید.دقت کنید که پوشهی `node_modules` در فایل ارسالی نباشد.