diff --git a/front/components/modals/CourseEdit/NewElement.tsx b/front/components/modals/CourseEdit/NewElement.tsx
index 6903a210..e8a0f4ae 100644
--- a/front/components/modals/CourseEdit/NewElement.tsx
+++ b/front/components/modals/CourseEdit/NewElement.tsx
@@ -1,39 +1,62 @@
import React, { useState } from "react";
+import { ArrowLeftIcon, Cross1Icon } from "@radix-ui/react-icons";
import Modal from "../Modal";
+import styled from "styled-components";
+import dynamic from "next/dynamic";
+import DynamicCanvaModal from "./NewElementModal/DynamicCanva";
+import VideoModal from "./NewElementModal/Video";
-function NewElementModal({ closeModal, submitElement, chapterId }: any) {
- const [elementName, setElementName] = useState("");
- const [elementDescription, setElementDescription] = useState("");
-
- const handleElementNameChange = (e: any) => {
- setElementName(e.target.value);
- };
-
- const handleElementDescriptionChange = (e: any) => {
- setElementDescription(e.target.value);
- };
-
- const handleSubmit = async (e: any) => {
- e.preventDefault();
- console.log({ elementName, elementDescription, chapterId });
- submitElement({
- name: elementName,
- chapterId: chapterId,
- type: "dynamic",
- });
- };
+function NewElementModal({ closeModal, submitElement, submitFileElement, chapterId }: any) {
+ const [selectedView, setSelectedView] = useState("home");
return (
-
- Add New Element
-
-
-
+
+
+ Add New Element
-
+
+ {selectedView === "home" && (
+
+ {setSelectedView("dynamic")}}>✨📄
+ {setSelectedView("video")}}>📹
+
+ )}
+
+ {selectedView === "dynamic" && (
+
+ )}
+
+ {selectedView === "video" && (
+
+ )}
+
);
}
+const ElementChooserWrapper = styled.div`
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ justify-content: center;
+ gap: 20px;
+`;
+
+const ElementButton = styled.button`
+ padding: 20px;
+ border-radius: 10px;
+ border: none;
+ font-size: 50px;
+ background-color: #8c949c33;
+ cursor: pointer;
+ &:hover {
+ background-color: #8c949c7b;
+ }
+`;
+
export default NewElementModal;
diff --git a/front/components/modals/CourseEdit/NewElementModal/DynamicCanva.tsx b/front/components/modals/CourseEdit/NewElementModal/DynamicCanva.tsx
new file mode 100644
index 00000000..5caf5577
--- /dev/null
+++ b/front/components/modals/CourseEdit/NewElementModal/DynamicCanva.tsx
@@ -0,0 +1,36 @@
+import React, { useState } from "react";
+
+function DynamicCanvaModal({ submitElement, chapterId }: any) {
+ const [elementName, setElementName] = useState("");
+ const [elementDescription, setElementDescription] = useState("");
+
+ const handleElementNameChange = (e: any) => {
+ setElementName(e.target.value);
+ };
+
+ const handleElementDescriptionChange = (e: any) => {
+ setElementDescription(e.target.value);
+ };
+
+ const handleSubmit = async (e: any) => {
+ e.preventDefault();
+ console.log({ elementName, elementDescription, chapterId });
+ submitElement({
+ name: elementName,
+ chapterId: chapterId,
+ type: "dynamic",
+ });
+ };
+ return (
+
+ );
+}
+
+export default DynamicCanvaModal;
diff --git a/front/components/modals/CourseEdit/NewElementModal/Video.tsx b/front/components/modals/CourseEdit/NewElementModal/Video.tsx
new file mode 100644
index 00000000..fce8f192
--- /dev/null
+++ b/front/components/modals/CourseEdit/NewElementModal/Video.tsx
@@ -0,0 +1,37 @@
+import React from "react";
+
+function VideoModal({ submitFileElement, chapterId }: any) {
+ const [video, setVideo] = React.useState(null) as any;
+ const [name, setName] = React.useState("");
+
+ const handleVideoChange = (event: React.ChangeEvent) => {
+ setVideo(event.target.files[0]);
+ };
+
+ const handleNameChange = (event: React.ChangeEvent) => {
+ setName(event.target.value);
+ };
+
+ const handleSubmit = async (e: any) => {
+ e.preventDefault();
+ let status = await submitFileElement(video, "video", { name, type: "video" }, chapterId);
+ };
+
+ /* TODO : implement some sort of progress bar for file uploads, it is not possible yet because i'm not using axios.
+ and the actual upload isn't happening here anyway, it's in the submitFileElement function */
+
+ return (
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+export default VideoModal;
diff --git a/front/pages/org/[orgslug]/course/[courseid]/edit/index.tsx b/front/pages/org/[orgslug]/course/[courseid]/edit/index.tsx
index 50f0e1d2..17574061 100644
--- a/front/pages/org/[orgslug]/course/[courseid]/edit/index.tsx
+++ b/front/pages/org/[orgslug]/course/[courseid]/edit/index.tsx
@@ -11,7 +11,7 @@ import { createChapter, deleteChapter, getCourseChaptersMetadata, updateChapters
import { useRouter } from "next/router";
import NewChapterModal from "../../../../../../components/modals/CourseEdit/NewChapter";
import NewElementModal from "../../../../../../components/modals/CourseEdit/NewElement";
-import { createElement } from "../../../../../../services/courses/elements";
+import { createElement, createFileElement } from "../../../../../../services/courses/elements";
function CourseEdit() {
const router = useRouter();
@@ -79,6 +79,15 @@ function CourseEdit() {
setNewElementModal(false);
};
+ // Submit File Upload
+ const submitFileElement = async (file: any, type: any, element: any, chapterId: string) => {
+ console.log("submitFileElement", file);
+ await updateChaptersMetadata(courseid, data);
+ await createFileElement(file, type, element, chapterId);
+ await getCourseChapters();
+ setNewElementModal(false);
+ };
+
const deleteChapterUI = async (chapterId: any) => {
console.log("deleteChapter", chapterId);
await deleteChapter(chapterId);
@@ -87,7 +96,7 @@ function CourseEdit() {
const updateChapters = () => {
console.log(data);
- updateChaptersMetadata(courseid,data);
+ updateChaptersMetadata(courseid, data);
};
/*
@@ -234,7 +243,14 @@ function CourseEdit() {
{newChapterModal && }
- {newElementModal && }
+ {newElementModal && (
+
+ )}
{winReady && (
diff --git a/front/services/courses/elements.ts b/front/services/courses/elements.ts
index e0228b20..cf4b2777 100644
--- a/front/services/courses/elements.ts
+++ b/front/services/courses/elements.ts
@@ -1,59 +1,100 @@
import { getAPIUrl } from "../config";
export async function createElement(data: any, chapter_id: any) {
- data.content = {}
- console.log("data", data, chapter_id);
+ data.content = {};
+ console.log("data", data, chapter_id);
- // remove chapter_id from data
- delete data.chapterId;
-
- const HeadersConfig = new Headers({ "Content-Type": "application/json" });
+ // remove chapter_id from data
+ delete data.chapterId;
+
+ const HeadersConfig = new Headers({ "Content-Type": "application/json" });
+
+ const requestOptions: any = {
+ method: "POST",
+ headers: HeadersConfig,
+ redirect: "follow",
+ credentials: "include",
+ body: JSON.stringify(data),
+ };
+
+ const result: any = await fetch(`${getAPIUrl()}elements/?coursechapter_id=${chapter_id}`, requestOptions)
+ .then((result) => result.json())
+ .catch((error) => console.log("error", error));
+
+ console.log("result", result);
+
+ return result;
+}
+
+export async function createFileElement(file: File, type: string, data: any, chapter_id: any) {
- const requestOptions: any = {
- method: "POST",
- headers: HeadersConfig,
- redirect: "follow",
- credentials: "include",
- body: JSON.stringify(data),
- };
+
+ const HeadersConfig = new Headers();
+
+ // Send file thumbnail as form data
+ const formData = new FormData();
+ formData.append("coursechapter_id", chapter_id);
+ console.log("type" , type);
- const result: any = await fetch(`${getAPIUrl()}elements/?coursechapter_id=${chapter_id}`, requestOptions)
- .then((result) => result.json())
- .catch((error) => console.log("error", error));
-
- console.log("result", result);
-
- return result;
+
+ let endpoint = `${getAPIUrl()}elements/video`;
+
+ if (type === "video") {
+ formData.append("name", data.name);
+ formData.append("video_file", file);
+ endpoint = `${getAPIUrl()}elements/video`;
}
- export async function getElement(element_id: any) {
- const requestOptions: any = {
- method: "GET",
- redirect: "follow",
- credentials: "include",
- };
+ console.log();
- const result: any = await fetch(`${getAPIUrl()}elements/${element_id}`, requestOptions)
- .then((result) => result.json())
- .catch((error) => console.log("error", error));
-
- return result;
- }
- export async function updateElement(data: any, element_id: any) {
- const HeadersConfig = new Headers({ "Content-Type": "application/json" });
+ const requestOptions: any = {
+ method: "POST",
+ headers: HeadersConfig,
+ redirect: "follow",
+ credentials: "include",
+ body: formData,
+ };
+
+ const result: any = await fetch(endpoint, requestOptions)
+ .then((result) => result.json())
+ .catch((error) => console.log("error", error));
+
- const requestOptions: any = {
- method: "PUT",
- headers: HeadersConfig,
- redirect: "follow",
- credentials: "include",
- body: JSON.stringify(data),
- };
- const result: any = await fetch(`${getAPIUrl()}elements/${element_id}`, requestOptions)
- .then((result) => result.json())
- .catch((error) => console.log("error", error));
-
- return result;
- }
\ No newline at end of file
+ console.log("result", result);
+
+ return result;
+}
+
+export async function getElement(element_id: any) {
+ const requestOptions: any = {
+ method: "GET",
+ redirect: "follow",
+ credentials: "include",
+ };
+
+ const result: any = await fetch(`${getAPIUrl()}elements/${element_id}`, requestOptions)
+ .then((result) => result.json())
+ .catch((error) => console.log("error", error));
+
+ return result;
+}
+
+export async function updateElement(data: any, element_id: any) {
+ const HeadersConfig = new Headers({ "Content-Type": "application/json" });
+
+ const requestOptions: any = {
+ method: "PUT",
+ headers: HeadersConfig,
+ redirect: "follow",
+ credentials: "include",
+ body: JSON.stringify(data),
+ };
+
+ const result: any = await fetch(`${getAPIUrl()}elements/${element_id}`, requestOptions)
+ .then((result) => result.json())
+ .catch((error) => console.log("error", error));
+
+ return result;
+}