diff --git a/backend/docs/ANALYSIS_GUIDE.md b/backend/docs/ANALYSIS_GUIDE.md
index f6d867c..3cb0e18 100644
--- a/backend/docs/ANALYSIS_GUIDE.md
+++ b/backend/docs/ANALYSIS_GUIDE.md
@@ -117,7 +117,7 @@ src/analysis/
"speechDurationMs": 8500,
"silenceDurationMs": 500,
"volumeDb": -25.3,
- "transcribedText": "ログイン画面でパスワードを入力しても弾かれます"
+ "transcribedText": "ログインして移動したのに、ダッシュボードが真っ白で何も表示されません"
},
{
"turnIndex": 2,
@@ -126,7 +126,7 @@ src/analysis/
"speechDurationMs": 12000,
"silenceDurationMs": 300,
"volumeDb": -22.1,
- "transcribedText": "いや、それは違います。なぜならパスワードリセットのリンクが表示されないんです"
+ "transcribedText": "いや、キャッシュの問題ではないと思います。なぜなら別のブラウザで試しても画面が出ないんです"
},
{
"turnIndex": 3,
@@ -135,7 +135,7 @@ src/analysis/
"speechDurationMs": null,
"silenceDurationMs": null,
"volumeDb": null,
- "transcribedText": "もういいです、別の方法を試します"
+ "transcribedText": "もう解決しそうにないので、エンジニアの方に確認してもらえますか"
}
]
}
diff --git a/backend/src/services/fallbackData.ts b/backend/src/services/fallbackData.ts
index 339ecf8..87beabc 100644
--- a/backend/src/services/fallbackData.ts
+++ b/backend/src/services/fallbackData.ts
@@ -17,17 +17,7 @@ export interface FallbackEntry {
export const FALLBACK_TABLE: FallbackEntry[] = [
// ===== ラリー1系: 状況説明キーワード =====
{
- keywords: ['ログイン', 'パスワード', 'サインイン', 'ログアウト', '認証', 'アカウント'],
- responses: [
- { response: 'パスワードは半角英数字で入力していただく必要がございます。たぶん。', emotion: 'confident' },
- { response: 'ブラウザのCookieをクリアしてみてください。それで直ると思います。', emotion: 'confused' },
- { response: 'ブラウザを変えてみるのが早いかもしれません。根拠はないですけど。', emotion: 'confused' },
- { response: 'ログイン画面を一度閉じて、もう一度開いてみてください。', emotion: 'confident' },
- { response: 'パスワードの大文字小文字は区別されますので、ご確認いただけますでしょうか。', emotion: 'neutral' },
- ],
- },
- {
- keywords: ['ダッシュボード', '画面', '表示されない', '見えない', '出ない', '真っ白', '白い'],
+ keywords: ['ダッシュボード', 'メイン画面', 'ログイン後', '表示されない', '見えない', '出ない', '真っ白', '白い', '画面移行'],
responses: [
{ response: 'ページを更新してみてください。F5キーを押すと更新できます。', emotion: 'confident' },
{ response: 'キャッシュが原因の可能性がございます。コントロールとシフトとデリートで削除できます。', emotion: 'confused' },
@@ -35,6 +25,16 @@ export const FALLBACK_TABLE: FallbackEntry[] = [
{ response: '別のタブで開き直してみるとうまくいくかもしれません。', emotion: 'neutral' },
],
},
+ {
+ keywords: ['ログイン', 'パスワード', 'サインイン', 'ログアウト', '認証', 'アカウント', '入れない'],
+ responses: [
+ { response: 'パスワードは半角英数字で入力していただく必要がございます。たぶん。', emotion: 'confident' },
+ { response: 'ログイン画面を一度閉じて、もう一度開いてみてください。', emotion: 'confident' },
+ { response: 'パスワードの大文字小文字は区別されますので、ご確認いただけますでしょうか。', emotion: 'neutral' },
+ { response: 'ブラウザのCookieをクリアしてみてください。それで直ると思います。', emotion: 'confused' },
+ { response: 'ブラウザを変えてみるのが早いかもしれません。根拠はないですけど。', emotion: 'confused' },
+ ],
+ },
{
keywords: ['エラー', 'エラーコード', '500', '404', '403', '不具合', 'バグ', 'おかしい'],
responses: [
diff --git a/frontend/public/RealYouLogo.png b/frontend/public/images/RealYouLogo.png
similarity index 100%
rename from frontend/public/RealYouLogo.png
rename to frontend/public/images/RealYouLogo.png
diff --git a/frontend/public/StartButton.png b/frontend/public/images/StartButton.png
similarity index 100%
rename from frontend/public/StartButton.png
rename to frontend/public/images/StartButton.png
diff --git a/frontend/public/images/game2_backcground.png b/frontend/public/images/game2_backcground.png
new file mode 100644
index 0000000..080b7af
Binary files /dev/null and b/frontend/public/images/game2_backcground.png differ
diff --git a/frontend/public/start-se.mp3 b/frontend/public/sounds/start-se.mp3
similarity index 100%
rename from frontend/public/start-se.mp3
rename to frontend/public/sounds/start-se.mp3
diff --git "a/frontend/public/sounds/\351\233\273\350\251\261\343\201\214\345\210\207\343\202\214\343\202\2131.mp3" "b/frontend/public/sounds/\351\233\273\350\251\261\343\201\214\345\210\207\343\202\214\343\202\2131.mp3"
new file mode 100644
index 0000000..6e0ac78
Binary files /dev/null and "b/frontend/public/sounds/\351\233\273\350\251\261\343\201\214\345\210\207\343\202\214\343\202\2131.mp3" differ
diff --git "a/frontend/public/sounds/\351\233\273\350\251\261\343\201\256\345\221\274\343\201\263\345\207\272\343\201\227\351\237\263.mp3" "b/frontend/public/sounds/\351\233\273\350\251\261\343\201\256\345\221\274\343\201\263\345\207\272\343\201\227\351\237\263.mp3"
new file mode 100644
index 0000000..a82da89
Binary files /dev/null and "b/frontend/public/sounds/\351\233\273\350\251\261\343\201\256\345\221\274\343\201\263\345\207\272\343\201\227\351\237\263.mp3" differ
diff --git a/frontend/src/app/page.tsx b/frontend/src/app/page.tsx
index 5bbc151..7650a2b 100644
--- a/frontend/src/app/page.tsx
+++ b/frontend/src/app/page.tsx
@@ -1,5 +1,6 @@
'use client';
+import Image from 'next/image';
import { useRouter } from 'next/navigation';
import { useState } from 'react';
import type { CSSProperties } from 'react';
@@ -62,7 +63,7 @@ export default function TopPage() {
const handleStartClick = () => {
setShowExplosion(true);
- const audio = new Audio('/start-se.mp3');
+ const audio = new Audio('/sounds/start-se.mp3');
audio.play().catch(() => {});
setTimeout(() => {
@@ -88,15 +89,12 @@ export default function TopPage() {
}}
>
-
@@ -104,15 +102,12 @@ export default function TopPage() {
onClick={handleStartClick}
className="transition-all duration-100 ease-out hover:scale-110 active:scale-95 active:opacity-50"
>
-

diff --git a/frontend/src/features/games/helpdesk/components/HelpdeskGameFlow.tsx b/frontend/src/features/games/helpdesk/components/HelpdeskGameFlow.tsx
index 6cebb5d..b1f8aad 100644
--- a/frontend/src/features/games/helpdesk/components/HelpdeskGameFlow.tsx
+++ b/frontend/src/features/games/helpdesk/components/HelpdeskGameFlow.tsx
@@ -1,18 +1,18 @@
'use client';
import { useRouter } from 'next/navigation';
-import { useCallback, useEffect, useRef, useState } from 'react';
+import { useCallback, useRef, useState } from 'react';
import type { Game2Data } from '@/features/games/types';
import { submitGame } from '@/lib/api';
import { useHelpdeskGame } from '../hooks/useHelpdeskGame';
import Spinner from '@/components/ui/Spinner';
+import { GAME_TOPIC } from '../data/supportResponses';
type SubmitStatus = 'loading' | 'success' | 'error';
export default function HelpdeskGameFlow() {
const router = useRouter();
const [textInput, setTextInput] = useState('');
- const chatEndRef = useRef
(null);
const [submitStatus, setSubmitStatus] = useState('loading');
const pendingDataRef = useRef(null);
@@ -72,11 +72,22 @@ export default function HelpdeskGameFlow() {
switchToText,
onKeyDown,
resetTyping,
- isVoiceSupported,
voiceApiRetrying,
retryVoiceApi,
+ startInstruction,
+ gameTopic,
+ hints,
} = useHelpdeskGame({ onComplete: handleComplete });
+ const [hintIndex, setHintIndex] = useState(0);
+ const [prevHints, setPrevHints] = useState(hints);
+
+ // ヒント内容が更新されたら(AIの応答に基づき)、インデックスを0(おすすめ)にリセットする
+ if (hints !== prevHints) {
+ setPrevHints(hints);
+ setHintIndex(0);
+ }
+
const handleTextSubmit = useCallback(() => {
if (!textInput.trim()) return;
submitTextTurn(textInput);
@@ -84,63 +95,38 @@ export default function HelpdeskGameFlow() {
resetTyping();
}, [textInput, submitTextTurn, resetTyping]);
- useEffect(() => {
- chatEndRef.current?.scrollIntoView({ behavior: 'smooth' });
- }, [chatHistory]);
-
- // --- 完了画面 ---
- if (gamePhase === 'completed') {
- if (submitStatus === 'loading') {
- return (
-
-
-
- );
- }
- if (submitStatus === 'error') {
- return (
-
-
- 通信に失敗しました
-
+ // --- チャット画面 (ゲームメイン画面) ---
+ return (
+
+ {/* 画面右上: キーボード入力 切替ボタン */}
+ {inputMethod === 'voice' &&
+ gamePhase !== 'tutorial' &&
+ gamePhase !== 'instruction' && (
-
- );
- }
- return (
-
-
-
完了しました
-
- 次のゲームに移動します...
-
-
-
- );
- }
+ )}
- // --- チャット画面 ---
- return (
-
{/* --- AI応答取得失敗オーバーレイ --- */}
{gamePhase === 'voice-api-error' && (
-
-
-
- 通信に失敗しました
-
+
+
+
通信に失敗しました
{voiceApiRetrying ? (
-
+
+
+
) : (
@@ -149,137 +135,231 @@ export default function HelpdeskGameFlow() {
)}
- {/* --- 指示ポップアップ(オーバーレイ / 全体タップで進む) --- */}
+ {/* --- ルールポップアップ (チュートリアルフェーズ) --- */}
+ {gamePhase === 'tutorial' && (
+
+
+ {/* 閉じるボタン */}
+
+
+
+ ルール
+
+
+
+ {instructionText}
+
+
+
+ )}
+
+ {/* --- お題提示カットイン (インストラクションフェーズ) --- */}
{gamePhase === 'instruction' && (