配列でWBS風Todoアプリ作ってみた

こんにちは。やらなければいけない事をTodoリストにまとめているけれどいつも期限を忘れてしまうマンです。今回はWBS風Todoアプリを作ってみました。

#使用した技術
・Windows10(PC)
・TypeScript
・HTML/CSS
・Vue3
・<a href="https://getbootstrap.jp/">Bootstrap5</a>

#画面
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2365717/ba3ec6f8-9cc6-db12-751e-4786250127b5.png)

項目名にやりたい事／開始日／終了日を入れて追加ボタン押すとお花が咲きます。
これでやらなきゃいけない事の期限が分かります。

#コードで説明
まずは予定の始めの日付と終わりの日付を取得
→start/endに代入します。

```typescript
const addTodo = () => {
      //空欄だったらエラー
      if (todo.value === "") {
        error.value = "予定を入力して下さい";
        return;
      }
      //お花入れる用配列
      const array = new Array<string>();
      //エラーを初期化
      error.value = "";

      //予定の始めの月(入力してもらった日付)
      let start = new Date(startDate.value).getDate() - 1;
      //予定の終わりの月(入力してもらった日付)
      let end = new Date(endDate.value).getDate() - 1;

      //始めの日よりも終わりの日が前だったらエラー
      if (
        new Date(startDate.value) > new Date(endDate.value) ||
        todo.value === ""
      ) {
        error.value = "予定の始めは終わりよりも前に設定して下さい";
        return;
      }
```
その後に色々な入力パターンを想定して、if文を書きます。

(1)予定が今月に被っていない
　　→今は1か月分しか表示されていないので、花は全くつきません。その場合startに-1を入れておきます。

```typescript
      //今月に予定が被っていなければ空白をpush
      //始めが先月より前&&終わりが今よりも前 || 始めが先月より後&&終わりが今よりも後
      if (
        (new Date(startDate.value) > new Date() &&
          new Date(endDate.value) > new Date()) ||
        (new Date(startDate.value) < new Date() &&
          new Date(endDate.value) < new Date())
      ) {
        if (
          (new Date(startDate.value).getMonth() != new Date().getMonth() ||
            new Date(startDate.value).getFullYear() !=
              new Date().getFullYear()) &&
          (new Date(endDate.value).getMonth() != new Date().getMonth() ||
            new Date(endDate.value).getFullYear() != new Date().getFullYear())
        ) {
          start = -1;
          array.push(" ");
        }
      }
```

(2)入力した終わりの日が来月以降→月末まで塗りつぶされるのでendに月末を代入
※nowEndDateには月末の日付が入ってます。

```typescript
      //入力した終わりの日が来月以降の場合、月末まで塗つぶす
      if (new Date(endDate.value) > new Date()) {
        if (
          new Date(endDate.value).getMonth() != new Date().getMonth() ||
          new Date(endDate.value).getFullYear() != new Date().getFullYear()
        ) {
          end = nowEndDate - 1;
        }
      }
```

(3)入力した始めの日が先月以前→1日から塗りつぶされるのでstartに1を代入

```typescript
      //入力した始めの日が先月以前の場合、月初から塗つぶす
      if (new Date(startDate.value) < new Date()) {
        if (
          new Date(startDate.value).getMonth() != new Date().getMonth() ||
          new Date(startDate.value).getFullYear() != new Date().getFullYear()
        ) {
          start = 0;
        }
      }
```

やっと準備が整いました。
start/endの数字を使って、配列に適切な数のお花を入れていきます。

```typescript
      //-1の際と日付がnullの場合は塗つぶす必要なし
      if (start != -1 && startDate.value != "" && endDate.value != "") {
        for (let i = start; i <= end; i++) {
          array[i] = "❁";
        }
        for (let i = end + 1; i <= nowEndDate; i++) {
          array.push(" ");
        }
      } else {
        for (let i = 0; i <= nowEndDate; i++) {
          array.push(" ");
        }
      }
      //予定用の配列に名前とお花の配列を入れる
      gantArray.value.push({ name: todo.value, hana: array });

      //要素を空にする
      todo.value = "";
      finishList.value.splice(0, finishList.value.length);
      startDate.value = "";
      endDate.value = "";
    };
```

配列を回す際、始まりにstart/終わりにendを入れて回したので入れたい箱番号(添え字)のところにお花が入ってくれました。もし日付を入れていなかったら、特に日付指定がないという事で空欄をpushしています。


#まとめ
最初はTodoリストを作ろうとしたのですが、すこし面白いものが作りたいなと思い特殊なタイプを作成してみました。配列は色々な使い方があって奥深いですね…

ここまでご覧いただきありがとうございました。