import React, { useEffect, useMemo, useState } from "react"; import { motion, AnimatePresence } from "framer-motion"; import { Camera, Sparkles, Refrigerator, ShoppingBag, Send, CheckCircle2, Clock3, Users, Soup, Milk, Egg, Beef, Leaf, MessageCircle, ChevronRight, RotateCcw, Heart, Bell, Plus, Minus, Home, Utensils, Gift, } from "lucide-react"; const steps = [ { key: "home", label: "ホーム" }, { key: "capture", label: "撮影" }, { key: "analyzing", label: "AI解析" }, { key: "inventory", label: "在庫" }, { key: "recipes", label: "献立" }, { key: "request", label: "買ってキテ" }, { key: "family", label: "家族側" }, ]; const detectedItemsBase = [ { id: 1, name: "卵", note: "残り 4個くらい", confidence: 94, icon: Egg, tag: "朝食にも" }, { id: 2, name: "牛乳", note: "少なめかも", confidence: 87, icon: Milk, tag: "期限注意" }, { id: 3, name: "豚こま", note: "1パック", confidence: 82, icon: Beef, tag: "今日使いたい" }, { id: 4, name: "キャベツ", note: "半玉くらい", confidence: 89, icon: Leaf, tag: "野菜" }, { id: 5, name: "納豆", note: "3パック", confidence: 78, icon: Soup, tag: "定番" }, ]; const recipes = [ { title: "豚こまキャベツ炒め", badge: "買い足しなし", time: "10分", desc: "豚こま・キャベツ・卵で、今日すぐ作れる節約メニュー。", ingredients: ["豚こま", "キャベツ", "卵"], }, { title: "豆腐だけ買えば麻婆豆腐", badge: "豆腐だけ買ってキテ", time: "15分", desc: "帰り道の家族に豆腐だけ頼めば、夕食のメインが完成。", ingredients: ["豚こま", "豆腐", "ねぎ"], recommended: true, }, { title: "子ども向けチーズオムレツ", badge: "子ども向け", time: "8分", desc: "卵と牛乳でふんわり。冷蔵庫にチーズがあればさらに◎。", ingredients: ["卵", "牛乳", "チーズ"], }, ]; function cx(...classes) { return classes.filter(Boolean).join(" "); } function Logo() { return (
Katteキテ
AI fridge family app
); } function PhoneShell({ children }) { return (
{children}
); } function AppHeader({ step, goTo }) { return (
{steps.slice(0, 7).map((s) => (
x.key === step) >= steps.findIndex((x) => x.key === s.key) ? "bg-orange-400" : "bg-orange-100" )} /> ))}
); } function FridgeIllustration({ scanning = false }) { const foods = [ { label: "MILK", className: "left-[12%] top-[14%] h-20 w-12 bg-blue-100" }, { label: "EGG", className: "left-[34%] top-[17%] h-11 w-24 bg-amber-100" }, { label: "MEAT", className: "left-[13%] top-[47%] h-12 w-28 bg-rose-100" }, { label: "VEG", className: "left-[53%] top-[43%] h-16 w-24 bg-emerald-100" }, { label: "NATTO", className: "left-[57%] top-[18%] h-12 w-20 bg-yellow-100" }, ]; return (
{foods.map((food) => ( {food.label} ))}
{scanning && ( )}
); } function HomeScreen({ goTo }) { return (
冷蔵庫を1枚撮るだけ

今日のごはんと、
買い足しが決まる。

冷蔵庫の中身をAIがざっくり読み取り。献立・不足食材・家族への買い物依頼まで、30秒で完了。

{[ [Camera, "撮る"], [Utensils, "決まる"], [Send, "頼める"], ].map(([Icon, label]) => (
{label}
))}
); } function CaptureScreen({ goTo }) { return (
冷蔵庫を撮影

完璧に写らなくてもOK。見える食材をAIが候補として出します。

); } function AnalyzingScreen({ goTo }) { const messages = ["食材を読み取り中…", "似ている商品を照合中…", "献立候補を考え中…"]; const [messageIndex, setMessageIndex] = useState(0); useEffect(() => { const msgTimer = setInterval(() => { setMessageIndex((v) => (v + 1) % messages.length); }, 850); const timer = setTimeout(() => goTo("inventory"), 3200); return () => { clearInterval(msgTimer); clearTimeout(timer); }; }, [goTo]); return (
AI解析中
だいたい認識でOK
{messages[messageIndex]}
); } function InventoryScreen({ goTo }) { const [items, setItems] = useState(detectedItemsBase.map((item) => ({ ...item, active: true }))); const toggleItem = (id) => { setItems((current) => current.map((item) => (item.id === id ? { ...item, active: !item.active } : item))); }; return (
AIが見つけた食材

違っていたらワンタップで修正。完璧な在庫表は目指しません。

5
検出
{items.map((item) => { const Icon = item.icon; return ( ); })}
); } function RecipesScreen({ goTo }) { return (
今日作れるごはん

家族の好み・調理時間・買い足し最小をもとに3つだけ提案。

{recipes.map((recipe) => (
{recipe.badge} {recipe.time}
{recipe.title}

{recipe.desc}

{recipe.recommended && (
)}
{recipe.ingredients.map((ingredient) => ( {ingredient} ))}
))}
); } function RequestScreen({ goTo }) { const [sent, setSent] = useState(false); return (
家族に買ってキテ

料理に足りない食材だけを、家族にワンタップ共有。

パパに送る
帰り道に買えるものだけ
豆腐だけ買ってキテ
冷蔵庫の豚こまと合わせて、麻婆豆腐にする予定!
買うもの
豆腐
1丁あればOK
不足
); } function FamilyScreen({ goTo }) { const [status, setStatus] = useState("unread"); const statusView = useMemo(() => { if (status === "bought") return { text: "買ったよ!", color: "emerald", icon: CheckCircle2 }; if (status === "alt") return { text: "木綿豆腐がなかったので絹豆腐にしたよ", color: "orange", icon: ShoppingBag }; if (status === "none") return { text: "売ってなかった…", color: "slate", icon: Minus }; return null; }, [status]); return (
家族側の画面
通知

頼まれた側は、買えたかどうかをワンタップで返せます。

豆腐だけ買ってキテ
麻婆豆腐にする予定!1丁あればOK。
豆腐
スーパーで買うもの
{status === "unread" ? (
) : ( {(() => { const Icon = statusView.icon; return ; })()}
{statusView.text}
料理担当にも自動で共有されました
)}
); } function ScreenWrap({ children }) { return (
{children}
); } function SidePanel({ goTo }) { const cards = [ { icon: Camera, title: "撮るだけで始まる", text: "手入力ではなく、冷蔵庫の写真を入口にするから利用ハードルが低い。", }, { icon: Sparkles, title: "完璧な在庫表を目指さない", text: "AIのざっくり認識+ワンタップ修正で、日常利用に寄せる。", }, { icon: Users, title: "家族共有がコア機能", text: "買い物担当と料理担当をつなぎ、家庭内の小さなストレスを減らす。", }, { icon: Gift, title: "将来の収益化余地", text: "家族プレミアム、レシートポイント、送客、匿名統計データ活用へ拡張。", }, ]; return (
社内提案用 UI/UXモック

冷蔵庫管理ではなく、
家族の買い物OSへ。

Katteキテは、スマホで冷蔵庫を撮るだけで「今日作れるもの」「足りないもの」「家族に頼むもの」をつなげるアプリの体験モックです。

{cards.map((card) => { const Icon = card.icon; return (
{card.title}

{card.text}

); })}
MVPで検証する導線
{[ "冷蔵庫撮影", "AI解析", "ワンタップ修正", "献立提案", "買ってキテ共有", "家族の完了報告", ].map((label, index) => ( {label} {index < 5 && } ))}
); } export default function KatteKiteMock() { const [step, setStep] = useState("home"); const goTo = (next) => setStep(next); const CurrentScreen = { home: HomeScreen, capture: CaptureScreen, analyzing: AnalyzingScreen, inventory: InventoryScreen, recipes: RecipesScreen, request: RequestScreen, family: FamilyScreen, }[step]; return (
); }