در شرکت شبکهی الکترونیکی پرداخت کارت که به اختصار شاپرک نامیده میشود همه کارها به صورت خودکار و با برنامهریزی دقیق کنترل میشوند، کارمندان شاپرک نیاز به یک سیستم قدرتمند برای مدیریت وظایف روزمره خود دارند.
این وظایف میتوانند شامل هر چیزی مثل آبیاری گیاهان، تنظیم دمای شرکت، گرفتن نسخه پشتیبان از دادهها و حتی درست کردن قهوه در زمانی دقیق و مشخص باشند. زمان برای کارمندان این شرکت بسیار مهم است و دقیقترین برنامهریزی لازم است تا کارها در شرکت به خوبی پیش برود. شما، به عنوان برنامهنویسان این شرکت، مأموریت دارید تا یک سیستم زمانبندی وظایف برای همهی کارمندان ایجاد کنید. این سیستم باید قابلیت مدیریت وظایف را از طریق یک رابط کاربری ساده برای کاربران فراهم کند. سیستم باید قابل اطمینان باشد و بتواند وظایف را حتی پس از بارگذاری مجدد صفحه برنامهریزی و اجرا کند.
ظاهر کلی برنامه به شکل زیر است:
![خروجی](https://quera.org/qbox/view/ihnTp1dK4x/D.gif)
# پروژه اولیه
پروژه اولیه را از
[این لینک](/problemset/assignments/4367/download_problem_initial_project/251302/)
دانلود کنید. ساختار فایلهای این پروژه به صورت زیر است.
```
initial-project.zip
├── assets
│ ├── bg.png
│ └── icon.png
├── index.html
├── styles.css
└── <mark class="violet">script.js</mark>
```
# جزئیات
<details class="blue">
<summary>
**توابع مورد نیاز**
</summary>
| تابع | تعریف |
|:------------------:|:------------------:|
| `addTask` | زمانی که کاربر نام وظیفه، تاریخ و ساعت انجام، وابستگی آن به وظیفههای دیگر (در صورت وجود) و مدت زمان اجرای آن به ثانیه را وارد کرد، با کلیک بر روی دکمه `Add Task` یک وظیفه جدید با وضعیت `Scheduled` اضافه میکند. کاربر نمیتواند وظیفهای را در زمان گذشته اضافه کند و در این صورت پیغام `Task start time cannot be in the past.` را دریافت میکند. |
| `appendTaskToList` | این تابع یک `task` را به عنوان ورودی دریافت کرده و آن را به جدول وظایف اضافه میکند. |
| `saveTaskToLocalStorage` | این تابع یک `task` را به عنوان ورودی دریافت کرده و آن را به لیست تسکها در Local Storage اضافه میکند. |
| `loadTasksFromLocalStorage` | این تابع هنگام بارگذاری صفحه فراخوانی میشود و وظایف داخل Local Storage را بازیابی کرده و به جدول اضافه میکند. |
| `updateTaskInDOMAndStorage` | زمانی که وظیفه اضافه شود، وضعیت آن `Scheduled` میباشد. زمان اجرای توابع که فرا رسید، وضعیت آن `Running` میشود و پس از پایان وظیفه، وضعیت آن به `Done` تغییر میکند. این تابع یک `task` را به عنوان ورودی دریافت میکند و وظیفه بهروزرسانی وضعیت وظایف را در لیست و Local Storage برعهده دارد. |
| `showNotification` | این تابع زمانی که یک وظیفه شروع به اجرا میکند و در وضعیت `Running` قرار میگیرد فراخوانی میشود و یک `message` را به عنوان ورودی دریافت میکندو یک pop-up با متن `Task '${task.name}' has started.` و آیکون `icon.png` به مدت ۳ ثانیه به کاربر نمایش داده میشود. همچنین یک `Notification` با همین متن و آیکون برای او ارسال میشود تا اگر کاربر در صفحه نباشد باز هم پیغام را دریافت کند. |
| `removeTask` | این تابع یک `task` و سطر مربوط به آن در جدول را به عنوان ورودی دریافت کرده و آن وظیفه را از جدول و Local Storage حذف میکند. |
</details>
<details class="violet">
<summary>
**توجه**
</summary>
برای شروع اجرای هر وظیفه، لازم است ابتدا وابستگی آن انجام شده باشد و در وضعیت `Done` قرار گرفته باشد. بنابراین اگر زمان شروع یک وظیفه فرا رسید، ولی هنوز وابستگی آن انجام نشده بود، وظیفه هنوز اجازه اجرا ندارد و باید تا زمان تکمیل وابستگی خود صبر کند.
</details>
<details class="green">
<summary>
**راهنمایی**
</summary>
برای دکمه حذف میتوانید از قطعه کد زیر استفاده کنید و سپس آن را به آخرین سلول سطر مورد نظر در جدول اضافه کنید:
```js
const deleteButton = document.createElement('button');
deleteButton.style = 'font-size:16px;background-color:#a83236;background-image:none;color:#fff;cursor:pointer';
deleteButton.textContent = 'Delete';
```
</details>
# خواسته مسئله
در فایل `script.js` توابع مورد نیاز تعریف شده که شما تنها قادر به پیادهسازی توضیحات مسئله در آن هستید.
# نکات
+ برای تعیین زمان انجام وظایف، نیاز به تاریخ و ساعت دقیق دارید. برای اینکار، از یک فیلد ورودی با تایپ `datetime-local` استفاده شده است.
+ هر سطر جدول (`tr`) باید دارای آیدی برابر با نام وظیفه باشد.
+ استایلهای مورد نیاز برای نوتیفیکیشن در انتهای فایل `styles.css` موجود است.
+ در صورت نیاز میتوانید توابع بیشتری به فایل جاوااسکریپت اضافه کنید.
# نحوهی ارسال پاسخ
پس از اعمال تغییرات در `script.js`، فایلهای پروژه را به صورت یک فایل *ZIP* با ساختار زیر ارسال نمایید.
```
[your-zip-file-name].zip
├── assets
│ ├── bg.png
│ └── icon.png
├── index.html
├── styles.css
└── <mark class="violet">script.js</mark>
```