現場とコードの間 - 7ngenious
2025.02.11
🚀 スタート:午前9時、Claudeと一緒に
2025年2月11日朝。
「習慣トラッカーを作ってみよう」という考えでClaude AIを起動した。Spring Bootを勉強しているが、フロントエンドを先に完成することにした。
最初の会話
私:「毎月毎週習慣を表で構成して、デイリーでチェックしながら
進捗度をグラフで見られるプログラムを作りたいです
写真のような感じです」
[スクリーンショット添付]
Claude:「良いプロジェクトアイデアですね!
あなたのSpring Boot学習ともよく合うし、
ポートフォリオとしても活用しやすいと思います。」
そしてすぐに質問が飛んできた。
🎯 戦略樹立:「速く、実用的に」
Claudeの質問
- 技術スタック:フルスタック?フロントのみ?バックエンドのみ?
- 必須機能:本当に必要なものだけ?
- 開発期間:いつまでに?
私の答え
✅ 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分)
一番難しかった部分!
月別カレンダーを描くためには:
- 該当月のすべての日付生成
- 最初の週の空白計算(日曜日が開始日でなければ)
- 週次計算
// 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できれいに
デザイン原則
- 簡潔さ:不要な装飾なしで
- 直感性:見た瞬間理解可能
- レスポンシブ:モバイルも快適に
主要技術
/* 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時間(休憩含む)
📸 完成画面
💡 「バイブコーディング」とは?
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認証
🔗 プロジェクトリンク
- Live Demo: https://habitflow-mvp.vercel.app
- GitHub: https://github.com/7ngenious/habitflow-mvp
シリーズ
- 0編:習慣を「感じられる」ように
- 1編:バイブコーディングで1日でMVP完成(現在)
- 2編:デプロイ後Git Pushができない時 - HTTP 400エラー解決記(予定)
Tags: #React #Vite #AIコーディング #Claude #LocalStorage #Recharts #ポートフォリオ #1日開発


