@@ -9,6 +9,7 @@ const ANSWERS = {
99 p1 : "すばらしい。" ,
1010 p2 : "./images/star5.png" ,
1111 p3Visible : false ,
12+ p4 : "30%割引が適用されました!" ,
1213}
1314
1415function App ( ) {
@@ -21,10 +22,11 @@ function App() {
2122 // イベントリスナー内で最新の step を参照するための Ref
2223 const stepRef = useRef ( step )
2324 // 各ステップの初期値を保持するベースライン
24- const baselineRef = useRef < { p1 : string | null ; p2 : string | null ; p3Visible : boolean | null } > ( {
25+ const baselineRef = useRef < { p1 : string | null ; p2 : string | null ; p3Visible : boolean | null ; p4 : string | null } > ( {
2526 p1 : null ,
2627 p2 : null ,
2728 p3Visible : null ,
29+ p4 : null ,
2830 } )
2931
3032 // state が変わったら ref も更新しておく
@@ -44,14 +46,11 @@ function App() {
4446
4547 port . onMessage . addListener ( ( msg ) => {
4648 if ( msg ?. type === 'DOM_VALUE_UPDATE' ) {
47- const { p1, p2, p3Visible } = msg . values
49+ const { p1, p2, p3Visible, p4 } = msg . values
4850 const currentStep = stepRef . current
4951
5052 if ( currentStep === 1 ) {
51- if ( baselineRef . current . p1 === null ) {
52- baselineRef . current . p1 = p1
53- return
54- }
53+ if ( baselineRef . current . p1 === null ) { baselineRef . current . p1 = p1 ; return }
5554 if ( p1 !== baselineRef . current . p1 ) {
5655 const isCorrect = p1 === ANSWERS . p1
5756 setResult ( { ok : isCorrect , details : isCorrect ? `一致: "${ p1 } "` : `不一致: "${ p1 } "` } )
@@ -60,16 +59,13 @@ function App() {
6059 setStep ( 2 )
6160 setResult ( null )
6261 baselineRef . current . p2 = p2
63- } , 2000 )
62+ } , 4000 )
6463 }
6564 }
6665 }
6766
6867 if ( currentStep === 2 ) {
69- if ( baselineRef . current . p2 === null ) {
70- baselineRef . current . p2 = p2
71- return
72- }
68+ if ( baselineRef . current . p2 === null ) { baselineRef . current . p2 = p2 ; return }
7369 if ( p2 !== baselineRef . current . p2 ) {
7470 const isCorrect = p2 . includes ( ANSWERS . p2 )
7571 setResult ( { ok : isCorrect , details : isCorrect ? `一致: (${ p2 } )` : `不一致: (${ p2 } )` } )
@@ -78,30 +74,36 @@ function App() {
7874 setStep ( 3 )
7975 setResult ( null )
8076 baselineRef . current . p3Visible = p3Visible
81- } , 2000 )
77+ } , 4000 )
8278 }
8379 }
8480 }
8581
86- // 問題3のロジック
8782 if ( currentStep === 3 ) {
88- if ( baselineRef . current . p3Visible === null ) {
89- baselineRef . current . p3Visible = p3Visible
90- return
91- }
83+ if ( baselineRef . current . p3Visible === null ) { baselineRef . current . p3Visible = p3Visible ; return }
9284 if ( p3Visible !== baselineRef . current . p3Visible ) {
9385 const isCorrect = p3Visible === ANSWERS . p3Visible
86+ setResult ( { ok : isCorrect , details : isCorrect ? `要素が非表示になりました` : `要素はまだ表示されています` } )
87+ if ( isCorrect ) { setTimeout ( ( ) => { setStep ( 4 ) ; setResult ( null ) ; baselineRef . current . p4 = p4 } , 4000 ) }
88+ }
89+ }
90+
91+ // 問題4のロジック
92+ if ( currentStep === 4 ) {
93+ if ( baselineRef . current . p4 === null ) { baselineRef . current . p4 = p4 ; return }
94+ if ( p4 !== baselineRef . current . p4 ) {
95+ const isCorrect = p4 === ANSWERS . p4
9496 setResult ( {
9597 ok : isCorrect ,
96- details : isCorrect ? `要素が非表示になりました ` : `要素はまだ表示されています `
98+ details : isCorrect ? `割引が適用されました! ` : `まだ割引が適用されていません。 `
9799 } )
98100 }
99101 }
100102 }
101103 } )
102104
103105 port . onDisconnect . addListener ( ( ) => {
104- baselineRef . current = { p1 : null , p2 : null , p3Visible : null }
106+ baselineRef . current = { p1 : null , p2 : null , p3Visible : null , p4 : null }
105107 port = null
106108 setResult ( null )
107109 setStep ( 1 )
@@ -117,7 +119,7 @@ function App() {
117119 if ( port ) {
118120 try { port . disconnect ( ) } catch { }
119121 }
120- baselineRef . current = { p1 : null , p2 : null , p3Visible : null }
122+ baselineRef . current = { p1 : null , p2 : null , p3Visible : null , p4 : null }
121123 }
122124 } , [ ] )
123125
@@ -144,18 +146,27 @@ function App() {
144146 </ div >
145147 ) }
146148
147- { /* ステップ3の表示 */ }
148149 { step === 3 && (
149150 < div >
150151 < h2 > 問題3</ h2 >
151152 < p > 一つ目のレビューを、CSSを使って非表示にしてみよう!</ p >
153+ { result && < div className = { result . ok ? "result-ok" : "result-ng" } > < h3 > 判定: { result . ok ? '正解!' : '不正解' } </ h3 > < p > { result . details } </ p > { result . ok && < p > 次の問題へ進みます...</ p > } </ div > }
154+ { ! result && < p className = "hint" > ヒント:DevToolsのスタイルパネルで < code > display: none;</ code > を追加してみよう。</ p > }
155+ </ div >
156+ ) }
157+
158+ { /* 問題4のUI */ }
159+ { step === 4 && (
160+ < div >
161+ < h2 > 問題4</ h2 >
162+ < p > 割引コードを盗んで、30%割引を適用させよう!</ p >
152163 { result && (
153164 < div className = { result . ok ? "result-ok" : "result-ng" } >
154165 < h3 > 判定: { result . ok ? '正解!' : '不正解' } </ h3 >
155166 < p > { result . details } </ p >
156167 </ div >
157168 ) }
158- { ! result && < p className = "hint" > ヒント:DevToolsのスタイルパネルで < code > display: none; </ code > を追加してみよう。 </ p > }
169+ { ! result && < p className = "hint" > ヒント:sourcesに割引コードが書かれているかも </ p > }
159170 </ div >
160171 ) }
161172 </ div >
0 commit comments