0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

[プロジェクト] バイブコーディングで1日でMVP完成 - HabitFlow 開発記 (1編)

0
Last updated at Posted at 2026-02-18

現場とコードの間 - 7ngenious
2025.02.11

🚀 スタート:午前9時、Claudeと一緒に

2025年2月11日朝。

「習慣トラッカーを作ってみよう」という考えでClaude AIを起動した。Spring Bootを勉強しているが、フロントエンドを先に完成することにした。

最初の会話

私:「毎月毎週習慣を表で構成して、デイリーでチェックしながら
    進捗度をグラフで見られるプログラムを作りたいです
    写真のような感じです」
    [スクリーンショット添付]

Claude:「良いプロジェクトアイデアですね!
        あなたのSpring Boot学習ともよく合うし、
        ポートフォリオとしても活用しやすいと思います。」

そしてすぐに質問が飛んできた。


🎯 戦略樹立:「速く、実用的に」

Claudeの質問

  1. 技術スタック:フルスタック?フロントのみ?バックエンドのみ?
  2. 必須機能:本当に必要なものだけ?
  3. 開発期間:いつまでに?

私の答え

✅ Reactのみ(LocalStorage、1週間完成)
✅ 必須機能のみ:
   - 習慣追加/削除
   - 日別チェック
   - 月別カレンダービュー
   - 進捗度グラフ
✅ 今すぐ開始!

決定理由:

  • バックエンドなしで速いプロトタイピング
  • LocalStorageでデータ永続化
  • 後でSpring Boot連動予定

📐 設計:始める前に構造から

システムアーキテクチャ

┌─────────────────────────────────┐
│   React SPA (Port 3000)         │
│   - React Router                │
│   - Axios (後でAPI用)           │
│   - Recharts (チャート)         │
│   - date-fns (日付処理)        │
└─────────────────────────────────┘
           ↕
┌─────────────────────────────────┐
│   LocalStorage                  │
│   - habits (習慣リスト)         │
│   - habitChecks (チェック記録)  │
└─────────────────────────────────┘

データ構造設計

習慣データ

{
  id: "1675840000000",
  name: "朝の運動",
  icon: "🏃",
  color: "#22C55E",
  createdAt: "2025-02-10"
}

チェックデータ

{
  "1675840000000": {
    "2025-02-10": true,
    "2025-02-11": false,
    "2025-02-12": true
  }
}

なぜこうするか?

  • シンプル:複雑な関係なしで直感的
  • 速い:LocalStorage読み書き速い
  • 拡張可能:後でBackendに簡単に転換

💻 開発:コンポーネント一つずつ

1段階:プロジェクト生成(5分)

# ViteでReactプロジェクト生成
npm create vite@latest habitflow-mvp -- --template react
cd habitflow-mvp
npm install

# 必須ライブラリインストール
npm install recharts date-fns react-icons

なぜVite?

  • 速いHMR(Hot Module Replacement)
  • Create React Appより軽くて速い
  • 最新のフロントエンド標準

2段階:Custom Hook - useLocalStorage(15分)

核心アイデア:LocalStorageをReact Stateのように使用

// src/hooks/useLocalStorage.js
export function useLocalStorage(key, initialValue) {
  // 初期値:LocalStorageから読み込み
  const [storedValue, setStoredValue] = useState(() => {
    try {
      const item = window.localStorage.getItem(key);
      return item ? JSON.parse(item) : initialValue;
    } catch (error) {
      console.error(`Error loading ${key}:`, error);
      return initialValue;
    }
  });

  // 値が変更されるたびにLocalStorageに保存
  useEffect(() => {
    try {
      window.localStorage.setItem(key, JSON.stringify(storedValue));
    } catch (error) {
      console.error(`Error saving ${key}:`, error);
    }
  }, [key, storedValue]);

  return [storedValue, setStoredValue];
}

学んだこと:

  • Custom Hookの力:ロジック再利用
  • useStateのlazy initialization
  • useEffectの依存配列

3段階:日付ユーティリティ(30分)

一番難しかった部分!

月別カレンダーを描くためには:

  1. 該当月のすべての日付生成
  2. 最初の週の空白計算(日曜日が開始日でなければ)
  3. 週次計算
// src/utils/dateUtils.js
export function getCalendarDays(year, month) {
  const firstDay = startOfMonth(new Date(year, month - 1));
  const lastDay = endOfMonth(new Date(year, month - 1));
  
  // 最初の週の空白(日曜日 = 0)
  const startPadding = getDay(firstDay);
  const emptyStart = Array(startPadding).fill(null);
  
  // 実際の日付
  const days = eachDayOfInterval({ start: firstDay, end: lastDay });
  
  return [...emptyStart, ...days];
}

