feat: use modal for course creation

This commit is contained in:
swve 2023-04-21 00:08:04 +02:00
parent 2a3a1d18e6
commit b99eda15e5
2 changed files with 135 additions and 5 deletions

View file

@ -9,10 +9,13 @@ import { deleteCourseFromBackend } from "@services/courses/courses";
import useSWR, { mutate } from "swr"; import useSWR, { mutate } from "swr";
import { swrFetcher } from "@services/utils/ts/requests"; import { swrFetcher } from "@services/utils/ts/requests";
import { Edit2, Trash } from "lucide-react"; import { Edit2, Trash } from "lucide-react";
import Modal from "@components/UI/Modal/Modal";
import CreateCourseModal from "@components/Pages/CreateCourse/CreateCourse";
const CoursesIndexPage = (params: any) => { const CoursesIndexPage = (params: any) => {
const router = useRouter(); const router = useRouter();
const orgslug = params.params.orgslug; const orgslug = params.params.orgslug;
const [newCourseModal, setNewCourseModal] = React.useState(false);
const { data: courses, error: error } = useSWR(`${getAPIUrl()}courses/org_slug/${orgslug}/page/1/limit/10`, swrFetcher); const { data: courses, error: error } = useSWR(`${getAPIUrl()}courses/org_slug/${orgslug}/page/1/limit/10`, swrFetcher);
@ -21,18 +24,34 @@ const CoursesIndexPage = (params: any) => {
mutate(`${getAPIUrl()}courses/org_slug/${orgslug}/page/1/limit/10`); mutate(`${getAPIUrl()}courses/org_slug/${orgslug}/page/1/limit/10`);
} }
async function closeNewCourseModal() {
setNewCourseModal(false);
}
// function to remove "course_" from the course_id // function to remove "course_" from the course_id
function removeCoursePrefix(course_id: string) { function removeCoursePrefix(course_id: string) {
return course_id.replace("course_", ""); return course_id.replace("course_", "");
} }
return ( return (
<> <>
<Title> <Title>
Courses :{" "} Courses {" "}
<Link href={getUriWithOrg(orgslug, "/courses/new")}> <Modal
<button>+</button> isDialogOpen={newCourseModal}
</Link>{" "} onOpenChange={setNewCourseModal}
minHeight="md"
dialogContent={<CreateCourseModal
closeModal={closeNewCourseModal}
orgslug={orgslug}
></CreateCourseModal>}
dialogTitle="Create Course"
dialogDescription="Create a new course"
dialogTrigger={
<button> Add Course +
</button>
}
/>
</Title> </Title>
{error && <p>Failed to load</p>} {error && <p>Failed to load</p>}
{!courses ? ( {!courses ? (

View file

@ -0,0 +1,111 @@
import FormLayout, { ButtonBlack, Flex, FormField, FormLabel, FormMessage, Input, Textarea } from '@components/UI/Form/Form'
import * as Form from '@radix-ui/react-form'
import { getAPIUrl, getUriWithOrg } from '@services/config/config';
import { createNewCourse } from '@services/courses/courses';
import { getOrganizationContextInfo } from '@services/organizations/orgs';
import React, { useState } from 'react'
import { BarLoader } from 'react-spinners'
import { mutate } from 'swr';
function CreateCourseModal({ closeModal, orgslug }: any) {
const [isSubmitting, setIsSubmitting] = useState(false);
const [name, setName] = React.useState("");
const [description, setDescription] = React.useState("");
const [isLoading, setIsLoading] = React.useState(false);
const [thumbnail, setThumbnail] = React.useState(null) as any;
const [orgId, setOrgId] = React.useState(null) as any;
const getOrgMetadata = async () => {
const org = await getOrganizationContextInfo(orgslug);
setOrgId(org.org_id);
}
const handleNameChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setName(event.target.value);
};
const handleDescriptionChange = (event: React.ChangeEvent<any>) => {
setDescription(event.target.value);
};
const handleThumbnailChange = (event: React.ChangeEvent<any>) => {
setThumbnail(event.target.files[0]);
};
const handleSubmit = async (e: any) => {
e.preventDefault();
setIsSubmitting(true);
let status = await createNewCourse(orgId, { name, description }, thumbnail);
mutate(`${getAPIUrl()}courses/org_slug/${orgslug}/page/1/limit/10`);
setIsSubmitting(false);
if (status.org_id == orgId) {
closeModal();
} else {
alert("Error creating course, please see console logs");
console.log(status);
}
};
React.useEffect(() => {
if (orgslug) {
getOrgMetadata();
}
}, [isLoading, orgslug]);
return (
<FormLayout onSubmit={handleSubmit}>
<FormField name="course-name">
<Flex css={{ alignItems: 'baseline', justifyContent: 'space-between' }}>
<FormLabel>Course name</FormLabel>
<FormMessage match="valueMissing">Please provide a course name</FormMessage>
</Flex>
<Form.Control asChild>
<Input onChange={handleNameChange} type="text" required />
</Form.Control>
</FormField>
<FormField name="course-desc">
<Flex css={{ alignItems: 'baseline', justifyContent: 'space-between' }}>
<FormLabel>Course description</FormLabel>
<FormMessage match="valueMissing">Please provide a course description</FormMessage>
</Flex>
<Form.Control asChild>
<Textarea onChange={handleDescriptionChange} required />
</Form.Control>
</FormField>
<FormField name="course-thumbnail">
<Flex css={{ alignItems: 'baseline', justifyContent: 'space-between' }}>
<FormLabel>Course thumbnail</FormLabel>
<FormMessage match="valueMissing">Please provide a thumbnail for your course</FormMessage>
</Flex>
<Form.Control asChild>
<Input onChange={handleThumbnailChange} type="file" required />
</Form.Control>
</FormField>
<FormField name="course-learnings">
<Flex css={{ alignItems: 'baseline', justifyContent: 'space-between' }}>
<FormLabel>Course Learnings</FormLabel>
<FormMessage match="valueMissing">Please provide a learning elements, separated by comma (,)</FormMessage>
</Flex>
<Form.Control asChild>
<Textarea required />
</Form.Control>
</FormField>
<Flex css={{ marginTop: 25, justifyContent: 'flex-end' }}>
<Form.Submit asChild>
<ButtonBlack type="submit" css={{ marginTop: 10 }}>
{isSubmitting ? <BarLoader cssOverride={{ borderRadius: 60, }} width={60} color="#ffffff" />
: "Create Course"}
</ButtonBlack>
</Form.Submit>
</Flex>
</FormLayout>
)
}
export default CreateCourseModal