add lint js

This commit is contained in:
Romulus21
2024-03-06 09:42:12 +01:00
parent 2de7c78344
commit 115d597a09
26 changed files with 479 additions and 163 deletions

View File

@@ -1,9 +1,9 @@
import React, {FC} from "react";
import {PropsWithChildren} from "react";
import React, {FC} from "react"
import {PropsWithChildren} from "react"
const Card: FC<PropsWithChildren<CardProps>> = ({children, className = ''}) => {
return <div className={`${className} border m-1 rounded py-1 px-2`}>
return <div className={`${className} m-1 rounded border px-2 py-1`}>
{children}
</div>
}

View File

@@ -10,7 +10,7 @@ const Field: FC<FieldProps> = ({children, type = 'text', className = '', ...prop
htmlFor={props.id ?? undefined}>
{children}
</label>}
<input className={`${className} w-full mt-2 rounded dark:bg-gray-700`}
<input className={`${className} mt-2 w-full rounded dark:bg-gray-700`}
type={type}
{...props}/>
<div className={`error-message`} />
@@ -24,7 +24,7 @@ interface FieldProps {
type?: HTMLInputTypeAttribute,
name: string,
id?: string,
value: any,
value?: string|number|undefined,
placeholder?: string,
autoFocus?: boolean,
className?: string,

View File

@@ -7,7 +7,7 @@ const Header = () => {
const {authUser} = useAuthUser()
const location = useLocation()
return <header className="flex justify-between py-3 px-5 bg-blue-700 text-white text-xl">
return <header className="flex justify-between bg-blue-700 px-5 py-3 text-xl text-white">
<div>
<Link to="/">Bermite</Link>
</div>

View File

@@ -1,4 +1,4 @@
import React, {FC} from "react";
import React, {FC} from "react"
const Img: FC<{src: string, alt: string, width: string}> = ({src, alt, width, ...props}) => {

View File

@@ -1,7 +1,7 @@
import React, {Dispatch, FC, FormEvent, SetStateAction, useState} from "react"
import useAxiosTools from "../../hooks/AxiosTools";
import Field from "../Field";
import Card from "../Card";
import useAxiosTools from "../../hooks/AxiosTools"
import Field from "../Field"
import Card from "../Card"
const AddRainfall: FC<AddRainfallProps> = ({reload}) => {
@@ -23,12 +23,12 @@ const AddRainfall: FC<AddRainfallProps> = ({reload}) => {
}
}
return <Card className="min-w-[300px] overflow-hidden self-start w-full md:w-auto">
<h2 className="text-center bg-blue-500 text-white -mx-2 -mt-1 text-lg font-bold px-2 py-1">
Ajout d'une mesure
return <Card className="w-full min-w-[300px] self-start overflow-hidden md:w-auto">
<h2 className="-mx-2 -mt-1 bg-blue-500 px-2 py-1 text-center text-lg font-bold text-white">
Ajout d&apos;une mesure
</h2>
{errorLabel()}
<form onSubmit={handleSubmit} className="p-2 flex flex-col gap-2">
<form onSubmit={handleSubmit} className="flex flex-col gap-2 p-2">
<Field type="date"
name="date"
value={data.date}

View File

@@ -1,9 +1,9 @@
import React, {FC, useEffect, useState} from "react"
import useAxiosTools from "../../hooks/AxiosTools";
import {rainfall} from "../../types";
import {AxiosError} from "axios";
import Card from "../Card";
import {Link} from "react-router-dom";
import useAxiosTools from "../../hooks/AxiosTools"
import {rainfall} from "../../types"
import {AxiosError} from "axios"
import Card from "../Card"
import {Link} from "react-router-dom"
const LastFiveMesure: FC<LastFiveMesureProps> = ({loadedAt}) => {
@@ -27,14 +27,14 @@ const LastFiveMesure: FC<LastFiveMesureProps> = ({loadedAt}) => {
}
}
return <Card className="min-w-[300px] overflow-hidden self-start w-full md:w-auto">
<h1 className="text-center bg-blue-500 text-white -mx-2 -mt-1 text-lg font-bold px-2 py-1">5 dernières mesures</h1>
return <Card className="w-full min-w-[300px] self-start overflow-hidden md:w-auto">
<h1 className="-mx-2 -mt-1 bg-blue-500 px-2 py-1 text-center text-lg font-bold text-white">5 dernières mesures</h1>
{errorLabel()}
<table className="w-full text-center">
<tbody>
{data.map(line => <tr key={line.id} className="">
<td>{(new Date(line.date)).toLocaleDateString()}</td>
<td className="text-right px-2">{line.value}</td>
<td className="px-2 text-right">{line.value}</td>
</tr>)}
</tbody>
</table>

View File

@@ -0,0 +1,122 @@
import React, {FC, useEffect, useRef, useState} from "react"
import {rainfallGraphData} from "../../types"
import {init, getInstanceByDom} from 'echarts'
import type {ECharts } from "echarts"
const RainFallEcharts: FC<RainFallEchartsProps> = ({width, height, data, loading}) => {
// https://dev.to/manufac/using-apache-echarts-with-react-and-typescript-353k
const chartRef = useRef<HTMLDivElement>(null)
const [option, setOption] = useState({
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
}
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
label: {
show: true,
},
xAxis: [
{
type: 'category',
data: data.map(d => d.label),
axisTick: {
alignWithLabel: true
}
}
],
yAxis: [
{
type: 'value'
}
],
series: [
{
name: 'Pluviométrie',
type: 'bar',
color: ['steelblue'],
barWidth: '80%',
data: data.map(d => d.value)
}
]
})
useEffect(() => {
let chart: ECharts | undefined
console.log('in', width, height)
if (chartRef.current !== null) {
chart = init(chartRef.current)
}
function resizeChart() {
chart?.resize()
}
window.addEventListener("resize", resizeChart)
return () => {
chart?.dispose()
window.removeEventListener("resize", resizeChart)
}
}, [])
useEffect(() => {
console.log('data')
if (chartRef.current !== null) {
console.log('data', data)
const chart = getInstanceByDom(chartRef.current)
chart?.setOption(option)
}
}, [option, data])
useEffect(() => {
setOption({...option,
xAxis: [
{
type: 'category',
data: data.map(d => d.label),
axisTick: {
alignWithLabel: true
}
}
],
series: [
{
name: 'Pluviométrie',
type: 'bar',
color: ['steelblue'],
barWidth: '80%',
data: data.map(d => d.value)
}
]
})
}, [data])
useEffect(() => {
if (chartRef.current !== null) {
const chart = getInstanceByDom(chartRef.current)
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
loading === true ? chart?.showLoading() : chart?.hideLoading()
}
}, [loading])
return <div className="relative">
<div ref={chartRef} style={{width: "100%", height}} />
<div id="tooltip" className="absolute left-10 top-3 rounded border p-2" style={{opacity: 0}}></div>
</div>
}
export default RainFallEcharts
interface RainFallEchartsProps {
width: number,
height: number,
data: rainfallGraphData[],
loading: boolean,
}

View File

@@ -1,6 +1,6 @@
import * as d3 from "d3"
import React, {FC, LegacyRef, useEffect, useRef} from "react"
import {rainfall, rainfallGraphData} from "../../types";
import React, {FC, useEffect, useRef} from "react"
import {rainfallGraphData} from "../../types"
const RainfallGraph: FC<RainfallGraphProps> = ({width, height, data, start_date, end_date}) => {
@@ -50,7 +50,7 @@ const RainfallGraph: FC<RainfallGraphProps> = ({width, height, data, start_date,
.call(d3.axisBottom(x)
.ticks(8)
.tickFormat(
// @ts-ignore
// @ts-expect-error change time format
d3.timeFormat("%d/%m/%Y")
)
, 0)
@@ -101,7 +101,7 @@ const RainfallGraph: FC<RainfallGraphProps> = ({width, height, data, start_date,
return <div className="relative">
<svg ref={svgRef} />
<div id="tooltip" className="absolute px-2 py-2 top-3 left-10 rounded border" style={{opacity: 0}}></div>
<div id="tooltip" className="absolute left-10 top-3 rounded border p-2" style={{opacity: 0}}></div>
</div>
}

View File

@@ -1,5 +1,6 @@
const weekDays = ['dimanche', 'lundi', 'mardi', 'mercredi', 'jeudi', 'vendredi', 'samedi']
// eslint-disable-next-line @typescript-eslint/no-unused-vars
interface Date {
getWeekDay(): string,
toSQLDate(): string,

View File

@@ -6,8 +6,8 @@ import React, {
useContext,
useEffect,
useState
} from "react";
import axios from "axios";
} from "react"
import axios from "axios"
const AuthUserContext = createContext<AuthUserProps|undefined>(undefined)
@@ -28,7 +28,7 @@ export const AuthUserProvider = ({children}: PropsWithChildren) => {
const res = await axios.get('/api/user')
setAuthUser(res.data)
} catch (e) {
// @ts-ignore
// @ts-expect-error check axios response status
if (e.response.status === 401) {
console.info('no user login')
if (window.location.pathname !== '/connexion') {
@@ -44,7 +44,7 @@ export const AuthUserProvider = ({children}: PropsWithChildren) => {
const logout = async () => {
try {
setLoadingAuthUser(false)
const res = await axios.delete('/api/logout')
await axios.delete('/api/logout')
setAuthUser(null)
window.location.replace('/')
} catch (e) {

View File

@@ -1,29 +1,31 @@
import {useState} from "react";
import axios from "axios";
import React from "react";
import {cleanErrorsForm, displayFormErrors} from "../utilities/form";
import {useState} from "react"
import axios, {AxiosError} from "axios"
import React from "react"
import {cleanErrorsForm, displayFormErrors, ValidationErrors} from "../utilities/form"
const useAxiosTools = () => {
const [loading, setLoading] = useState(false)
const [error, setError] = useState<string|null>(null)
const [error, setError] = useState<string|null|undefined>(null)
const axiosGet = axios.get
const axiosPost = axios.post
const axiosPut = axios.put
const axiosDelete = axios.delete
const errorCatch = (error: any) => {
if (error.response && error.response.status === 422) {
displayFormErrors(error)
} else {
setError(error.response?.data.message || error.message)
const errorCatch = (error: Error|AxiosError|unknown) => {
if (axios.isAxiosError(error)) {
(error.response?.status === 422)
? displayFormErrors(error)
: setError(error.response?.data.message || error.message)
} else if (error instanceof Error) {
setError(error.message)
}
}
const errorLabel = () => {
return error ? <div className="bg-red-600 rounded m-2 text-center text-white px-2 py-1 mx-auto">{error}</div>: null
return error ? <div className="m-2 mx-auto rounded bg-red-600 px-2 py-1 text-center text-white">{error}</div>: null
}
const cleanErrors = () => {

View File

@@ -4,12 +4,13 @@ const useDimension = () => {
const RESET_TIMEOUT = 300
let movement_timer: number|undefined = undefined
const targetRef = useRef<any>()
const targetRef = useRef<HTMLDivElement>()
const [dimensions, setDimensions] = useState({ width:0, height: 0 })
useEffect(() => {
window.addEventListener('resize', ()=>{
clearInterval(movement_timer)
// @ts-expect-error setTimeout defined in var
movement_timer = setTimeout(testDimensions, RESET_TIMEOUT)
})
})

View File

@@ -1,9 +1,6 @@
import React, {FormEvent, SyntheticEvent, useState} from "react"
import Field from "../../components/Field";
import axios from "axios";
import {useNavigate} from "react-router-dom";
import useAuthUser from "../../hooks/AuthUser";
import useAxiosTools from "../../hooks/AxiosTools";
import React, {FormEvent, useState} from "react"
import Field from "../../components/Field"
import useAxiosTools from "../../hooks/AxiosTools"
const ForgotPassword = () => {
@@ -16,15 +13,15 @@ const ForgotPassword = () => {
try {
cleanErrors()
await axiosGet('/sanctum/csrf-cookie')
const res = await axiosPost('/api/forgot', {email})
await axiosPost('/api/forgot', {email})
setMessage(true)
} catch (e) {
errorCatch(e)
} catch (error) {
errorCatch(error)
}
}
return <div>
<form onSubmit={handleSubmit} className="w-96 mx-auto mt-10 border shadow p-3">
<form onSubmit={handleSubmit} className="mx-auto mt-10 w-96 border p-3 shadow">
<h1 className="text-center">Mot de passe oublié</h1>
{message && <p className="bg-green-600">Un email vous a é envoyé pour modifier le mot de passe.</p>}
@@ -37,7 +34,7 @@ const ForgotPassword = () => {
value={email}
onChange={event => setEmail(event.target.value)}
autoFocus>Email</Field>
<button type="submit" className="mt-5 btn-primary w-full block text-lg">Valider</button>
<button type="submit" className="btn-primary mt-5 block w-full text-lg">Valider</button>
</form>
</div>
}

View File

@@ -1,10 +1,9 @@
import React, {FormEvent, SyntheticEvent, useState} from "react"
import Field from "../../components/Field";
import axios from "axios";
import {Link, useNavigate} from "react-router-dom";
import useAuthUser from "../../hooks/AuthUser";
import Card from "../../components/Card";
import useAxiosTools from "../../hooks/AxiosTools";
import React, {FormEvent, useState} from "react"
import Field from "../../components/Field"
import {Link, useNavigate} from "react-router-dom"
import useAuthUser from "../../hooks/AuthUser"
import Card from "../../components/Card"
import useAxiosTools from "../../hooks/AxiosTools"
const Login = () => {
@@ -22,15 +21,15 @@ const Login = () => {
const res = await axiosPost('/api/login', {email, password})
setAuthUser(res.data.user)
navigate('/')
} catch (e) {
errorCatch(e)
} catch (error) {
errorCatch(error)
}
}
return <div>
<Card className="w-96 mx-auto mt-10 p-2 overflow-hidden">
<Card className="mx-auto mt-10 w-96 overflow-hidden p-2">
<form onSubmit={handleSubmit}>
<h1 className="text-center bg-blue-500 -mx-2 -mt-1 text-lg font-bold px-2 py-1 mb-2">
<h1 className="-mx-2 -mt-1 mb-2 bg-blue-500 px-2 py-1 text-center text-lg font-bold">
Connexion
</h1>
{errorLabel()}
@@ -46,7 +45,7 @@ const Login = () => {
placeholder="******"
value={password}
onChange={event => setPassword(event.target.value)}>Mot de passe</Field>
<button type="submit" className="mt-5 btn-primary w-full block text-lg">Valider</button>
<button type="submit" className="btn-primary mt-5 block w-full text-lg">Valider</button>
<Link to="/mot-de-passe-oubliee" className="mt-2 inline-block">Mot de passe oublié ?</Link>
</form>
</Card>

View File

@@ -1,9 +1,9 @@
import React, {FormEvent, useState} from "react"
import useAuthUser from "../../hooks/AuthUser"
import PageLayout from "../../components/PageLayout"
import Card from "../../components/Card";
import Field from "../../components/Field";
import useAxiosTools from "../../hooks/AxiosTools";
import Card from "../../components/Card"
import Field from "../../components/Field"
import useAxiosTools from "../../hooks/AxiosTools"
const Profile = () => {
@@ -18,8 +18,8 @@ const Profile = () => {
try {
const res = await axiosPost(`/api/locations`, {latitude, longitude})
setAuthUser(res.data)
} catch (e) {
errorCatch(e)
} catch (error) {
errorCatch(error)
}
}
@@ -65,7 +65,7 @@ const Profile = () => {
Longitude
</Field>
<div className="self-end">
<button type="submit" className="btn-primary w-24 h-10">Valider</button>
<button type="submit" className="btn-primary h-10 w-24">Valider</button>
</div>
</div>
</form>}

View File

@@ -1,8 +1,8 @@
import React, {ChangeEvent, FormEvent, SyntheticEvent, useState} from "react"
import Field from "../../components/Field";
import axios from "axios";
import {useNavigate} from "react-router-dom";
import Card from "../../components/Card";
import React, {FormEvent, useState} from "react"
import Field from "../../components/Field"
import axios from "axios"
import {useNavigate} from "react-router-dom"
import Card from "../../components/Card"
const Register = () => {
@@ -15,18 +15,18 @@ const Register = () => {
event.preventDefault()
try {
await axios.get('/sanctum/csrf-cookie')
const res = await axios.post('/api/register', {name, email, password})
await axios.post('/api/register', {name, email, password})
navigate('/')
} catch (e) {
console.error(e)
} catch (error) {
console.error(error)
}
}
return <div>
<Card className="w-96 mx-auto mt-10 p-2 overflow-hidden">
<Card className="mx-auto mt-10 w-96 overflow-hidden p-2">
<form onSubmit={handleSubmit}>
<h1 className="text-center bg-blue-500 -mx-2 -mt-1 text-lg font-bold px-2 py-1 mb-2">
S'inscrire
<h1 className="-mx-2 -mt-1 mb-2 bg-blue-500 px-2 py-1 text-center text-lg font-bold">
S&apos;inscrire
</h1>
<Field placeholder="Nom"
@@ -46,7 +46,7 @@ const Register = () => {
value={password}
onChange={event => setPassword(event.target.value)}
autoFocus>Mot de passe</Field>
<button type="submit" className="mt-5 btn-primary w-full block text-lg">Valider</button>
<button type="submit" className="btn-primary mt-5 block w-full text-lg">Valider</button>
</form>
</Card>
</div>

View File

@@ -1,14 +1,12 @@
import PageLayout from "../../components/PageLayout";
import Field from "../../components/Field";
import React, {FormEvent, useState} from "react";
import {useNavigate, useParams} from "react-router-dom";
import useAuthUser from "../../hooks/AuthUser";
import axios from "axios";
import useAxiosTools from "../../hooks/AxiosTools";
import Field from "../../components/Field"
import React, {FormEvent, useState} from "react"
import {useNavigate, useParams} from "react-router-dom"
import useAuthUser from "../../hooks/AuthUser"
import useAxiosTools from "../../hooks/AxiosTools"
const Reset = () => {
let {token} = useParams()
const {token} = useParams()
const navigate = useNavigate()
const {setAuthUser} = useAuthUser()
const [email, setEmail] = useState('')
@@ -24,13 +22,13 @@ const Reset = () => {
const res = await axiosPost('/api/reset', {email, token, password, samePassword})
setAuthUser(res.data.user)
navigate('/connexion')
} catch (e) {
errorCatch(e)
} catch (error) {
errorCatch(error)
}
}
return <div>
<form onSubmit={handleSubmit} className="w-96 mx-auto mt-10 border shadow p-3">
<form onSubmit={handleSubmit} className="mx-auto mt-10 w-96 border p-3 shadow">
<h1 className="text-center">Modifier voter mot de passe</h1>
{errorLabel()}
@@ -51,7 +49,7 @@ const Reset = () => {
placeholder="******"
value={samePassword}
onChange={event => setSamePassword(event.target.value)}>Confirmation du mot de passe</Field>
<button type="submit" className="mt-5 btn-primary w-full block text-lg">Valider</button>
<button type="submit" className="btn-primary mt-5 block w-full text-lg">Valider</button>
</form>
</div>
}

View File

@@ -1,12 +1,12 @@
import React, {useEffect, useState} from "react"
import PageLayout from "../components/PageLayout";
import LastFiveMesure from "../components/rainfall/LastFiveMesure";
import AddRainfall from "../components/rainfall/AddRainfall";
import RainfallGraph from "../components/rainfall/RainfallGraph";
import useAxiosTools from "../hooks/AxiosTools";
import {rainfall, rainfallGraphData} from "../types";
import Field from "../components/Field";
import useDimension from "../hooks/DimensionHook";
import PageLayout from "../components/PageLayout"
import LastFiveMesure from "../components/rainfall/LastFiveMesure"
import AddRainfall from "../components/rainfall/AddRainfall"
import useAxiosTools from "../hooks/AxiosTools"
import {rainfallGraphData} from "../types"
import Field from "../components/Field"
import useDimension from "../hooks/DimensionHook"
import RainFallEcharts from "../components/rainfall/RainFallEcharts"
const Rainfall = () => {
@@ -17,7 +17,7 @@ const Rainfall = () => {
end_date: (new Date()).toSQLDate(),
period: 'day',
})
const {errorCatch, errorLabel, axiosGet} = useAxiosTools()
const {loading, setLoading, errorCatch, errorLabel, axiosGet} = useAxiosTools()
const {targetRef, dimensions} = useDimension()
useEffect(() => {
@@ -26,22 +26,25 @@ const Rainfall = () => {
const fetchGraphData = async () => {
try {
setLoading(true)
const params = `start=${graphDetails.start_date}&end=${graphDetails.end_date}&period=${graphDetails.period}`
const res = await axiosGet(`/api/rainfalls/graph?${params}`)
setGraphData(res.data)
} catch (error) {
errorCatch(error)
} finally {
setLoading(false)
}
}
return <PageLayout>
<div className="flex flex-wrap gap-2 justify-between">
<div className="flex flex-wrap justify-between gap-2">
<LastFiveMesure loadedAt={loadedAt} />
<AddRainfall reload={reload} />
</div>
{errorLabel()}
<form className="flex mb-2 mx-5 gap-2 flex-wrap">
<form className="mx-5 mb-2 flex flex-wrap gap-2">
<Field name="start_date"
type="date"
value={graphDetails.start_date}
@@ -51,7 +54,7 @@ const Rainfall = () => {
value={graphDetails.end_date}
onChange={e => setGraphDetails({...graphDetails, end_date: (new Date(e.target.value)).toSQLDate()})} />
<div className="form-control">
<select className={` w-full mt-2 rounded dark:bg-gray-700`}
<select className={` mt-2 w-full rounded dark:bg-gray-700`}
value={graphDetails.period}
onChange={e => setGraphDetails({...graphDetails, period: e.target.value})}>
<option value="day">Jour</option>
@@ -61,11 +64,15 @@ const Rainfall = () => {
</select>
</div>
</form>
<div ref={targetRef} className="mb-20">
<RainfallGraph width={dimensions.width}
height={500}
data={graphData} start_date={graphDetails.start_date}
end_date={graphDetails.end_date} />
<div ref={targetRef} className="mb-20 min-h-96">
<RainFallEcharts width={dimensions.width}
height={500}
data={graphData}
loading={loading} />
{/*<RainfallGraph width={dimensions.width}*/}
{/* height={500}*/}
{/* data={graphData} start_date={graphDetails.start_date}*/}
{/* end_date={graphDetails.end_date} />*/}
</div>
</PageLayout>
}

View File

@@ -1,7 +1,7 @@
import React, {useEffect, useState} from "react";
import PageLayout from "../../components/PageLayout";
import useAxiosTools from "../../hooks/AxiosTools";
import {rainfall} from "../../types";
import React, {useEffect, useState} from "react"
import PageLayout from "../../components/PageLayout"
import useAxiosTools from "../../hooks/AxiosTools"
import {rainfall} from "../../types"
const RainfallIndex = () => {
@@ -24,13 +24,9 @@ const RainfallIndex = () => {
}
}
const handleEdit = (rainfall: rainfall) => {
console.log(rainfall)
}
const handleDelete = async (rainfall: rainfall) => {
try {
const res = await axiosDelete(`/api/rainfalls/${rainfall.id}`)
await axiosDelete(`/api/rainfalls/${rainfall.id}`)
setRainfalls(rainfalls.filter(r => r.id !== rainfall.id))
} catch (error) {
errorCatch(error)
@@ -39,7 +35,7 @@ const RainfallIndex = () => {
return <PageLayout>
{errorLabel()}
<table className="border w-96 text-center mx-auto">
<table className="mx-auto w-96 border text-center">
<thead>
<tr>
<th>Date</th>

View File

@@ -8,14 +8,13 @@ const ForgotPassword = lazy(() => import('./Auth/ForgotPassword'))
const Home = lazy(() => import('./Home'))
const Login = lazy(() => import('./Auth/Login'))
const Profile = lazy(() => import('./Auth/Profile'))
const Register = lazy(() => import('./Auth/Register'))
const Reset = lazy(() => import('./Auth/Reset'))
const Rainfall = lazy(() => import('./Rainfall'))
const RainfallIndex = lazy(() => import('./Rainfall/RainfallIndex'))
const Router = () => {
const {authUser, loadingAuthUser, logout} = useAuthUser()
const {loadingAuthUser} = useAuthUser()
return <>
{loadingAuthUser ? '...loading'

View File

@@ -9,7 +9,6 @@ const Weather = () => {
const [currentWeather, setCurrentWeather] = useState<WeatherValue|null>(null)
const [fetchTime, setFetchTime] = useState(0)
const [count, setCount] = useState(0)
const [weatherDays, setWeatherDays] = useState<[string, WeatherValue[]][]|null>(null)
const {loading, setLoading, errorLabel, errorCatch, cleanErrors, axiosGet} = useAxiosTools()
@@ -31,9 +30,9 @@ const Weather = () => {
const res = await axiosGet(`/api/weather`)
const currentWeather = res.data.list[0]
let weatherDays: [string, WeatherValue[]][] = []
const weatherDays: [string, WeatherValue[]][] = []
let objectEntries = {index: -1, date: ''}
res.data.list.forEach((item: WeatherValue, index: number) => {
res.data.list.forEach((item: WeatherValue) => {
const date = item.dt_txt.split(' ')[0]
if (date === (new Date).toSQLDate()) {
@@ -70,7 +69,7 @@ const Weather = () => {
{errorLabel()}
<Card className="flex justify-between">
<div className="flex flex-col m-2 justify-between">
<div className="m-2 flex flex-col justify-between">
<span className="text-6xl">{currentWeather?.main.temp.toFixed()} °C</span>
<span className="text-secondary dark:text-secondary-ligth">{currentWeather?.weather[0].description}</span>
</div>
@@ -81,9 +80,9 @@ const Weather = () => {
{currentWeather && <Img src={`images/icons/${currentWeather?.weather[0].icon}.svg`}
alt={currentWeather?.weather[0].main} width="120px" />}
</div>
<div className="flex gap-1 flex-col">
<span className="text-4xl pt-5">{currentWeather?.main.temp_max.toFixed()} <span className="text-2xl">°C</span></span>
<span className="text-secondary text-2xl mt-2 dark:text-secondary-ligth">{currentWeather?.main.temp_min.toFixed()} °C</span>
<div className="flex flex-col gap-1">
<span className="pt-5 text-4xl">{currentWeather?.main.temp_max.toFixed()} <span className="text-2xl">°C</span></span>
<span className="mt-2 text-2xl text-secondary dark:text-secondary-ligth">{currentWeather?.main.temp_min.toFixed()} °C</span>
</div>
</div>
</Card>
@@ -108,7 +107,7 @@ const WeatherCard: FC<{date: string, values: WeatherValue[]}> = ({date, values=
icon: '',
description: '',
}
const result: {[k: string]: number} = {}
const result: Record<string, number> = {}
values.forEach(value => {
if (value.main.temp_min < weatherState.min) {
weatherState.min = value.main.temp_min
@@ -144,17 +143,17 @@ const WeatherCard: FC<{date: string, values: WeatherValue[]}> = ({date, values=
}, [])
return <div className="flex gap-5">
<div className="flex flex-col gap-2 flex-1 h-full">
<span className="font-bold text-lg" title={(new Date(date)).toLocaleDateString()}>{(new Date(date)).getWeekDay()}</span>
<div className="flex h-full flex-1 flex-col gap-2">
<span className="text-lg font-bold" title={(new Date(date)).toLocaleDateString()}>{(new Date(date)).getWeekDay()}</span>
<span className="text-secondary dark:text-secondary-ligth">{weatherState?.description}</span>
</div>
<div className="flex items-center -mt-1.5">
<div className="-mt-1.5 flex items-center">
<Img src={`images/icons/${weatherState?.icon}.svg`}
alt={weatherState?.main + ' ' + weatherState?.icon}
width="80px" />
</div>
<div className="flex gap-1 flex-col">
<div className="flex flex-col gap-1">
<span className="text-lg">{weatherState?.max.toFixed()} °C</span>
<span className="text-secondary dark:text-secondary-ligth">{weatherState?.min.toFixed()} °C</span>
</div>

View File

@@ -38,7 +38,3 @@ export interface WeatherTime {
icon: string,
main: 'Rain',
}
export interface WeatherCompilation {
[k: string]: WeatherValue[]
}

View File

@@ -1,14 +1,27 @@
import {AxiosError} from "axios"
export function displayFormErrors(error: any, form: HTMLElement|null = null) {
export function displayFormErrors(error: AxiosError, form: HTMLElement|null = null) {
if (error.response && error.response.status === 422) {
let errors = error.response.data.errors
// @ts-expect-error test axios error
const errors = error.response.data.errors
const formBase = (form) ? form : document.body
Object.keys(errors).forEach(key => {
displayError(key, errors[key], formBase)
Object.entries(errors).forEach(([key, value]) => {
displayError(key, value, formBase)
})
}
}
export interface ValidationErrors {
response: {
status: number,
data: {
errors: object
message?: string,
}
},
message?: string,
}
export function displayError(key: string, message: string, form: HTMLElement|null = null) {
const formBase = (form) ? form : document
const input = formBase.querySelector(`input[name="${key}"], select[name="${key}"], textarea[name="${key}"]`)