Styled and refactored UploadForm component

This commit is contained in:
Dmitriy Shishkov 2021-07-15 18:38:06 +05:00
parent 4365473f0d
commit cfc89ec987
No known key found for this signature in database
GPG Key ID: 14358F96FCDD8060
2 changed files with 103 additions and 41 deletions

View File

@ -0,0 +1,55 @@
.container {
margin: 15vh;
border: 2px dashed black;
height: 70vh;
}
.container:hover {
border-style: solid;
}
.label {
height: 100%;
width: 100%;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
padding: 2vh;
font-size: 1.5rem;
}
.plus {
width: 15vh;
margin-right: 5vh;
}
.error {
color: red;
}
.fileInput {
width: 0.1px;
height: 0.1px;
opacity: 0;
overflow: hidden;
position: absolute;
z-index: -1;
}
@media screen and (orientation: portrait) {
.container {
margin: 15vw;
height: calc(100vh - 30vw);
}
.label {
flex-direction: column;
text-align: center;
}
.plus {
margin-right: 0;
margin-bottom: 5vh;
}
}

View File

@ -1,57 +1,64 @@
import React, { useState } from "react";
const validState = (input: HTMLInputElement) => {
const file = input.files?.[0];
if (!file) throw new Error("Book file is required. Please, attach one");
if (!file.name.match(/\.(fb2|epub)/))
throw new Error(
"Wrong file type. Only FB2 and Epub files are supported. \
If you are trying to upload fb2.zip, please, uncopress it first."
);
if (file.size > 100 * 1024 * 1024)
throw new Error(
"File size is too big. Sorry, but parser is served on a rather cheap hosting, \
so application can't handle such big files."
);
return true;
};
import plusIcon from "@assets/plus.svg";
import styles from "./UploadForm.module.css";
import { submitFile, validateResponse, validState } from "../api";
export const UploadForm = () => {
const [error, setError] = useState("");
const [loading, setLoading] = useState(false);
const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setError("");
const fileInput = e.currentTarget;
const processFile = async (file: File | undefined) => {
try {
validState(fileInput);
} catch (e) {
setError(e.message);
if (validState(file)) {
setError("");
setLoading(true);
const res = await submitFile(file);
setLoading(false);
if (validateResponse(res)) {
// TODO: save book to localstorage
// TODO: redirect to main menu
}
}
} catch (err) {
setError(err.message);
}
};
const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) =>
processFile(e.currentTarget.files?.[0]);
const handleFileDrop = (e: React.DragEvent<HTMLFormElement>) =>
processFile(e.dataTransfer.files[0]);
const handleDragOver = (e: React.DragEvent<HTMLFormElement>) => {
e.stopPropagation();
e.preventDefault();
};
return (
<div>
<form onSubmit={handleSubmit}>
<label htmlFor="input">Book file</label>
<input
required
onChange={handleFileChange}
type="file"
name="file"
id="file"
/>
<p>{error}</p>
<input type="submit" value="test" disabled={error !== ""} />
</form>
</div>
<form
className={styles.container}
onDrop={handleFileDrop}
onDragOver={handleDragOver}
>
<label className={styles.label} htmlFor="file">
<img className={styles.plus} src={plusIcon} />
<span>
Choose book file or drag and drop it
<br />
<span className={styles.error}>{error}</span>
</span>
</label>
<input
className={styles.fileInput}
onChange={handleFileChange}
type="file"
name="file"
id="file"
/>
</form>
);
};