mirror of
https://github.com/rzmk/learnhouse.git
synced 2025-12-19 04:19:25 +00:00
fix: collections and courses remaining bugs
This commit is contained in:
parent
4245e61df8
commit
212c50768f
8 changed files with 155 additions and 113 deletions
|
|
@ -1,29 +1,27 @@
|
|||
"use client";
|
||||
import { useRouter } from "next/navigation";
|
||||
import React from "react";
|
||||
import React, { useState } from "react";
|
||||
import { createCollection } from "@services/courses/collections";
|
||||
import useSWR from "swr";
|
||||
import { getAPIUrl, getUriWithOrg } from "@services/config/config";
|
||||
import { revalidateTags, swrFetcher } from "@services/utils/ts/requests";
|
||||
import { getOrganizationContextInfo } from "@services/organizations/orgs";
|
||||
import { useOrg } from "@components/Contexts/OrgContext";
|
||||
|
||||
function NewCollection(params: any) {
|
||||
const org = useOrg() as any;
|
||||
const orgslug = params.params.orgslug;
|
||||
const [name, setName] = React.useState("");
|
||||
const [org, setOrg] = React.useState({}) as any;
|
||||
const [description, setDescription] = React.useState("");
|
||||
const [selectedCourses, setSelectedCourses] = React.useState([]) as any;
|
||||
const router = useRouter();
|
||||
|
||||
const { data: courses, error: error } = useSWR(`${getAPIUrl()}courses/org_slug/${orgslug}/page/1/limit/10`, swrFetcher);
|
||||
const [isPublic, setIsPublic] = useState('true');
|
||||
|
||||
const handleVisibilityChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
|
||||
setIsPublic(e.target.value);
|
||||
};
|
||||
|
||||
React.useEffect(() => {
|
||||
async function getOrg() {
|
||||
const org = await getOrganizationContextInfo(orgslug, { revalidate: 1800 });
|
||||
setOrg(org);
|
||||
}
|
||||
getOrg();
|
||||
}, []);
|
||||
|
||||
const handleNameChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setName(event.target.value);
|
||||
|
|
@ -35,83 +33,94 @@ function NewCollection(params: any) {
|
|||
|
||||
const handleSubmit = async (e: any) => {
|
||||
e.preventDefault();
|
||||
|
||||
|
||||
const collection = {
|
||||
name: name,
|
||||
description: description,
|
||||
courses: selectedCourses,
|
||||
public: true,
|
||||
public: isPublic,
|
||||
org_id: org.id,
|
||||
};
|
||||
await createCollection(collection);
|
||||
await revalidateTags(["collections"], orgslug);
|
||||
await revalidateTags(["collections"], org.slug);
|
||||
// reload the page
|
||||
router.refresh();
|
||||
router.prefetch(getUriWithOrg(orgslug, "/collections"));
|
||||
router.push(getUriWithOrg(orgslug, "/collections"));
|
||||
|
||||
// wait for 2s before reloading the page
|
||||
setTimeout(() => {
|
||||
router.push(getUriWithOrg(orgslug, "/collections"));
|
||||
}
|
||||
, 1000);
|
||||
};
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="w-64 m-auto py-20">
|
||||
<div className="font-bold text-lg mb-4">Add new</div>
|
||||
<div className="font-bold text-lg mb-4">Add new</div>
|
||||
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Name"
|
||||
value={name}
|
||||
onChange={handleNameChange}
|
||||
className="w-full px-4 py-2 mb-4 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
|
||||
/>
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Name"
|
||||
value={name}
|
||||
onChange={handleNameChange}
|
||||
className="w-full px-4 py-2 mb-4 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
|
||||
/>
|
||||
|
||||
{!courses ? (
|
||||
<select
|
||||
onChange={handleVisibilityChange}
|
||||
className="w-full px-4 py-2 mb-4 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
|
||||
defaultValue={isPublic}
|
||||
>
|
||||
<option value="false">Private Collection</option>
|
||||
<option value="true">Public Collection </option>
|
||||
</select>
|
||||
|
||||
|
||||
{!courses ? (
|
||||
<p className="text-gray-500">Loading...</p>
|
||||
) : (
|
||||
<div>
|
||||
<div className="space-y-4 p-3">
|
||||
<p>Courses</p>
|
||||
{courses.map((course: any) => (
|
||||
<div key={course.course_uuid} className="flex items-center mb-2">
|
||||
<div key={course.course_uuid} className="flex items-center space-x-2">
|
||||
|
||||
<input
|
||||
<input
|
||||
type="checkbox"
|
||||
id={course.id}
|
||||
name={course.name}
|
||||
value={course.id}
|
||||
onChange={(e) => {
|
||||
if (e.target.checked) {
|
||||
setSelectedCourses([...selectedCourses, course.id]);
|
||||
}
|
||||
else {
|
||||
setSelectedCourses(selectedCourses.filter((course_uuid: any) => course_uuid !== course.course_uuid));
|
||||
}
|
||||
}}
|
||||
className="text-blue-500 rounded focus:ring-2 focus:ring-blue-500"
|
||||
/>
|
||||
|
||||
type="checkbox"
|
||||
id={course.id}
|
||||
name={course.name}
|
||||
value={course.id}
|
||||
// id is an integer, not a string
|
||||
|
||||
onChange={(e) => {
|
||||
if (e.target.checked) {
|
||||
setSelectedCourses([...selectedCourses, course.id]);
|
||||
}
|
||||
else {
|
||||
setSelectedCourses(selectedCourses.filter((course_uuid: any) => course_uuid !== course.course_uuid));
|
||||
}
|
||||
}
|
||||
}
|
||||
className="mr-2"
|
||||
/>
|
||||
|
||||
<label htmlFor={course.course_uuid} className="text-sm">{course.name}</label>
|
||||
<label htmlFor={course.course_uuid} className="text-sm text-gray-700">{course.name}</label>
|
||||
</div>
|
||||
))}
|
||||
|
||||
</div>
|
||||
)}
|
||||
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Description"
|
||||
value={description}
|
||||
onChange={handleDescriptionChange}
|
||||
className="w-full px-4 py-2 mb-4 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
|
||||
/>
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Description"
|
||||
value={description}
|
||||
onChange={handleDescriptionChange}
|
||||
className="w-full px-4 py-2 mb-4 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
|
||||
/>
|
||||
|
||||
<button
|
||||
onClick={handleSubmit}
|
||||
className="px-6 py-3 text-white bg-black rounded-lg shadow-md hover:bg-black focus:outline-none focus:ring-2 focus:ring-blue-500"
|
||||
>
|
||||
Submit
|
||||
</button>
|
||||
<button
|
||||
onClick={handleSubmit}
|
||||
className="px-6 py-3 text-white bg-black rounded-lg shadow-md hover:bg-black focus:outline-none focus:ring-2 focus:ring-blue-500"
|
||||
>
|
||||
Submit
|
||||
</button>
|
||||
</div>
|
||||
|
||||
</>
|
||||
|
|
|
|||
|
|
@ -59,11 +59,11 @@ const CourseClient = (props: any) => {
|
|||
useEffect(() => {
|
||||
getLearningTags();
|
||||
}
|
||||
, [org]);
|
||||
, [org, course]);
|
||||
|
||||
return (
|
||||
<>
|
||||
{!course ? (
|
||||
{!course && !org ? (
|
||||
<PageLoading></PageLoading>
|
||||
) : (
|
||||
<GeneralWrapperStyled>
|
||||
|
|
@ -74,8 +74,8 @@ const CourseClient = (props: any) => {
|
|||
</h1>
|
||||
</div>
|
||||
|
||||
{props.course.thumbnail_image ?
|
||||
<div className="inset-0 ring-1 ring-inset ring-black/10 rounded-lg shadow-xl relative w-auto h-[400px] bg-cover bg-center mb-4" style={{ backgroundImage: `url(${getCourseThumbnailMediaDirectory(org?.org_uuid, course.course_uuid, course.thumbnail_image)})` }}>
|
||||
{props.course?.thumbnail_image && org ?
|
||||
<div className="inset-0 ring-1 ring-inset ring-black/10 rounded-lg shadow-xl relative w-auto h-[400px] bg-cover bg-center mb-4" style={{ backgroundImage: `url(${getCourseThumbnailMediaDirectory(org?.org_uuid, course?.course_uuid, course?.thumbnail_image)})` }}>
|
||||
</div>
|
||||
:
|
||||
<div className="inset-0 ring-1 ring-inset ring-black/10 rounded-lg shadow-xl relative w-auto h-[400px] bg-cover bg-center mb-4" style={{ backgroundImage: `url('../empty_thumbnail.png')`, backgroundSize: 'auto' }}>
|
||||
|
|
@ -193,19 +193,19 @@ const CourseClient = (props: any) => {
|
|||
<div className="course_metadata_right space-y-3 w-72 antialiased flex flex-col ml-10 h-fit p-3 py-5 bg-white shadow-md shadow-gray-300/25 outline outline-1 outline-neutral-200/40 rounded-lg overflow-hidden">
|
||||
{user &&
|
||||
<div className="flex flex-col mx-auto space-y-3 px-2 py-2 items-center">
|
||||
<UserAvatar border="border-8" avatar_url={getUserAvatarMediaDirectory(course.authors[0].user_uuid,course.authors[0].avatar_image)} width={100} />
|
||||
<UserAvatar border="border-8" avatar_url={getUserAvatarMediaDirectory(course.authors[0].user_uuid, course.authors[0].avatar_image)} width={100} />
|
||||
<div className="-space-y-2 ">
|
||||
<div className="text-[12px] text-neutral-400 font-semibold">Author</div>
|
||||
<div className="text-xl font-bold text-neutral-800">
|
||||
{course.authors[0].first_name && course.authors[0].last_name && (
|
||||
<div className="flex space-x-2 items-center">
|
||||
<p>{course.authors[0].first_name + ' ' + course.authors[0].last_name}</p><span className="text-xs bg-neutral-100 p-1 px-3 rounded-full text-neutral-400 font-semibold"> @{course.authors[0].username }</span>
|
||||
</div>)}
|
||||
<div className="flex space-x-2 items-center">
|
||||
<p>{course.authors[0].first_name + ' ' + course.authors[0].last_name}</p><span className="text-xs bg-neutral-100 p-1 px-3 rounded-full text-neutral-400 font-semibold"> @{course.authors[0].username}</span>
|
||||
</div>)}
|
||||
{!course.authors[0].first_name && !course.authors[0].last_name && (
|
||||
<div className="flex space-x-2 items-center">
|
||||
<p>@{course.authors[0].username}</p>
|
||||
</div>)}
|
||||
</div>
|
||||
<div className="flex space-x-2 items-center">
|
||||
<p>@{course.authors[0].username}</p>
|
||||
</div>)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
|
@ -226,12 +226,4 @@ const CourseClient = (props: any) => {
|
|||
};
|
||||
|
||||
|
||||
const StyledBox = (props: any) => (
|
||||
<div className="p-3 pl-10 bg-white w-[100%] h-auto ring-1 ring-inset ring-gray-400/10 rounded-lg shadow-sm">
|
||||
{props.children}
|
||||
</div>
|
||||
|
||||
);
|
||||
|
||||
|
||||
export default CourseClient;
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ export default function Error({
|
|||
|
||||
return (
|
||||
<div>
|
||||
<ErrorUI></ErrorUI>
|
||||
<ErrorUI ></ErrorUI>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue