2025.01.05
今年の目標、成し遂げることをサポートします
はじめに
2024年末の忘年会で「来年こそはなにかを成し遂げたい」という話題が出ました。 「今年こそ何かを成し遂げたい」という思いを持つ方のために、その目標達成をサポートするアプリを作りました。
今回作ったもの
「なにかを成し遂げたい」という人が記録をつけ、年末にみんなに発表できるアプリを作りました。
まずはGoogleアカウントでログインします。 ログイン後はこのような画面になります。成し遂げたいことを書き込んでいきましょう。
設定した目標は12月28日から1月3日の間のみ編集可能です。元旦に立てた目標を守りましょう。
次に、目標に対する進捗を記録できます。進捗は画面右下の「+」ボタンから追加し、投稿フォームはボトムシート形式で表示されます。
記録した進捗はスレッド形式で表示され、いつでも振り返ることができます。
達成率も記録し、年末にはグラフで振り返ることができる設計です。
モチベーション
忘年会で次のような会話がありました。
H「最近なにも成し遂げてないな〜」
U「2025年はなにかを成し遂げたいよね」
H「けどなにを成し遂げるかは来年末まで言いたくないわ」
M「先に宣言しておかないと、1年間の途中で目標を下方修正してしまいそう」
U「来年末になったら、お互いがどんな感じで目標に向かって1年間取り組んできたかを見返したい」
M「じゃあ元旦にしか編集できないメモアプリを作って、時期が来たらお互いに公開できるようにしたらどう?」
ということで忘年会で酔った勢いでアプリを作りました。
今回のアプリ開発のゴールは、次のことを満たすことでした。
- 1年間かけてなにかを成し遂げたい。そのための記録をつけたい
- 何を成し遂げるかは言いたくないが、途中で目標を変えていないことを保証したい
- 目標に向かい続けるモチベーションを維持したい
- 途中で達成率を記録したい
- 年末に公開して、みんなで振り返りたい
制作期間
今回は元旦にリリースしたかったため、本業を納めてから2日で突貫で作りました。デザインや機能はある程度イメージができていたため、すぐに実装に取りかかれました。過去のコード資産を活用することで、素早く作るができました。
ある程度実装が進んだ段階で数人に触ってもらい、フィードバックを受けながらブラッシュアップしていきました。
技術構成
リリース目標日が決まっていたため、スピードを最優先し、慣れている技術を使いながらランニングコストを抑えられる構成にしました。検討の結果、Next.js + Firebase + Vercelという組み合わせに決定しました。
Next.js
これまで何度も使用しており、再利用できるコード資産が豊富にあったため、フロントエンドフレームワークにはNext.jsを採用しました。これにより、開発スピードを大きく向上させることができました。
Firebase
スレッド形式で投稿していく仕様のため、小さなデータが大量に作成されることを想定しました。複雑なリレーションが不要なことから、Firestoreで無理なく設計できると判断しました。Firestoreは無料枠があり、従量課金になってもサービスの性質上、インフラコストはそれほどかからないと見込んでいます。
また、Firebase AuthenticationとCloud Storage for Firebaseも利用し、Firebaseのエコシステムを最大限活用しました。
Vercel
Next.jsのデプロイしやすさからVercelを選択しました。ホビープランを利用しており、無料で運用しています。
Mantine
コンポーネントライブラリにはMantineを採用しています。過去にMantineを使ってフォームをたくさん作ってきたため、こちらも再利用できるコードの資産がたくさんあり、開発スピードを上げることができました。
実装で工夫したこと
環境構築
昨年作成したテンプレートリポジトリを使用したため、環境構築はスキップできました。 詳しくはこちらのブログで紹介しています。
Firebaseを使ったモノレポ構成のテンプレートリポジトリを作りました
スレッドのUI
身内向けのアプリであるため、デザインにはあまりこだわらず、コンポーネントライブラリが提供するパーツを組み合わせてUIを構築しました。進捗はスレッド形式で表示したかったため、MantineのTimelineコンポーネントを使用しました。
目標ごとにスレッドが作成される仕組みとなっており、目標はサイドバーに収納されます。このUIはChatGPTのスレッドUIを参考にしています。PC版ではサイドバーが常に表示され、スマートフォン版ではハンバーガーメニューをタップすることでサイドバーが展開される仕様です。
EmptyのUI
Empty画面とは – ユーザーがまだデータを作成していない場合や、特定の条件で表示されるコンテンツが存在しない場合に表示される画面です。
たとえば、目標が未設定の場合や、進捗が一件も記録されていない際に表示されます。Empty画面は「何もない」という状態を視覚的にわかりやすく示しつつ、次のアクションを促す役割を果たします。 今回のアプリでは、目標設定ページや進捗記録ページにEmpty画面を設け、「目標を設定しましょう」「最初の進捗を記録しましょう」といったガイドメッセージを表示することで、ユーザーが自然と操作を進めたくなるようデザインしました。
Empty画面は、ユーザー体験を向上させるための重要な要素です。画面が「空」であっても単なる無機質な表示ではなく、次のアクションにつながるUIを意識しました。 Empty画面のデザインはこちらを参考にしています。
画像のトリミング
画像のトリミングとアップロード機能は、過去に作成したものを流用しました。過去の個人開発で紹介していますが、再利用できる形で実装しておいたことが役立ちました。
Reactでアップロードした画像を切り取る:コンポーネントとカスタムフックの実装ガイド - Zenn
認証
毎日使うアプリではないため、メールアドレスとパスワードによる認証では、使用したメールアドレスやパスワードを忘れてしまう可能性があります。そこで、Googleアカウントでのログインを採用しました。Firebase AuthenticationのGoogle Providerをそのまま使用しています。
さいごに
掲げた目標を1年間ぶらさずに成し遂げたい──そんな熱い想いをサポートするアプリを作ることができました。
今後の開発としては、年末までに次の2つの機能をリリースする予定です。まだまだ余裕があります。
- 目標と進捗の公開機能
- 進捗率をグラフで表示する機能
何か成し遂げたいことがある方は、ぜひ使ってみてください。