mirror of
https://github.com/rzmk/learnhouse.git
synced 2025-12-19 04:19:25 +00:00
feat: implement youtube backend and partial front
This commit is contained in:
parent
cdd1ca46d3
commit
77d4f5fa1c
6 changed files with 51 additions and 20 deletions
|
|
@ -11,7 +11,7 @@ import { createChapter, deleteChapter, getCourseChaptersMetadata, updateChapters
|
||||||
import { useRouter } from "next/navigation";
|
import { useRouter } from "next/navigation";
|
||||||
import NewChapterModal from "@components/Modals/Chapters/NewChapter";
|
import NewChapterModal from "@components/Modals/Chapters/NewChapter";
|
||||||
import NewActivityModal from "@components/Modals/Activities/Create/NewActivity";
|
import NewActivityModal from "@components/Modals/Activities/Create/NewActivity";
|
||||||
import { createActivity, createFileActivity, createYouTubeVideoActivity } from "@services/courses/activities";
|
import { createActivity, createFileActivity, createExternalVideoActivity } from "@services/courses/activities";
|
||||||
import { getOrganizationContextInfo } from "@services/organizations/orgs";
|
import { getOrganizationContextInfo } from "@services/organizations/orgs";
|
||||||
import Modal from "@components/UI/Modal/Modal";
|
import Modal from "@components/UI/Modal/Modal";
|
||||||
import { denyAccessToUser } from "@services/utils/react/middlewares/views";
|
import { denyAccessToUser } from "@services/utils/react/middlewares/views";
|
||||||
|
|
@ -96,9 +96,10 @@ function CourseEdit(params: any) {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Submit YouTube Video Upload
|
// Submit YouTube Video Upload
|
||||||
const submitVideoYouTubeActivity = async (data : any, activity: any, chapterId: string) => {
|
const submitExternalVideo = async (external_video_data : any, activity: any, chapterId: string) => {
|
||||||
|
console.log("submitExternalVideo", external_video_data);
|
||||||
await updateChaptersMetadata(courseid, data);
|
await updateChaptersMetadata(courseid, data);
|
||||||
await createYouTubeVideoActivity(data, activity, chapterId);
|
await createExternalVideoActivity(external_video_data , activity, chapterId);
|
||||||
await getCourseChapters();
|
await getCourseChapters();
|
||||||
setNewActivityModal(false);
|
setNewActivityModal(false);
|
||||||
};
|
};
|
||||||
|
|
@ -275,6 +276,7 @@ function CourseEdit(params: any) {
|
||||||
dialogContent={<NewActivityModal
|
dialogContent={<NewActivityModal
|
||||||
closeModal={closeNewActivityModal}
|
closeModal={closeNewActivityModal}
|
||||||
submitFileActivity={submitFileActivity}
|
submitFileActivity={submitFileActivity}
|
||||||
|
submitExternalVideo={submitExternalVideo}
|
||||||
submitActivity={submitActivity}
|
submitActivity={submitActivity}
|
||||||
chapterId={newActivityModalData}
|
chapterId={newActivityModalData}
|
||||||
></NewActivityModal>}
|
></NewActivityModal>}
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ import VideoModal from "./NewActivityModal/Video";
|
||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
import DocumentPdfModal from "./NewActivityModal/DocumentPdf";
|
import DocumentPdfModal from "./NewActivityModal/DocumentPdf";
|
||||||
|
|
||||||
function NewActivityModal({ closeModal, submitActivity, submitFileActivity, chapterId }: any) {
|
function NewActivityModal({ closeModal, submitActivity, submitFileActivity, submitExternalVideo, chapterId }: any) {
|
||||||
const [selectedView, setSelectedView] = useState("home");
|
const [selectedView, setSelectedView] = useState("home");
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -43,7 +43,8 @@ function NewActivityModal({ closeModal, submitActivity, submitFileActivity, chap
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{selectedView === "video" && (
|
{selectedView === "video" && (
|
||||||
<VideoModal submitFileActivity={submitFileActivity} chapterId={chapterId} />
|
<VideoModal submitFileActivity={submitFileActivity} submitExternalVideo={submitExternalVideo}
|
||||||
|
chapterId={chapterId} />
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{selectedView === "documentpdf" && (
|
{selectedView === "documentpdf" && (
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,14 @@ import * as Form from '@radix-ui/react-form';
|
||||||
import BarLoader from "react-spinners/BarLoader";
|
import BarLoader from "react-spinners/BarLoader";
|
||||||
import { Youtube } from "lucide-react";
|
import { Youtube } from "lucide-react";
|
||||||
|
|
||||||
function VideoModal({ submitFileActivity, chapterId }: any) {
|
interface ExternalVideoObject {
|
||||||
|
name: string,
|
||||||
|
type: string,
|
||||||
|
uri: string
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function VideoModal({ submitFileActivity, submitExternalVideo, chapterId }: any) {
|
||||||
const [video, setVideo] = React.useState(null) as any;
|
const [video, setVideo] = React.useState(null) as any;
|
||||||
const [isSubmitting, setIsSubmitting] = useState(false);
|
const [isSubmitting, setIsSubmitting] = useState(false);
|
||||||
const [name, setName] = React.useState("");
|
const [name, setName] = React.useState("");
|
||||||
|
|
@ -26,13 +33,19 @@ function VideoModal({ submitFileActivity, chapterId }: any) {
|
||||||
const handleSubmit = async (e: any) => {
|
const handleSubmit = async (e: any) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
setIsSubmitting(true);
|
setIsSubmitting(true);
|
||||||
|
|
||||||
if (selectedView === "file") {
|
if (selectedView === "file") {
|
||||||
let status = await submitFileActivity(video, "video", { name, type: "video" }, chapterId);
|
let status = await submitFileActivity(video, "video", { name, type: "video" }, chapterId);
|
||||||
setIsSubmitting(false);
|
setIsSubmitting(false);
|
||||||
}
|
}
|
||||||
if (selectedView === "youtube") {
|
if (selectedView === "youtube") {
|
||||||
let status = await submitFileActivity(video, "video", { name, type: "video" }, chapterId);
|
let external_video_object: ExternalVideoObject = {
|
||||||
setIsSubmitting(false);
|
name,
|
||||||
|
type: "youtube",
|
||||||
|
uri: youtubeUrl
|
||||||
|
}
|
||||||
|
let status = await submitExternalVideo(external_video_object, 'activity' ,chapterId);
|
||||||
|
setIsSubmitting(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
@ -69,7 +82,6 @@ function VideoModal({ submitFileActivity, chapterId }: any) {
|
||||||
</FormField>
|
</FormField>
|
||||||
</div>)}
|
</div>)}
|
||||||
{selectedView === "youtube" && (
|
{selectedView === "youtube" && (
|
||||||
|
|
||||||
<div className="p-4 justify-center m-auto align-middle">
|
<div className="p-4 justify-center m-auto align-middle">
|
||||||
<FormField name="video-activity-file">
|
<FormField name="video-activity-file">
|
||||||
<Flex css={{ alignItems: 'baseline', justifyContent: 'space-between' }}>
|
<Flex css={{ alignItems: 'baseline', justifyContent: 'space-between' }}>
|
||||||
|
|
|
||||||
|
|
@ -36,8 +36,12 @@ export async function createFileActivity(file: File, type: string, data: any, ch
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function createYouTubeVideoActivity(data: any, activity: any, chapter_id: any) {
|
export async function createExternalVideoActivity(data: any, activity: any, chapter_id: any) {
|
||||||
const result = await fetch(`${getAPIUrl()}activities/youtubevideo?coursechapter_id=${chapter_id}`, RequestBody("POST", data));
|
// add coursechapter_id to data
|
||||||
|
data.coursechapter_id = chapter_id;
|
||||||
|
data.activity_id = activity.id;
|
||||||
|
|
||||||
|
const result = await fetch(`${getAPIUrl()}activities/external_video?coursechapter_id=${chapter_id}`, RequestBody("POST", data));
|
||||||
const res = await result.json();
|
const res = await result.json();
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -99,21 +99,19 @@ async def api_create_video_activity(
|
||||||
async def api_create_external_video_activity(
|
async def api_create_external_video_activity(
|
||||||
request: Request,
|
request: Request,
|
||||||
external_video: ExternalVideo,
|
external_video: ExternalVideo,
|
||||||
coursechapter_id: str = Form(),
|
|
||||||
current_user: PublicUser = Depends(get_current_user),
|
current_user: PublicUser = Depends(get_current_user),
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
Create new activity
|
Create new activity
|
||||||
"""
|
"""
|
||||||
return await create_external_video_activity(
|
return await create_external_video_activity(
|
||||||
request, coursechapter_id, current_user, external_video
|
request, current_user, external_video
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@router.post("/documentpdf")
|
@router.post("/documentpdf")
|
||||||
async def api_create_documentpdf_activity(
|
async def api_create_documentpdf_activity(
|
||||||
request: Request,
|
request: Request,
|
||||||
org_id: str,
|
|
||||||
name: str = Form(),
|
name: str = Form(),
|
||||||
coursechapter_id: str = Form(),
|
coursechapter_id: str = Form(),
|
||||||
current_user: PublicUser = Depends(get_current_user),
|
current_user: PublicUser = Depends(get_current_user),
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,12 @@ async def create_video_activity(
|
||||||
{"chapters_content.coursechapter_id": coursechapter_id}
|
{"chapters_content.coursechapter_id": coursechapter_id}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if not coursechapter:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_409_CONFLICT,
|
||||||
|
detail="CourseChapter : No coursechapter found",
|
||||||
|
)
|
||||||
|
|
||||||
org_id = coursechapter["org_id"]
|
org_id = coursechapter["org_id"]
|
||||||
|
|
||||||
# check if video_file is not None
|
# check if video_file is not None
|
||||||
|
|
@ -101,12 +107,14 @@ class ExternalVideo(BaseModel):
|
||||||
name: str
|
name: str
|
||||||
uri: str
|
uri: str
|
||||||
type: Literal["youtube", "vimeo"]
|
type: Literal["youtube", "vimeo"]
|
||||||
|
coursechapter_id: str
|
||||||
|
|
||||||
|
class ExternalVideoInDB(BaseModel):
|
||||||
activity_id: str
|
activity_id: str
|
||||||
|
|
||||||
|
|
||||||
async def create_external_video_activity(
|
async def create_external_video_activity(
|
||||||
request: Request,
|
request: Request,
|
||||||
coursechapter_id: str,
|
|
||||||
current_user: PublicUser,
|
current_user: PublicUser,
|
||||||
data: ExternalVideo,
|
data: ExternalVideo,
|
||||||
):
|
):
|
||||||
|
|
@ -118,15 +126,21 @@ async def create_external_video_activity(
|
||||||
|
|
||||||
# get org_id from course
|
# get org_id from course
|
||||||
coursechapter = await courses.find_one(
|
coursechapter = await courses.find_one(
|
||||||
{"chapters_content.coursechapter_id": coursechapter_id}
|
{"chapters_content.coursechapter_id": data.coursechapter_id}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if not coursechapter:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_409_CONFLICT,
|
||||||
|
detail="CourseChapter : No coursechapter found",
|
||||||
|
)
|
||||||
|
|
||||||
org_id = coursechapter["org_id"]
|
org_id = coursechapter["org_id"]
|
||||||
|
|
||||||
activity_object = ActivityInDB(
|
activity_object = ActivityInDB(
|
||||||
org_id=org_id,
|
org_id=org_id,
|
||||||
activity_id=activity_id,
|
activity_id=activity_id,
|
||||||
coursechapter_id=coursechapter_id,
|
coursechapter_id=data.coursechapter_id,
|
||||||
name=data.name,
|
name=data.name,
|
||||||
type="video",
|
type="video",
|
||||||
content={
|
content={
|
||||||
|
|
@ -157,7 +171,7 @@ async def create_external_video_activity(
|
||||||
# todo : choose whether to update the chapter or not
|
# todo : choose whether to update the chapter or not
|
||||||
# update chapter
|
# update chapter
|
||||||
await courses.update_one(
|
await courses.update_one(
|
||||||
{"chapters_content.coursechapter_id": coursechapter_id},
|
{"chapters_content.coursechapter_id": data.coursechapter_id},
|
||||||
{"$addToSet": {"chapters_content.$.activities": activity_id}},
|
{"$addToSet": {"chapters_content.$.activities": activity_id}},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue