【個人開発】1日の集中時間を可視化するポモドーロタイマーアプリを作りました！【React/TypeScript/Jotai】

# はじめに
今回はReactの学習とアウトプットのため、<font color="red">**「ポモドーロアプリ」**</font>を個人で開発してみました。自分で何を作ろうかと迷っている時間が長く、どちらかというと実際に困っている人の意見を聞いて、その人のために作る気持ちで作ってみました。開発規模としては目安として1ヶ月程度で終わるように考えていたので、そこまで複雑にならないようにっていうように考えていたのですが、当初考えていたMVPよりも作業量が多く、機能面も充実しないといけなかったというのでなんだかんだで複雑っぽくなってしまいました。またReactをメインでアウトプットをしたいという思いからUIは少し手抜きです。

# 開発理由
冒頭でも挙げたように、最初は自分が困っていることがそんなにない事からアイデア出しで難航しておりました。なので、直接ヒアリングした方が早い！という気持ちからフリーランスのコミュニティ内で困っていることなどをまとめてみたのがきっかけで自分の中でアイデアが決まりました。

実際に困っていたことは下記になります。
- 簡単なwebサイト制作を学習していても、モチベーションが上がらない
- 自分の1日の時間は何に使っているのか把握できていない
- 1日のルーティンはどうしたらいいかわからない

主に多かったのはこの三つでした。
コミュニティ内では**ポモドーロ**をやる機会が多かったのもあり、
「営業」
「作業」
「勉強」
と言ったようにカテゴリに分けて自分の1日の作業時間を測ることができれば、
自分に今足りていないものや、自分が今無駄に使ってしまっている時間がわかりやすいのかなと思ったので、
今回のアプリを制作することになりました。


# 技術スタック
あまり悩みたくなかったので下記のようなシンプルにしました。
```
- フロントエンド
　React + TypeScript + SCSS Modules + react-circular-progressbar + React Router
 
- タイマー管理
  react-timer-hook

- 状態管理ライブラリ
　Jotai
 
- バックエンド / DB
　Supabase（タスクの記録 & 分析データ保存）
 
- 認証
　Supabase Auth（Googleログイン）~~　標準のログイン

- テスト
　testing-library
  Jest
```

# メインの機能一覧

### ログイン画面


![スクリーンショット 2025-03-15 16.02.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3889366/57461847-5341-46a7-b212-cd92efe49ee8.png)

基本的にはsupabase authだったのですが一旦、メールアドレスなどの入力でどこまで行けるのか判断したかったため、google認証は一旦やめました。

![ook03-3xsbm.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3889366/09455e86-fd9c-4bee-a7c7-9823e8a0891e.gif)

新規登録する際はこんな感じです

### タイマー
UIはこんな感じ
ちょっと手抜き感があるので、今後詰めておきたいところですね、、、
![スクリーンショット 2025-03-15 16.17.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3889366/83e2e0ec-d34a-4c34-ad12-7bc741b7a9de.png)




結構手間取ったのが、作業終了後にすぐに休憩に入る機能を作った時でした

### 目標画面
目標値を決めたり、一覧として出す画面です
基本的には1週間の達成したい目標時間を記入するようにしています

![スクリーンショット 2025-03-15 16.23.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3889366/ff7844b1-1b9c-4180-b9f8-e59870d219a0.png)

記入する時はこんな感じです
![画面収録-2025-03-15-21.03.01.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3889366/4c63c415-5db3-460d-b22c-cf683e47f131.gif)


### レビュー画面
100%を超えていたら達成済みという機能を作っています



![tmw39-6hney.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3889366/0af79312-f6ea-4f7e-88e3-fa7b04f6069a.gif)




# databaseのテーブルについて
あまり難しく考えず作ってみたところ、かなり難航した覚えがあります。まずはuser全体としてそれぞれの値を確保する中間のテーブルです
※ログインとしての機能はsupabase authでやっているため、あくまで紐付けするためのテーブルになります

**usersテーブル**
| カラム名      | 型      | 説明                          |
|--------------|--------|-----------------------------|
| id          | string | UUID, 主キー                |
| name        | string | 文字列, ユーザー名           |
| created_at  | string | タイムスタンプ, アカウント作成日 |
| user_id     | string | ユーザーと紐づけるためのテーブル |
| record_id   | string | レコードテーブル            |
| goals_id    | string | ゴールテーブル              |

