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?

【個人開発PWA】CoupleOpsのWeek0:30秒ループを作るまで——心理学×UI/UXで“責めずに、決められる”を形にする

Posted at

開発を始めた背景

AI駆動の開発をしてみたいと考えていた時に知り合いが同棲をするうえで想像と現実のギャップやズレが多くてメンタルを崩す、体調が安定しないといった話を聞いて役に立てるものがつくれないかと思い始めました。

Week0のスコープ範囲

ねらいはシンプル——ログイン不要の30秒体験で「完了→💖→3秒後の一言」を届け、責めずに感謝と小さな意思決定を回すところまで。

心理学の要素を入れた機能について

  • 実行意図(If–Then):合図→行動の型を先に決めると実行率が上がる(中〜大の効果)
  • 感謝介入:短い感謝でも気分・関係満足が改善(小〜中)
  • 選択過多:最初は 3 択に絞るほうが動きやすい。 → CoupleOps は 完了→💖→3秒後に一言(3択) を最小ループに採用

アーキテクチャ

  • PWA(React + TypeScript + Vite)
  • データ:events[] = { ts, type, attrs? } を端末内に保存
  • 画面:Welcome / Home / Weekly / Evidence / Settings
  • PWA:manifest.webmanifest + アイコン(SWは任意)

コード抜粋

1.PWA マニフェスト

{
"name": "CoupleOps",
"short_name": "CoupleOps",
"start_url": "/",
"display": "standalone",
"background_color": "#ffffff",
"theme_color": "#ffd7e0",
"icons": [
{ "src": "/icons/icon-192.png", "sizes": "192x192", "type": "image/png" },
{ "src": "/icons/icon-512.png", "sizes": "512x512", "type": "image/png" }
]
}

<link rel="manifest" href="/manifest.webmanifest" />
<meta name="theme-color" content="#ffd7e0" />

2.イベントの端末内保存(週次集計)

export type Ev={ts:number;type:string;attrs?:Record<string,any>};
const buf:Ev[]=JSON.parse(localStorage.getItem('co_ev')||'[]');
export function log(type:string,attrs:Record<string,any>={}){
buf.push({ts:Date.now(),type,attrs});
localStorage.setItem('co_ev',JSON.stringify(buf));
}
export function readWeek(){
const now=new Date(); const day=now.getDay();
const diff=now.getDate()-day+(day===0?-6:1);
const monday=new Date(now.setDate(diff)); monday.setHours(0,0,0,0);
return buf.filter(e=>e.ts>=monday.getTime());
}

3.Home の 30秒ループ(3秒後の一言)

const TPLS=['助かった!今日はゆっくりしてね','いつもありがとう。次は私が畳むね','いい感じ、続けたいね'];
const [stage,setStage]=useState<'idle'|'done'|'acr'>('idle');
const [showTpl,setShowTpl]=useState(false);
function complete(){
log('card_created',{first:true});
setStage('done');
setTimeout(()=>setShowTpl(true),3000); // ← ここが“3秒後の一言”
}
function sendStamp(){ log('acr_stamp_sent'); }
function sendText(t:string){ log('acr_text_added',{source:'tpl',text:t}); setStage('acr'); }

4.Weekly の可視化(丸め表記とQuiet)

function fmt(n:number){return n<1000?`${n}+`:`${(n/1000).toFixed(1)}K+`;}
const quiet=(thx*2+ift*3+tplRate*10);
const quietLabel=quiet>=30?'穏やか':'ざわざわ';

UI/UX(Week0の指針)

  • 色テーマ:3種(既定:ライトピンク #FFD7E0 / ダーク / ターコイズ)
  • ボタン:角丸12–16px、境界線薄め、余白広め、影は控えめ
  • レイアウト:幅720px以内の単一カラム+下部バナーの余白を確保
  • マイクロコピー:肯定・短文・具体(例:「助かった!」)
  • アクセシビリティ:コントラストAA相当、フォーカスリング表示

ここまでのつまずき&解決メモ

  • Vite 起動時の rolldown-vite (Experimental) 表示 → 情報メッセージ。気になる場合は vite@5.0.0 --save-exact に固定
  • iOSでのインストール案内 → 自動で出ないことがある。**「ホーム画面に追加」**のマイクロコピーをWelcomeに記載
  • オフライン対応 → SWは次回以降(vite-plugin-pwa)

次回以降(予告)

1.Soloループの磨き込み(UI/UX・A/B・3テーマ)
2.Evidence(研究の裏付け)の読みやすい見せ方
3.PWA実用化:Service Worker(キャッシュ・オフライン)
4.BYOK(Gemini)で一言テンプレ提案、Google Calendar 連携
5.社会的証明:Cloudflare Workers + KV で「今週 50+ が体験」を表示

参考リンク

GitHub

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?