mirror of
https://github.com/rzmk/learnhouse.git
synced 2025-12-19 04:19:25 +00:00
feat: add animations and avatar to editor
This commit is contained in:
parent
f349378ff9
commit
2995c8ec84
2 changed files with 87 additions and 36 deletions
|
|
@ -6,10 +6,12 @@ import CollaborationCursor from "@tiptap/extension-collaboration-cursor";
|
||||||
import { AuthContext } from "../Security/AuthProvider";
|
import { AuthContext } from "../Security/AuthProvider";
|
||||||
import learnhouseIcon from "public/learnhouse_icon.png";
|
import learnhouseIcon from "public/learnhouse_icon.png";
|
||||||
import { ToolbarButtons } from "./Toolbar/ToolbarButtons";
|
import { ToolbarButtons } from "./Toolbar/ToolbarButtons";
|
||||||
|
import { motion, AnimatePresence } from "framer-motion";
|
||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
import styled from "styled-components";
|
import styled from "styled-components";
|
||||||
import { getBackendUrl } from "../../services/config";
|
import { getBackendUrl } from "../../services/config";
|
||||||
import { RocketIcon, SlashIcon, TriangleLeftIcon, TriangleRightIcon } from "@radix-ui/react-icons";
|
import { GlobeIcon, SlashIcon } from "@radix-ui/react-icons";
|
||||||
|
import Avvvatars from "avvvatars-react";
|
||||||
|
|
||||||
interface Editor {
|
interface Editor {
|
||||||
content: string;
|
content: string;
|
||||||
|
|
@ -50,28 +52,58 @@ function Editor(props: Editor) {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<EditorTop>
|
<motion.div
|
||||||
<EditorDocSection>
|
initial={{ opacity: 0, scale: 0.9 }}
|
||||||
<EditorInfoWrapper>
|
animate={{ opacity: 1, scale: 1 }}
|
||||||
<EditorInfoLearnHouseLogo width={23} height={23} src={learnhouseIcon} alt="" />
|
key="modal"
|
||||||
<EditorInfoThumbnail src={`${getBackendUrl()}content/uploads/img/${props.course.course.thumbnail}`} alt=""></EditorInfoThumbnail>
|
transition={{
|
||||||
<EditorInfoDocName>
|
type: "spring",
|
||||||
{" "}
|
stiffness: 360,
|
||||||
<b>{props.course.course.name}</b> <SlashIcon /> {props.element.name}{" "}
|
damping: 70,
|
||||||
</EditorInfoDocName>
|
delay: 0.02,
|
||||||
<EditorSaveButton onClick={() => props.setContent(editor.getJSON())}>
|
}}
|
||||||
<RocketIcon></RocketIcon>
|
exit={{ opacity: 0 }}
|
||||||
</EditorSaveButton>
|
>
|
||||||
</EditorInfoWrapper>
|
<EditorTop>
|
||||||
<EditorButtonsWrapper>
|
<EditorDocSection>
|
||||||
<ToolbarButtons editor={editor} />
|
<EditorInfoWrapper>
|
||||||
</EditorButtonsWrapper>
|
<EditorInfoLearnHouseLogo width={23} height={23} src={learnhouseIcon} alt="" />
|
||||||
</EditorDocSection>
|
<EditorInfoThumbnail src={`${getBackendUrl()}content/uploads/img/${props.course.course.thumbnail}`} alt=""></EditorInfoThumbnail>
|
||||||
<EditorUsersSection></EditorUsersSection>
|
<EditorInfoDocName>
|
||||||
</EditorTop>
|
{" "}
|
||||||
|
<b>{props.course.course.name}</b> <SlashIcon /> {props.element.name}{" "}
|
||||||
|
</EditorInfoDocName>
|
||||||
|
<EditorSaveButton onClick={() => props.setContent(editor.getJSON())}>
|
||||||
|
<GlobeIcon></GlobeIcon>
|
||||||
|
</EditorSaveButton>
|
||||||
|
</EditorInfoWrapper>
|
||||||
|
<EditorButtonsWrapper>
|
||||||
|
<ToolbarButtons editor={editor} />
|
||||||
|
</EditorButtonsWrapper>
|
||||||
|
</EditorDocSection>
|
||||||
|
<EditorUsersSection>
|
||||||
|
<EditorUserProfileWrapper>
|
||||||
|
<Avvvatars value={auth.userInfo.user_object.user_id} style="shape" />
|
||||||
|
</EditorUserProfileWrapper>
|
||||||
|
</EditorUsersSection>
|
||||||
|
</EditorTop>
|
||||||
|
</motion.div>
|
||||||
|
<motion.div
|
||||||
|
initial={{ opacity: 0, scale: 0.9 }}
|
||||||
|
animate={{ opacity: 1, scale: 1 }}
|
||||||
|
key="modal"
|
||||||
|
transition={{
|
||||||
|
type: "spring",
|
||||||
|
stiffness: 360,
|
||||||
|
damping: 70,
|
||||||
|
delay: 0.5,
|
||||||
|
}}
|
||||||
|
exit={{ opacity: 0 }}
|
||||||
|
>
|
||||||
<EditorContentWrapper>
|
<EditorContentWrapper>
|
||||||
<EditorContent editor={editor} />
|
<EditorContent editor={editor} />
|
||||||
</EditorContentWrapper>
|
</EditorContentWrapper>
|
||||||
|
</motion.div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -82,6 +114,12 @@ const EditorTop = styled.div`
|
||||||
margin: 40px;
|
margin: 40px;
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
box-shadow: 0px 4px 16px rgba(0, 0, 0, 0.03);
|
||||||
|
//position: fixed;
|
||||||
|
z-index: 3;
|
||||||
|
width: -webkit-fill-available;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
// Inside EditorTop
|
// Inside EditorTop
|
||||||
|
|
@ -92,6 +130,8 @@ const EditorDocSection = styled.div`
|
||||||
const EditorUsersSection = styled.div`
|
const EditorUsersSection = styled.div`
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
// Inside EditorDocSection
|
// Inside EditorDocSection
|
||||||
|
|
@ -103,7 +143,12 @@ const EditorInfoWrapper = styled.div`
|
||||||
const EditorButtonsWrapper = styled.div``;
|
const EditorButtonsWrapper = styled.div``;
|
||||||
|
|
||||||
// Inside EditorUsersSection
|
// Inside EditorUsersSection
|
||||||
const EditorUserProfileWrapper = styled.div``;
|
const EditorUserProfileWrapper = styled.div`
|
||||||
|
padding-right: 8px;
|
||||||
|
svg {
|
||||||
|
border-radius: 7px;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
// Inside EditorInfoWrapper
|
// Inside EditorInfoWrapper
|
||||||
//..todo
|
//..todo
|
||||||
|
|
@ -117,11 +162,13 @@ const EditorInfoDocName = styled.div`
|
||||||
align-items: center;
|
align-items: center;
|
||||||
display: flex;
|
display: flex;
|
||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
|
color: #494949;
|
||||||
|
|
||||||
svg {
|
svg {
|
||||||
margin-left: 4px;
|
margin-left: 4px;
|
||||||
margin-right: 4px;
|
margin-right: 4px;
|
||||||
color: #909090;
|
padding: 3px;
|
||||||
|
color: #353535;
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
|
@ -161,20 +208,24 @@ const EditorInfoThumbnail = styled.img`
|
||||||
|
|
||||||
const EditorContentWrapper = styled.div`
|
const EditorContentWrapper = styled.div`
|
||||||
margin: 40px;
|
margin: 40px;
|
||||||
|
margin-top: 20px;
|
||||||
background-color: white;
|
background-color: white;
|
||||||
|
border-radius: 10px;
|
||||||
|
box-shadow: 0px 4px 16px rgba(0, 0, 0, 0.03);
|
||||||
|
|
||||||
// disable chrome outline
|
// disable chrome outline
|
||||||
|
|
||||||
|
|
||||||
.ProseMirror {
|
.ProseMirror {
|
||||||
padding: 10px;
|
padding-left: 20px;
|
||||||
|
padding-right: 20px;
|
||||||
|
padding-bottom: 6px;
|
||||||
|
padding-top: 1px;
|
||||||
&:focus {
|
&:focus {
|
||||||
outline: none !important;
|
outline: none !important;
|
||||||
outline-style: none !important;
|
outline-style: none !important;
|
||||||
box-shadow: none !important;
|
box-shadow: none !important;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export default Editor;
|
export default Editor;
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,12 @@ export const ToolbarButtons = ({ editor }: any) => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ToolButtonsWrapper>
|
<ToolButtonsWrapper>
|
||||||
|
<ToolBtn onClick={() => editor.chain().focus().undo().run()}>
|
||||||
|
<ArrowLeftIcon />
|
||||||
|
</ToolBtn>
|
||||||
|
<ToolBtn onClick={() => editor.chain().focus().redo().run()}>
|
||||||
|
<ArrowRightIcon />
|
||||||
|
</ToolBtn>
|
||||||
<ToolBtn onClick={() => editor.chain().focus().toggleBold().run()} className={editor.isActive("bold") ? "is-active" : ""}>
|
<ToolBtn onClick={() => editor.chain().focus().toggleBold().run()} className={editor.isActive("bold") ? "is-active" : ""}>
|
||||||
<FontBoldIcon />
|
<FontBoldIcon />
|
||||||
</ToolBtn>
|
</ToolBtn>
|
||||||
|
|
@ -17,13 +23,6 @@ export const ToolbarButtons = ({ editor }: any) => {
|
||||||
<ToolBtn onClick={() => editor.chain().focus().toggleStrike().run()} className={editor.isActive("strike") ? "is-active" : ""}>
|
<ToolBtn onClick={() => editor.chain().focus().toggleStrike().run()} className={editor.isActive("strike") ? "is-active" : ""}>
|
||||||
<StrikethroughIcon />
|
<StrikethroughIcon />
|
||||||
</ToolBtn>
|
</ToolBtn>
|
||||||
|
|
||||||
<ToolBtn onClick={() => editor.chain().focus().undo().run()}>
|
|
||||||
<ArrowLeftIcon />
|
|
||||||
</ToolBtn>
|
|
||||||
<ToolBtn onClick={() => editor.chain().focus().redo().run()}>
|
|
||||||
<ArrowRightIcon />
|
|
||||||
</ToolBtn>
|
|
||||||
<ToolSelect onChange={(e) => editor.chain().focus().toggleHeading({ level: parseInt(e.target.value) }).run() }>
|
<ToolSelect onChange={(e) => editor.chain().focus().toggleHeading({ level: parseInt(e.target.value) }).run() }>
|
||||||
<option value="1">Heading 1</option>
|
<option value="1">Heading 1</option>
|
||||||
<option value="2">Heading 2</option>
|
<option value="2">Heading 2</option>
|
||||||
|
|
@ -52,6 +51,7 @@ const ToolBtn = styled.div`
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
font-size: 5px;
|
font-size: 5px;
|
||||||
margin-right: 5px;
|
margin-right: 5px;
|
||||||
|
transition: all 0.2s ease-in-out;
|
||||||
|
|
||||||
&.is-active {
|
&.is-active {
|
||||||
background: rgba(176, 176, 176, 0.5);
|
background: rgba(176, 176, 176, 0.5);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue