import {
Box,
Button,
Grid,
Heading,
Input,
Modal,
ModalBody,
ModalCloseButton,
ModalContent,
ModalFooter,
ModalHeader,
ModalOverlay,
Stack,
Text,
VStack,
} from '@chakra-ui/react'; // Importing Chakra UI components.
import React, { useState } from 'react'; // Importing React and useState for local state management.
import { RiDeleteBin7Fill } from 'react-icons/ri'; // Importing delete icon from react-icons.
import { fileUploadCss } from '../../Auth/Register'; // Custom CSS for file input.
const CourseModal = ({
isOpen, // Modal open state.
onClose, // Function to close the modal.
id, // Course ID.
deleteButtonHandler, // Handler function to delete a lecture.
addLectureHandler, // Handler function to add a lecture.
courseTitle, // Title of the course.
lectures = [], // List of lectures for the course.
loading, // Loading state to disable actions when processing.
}) => {
// Local state to manage form inputs for adding a new lecture.
const [title, setTitle] = useState(''); // Lecture title.
const [description, setDescription] = useState(''); // Lecture description.
const [video, setVideo] = useState(''); // Video file to be uploaded.
const [videoPrev, setVideoPrev] = useState(''); // Preview URL for the selected video.
// Handler for video file input, converting the video to a preview URL.
const changeVideoHandler = e => {
const file = e.target.files[0]; // Get the selected file.
const reader = new FileReader();
reader.readAsDataURL(file); // Read the file as a data URL.
reader.onloadend = () => {
setVideoPrev(reader.result); // Set the video preview.
setVideo(file); // Set the video file.
};
};
// Function to reset the form and close the modal.
const handleClose = () => {
setTitle(''); // Reset title.
setDescription(''); // Reset description.
setVideo(''); // Reset video file.
setVideoPrev(''); // Reset video preview.
onClose(); // Close the modal.
};
return (
<Modal
isOpen={isOpen} // Modal is open or not.
size="full" // Modal size is full screen.
onClose={handleClose} // Close modal function.
scrollBehavior="outside" // Allow scrolling outside the modal content.
>
<ModalOverlay /> {/* Background overlay for modal. */}
<ModalContent>
<ModalHeader>{courseTitle}</ModalHeader> {/* Modal header shows the course title */}
<ModalCloseButton /> {/* Button to close the modal */}
<ModalBody p="16">
<Grid templateColumns={['1fr', '3fr 1fr']}> {/* Responsive grid layout for content */}
{/* Left side of modal: course details and lectures list */}
<Box px={['0', '16']}>
<Box my="5">
<Heading children={courseTitle} /> {/* Display course title */}
<Heading children={`#${id}`} size="sm" opacity={0.4} /> {/* Display course ID */}
</Box>
<Heading children={'Lectures'} size="lg" /> {/* Section for lectures */}
{/* List of lectures for the course */}
{lectures.map((item, i) => (
<VideoCard
key={i}
title={item.title}
description={item.description}
num={i + 1} /* Lecture number */
lectureId={item._id} /* ID of the lecture */
courseId={id} /* ID of the course */
deleteButtonHandler={deleteButtonHandler} /* Pass the delete handler */
loading={loading} /* Pass the loading state */
/>
))}
</Box>
{/* Right side of modal: form to add a new lecture */}
<Box>
<form
onSubmit={e =>
addLectureHandler(e, id, title, description, video) /* Handles lecture addition */
}
>
<VStack spacing={'4'}>
<Heading
children="Add Lecture" /* Section heading */
size={'md'}
textTransform="uppercase"
/>
{/* Input for lecture title */}
<Input
focusBorderColor="purple.300" /* Color on focus */
placeholder="Title"
value={title} /* Controlled input value */
onChange={e => setTitle(e.target.value)} /* Updates title state */
/>
{/* Input for lecture description */}
<Input
focusBorderColor="purple.300"
placeholder="Description"
value={description} /* Controlled input value */
onChange={e => setDescription(e.target.value)} /* Updates description state */
/>
{/* File input for video upload */}
<Input
accept="video/mp4" /* Only accepts mp4 videos */
required
type={'file'}
focusBorderColor="purple.300"
css={{
'&::file-selector-button': {
...fileUploadCss, /* Custom file upload CSS */
color: 'purple',
},
}}
onChange={changeVideoHandler} /* Video file change handler */
/>
{/* Display video preview if a video is selected */}
{videoPrev && (
<video
controlsList="nodownload" /* Disable video download */
controls
src={videoPrev} /* Video preview source */
></video>
)}
{/* Button to upload the lecture */}
<Button
isLoading={loading} /* Shows loading spinner when loading */
w="full" /* Full width button */
colorScheme={'purple'} /* Purple button style */
type="submit" /* Submit button for form */
>
Upload
</Button>
</VStack>
</form>
</Box>
</Grid>
</ModalBody>
{/* Footer with close button */}
<ModalFooter>
<Button onClick={handleClose}>Close</Button> {/* Close modal button */}
</ModalFooter>
</ModalContent>
</Modal>
);
};
export default CourseModal; // Export the CourseModal component.
/* VideoCard component to display individual lecture information with a delete button */
function VideoCard({
title,
description,
num, // Lecture number.
lectureId, // Lecture ID.
courseId, // Course ID.
deleteButtonHandler,// Function to delete the lecture.
loading, // Loading state to disable buttons when processing.
}) {
return (
<Stack
direction={['column', 'row']} /* Responsive layout: column on small screens, row on larger */
my="8" /* Margin */
borderRadius={'lg'} /* Rounded corners */
boxShadow={'0 0 10px rgba(107,70,193,0.5)'} /* Box shadow for styling */
justifyContent={['flex-start', 'space-between']} /* Responsive content alignment */
p={['4', '8']} /* Padding */
>
<Box>
<Heading size={'sm'} children={`#${num} ${title}`} /> {/* Display lecture number and title */}
<Text children={description} /> {/* Display lecture description */}
</Box>
{/* Button to delete the lecture */}
<Button
isLoading={loading} /* Show loading spinner if loading */
color={'purple.600'} /* Purple color */
onClick={() => deleteButtonHandler(courseId, lectureId)} /* Delete handler */
>
<RiDeleteBin7Fill /> {/* Trash bin icon for delete */}
</Button>
</Stack>
);
}
For further actions, you may consider blocking this person and/or reporting abuse
Top comments (0)