raintrack-ui/src/components/FileManualForm.js

116 lines
4.4 KiB
JavaScript

import React, {useContext, useEffect, useState} from 'react';
import {toast} from "react-toastify";
import {AuthContext} from "../App";
import {useForm} from "react-hook-form";
import {query} from "../auth";
import {Input} from "../custom";
function FileManualForm({id, title = "Upload Individual Entry", defaultData = {}, editType: edit = false}) {
const {authState} = useContext(AuthContext)
const [manualError, setManualError] = useState("")
const {register, handleSubmit, errors, setError, reset, setValue} = useForm();
const manualUpload = async (data) => {
const {status, json} = await query("/data/add", data).catch(() => {
return {status: 500, json: {reason: "The upload server is offline!"}}
})
console.debug("Manual Upload Response:", json)
return {status, json}
}
function submitManual(data) {
let req = data
let split = data.date.split(/[/-]/);
// noinspection JSCheckFunctionSignatures
let date = new Date(split[2], Number(split[0]) - 1, split[1])
req.date = date.getFullYear() + "-" + (date.getMonth() + 1) + "-" + date.getDate()
if (date > new Date()) return setError("date", "time", "Your date must be in the past.")
if (date < new Date(1900, 0, 0)) return setError("date", "time", "Your date must be after 1900.")
if (date.getDate() === 0) return setError("date", "format", "Invalid Date format (MM-DD-YYYY)")
if (isNaN(parseFloat(data["precipitation"]))) {
setError("precipitation", "format", "Invalid format. Precipitation must be a number. E.g 0.24")
}
req.precipitation = parseFloat(data["precipitation"])
req.id = id
req.token = authState.token;
(async () => {
let {json, status} = await manualUpload(data)
if (status !== 200) return setManualError(json.reason)
reset()
if (edit) window.location.reload()
toast.success("Entry successfully uploaded")
})();
}
const formClasses = edit
? "bg-white shadow-lg p-4 overflow-hidden rounded-lg my-6 px-6 max-w-lg w-128"
: "bg-white shadow-lg p-4 overflow-hidden rounded-lg my-6 px-6 w-11/12 lg:mx-2 lg:my-5 lg:px-5 lg:w-5/12"
useEffect(() => {
if (edit) {
const date = new Date(defaultData.Date)
const formattedDate = (date.getMonth() + 1).toString().padStart(2, "0") + "-" + date.getDate().toString().padStart(2, "0") + "-" + date.getFullYear()
setValue([
{date: formattedDate},
{precipitation: defaultData.Precipitation},
{latitude: defaultData.Latitude},
{longitude: defaultData.Longitude},
{remarks: defaultData.Remarks},
])
}
}, [defaultData, edit, setValue])
return (
<form className={formClasses} onSubmit={handleSubmit(submitManual)}>
<div className="text-lg font-medium mb-4">{title}</div>
{manualError && <div
className="px-2 py-2 mb-8 bg-red-300 text-red-900 text-xs font-semibold border border-red-600 rounded">
{manualError}
</div>
}
<Input name="date" type="text" placeholder="Date (MM-DD-YYYY)" errors={errors}
register={register({
required: {value: true, message: "You must provide a date."},
pattern: {
value: /^\d\d?[/-]\d\d?[/-]\d\d\d?\d?$/,
message: "Invalid Date format (MM-DD-YYYY)"
},
})}/>
<Input name="precipitation" placeholder="Precipitation (Inches)" errors={errors}
register={register({
required: {value: true, message: "You must provide the precipitation."},
pattern: {
value: /^\d*\.?\d*$/,
message: "Invalid format. Precipitation must be a number. E.g 0.24"
}
})}/>
<Input name="latitude" type="text" placeholder="Latitude" errors={errors}
register={register({
required: {value: true, message: "Latitude and Longitude are both required."}
})}/>
<Input name="longitude" type="text" placeholder="Longitude" errors={errors}
register={register({
required: {value: true, message: "Latitude and Longitude are both required."}
})}/>
<Input name="remarks" type="text" placeholder="Remarks (Optional)" errors={errors}
register={register}/>
<div className="flex flex-1 justify-center">
<input className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 text-center rounded"
type="submit" value="Submit"/>
</div>
</form>
);
}
export default FileManualForm;