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"; import React, { useState } from "react";
const validState = (input: HTMLInputElement) => { import plusIcon from "@assets/plus.svg";
const file = input.files?.[0]; import styles from "./UploadForm.module.css";
import { submitFile, validateResponse, validState } from "../api";
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;
};
export const UploadForm = () => { export const UploadForm = () => {
const [error, setError] = useState(""); const [error, setError] = useState("");
const [loading, setLoading] = useState(false);
const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => { const processFile = async (file: File | undefined) => {
setError("");
const fileInput = e.currentTarget;
try { try {
validState(fileInput); if (validState(file)) {
} catch (e) { setError("");
setError(e.message);
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(); e.preventDefault();
}; };
return ( return (
<div> <form
<form onSubmit={handleSubmit}> className={styles.container}
<label htmlFor="input">Book file</label> onDrop={handleFileDrop}
<input onDragOver={handleDragOver}
required >
onChange={handleFileChange} <label className={styles.label} htmlFor="file">
type="file" <img className={styles.plus} src={plusIcon} />
name="file" <span>
id="file" Choose book file or drag and drop it
/> <br />
<p>{error}</p> <span className={styles.error}>{error}</span>
<input type="submit" value="test" disabled={error !== ""} /> </span>
</form> </label>
</div> <input
className={styles.fileInput}
onChange={handleFileChange}
type="file"
name="file"
id="file"
/>
</form>
); );
}; };