import {
Button,
Container,
Grid,
Heading,
Image,
Input,
Select,
VStack,
} from '@chakra-ui/react';
import React, { useEffect, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import cursor from '../../../assets/images/cursor.png'; // Custom cursor image
import { createCourse } from '../../../redux/actions/admin'; // Redux action to create a course
import { fileUploadCss } from '../../Auth/Register'; // Custom file upload styles
import Sidebar from '../Sidebar'; // Sidebar component for admin dashboard
import toast from 'react-hot-toast'; // For toast notifications
const CreateCourse = () => {
const [title, setTitle] = useState(''); // State for course title
const [description, setDescription] = useState(''); // State for course description
const [createdBy, setCreatedBy] = useState(''); // State for creator's name
const [category, setCategory] = useState(''); // State for course category
const [image, setImage] = useState(''); // State for the course image file
const [imagePrev, setImagePrev] = useState(''); // State for the image preview
const dispatch = useDispatch(); // Dispatch function from Redux
const { loading, error, message } = useSelector(state => state.admin); // Access Redux state
// List of categories for the course
const categories = [
'Web development',
'Artificial Intelligence',
'Data Structure & Algorithm',
'App Development',
'Data Science',
'Game Development',
];
// Handle file input change for the course image
const changeImageHandler = e => {
const file = e.target.files[0]; // Get the selected file
const reader = new FileReader(); // Create a FileReader to preview the image
reader.readAsDataURL(file); // Read the file as a data URL
reader.onloadend = () => {
setImagePrev(reader.result); // Set the preview image
setImage(file); // Set the file to be uploaded
};
};
// Handle form submission for creating a new course
const submitHandler = e => {
e.preventDefault(); // Prevent the default form submission
const myForm = new FormData(); // Create a FormData object for sending form data
myForm.append('title', title); // Add title to the form data
myForm.append('description', description); // Add description to the form data
myForm.append('category', category); // Add category to the form data
myForm.append('createdBy', createdBy); // Add creator's name to the form data
myForm.append('file', image); // Add the image file to the form data
dispatch(createCourse(myForm)); // Dispatch the createCourse action
};
// useEffect hook to handle errors and success messages from Redux
useEffect(() => {
if (error) {
toast.error(error); // Show error toast notification
dispatch({ type: 'clearError' }); // Clear the error in Redux
}
if (message) {
toast.success(message); // Show success toast notification
dispatch({ type: 'clearMessage' }); // Clear the success message in Redux
}
}, [dispatch, error, message]); // Dependency array: triggers when dispatch, error, or message changes
return (
<Grid
css={{
cursor: `url(${cursor}), default`, // Set a custom cursor
}}
minH={'100vh'} // Full height grid
templateColumns={['1fr', '5fr 1fr']} // Responsive grid: full-width on small screens, 5:1 ratio on large screens
>
<Container py="16">
<form onSubmit={submitHandler}>
<Heading
textTransform={'uppercase'} // Uppercase text for heading
children="Create Course" // Heading text
my="16" // Margin for heading
textAlign={['center', 'left']} // Centered text on small screens, left-aligned on larger screens
/>
<VStack m="auto" spacing={'8'}> {/* Vertical stack for form elements */}
{/* Title input */}
<Input
value={title}
onChange={e => setTitle(e.target.value)}
placeholder="Title"
type={'text'}
focusBorderColor="purple.300" // Purple border on focus
/>{' '}
{/* Description input */}
<Input
value={description}
onChange={e => setDescription(e.target.value)}
placeholder="Description"
type={'text'}
focusBorderColor="purple.300"
/>
{/* Creator name input */}
<Input
value={createdBy}
onChange={e => setCreatedBy(e.target.value)}
placeholder="Creator Name"
type={'text'}
focusBorderColor="purple.300"
/>
{/* Category select input */}
<Select
focusBorderColor="purple.300"
value={category}
onChange={e => setCategory(e.target.value)}
>
<option value="">Category</option> {/* Default option */}
{categories.map(item => (
<option key={item} value={item}> {/* Options for categories */}
{item}
</option>
))}
</Select>
{/* Image file input */}
<Input
accept="image/*" // Accept image files only
required
type={'file'}
focusBorderColor="purple.300"
css={{
'&::file-selector-button': { // Custom CSS for file input
...fileUploadCss,
color: 'purple',
},
}}
onChange={changeImageHandler} // Handle file input change
/>
{/* Display image preview if image is selected */}
{imagePrev && (
<Image src={imagePrev} boxSize="64" objectFit={'contain'} />
)}
{/* Submit button */}
<Button
isLoading={loading} // Show loading spinner when submitting
w="full"
colorScheme={'purple'} // Purple button style
type="submit" // Submit button
>
Create
</Button>
</VStack>
</form>
</Container>
<Sidebar /> {/* Sidebar component */}
</Grid>
);
};
export default CreateCourse; // Export CreateCourse component
For further actions, you may consider blocking this person and/or reporting abuse
Top comments (0)