Switched to using Verbum (https://github.com/ozanyurtsever/verbum) which builds on Lexical to create a rich text editor; Isolated the rich text editor into a component so it can be easily swapped out; Added a higher resolution background for the student login page; Still a lot of bugs in the workshop list view.

This commit is contained in:
2022-10-27 08:56:26 -07:00
parent 77b420ea6f
commit cab09e59b9
10 changed files with 433 additions and 24 deletions

View File

@@ -1,4 +1,4 @@
import React, { useState } from 'react';
import React, { useState, useEffect } from 'react';
import {Meteor} from "meteor/meteor";
import {Roles} from 'meteor/alanning:roles';
import { useTracker } from 'meteor/react-meteor-data';
@@ -16,11 +16,23 @@ import DialogActions from '@mui/material/DialogActions';
import DialogContent from '@mui/material/DialogContent';
import DialogContentText from '@mui/material/DialogContentText';
import DialogTitle from '@mui/material/DialogTitle';
import {Editor} from 'react-draft-wysiwyg'
import 'react-draft-wysiwyg/dist/react-draft-wysiwyg.css'
import {Students} from "/imports/api/students";
import {Staff} from "/imports/api/staff";
import {conditions} from "/imports/api/assets";
import {Workshops} from "/imports/api/workshops";
import {$getRoot, $getSelection} from 'lexical';
import {LexicalComposer} from '@lexical/react/LexicalComposer';
import {PlainTextPlugin} from '@lexical/react/LexicalPlainTextPlugin';
import {ContentEditable} from '@lexical/react/LexicalContentEditable';
import {HistoryPlugin} from '@lexical/react/LexicalHistoryPlugin';
import {OnChangePlugin} from '@lexical/react/LexicalOnChangePlugin';
import {useLexicalComposerContext} from '@lexical/react/LexicalComposerContext';
import {RichTextPlugin} from "@lexical/react/LexicalRichTextPlugin";
import {LinkPlugin} from "@lexical/react/LexicalLinkPlugin";
import {MarkdownShortcutPlugin} from "@lexical/react/LexicalMarkdownShortcutPlugin";
import {AutoLinkNode, LinkNode} from '@lexical/link';
import {Editor} from "/imports/ui/components/RichText/Editor";
const cssTwoColumnContainer = {
display: 'grid',
@@ -29,7 +41,7 @@ const cssTwoColumnContainer = {
rowGap: '0.4rem',
}
export const Workshops = () => {
export const WorkshopList = () => {
Meteor.subscribe('students');
Meteor.subscribe('staff');
Meteor.subscribe('workshops');
@@ -58,46 +70,66 @@ export const Workshops = () => {
backgroundColor: selectedWorkshop === item ? '#EECFA6' : 'white'
}
}
const [openWorkshopEditor, setOpenWorkshopEditor] = useState(false)
const [editedWorkshop, setEditedWorkshop] = useState({})
const [editedName, setEditedName] = useState("")
const [editedDescription, setEditedDescription] = useState("")
const [editedSignupLimit, setEditedSignupLimit] = useState("")
const newWorkshop = () => {
if(isAdmin) {
setEditedDescription("")
setEditedWorkshop({})
setEditedDescription("")
setEditedName("")
setEditedSignupLimit("")
setOpenWorkshopEditor(true)
}
}
const editWorkshop = () => {
if(isAdmin && selectedWorkshop) {
setEditedWorkshop({...selectedWorkshop})
setEditedDescription(selectedWorkshop.description ? selectedWorkshop.description : "")
setEditedName(selectedWorkshop.name ? selectedWorkshop.name : "")
setEditedSignupLimit(selectedWorkshop.signupLimit ? selectedWorkshop.signupLimit : "")
setOpenWorkshopEditor(true)
}
}
const [openWorkshopEditor, setOpenWorkshopEditor] = useState(false)
const [editedWorkshop, setEditedWorkshop] = useState(false)
const workshopEditorClosed = (save) => {
const completeHandler = (err, result) => {
if(err) console.error(err)
else {
setOpenWorkshopEditor(false)
setEditedWorkshop(null)
}
}
if(save) {
if(editedWorkshop._id) Meteor.call('workshops.update', editedWorkshop._id, editedWorkshop.name, editedWorkshop.description, editedWorkshop.signupLimit, completeHandler)
else Meteor.call('workshops.add', editedWorkshop.name, editedWorkshop.description, editedWorkshop.signupLimit, completeHandler)
if(editedWorkshop._id) Meteor.call('workshops.update', editedWorkshop._id, editedName, editedDescription, editedSignupLimit, completeHandler)
else Meteor.call('workshops.add', editedName, editedDescription, editedSignupLimit, completeHandler)
}
else completeHandler()
}
const onLexicalComposerError = (err) => {
console.error(err)
}
const lexicalComposerTheme = {
}
const lexicalComposerChanged = (e) => {
console.log(e)
}
const descriptionEditorNodes = [LinkNode]
return (
<>
<Dialog open={openWorkshopEditor} onClose={workshopEditorClosed}>
<DialogTitle>Workshop Editor</DialogTitle>
<DialogContent style={{display: 'flex', flexDirection: 'column'}}>
<TextField style={{marginTop: '1rem',minWidth: '30rem'}} variant="standard" label="Name" value={editedWorkshop.name} onChange={(e) => {editedWorkshop.name = e.target.value; setEditedWorkshop(editedWorkshop)}}/>
<Editor editorState={selectedWorkshop.description} toolbarClassName="editorToolbar" wrapperClassName="editorWrapper" editorClassName="editor" onEditorStateChange={(e) => {selectedWorkshop.description = e.target.value; setEditedWorkshop(editedWorkshop)}}/>
<TextField style={{marginTop: '1rem',minWidth: '30rem'}} variant="standard" type="number" label="Signup Limit" value={editedWorkshop.signupLimit} onChange={(e) => {editedWorkshop.signupLimit = e.target.value; setEditedWorkshop(editedWorkshop)}}/>
<TextField style={{marginTop: '1rem',minWidth: '30rem'}} variant="standard" label="Name" value={editedName} onChange={(e) => {setEditedName(e.target.value)}}/>
<Editor config={{namespace: 'WorkshopDescriptionEditor', state: selectedWorkshop ? selectedWorkshop.description : "", theme: lexicalComposerTheme}}></Editor>
<TextField style={{marginTop: '1rem',minWidth: '30rem'}} variant="standard" type="number" label="Signup Limit" value={editedSignupLimit} onChange={(e) => {setEditedSignupLimit(e.target.value)}}/>
</DialogContent>
<DialogActions>
<Button onClick={() => workshopEditorClosed(true)}>Save</Button>
@@ -121,10 +153,10 @@ export const Workshops = () => {
<Box style={{...cssTwoColumnContainer}}>
<Paper>
{/*<Editor editorState={selectedWorkshop.description} toolbarClassName="editorToolbar" wrapperClassName="editorWrapper" editorClassName="editor" onEditorStateChange={(e) => {selectedWorkshop.description = ""}}/>*/}
{`${selectedWorkshop.description}`}
{selectedWorkshop && `${selectedWorkshop.description}`}
</Paper>
<List>
{selectedWorkshop.signupSheet.map((next, i) => {
{selectedWorkshop && selectedWorkshop.signupSheet.map((next, i) => {
return (
<ListItem key={next._id}>
<ListItemText primary={next.data.firstName + " " + next.data.lastName} secondary={next.data.email}/>