diff --git a/src/models/flashCardsModel.ts b/src/models/flashCardsModel.ts index 250d0ccd..fc081d81 100644 --- a/src/models/flashCardsModel.ts +++ b/src/models/flashCardsModel.ts @@ -19,7 +19,7 @@ export interface sessionTrainingData { numberOfTimesWrittenFast: number; numberOfTimesWrittenWrong: number; lastTenTimesSpeed: number[]; - completed: boolean; + completed: boolean | null; } export interface generatedData { @@ -62,6 +62,11 @@ export interface flashCardActionModel { loadNextDailyTraining: Action; setSessionTrainingData: Action; + setInfiniteSessionTrainingData: Action< + flashCardStoreStateModel, + activeFlashCard[] + >; + mergeSessionTrainingData: Action; addTimeSessionTrainingData: Action; fetchUserData: Thunk; diff --git a/src/pages/concepts-page/ConceptsPage.styled.tsx b/src/pages/concepts-page/ConceptsPage.styled.tsx index 73ed07ca..908849bf 100644 --- a/src/pages/concepts-page/ConceptsPage.styled.tsx +++ b/src/pages/concepts-page/ConceptsPage.styled.tsx @@ -19,5 +19,5 @@ export const PageContainer = styled.div.attrs({ className: 'text-gray-600 body-font flex flex-row', })` background-color: #222424; - ${height} + min-height: ${height}; `; diff --git a/src/pages/concepts-page/custom-training-tier/CustomTrainingTier.styled.tsx b/src/pages/concepts-page/custom-training-tier/CustomTrainingTier.styled.tsx index d31d09ca..33983906 100644 --- a/src/pages/concepts-page/custom-training-tier/CustomTrainingTier.styled.tsx +++ b/src/pages/concepts-page/custom-training-tier/CustomTrainingTier.styled.tsx @@ -7,3 +7,19 @@ export const FullWidthFullHeightContainer = styled.div.attrs({ export const SmallScreenButtons = styled.div.attrs({ className: 'flex flex-row justify-between w-full mb-4', })``; + +export const FinishTrainingButton = styled.button.attrs({ + className: + 'import sc-bYwzuL text-white rounded p-2 mb-4 inline-block ml-2 bg-[#333] hover:bg-[#3b3b3b] active:bg-[#222] position-relative', +})` + font-size: 1.2rem; + width: 150px; + height: 50px; +`; + +export const ButtonContainer = styled.div.attrs({ + className: ` + text-md font-bold mt-12 flex flex-col items-center w-full justify-center text-white + sm:text-xl md:text-2xl xl:mt-12 content:center + `, +})``; diff --git a/src/pages/concepts-page/custom-training-tier/CustomTrainingTier.tsx b/src/pages/concepts-page/custom-training-tier/CustomTrainingTier.tsx index 173ef33e..ef7407cc 100644 --- a/src/pages/concepts-page/custom-training-tier/CustomTrainingTier.tsx +++ b/src/pages/concepts-page/custom-training-tier/CustomTrainingTier.tsx @@ -6,7 +6,10 @@ import { TrainingComponent } from '../trainingComponent/TrainingComponent'; import { FullWidthFullHeightContainer, SmallScreenButtons, + ButtonContainer, + FinishTrainingButton, } from './CustomTrainingTier.styled'; +import { useStoreActions } from '../../../store/store'; interface CustomTrainingTierProps { setCurrentTier: (tier: number) => void; @@ -15,15 +18,23 @@ interface CustomTrainingTierProps { export const CustomTrainingTier = ({ setCurrentTier, }: CustomTrainingTierProps) => { + const mergeSessionTrainingData = useStoreActions( + (actions) => actions.mergeSessionTrainingData, + ); + const [activeTraining, setActiveTraining] = useState(false); const startTraining = () => { setActiveTraining(true); }; + const finishTraining = () => { + mergeSessionTrainingData(); + setActiveTraining(false); + }; + return ( - Under Construction {activeTraining ? ( <> @@ -31,7 +42,12 @@ export const CustomTrainingTier = ({ - + + + finishTraining()}> + Finish Training + + ) : ( diff --git a/src/pages/concepts-page/custom-training-tier/CustomTrainingWelcome.styled.tsx b/src/pages/concepts-page/custom-training-tier/CustomTrainingWelcome.styled.tsx index 1b9bbcc6..362274da 100644 --- a/src/pages/concepts-page/custom-training-tier/CustomTrainingWelcome.styled.tsx +++ b/src/pages/concepts-page/custom-training-tier/CustomTrainingWelcome.styled.tsx @@ -4,7 +4,6 @@ export const FlexContainer = styled.div` display: flex; flex-direction: column; align-items: center; - padding-top: 50px; `; export const Header = styled.h1` diff --git a/src/pages/concepts-page/custom-training-tier/CustomTrainingWelcome.tsx b/src/pages/concepts-page/custom-training-tier/CustomTrainingWelcome.tsx index 19c345ac..3368b579 100644 --- a/src/pages/concepts-page/custom-training-tier/CustomTrainingWelcome.tsx +++ b/src/pages/concepts-page/custom-training-tier/CustomTrainingWelcome.tsx @@ -1,5 +1,5 @@ import React, { useState } from 'react'; -import { useStoreState } from '../../../store/store'; +import { useStoreState, useStoreActions } from '../../../store/store'; import { TagSelection } from './TagSelection'; import { FlexContainer, @@ -11,6 +11,7 @@ import { ActionButton, BeginButton, } from './CustomTrainingWelcome.styled'; +import type { activeFlashCard } from 'src/models/flashCardsModel'; interface CustomTrainingWelcomeProps { setActiveTraining: () => void; @@ -20,11 +21,34 @@ export const CustomTrainingWelcome = ({ setActiveTraining, }: CustomTrainingWelcomeProps) => { const tags = useStoreState((state) => state.tags); + const setInfiniteSessionTrainingData = useStoreActions( + (actions) => actions.setInfiniteSessionTrainingData, + ); + const flashCards = useStoreState((state) => state.flashCards); const [unSelectedTags, setUnSelectedTags] = useState( Object.keys(tags), ); - const [selectedTags, setSelectedTags] = useState(['hello']); + const [selectedTags, setSelectedTags] = useState([]); + + const startTraining = () => { + if (selectedTags.length != 0) { + const filteredFlashCards: activeFlashCard[] = []; + flashCards.forEach((flashCard, index) => { + for (const tag of selectedTags) { + if (flashCard.tags.includes(tag)) { + filteredFlashCards.push({ + flashCard: flashCard, + flashCardIndex: index, + }); + break; + } + } + }); + setInfiniteSessionTrainingData(filteredFlashCards); + setActiveTraining(); + } + }; const switchTag = (tag: string, selected: boolean) => { if (selected == true) { @@ -78,7 +102,7 @@ export const CustomTrainingWelcome = ({ /> - setActiveTraining()}> + startTraining()}> Begin Training diff --git a/src/pages/concepts-page/manager-tier/DialogPortal.tsx b/src/pages/concepts-page/manager-tier/DialogPortal.tsx index ec266879..90536ad6 100644 --- a/src/pages/concepts-page/manager-tier/DialogPortal.tsx +++ b/src/pages/concepts-page/manager-tier/DialogPortal.tsx @@ -12,7 +12,6 @@ export const DialogPortal = ({ selectedFlashcardIndices, }: DialogPortalProps) => { const addTagFlashCard = useStoreActions((state) => state.addTagFlashCard); - const tags = useStoreState((state) => state.tags); const updatedFlashCards = useStoreState((state) => state.flashCards); const [showModal, setShowModal] = useState(false); @@ -27,6 +26,7 @@ export const DialogPortal = ({ const handleAddTag = () => { console.log('Adding tag:', input); + console.log('happening'); selectedFlashcardIndices.forEach((index) => { addTagFlashCard({ key: input, index }); diff --git a/src/pages/concepts-page/manager-tier/FlashCard.tsx b/src/pages/concepts-page/manager-tier/FlashCard.tsx index 01696b58..9373fddb 100644 --- a/src/pages/concepts-page/manager-tier/FlashCard.tsx +++ b/src/pages/concepts-page/manager-tier/FlashCard.tsx @@ -71,9 +71,19 @@ export const FlashCard = ({ const onSelectedChange = (selected: string) => { if (selected === 'text') { - setNewFlashCard({ ...newFlashCard, type: 'text', imageSrc: '' }); + setNewFlashCard({ + ...newFlashCard, + type: 'text', + question: newFlashCard.answer, + imageSrc: '', + }); } else if (selected === 'translation') { - setNewFlashCard({ ...newFlashCard, type: 'translation', imageSrc: '' }); + setNewFlashCard({ + ...newFlashCard, + type: 'translation', + question: newFlashCard.answer, + imageSrc: '', + }); } else if (selected === 'image') { setNewFlashCard({ ...newFlashCard, type: 'image', question: '' }); } @@ -138,9 +148,17 @@ export const FlashCard = ({ - setNewFlashCard({ ...newFlashCard, answer: e.target.value }) - } + onChange={(e) => { + if (newFlashCard.type === 'text') { + setNewFlashCard({ + ...newFlashCard, + answer: e.target.value, + question: e.target.value, + }); + } else { + setNewFlashCard({ ...newFlashCard, answer: e.target.value }); + } + }} value={newFlashCard.answer} //value = {questionInput} /> diff --git a/src/pages/concepts-page/trainingComponent/TrainingComponent.tsx b/src/pages/concepts-page/trainingComponent/TrainingComponent.tsx index e63870ca..de3ed027 100644 --- a/src/pages/concepts-page/trainingComponent/TrainingComponent.tsx +++ b/src/pages/concepts-page/trainingComponent/TrainingComponent.tsx @@ -36,8 +36,9 @@ export function TrainingComponent({ useEffect(() => { const filteredSessionData = sessionTrainingData.filter( - (item) => item.completed == false, + (item) => item.completed == false || item.completed == null, ); + console.log(trainingData); if (filteredSessionData.length != 0) { if (itemsInSession != filteredSessionData.length) { setTrainingData([ diff --git a/src/pages/concepts-page/util/generateTrainingData.ts b/src/pages/concepts-page/util/generateTrainingData.ts index 7efc6f20..10fe4996 100644 --- a/src/pages/concepts-page/util/generateTrainingData.ts +++ b/src/pages/concepts-page/util/generateTrainingData.ts @@ -8,7 +8,7 @@ const numberItemsToGenerate = 20; const generateTrainingData = (sessionTrainingData: sessionTrainingData[]) => { const filteredSessionTrainingData: number[] = []; sessionTrainingData.forEach((card, index) => { - if (card.completed === false) { + if (card.completed === false || card.completed === null) { filteredSessionTrainingData.push(index); } }); diff --git a/src/store/flashCardStore/action.ts b/src/store/flashCardStore/action.ts index 96e59671..a27ce69a 100644 --- a/src/store/flashCardStore/action.ts +++ b/src/store/flashCardStore/action.ts @@ -3,7 +3,6 @@ import type { flashCardActionModel, sessionTrainingData, flashCard, - tag, } from '../../models/flashCardsModel'; const flashCardStoreActions: flashCardActionModel = { @@ -58,7 +57,9 @@ const flashCardStoreActions: flashCardActionModel = { addTagFlashCard: action((state, payload) => { const { key, index } = payload; - state.flashCards[index].tags.push(key); + if (!state.flashCards[index].tags.includes(key)) { + state.flashCards[index].tags.push(key); + } if (!(key in state.tags)) { state.tags[key] = []; } @@ -68,6 +69,7 @@ const flashCardStoreActions: flashCardActionModel = { }), setSelectedTag: action((state, payload) => { + console.log('Setting a tag'); state.selectedTags = payload; }), @@ -90,12 +92,10 @@ const flashCardStoreActions: flashCardActionModel = { state.nextTrainingDate = currentDate; - console.log(currentDate.getTime()); localStorage.setItem('nextDailyTraining', currentDate.getTime().toString()); }), loadNextDailyTraining: action((state, payload) => { - console.log(payload); state.nextTrainingDate = payload; }), @@ -126,6 +126,39 @@ const flashCardStoreActions: flashCardActionModel = { state.sessionTrainingData = sessionTrainingData; }), + setInfiniteSessionTrainingData: action((state, payload) => { + const activeFlashCards = payload; + const sessionTrainingData: sessionTrainingData[] = []; + + while (activeFlashCards.length != 0) { + const randomIndex = Math.floor(Math.random() * activeFlashCards.length); + const randomFlashCard = activeFlashCards[randomIndex].flashCard; + + sessionTrainingData.push({ + flashCard: randomFlashCard, + flashCardIndex: activeFlashCards[randomIndex].flashCardIndex, + numberOfTimesWritten: 0, + numberOfTimesWrittenFast: 0, + numberOfTimesWrittenWrong: 0, + lastTenTimesSpeed: [], + completed: null, + }); + + activeFlashCards.splice(randomIndex, 1); + } + state.sessionTrainingData = sessionTrainingData; + }), + + mergeSessionTrainingData: action((state) => { + state.sessionTrainingData.forEach((card) => { + state.flashCards[card.flashCardIndex].timesTyped += + card.numberOfTimesWritten; + state.flashCards[card.flashCardIndex].timesErrored += + card.numberOfTimesWrittenWrong; + }); + state.sessionTrainingData = []; + }), + addTimeSessionTrainingData: action((state, payload) => { const index = payload[0]; const time = payload[1]; @@ -147,8 +180,9 @@ const flashCardStoreActions: flashCardActionModel = { state.sessionTrainingData[index].numberOfTimesWritten++; if ( - state.sessionTrainingData[index].numberOfTimesWritten >= 6 || - state.sessionTrainingData[index].numberOfTimesWrittenFast >= 10 + state.sessionTrainingData[index].completed != null && + (state.sessionTrainingData[index].numberOfTimesWritten >= 6 || + state.sessionTrainingData[index].numberOfTimesWrittenFast >= 10) ) { state.sessionTrainingData[index].completed = true; const flashCardIndex = state.sessionTrainingData[index].flashCardIndex;