feat: finish step flow without losing quiz, clear-and-start option, scroll to comprehension

Made-with: Cursor
This commit is contained in:
posimai 2026-04-19 16:40:41 +09:00
parent 16547cf0ad
commit ca658f6369
3 changed files with 52 additions and 13 deletions

View File

@ -645,25 +645,36 @@ header{display:flex;align-items:center;justify-content:space-between;padding:0 1
</div>
<!-- Study mode buttons -->
<div style="display:flex;gap:8px;margin-bottom:14px;flex-wrap:wrap" x-show="currentUnit && !stepMode">
<button class="btn-sm btn-accent" @click="startStepMode()"
<div style="display:flex;gap:8px;margin-bottom:14px;flex-wrap:wrap;align-items:center" x-show="currentUnit && !stepMode">
<button class="btn-sm btn-accent" type="button" @click="startStepMode()"
x-show="currentUnit?.keypoints?.length">
<i data-lucide="layers" style="width:11px;height:11px"></i>
3ステップで学ぶ
</button>
<button class="btn-sm" type="button" @click="startStepModeClearQuiz()"
x-show="currentUnit?.keypoints?.length && currentUnit?.quiz?.length && Object.keys(quizState).length">
<i data-lucide="refresh-cw" style="width:11px;height:11px"></i>
理解度をクリアして学ぶ
</button>
</div>
<!-- Step mode card -->
<div class="card" x-show="stepMode" style="margin-bottom:14px">
<div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:14px">
<div class="card-title" style="margin-bottom:0">
<div style="display:flex;flex-wrap:wrap;align-items:flex-start;justify-content:space-between;gap:10px;margin-bottom:14px">
<div class="card-title" style="margin-bottom:0;flex:1;min-width:0">
<i data-lucide="layers" style="width:13px;height:13px"></i>
3ステップで学ぶ
</div>
<button class="btn-sm" type="button" @click="stepGoBack()" aria-label="1つ前に戻る">
<div style="display:flex;gap:8px;flex-wrap:wrap;justify-content:flex-end">
<button class="btn-sm" type="button" @click="stepGoBack()" aria-label="1つ前のカードに戻る">
<i data-lucide="arrow-left" style="width:11px;height:11px"></i>
戻る
</button>
<button class="btn-sm" type="button" @click="finishStepMode()" aria-label="学習フローを終了し理解度チェックへ">
<i data-lucide="check" style="width:11px;height:11px"></i>
学習フローを終了
</button>
</div>
</div>
<div class="step-pips">
<div class="step-pip" :class="stepPipCls(1)"></div>
@ -732,14 +743,22 @@ header{display:flex;align-items:center;justify-content:space-between;padding:0 1
<i data-lucide="check-circle-2" style="width:12px;height:12px"></i>
Step 3 — 本番問題
</div>
<p style="font-size:12px;color:var(--text2);line-height:1.65">
下の理解度チェックを解いて完了です。全問正解でこの単元をマスターしましょう
<p style="font-size:12px;color:var(--text2);line-height:1.65;margin-bottom:8px">
下の理解度チェックで確認します。途中まで答えた内容はそのまま続きからできます。最初から出し直すときは、全問に一度答えたあとに表示される「やり直し」か、フロー外の「理解度をクリアして学ぶ」を使ってください
</p>
<p style="font-size:11px;color:var(--text3);line-height:1.55;margin-bottom:12px"
x-show="Object.keys(quizState).length">
現在の解答は保持されています。
</p>
<button class="btn-sm btn-accent" type="button" @click="scrollToComprehension()">
<i data-lucide="chevron-down" style="width:11px;height:11px"></i>
理解度チェックへ移動
</button>
</div>
</div>
<!-- Quiz -->
<div class="card" x-show="currentUnit?.quiz?.length && (!stepMode || stepStep === 3)">
<div id="comprehension-quiz" class="card" x-show="currentUnit?.quiz?.length && (!stepMode || stepStep === 3)">
<div class="quiz-header">
<div class="quiz-title-label">
<i data-lucide="check-circle-2" style="width:13px;height:13px"></i>

View File

@ -418,17 +418,37 @@ document.addEventListener('alpine:init', () => {
this.stepDrillIdx=0;
this.stepDrillAnswered=false;
this.stepDrillSelected=-1;
this.quizState={};
this.$nextTick(()=>{
if(window.lucide) lucide.createIcons();
const m=document.getElementById('main');
if(m) m.scrollTo({top:0,behavior:'smooth'});
});
},
/** 理解度を空にしてから 3 ステップStep3 で一貫した初回解答) */
startStepModeClearQuiz(){
this.quizState={};
this.startStepMode();
},
exitStepMode(){
this.stepMode=false;
this.$nextTick(()=>{ if(window.lucide) lucide.createIcons(); });
},
/** ガイド付き学習をやめ、単元画面に戻す(理解度の回答は保持) */
finishStepMode(){
this.stepMode=false;
this.$nextTick(()=>{
if(window.lucide) lucide.createIcons();
const el=document.getElementById('comprehension-quiz');
if(el) el.scrollIntoView({behavior:'smooth',block:'start'});
});
},
scrollToComprehension(){
this.$nextTick(()=>{
const el=document.getElementById('comprehension-quiz');
if(el) el.scrollIntoView({behavior:'smooth',block:'start'});
if(window.lucide) lucide.createIcons();
});
},
/** ヘッダ「戻る」: 同一ステップ内なら1枚前、先頭なら3ステップを終了 */
stepGoBack(){
if(!this.stepMode) return;

2
sw.js
View File

@ -1,5 +1,5 @@
// posimai-boki SW — stale-while-revalidate + skipWaiting
const CACHE = 'posimai-boki-v16';
const CACHE = 'posimai-boki-v17';
const STATIC = ['/', '/index.html', '/manifest.json', '/logo.png', '/js/app.js', '/js/data/drills.js', '/js/data/categories.js'];
self.addEventListener('install', e => {