Hooked training content to backend, did refactors to training components and record.tsx

This commit is contained in:
Carlos Mesquita
2024-08-01 20:40:31 +01:00
parent a534126c61
commit a71e6632d6
13 changed files with 1243 additions and 821 deletions

View File

@@ -2,24 +2,10 @@ import React, { useState, useEffect, useRef, useCallback } from 'react';
import { animated } from '@react-spring/web';
import { FaRegCirclePlay, FaRegCircleStop } from "react-icons/fa6";
import HighlightedContent from './AnimatedHighlight';
import { SegmentRef, TimelineEvent, WalkthroughConfigs } from './TrainingInterfaces';
import { ITrainingTip, SegmentRef, TimelineEvent } from './TrainingInterfaces';
interface ExerciseWalkthroughProps {
highlightable: string;
walkthrough: WalkthroughConfigs[];
question: string;
tip: {
category: string;
body: string;
};
}
const ExerciseWalkthrough: React.FC<ExerciseWalkthroughProps> = ({
highlightable,
walkthrough,
question,
tip
}) => {
const ExerciseWalkthrough: React.FC<ITrainingTip> = (tip: ITrainingTip) => {
const [isAutoPlaying, setIsAutoPlaying] = useState<boolean>(false);
const [currentTime, setCurrentTime] = useState<number>(0);
const [walkthroughHtml, setWalkthroughHtml] = useState<string>('');
@@ -47,8 +33,9 @@ const ExerciseWalkthrough: React.FC<ExerciseWalkthroughProps> = ({
}, []);
const getMaxTime = (): number => {
return walkthrough.reduce((sum, segment) =>
sum + segment.wordDelay * segment.html.split(/\s+/).length + segment.holdDelay, 0);
return tip.exercise?.segments.reduce((sum, segment) =>
sum + segment.wordDelay * segment.html.split(/\s+/).length + segment.holdDelay, 0
) ?? 0;
};
useEffect(() => {
@@ -56,7 +43,7 @@ const ExerciseWalkthrough: React.FC<ExerciseWalkthroughProps> = ({
let currentTimePosition = 0;
segmentsRef.current = [];
walkthrough.forEach((segment, index) => {
tip.exercise?.segments.forEach((segment, index) => {
const parser = new DOMParser();
const doc = parser.parseFromString(segment.html, 'text/html');
const words: string[] = [];
@@ -99,7 +86,7 @@ const ExerciseWalkthrough: React.FC<ExerciseWalkthroughProps> = ({
});
timelineRef.current = timeline;
}, [walkthrough]);
}, [tip.exercise?.segments]);
const updateText = useCallback(() => {
const currentEvent = timelineRef.current.find(
@@ -231,11 +218,24 @@ const ExerciseWalkthrough: React.FC<ExerciseWalkthroughProps> = ({
}
};
if (tip.standalone || !tip.exercise) {
return (
<div className="container mx-auto">
<h1 className='text-xl font-bold text-red-600'>The exercise for this tip is not available yet!</h1>
<div className="tip-container bg-blue-100 p-4 rounded-lg shadow-md mb-4 mt-10">
<h3 className="text-xl font-semibold text-blue-800 mb-2">{tip.tipCategory}</h3>
<div className="text-gray-700" dangerouslySetInnerHTML={{ __html: tip.tipHtml }} />
</div>
</div>
);
}
return (
<div className="container mx-auto">
<div className="tip-container bg-blue-100 p-4 rounded-lg shadow-md mb-4">
<h3 className="text-xl font-semibold text-blue-800 mb-2">{tip.category}</h3>
<div className="text-gray-700" dangerouslySetInnerHTML={{ __html: tip.body }} />
<h3 className="text-xl font-semibold text-blue-800 mb-2">{tip.tipCategory}</h3>
<div className="text-gray-700" dangerouslySetInnerHTML={{ __html: tip.tipHtml }} />
</div>
<div className='flex flex-col space-y-4'>
<div className='flex flex-row items-center space-x-4 py-4'>
@@ -266,8 +266,8 @@ const ExerciseWalkthrough: React.FC<ExerciseWalkthroughProps> = ({
<div className='flex flex-col md:flex-row space-y-4 md:space-y-0 md:space-x-4'>
<div className='flex-1 bg-white p-6 rounded-lg shadow'>
{/*<h2 className="text-xl font-bold mb-4">Question</h2>*/}
<div className="mb-4" dangerouslySetInnerHTML={{ __html: question }} />
<HighlightedContent html={highlightable} highlightPhrases={highlightedPhrases} />
<div className="mb-4" dangerouslySetInnerHTML={{ __html: tip.exercise.question }} />
<HighlightedContent html={tip.exercise.highlightable} highlightPhrases={highlightedPhrases} />
</div>
<div className='flex-1'>
<div className='bg-gray-50 rounded-lg shadow'>