diff --git a/front/components/Canva/Canva.tsx b/front/components/Canva/Canva.tsx
new file mode 100644
index 00000000..81991667
--- /dev/null
+++ b/front/components/Canva/Canva.tsx
@@ -0,0 +1,32 @@
+import React from "react";
+import { useEditor, EditorContent } from "@tiptap/react";
+import StarterKit from "@tiptap/starter-kit";
+// Custom Extensions
+import InfoCallout from "../Editor/Extensions/Callout/Info/InfoCallout";
+
+interface Editor {
+ content: string;
+ element: any;
+ //course: any;
+}
+
+function Canva(props: Editor) {
+ const isEditable = false;
+ const editor: any = useEditor({
+ editable: isEditable,
+ extensions: [
+ StarterKit,
+
+ // Custom Extensions
+ InfoCallout.configure({
+ editable: isEditable,
+ }),
+ ],
+
+ content: props.content,
+ });
+
+ return ;
+}
+
+export default Canva;
diff --git a/front/components/Editor/Editor.tsx b/front/components/Editor/Editor.tsx
index d0fb944c..6f098fd9 100644
--- a/front/components/Editor/Editor.tsx
+++ b/front/components/Editor/Editor.tsx
@@ -10,8 +10,10 @@ import { motion, AnimatePresence } from "framer-motion";
import Image from "next/image";
import styled from "styled-components";
import { getBackendUrl } from "../../services/config";
-import { GlobeIcon, PaperPlaneIcon, SlashIcon } from "@radix-ui/react-icons";
+import { SlashIcon } from "@radix-ui/react-icons";
import Avvvatars from "avvvatars-react";
+// extensions
+import InfoCallout from "./Extensions/Callout/Info/InfoCallout";
interface Editor {
content: string;
@@ -26,23 +28,27 @@ function Editor(props: Editor) {
const auth: any = React.useContext(AuthContext);
const editor: any = useEditor({
+ editable: true,
extensions: [
StarterKit.configure({
// The Collaboration extension comes with its own history handling
- history: false,
+ // history: false,
+ }),
+ InfoCallout.configure({
+ editable: true,
}),
// Register the document with Tiptap
- Collaboration.configure({
- document: props.ydoc,
- }),
+ // Collaboration.configure({
+ // document: props.ydoc,
+ // }),
// Register the collaboration cursor extension
- CollaborationCursor.configure({
- provider: props.provider,
- user: {
- name: auth.userInfo.username,
- color: "#f783ac",
- },
- }),
+ // CollaborationCursor.configure({
+ // provider: props.provider,
+ // user: {
+ // name: auth.userInfo.username,
+ // color: "#f783ac",
+ // },
+ // }),
],
content: props.content,
@@ -65,15 +71,13 @@ function Editor(props: Editor) {
-
+
{" "}
{props.course.course.name} {props.element.name}{" "}
- props.setContent(editor.getJSON())}>
- Save
-
+ props.setContent(editor.getJSON())}>Save
@@ -90,7 +94,6 @@ function Editor(props: Editor) {
);
}
+
const Page = styled.div`
height: 100vh;
width: 100%;
@@ -113,13 +117,13 @@ const Page = styled.div`
min-width: 100vw;
padding-top: 30px;
- // dots background
+ // dots background
background-image: radial-gradient(#4744446b 1px, transparent 1px), radial-gradient(#4744446b 1px, transparent 1px);
background-position: 0 0, 25px 25px;
background-size: 50px 50px;
background-attachment: fixed;
background-repeat: repeat;
-`
+`;
const EditorTop = styled.div`
background-color: #ffffffb8;
diff --git a/front/components/Editor/Extensions/Callout/Info/InfoCallout.ts b/front/components/Editor/Extensions/Callout/Info/InfoCallout.ts
new file mode 100644
index 00000000..a12aaf45
--- /dev/null
+++ b/front/components/Editor/Extensions/Callout/Info/InfoCallout.ts
@@ -0,0 +1,27 @@
+import { mergeAttributes, Node } from "@tiptap/core";
+import { ReactNodeViewRenderer } from "@tiptap/react";
+
+import InfoCalloutComponent from "./InfoCalloutComponent";
+
+export default Node.create({
+ name: "calloutInfo",
+ group: "block",
+ draggable: true,
+ content: "inline*",
+
+ parseHTML() {
+ return [
+ {
+ tag: "callout-info",
+ },
+ ];
+ },
+
+ renderHTML({ HTMLAttributes }) {
+ return ["callout-info", mergeAttributes(HTMLAttributes), 0];
+ },
+
+ addNodeView() {
+ return ReactNodeViewRenderer(InfoCalloutComponent);
+ },
+});
diff --git a/front/components/Editor/Extensions/Callout/Info/InfoCalloutComponent.tsx b/front/components/Editor/Extensions/Callout/Info/InfoCalloutComponent.tsx
new file mode 100644
index 00000000..7ef60f05
--- /dev/null
+++ b/front/components/Editor/Extensions/Callout/Info/InfoCalloutComponent.tsx
@@ -0,0 +1,45 @@
+import { NodeViewContent, NodeViewWrapper } from "@tiptap/react";
+import React from "react";
+import styled from "styled-components";
+
+function InfoCalloutComponent(props: any) {
+ return (
+
+
+ ⚠️
+
+
+ );
+}
+
+const InfoCalloutWrapper = styled.div`
+ display: flex;
+ flex-direction: row;
+ background: #fefce8;
+ color: #713f11;
+ border: 1px solid #fff103;
+ border-radius: 16px;
+ margin: 1rem 0;
+ align-items: center;
+ padding-left: 15px;
+
+
+ .content {
+ margin: 5px;
+ padding: 0.5rem;
+ border: ${(props) => (props.contentEditable ? "2px dashed #713f1117" : "none")};
+ border-radius: 0.5rem;
+ }
+`;
+
+const DragHandle = styled.div`
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 1rem;
+ height: 100%;
+ cursor: move;
+ z-index: 1;
+`;
+
+export default InfoCalloutComponent;
diff --git a/front/components/Editor/Toolbar/ToolbarButtons.tsx b/front/components/Editor/Toolbar/ToolbarButtons.tsx
index 3e682fbc..995a4a03 100644
--- a/front/components/Editor/Toolbar/ToolbarButtons.tsx
+++ b/front/components/Editor/Toolbar/ToolbarButtons.tsx
@@ -1,5 +1,6 @@
import styled from "styled-components";
-import { FontBoldIcon, FontItalicIcon, StrikethroughIcon, ArrowLeftIcon, ArrowRightIcon } from "@radix-ui/react-icons";
+import { FontBoldIcon, FontItalicIcon, StrikethroughIcon, ArrowLeftIcon, ArrowRightIcon, OpacityIcon } from "@radix-ui/react-icons";
+import { AlertTriangle, Info } from "lucide-react";
export const ToolbarButtons = ({ editor }: any) => {
if (!editor) {
@@ -31,6 +32,10 @@ export const ToolbarButtons = ({ editor }: any) => {
+ {/* TODO: fix this : toggling only works one-way */}
+ editor.chain().focus().toggleNode('calloutInfo').run()} >
+
+
);
};
@@ -49,10 +54,13 @@ const ToolBtn = styled.div`
width: 25px;
height: 25px;
padding: 5px;
- font-size: 5px;
margin-right: 5px;
transition: all 0.2s ease-in-out;
+ svg{
+ padding: 1px;
+ }
+
&.is-active {
background: rgba(176, 176, 176, 0.5);
diff --git a/front/package-lock.json b/front/package-lock.json
index 4542cc72..a342a827 100644
--- a/front/package-lock.json
+++ b/front/package-lock.json
@@ -17,6 +17,7 @@
"@tiptap/starter-kit": "^2.0.0-beta.199",
"avvvatars-react": "^0.4.2",
"framer-motion": "^7.3.6",
+ "lucide-react": "^0.104.1",
"next": "12.3.1",
"react": "18.2.0",
"react-beautiful-dnd": "^13.1.1",
@@ -3532,6 +3533,15 @@
"node": ">=10"
}
},
+ "node_modules/lucide-react": {
+ "version": "0.104.1",
+ "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.104.1.tgz",
+ "integrity": "sha512-BKvhulnLKmBj+6pqUN5ViYk4a5fabMgc4B0a4ZLUnbRqkDDWH3h7Iet6U4WbesJzjWauQrXUlEvQCe5XpFuRnw==",
+ "peerDependencies": {
+ "prop-types": "^15.7.2",
+ "react": "^16.5.1 || ^17.0.0 || ^18.0.0"
+ }
+ },
"node_modules/memoize-one": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz",
@@ -7577,6 +7587,12 @@
"yallist": "^4.0.0"
}
},
+ "lucide-react": {
+ "version": "0.104.1",
+ "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.104.1.tgz",
+ "integrity": "sha512-BKvhulnLKmBj+6pqUN5ViYk4a5fabMgc4B0a4ZLUnbRqkDDWH3h7Iet6U4WbesJzjWauQrXUlEvQCe5XpFuRnw==",
+ "requires": {}
+ },
"memoize-one": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz",
diff --git a/front/package.json b/front/package.json
index ec6ffb14..1f7280a8 100644
--- a/front/package.json
+++ b/front/package.json
@@ -18,6 +18,7 @@
"@tiptap/starter-kit": "^2.0.0-beta.199",
"avvvatars-react": "^0.4.2",
"framer-motion": "^7.3.6",
+ "lucide-react": "^0.104.1",
"next": "12.3.1",
"react": "18.2.0",
"react-beautiful-dnd": "^13.1.1",
diff --git a/front/pages/index.tsx b/front/pages/index.tsx
index 0fe7549e..cf64a4ae 100644
--- a/front/pages/index.tsx
+++ b/front/pages/index.tsx
@@ -4,12 +4,10 @@ import styled from "styled-components";
import learnhouseBigIcon from "public/learnhouse_bigicon.png";
import Image from "next/image";
import Link from "next/link";
-import { PreAlphaLabel } from "../components//UI/Layout";
const Home: NextPage = () => {
return (
- 🚧 Pre-Alpha
{
- if (router.isReady && !isLoading) {
- console.log(element);
-
- if (element.type == "dynamic") {
- let content =
- Object.keys(element.content).length > 0
- ? element.content
- : {
- type: "doc",
- content: [
- {
- type: "paragraph",
- content: [
- {
- type: "text",
- text: "Hello world, this is a example Canva ⚡️",
- },
- ],
- },
- ],
- };
- console.log("element", content);
-
- return generateHTML(content, [Document, StarterKit, Paragraph, Text, Bold]);
- }
- }
- }, [element.content]);
-
return (
{isLoading ? (
@@ -69,7 +35,7 @@ function ElementPage() {
{element.name}
- {element.type == "dynamic" && }
+ {element.type == "dynamic" && }
{/* todo : use apis & streams instead of this */}
{element.type == "video" && (
diff --git a/front/tsconfig.json b/front/tsconfig.json
index 99710e85..b8d3d81d 100644
--- a/front/tsconfig.json
+++ b/front/tsconfig.json
@@ -16,5 +16,12 @@
"incremental": true
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
+ "paths": {
+ "@components/*": ["components/*"],
+ "@public/*": ["public/*"],
+ "@images/*": ["public/img/*"],
+ "@services/*": ["services/*"],
+ "@editor/*": ["components/Editor/*"]
+ },
"exclude": ["node_modules"]
}