Skip to content
Open
Show file tree
Hide file tree
Changes from 13 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions front/global.types.d.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
declare module '*.png';
declare module '*.svg';
declare module '*.css';
Comment thread
Franlop7 marked this conversation as resolved.
Outdated
2,829 changes: 2,795 additions & 34 deletions front/package-lock.json

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions front/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,21 @@
"license": "MIT",
"homepage": "",
"dependencies": {
"@codemirror/language-data": "^6.1.0",
"@emotion/css": "^11.10.5",
"@emotion/react": "^11.10.5",
"@emotion/styled": "^11.10.5",
"@mui/icons-material": "^5.11.0",
"@mui/material": "^5.11.8",
"axios": "^1.3.2",
"codemirror": "^6.0.1",
"lodash.merge": "^4.6.2",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-markdown": "^8.0.6",
"react-router-dom": "^6.8.1",
"regenerator-runtime": "^0.13.11",
"remark-gfm": "^3.0.1",
"socket.io": "^2.5.0"
},
"devDependencies": {
Expand Down
79 changes: 79 additions & 0 deletions front/src/common/markdowneditor/markdowneditor.component.tsx
Comment thread
Franlop7 marked this conversation as resolved.
Outdated
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import React from "react";
import { basicSetup, EditorView } from 'codemirror'
import { EditorState } from '@codemirror/state'
import { useEffect, useRef } from 'react'
Comment thread
Franlop7 marked this conversation as resolved.
Outdated
import { markdown } from '@codemirror/lang-markdown'
import { languages } from '@codemirror/language-data'
import { tags } from '@lezer/highlight'
import { syntaxHighlighting, HighlightStyle} from '@codemirror/language'
import * as classes from './markdowneditor.styles';

const stylesEditor = HighlightStyle.define([
Comment thread
Franlop7 marked this conversation as resolved.
Outdated
{ tag: tags.heading1, class: classes.headerH1},
{ tag: tags.heading2, class: classes.headerH2},
{ tag: tags.heading3, class: classes.headerH3},
]);

interface Props {
value: string
onChange?: (value: string) => void
className?: string
}

export const MarkdownEditor: React.FC<Props> = (props) => {

const refContainer = useRef(null)
const editorView = useRef<EditorView>()

useEffect(() => {
if (!refContainer.current) return

editorView.current = new EditorView({
state: EditorState.create({
doc: props.value,
extensions: [
basicSetup,
markdown({
codeLanguages: languages,
}),
syntaxHighlighting(stylesEditor),
EditorView.lineWrapping,
EditorView.updateListener.of((update) => {
props.onChange(update.state.doc.toString())
}),
EditorView.theme({
'&': {
border: '2px solid #070707',
height: '300px',
},
}),
]
}),
parent: refContainer.current
});

return () => editorView.current?.destroy()
}, []);

const scrollToEnd = () => {
if (!refContainer.current) return;

const scrollHeight = refContainer.current.scrollHeight;
const clientHeight = refContainer.current.clientHeight;
editorView.current.scrollDOM.scrollTop = scrollHeight - clientHeight;
}

useEffect(() => {
const state = editorView.current?.state
const currentValue = state?.doc.toString()
if (state && currentValue !== props.value) {
const update = state.update({
changes: { from: 0, to: state.doc.length, insert: props.value }
});
editorView.current?.update([update]);
scrollToEnd();
}
}, [props.value]);

return <div ref={refContainer} className={ props.className } />
};
13 changes: 13 additions & 0 deletions front/src/common/markdowneditor/markdowneditor.styles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { css } from '@emotion/css';

export const headerH1 = css`
font-size: 2.3rem;
`;

export const headerH2 = css`
font-size: 1.8rem;
`;

export const headerH3 = css`
font-size: 1.3rem;
`;
16 changes: 16 additions & 0 deletions front/src/common/markdownview/markdownView.tsx
Comment thread
Franlop7 marked this conversation as resolved.
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import React from 'react';
import ReactMarkdown from 'react-markdown';
import remarkGfm from 'remark-gfm';

interface Props {
value: string
className?: string;
}

export const MarkdownView: React.FC<Props> = (props) => {
Comment thread
Franlop7 marked this conversation as resolved.
Outdated
return (
<div className={ props.className }>
<ReactMarkdown children={props.value} remarkPlugins={[remarkGfm]} />
</div>
);
};
23 changes: 5 additions & 18 deletions front/src/pods/student/student.component.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
import React from 'react';
import TextareaAutosize from '@mui/material/TextareaAutosize';
import Typography from '@mui/material/Typography';

import Checkbox from '@mui/material/Checkbox';
import FormControlLabel from '@mui/material/FormControlLabel';

import * as innerClasses from './student.styles';
import { useAutoScroll } from 'common/hooks/auto-scroll.hook';
import { MarkdownView } from 'common/markdownview/markdownView';
import * as innerClasses from './student.styles';

interface Props {
room: string;
log: string;
className?: string;
}

export const StudentComponent: React.FC<Props> = props => {
Expand All @@ -19,7 +18,6 @@ export const StudentComponent: React.FC<Props> = props => {
const {
isAutoScrollEnabled,
setIsAutoScrollEnabled,
textAreaRef,
doAutoScroll,
} = useAutoScroll();

Expand All @@ -40,20 +38,9 @@ export const StudentComponent: React.FC<Props> = props => {
<label className={innerClasses.label} htmlFor="session">
Content
</label>
<div role="log">
<TextareaAutosize
ref={textAreaRef}
data-testid="session"
id="session"
maxRows={30}
minRows={30}
className={innerClasses.textarea}
value={log ?? ''}
readOnly={true}
/>
</div>
<MarkdownView value={log ?? ''} className={innerClasses.textView} />
Comment thread
Franlop7 marked this conversation as resolved.
Outdated
<FormControlLabel
label="Disable AutoScroll"
label="Enable AutoScroll"
control={
<Checkbox
checked={isAutoScrollEnabled}
Expand Down
4 changes: 3 additions & 1 deletion front/src/pods/student/student.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,10 @@ export const label = css`
font-size: 1.125rem;
`;

export const textarea = css`
export const textView = css`
width: 100%;
height: 600px;
overflow: auto;
box-sizing: border-box;
padding: ${spacing(2)};
font-family: ${typography.fontFamily};
Expand Down
34 changes: 16 additions & 18 deletions front/src/pods/trainer/components/new-text.component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,46 +2,44 @@ import React from 'react';
import { cx } from '@emotion/css';
import ArrowForwardRoundedIcon from '@mui/icons-material/ArrowForwardRounded';
import Button from '@mui/material/Button';
import TextareaAutosize from '@mui/material/TextareaAutosize';
import * as innerClasses from './new-text.styles';
import { SelectComponent } from './select.component';
import { MarkdownEditor } from 'common/markdowneditor/markdowneditor.component';

interface Props {
handleAppendTrainerText: (trainerText: string) => void;
className?: string;
}

export const NewTextComponent: React.FC<Props> = (props) => {
const { handleAppendTrainerText, className } = props;
const [language, setLanguage] = React.useState('');
const [trainerText, setTrainerText] = React.useState<string>('');

const languageModify = (language: string): string => language === "" ? "" : `\`\`\`${language}\n\n\`\`\``;
Comment thread
Franlop7 marked this conversation as resolved.
Outdated

const { handleAppendTrainerText, className } = props;

const handleAppendTrainerTextInternal = (): void => {
if (trainerText) {
handleAppendTrainerText(trainerText);
setTrainerText('');
setTrainerText(languageModify(language));
setLanguage(language);
}
};

const handleOnChange = (e: React.ChangeEvent<HTMLTextAreaElement>): void => {
setTrainerText(e.target.value);
};
React.useEffect(() => {
if (language) {
setTrainerText(languageModify(language));
}
},[language]);

return (
<form className={cx(innerClasses.root, className)}>
<label className={innerClasses.label} htmlFor="new-text">
New text
</label>
<TextareaAutosize
maxRows={10}
minRows={10}
className={innerClasses.textarea}
onChange={(e) => handleOnChange(e)}
onKeyDown={(event) => {
Comment thread
Franlop7 marked this conversation as resolved.
if (event.key === 'Enter' && event.ctrlKey) {
handleAppendTrainerTextInternal();
}
}}
value={trainerText}
/>
<SelectComponent value={language} onChange={setLanguage} />
<MarkdownEditor value={trainerText} onChange={setTrainerText} />
<Button
variant="contained"
color="primary"
Expand Down
34 changes: 34 additions & 0 deletions front/src/pods/trainer/components/select.component.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import React from 'react';
import InputLabel from '@mui/material/InputLabel';
import FormControl from '@mui/material/FormControl';
import Select from '@mui/material/Select';
import { MenuItem } from '@mui/material';
Comment thread
Franlop7 marked this conversation as resolved.
Outdated
import { languageFormat } from '../trainer.constants';

interface Props {
onChange: (value: string) => void;
value: string;
}

export const SelectComponent: React.FC<Props> = (props) => {
const {onChange,value} = props;

const handleSelectChange = event => {
onChange(event.target.value as string);
};

return (
<FormControl variant="outlined">
<InputLabel htmlFor="outlined-lang-native-simple">Language</InputLabel>
<Select
label="Language"
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove htmlFor

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

or try add id="select" and change htmlFor="select"

value={value}
onChange={handleSelectChange}
>
{languageFormat.map(language =>
<MenuItem key={language.id} value={language.id}>{language.label}</MenuItem>
)}
</Select>
</FormControl>
);
};
59 changes: 25 additions & 34 deletions front/src/pods/trainer/components/session.component.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
import React from 'react';
import { cx } from '@emotion/css';
import TextareaAutosize from '@mui/material/TextareaAutosize';
import ArrowForwardRoundedIcon from '@mui/icons-material/ArrowForwardRounded';
import UndoIcon from '@mui/icons-material/Undo';
import Button from '@mui/material/Button';

import FormControlLabel from '@mui/material/FormControlLabel';
import Checkbox from '@mui/material/Checkbox';

import * as innerClasses from './session.styles';
import { useAutoScroll } from 'common/hooks/auto-scroll.hook';
import { MarkdownEditor } from 'common/markdowneditor/markdowneditor.component';
import * as innerClasses from './session.styles';

interface Props {
log: string;
handleSendFullContentLog: (fullContent: string) => void;
Expand Down Expand Up @@ -37,7 +36,6 @@ export const SessionComponent: React.FC<Props> = (props) => {
const {
isAutoScrollEnabled,
setIsAutoScrollEnabled,
textAreaRef,
doAutoScroll,
} = useAutoScroll();

Expand All @@ -51,35 +49,7 @@ export const SessionComponent: React.FC<Props> = (props) => {
<label className={innerClasses.label} htmlFor="session">
Session
</label>

<TextareaAutosize
role="log"
Comment thread
Franlop7 marked this conversation as resolved.
ref={textAreaRef}
id="session"
maxRows={20}
minRows={20}
className={innerClasses.textarea}
/>
<FormControlLabel
label="Disable AutoScroll"
control={
<Checkbox
checked={isAutoScrollEnabled}
onChange={(e) => setIsAutoScrollEnabled(e.target.checked)}
color="primary"
/>
}
/>
<Button
variant="contained"
color="secondary"
disableElevation
className={innerClasses.undoButton}
onClick={() => handleSetSessionContent(log)}
>
<UndoIcon className={innerClasses.undoIcon} />
Undo
</Button>
<MarkdownEditor value={log} onChange={handleSendFullContentLog} className={innerClasses.textEditor} />
<Button
variant="contained"
color="primary"
Expand All @@ -90,6 +60,27 @@ export const SessionComponent: React.FC<Props> = (props) => {
Send Full Content
<ArrowForwardRoundedIcon className={innerClasses.sendIcon} />
</Button>
<Button
variant="contained"
color="secondary"
disableElevation
className={innerClasses.undoButton}
onClick={() => handleSetSessionContent(log)}
>
<UndoIcon className={innerClasses.undoIcon} />
Undo
</Button>
<FormControlLabel
className={innerClasses.autoScroll}
label="Enable AutoScroll"
control={
<Checkbox
checked={isAutoScrollEnabled}
onChange={(e) => setIsAutoScrollEnabled(e.target.checked)}
color="primary"
/>
}
/>
</form>
);
};
Loading