commit materials

This commit is contained in:
Firesieht 2021-04-24 13:58:03 +03:00
parent a02ad3e417
commit 854baf27a2
17 changed files with 1954 additions and 13508 deletions

File diff suppressed because it is too large Load Diff

96
package-lock.json generated
View File

@ -4646,6 +4646,16 @@
"integrity": "sha512-TbH79tcyi9FHwbyboOKeRachRq63mSuWYXOflsNO9ZyE5ClQ/JaozNKl+aWUq87qPNsXasXxi2AbgfwIJ+8GQw==",
"dev": true
},
"@types/draft-js": {
"version": "0.11.1",
"resolved": "https://registry.npmjs.org/@types/draft-js/-/draft-js-0.11.1.tgz",
"integrity": "sha512-jV4LAXYdVvS0ahIROZehkKqHgfLxaDBl3fzfEVqho8NxFAtEaObdIiu7FpPUu/Y97PlJVxGajar7aSikQqz9sQ==",
"dev": true,
"requires": {
"@types/react": "*",
"immutable": "~3.7.4"
}
},
"@types/eslint": {
"version": "7.2.7",
"resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.2.7.tgz",
@ -4898,9 +4908,9 @@
}
},
"@types/react": {
"version": "16.14.5",
"resolved": "https://registry.npmjs.org/@types/react/-/react-16.14.5.tgz",
"integrity": "sha512-YRRv9DNZhaVTVRh9Wmmit7Y0UFhEVqXqCSw3uazRWMxa2x85hWQZ5BN24i7GXZbaclaLXEcodEeIHsjBA8eAMw==",
"version": "17.0.3",
"resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.3.tgz",
"integrity": "sha512-wYOUxIgs2HZZ0ACNiIayItyluADNbONl7kt8lkLjVK8IitMH5QMyAh75Fwhmo37r1m7L2JaFj03sIfxBVDvRAg==",
"requires": {
"@types/prop-types": "*",
"@types/scheduler": "*",
@ -4926,6 +4936,16 @@
"@types/react": "*"
}
},
"@types/react-draft-wysiwyg": {
"version": "1.13.2",
"resolved": "https://registry.npmjs.org/@types/react-draft-wysiwyg/-/react-draft-wysiwyg-1.13.2.tgz",
"integrity": "sha512-Fz+DzXi5emVwEnrs9awgcivQ8kVcPkvTEr4prNogEeAFWZq7UJLe3u4Ws1UWU/kSxga0+3wWomb9ZzzrPKlkZw==",
"dev": true,
"requires": {
"@types/draft-js": "*",
"@types/react": "*"
}
},
"@types/react-router": {
"version": "5.1.12",
"resolved": "https://registry.npmjs.org/@types/react-router/-/react-router-5.1.12.tgz",
@ -7578,8 +7598,7 @@
"classnames": {
"version": "2.2.6",
"resolved": "https://registry.npmjs.org/classnames/-/classnames-2.2.6.tgz",
"integrity": "sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q==",
"dev": true
"integrity": "sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q=="
},
"clean-css": {
"version": "4.2.3",
@ -9362,6 +9381,38 @@
}
}
},
"draft-js": {
"version": "0.11.7",
"resolved": "https://registry.npmjs.org/draft-js/-/draft-js-0.11.7.tgz",
"integrity": "sha512-ne7yFfN4sEL82QPQEn80xnADR8/Q6ALVworbC5UOSzOvjffmYfFsr3xSZtxbIirti14R7Y33EZC5rivpLgIbsg==",
"requires": {
"fbjs": "^2.0.0",
"immutable": "~3.7.4",
"object-assign": "^4.1.1"
},
"dependencies": {
"fbjs": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/fbjs/-/fbjs-2.0.0.tgz",
"integrity": "sha512-8XA8ny9ifxrAWlyhAbexXcs3rRMtxWcs3M0lctLfB49jRDHiaxj+Mo0XxbwE7nKZYzgCFoq64FS+WFd4IycPPQ==",
"requires": {
"core-js": "^3.6.4",
"cross-fetch": "^3.0.4",
"fbjs-css-vars": "^1.0.0",
"loose-envify": "^1.0.0",
"object-assign": "^4.1.0",
"promise": "^7.1.1",
"setimmediate": "^1.0.5",
"ua-parser-js": "^0.7.18"
}
}
}
},
"draftjs-utils": {
"version": "0.10.2",
"resolved": "https://registry.npmjs.org/draftjs-utils/-/draftjs-utils-0.10.2.tgz",
"integrity": "sha512-EstHqr3R3JVcilJrBaO/A+01GvwwKmC7e4TCjC7S94ZeMh4IVmf60OuQXtHHpwItK8C2JCi3iljgN5KHkJboUg=="
},
"duplexer": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz",
@ -12141,6 +12192,11 @@
"integrity": "sha512-1qYz89hW3lFDEazhjW0yVAV87lw8lVkrJocr72XmBkMKsoSVJCQx3W8BXsC7hO2qAt8BoVjYjtAcZ9perqGnNg==",
"dev": true
},
"html-to-draftjs": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/html-to-draftjs/-/html-to-draftjs-1.5.0.tgz",
"integrity": "sha512-kggLXBNciKDwKf+KYsuE+V5gw4dZ7nHyGMX9m0wy7urzWjKGWyNFetmArRLvRV0VrxKN70WylFsJvMTJx02OBQ=="
},
"html-void-elements": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-1.0.5.tgz",
@ -15270,6 +15326,14 @@
"resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz",
"integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA="
},
"linkify-it": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.2.0.tgz",
"integrity": "sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw==",
"requires": {
"uc.micro": "^1.0.1"
}
},
"listr": {
"version": "0.14.3",
"resolved": "https://registry.npmjs.org/listr/-/listr-0.14.3.tgz",
@ -18955,6 +19019,18 @@
"scheduler": "^0.20.1"
}
},
"react-draft-wysiwyg": {
"version": "1.14.6",
"resolved": "https://registry.npmjs.org/react-draft-wysiwyg/-/react-draft-wysiwyg-1.14.6.tgz",
"integrity": "sha512-EMIteBVnlMAP3T97OfjlKchsHZ15mYWQwRw8QIInOtAvlZnnTydRjuHMCN0PuQ2dsXwMkJ7+MWc2aTL5RiXmFg==",
"requires": {
"classnames": "^2.2.6",
"draftjs-utils": "^0.10.2",
"html-to-draftjs": "^1.5.0",
"linkify-it": "^2.2.0",
"prop-types": "^15.7.2"
}
},
"react-draggable": {
"version": "4.4.3",
"resolved": "https://registry.npmjs.org/react-draggable/-/react-draggable-4.4.3.tgz",
@ -22252,6 +22328,11 @@
"resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.25.tgz",
"integrity": "sha512-8NFExdfI24Ny8R3Vc6+uUytP/I7dpqk3JERlvxPWlrtx5YboqCgxAXYKPAifbPLV2zKbgmmPL53ufW7mUC/VOQ=="
},
"uc.micro": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz",
"integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA=="
},
"unbox-primitive": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.0.tgz",
@ -23104,6 +23185,11 @@
"integrity": "sha512-wYxSGajtmoP4WxfejAPIr4l0fVh+jeMXZb08wNc0tMg6xsfZXj3cECqIK0G7ZAqUq0PP8WlMDtaOGVBTAWztNw==",
"dev": true
},
"web-vitals": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-1.1.1.tgz",
"integrity": "sha512-jYOaqu01Ny1NvMwJ3dBJDUOJ2PGWknZWH4AUnvFOscvbdHMERIKT2TlgiAey5rVyfOePG7so2JcXXZdSnBvioQ=="
},
"webidl-conversions": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz",

