Opentrons Labworks Inc
Software for writing protocols and running them on the Opentrons Flex and Opentrons OT-2
食べたものを写真で残し、食べすぎたかを○×で振り返る日記
Translation pending
HealthTypeScript · SCSSGitHub @hiro603OnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
食べたものを写真で残し、食べすぎたかを○×で振り返る食事日記PWA(Next.js / TypeScript / IndexedDB)
Translation pending
Taken from the repository README
Loading the full README.
Read the full README ↗写真とかんたんな記録を日付ごとに残し、月のカレンダーで振り返るスマホ向けの日記アプリを、共通の土台(packages/journal/)の上に2つ作りました。
どちらも記録は端末内(IndexedDB)にだけ保存し、サーバーには送りません。ホーム画面に追加してアプリのように使えます(PWA)。
| アプリ | 内容 | デモ |
|---|---|---|
食事日記(apps/meal/) | 食べたものを写真で残し、その日に「食べすぎたか」を ○ / × で付ける。1日1件 | https://meal-diary-sable.vercel.app |
釣果ノート(apps/fishing/) | 釣行ごとに釣果・釣り場・天気・潮・風・仕掛けを記録する。1日に複数件 | https://fishing-log-chi.vercel.app |
スマホで開き、ホーム画面に追加して使うのがおすすめです。
| 分類 | 使用技術 |
|---|---|
| フレームワーク | Next.js 16(App Router)、React 19、TypeScript |
| スタイル | SCSS(CSS Modules)、デザイントークン(primitive / semantic の2層) |
| データ保存 | IndexedDB(Dexie.js 4、dexie-react-hooks) |
| テスト | Vitest、fake-indexeddb、Playwright(画面と画像処理の検証) |
| ホスティング | Vercel |
汎用的な部分(packages/journal/)とアプリに固有の部分(apps/meal/、apps/fishing/)を分け、1つのリポジトリで複数のアプリを管理する構成(npm workspaces)にしています。釣果ノートは、この土台の上に後から作りました。
Entry<TFields> 型で表し、アプリ固有の項目は型引数で渡します。食事日記では { overate: boolean | null }、釣果ノートでは釣り場・天気・潮・風・仕掛けと、魚種ごとの釣果の配列ですgetBadge 関数で、その日の記録の一覧から印(○× や合計匹数)を作って渡します。1日1件の食事日記も、1日に複数件の釣果ノートも同じ部品で表示できますJournalRepository インターフェースだけです。将来クラウド保存(Supabase)に移るときは、その実装を差し替えるだけで済みます保存ボタンは置かず、入力が止まって0.5秒たったら保存します(useDebouncedSave)。画面を離れるときと、アプリが裏に回ったとき(visibilitychange)は待たずに保存するので、入力の途中でアプリを閉じても消えません。釣果ノートの匹数・サイズ・風速は、入力中は文字列のまま持ち、保存するときに数値に直します。数値で持つと、「23.」のような入力の途中の値が「23」に戻ってしまうためです。
createdAt / updatedAt で持ちます。将来クラウドと同期するときに、ID が衝突せず、どちらが新しいかを比べられますundefined ではなく null で表します。値が入っていない状態と、項目そのものがない状態を区別するためです撮った写真は createImageBitmap で読み込み、canvas に描き直してから JPEG で保存します。描き直した画素だけが残るので、位置情報などの EXIF は一緒に保存されません。回転情報は描画の前に反映されるため、向きもずれません。この挙動は、位置情報と回転情報を埋め込んだ画像を使って実際のブラウザで確かめています。
日付は "YYYY-MM-DD" のローカル日付で扱います。toISOString() は UTC で計算するため、日本時間の朝9時より前に記録すると前日の日付になってしまいます。これを避けるためです。「今日」はサーバー(UTC・ビルド時刻)では決めず、端末側で useSyncExternalStore を使って求めます。
| 起きた問題 | 対応 |
|---|---|
| メモを入力してキーボードを閉じると、画面が押し上げられたまま戻らない | body に overflow: hidden を付けて内側だけスクロールさせる作りをやめ、ページ全体をスクロールさせる。タブバーと操作バーは sticky で画面下に固定する |
| 16px 未満の入力欄にフォーカスすると、画面が拡大される | 入力欄の文字は 16px 以上にする |
capture 属性を付けると、アルバムから選べなくなる | 「撮る」(capture あり)と「選ぶ」(capture なし)でボタンを分ける |
| Safari とホーム画面のアプリで、データが別々に保存される | Safari で開いたときにホーム画面への追加を案内し、記録を始める場所をアプリに揃える |
| 7日間使わないとデータが消えることがある | ホーム画面に追加すると、この削除の対象外になる。あわせて navigator.storage.persist() を呼ぶ |
packages/journal/ # 汎用層:型、Repository、Dexie の実装、フック、部品(カレンダー・写真・メモ・タブバーなど)、日付・画像処理
apps/meal/src/
├─ app/ # ルーティング(今日 / 日付指定 / カレンダー)、manifest
├─ meal/ # 食事日記に固有の部分:項目の型、○× の切り替え、画面
└─ styles/tokens/ # デザイントークン(primitive / semantic)。オレンジ系
apps/fishing/src/
├─ app/ # ルーティング(今日 / 日付指定 / 釣行 / カレンダー)、manifest
├─ fishing/ # 釣果ノートに固有の部分:項目の型、入力値の変換、並べ替え・集計、画面
└─ styles/tokens/ # デザイントークン。青系
共通の部品は semantic トークン(CSS 変数)だけを参照しています。2つのアプリは同じ変数名で値だけを変えているので、同じ部品のまま見た目が変わります。
npm install # リポジトリ直下で実行(全ワークスペースが入る)
npm run dev:meal # http://localhost:3000
npm run dev:fishing # http://localhost:3001
npm run dev:lan --workspace=apps/meal # 同じ Wi-Fi のスマホから http://<MacのIP>:3000 で開く(釣果ノートは apps/fishing、3001)
npm test # Vitest(日付計算・Repository・画像の寸法計算・釣果の入力変換と集計)
npm run typecheck # 各ワークスペースの型チェック
npm run build
LAN の http から開いた場合、HTTPS でしか使えない API(storage.persist() など)は動きません。ホーム画面への追加もうまく確認できません。これらの確認は、デプロイした後に本番の URL で行ってください。
スクリーンショットの料理写真には、Wikimedia Commons で CC0(パブリックドメイン)として公開されている画像を使い、実際にアプリへ読み込ませて撮影しました。