【個人開発】プログラミング学習者向け 学習時間計測・記録アプリを作りました🌿🐨

## はじめに
どうも こんにちは！　ななみんと申します。
未経験からのエンジニア転職に向けて2023年の4月から学習を始めて、1年が経とうとしています。
ここまであっという間でした…。
こうして学習を続けられたのも、同じ目的を持って学習するコミュニティーがあったからだなと思っています。

### そこで！
一緒に学習する仲間を見つけて学習時間を記録、学習時間を達成できるアプリを作りました。

#### 「やる気の森」

**▼URL**
https://www.yaruki-morimori.com/

**▼GitHub**
https://github.com/nanamitoshimasu/studying_mate

想定されるユーザーは以下の通りです。

🙋🏻 プログラミング学習を継続して行いたい方。
🙋🏻 学習時間を確保したい、目標時間を設けて達成させたい方。
🙋🏻 1人だとつい怠けてしまう方。
🙋🏻 プログラミング学習を通して交流を深めたい方。

### もっと楽しんで学習していただきたい！
学習記録アプリを作るにあたって、仲間を作って学習する以外にも楽しく学習できる要素と自分らしい世界観を取り入れたいと思い、
**"学習時間を記録することで絶滅危惧種を救う"**
これにしました。

元々、私は動物や自然が大好きだったので、個人開発するならこういう要素を入れたいと思っておりました。

学習するにあたって、エンジニア学習の記録を図る一つの手段として用いられる`GitHubで草を生やす`という文化があることを知りました。GitHubのコントリビューションが増えると美しい緑が広がります。

「この増えた緑が実際に森林として増えているとしたら森林伐採や温暖化などの気候変動で住む場所を追われてしまった動物たちを救えるんじゃ…」（ここまで一息）（オタク特有の早口）

そういうわけで、
絶滅危惧種に応じて学習目標時間を設け、
学習時間を計測し記録することを「森林を増やす」と表現し、
絶滅危惧種を救うために仲間と協力して学習記録を行うことで、学習習慣を身につけられるように作成しました。


## 機能一覧

### 1. 仲間募集一覧
仲間の募集ステータスをつけて、わかりやすくしました。
・募集期間中で定員数に達成ていない場合は「募集中」
・募集期間中に定員数に達した場合は「満員御礼」
・募集期間を過ぎている場合は「募集期間終了」