date-fnsライブラリのおかげではるかに簡単だった。


4段階:習慣管理コンポーネント(1時間)

HabitList.jsx:習慣追加/削除/表示

// 習慣追加
const handleAddHabit = (habit) => {
  setHabits([...habits, {
    ...habit,
    id: Date.now().toString(),
    createdAt: new Date().toISOString()
  }]);
};

// 習慣削除
const handleDeleteHabit = (habitId) => {
  if (window.confirm('本当にこの習慣を削除しますか?')) {
    setHabits(habits.filter(h => h.id !== habitId));
  }
};

UI特徴:

  • アイコン選択器(10個プリセット)
  • 色選択器(6個プリセット)
  • カード形態できれいに

5段階:日別チェック画面(45分)

DailyCheck.jsx:今日の習慣チェックリスト

// 今日の達成率計算
const completedCount = habits.filter(habit => 
  checks[habit.id]?.[today] === true
).length;

const completionRate = habits.length > 0 
  ? Math.round((completedCount / habits.length) * 100) 
  : 0;

UIポイント:

  • リアルタイム達成率表示
  • 進捗度バーアニメーション
  • 全体完了時お祝いメッセージ 🎉

6段階:月別カレンダー(1.5時間)

MonthCalendar.jsx:最も核心機能!

// 7x5グリッドレンダリング
<div className="calendar-grid">
  {calendarDays.map((day, index) => {
    if (!day) {
      return <div key={`empty-${index}`} className="calendar-day empty" />;
    }

    const dateStr = formatDate(day);
    const completionRate = getCompletionRate(day);

    return (
      <div key={dateStr} className="calendar-day">
        <div className="day-header">
          <span>{format(day, 'd')}</span>
          <span>{completionRate}%</span>
        </div>
        <div className="day-habits">
          {habits.map(habit => (
            <HabitCheckbox
              key={habit.id}
              habit={habit}
              date={dateStr}
              isChecked={checks[habit.id]?.[dateStr]}
              onToggle={() => onToggleCheck(habit.id, dateStr)}
            />
          ))}
        </div>
      </div>
    );
  })}
</div>

一番やりがいのあった瞬間:

  • カレンダーが正しくレンダリングされた時!
  • クリックするとチェックがすぐできること!

7段階:統計チャート(1時間)

ProgressChart.jsx:Rechartsでデータ可視化

// 最近30日データ生成
const dailyData = useMemo(() => {
  const data = [];
  const today = new Date();

  for (let i = 29; i >= 0; i--) {
    const date = subDays(today, i);
    const dateStr = formatDate(date);
    
    const completedCount = habits.filter(habit => 
      checks[habit.id]?.[dateStr] === true
    ).length;
    
    const rate = habits.length > 0 
      ? Math.round((completedCount / habits.length) * 100) 
      : 0;

    data.push({
      date: format(date, 'M/d'),
      達成率: rate
    });
  }

  return data;
}, [habits, checks]);

Recharts使用法:

  • ResponsiveContainer:レスポンシブ処理
  • LineChart:トレンド見る
  • BarChart:週間比較

🎨 スタイリング:CSSできれいに

デザイン原則

  1. 簡潔さ:不要な装飾なしで
  2. 直感性:見た瞬間理解可能
  3. レスポンシブ:モバイルも快適に

主要技術

/* CSS変数で一貫性 */
:root {
  --primary-color: #3b82f6;
  --success-color: #10b981;
  --gray-50: #f9fafb;
}

/* Gridレイアウト */
.calendar-grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 8px;
}

/* レスポンシブ */
@media (max-width: 768px) {
  .habits-grid {
    grid-template-columns: 1fr;
  }
}

⏰ タイムライン:実際どれくらいかかった?

09:00 - プロジェクト開始(Claudeと会話)
09:30 - Viteプロジェクト生成 & ライブラリインストール
10:00 - useLocalStorage Hook実装
11:00 - 日付ユーティリティ関数作成
12:00 - 昼食 🍱
13:00 - HabitListコンポーネント
14:00 - DailyCheckコンポーネント
15:00 - 休憩 ☕
15:30 - MonthCalendarコンポーネント(一番時間かかる)
17:00 - ProgressChartコンポーネント
18:00 - スタイリング & バグ修正
19:00 - Git初期化 & GitHub push
19:30 - Vercelデプロイ
20:00 - 完成! 🎉

総開発時間:約10時間(休憩含む)


