mirror of
https://github.com/rzmk/learnhouse.git
synced 2025-12-19 04:19:25 +00:00
feat: add elements
This commit is contained in:
parent
938cfcb4b3
commit
6f2cc5bdc6
23 changed files with 241 additions and 104 deletions
|
|
@ -1,36 +1,28 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import styled from "styled-components";
|
import styled from "styled-components";
|
||||||
import { DragDropContext, Droppable, Draggable } from "react-beautiful-dnd";
|
import { DragDropContext, Droppable, Draggable } from "react-beautiful-dnd";
|
||||||
import Element, { ElementWrapper } from "./element";
|
import Element, { ElementWrapper } from "./Element";
|
||||||
import Link from "next/link";
|
|
||||||
import { motion } from "framer-motion";
|
|
||||||
|
|
||||||
const ChapterWrapper = styled.div`
|
|
||||||
margin-bottom: 5px;
|
|
||||||
padding: 11px;
|
|
||||||
background-color: #00000010;
|
|
||||||
width: 310px;
|
|
||||||
display: block;
|
|
||||||
border-radius: 9px;
|
|
||||||
border: 1px solid rgba(255, 255, 255, 0.19);
|
|
||||||
box-shadow: 0px 13px 33px -13px rgb(0 0 0 / 12%);
|
|
||||||
transition: all 0.2s ease;
|
|
||||||
`;
|
|
||||||
|
|
||||||
function Chapter(props: any) {
|
function Chapter(props: any) {
|
||||||
return (
|
return (
|
||||||
<Draggable key={props.info.list.chapter.id} draggableId={props.info.list.chapter.id} index={props.index}>
|
<Draggable key={props.info.list.chapter.id} draggableId={props.info.list.chapter.id} index={props.index}>
|
||||||
{(provided, snapshot) => (
|
{(provided, snapshot) => (
|
||||||
|
|
||||||
<ChapterWrapper
|
<ChapterWrapper
|
||||||
{...provided.dragHandleProps}
|
{...provided.dragHandleProps}
|
||||||
{...provided.draggableProps}
|
{...provided.draggableProps}
|
||||||
ref={provided.innerRef}
|
ref={provided.innerRef}
|
||||||
isDragging={snapshot.isDragging}
|
// isDragging={snapshot.isDragging}
|
||||||
key={props.info.list.chapter.id}
|
key={props.info.list.chapter.id}
|
||||||
>
|
>
|
||||||
<h3>
|
<h3>
|
||||||
{props.info.list.chapter.name}{" "}
|
{props.info.list.chapter.name}{" "}
|
||||||
|
<button
|
||||||
|
onClick={() => {
|
||||||
|
props.openNewElementModal(props.info.list.chapter.id);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Create Element
|
||||||
|
</button>
|
||||||
<button
|
<button
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
props.deleteChapter(props.info.list.chapter.id);
|
props.deleteChapter(props.info.list.chapter.id);
|
||||||
|
|
@ -50,12 +42,23 @@ function Chapter(props: any) {
|
||||||
)}
|
)}
|
||||||
</Droppable>
|
</Droppable>
|
||||||
</ChapterWrapper>
|
</ChapterWrapper>
|
||||||
|
|
||||||
)}
|
)}
|
||||||
</Draggable>
|
</Draggable>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const ChapterWrapper = styled.div`
|
||||||
|
margin-bottom: 5px;
|
||||||
|
padding: 11px;
|
||||||
|
background-color: #00000010;
|
||||||
|
width: 310px;
|
||||||
|
display: block;
|
||||||
|
border-radius: 9px;
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.19);
|
||||||
|
box-shadow: 0px 13px 33px -13px rgb(0 0 0 / 12%);
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
`;
|
||||||
|
|
||||||
const ElementsList = styled.div`
|
const ElementsList = styled.div`
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
`;
|
`;
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ function Element(props: any) {
|
||||||
<Draggable key={props.element.id} draggableId={props.element.id} index={props.index}>
|
<Draggable key={props.element.id} draggableId={props.element.id} index={props.index}>
|
||||||
{(provided) => (
|
{(provided) => (
|
||||||
<ElementWrapper key={props.element.id} {...provided.draggableProps} {...provided.dragHandleProps} ref={provided.innerRef}>
|
<ElementWrapper key={props.element.id} {...provided.draggableProps} {...provided.dragHandleProps} ref={provided.innerRef}>
|
||||||
{props.element.content}
|
<p>{props.element.name} </p>
|
||||||
</ElementWrapper>
|
</ElementWrapper>
|
||||||
)}
|
)}
|
||||||
</Draggable>
|
</Draggable>
|
||||||
|
|
|
||||||
39
front/components/modals/CourseEdit/NewElement.tsx
Normal file
39
front/components/modals/CourseEdit/NewElement.tsx
Normal file
|
|
@ -0,0 +1,39 @@
|
||||||
|
import React, { useState } from "react";
|
||||||
|
import Modal from "../Modal";
|
||||||
|
|
||||||
|
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",
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Modal>
|
||||||
|
<h1>
|
||||||
|
Add New Element <button onClick={closeModal}>X</button>
|
||||||
|
</h1>
|
||||||
|
<input type="text" onChange={handleElementNameChange} placeholder="Element Name" /> <br />
|
||||||
|
<input type="text" onChange={handleElementDescriptionChange} placeholder="Element Description" />
|
||||||
|
<br />
|
||||||
|
<button onClick={handleSubmit}>Add Element</button>
|
||||||
|
</Modal>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default NewElementModal;
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { Menu } from "./elements/menu";
|
|
||||||
import Link from 'next/link'
|
import Link from 'next/link'
|
||||||
import styled from "styled-components";
|
import styled from "styled-components";
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,9 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import Head from "next/head";
|
import Head from "next/head";
|
||||||
import { Header } from "./header";
|
|
||||||
import styled from "styled-components";
|
import styled from "styled-components";
|
||||||
import AuthProvider from "../security/AuthProvider";
|
import AuthProvider from "../security/AuthProvider";
|
||||||
import { motion } from "framer-motion";
|
import { motion } from "framer-motion";
|
||||||
import { Menu } from "./elements/menu";
|
import { Menu } from "./elements/Menu";
|
||||||
|
|
||||||
const Layout = (props: any) => {
|
const Layout = (props: any) => {
|
||||||
const variants = {
|
const variants = {
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import styled from "styled-components";
|
||||||
import learnhouseBigIcon from "public/learnhouse_bigicon.png";
|
import learnhouseBigIcon from "public/learnhouse_bigicon.png";
|
||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { PreAlphaLabel } from "../components/ui/layout";
|
import { PreAlphaLabel } from "../components/ui/Layout";
|
||||||
|
|
||||||
const Home: NextPage = () => {
|
const Home: NextPage = () => {
|
||||||
return (
|
return (
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
import Router from "next/router";
|
import Router from "next/router";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { Header } from "../components/ui/header";
|
import { Header } from "../components/ui/Header";
|
||||||
import Layout from "../components/ui/layout";
|
import Layout from "../components/ui/Layout";
|
||||||
import { Title } from "../components/ui/styles/title";
|
import { Title } from "../components/ui/styles/Title";
|
||||||
import { loginAndGetToken } from "../services/auth/auth";
|
import { loginAndGetToken } from "../services/auth/auth";
|
||||||
|
|
||||||
const Login = () => {
|
const Login = () => {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import { default as React, useEffect, useRef } from "react";
|
import { default as React, useEffect, useRef } from "react";
|
||||||
|
|
||||||
import Layout from "../../../../../../components/ui/layout";
|
import Layout from "../../../../../../components/ui/Layout";
|
||||||
import { Title } from "../../../../../../components/ui/styles/title";
|
import { Title } from "../../../../../../components/ui/styles/Title";
|
||||||
import dynamic from "next/dynamic";
|
import dynamic from "next/dynamic";
|
||||||
import { AuthContext } from "../../../../../../components/security/AuthProvider";
|
import { AuthContext } from "../../../../../../components/security/AuthProvider";
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,27 +1,38 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { useState, useEffect } from "react";
|
import { useState, useEffect } from "react";
|
||||||
import styled from "styled-components";
|
import styled from "styled-components";
|
||||||
import { Header } from "../../../../../../components/ui/header";
|
import { Header } from "../../../../../../components/ui/Header";
|
||||||
import Layout from "../../../../../../components/ui/layout";
|
import Layout from "../../../../../../components/ui/Layout";
|
||||||
import { Title } from "../../../../../../components/ui/styles/title";
|
import { Title } from "../../../../../../components/ui/styles/Title";
|
||||||
import { DragDropContext, Droppable, Draggable } from "react-beautiful-dnd";
|
import { DragDropContext, Droppable, Draggable } from "react-beautiful-dnd";
|
||||||
import { initialData, initialData2 } from "../../../../../../components/drags/data";
|
import { initialData, initialData2 } from "../../../../../../components/drags/data";
|
||||||
import Chapter from "../../../../../../components/drags/chapter";
|
import Chapter from "../../../../../../components/drags/Chapter";
|
||||||
import { createChapter, deleteChapter, getCourseChaptersMetadata } from "../../../../../../services/chapters";
|
import { createChapter, deleteChapter, getCourseChaptersMetadata } from "../../../../../../services/courses/chapters";
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
import NewChapterModal from "../../../../../../components/modals/chapters/new";
|
import NewChapterModal from "../../../../../../components/modals/CourseEdit/NewChapter";
|
||||||
|
import NewElementModal from "../../../../../../components/modals/CourseEdit/NewElement";
|
||||||
|
import { createElement } from "../../../../../../services/courses/elements";
|
||||||
|
|
||||||
function CourseEdit() {
|
function CourseEdit() {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
|
// Initial Course State
|
||||||
const [data, setData] = useState(initialData2) as any;
|
const [data, setData] = useState(initialData2) as any;
|
||||||
|
|
||||||
|
// New Chapter Modal State
|
||||||
const [newChapterModal, setNewChapterModal] = useState(false) as any;
|
const [newChapterModal, setNewChapterModal] = useState(false) as any;
|
||||||
|
// New Element Modal State
|
||||||
|
const [newElementModal, setNewElementModal] = useState(false) as any;
|
||||||
|
const [newElementModalData, setNewElementModalData] = useState("") as any;
|
||||||
|
|
||||||
|
// Check window availability
|
||||||
const [winReady, setwinReady] = useState(false);
|
const [winReady, setwinReady] = useState(false);
|
||||||
const { courseid } = router.query;
|
const { courseid } = router.query;
|
||||||
|
|
||||||
async function getCourseChapters() {
|
async function getCourseChapters() {
|
||||||
const courseChapters = await getCourseChaptersMetadata(courseid);
|
const courseChapters = await getCourseChaptersMetadata(courseid);
|
||||||
setData(courseChapters);
|
setData(courseChapters);
|
||||||
console.log( "courseChapters" , courseChapters);
|
console.log("courseChapters", courseChapters);
|
||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
@ -59,20 +70,44 @@ function CourseEdit() {
|
||||||
setNewChapterModal(false);
|
setNewChapterModal(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Submit new element
|
||||||
|
const submitElement = async (element: any) => {
|
||||||
|
console.log("submitElement", element);
|
||||||
|
await createElement(element, element.chapterId);
|
||||||
|
getCourseChapters();
|
||||||
|
setNewElementModal(false);
|
||||||
|
};
|
||||||
|
|
||||||
const deleteChapterUI = async (chapterId: any) => {
|
const deleteChapterUI = async (chapterId: any) => {
|
||||||
console.log("deleteChapter", chapterId);
|
console.log("deleteChapter", chapterId);
|
||||||
await deleteChapter(chapterId);
|
await deleteChapter(chapterId);
|
||||||
|
|
||||||
getCourseChapters();
|
getCourseChapters();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const openNewElementModal = async (chapterId: any) => {
|
||||||
|
console.log("openNewElementModal", chapterId);
|
||||||
|
setNewElementModal(true);
|
||||||
|
setNewElementModalData(chapterId);
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
Modals
|
||||||
|
|
||||||
|
*/
|
||||||
// Close new chapter modal
|
// Close new chapter modal
|
||||||
const closeModal = () => {
|
const closeNewChapterModal = () => {
|
||||||
setNewChapterModal(false);
|
setNewChapterModal(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const closeNewElementModal = () => {
|
||||||
|
setNewElementModal(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Drag and drop functions
|
||||||
|
|
||||||
|
*/
|
||||||
const onDragEnd = (result: any) => {
|
const onDragEnd = (result: any) => {
|
||||||
const { destination, source, draggableId, type } = result;
|
const { destination, source, draggableId, type } = result;
|
||||||
console.log(result);
|
console.log(result);
|
||||||
|
|
@ -175,21 +210,34 @@ function CourseEdit() {
|
||||||
<Layout>
|
<Layout>
|
||||||
<Header></Header>
|
<Header></Header>
|
||||||
<Title>
|
<Title>
|
||||||
Edit Course Chapters <button onClick={()=> {setNewChapterModal(true)}}>+</button>
|
Edit Course Chapters{" "}
|
||||||
|
<button
|
||||||
|
onClick={() => {
|
||||||
|
setNewChapterModal(true);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
+
|
||||||
|
</button>
|
||||||
</Title>
|
</Title>
|
||||||
{newChapterModal && <NewChapterModal closeModal={closeModal} submitChapter={submitChapter}></NewChapterModal>}
|
{newChapterModal && <NewChapterModal closeModal={closeNewChapterModal} submitChapter={submitChapter}></NewChapterModal>}
|
||||||
|
{newElementModal && <NewElementModal closeModal={closeNewElementModal} submitElement={submitElement} chapterId={newElementModalData}></NewElementModal>}
|
||||||
|
|
||||||
<br />
|
<br />
|
||||||
{winReady && (
|
{winReady && (
|
||||||
<ChapterlistWrapper>
|
<ChapterlistWrapper>
|
||||||
<DragDropContext onDragEnd={onDragEnd}>
|
<DragDropContext onDragEnd={onDragEnd}>
|
||||||
<Droppable key="chapters" droppableId="chapters" type="chapter">
|
<Droppable key="chapters" droppableId="chapters" type="chapter">
|
||||||
{(provided) => (
|
{(provided) => (
|
||||||
|
<>
|
||||||
<div key={"chapters"} {...provided.droppableProps} ref={provided.innerRef}>
|
<div key={"chapters"} {...provided.droppableProps} ref={provided.innerRef}>
|
||||||
{getChapters().map((info: any, index: any) => (
|
{getChapters().map((info: any, index: any) => (
|
||||||
<Chapter deleteChapter={deleteChapterUI} key={index} info={info} index={index}></Chapter>
|
<>
|
||||||
|
<Chapter openNewElementModal={openNewElementModal} deleteChapter={deleteChapterUI} key={index} info={info} index={index}></Chapter>
|
||||||
|
</>
|
||||||
))}
|
))}
|
||||||
{provided.placeholder}
|
{provided.placeholder}
|
||||||
</div>
|
</div>
|
||||||
|
</>
|
||||||
)}
|
)}
|
||||||
</Droppable>
|
</Droppable>
|
||||||
</DragDropContext>
|
</DragDropContext>
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import styled from "styled-components";
|
import styled from "styled-components";
|
||||||
import Layout from "../../../../../components/ui/layout";
|
import Layout from "../../../../../components/ui/Layout";
|
||||||
import { getAPIUrl, getBackendUrl } from "../../../../../services/config";
|
import { getAPIUrl, getBackendUrl } from "../../../../../services/config";
|
||||||
import { getCourse } from "../../../../../services/courses";
|
import { getCourse } from "../../../../../services/courses/courses";
|
||||||
import { getOrganizationContextInfo } from "../../../../../services/orgs";
|
import { getOrganizationContextInfo } from "../../../../../services/orgs";
|
||||||
|
|
||||||
const CourseIdPage = () => {
|
const CourseIdPage = () => {
|
||||||
|
|
|
||||||
|
|
@ -2,11 +2,11 @@ import Link from "next/link";
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import styled from "styled-components";
|
import styled from "styled-components";
|
||||||
import { Header } from "../../../../components/ui/header";
|
import { Header } from "../../../../components/ui/Header";
|
||||||
import Layout from "../../../../components/ui/layout";
|
import Layout from "../../../../components/ui/Layout";
|
||||||
import { Title } from "../../../../components/ui/styles/title";
|
import { Title } from "../../../../components/ui/styles/Title";
|
||||||
import { getBackendUrl } from "../../../../services/config";
|
import { getBackendUrl } from "../../../../services/config";
|
||||||
import { deleteCourseFromBackend, getOrgCourses } from "../../../../services/courses";
|
import { deleteCourseFromBackend, getOrgCourses } from "../../../../services/courses/courses";
|
||||||
import { getOrganizationContextInfo } from "../../../../services/orgs";
|
import { getOrganizationContextInfo } from "../../../../services/orgs";
|
||||||
|
|
||||||
const CoursesIndexPage = () => {
|
const CoursesIndexPage = () => {
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { Header } from "../../../../../components/ui/header";
|
import { Header } from "../../../../../components/ui/Header";
|
||||||
import Layout from "../../../../../components/ui/layout";
|
import Layout from "../../../../../components/ui/Layout";
|
||||||
import { Title } from "../../../../../components/ui/styles/title";
|
import { Title } from "../../../../../components/ui/styles/Title";
|
||||||
import { createNewCourse } from "../../../../../services/courses";
|
import { createNewCourse } from "../../../../../services/courses/courses";
|
||||||
import { getOrganizationContextInfo } from "../../../../../services/orgs";
|
import { getOrganizationContextInfo } from "../../../../../services/orgs";
|
||||||
|
|
||||||
const NewCoursePage = () => {
|
const NewCoursePage = () => {
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
import Layout from "../../../components/ui/layout";
|
import Layout from "../../../components/ui/Layout";
|
||||||
import { Title } from "../../../components/ui/styles/title";
|
import { Title } from "../../../components/ui/styles/Title";
|
||||||
import { Header } from "../../../components/ui/header";
|
import { Header } from "../../../components/ui/Header";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
|
|
||||||
const OrgHomePage = () => {
|
const OrgHomePage = () => {
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import AuthenticatedOnly from "../../components/security/AuthenticatedOnly";
|
import AuthenticatedOnly from "../../components/security/AuthenticatedOnly";
|
||||||
import Layout from "../../components/ui/layout";
|
import Layout from "../../components/ui/Layout";
|
||||||
import { Title } from "../../components/ui/styles/title";
|
import { Title } from "../../components/ui/styles/Title";
|
||||||
import { deleteOrganizationFromBackend, getUserOrganizations } from "../../services/orgs";
|
import { deleteOrganizationFromBackend, getUserOrganizations } from "../../services/orgs";
|
||||||
|
|
||||||
const Organizations = () => {
|
const Organizations = () => {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import Layout from "../../components/ui/layout";
|
import Layout from "../../components/ui/Layout";
|
||||||
import { Title } from "../../components/ui/styles/title";
|
import { Title } from "../../components/ui/styles/Title";
|
||||||
import { createNewOrganization } from "../../services/orgs";
|
import { createNewOrganization } from "../../services/orgs";
|
||||||
|
|
||||||
const Organizations = () => {
|
const Organizations = () => {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { Header } from "../components/ui/header";
|
import { Header } from "../components/ui/Header";
|
||||||
import Layout from "../components/ui/layout";
|
import Layout from "../components/ui/Layout";
|
||||||
import { Title } from "../components/ui/styles/title";
|
import { Title } from "../components/ui/styles/Title";
|
||||||
import { signup } from "../services/auth/auth";
|
import { signup } from "../services/auth/auth";
|
||||||
|
|
||||||
const SignUp = () => {
|
const SignUp = () => {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import { initialData } from "../components/drags/data";
|
import { initialData } from "../../components/drags/data";
|
||||||
import { getAPIUrl } from "./config";
|
import { getAPIUrl } from "../config";
|
||||||
|
|
||||||
export async function getCourseChaptersMetadata(course_id: any) {
|
export async function getCourseChaptersMetadata(course_id: any) {
|
||||||
const HeadersConfig = new Headers({ "Content-Type": "application/json" });
|
const HeadersConfig = new Headers({ "Content-Type": "application/json" });
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { getAPIUrl } from "./config";
|
import { getAPIUrl } from "../config";
|
||||||
|
|
||||||
export async function getOrgCourses(org_id: number) {
|
export async function getOrgCourses(org_id: number) {
|
||||||
const HeadersConfig = new Headers({ "Content-Type": "application/json" });
|
const HeadersConfig = new Headers({ "Content-Type": "application/json" });
|
||||||
27
front/services/courses/elements.ts
Normal file
27
front/services/courses/elements.ts
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
import { getAPIUrl } from "../config";
|
||||||
|
|
||||||
|
export async function createElement(data: any, chapter_id: any) {
|
||||||
|
data.content = {}
|
||||||
|
console.log("data", data, chapter_id);
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
|
@ -4,20 +4,18 @@ from typing import List
|
||||||
from uuid import uuid4
|
from uuid import uuid4
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
from src.services.courses.courses import Course, CourseInDB
|
from src.services.courses.courses import Course, CourseInDB
|
||||||
|
from src.services.courses.elements import Element, ElementInDB
|
||||||
from src.services.database import create_config_collection, check_database, create_database, learnhouseDB, learnhouseDB
|
from src.services.database import create_config_collection, check_database, create_database, learnhouseDB, learnhouseDB
|
||||||
from src.services.security import verify_user_rights_with_roles
|
from src.services.security import verify_user_rights_with_roles
|
||||||
from src.services.users import PublicUser
|
from src.services.users import PublicUser
|
||||||
from fastapi import FastAPI, HTTPException, status, Request, Response, BackgroundTasks, UploadFile, File
|
from fastapi import FastAPI, HTTPException, status, Request, Response, BackgroundTasks, UploadFile, File
|
||||||
|
|
||||||
|
|
||||||
class CourseElement(BaseModel):
|
|
||||||
element_id: str
|
|
||||||
|
|
||||||
|
|
||||||
class CourseChapter(BaseModel):
|
class CourseChapter(BaseModel):
|
||||||
name: str
|
name: str
|
||||||
description: str
|
description: str
|
||||||
elements: List[CourseElement]
|
elements: list
|
||||||
|
|
||||||
|
|
||||||
class CourseChapterInDB(CourseChapter):
|
class CourseChapterInDB(CourseChapter):
|
||||||
|
|
@ -164,13 +162,19 @@ async def get_coursechapters_meta(course_id: str, current_user: PublicUser):
|
||||||
await check_database()
|
await check_database()
|
||||||
coursechapters = learnhouseDB["coursechapters"]
|
coursechapters = learnhouseDB["coursechapters"]
|
||||||
courses = learnhouseDB["courses"]
|
courses = learnhouseDB["courses"]
|
||||||
|
elements = learnhouseDB["elements"]
|
||||||
|
|
||||||
coursechapters = coursechapters.find(
|
coursechapters = coursechapters.find(
|
||||||
{"course_id": course_id}).sort("name", 1)
|
{"course_id": course_id}).sort("name", 1)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
course = courses.find_one({"course_id": course_id})
|
course = courses.find_one({"course_id": course_id})
|
||||||
course = Course(**course) # type: ignore
|
course = Course(**course) # type: ignore
|
||||||
|
|
||||||
|
# elements
|
||||||
|
coursechapter_elementIds_global = []
|
||||||
|
|
||||||
# chapters
|
# chapters
|
||||||
chapters = {}
|
chapters = {}
|
||||||
for coursechapter in coursechapters:
|
for coursechapter in coursechapters:
|
||||||
|
|
@ -178,15 +182,27 @@ async def get_coursechapters_meta(course_id: str, current_user: PublicUser):
|
||||||
coursechapter_elementIds = []
|
coursechapter_elementIds = []
|
||||||
|
|
||||||
for element in coursechapter.elements:
|
for element in coursechapter.elements:
|
||||||
coursechapter_elementIds.append(element.element_id)
|
coursechapter_elementIds.append(element)
|
||||||
|
coursechapter_elementIds_global.append(element)
|
||||||
|
|
||||||
chapters[coursechapter.coursechapter_id] = {
|
chapters[coursechapter.coursechapter_id] = {
|
||||||
"id": coursechapter.coursechapter_id, "name": coursechapter.name, "elementIds": coursechapter_elementIds
|
"id": coursechapter.coursechapter_id, "name": coursechapter.name, "elementIds": coursechapter_elementIds
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# elements
|
||||||
|
elements_list = {}
|
||||||
|
for element in elements.find({"element_id": {"$in": coursechapter_elementIds_global}}):
|
||||||
|
element = ElementInDB(**element)
|
||||||
|
elements_list[element.element_id] = {
|
||||||
|
"id": element.element_id, "name": element.name, "type": element.type , "content": element.content
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
final = {
|
final = {
|
||||||
"chapters": chapters,
|
"chapters": chapters,
|
||||||
"chapterOrder": course.chapters
|
"chapterOrder": course.chapters,
|
||||||
|
"elements" : elements_list
|
||||||
}
|
}
|
||||||
|
|
||||||
return final
|
return final
|
||||||
|
|
|
||||||
|
|
@ -8,11 +8,11 @@ from datetime import datetime
|
||||||
|
|
||||||
#### Classes ####################################################
|
#### Classes ####################################################
|
||||||
|
|
||||||
|
|
||||||
class Element(BaseModel):
|
class Element(BaseModel):
|
||||||
name: str
|
name: str
|
||||||
element_type: str
|
type: str
|
||||||
content: str
|
content: object
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class ElementInDB(Element):
|
class ElementInDB(Element):
|
||||||
|
|
@ -29,9 +29,10 @@ class ElementInDB(Element):
|
||||||
####################################################
|
####################################################
|
||||||
|
|
||||||
|
|
||||||
async def create_element(element_object: Element, coursechapter_id : str , current_user: PublicUser):
|
async def create_element(element_object: Element, coursechapter_id: str, current_user: PublicUser):
|
||||||
await check_database()
|
await check_database()
|
||||||
elements = learnhouseDB["elements"]
|
elements = learnhouseDB["elements"]
|
||||||
|
coursechapters = learnhouseDB["coursechapters"]
|
||||||
|
|
||||||
# generate element_id
|
# generate element_id
|
||||||
element_id = str(f"element_{uuid4()}")
|
element_id = str(f"element_{uuid4()}")
|
||||||
|
|
@ -47,6 +48,10 @@ async def create_element(element_object: Element, coursechapter_id : str , curre
|
||||||
datetime.now()), coursechapter_id=coursechapter_id, updateDate=str(datetime.now()), element_id=element_id)
|
datetime.now()), coursechapter_id=coursechapter_id, updateDate=str(datetime.now()), element_id=element_id)
|
||||||
elements.insert_one(element.dict())
|
elements.insert_one(element.dict())
|
||||||
|
|
||||||
|
# update chapter
|
||||||
|
coursechapters.update_one({"coursechapter_id": coursechapter_id}, {
|
||||||
|
"$addToSet": {"elements": element_id}})
|
||||||
|
|
||||||
return element
|
return element
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -88,7 +93,7 @@ async def update_element(element_object: Element, element_id: str, current_user:
|
||||||
datetime_object = datetime.now()
|
datetime_object = datetime.now()
|
||||||
|
|
||||||
updated_course = ElementInDB(
|
updated_course = ElementInDB(
|
||||||
element_id=element_id,coursechapter_id=element["coursechapter_id"] ,creationDate=creationDate, updateDate=str(datetime_object), **element_object.dict())
|
element_id=element_id, coursechapter_id=element["coursechapter_id"], creationDate=creationDate, updateDate=str(datetime_object), **element_object.dict())
|
||||||
|
|
||||||
elements.update_one({"element_id": element_id}, {
|
elements.update_one({"element_id": element_id}, {
|
||||||
"$set": updated_course.dict()})
|
"$set": updated_course.dict()})
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@ class Elements(BaseModel):
|
||||||
collections: List[str]
|
collections: List[str]
|
||||||
organizations: List[str]
|
organizations: List[str]
|
||||||
coursechapters: List[str]
|
coursechapters: List[str]
|
||||||
|
elements : List[str]
|
||||||
|
|
||||||
|
|
||||||
class Role(BaseModel):
|
class Role(BaseModel):
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue