|
|
@ -1,43 +1,44 @@ |
|
|
|
import React, { useEffect } from 'react'; |
|
|
|
import React, {useEffect} from 'react' |
|
|
|
import { useNavigate } from 'react-router-dom'; |
|
|
|
import {useLocation, useNavigate} from 'react-router-dom' |
|
|
|
import Markdown from 'react-markdown'; |
|
|
|
import Markdown from 'react-markdown' |
|
|
|
import rehypeRaw from 'rehype-raw'; |
|
|
|
import rehypeRaw from 'rehype-raw' |
|
|
|
import BackButton from '../../components/BackButton'; |
|
|
|
import BackButton from '../../components/BackButton' |
|
|
|
import { useAppSelector, useAppDispatch } from '../../redux/hooks'; |
|
|
|
import {useAppSelector, useAppDispatch} from '../../redux/hooks' |
|
|
|
import './index.scss'; |
|
|
|
import './index.scss' |
|
|
|
|
|
|
|
|
|
|
|
function StepDetailPage() { |
|
|
|
function StepDetailPage() { |
|
|
|
const navigate = useNavigate(); |
|
|
|
const navigate = useNavigate() |
|
|
|
const dispatch = useAppDispatch(); |
|
|
|
const location = useLocation() |
|
|
|
const queryParams = new URLSearchParams(location.search); |
|
|
|
const dispatch = useAppDispatch() |
|
|
|
const id = queryParams.get('id') as string; |
|
|
|
const queryParams = new URLSearchParams(location.search) |
|
|
|
const stepId = Number(queryParams.get('stepId')); |
|
|
|
const id = queryParams.get('id') as string |
|
|
|
|
|
|
|
const stepId = Number(queryParams.get('stepId')) |
|
|
|
const { |
|
|
|
const { |
|
|
|
workshop: { detail, selectedId }, |
|
|
|
workshop: {detail, selectedId}, |
|
|
|
remixide: { errorLoadingFile, errors, success }, |
|
|
|
remixide: {errorLoadingFile, errors, success}, |
|
|
|
} = useAppSelector((state: any) => state); |
|
|
|
} = useAppSelector((state: any) => state) |
|
|
|
const entity = detail[selectedId].entities[id]; |
|
|
|
const entity = detail[selectedId].entities[id] |
|
|
|
const steps = entity.steps; |
|
|
|
const steps = entity.steps |
|
|
|
const step = steps[stepId]; |
|
|
|
const step = steps[stepId] |
|
|
|
console.log(step); |
|
|
|
console.log(step) |
|
|
|
|
|
|
|
|
|
|
|
useEffect(() => { |
|
|
|
useEffect(() => { |
|
|
|
dispatch({ |
|
|
|
dispatch({ |
|
|
|
type: 'remixide/displayFile', |
|
|
|
type: 'remixide/displayFile', |
|
|
|
payload: step, |
|
|
|
payload: step, |
|
|
|
}); |
|
|
|
}) |
|
|
|
dispatch({ |
|
|
|
dispatch({ |
|
|
|
type: 'remixide/save', |
|
|
|
type: 'remixide/save', |
|
|
|
payload: { errors: [], success: false }, |
|
|
|
payload: {errors: [], success: false}, |
|
|
|
}); |
|
|
|
}) |
|
|
|
window.scrollTo(0, 0); |
|
|
|
window.scrollTo(0, 0) |
|
|
|
}, [step]); |
|
|
|
}, [step]) |
|
|
|
|
|
|
|
|
|
|
|
useEffect(() => { |
|
|
|
useEffect(() => { |
|
|
|
if (errors.length > 0 || success) { |
|
|
|
if (errors.length > 0 || success) { |
|
|
|
window.scrollTo(0, document.documentElement.scrollHeight); |
|
|
|
window.scrollTo(0, document.documentElement.scrollHeight) |
|
|
|
} |
|
|
|
} |
|
|
|
}, [errors, success]); |
|
|
|
}, [errors, success]) |
|
|
|
|
|
|
|
|
|
|
|
return ( |
|
|
|
return ( |
|
|
|
<> |
|
|
|
<> |
|
|
@ -57,7 +58,7 @@ function StepDetailPage() { |
|
|
|
dispatch({ |
|
|
|
dispatch({ |
|
|
|
type: 'remixide/displayFile', |
|
|
|
type: 'remixide/displayFile', |
|
|
|
payload: step, |
|
|
|
payload: step, |
|
|
|
}); |
|
|
|
}) |
|
|
|
}} |
|
|
|
}} |
|
|
|
> |
|
|
|
> |
|
|
|
Load the file |
|
|
|
Load the file |
|
|
@ -71,9 +72,7 @@ function StepDetailPage() { |
|
|
|
</> |
|
|
|
</> |
|
|
|
)} |
|
|
|
)} |
|
|
|
<div className="container-fluid"> |
|
|
|
<div className="container-fluid"> |
|
|
|
<Markdown rehypePlugins={[rehypeRaw]}> |
|
|
|
<Markdown rehypePlugins={[rehypeRaw]}>{step.markdown?.content}</Markdown> |
|
|
|
{step.markdown?.content} |
|
|
|
|
|
|
|
</Markdown> |
|
|
|
|
|
|
|
</div> |
|
|
|
</div> |
|
|
|
{step.test?.content ? ( |
|
|
|
{step.test?.content ? ( |
|
|
|
<> |
|
|
|
<> |
|
|
@ -85,7 +84,7 @@ function StepDetailPage() { |
|
|
|
dispatch({ |
|
|
|
dispatch({ |
|
|
|
type: 'remixide/displayFile', |
|
|
|
type: 'remixide/displayFile', |
|
|
|
payload: step, |
|
|
|
payload: step, |
|
|
|
}); |
|
|
|
}) |
|
|
|
}} |
|
|
|
}} |
|
|
|
> |
|
|
|
> |
|
|
|
Load the file |
|
|
|
Load the file |
|
|
@ -100,7 +99,7 @@ function StepDetailPage() { |
|
|
|
dispatch({ |
|
|
|
dispatch({ |
|
|
|
type: 'remixide/testStep', |
|
|
|
type: 'remixide/testStep', |
|
|
|
payload: step, |
|
|
|
payload: step, |
|
|
|
}); |
|
|
|
}) |
|
|
|
}} |
|
|
|
}} |
|
|
|
> |
|
|
|
> |
|
|
|
Check Answer |
|
|
|
Check Answer |
|
|
@ -112,7 +111,7 @@ function StepDetailPage() { |
|
|
|
dispatch({ |
|
|
|
dispatch({ |
|
|
|
type: 'remixide/showAnswer', |
|
|
|
type: 'remixide/showAnswer', |
|
|
|
payload: step, |
|
|
|
payload: step, |
|
|
|
}); |
|
|
|
}) |
|
|
|
}} |
|
|
|
}} |
|
|
|
> |
|
|
|
> |
|
|
|
Show answer |
|
|
|
Show answer |
|
|
@ -126,11 +125,7 @@ function StepDetailPage() { |
|
|
|
<button |
|
|
|
<button |
|
|
|
className="nav-item rounded-0 nav-link btn btn-success test" |
|
|
|
className="nav-item rounded-0 nav-link btn btn-success test" |
|
|
|
onClick={() => { |
|
|
|
onClick={() => { |
|
|
|
navigate( |
|
|
|
navigate(stepId === steps.length - 1 ? `/list?id=${id}` : `/detail?id=${id}&stepId=${stepId + 1}`) |
|
|
|
stepId === steps.length - 1 |
|
|
|
|
|
|
|
? `/list?id=${id}` |
|
|
|
|
|
|
|
: `/detail?id=${id}&stepId=${stepId + 1}`, |
|
|
|
|
|
|
|
); |
|
|
|
|
|
|
|
}} |
|
|
|
}} |
|
|
|
> |
|
|
|
> |
|
|
|
Next |
|
|
|
Next |
|
|
@ -142,7 +137,7 @@ function StepDetailPage() { |
|
|
|
dispatch({ |
|
|
|
dispatch({ |
|
|
|
type: 'remixide/showAnswer', |
|
|
|
type: 'remixide/showAnswer', |
|
|
|
payload: step, |
|
|
|
payload: step, |
|
|
|
}); |
|
|
|
}) |
|
|
|
}} |
|
|
|
}} |
|
|
|
> |
|
|
|
> |
|
|
|
Show answer |
|
|
|
Show answer |
|
|
@ -159,11 +154,7 @@ function StepDetailPage() { |
|
|
|
<button |
|
|
|
<button |
|
|
|
className="w-100 rounded-0 nav-item nav-link btn btn-success" |
|
|
|
className="w-100 rounded-0 nav-item nav-link btn btn-success" |
|
|
|
onClick={() => { |
|
|
|
onClick={() => { |
|
|
|
navigate( |
|
|
|
navigate(stepId === steps.length - 1 ? `/list?id=${id}` : `/detail?id=${id}&stepId=${stepId + 1}`) |
|
|
|
stepId === steps.length - 1 |
|
|
|
|
|
|
|
? `/list?id=${id}` |
|
|
|
|
|
|
|
: `/detail?id=${id}&stepId=${stepId + 1}`, |
|
|
|
|
|
|
|
); |
|
|
|
|
|
|
|
}} |
|
|
|
}} |
|
|
|
> |
|
|
|
> |
|
|
|
Next |
|
|
|
Next |
|
|
@ -171,28 +162,19 @@ function StepDetailPage() { |
|
|
|
)} |
|
|
|
)} |
|
|
|
<div id="errors"> |
|
|
|
<div id="errors"> |
|
|
|
{success && ( |
|
|
|
{success && ( |
|
|
|
<div |
|
|
|
<div className="alert rounded-0 alert-success mb-0 mt-0" role="alert"> |
|
|
|
className="alert rounded-0 alert-success mb-0 mt-0" |
|
|
|
|
|
|
|
role="alert" |
|
|
|
|
|
|
|
> |
|
|
|
|
|
|
|
Well done! No errors. |
|
|
|
Well done! No errors. |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
)} |
|
|
|
)} |
|
|
|
{errors.length > 0 && ( |
|
|
|
{errors.length > 0 && ( |
|
|
|
<> |
|
|
|
<> |
|
|
|
{!success && ( |
|
|
|
{!success && ( |
|
|
|
<div |
|
|
|
<div className="alert rounded-0 alert-danger mb-0 mt-0" role="alert"> |
|
|
|
className="alert rounded-0 alert-danger mb-0 mt-0" |
|
|
|
|
|
|
|
role="alert" |
|
|
|
|
|
|
|
> |
|
|
|
|
|
|
|
Errors |
|
|
|
Errors |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
)} |
|
|
|
)} |
|
|
|
{errors.map((error: string, index: number) => ( |
|
|
|
{errors.map((error: string, index: number) => ( |
|
|
|
<div |
|
|
|
<div key={index} className="alert rounded-0 alert-warning mb-0 mt-0"> |
|
|
|
key={index} |
|
|
|
|
|
|
|
className="alert rounded-0 alert-warning mb-0 mt-0" |
|
|
|
|
|
|
|
> |
|
|
|
|
|
|
|
{error} |
|
|
|
{error} |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
))} |
|
|
|
))} |
|
|
@ -210,7 +192,7 @@ function StepDetailPage() { |
|
|
|
dispatch({ |
|
|
|
dispatch({ |
|
|
|
type: 'remixide/showAnswer', |
|
|
|
type: 'remixide/showAnswer', |
|
|
|
payload: step, |
|
|
|
payload: step, |
|
|
|
}); |
|
|
|
}) |
|
|
|
}} |
|
|
|
}} |
|
|
|
> |
|
|
|
> |
|
|
|
Show answer |
|
|
|
Show answer |
|
|
@ -221,7 +203,7 @@ function StepDetailPage() { |
|
|
|
<button |
|
|
|
<button |
|
|
|
className="w-100 btn btn-success" |
|
|
|
className="w-100 btn btn-success" |
|
|
|
onClick={() => { |
|
|
|
onClick={() => { |
|
|
|
navigate(`/detail?id=${id}&stepId=${stepId + 1}`); |
|
|
|
navigate(`/detail?id=${id}&stepId=${stepId + 1}`) |
|
|
|
}} |
|
|
|
}} |
|
|
|
> |
|
|
|
> |
|
|
|
Next |
|
|
|
Next |
|
|
@ -231,7 +213,7 @@ function StepDetailPage() { |
|
|
|
<button |
|
|
|
<button |
|
|
|
className="w-100 btn btn-success" |
|
|
|
className="w-100 btn btn-success" |
|
|
|
onClick={() => { |
|
|
|
onClick={() => { |
|
|
|
navigate(`/list?id=${id}`); |
|
|
|
navigate(`/list?id=${id}`) |
|
|
|
}} |
|
|
|
}} |
|
|
|
> |
|
|
|
> |
|
|
|
Finish tutorial |
|
|
|
Finish tutorial |
|
|
@ -240,7 +222,7 @@ function StepDetailPage() { |
|
|
|
</> |
|
|
|
</> |
|
|
|
)} |
|
|
|
)} |
|
|
|
</> |
|
|
|
</> |
|
|
|
); |
|
|
|
) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
export default StepDetailPage; |
|
|
|
export default StepDetailPage |
|
|
|