📸 完成画面

Today画面:
ScreenExample_3.png
カレンダー画面:
ScreenExample_2.png
通計画面:
ScreenExample_1.png


💡 「バイブコーディング」とは?

AIペアプログラミング

従来の開発:

問題 → Google → Stack Overflow → コピペ → デバッグ → 繰り返し

バイブコーディング:

問題 → Claudeに質問 → コード生成 → 理解 → カスタマイズ → 完成

Claudeの役割

  • 🧠 設計者:プロジェクト構造提案
  • 💻 コーダー:ボイラープレートコード生成
  • 📚 先生:知らない概念説明
  • 🐛 デバッガー:エラー解決支援

私の役割

  • 🎯 企画者:何を作るか決定
  • 🎨 デザイナー:UI/UX方向設定
  • テスター:実際使用して検証
  • 🔧 統合者:すべての部分組み合わせ

📚 学んだこと

React実践経験

  • ✅ Custom Hook設計(useLocalStorage)
  • ✅ useMemoで性能最適化
  • ✅ コンポーネント分離と再利用
  • ✅ Props drillingなしで効率的なデータ伝達
  • ✅ 状態管理

日付処理の難しさ

  • ✅ date-fnsライブラリ活用
  • ✅ Timezone問題(LocalDate使用)
  • ✅ 週次計算ロジック
  • ✅ カレンダーグリッド生成

データ可視化

  • ✅ Rechartsライブラリ
  • ✅ レスポンシブチャート
  • ✅ データ加工及び変換

LocalStorage活用

  • ✅ JSON直列化/逆直列化
  • ✅ 状態永続化
  • ✅ ブラウザストレージ限界理解

開発プロセス

  • ✅ 速いプロトタイピング:1週間以内にMVP完成
  • ✅ Gitワークフロー:コミットメッセージコンベンション、ブランチ戦略
  • ✅ デプロイ自動化:VercelでCI/CD
  • ✅ ドキュメント化:README、ガイド文書作成

🎯 結果:MVP完成!

完成した機能

  • ✅ 習慣追加/削除
  • ✅ 今日のチェック画面
  • ✅ 月別カレンダービュー
  • ✅ 進捗度グラフ(30日、週間)
  • ✅ レスポンシブデザイン
  • ✅ LocalStorageデータ永続化

コード統計

  • 総行数:~1,500 lines
  • コンポーネント:4個
  • Custom Hook:1個
  • ユーティリティ関数:9個

GitHub & デプロイ

# Git初期化
git init
git add .
git commit -m "🎉 Initial commit: HabitFlow MVP"

# GitHub push
git remote add origin https://github.com/7ngenious/habitflow-mvp.git
git push -u origin main

# Vercelデプロイ
vercel deploy --prod

デプロイ完了! https://habitflow-mvp.vercel.app


🤔 惜しいこと

まだない機能

  • 習慣修正機能
  • 各チェックにメモ追加
  • ダークモード
  • データエクスポート/インポート

改善したいこと

  • アニメーション効果
  • ローディング状態表示
  • エラーハンドリング改善
  • テストコード作成

🚀 次のステップ

Phase 1.1 - 機能追加(1週間)

  • 習慣修正機能
  • メモ機能
  • UI/UX改善

Phase 2.0 - バックエンド連動(2-3週間)

  • Spring Boot APIサーバー
  • MySQLデータベース
  • JWT認証/認可
  • フルスタックアプリケーション完成

💭 所感

「1日で完成できるだろうか?」

最初は疑問だった。しかしClaudeと一緒なら可能だった。

重要なのはAIではなく方向性だった。

AIは速くコードを生成してくれるが、何を作るかは私が決めなければならなかった。どんな機能が必要か、どんなUIが良いか、どのように実装するかは私が悩んだ。

そして製造現場の経験が役立った。

データ収集 → 分析 → 可視化という流れはPLCからSFCへとつながるプロセスと同じだった。MES開発者への道が見え始めた。


📅 次の話

2編ではデプロイ後に経験した問題を扱う。

  • Git pushができない時
  • HTTP 400エラー解決
  • Vercelデプロイタイミングイシュー
  • SSH vs HTTPS認証

🔗 プロジェクトリンク


シリーズ

  • 0編:習慣を「感じられる」ように
  • 1編:バイブコーディングで1日でMVP完成(現在)
  • 2編:デプロイ後Git Pushができない時 - HTTP 400エラー解決記(予定)

Tags: #React #Vite #AIコーディング #Claude #LocalStorage #Recharts #ポートフォリオ #1日開発

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?