mirror of
https://github.com/sergeyyarkov/educt-client.git
synced 2026-10-11 10:19:22 +03:00
feat: added materials uploader
This commit is contained in:
parent
359deec3bc
commit
03c8e3b8cc
@ -1,4 +1,4 @@
|
||||
import React, { useState } from 'react';
|
||||
import React from 'react';
|
||||
import * as helpres from '@educt/helpers';
|
||||
import { Stack, Flex, Box, Icon, Text, Input, IconButton, Button } from '@chakra-ui/react';
|
||||
import { MdOutlineFilePresent } from 'react-icons/md';
|
||||
@ -12,12 +12,11 @@ import { FileSupportedFormatsEnum } from '@educt/enums';
|
||||
|
||||
type FilesUploaderPropsType = {
|
||||
onChange: (files: File[]) => void;
|
||||
files?: Array<File> | undefined;
|
||||
files?: File[] | undefined;
|
||||
};
|
||||
|
||||
const FilesUploader: React.FC<FilesUploaderPropsType> = ({ onChange, files }) => {
|
||||
const fileInputRef = useRef<HTMLInputElement>(null);
|
||||
const [selectedFiles, setSelectedFiles] = useState<Array<File>>([]);
|
||||
|
||||
const onSelectFileHandler = () => {
|
||||
if (fileInputRef.current) {
|
||||
@ -28,12 +27,9 @@ const FilesUploader: React.FC<FilesUploaderPropsType> = ({ onChange, files }) =>
|
||||
/**
|
||||
* Detach file
|
||||
*/
|
||||
const onRemoveSelectedFileHandler = (selectedFile: File) => () =>
|
||||
setSelectedFiles(selectedFiles => {
|
||||
const updated = selectedFiles.filter(file => file.name !== selectedFile.name);
|
||||
onChange(updated);
|
||||
return updated;
|
||||
});
|
||||
const onRemoveSelectedFileHandler = (selectedFile: File) => () => {
|
||||
onChange([...Array.from(files?.filter(file => file.name !== selectedFile.name) || [])]);
|
||||
};
|
||||
|
||||
/**
|
||||
* Attach file
|
||||
@ -41,20 +37,13 @@ const FilesUploader: React.FC<FilesUploaderPropsType> = ({ onChange, files }) =>
|
||||
const onChangeFileHandler = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
e.preventDefault();
|
||||
|
||||
const { files } = e.target;
|
||||
|
||||
if (files && files.length !== 0) {
|
||||
const isAlreadySelected = selectedFiles.find(selectedFile =>
|
||||
Array.from(files).some(file => file.name === selectedFile.name)
|
||||
if (e.target.files && e.target.files.length !== 0) {
|
||||
const isAlreadySelected = (files || []).find(selectedFile =>
|
||||
Array.from(e.target.files || []).some(file => file.name === selectedFile.name)
|
||||
);
|
||||
|
||||
if (isAlreadySelected) return;
|
||||
|
||||
setSelectedFiles(selectedFiles => {
|
||||
const updated = [...selectedFiles, ...Array.from(files)];
|
||||
onChange(updated);
|
||||
return updated;
|
||||
});
|
||||
onChange([...Array.from(files || []), ...e.target.files]);
|
||||
}
|
||||
};
|
||||
|
||||
@ -72,7 +61,7 @@ const FilesUploader: React.FC<FilesUploaderPropsType> = ({ onChange, files }) =>
|
||||
/>
|
||||
{files && (
|
||||
<Stack>
|
||||
{selectedFiles.map((file, index) => (
|
||||
{files.map((file, index) => (
|
||||
<Flex
|
||||
key={index}
|
||||
alignItems={'center'}
|
||||
|
||||
@ -37,7 +37,6 @@ const LessonForm: React.FC<LessonFormPropsType> = ({ onSubmit, buttonLabel, isLo
|
||||
const {
|
||||
control,
|
||||
register,
|
||||
watch,
|
||||
formState: { errors, isDirty },
|
||||
} = reactHookForm;
|
||||
|
||||
@ -104,7 +103,7 @@ const LessonForm: React.FC<LessonFormPropsType> = ({ onSubmit, buttonLabel, isLo
|
||||
)}
|
||||
/>
|
||||
<Text as='small' color='red.500'>
|
||||
{errors.materials?.map(m => m.message)}
|
||||
{errors.materials?.message}
|
||||
</Text>
|
||||
<FormHelperText>
|
||||
Supported formats:{' '}
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
import { VideoSupportedFormatsEnum } from '@educt/enums';
|
||||
import * as helpers from '@educt/helpers';
|
||||
import yup from '@educt/schema';
|
||||
|
||||
const VIDEO_FILE_SIZE = 5000 * 1024 * 1024;
|
||||
const MATERIAL_FILE_SIZE = 10000 * 1024;
|
||||
const MATERIAL_FILE_SIZE = 100000 * 1024;
|
||||
|
||||
const LessonFormSchema = yup.object().shape({
|
||||
title: yup.string().required('Title field name is required').max(90, 'Title must be at most 90 characters'),
|
||||
@ -13,25 +13,26 @@ const LessonFormSchema = yup.object().shape({
|
||||
duration: yup.string().required('Duration field name is required'),
|
||||
video: yup
|
||||
.mixed()
|
||||
.test('fileSize', 'File size is too large', (value: File) => {
|
||||
if (!value) return true;
|
||||
return value && value.size <= VIDEO_FILE_SIZE;
|
||||
})
|
||||
.test('fileFormat', 'This file format is not supported', (value: File) => {
|
||||
if (!value) return true;
|
||||
return value && Object.values(VideoSupportedFormatsEnum).includes(value.type as VideoSupportedFormatsEnum);
|
||||
})
|
||||
.test(
|
||||
'fileSize',
|
||||
`File size is too large, maximum size is ${helpers.transformBytes(VIDEO_FILE_SIZE)}`,
|
||||
(value: File) => {
|
||||
if (!value) return true;
|
||||
return value && value.size <= VIDEO_FILE_SIZE;
|
||||
}
|
||||
)
|
||||
.required('Video field name is required'),
|
||||
// materials: yup
|
||||
// .mixed()
|
||||
// .test('fileSize', 'File size is too large', (value: File) => {
|
||||
// if (!value) return true;
|
||||
// return value && value.size <= VIDEO_FILE_SIZE;
|
||||
// })
|
||||
// .test('fileFormat', 'This file format is not supported', (value: File) => {
|
||||
// if (!value) return true;
|
||||
// return value && VIDEO_SUPPORTED_FORMATS.includes(value.type);
|
||||
// }),
|
||||
materials: yup
|
||||
.mixed()
|
||||
.test(
|
||||
'fileSize',
|
||||
`File size is too large, maximum size is ${helpers.transformBytes(MATERIAL_FILE_SIZE)}`,
|
||||
(values: File[]) => {
|
||||
if (!values) return true;
|
||||
return values && values.every(value => value.size <= MATERIAL_FILE_SIZE);
|
||||
}
|
||||
)
|
||||
.optional(),
|
||||
});
|
||||
|
||||
export default LessonFormSchema;
|
||||
|
||||
@ -19,7 +19,7 @@ export enum VideoSupportedFormatsEnum {
|
||||
|
||||
export enum FileSupportedFormatsEnum {
|
||||
PDF = 'application/pdf',
|
||||
ZIP = 'application/zip',
|
||||
ZIP = 'application/x-zip-compressed',
|
||||
RAR = 'application/x-rar-compressed',
|
||||
DOC = 'application/msword',
|
||||
DOCX = 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user