feat: added materials uploader

This commit is contained in:
Sergey Yarkov 2022-01-05 01:29:44 +03:00
parent 359deec3bc
commit 03c8e3b8cc
4 changed files with 33 additions and 44 deletions

View File

@ -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'}

View File

@ -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:{' '}

View File

@ -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) => {
.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;
})
.test('fileFormat', 'This file format is not supported', (value: File) => {
if (!value) return true;
return value && Object.values(VideoSupportedFormatsEnum).includes(value.type as VideoSupportedFormatsEnum);
})
}
)
.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;

View File

@ -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',