Skip to content

Commit

Permalink
Merge pull request #220 from hampster2018/latest_branch
Browse files Browse the repository at this point in the history
Merged latest UTD changes to Development Branch for Beta test
  • Loading branch information
jdestgermain authored Nov 9, 2023
2 parents 136f733 + a7d7f92 commit 64ba183
Show file tree
Hide file tree
Showing 122 changed files with 34,759 additions and 17,599 deletions.
45,263 changes: 27,724 additions & 17,539 deletions package-lock.json

Large diffs are not rendered by default.

11 changes: 9 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,15 @@
"@popperjs/core": "^2.11.0",
"@snowpack/plugin-typescript": "^1.2.1",
"@types/node": "^20.4.8",
"@uiw/react-heat-map": "^2.2.0",
"@uiw/react-tooltip": "^4.22.0",
"apexcharts": "^3.32.1",
"axios": "^1.4.0",
"bootstrap": "^5.1.3",
"chart.js": "^3.7.0",
"chart.js": "^3.9.1",
"dotenv": "^16.3.1",
"easy-peasy": "^5.0.4",
"gridjs": "^6.0.6",
"hex-to-bin": "^1.0.1",
"hex-to-binary": "^1.0.1",
"midi-note": "^1.0.0",
Expand All @@ -29,9 +32,13 @@
"react-accordion-with-header": "^0.1.3",
"react-apexcharts": "^1.3.9",
"react-bootstrap": "^2.1.0",
"react-chartjs-2": "^4.0.0",
"react-chartjs-2": "^4.3.1",
"react-dom": "^17.0.2",
"react-dropdown": "^1.11.0",
"react-fade-in": "^2.0.1",
"react-icons": "^4.7.1",
"react-native-dropdown-picker": "^5.4.6",
"react-native-element-dropdown": "^2.10.0",
"react-piano": "^3.1.3",
"react-popper": "^2.2.5",
"react-portal": "^4.2.1",
Expand Down
Binary file added src/assets/AnalyticalDashboard.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 10 additions & 0 deletions src/components/hamburgerMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,16 @@ export default function HamburgerMenu() {
if (!history.location.pathname.endsWith(ROUTER_PATHS.home)) {
history.push(ROUTER_PATHS.home);
}
} else if (level == 'CM') {
setModuleNumber(1);
const payload: any[] = [];
payload.push('');
sessionStorage.removeItem('tempTestDeIncrement');
setTrainingLevel('CM');
beginTraining(payload);
if (!history.location.pathname.endsWith(ROUTER_PATHS.home)) {
history.push(ROUTER_PATHS.home);
}
}
}
}
Expand Down
89 changes: 77 additions & 12 deletions src/components/navbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,16 @@ import CPM_Icon from '../assets/CPM_icon.png';
import Crown_Icon from '../assets/Crown_icon.png';
import StM_Icon from '../assets/StM.png';
import tWPM_Icon from '../assets/tWPM.png';
import analytic_DashIcon from '../assets/AnalyticalDashboard.png';
import LockIconWhite from '../../src/pages/test/components/LockIconWhite';
import ConstructionIconWhite from '../../src/pages/test/components/ConstructionIconWhite';
import { ScoresComponent } from './scoresComponent';
import InfoIcon from '../../src/pages/test/components/InfoIcon';
import type { TrainingLevels } from '../../src/models/trainingLevels';
import Circle from './CircleHighlight';
import AnalyticalDashboardButton from '../../src/pages/test/components/AnalyticalDashboardButton';
import HamburgerMenu from './hamburgerMenu';
//import ConceptsPage from 'src/pages/concepts-page/concepts-page';

