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:
@@ -14,7 +14,7 @@ standard-minifier-css@1.8.1 # CSS minifier run for production mode
|
|||||||
standard-minifier-js@2.8.0 # JS minifier run for production mode
|
standard-minifier-js@2.8.0 # JS minifier run for production mode
|
||||||
es5-shim@4.8.0 # ECMAScript 5 compatibility for older browsers
|
es5-shim@4.8.0 # ECMAScript 5 compatibility for older browsers
|
||||||
ecmascript@0.16.2 # Enable ECMAScript2015+ syntax in app code
|
ecmascript@0.16.2 # Enable ECMAScript2015+ syntax in app code
|
||||||
typescript@4.5.4 # Enable TypeScript syntax in .ts and .tsx modules
|
typescript # Enable TypeScript syntax in .ts and .tsx modules
|
||||||
shell-server@0.5.0 # Server-side component of the `meteor shell` command
|
shell-server@0.5.0 # Server-side component of the `meteor shell` command
|
||||||
|
|
||||||
static-html@1.3.2 # Define static page content in .html files
|
static-html@1.3.2 # Define static page content in .html files
|
||||||
@@ -26,4 +26,4 @@ service-configuration@1.3.0
|
|||||||
google-config-ui@1.0.3 # Adds the UI for logging in via Google
|
google-config-ui@1.0.3 # Adds the UI for logging in via Google
|
||||||
alanning:roles # Adds roles to the user
|
alanning:roles # Adds roles to the user
|
||||||
|
|
||||||
msavin:mongol # Free version of MeteorToys - Provides access to the client side MongoDB for debugging. (Ctrl-M to activate :: https://atmospherejs.com/msavin/mongol)
|
msavin:mongol # Free version of MeteorToys - Provides access to the client side MongoDB for debugging. (Ctrl-M to activate :: https://atmospherejs.com/msavin/mongol)
|
||||||
|
|||||||
@@ -7,5 +7,6 @@ import "./sites.js";
|
|||||||
import "./asset-types.js";
|
import "./asset-types.js";
|
||||||
import "./assets.js";
|
import "./assets.js";
|
||||||
import "./asset-assignment-history.js";
|
import "./asset-assignment-history.js";
|
||||||
|
import "./workshops.js";
|
||||||
|
|
||||||
// console.log("Finished setting up server side models.");
|
// console.log("Finished setting up server side models.");
|
||||||
@@ -29,7 +29,7 @@ Meteor.methods({
|
|||||||
let signupSheet = [];
|
let signupSheet = [];
|
||||||
|
|
||||||
check(name, String);
|
check(name, String);
|
||||||
check(description, String);
|
check(description, Match.Maybe(String));
|
||||||
// Match a positive integer or undefined/null.
|
// Match a positive integer or undefined/null.
|
||||||
check(signupLimit, Match.Where((x) => {
|
check(signupLimit, Match.Where((x) => {
|
||||||
check(x, Match.Maybe(Match.Integer));
|
check(x, Match.Maybe(Match.Integer));
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import Users from './pages/Users'
|
|||||||
import Admin from './pages/Admin'
|
import Admin from './pages/Admin'
|
||||||
import Home from './pages/Home'
|
import Home from './pages/Home'
|
||||||
import {StudentPage} from './pages/Student/StudentPage'
|
import {StudentPage} from './pages/Student/StudentPage'
|
||||||
import {Workshops} from './pages/Student/Workshops'
|
import {WorkshopList} from './pages/Student/WorkshopList'
|
||||||
|
|
||||||
const appTheme = createTheme({
|
const appTheme = createTheme({
|
||||||
components: {
|
components: {
|
||||||
@@ -92,7 +92,7 @@ export const App = (props) => {
|
|||||||
}/>
|
}/>
|
||||||
<Route path="/student" element={
|
<Route path="/student" element={
|
||||||
<StudentPage>
|
<StudentPage>
|
||||||
{user && <Workshops/>}
|
{user && <WorkshopList/>}
|
||||||
</StudentPage>
|
</StudentPage>
|
||||||
}/>
|
}/>
|
||||||
<Route path="/assignments/*" element={
|
<Route path="/assignments/*" element={
|
||||||
|
|||||||
122
imports/ui/components/RichText/Editor.jsx
Normal file
122
imports/ui/components/RichText/Editor.jsx
Normal file
@@ -0,0 +1,122 @@
|
|||||||
|
// import {RichTextPlugin} from "@lexical/react/LexicalRichTextPlugin";
|
||||||
|
// import {ContentEditable} from "@lexical/react/LexicalContentEditable";
|
||||||
|
// import {OnChangePlugin} from "@lexical/react/LexicalOnChangePlugin";
|
||||||
|
// import {HistoryPlugin} from "@lexical/react/LexicalHistoryPlugin";
|
||||||
|
// import {LinkPlugin} from "@lexical/react/LexicalLinkPlugin";
|
||||||
|
// import {MarkdownShortcutPlugin} from "@lexical/react/LexicalMarkdownShortcutPlugin";
|
||||||
|
// import {LexicalComposer} from "@lexical/react/LexicalComposer";
|
||||||
|
|
||||||
|
// import {AutoFocusPlugin} from '@lexical/react/LexicalAutoFocusPlugin';
|
||||||
|
// import {AutoScrollPlugin} from '@lexical/react/LexicalAutoScrollPlugin';
|
||||||
|
// import {CharacterLimitPlugin} from '@lexical/react/LexicalCharacterLimitPlugin';
|
||||||
|
// import {CheckListPlugin} from '@lexical/react/LexicalCheckListPlugin';
|
||||||
|
// import {ClearEditorPlugin} from '@lexical/react/LexicalClearEditorPlugin';
|
||||||
|
// import {CollaborationPlugin} from '@lexical/react/LexicalCollaborationPlugin';
|
||||||
|
// import {HashtagPlugin} from '@lexical/react/LexicalHashtagPlugin';
|
||||||
|
// import {ListPlugin} from '@lexical/react/LexicalListPlugin';
|
||||||
|
// // import {PlainTextPlugin} from '@lexical/react/LexicalPlainTextPlugin';
|
||||||
|
// import {TablePlugin} from '@lexical/react/LexicalTablePlugin';
|
||||||
|
|
||||||
|
// import {createWebsocketProvider} from './collaboration'
|
||||||
|
// import {useSettings} from './context/SettingsContext'
|
||||||
|
// import {useSharedHistoryContext} from './context/SharedHistoryContext'
|
||||||
|
// import TableCellNodes from './nodes/TableCellNodes'
|
||||||
|
// import ActionsPlugin from './plugins/ActionsPlugin'
|
||||||
|
// import AutocompletePlugin from './plugins/AutocompletePlugin'
|
||||||
|
// import AutoEmbedPlugin from './plugins/AutoEmbedPlugin'
|
||||||
|
// import AutoLinkPlugin from './plugins/AutoLinkPlugin'
|
||||||
|
// import ClickableLinkPlugin from './plugins/ClickableLinkPlugin'
|
||||||
|
// import CodeActionMenuPlugin from './plugins/CodeActionMenuPlugin';
|
||||||
|
// import CodeHighlightPlugin from './plugins/CodeHighlightPlugin'
|
||||||
|
// import CollapsiblePlugin from './plugins/CollapsiblePlugin'
|
||||||
|
// import CommentPlugin from './plugins/CommentPlugin'
|
||||||
|
// import ComponentPickerPlugin from './plugins/ComponentPickerPlugin'
|
||||||
|
// import DraggableBlockPlugin from './plugins/DraggableBlockPlugin'
|
||||||
|
// import EmojiPickerPlugin from './plugins/EmojiPickerPlugin'
|
||||||
|
// import EmojisPlugin from './plugins/EmojisPlugin'
|
||||||
|
// import EquationsPlugin from './plugins/EquationsPlugin'
|
||||||
|
// import ExcalidrawPlugin from './plugins/ExcalidrawPlugin'
|
||||||
|
// import FigmaPlugin from './plugins/FigmaPlugin'
|
||||||
|
// import FloatingLinkEditorPlugin from './plugins/FloatingLinkEditorPlugin'
|
||||||
|
// import FloatingTextFormatToolbarPlugin from './plugins/FloatingTextFormatToolbarPlugin'
|
||||||
|
// import HorizontalRulePlugin from './plugins/HorizontalRulePlugin'
|
||||||
|
// import ImagesPlugin from './plugins/ImagesPlugin'
|
||||||
|
// import KeywordsPlugin from './plugins/KeywordsPlugin'
|
||||||
|
// import ListMaxIndentLevelPlugin from './plugins/ListMaxIndentLevelPlugin'
|
||||||
|
// import MarkdownShortcutPlugin from './plugins/MarkdownShortcutPlugin'
|
||||||
|
// import {MaxLengthPlugin} from './plugins/MaxLengthPlugin'
|
||||||
|
// import MentionsPlugin from './plugins/MentionsPlugin'
|
||||||
|
// import PollPlugin from './plugins/PollPlugin'
|
||||||
|
// import SpeechToTextPlugin from './plugins/SpeechToTextPlugin'
|
||||||
|
// import TabFocusPlugin from './plugins/TabFocusPlugin'
|
||||||
|
// import TableCellActionMenuPlugin from './plugins/TableActionMenuPlugin'
|
||||||
|
// import TableCellResizer from './plugins/TableCellResizer'
|
||||||
|
// import TableOfContentsPlugin from './plugins/TableOfContentsPlugin'
|
||||||
|
// import {TablePlugin as NewTablePlugin} from './plugins/TablePlugin'
|
||||||
|
// import ToolbarPlugin from './plugins/ToolbarPlugin'
|
||||||
|
// import TreeViewPlugin from './plugins/TreeViewPlugin'
|
||||||
|
// import TwitterPlugin from './plugins/TwitterPlugin'
|
||||||
|
// import YouTubePlugin from './plugins/YouTubePlugin'
|
||||||
|
// import PlaygroundEditorTheme from './themes/PlaygroundEditorTheme'
|
||||||
|
// import ContentEditable from './ui/ContentEditable'
|
||||||
|
// import ErrorBoundary from './ui/ErrorBoundary'
|
||||||
|
// import Placeholder from './ui/Placeholder'
|
||||||
|
|
||||||
|
import * as React from 'react';
|
||||||
|
import {useRef, useState} from 'react';
|
||||||
|
import {
|
||||||
|
EditorComposer,
|
||||||
|
Editor as InternalEditor,
|
||||||
|
ToolbarPlugin,
|
||||||
|
AlignDropdown,
|
||||||
|
BackgroundColorPicker,
|
||||||
|
BoldButton,
|
||||||
|
CodeFormatButton,
|
||||||
|
FloatingLinkEditor,
|
||||||
|
FontFamilyDropdown,
|
||||||
|
FontSizeDropdown,
|
||||||
|
InsertDropdown,
|
||||||
|
InsertLinkButton,
|
||||||
|
ItalicButton,
|
||||||
|
TextColorPicker,
|
||||||
|
TextFormatDropdown,
|
||||||
|
UnderlineButton,
|
||||||
|
Divider,
|
||||||
|
} from 'verbum';
|
||||||
|
|
||||||
|
// import nodes from './Nodes'
|
||||||
|
|
||||||
|
export const Editor = (props) => {
|
||||||
|
return (
|
||||||
|
// <LexicalComposer initialConfig={{editorState: props.state, namespace: props.namespace, onError: props.onError, theme: props.theme, nodes}}>
|
||||||
|
// <ToolbarPlugin/>
|
||||||
|
// <RichTextPlugin contentEditable={<ContentEditable/>} placeholder={<div>Sample...</div>}/>
|
||||||
|
// {props.onChange && <OnChangePlugin onChange={props.onChange} ignoreSelectionChange={true}/>}
|
||||||
|
// <HistoryPlugin/>
|
||||||
|
// <LinkPlugin/>
|
||||||
|
// <MarkdownShortcutPlugin/>
|
||||||
|
// </LexicalComposer>
|
||||||
|
|
||||||
|
<EditorComposer>
|
||||||
|
<InternalEditor hashtagsEnabled={true} onChange={props.onChange} initialEditorState={props.state}>
|
||||||
|
<ToolbarPlugin defaultFontSize="20px">
|
||||||
|
<FontFamilyDropdown />
|
||||||
|
<FontSizeDropdown />
|
||||||
|
<Divider />
|
||||||
|
<BoldButton />
|
||||||
|
<ItalicButton />
|
||||||
|
<UnderlineButton />
|
||||||
|
<CodeFormatButton />
|
||||||
|
<InsertLinkButton />
|
||||||
|
<TextColorPicker />
|
||||||
|
<BackgroundColorPicker />
|
||||||
|
<TextFormatDropdown />
|
||||||
|
<Divider />
|
||||||
|
<InsertDropdown enablePoll={true} enableTable={true} />
|
||||||
|
<Divider />
|
||||||
|
<AlignDropdown />
|
||||||
|
</ToolbarPlugin>
|
||||||
|
</InternalEditor>
|
||||||
|
</EditorComposer>
|
||||||
|
)
|
||||||
|
}
|
||||||
65
imports/ui/components/RichText/Nodes.js
Normal file
65
imports/ui/components/RichText/Nodes.js
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
/*
|
||||||
|
import {CodeHighlightNode, CodeNode} from '@lexical/code';
|
||||||
|
import {HashtagNode} from '@lexical/hashtag';
|
||||||
|
import {AutoLinkNode, LinkNode} from '@lexical/link';
|
||||||
|
import {ListItemNode, ListNode} from '@lexical/list';
|
||||||
|
import {MarkNode} from '@lexical/mark';
|
||||||
|
import {OverflowNode} from '@lexical/overflow';
|
||||||
|
import {HorizontalRuleNode} from '@lexical/react/LexicalHorizontalRuleNode';
|
||||||
|
import {HeadingNode, QuoteNode} from '@lexical/rich-text';
|
||||||
|
import {TableCellNode, TableNode, TableRowNode} from '@lexical/table';
|
||||||
|
|
||||||
|
// import {CollapsibleContainerNode} from '../plugins/CollapsiblePlugin/CollapsibleContainerNode';
|
||||||
|
// import {CollapsibleContentNode} from '../plugins/CollapsiblePlugin/CollapsibleContentNode';
|
||||||
|
// import {CollapsibleTitleNode} from '../plugins/CollapsiblePlugin/CollapsibleTitleNode';
|
||||||
|
// import {AutocompleteNode} from './AutocompleteNode';
|
||||||
|
// import {EmojiNode} from './EmojiNode';
|
||||||
|
// import {EquationNode} from './EquationNode';
|
||||||
|
// import {ExcalidrawNode} from './ExcalidrawNode';
|
||||||
|
// import {FigmaNode} from './FigmaNode';
|
||||||
|
// import {ImageNode} from './ImageNode';
|
||||||
|
// import {KeywordNode} from './KeywordNode';
|
||||||
|
// import {MentionNode} from './MentionNode';
|
||||||
|
// import {PollNode} from './PollNode';
|
||||||
|
// import {StickyNode} from './StickyNode';
|
||||||
|
// import {TableNode as NewTableNode} from './TableNode';
|
||||||
|
// import {TweetNode} from './TweetNode';
|
||||||
|
// import {YouTubeNode} from './YouTubeNode';
|
||||||
|
|
||||||
|
const Nodes = [
|
||||||
|
HeadingNode,
|
||||||
|
ListNode,
|
||||||
|
ListItemNode,
|
||||||
|
QuoteNode,
|
||||||
|
CodeNode,
|
||||||
|
TableNode,
|
||||||
|
TableCellNode,
|
||||||
|
TableRowNode,
|
||||||
|
HashtagNode,
|
||||||
|
CodeHighlightNode,
|
||||||
|
AutoLinkNode,
|
||||||
|
LinkNode,
|
||||||
|
OverflowNode,
|
||||||
|
HorizontalRuleNode,
|
||||||
|
MarkNode,
|
||||||
|
// NewTableNode,
|
||||||
|
// PollNode,
|
||||||
|
// StickyNode,
|
||||||
|
// ImageNode,
|
||||||
|
// MentionNode,
|
||||||
|
// EmojiNode,
|
||||||
|
// ExcalidrawNode,
|
||||||
|
// EquationNode,
|
||||||
|
// AutocompleteNode,
|
||||||
|
// KeywordNode,
|
||||||
|
// TweetNode,
|
||||||
|
// YouTubeNode,
|
||||||
|
// FigmaNode,
|
||||||
|
// CollapsibleContainerNode,
|
||||||
|
// CollapsibleContentNode,
|
||||||
|
// CollapsibleTitleNode,
|
||||||
|
];
|
||||||
|
|
||||||
|
export default Nodes;
|
||||||
|
|
||||||
|
*/
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import React, { useState } from 'react';
|
import React, { useState, useEffect } from 'react';
|
||||||
import {Meteor} from "meteor/meteor";
|
import {Meteor} from "meteor/meteor";
|
||||||
import {Roles} from 'meteor/alanning:roles';
|
import {Roles} from 'meteor/alanning:roles';
|
||||||
import { useTracker } from 'meteor/react-meteor-data';
|
import { useTracker } from 'meteor/react-meteor-data';
|
||||||
@@ -16,11 +16,23 @@ import DialogActions from '@mui/material/DialogActions';
|
|||||||
import DialogContent from '@mui/material/DialogContent';
|
import DialogContent from '@mui/material/DialogContent';
|
||||||
import DialogContentText from '@mui/material/DialogContentText';
|
import DialogContentText from '@mui/material/DialogContentText';
|
||||||
import DialogTitle from '@mui/material/DialogTitle';
|
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 {Students} from "/imports/api/students";
|
||||||
import {Staff} from "/imports/api/staff";
|
import {Staff} from "/imports/api/staff";
|
||||||
import {conditions} from "/imports/api/assets";
|
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 = {
|
const cssTwoColumnContainer = {
|
||||||
display: 'grid',
|
display: 'grid',
|
||||||
@@ -29,7 +41,7 @@ const cssTwoColumnContainer = {
|
|||||||
rowGap: '0.4rem',
|
rowGap: '0.4rem',
|
||||||
}
|
}
|
||||||
|
|
||||||
export const Workshops = () => {
|
export const WorkshopList = () => {
|
||||||
Meteor.subscribe('students');
|
Meteor.subscribe('students');
|
||||||
Meteor.subscribe('staff');
|
Meteor.subscribe('staff');
|
||||||
Meteor.subscribe('workshops');
|
Meteor.subscribe('workshops');
|
||||||
@@ -58,46 +70,66 @@ export const Workshops = () => {
|
|||||||
backgroundColor: selectedWorkshop === item ? '#EECFA6' : 'white'
|
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 = () => {
|
const newWorkshop = () => {
|
||||||
if(isAdmin) {
|
if(isAdmin) {
|
||||||
|
setEditedDescription("")
|
||||||
setEditedWorkshop({})
|
setEditedWorkshop({})
|
||||||
|
setEditedDescription("")
|
||||||
|
setEditedName("")
|
||||||
|
setEditedSignupLimit("")
|
||||||
setOpenWorkshopEditor(true)
|
setOpenWorkshopEditor(true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const editWorkshop = () => {
|
const editWorkshop = () => {
|
||||||
if(isAdmin && selectedWorkshop) {
|
if(isAdmin && selectedWorkshop) {
|
||||||
setEditedWorkshop({...selectedWorkshop})
|
setEditedWorkshop({...selectedWorkshop})
|
||||||
|
setEditedDescription(selectedWorkshop.description ? selectedWorkshop.description : "")
|
||||||
|
setEditedName(selectedWorkshop.name ? selectedWorkshop.name : "")
|
||||||
|
setEditedSignupLimit(selectedWorkshop.signupLimit ? selectedWorkshop.signupLimit : "")
|
||||||
setOpenWorkshopEditor(true)
|
setOpenWorkshopEditor(true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const [openWorkshopEditor, setOpenWorkshopEditor] = useState(false)
|
|
||||||
const [editedWorkshop, setEditedWorkshop] = useState(false)
|
|
||||||
const workshopEditorClosed = (save) => {
|
const workshopEditorClosed = (save) => {
|
||||||
const completeHandler = (err, result) => {
|
const completeHandler = (err, result) => {
|
||||||
if(err) console.error(err)
|
if(err) console.error(err)
|
||||||
else {
|
else {
|
||||||
setOpenWorkshopEditor(false)
|
setOpenWorkshopEditor(false)
|
||||||
setEditedWorkshop(null)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(save) {
|
if(save) {
|
||||||
if(editedWorkshop._id) Meteor.call('workshops.update', editedWorkshop._id, 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', editedWorkshop.name, editedWorkshop.description, editedWorkshop.signupLimit, completeHandler)
|
else Meteor.call('workshops.add', editedName, editedDescription, editedSignupLimit, completeHandler)
|
||||||
}
|
}
|
||||||
else completeHandler()
|
else completeHandler()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const onLexicalComposerError = (err) => {
|
||||||
|
console.error(err)
|
||||||
|
}
|
||||||
|
const lexicalComposerTheme = {
|
||||||
|
|
||||||
|
}
|
||||||
|
const lexicalComposerChanged = (e) => {
|
||||||
|
console.log(e)
|
||||||
|
}
|
||||||
|
const descriptionEditorNodes = [LinkNode]
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Dialog open={openWorkshopEditor} onClose={workshopEditorClosed}>
|
<Dialog open={openWorkshopEditor} onClose={workshopEditorClosed}>
|
||||||
<DialogTitle>Workshop Editor</DialogTitle>
|
<DialogTitle>Workshop Editor</DialogTitle>
|
||||||
<DialogContent style={{display: 'flex', flexDirection: 'column'}}>
|
<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)}}/>
|
<TextField style={{marginTop: '1rem',minWidth: '30rem'}} variant="standard" label="Name" value={editedName} onChange={(e) => {setEditedName(e.target.value)}}/>
|
||||||
<Editor editorState={selectedWorkshop.description} toolbarClassName="editorToolbar" wrapperClassName="editorWrapper" editorClassName="editor" onEditorStateChange={(e) => {selectedWorkshop.description = e.target.value; setEditedWorkshop(editedWorkshop)}}/>
|
<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={editedWorkshop.signupLimit} onChange={(e) => {editedWorkshop.signupLimit = e.target.value; setEditedWorkshop(editedWorkshop)}}/>
|
<TextField style={{marginTop: '1rem',minWidth: '30rem'}} variant="standard" type="number" label="Signup Limit" value={editedSignupLimit} onChange={(e) => {setEditedSignupLimit(e.target.value)}}/>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
<DialogActions>
|
<DialogActions>
|
||||||
<Button onClick={() => workshopEditorClosed(true)}>Save</Button>
|
<Button onClick={() => workshopEditorClosed(true)}>Save</Button>
|
||||||
@@ -121,10 +153,10 @@ export const Workshops = () => {
|
|||||||
<Box style={{...cssTwoColumnContainer}}>
|
<Box style={{...cssTwoColumnContainer}}>
|
||||||
<Paper>
|
<Paper>
|
||||||
{/*<Editor editorState={selectedWorkshop.description} toolbarClassName="editorToolbar" wrapperClassName="editorWrapper" editorClassName="editor" onEditorStateChange={(e) => {selectedWorkshop.description = ""}}/>*/}
|
{/*<Editor editorState={selectedWorkshop.description} toolbarClassName="editorToolbar" wrapperClassName="editorWrapper" editorClassName="editor" onEditorStateChange={(e) => {selectedWorkshop.description = ""}}/>*/}
|
||||||
{`${selectedWorkshop.description}`}
|
{selectedWorkshop && `${selectedWorkshop.description}`}
|
||||||
</Paper>
|
</Paper>
|
||||||
<List>
|
<List>
|
||||||
{selectedWorkshop.signupSheet.map((next, i) => {
|
{selectedWorkshop && selectedWorkshop.signupSheet.map((next, i) => {
|
||||||
return (
|
return (
|
||||||
<ListItem key={next._id}>
|
<ListItem key={next._id}>
|
||||||
<ListItemText primary={next.data.firstName + " " + next.data.lastName} secondary={next.data.email}/>
|
<ListItemText primary={next.data.firstName + " " + next.data.lastName} secondary={next.data.email}/>
|
||||||
@@ -10,25 +10,29 @@
|
|||||||
"@babel/runtime": "^7.16.7",
|
"@babel/runtime": "^7.16.7",
|
||||||
"@emotion/react": "^11.10.0",
|
"@emotion/react": "^11.10.0",
|
||||||
"@emotion/styled": "^11.10.0",
|
"@emotion/styled": "^11.10.0",
|
||||||
|
"@lexical/headless": "^0.5.0",
|
||||||
|
"@lexical/link": "^0.5.0",
|
||||||
|
"@lexical/react": "^0.5.0",
|
||||||
"@mui/icons-material": "^5.10.2",
|
"@mui/icons-material": "^5.10.2",
|
||||||
"@mui/material": "^5.10.2",
|
"@mui/material": "^5.10.2",
|
||||||
"bcrypt": "^5.0.1",
|
"bcrypt": "^5.0.1",
|
||||||
"classnames": "^2.2.6",
|
"classnames": "^2.2.6",
|
||||||
"csv-parse": "^5.3.0",
|
"csv-parse": "^5.3.0",
|
||||||
"dayjs": "^1.11.3",
|
"dayjs": "^1.11.3",
|
||||||
"draft-js": "^0.11.7",
|
|
||||||
"html5-qrcode": "^2.2.0",
|
"html5-qrcode": "^2.2.0",
|
||||||
"jquery": "^3.6.0",
|
"jquery": "^3.6.0",
|
||||||
|
"lexical": "^0.5.0",
|
||||||
"lodash": "^4.17.15",
|
"lodash": "^4.17.15",
|
||||||
"meteor-node-stubs": "^1.0.0",
|
"meteor-node-stubs": "^1.0.0",
|
||||||
"moment": "^2.29.2",
|
"moment": "^2.29.2",
|
||||||
"mongodb": "^4.4.1",
|
"mongodb": "^4.4.1",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"react-draft-wysiwyg": "^1.15.0",
|
|
||||||
"react-router-dom": "^6.3.0",
|
"react-router-dom": "^6.3.0",
|
||||||
|
"typescript": "^4.8.4",
|
||||||
"umbrellajs": "^3.3.1",
|
"umbrellajs": "^3.3.1",
|
||||||
"underscore": "^1.13.2",
|
"underscore": "^1.13.2",
|
||||||
|
"verbum": "^0.4.0",
|
||||||
"winston": "^3.7.2",
|
"winston": "^3.7.2",
|
||||||
"winston-daily-rotate-file": "^4.6.1",
|
"winston-daily-rotate-file": "^4.6.1",
|
||||||
"ws": "^8.4.2"
|
"ws": "^8.4.2"
|
||||||
|
|||||||
182
public/images/student2.svg
Normal file
182
public/images/student2.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 8.3 MiB |
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
/* Basic Options */
|
/* Basic Options */
|
||||||
"target": "es2018",
|
"target": "es2019",
|
||||||
"module": "esNext",
|
"module": "esNext",
|
||||||
"lib": ["esnext", "dom"],
|
"lib": ["esnext", "dom"],
|
||||||
"allowJs": true,
|
"allowJs": true,
|
||||||
@@ -25,7 +25,7 @@
|
|||||||
"baseUrl": ".",
|
"baseUrl": ".",
|
||||||
"paths": {
|
"paths": {
|
||||||
/* Support absolute /imports/* with a leading '/' */
|
/* Support absolute /imports/* with a leading '/' */
|
||||||
"/*": ["*"]
|
"/*": ["*"],
|
||||||
},
|
},
|
||||||
"moduleResolution": "node",
|
"moduleResolution": "node",
|
||||||
"resolveJsonModule": true,
|
"resolveJsonModule": true,
|
||||||
@@ -33,6 +33,9 @@
|
|||||||
"esModuleInterop": true,
|
"esModuleInterop": true,
|
||||||
"preserveSymlinks": true
|
"preserveSymlinks": true
|
||||||
},
|
},
|
||||||
|
"include": [
|
||||||
|
"./imports/**"
|
||||||
|
],
|
||||||
"exclude": [
|
"exclude": [
|
||||||
"./.meteor/**",
|
"./.meteor/**",
|
||||||
"./packages/**"
|
"./packages/**"
|
||||||
|
|||||||
Reference in New Issue
Block a user