Styled and refactored UploadForm component
This commit is contained in:
parent
4365473f0d
commit
cfc89ec987
@ -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;
|
||||||
|
}
|
||||||
|
}
|
@ -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>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user