const Navbar = (): ReactElement => {
const history = useHistory();
Expand Down Expand Up @@ -92,7 +95,18 @@ const Navbar = (): ReactElement => {
if (!history.location.pathname.endsWith(ROUTER_PATHS.home)) {
history.push(ROUTER_PATHS.home);
}
} else if (level == 'CM') {
setModuleNumber(1);
const payload: any[] = [];
payload.push('CONCEPTSMASTERED');
sessionStorage.removeItem('tempTestDeIncrement');
setTrainingLevel('CM');
beginTraining(payload);
if (!history.location.pathname.endsWith(ROUTER_PATHS.home)) {
history.push(ROUTER_PATHS.home);
}
}
console.log('training level: ', trainingLevel);
}
}
function triggerPasswordModal() {
Expand Down Expand Up @@ -170,17 +184,36 @@ const Navbar = (): ReactElement => {
<NavLinksImage open={false} src={tWPM_Icon} alt="" />
</NavMenuLink>
<NavMenuLink aria-current="page">
<ConstructionIconStyle>
<ConstructionIconWhite />
</ConstructionIconStyle>
<NavLinksImage open={false} src={CM_Icon} alt="" />
{trainingLevel == 'CM' ? <Circle /> : ''}
<div className="text-white font-mono">CM</div>
<NavLinksImage
open={true}
src={CM_Icon}
alt=""
onClick={() => (window.location.href = '#/concepts-page')}
/>
</NavMenuLink>
</NavMenu>
<ScoresComponent />

<div className="flex-row">
<NavMenuLink style={{ paddingTop: '100px' }}>
<NavLinksBtnImage
href="#/analyticalDashboard"
onClick={() => setTrainingLevel('')}
>
<img
src={analytic_DashIcon}
style={{ width: '40px', height: '50px', paddingTop: '10px' }}
></img>
</NavLinksBtnImage>
</NavMenuLink>
</div>
<NavBtn>
<NavMenuLink aria-current="page">
<NavLinksImage open={false} src={Crown_Icon} alt="" />
</NavMenuLink>

<NavBtnLink href="#/manager" onClick={() => setTrainingLevel('')}>
<div className="text-white">Manager</div>
</NavBtnLink>
Expand Down Expand Up @@ -211,7 +244,7 @@ const LogoLink = styled.a.attrs({
})``;

const NavMenuLink = styled.a.attrs({
className: `py-1 rounded-md hover:bg-[#333]`,
className: `py-1 items-center relative rounded-md hover:bg-[#333] align-center`,
})``;

const NavI = styled.nav`
Expand All @@ -232,13 +265,13 @@ const NavI = styled.nav`
`;

const NavbarContainer = styled.div`
display: flex;
justify-content: space-between;
height: 63px;
z-index: 1;
width: 100%;
padding 0 24px;
max-width: 1100px;
display: flex;
justify-content: space-between;
height: 63px;
z-index: 1;
width: 100%;
padding 0 24px;
max-width: 1100px;
`;

const NavLogo = styled.div`
Expand Down Expand Up @@ -298,6 +331,20 @@ const NavLinksImage = styled.img<{ open: boolean }>`
}
`;

const NavLinksBtnImage = styled.a`
align-items: center;
color: #fff;
display: relative;
cursor: pointer;
color: #fff;
justify-content: center;
justify-self: flex-start;
@media screen and (max-width: 1000px) {
display: none;
}
`;

const NavLinksImageTransparent = styled.img`
color: #fff;
display: flex;
Expand Down Expand Up @@ -343,3 +390,21 @@ const NavBtnLink = styled.a`
transition: 0.3s ease out;
}
`;

const ConBtnLink = styled.a`
radius: 50px;
white-space: nowrap;
color: #222424;
font-size: 16px;
outline: none;
border: 1px solid white;
cursor: pointer;
transition: all 0.2s ease-in-out;
text-decoration: none;
&:hover {
color: #ffff;
background: #01a049;
transition: 0.3s ease out;
}
`;
17 changes: 17 additions & 0 deletions src/components/router.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,23 @@ import Dashboard from '../pages/dashboard/dashboard';
import Manager from '../pages/manager/manager';
import Navbar from './navbar';
import TrainingTestPage from '../pages/test/trainingTest';
import AnalyticalDashboard from '../pages/analyticalDashboard/analyticalDashboard';
import TrainingPage from '../pages/training/training';
import { ClosingPrompt } from './closingPrompt';
import Piano from '../pages/piano/piano';
import Footer from './footer';
import TestCompletePage from '../../src/pages/test-complete/testComplete';
import ConceptsPage from '../pages/concepts-page/concepts-page';

export const ROUTER_PATHS = {
home: '/',
training: '/training',
manager: '/manager',
analyticalDashboard: '/analyticalDashboard',
piano: '/piano',
dashboard: '/dashboard',
results: '/results',
concepts_page: '/concepts-page',
};

/**
Expand Down Expand Up @@ -62,6 +66,19 @@ const Router = (): ReactElement => {
<Manager />
</Route>

{/* This is the route to the analytical dashbord page */}
<Route path={ROUTER_PATHS.analyticalDashboard}>
<Navbar />
<AnalyticalDashboard />
</Route>

{/* This is the route to the concepts manager page */}
<Route path={ROUTER_PATHS.concepts_page}>
<Navbar />
<ConceptsPage />
<Footer />
</Route>

{/* This is the route to the Chara Piano page. */}
<Route path={ROUTER_PATHS.piano}>
<Navbar />
Expand Down
7 changes: 7 additions & 0 deletions src/components/scoresComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React, { ReactElement } from 'react';
import styled from 'styled-components';
import { useStoreState } from 'easy-peasy';
import { wpmMethodCalculatorForStoredChords } from '../../src/helpers/aggregation';
import store from '../store/store';

export function ScoresComponent(): ReactElement {
const maxWPM = useStoreState((store) => store.fastestRecordedWordsPerMinute);
Expand All @@ -26,6 +27,12 @@ export function ScoresComponent(): ReactElement {
}
`;

const CPMTSpeed = parseInt(
Math.max.apply(Math, Object.values(maxWPM))?.toFixed(),
);
console.log('CPM Top Speed: ' + CPMTSpeed);
store.getActions().addCPMTopSpeed(CPMTSpeed);

return (
<React.Fragment>
<HideWhenScreenGetSmallEnough>
Expand Down
47 changes: 47 additions & 0 deletions src/models/flashCardStatistics.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
export interface FlashcardStatistics {
id: string; // Unique identifier for the flashcard
question: string; // The flashcard question
numberOfErrors: number; // Number of errors made with this flashcard
numberOfOccurrences: number; // Number of times the flashcard has been encountered
}

export const createFlashcardStatistics = (
id: string,
question: string,
initialErrors = 0,
initialOccurrences = 0,
): FlashcardStatistics => {
return {
id,
question,
numberOfErrors: initialErrors,
numberOfOccurrences: initialOccurrences,
};
};

export const flashcardStats: FlashcardStatistics[] = [
{
id: '1',
question: 'hello',
numberOfErrors: 1,
numberOfOccurrences: 2,
// Other properties...
},

{
id: '2',
question: 'chicken?',
numberOfErrors: 2,
numberOfOccurrences: 2,
// Other properties...
},

{
id: '3',
question: 'null?',
numberOfErrors: 2,
numberOfOccurrences: 2,
// Other properties...
},
// Other FlashcardStatistics objects...
];
81 changes: 81 additions & 0 deletions src/models/flashCardsModel.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import type { Action, Computed, Thunk } from 'easy-peasy';

export interface flashCard {
type: 'text' | 'image' | 'translation';
question: string;
answer: string;
imageSrc: string;
tags: string[];
url: string;
image: string;
ebbinghausValue: number;
nextReinforcement: number;
timesTyped: number;
timesErrored: number;
}

export interface sessionTrainingData {
flashCard: flashCard;
numberOfTimesWritten: number;
numberOfTimesWrittenFast: number;
numberOfTimesWrittenWrong: number;
lastTenTimesSpeed: number[];
}

export interface generatedData {
flashCard: flashCard;
sessionTrainingIndex: number;
}

export interface tag {
key: string;
index: number | undefined;
}

export interface flashCardActionModel {
setLoadedFromStorage: Action<flashCardStoreStateModel>;
updateLocalStorage: Action<flashCardStoreStateModel>;

// Actions to add and remove cards from the active flash card set
addFlashCard: Action<flashCardStoreStateModel, flashCard>;
addEmptyFlashCard: Action<flashCardStoreStateModel>;
removeFlashCard: Action<flashCardStoreStateModel, number>;
editFlashCard: Action<
flashCardStoreStateModel,
{ index: number; newFlashCard: flashCard }
>;

// Actions to add and remove tags from the tag set
addTagFlashCard: Action<flashCardStoreStateModel, tag>;
removeTagFlashCard: Action<flashCardStoreStateModel, tag>;

// Actions to get and set the last daily training date of a set
setNextDailyTraining: Action<flashCardStoreStateModel, Date>;

setSessionTrainingData: Action<flashCardStoreStateModel>;
addTimeSessionTrainingData: Action<flashCardStoreStateModel, number[]>;

fetchUserData: Thunk<flashCardActionModel>;
}

export interface flashCardStoreStateModel {
loadedFromStorage: boolean;

// All current flash card sets
flashCards: flashCard[];
tags: { [key: string]: number[] };

sessionTrainingData: sessionTrainingData[];

nextTrainingDate: Date;

// Number of flash cards to practice daily
numberOfDailyFlashCards: number;

activeFlashCards: Computed<flashCardStoreStateModel, flashCard[]>;

percentageCompleted: Computed<flashCardStoreStateModel, number>;
}

export type FlashCardStoreModel = flashCardStoreStateModel &
flashCardActionModel;
Loading

0 comments on commit 64ba183

Please sign in to comment.