مهدی بچه سربههوایی است. او همیشه کارهایی را که میخواهد انجام دهد فراموش میکند؛
به همین دلیل تا به حال با مشکلات زیادی روبهرو شده است، و نمیداند **حالا چه کار کند**.
مصطفی که پسری است مهربان، قصد دارد برای مهدی یک برنامه درست کند
تا او بتواند کارهای خود را با آن مدیریت کند.
مصطفی پس از کمی تحقیق تصمیم گرفت از کتابخانهی `ReactJS` برای انجام این پروژه استفاده کند؛
اما او پس از انجام بخش اعظمی از پروژه، متوجه شد که نمیتواند به تنهایی آن را به اتمام برساند،
و سه قسمت از پروژه هنوز باقی ماندهاند.
با تکمیل این سه بخش مصطفی را در انجام این کار خیر یاری دهید.
هدف نهایی پروژه در زیر به تصویر کشیده شده است.
با وارد کردن نام هر کار، و انتخاب اولویت بالا یا پایین، میتوان آن را به برنامه اضافه کرد.
با کلیک روی هر کار وضعیت انجام شدن آن تغییر میکند.
مصطفی بخش مربوط به فیلتر کارهای انجامشده را پیادهسازی کرده است؛
بنابراین این قسمت جزو موارد پیادهسازی شما نیست.
![توضیح تصویر](https://quera.ir/qbox/view/Up3Jt7ETAG/todo.gif)
# پروژه اولیه
پروژه اولیه را از
[اینجا](https://quera.ir/qbox/download/bAFZXAGiT7/todo-app.zip)
دانلود کنید.
ساختار فایلهای این پروژه به صورت زیر است.
مواردی که نیاز به تغییر دارند با `*` مشخص شدهاند.
```
todo-app
├── public
│ ├── favicon.ico
│ └── index.html
├── src
│ ├── components
│ │ ├── AddTodo.js
│ │ ├── App.js
│ │ ├── FilterTodo.js
│ │ ├── TodoItem.js *
│ │ ├── TodoList.js
│ │ └── TodoTable.js *
│ └── index.js
├── package.json
└── pnpm-lock.yaml
```
# راهاندازی پروژه
**برای اجرای پروژه، باید `NodeJS` و `npm` (یا `pnpm`) را از قبل نصب کرده باشید.**
- در پوشهی `todo-app` ، دستور `npm install` را برای نصب نیازمندیها اجرا کنید.
- **نکته:** برای نصب سریعتر از `pnpm install` استفاده کنید.
- در همین پوشه، دستور `npm start` را برای راهاندازی پروژه اجرا کنید.
- با مراجعه به `http://localhost:3000/` میتوانید نتیجه را ببینید.
# جزئیات
همانطور که مشاهده میکنید در این پروژه شش `Component` موجود است.
ابتدا آنها را مطالعه کنید تا با نحوهی کارکرد پروژه آشنا شوید.
شما باید دو فایل زیر را طبق توضیحات تکمیل کنید.
+ `TodoTable.js`: در این فایل دو تابع ناقص وجود دارد. تنها این دو تابع را تکمیل کنید.
+ تابع `addTodo(name, priority)`
: این تابع با دریافت نام و اولویت هر کار، آن را به لیست وظایف، یعنی `state.todoList` اضافه میکند.
هر عضو این لیست ساختار زیر را دارد (از چپ به راست نام، اولویت، حالت، و شناسه):
```
{name: string, priority: string, done: bool, id: string}
```
توجه کنید که
+ حالت یک کار ابتدا `false` است.
+ برای ساختن شناسه میتوانید از کتابخانهی `uuid` که در اختیار شما قرار داده شده است استفاده کنید.
+ لیست وظایف، یعنی `state.todoList` ، باید همواره بر اساس *اولویت* کارها
و در صورت برابری اولویت، به ترتیب *نام* کارها و به صورت *الفبایی* مرتب شده باشد
(پس از اضافه کردن هر کار این لیست مجددا مرتب شود).
بزرگ یا کوچک بودن حروف در مرتب کردن نامها تاثیری ندارد.
همچنین بدیهی است که کارهایی با اولویت `high` در لیست بالاتر از بقیهی کارها قرار میگیرند.
+ تابع `toggleDone(id)`: این تابع با دریافت شناسهی یک کار،
حالت آن را تغییر میدهد؛ اگر `false` باشد آن را `true` میکند و برعکس.
در زیر نمونهای از اجرای این دو تابع و تاثیر آنها در لیست مشاهده میشود.
```
>>>this.state.addTodo('buy milk', 'low')
>>>this.state.todoList --> [{name:"buy milk", priority:"low", done:false, id:"8803af5c-13a7-4692-9cbe-5a0467a5d053"}]
>>>this.state.addTodo('meet Mahdi', 'high')
>>>this.state.todoList --> [{name:"meet Mahdi", priority:"high", done:false, id:"d976e58d-2067-4e9a-81cf-3844d51cac83"}, {name:"buy milk", priority:"low", done:false, id:"8803af5c-13a7-4692-9cbe-5a0467a5d053"}]
>>>this.toggleDone("8803af5c-13a7-4692-9cbe-5a0467a5d053")
>>>this.state.todoList --> [{name:"meet Mahdi", priority:"high", done:false, id:"d976e58d-2067-4e9a-81cf-3844d51cac83"}, {name:"buy milk", priority:"low", done:true, id:"8803af5c-13a7-4692-9cbe-5a0467a5d053"}]
```
+ `TodoItem.js`: این فایل را به نحوی تکمیل کنید که
+ نام، اولویت، و حالت هر کار به ترتیب در تگهای `.name` ، `.priority` ، و `.status` نشان داده شوند.
توجه کنید که حالت یک کار در صورت `true` بودن با عبارت `Done` نشان داده میشود،
و در صورت `false` بودن خالی است.
برای مثال پس از فراخوانی تابعها به ترتیب نمونهی قسمت قبل، باید لیست به صورت زیر نمایش داده شود:
```
meet Mahdi
buy milk Done
```
+ با کلیک بر روی هر `.todo-item` باید حالت کار داخل آن تغییر کند.
# نکات
+ شما تنها مجاز به اعمال تغییر در فایل های `TodoItem.js` و `TodoTable.js` هستید.
+ پس از اعمال تغییرات، پروژه را _zip_ کرده و ارسال کنید. دقت کنید که پوشه `node_modules` در فایل ارسالی نباشد.