[![Image from Gyazo](https://i.gyazo.com/1497517f40f6bfdb5f27d2b007f43e10.jpg)](https://gyazo.com/1497517f40f6bfdb5f27d2b007f43e10)


### 2. 仲間の募集作成
救いたい絶滅危惧種を選択すると自動的に画像と目標時間数が表示されるようになっています。
無理なスケジュールでの人数設定や活動期間にならないように、バリデーションもつけています。

[![Image from Gyazo](https://i.gyazo.com/2fd3023f878b31639a7f588fe86557de.gif)](https://gyazo.com/2fd3023f878b31639a7f588fe86557de)

### 3. 仲間募集詳細、仲間の参加
募集詳細から仲間の参加ができるようになっています。
仲間に参加すると募集ボートの横にメンバーが表示されるようになっています。
募集の作成者は詳細ページから編集や削除もできます。

[![Image from Gyazo](https://i.gyazo.com/1a7e56d620def0ef1d232dd8667e1296.jpg)](https://gyazo.com/1a7e56d620def0ef1d232dd8667e1296)


### 4. 募集検索機能
タイトルや詳細文、動物、募集人数、開始日から検索できるようになっています。

[![Image from Gyazo](https://i.gyazo.com/785fb8b8b5c22e55e72e580e94fa6cc3.gif)](https://gyazo.com/785fb8b8b5c22e55e72e580e94fa6cc3)

### 5. 仲間の共有ページ
活動期間になったらトップページに「森林を増やす」ボタンが表示されます。
仲間の共有ページでは、活動期間・メンバー一覧・チームでの学習記録の表示とチャットができます。

[![Image from Gyazo](https://i.gyazo.com/ac803c2f564b8429d647e4444796dbd8.gif)](https://gyazo.com/ac803c2f564b8429d647e4444796dbd8)


### 6. 学習時間の計測
仲間の共有ページから学習時間の計測ページへ遷移できます。
計測中も目標までの学習時間の進捗の確認やチャットができるように、またタイマーの特性上、リロードや他のページに移動してしまうと計測ができないため、別タブで開くようにしております。

[![Image from Gyazo](https://i.gyazo.com/28c79838a7c3df45ecbb70ba76a247fa.gif)](https://gyazo.com/28c79838a7c3df45ecbb70ba76a247fa)


### 7. 計測一時停止機能
休憩ボタンを用意してより正確に、1日通してどれくらい学習したかを見られるようにしました。
[![Image from Gyazo](https://i.gyazo.com/3d086744fb168e6cbe0d756081fa901b.gif)](https://gyazo.com/3d086744fb168e6cbe0d756081fa901b)

### 8. 計測時間の編集機能
終了ボタンを押し忘れた！という場合に編集して正確な計測時間を記録できます。
[![Image from Gyazo](https://i.gyazo.com/17716fe9bc549b7728dcd83a40a1af14.gif)](https://gyazo.com/17716fe9bc549b7728dcd83a40a1af14)


### 9. マイページ機能
他の方のマイページも見ることができます。
個人の学習時間の確認と目標学習時間を達成できた場合には救った絶滅危惧種一覧に表示されます。
[![Image from Gyazo](https://i.gyazo.com/72420dde193eec67ea65e8ab21946c8d.jpg)](https://gyazo.com/72420dde193eec67ea65e8ab21946c8d)


## 使用技術
|カテゴリ|技術|
|:---:|:---:|
|バックエンド|Ruby on Rails (Rails7.0.8, Ruby 3.2.2)
|フロントエンド|JavaScript（Stimulus)|
|CSSフレームワーク| Tailwind CSS + DaisyUI|
|開発環境|Docker|
|Webアプリケーションサーバ|Heroku|
|ファイルサーバ|AWS S3|
|データベースサーバ|PostgreSQL|

### 選定理由
- バックエンドはプログラミングスクールで学習していた`Ruby on Rails`にすることで学習コストをかけずに開発できると考えたためです
- フロントエンドも`React`ほど学習コストがかからず、`Stimulus`を使えばSPA風に開発できると考えました
- デザインにあまり自信がなかったので、DaisyUIのCSSコンポーネントを使用しました
- 開発環境は`Docker`を本格的に使ったことがなかったのとローカルより早く環境構築できたため`Docker`にしました
- Webアプリケーションサーバは機能や公式ドキュメント、参考記事も充実している`Heroku`を採用することでより開発に集中できると考えたためです


## ER図
[![Image from Gyazo](https://i.gyazo.com/fe205e7efdee3e28e300592addedd8b3.png)](https://gyazo.com/fe205e7efdee3e28e300592addedd8b3)


## こだわったポイント
### 1. ログイン機能
- ログインハードルを下げるために、OAuthのログインにしました。プログラミング学習者用を想定しているのでGitHubでのログインにしました

### 2. 仲間の募集と参加
- 募集人数の定員に達した瞬間、募集ステータスが変更するように`Action Job`を使って即時反映されるようにし、募集中の仲間を探しやすいようにしました
- 絶滅危惧種の選択するとその動物の画像と目標時間の即時反映されることで楽しく選びつつ、どの動物がどのくらいの目標時間なのかがわかるようになっています

### 3 タイマー機能
- メインとなる機能なので、Stimulusを使って非同期通信を行い、正確にカウントアップ表示ができるように設定しました
- 休憩開始・終了ボタンを一つにして、表示を変えるようにすることで、ボタンが増えて使いにくくならないようにしました
- 終了ボタンの押し忘れは必ずあるので編集機能をつけて正確に記録できるようにしました

### 4. モーダル表示
- 学習時間計測終了後や編集後に、計測時間をモーダルで表示させ画面遷移を少なくしました
- 活動期間が終了もしくは学習目標を達成したタイミングで達成結果が表示されるようにしました
[![Image from Gyazo](https://i.gyazo.com/f3a863ce377ddc5566be665115bbc00d.gif)](https://gyazo.com/f3a863ce377ddc5566be665115bbc00d)

### 5. チャット機能
- コミュニケーションを取りやすいようにチャット機能を入れました
- Action Cableを使ってリアルタイムで反映されるようにしました
- ユーザー自身は右側、他のユーザーは左側に表示されるように設定しました


## 改善したいポイント、追加実装
#### レスポンシブ対応
- スマートフォンでもストレスなく使用できるようにしたいです
#### タイマー機能部分のUI
- 別タブになってしまうのでタブを閉じる手間がかかってしまっていることや計測結果モーダル表示後の画面遷移が少しややこしいのでもう少し改善したいです
#### ユーザーステータス表示
- チームのメンバーが活動中かどうかわかるようにリアルタイムでユーザーステータスを表示させたいです
#### テスト
- テストコードが書けていないので練習も兼ねて書いていきたいです


## おわりに
ここまで読んでいただきありがとうございました。
0からの実装で大変なことや分からないことばかりでしたが、なんとか形になって嬉しいです。
開発にあたって、講師の方や同期、他の期の方も本当にたくさんの方のおかげでなんとかリリースできました。
本当にありがとうございました🙇🏻
今後も改善していきながら学習を続けていきます。