View File

@ -16,9 +16,11 @@
"@types/node": "^12.20.6",
"@types/react": "^17.0.3",
"@types/react-sidebar": "^3.0.0",
"draft-js": "^0.11.7",
"graphql": "^15.5.0",
"react": "^17.0.1",
"react-dom": "^17.0.1",
"react-draft-wysiwyg": "^1.14.6",
"react-router-dom": "^5.2.0",
"react-scripts": "^4.0.3",
"react-sidebar": "^3.0.2",
@ -61,7 +63,9 @@
"@storybook/node-logger": "^6.1.21",
"@storybook/preset-create-react-app": "^3.1.7",
"@storybook/react": "^6.1.21",
"@types/draft-js": "^0.11.1",
"@types/react-dom": "^17.0.3",
"@types/react-draft-wysiwyg": "^1.13.2",
"@types/react-router-dom": "^5.1.7"
}
}

View File

@ -5,7 +5,26 @@ mutation auth($username:String!, $password:String!){
}
mutation register($username:String!, $password:String!){
registerUser(input:{username:$username, password:$password}){
createUser(username:$username, password:$password){
ok
}
}
}
query getMaterials($token: String){
materialsByUser(token:$token){
content
id
}
}
mutation UpdateDoc($id:ID, $content:String){
updateDoc(content:$content, id:$id){
ok
}
}
query getMaterialByID($id:ID!){
material(id:$id){
content
}
}