**goalsテーブル**
| カラム名             | 型      | 説明                                      |
|----------------------|--------|------------------------------------------|
| id                  | string |          |
| target_records_hours      | string |                                          |
| target_sales_hours  | string |                                          |
| target_works_hours  | string |                                          |
| current_by          | string ⇒ uuid |                                    |


**recordテーブル**

| カラム名             | 型      | 説明                                      |
|----------------------|--------|------------------------------------------|
| id                  | string |          |
| data      | string |                  json型                        |
| current_by          | string ⇒ uuid |                                    |


削除したり追加したりしてこのような構成になったと思います。

# 工夫したところと大変だったところや反省点

今回のアプリを作った上で工夫したところと大変だったところを書いていきます。

### 工夫したところ
- `database`の紐付けにおいて、意識したことは1ユーザー1レコードというところです。
そのまま書いていると容量が圧迫するなと思い、貯めていきそうなものは全てjsonにてまとめました。
- ディレクトリ構成について`Atomic Design`をそのまま採用するのではなく、その概念だけを取り入れました。元々`App router`の`Next.js`での開発経験があったため、そのまま使用することに違和感があり、どちらかというと概念だけ取り入れ、ちゃんと意識することによってコンポーネント分けの際にあまり迷わなくなりました。
- RLSを使ってセキュリティ設定をしました。あまりこう言ったものに触れてこなかったのですが触ることにより、なんで**やらないといけないのか**を掘り下げることができたため、新しく知識として取り入れることができたのかなと思います。
- タイマーの作成時に、なるべく無駄なレンダリングをしないようにしました。不要なレンダリングのせいでバグが何回か発生していたりして、どこでレンダリングが起こるのかなどを調べるために1つずつ`console.log`でみて、どこで不要なレンダリングが行われているかを調査して、できる限りレンダリングを抑えました。

### 大変だったところや反省点
- もっと設計をちゃんとやるべきだった
MVPに逸れたことをやっていたり、余計なものがあってできなかったので、もっとDBの設計だったり、事前情報としてタイマーには何が必要なのかなどの情報をまとめるべきだったなと思いました。
- UIの知識について
機能に集中するが故にUIを疎かにしていたなと感じています。情報収集もそうですが、ある程度のワイヤーフレームはないといけないと感じました。
- `scss module`での開発よりも`tailwind`などのモダンな技術を使うべきだった
中盤で思ったのが、scssだと面倒だなと思う箇所が多く、何度も切り替えようと思いました。`chakra-ui`と`scss`で迷ったところ、できる限りデザインに柔軟性があるscssを選びましたが、デザインが決まっていない状態だと`tailwind`や`chakra-ui`を選んだ方がいいのかなと思います。

# 今後の改修について
### UIをしっかりと作り込む
サイトマップはこのままにして一旦デザインをfigmaなどで組み直す予定です。実際にデザイナーさんなどに相談して指摘を頂きながら改修していきたいと思います。

### ユーザー設定画面の作成
主にパスワードのリセット機能であったり、ニックネームの変更や、ユーザーアイコンの追加などが行えるようにしたいなと思います。

### レビュー画面の改修
今は達成率しか見れませんが、当初の予定だと過去のデータの表示やグラフ化などを考えていました。また、1週間を想定していますが、1週間ごとにjsonが消えてしまうので、jsonにもそれぞれのデータに、`created_at`などを持たせて時間を記入してそこの時間から計算するようんして行きたいなと思います。

### タイマー機能の充実
カテゴリは現在絞られていますが、1日の作業時間以外にも計りたい人のために、自分でカスタマイズできるようにしておきたいなと思います。基本的にカテゴリと時間は全てjsonとして保存されるため、あまり大きな改修ではありませんが、やって行きます。

# 統括して
Reactを学習し始めて本格的にアプリを完成させることができたのは初めてでした。
完成させた達成感もありますが、作業着手前に多くの不安があった事から、自分がここまでできるようになったんだということにびっくりしています。こういった達成感や自分の成長は<font color="red">**動画だけを見て手を動かす学習では絶対に得られないものだと思います。**</font>この経験を活かして今後も**アウトプット**を中心とした学習を進めて行きたいと思います。


# JISOUのメンバー募集中！
プログラミングコーチングJISOUでは、新たなメンバーを募集しています。
日本一のアウトプットコミュニティでキャリアアップしませんか？
興味のある方は、ぜひホームページをのぞいてみてください！
▼▼▼

https://projisou.jp