View File

@ -16,7 +16,7 @@ export const App:react.FC = () => {
<Route path="/enter-user">
<RegScreen></RegScreen>
</Route>
<Route path="">
<Route path="/index">
<BaseScreen></BaseScreen>
</Route>
</Switch>

File diff suppressed because it is too large Load Diff

1
src/react-app-env.d.ts vendored Normal file
View File

@ -0,0 +1 @@
/// <reference types="react-scripts" />

View File

@ -1,21 +1,53 @@
import react from "react";
import {DocumentCard} from "../../uiKit/Documents/DocumentCard/DocumentCard"
import {ApplicationSidebar} from "../../uiKit/Sidebar/Sidebar";
import {useGetMaterialsQuery} from "../../generated/graphql"
import { Route, useRouteMatch, Switch } from "react-router";
import {useUpdateDocMutation} from "../../generated/graphql"
import {Document} from "../../uiKit/Documents/Document/Document"
export const BaseScreen:react.FC = () => {
return <ApplicationSidebar
content={[
{
link: "",
name: "name1"
},
{
link: "",
name: "name2"
}
]}
closed={true}
>
fuck you
</ApplicationSidebar>
let {url} = useRouteMatch();
const {loading, data} = useGetMaterialsQuery({variables:{token:localStorage.getItem("token")}});
if (loading){
return <h1>Loading...</h1>
}
return(
<div>
<ApplicationSidebar
content={[
{
link: "",
name: "Мои файлы"
},
{
link: "",
name: "Создать"
}
]}
closed={true}
>
<Switch>
<Route path={`${url}/:docID`}>
<Document></Document>
</Route>
<Route path={url}>
<div>
{data && data?.materialsByUser?.map( materials =>
<DocumentCard
id={materials?.id == undefined? "нет":materials?.id}
content={materials?.content == undefined? "нет":materials?.content
}></DocumentCard>
)}
</div>
</Route>
</Switch>
</ApplicationSidebar>
</div>
);
}

View File

@ -15,7 +15,7 @@ export const RegScreen:react.FC = () => {
const location = useLocation();
console.log(location);
const isSign = location.pathname.split("/").pop() == "Login";
if (CheckUser()) return <Redirect to=""></Redirect>
if (CheckUser()) return <Redirect to="/index"></Redirect>
return (
<div className="centered">
<div className="registration__container">

3
src/svg/TaskIcon.svg Normal file
View File

@ -0,0 +1,3 @@
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M3 0V3H0V5H3V8H5V5H8V3H5V0H3ZM10 3V5H16V16H5V10H3V16C3 17.1046 3.89543 18 5 18H16C17.1046 18 18 17.1046 18 16V5C18 3.89543 17.1046 3 16 3H10Z" fill="black"/>
</svg>

After

Width:  |  Height:  |  Size: 310 B

View File

@ -0,0 +1,43 @@
import react, {useState} from "react"
import {
useParams, useRouteMatch, Link, Switch, Route, Redirect
} from "react-router-dom"
import "./style.css";
import {MyUserComponentEditor} from "../TextEditor/TextEditor"
import {useUpdateDocMutation, useGetMaterialByIdQuery} from "../../../generated/graphql"
import {EditorState} from "draft-js"
import { convertFromRaw, convertToRaw } from 'draft-js';
export const Document:React.FC = () =>{
const [updateDoc] = useUpdateDocMutation();
const {docID} = useParams<{docID:string}>();
const {loading, data} = useGetMaterialByIdQuery({variables:{id:docID}})
if (loading){
return <h1>loading...</h1>
}
if (data?.material == null){
console.log("нет данных")
return <Redirect to="/index"></Redirect>
}
function onChange(state:any){
updateDoc({variables:{id:docID, content:JSON.stringify(convertToRaw(state))}})
}
let state = convertFromRaw(JSON.parse(data.material.content))
return (
<div id="doc">
<MyUserComponentEditor addComponents={true} state={state} onChange={(e:any)=>onChange(e)}></MyUserComponentEditor>
</div>
);
}

View File

View File

@ -0,0 +1,21 @@
import react, {useState} from "react"
import { FileWatcherEventKind } from "typescript";
import {
useParams, useRouteMatch, Link, Switch, Route, Redirect
} from "react-router-dom"
import "./style.css";
import {useUpdateDocMutation} from "../../../generated/graphql"
import {Document} from "../Document/Document"
interface DocumentCardIE{
id:string;
content:string
}
export const DocumentCard:React.FC<DocumentCardIE> = (props)=>{
let match = useRouteMatch();
return(
<div><Link to={match.url +"/" + props.id}>{props.content}</Link></div>
);
}

View File

@ -0,0 +1,199 @@
import React, { Component } from 'react';
import {
AtomicBlockUtils,
EditorState,
convertToRaw,
RichUtils} from 'draft-js';
import { Editor } from 'react-draft-wysiwyg';
import "./style.css"
import {DefaultButton} from "../../Button/Button"
import icon from "../../../svg/TaskIcon.svg"
import {Route, Switch, Redirect} from "react-router-dom";
export class MyUserComponentEditor extends React.Component {
constructor(props) {
super(props);
this.state = {
editorState: EditorState.createWithContent(props.state),
};
this.Type_task = "audio";
this.onChange = (editorState) => {
try{
props.onChange(editorState.getCurrentContent())
this.setState({editorState})
}
catch(e){
};
}
this.confirmMedia = this._confirmMedia.bind(this);
this.handleKeyCommand = this._handleKeyCommand.bind(this);
};
stopPropagation = (event) => {
event.stopPropagation();
};
test = (e) =>{
this.Type_task = e.target.innerText
this.confirmMedia()
};
renderModal = (props) => {
const { color } = props.currentState;
return (
<div onClick={this.stopPropagation}>
<div className="wrapper">
<DefaultButton handleClick={(e)=>this.test(e)} id={1} class="taskButton">Прочитать текст</DefaultButton>
<DefaultButton handleClick={(e)=>this.test(e)} id={2} class="taskButton">выбрать правильный вариант ответа</DefaultButton>
<DefaultButton handleClick={(e)=>this.test(e)} id={3} class="taskButton">правда/ложь</DefaultButton>
<DefaultButton handleClick={(e)=>this.test(e)} id={4} class="taskButton">расставить заголвки</DefaultButton>
</div>
</div>
);
};
taskPic = (props) =>{
const { expanded, onExpandEvent } = props;
return (
<div aria-haspopup="true" aria-expanded={expanded} aria-label="rdw-color-picker">
<div onClick={onExpandEvent}>
<div className="rdw-option-wrapper">
<img src={icon} alt=""/>
</div>
</div>
{expanded ? this.renderModal(props) : undefined}
</div>
);
}
_handleKeyCommand(command, editorState) {
const newState = RichUtils.handleKeyCommand(editorState, command);
if (newState) {
this.onChange(newState);
return true;
}
return false;
}
_confirmMedia() {
let {editorState, Type} = this.state;
Type = this.Type_task
const contentState = editorState.getCurrentContent();
const contentStateWithEntity = contentState.createEntity(
Type,
'IMMUTABLE',
);
const entityKey = contentStateWithEntity.getLastCreatedEntityKey();
const newEditorState = EditorState.set(
editorState,
{currentContent: contentStateWithEntity}
);
this.setState({
editorState: AtomicBlockUtils.insertAtomicBlock(
newEditorState,
entityKey,
' '
),
}, () => {
setTimeout(() => null, 0);
});
}
render() {
let toolbar = {};
if (this.props.addComponents == true){
toolbar = {colorPicker: { component: this.taskPic }}
}
return (
<div style={styles.root}>
<Editor
blockRendererFn={mediaBlockRenderer}
editorState={this.state.editorState}
handleKeyCommand={this.handleKeyCommand}
onEditorStateChange={this.onChange.bind(this)}
placeholder="Введи текст"
ref="editor"
wrapperClassName="demo-wrapper"
editorClassName="demo-editor"
toolbar={toolbar}
/>
</div>
);
}
}
function mediaBlockRenderer(block) {
if (block.getType() === 'atomic') {
return {
component: Media,
editable: false,
};
}
return null;
}
const Media = (props) => {
const entity = props.contentState.getEntity(
props.block.getEntityAt(0)
);
const type = entity.getType();
let media;
if (type === 'audio') {
media = <div>audio</div>;
} else if (type === "Прочитать текст") {
media = <div>Прочитать текст</div>;
} else if (type === 'выбрать правильный вариант ответа') {
media = <div>выбрать правильный вариант ответа</div>;
} else if (type === "правда/ложь"){
media = <div>правда/ложь</div>
} else if (type === "расставить заголвки"){
media = <div>расставить заголвки</div>
}
return media;
};
const styles = {
root: {
fontFamily: '\'Georgia\', serif',
padding: 20,
width: 600,
},
buttons: {
marginBottom: 10,
},
urlInputContainer: {
marginBottom: 10,
},
urlInput: {
fontFamily: '\'Georgia\', serif',
marginRight: 10,
padding: 3,
},
button: {
marginTop: 10,
textAlign: 'center',
},
media: {
width: '100%',
whiteSpace: 'initial'
},
};

File diff suppressed because it is too large Load Diff

View File

@ -29,19 +29,19 @@ export const ApplicationSidebar:react.FC<ISidebar> = (props) => {
const phoneAdaptation = window.matchMedia("(min-width:880px)")
const {url} = useRouteMatch();
const [docked, setDocked] = useState(true);
// const [docked, setDocked] = useState(true);
const [closed, setClosed] = useState(props.closed);
phoneAdaptation.addListener(() => {
setDocked(phoneAdaptation.matches)
})
// phoneAdaptation.addListener(() => {
// setDocked(phoneAdaptation.matches)
// })
return <Sidebar
sidebar={<ApplicationSidebarRoute content={props.content}></ApplicationSidebarRoute>}
open={closed}
onSetOpen={setClosed}
sidebarClassName={"sidebar__container"}
docked={docked}
docked={true}
shadow={false}
>
{props.children}