Address updates
This commit is contained in:
@@ -1,2 +1,2 @@
|
|||||||
export { useQueryAPI, useWeatherAPI, useMutationAPI, useCensusAPI } from './useAPI';
|
export { useQueryAPI, useWeatherAPI, useMutationAPI, useOSMAPI } from './useAPI';
|
||||||
export { useCommonHooks } from './useCommonHooks';
|
export { useCommonHooks } from './useCommonHooks';
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
|
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
|
||||||
import { useCommonHooks } from 'hooks';
|
import { useCallback, useRef } from 'react';
|
||||||
import { useCallback, useState } from 'react';
|
import { Flip, toast } from 'react-toastify';
|
||||||
|
|
||||||
const url = `${import.meta.env.PROD ? import.meta.env.VITE_DOMAIN_PROD : import.meta.env.VITE_DOMAIN_DEV}/${import.meta.env.VITE_BASE_URL}`;
|
const url = `${import.meta.env.PROD ? import.meta.env.VITE_DOMAIN_PROD : import.meta.env.VITE_DOMAIN_DEV}/${import.meta.env.VITE_BASE_URL}`;
|
||||||
|
|
||||||
@@ -33,8 +33,10 @@ export function useQueryAPI({ endpoint }: { endpoint: string }) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function useMutationAPI() {
|
export function useMutationAPI() {
|
||||||
const { notify } = useCommonHooks();
|
const toastId = useRef<any>(null);
|
||||||
const [message, setMessage] = useState('');
|
const notify = () => {
|
||||||
|
toastId.current = toast('Sending...', { position: 'bottom-right', autoClose: false });
|
||||||
|
};
|
||||||
const callEndpoint = async (
|
const callEndpoint = async (
|
||||||
method: string,
|
method: string,
|
||||||
endpoint: string,
|
endpoint: string,
|
||||||
@@ -53,11 +55,9 @@ export function useMutationAPI() {
|
|||||||
},
|
},
|
||||||
body: JSON.stringify(body),
|
body: JSON.stringify(body),
|
||||||
};
|
};
|
||||||
setMessage('Sending...');
|
notify();
|
||||||
notify(message);
|
|
||||||
const response = await fetch(`${url}/${endpoint}`, options);
|
const response = await fetch(`${url}/${endpoint}`, options);
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
notify('Error!');
|
|
||||||
const responseData = await response.json();
|
const responseData = await response.json();
|
||||||
if (typeof responseData.detail !== 'string') {
|
if (typeof responseData.detail !== 'string') {
|
||||||
const errorResponse = JSON.stringify({
|
const errorResponse = JSON.stringify({
|
||||||
@@ -69,7 +69,11 @@ export function useMutationAPI() {
|
|||||||
loc: responseData.detail[0]?.loc,
|
loc: responseData.detail[0]?.loc,
|
||||||
type: responseData.detail[0]?.type,
|
type: responseData.detail[0]?.type,
|
||||||
});
|
});
|
||||||
|
toast.update(toastId.current, {
|
||||||
|
render: errorResponse,
|
||||||
|
type: 'error',
|
||||||
|
autoClose: 5000,
|
||||||
|
});
|
||||||
throw new Error(errorResponse);
|
throw new Error(errorResponse);
|
||||||
}
|
}
|
||||||
if (typeof responseData.detail === 'object') {
|
if (typeof responseData.detail === 'object') {
|
||||||
@@ -80,7 +84,11 @@ export function useMutationAPI() {
|
|||||||
endpoint: endpoint,
|
endpoint: endpoint,
|
||||||
msg: responseData.detail.message,
|
msg: responseData.detail.message,
|
||||||
});
|
});
|
||||||
|
toast.update(toastId.current, {
|
||||||
|
render: errorResponse,
|
||||||
|
type: 'error',
|
||||||
|
autoClose: 5000,
|
||||||
|
});
|
||||||
throw new Error(errorResponse);
|
throw new Error(errorResponse);
|
||||||
}
|
}
|
||||||
const errorResponse = JSON.stringify({
|
const errorResponse = JSON.stringify({
|
||||||
@@ -90,10 +98,18 @@ export function useMutationAPI() {
|
|||||||
endpoint: endpoint,
|
endpoint: endpoint,
|
||||||
msg: responseData.detail,
|
msg: responseData.detail,
|
||||||
});
|
});
|
||||||
|
toast.update(toastId.current, {
|
||||||
|
render: errorResponse,
|
||||||
|
type: 'error',
|
||||||
|
autoClose: 5000,
|
||||||
|
});
|
||||||
throw new Error(errorResponse);
|
throw new Error(errorResponse);
|
||||||
}
|
}
|
||||||
setMessage('Success!');
|
toast.update(toastId.current, {
|
||||||
|
render: 'Success!',
|
||||||
|
autoClose: 2000,
|
||||||
|
transition: Flip,
|
||||||
|
});
|
||||||
return await response.json();
|
return await response.json();
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -117,16 +133,36 @@ export function useMutationAPI() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function useWeatherAPI({ endpoint }: { endpoint: string }) {
|
export function useWeatherAPI({
|
||||||
|
endpoint,
|
||||||
|
lat,
|
||||||
|
lon,
|
||||||
|
office,
|
||||||
|
station,
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
}: {
|
||||||
|
endpoint: string;
|
||||||
|
lat?: number;
|
||||||
|
lon?: number;
|
||||||
|
office?: string;
|
||||||
|
station?: string;
|
||||||
|
x?: number;
|
||||||
|
y?: number;
|
||||||
|
}) {
|
||||||
let url = '';
|
let url = '';
|
||||||
if (endpoint === 'baseline') {
|
if (endpoint === 'baseline') {
|
||||||
url = 'https://api.weather.gov/gridpoints/HGX/55,96';
|
url = `https://api.weather.gov/gridpoints/${office}/${x},${y}`;
|
||||||
} else if (endpoint === 'current') {
|
} else if (endpoint === 'current') {
|
||||||
url = 'https://api.weather.gov/stations/KSGR/observations';
|
url = `https://api.weather.gov/stations/${station}/observations`;
|
||||||
} else if (endpoint === 'forecast') {
|
} else if (endpoint === 'forecast') {
|
||||||
url = 'https://api.weather.gov/gridpoints/HGX/55,96/forecast';
|
url = `https://api.weather.gov/gridpoints/${office}/${x},${y}/forecast`;
|
||||||
} else if (endpoint === 'hourly') {
|
} else if (endpoint === 'hourly') {
|
||||||
url = 'https://api.weather.gov/gridpoints/HGX/55,96/forecast/hourly';
|
url = `https://api.weather.gov/gridpoints/${office}/${x},${y}/forecast/hourly`;
|
||||||
|
} else if (endpoint === 'points') {
|
||||||
|
url = `https://api.weather.gov/points/${lat},${lon}`;
|
||||||
|
} else if (endpoint === 'stations') {
|
||||||
|
url = `https://api.weather.gov/gridpoints/${office}/${x},${y}/stations`;
|
||||||
}
|
}
|
||||||
const callEndpoint = async () => {
|
const callEndpoint = async () => {
|
||||||
const response = await fetch(url);
|
const response = await fetch(url);
|
||||||
@@ -142,15 +178,15 @@ export function useWeatherAPI({ endpoint }: { endpoint: string }) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function useCensusAPI({ address }: { address: string }) {
|
export function useOSMAPI({ address }: { address: string }) {
|
||||||
const url = `https://geocoding.geo.census.gov/geocoder/locations/onelineaddress?address=${address?.replaceAll(' ', '+').replaceAll(',', '%2C').replaceAll('#', '%23')}&benchmark=4&format=json`;
|
const url = `https://nominatim.openstreetmap.org/search?addressdetails=1&format=jsonv2&limit=1&q=${address?.replaceAll(' ', '+')}`;
|
||||||
|
|
||||||
const callEndpoint = async () => {
|
const callEndpoint = async () => {
|
||||||
const response = await fetch(url);
|
const response = await fetch(url);
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
throw new Error(`${response.status} ${response.statusText}`);
|
throw new Error(`${response.status} ${response.statusText}`);
|
||||||
}
|
}
|
||||||
return await response.json();
|
const data = await response.json();
|
||||||
|
return await data;
|
||||||
};
|
};
|
||||||
|
|
||||||
return useQuery({
|
return useQuery({
|
||||||
|
|||||||
@@ -2,8 +2,7 @@ import { useLocalStorage } from '@mantine/hooks';
|
|||||||
import { appTheme } from 'contexts';
|
import { appTheme } from 'contexts';
|
||||||
import { useAtom } from 'jotai';
|
import { useAtom } from 'jotai';
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import { toast } from 'react-toastify';
|
import { useOSMAPI, useQueryAPI, useWeatherAPI } from './useAPI';
|
||||||
import { useCensusAPI, useQueryAPI, useWeatherAPI } from './useAPI';
|
|
||||||
|
|
||||||
export function useCommonHooks() {
|
export function useCommonHooks() {
|
||||||
const isMobile = window.matchMedia('(max-width: 600px)').matches;
|
const isMobile = window.matchMedia('(max-width: 600px)').matches;
|
||||||
@@ -62,10 +61,7 @@ export function useCommonHooks() {
|
|||||||
isFetching: wolClientsIsFetching,
|
isFetching: wolClientsIsFetching,
|
||||||
isLoading: wolClientsIsLoading,
|
isLoading: wolClientsIsLoading,
|
||||||
} = useQueryAPI({ endpoint: 'api/wolClients' });
|
} = useQueryAPI({ endpoint: 'api/wolClients' });
|
||||||
const { data: basicWeather } = useWeatherAPI({ endpoint: 'baseline' });
|
|
||||||
const { data: weather } = useWeatherAPI({ endpoint: 'current' });
|
|
||||||
const { data: forecast } = useWeatherAPI({ endpoint: 'forecast' });
|
|
||||||
const { data: hourly } = useWeatherAPI({ endpoint: 'hourly' });
|
|
||||||
const [theme, setTheme] = useAtom(appTheme);
|
const [theme, setTheme] = useAtom(appTheme);
|
||||||
const [themeName, setThemeName] = useLocalStorage<any>({
|
const [themeName, setThemeName] = useLocalStorage<any>({
|
||||||
key: 'theme',
|
key: 'theme',
|
||||||
@@ -102,8 +98,6 @@ export function useCommonHooks() {
|
|||||||
|
|
||||||
const [applicationData, setApplicationData] = useState<any>([]);
|
const [applicationData, setApplicationData] = useState<any>([]);
|
||||||
|
|
||||||
const notify = (notification: any) => toast(notification, { position: 'bottom-right' });
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (apps && !isAppsFetching) {
|
if (apps && !isAppsFetching) {
|
||||||
setApplicationData(apps);
|
setApplicationData(apps);
|
||||||
@@ -161,17 +155,40 @@ export function useCommonHooks() {
|
|||||||
}
|
}
|
||||||
}, [wolClients, wolClientsIsFetched]);
|
}, [wolClients, wolClientsIsFetched]);
|
||||||
|
|
||||||
const { data: locationData } = useCensusAPI({
|
const { data: weatherMetadata } = useOSMAPI({ address: personal?.[0].physicalAddress });
|
||||||
address: personalData?.[0]?.physicalAddress,
|
const { data: points } = useWeatherAPI({
|
||||||
|
endpoint: 'points',
|
||||||
|
lat: weatherMetadata?.[0].lat,
|
||||||
|
lon: weatherMetadata?.[0].lon,
|
||||||
|
});
|
||||||
|
const { data: basicWeather } = useWeatherAPI({
|
||||||
|
endpoint: 'baseline',
|
||||||
|
office: points?.properties.gridId,
|
||||||
|
x: points?.properties.gridX,
|
||||||
|
y: points?.properties.gridY,
|
||||||
|
});
|
||||||
|
const { data: stations } = useWeatherAPI({
|
||||||
|
endpoint: 'stations',
|
||||||
|
office: points?.properties.gridId,
|
||||||
|
x: points?.properties.gridX,
|
||||||
|
y: points?.properties.gridY,
|
||||||
|
});
|
||||||
|
const { data: weather } = useWeatherAPI({
|
||||||
|
endpoint: 'current',
|
||||||
|
station: stations?.features[0].properties.stationIdentifier,
|
||||||
|
});
|
||||||
|
const { data: forecast } = useWeatherAPI({
|
||||||
|
endpoint: 'forecast',
|
||||||
|
office: points?.properties.gridId,
|
||||||
|
x: points?.properties.gridX,
|
||||||
|
y: points?.properties.gridY,
|
||||||
|
});
|
||||||
|
const { data: hourly } = useWeatherAPI({
|
||||||
|
endpoint: 'hourly',
|
||||||
|
office: points?.properties.gridId,
|
||||||
|
x: points?.properties.gridX,
|
||||||
|
y: points?.properties.gridY,
|
||||||
});
|
});
|
||||||
|
|
||||||
const [location, setLocation] = useState<any>([]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (locationData) {
|
|
||||||
setLocation(locationData);
|
|
||||||
}
|
|
||||||
}, [locationData]);
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
isMobile,
|
isMobile,
|
||||||
@@ -234,7 +251,5 @@ export function useCommonHooks() {
|
|||||||
wolClientsIsFetched,
|
wolClientsIsFetched,
|
||||||
wolClientsIsFetching,
|
wolClientsIsFetching,
|
||||||
wolClientsIsLoading,
|
wolClientsIsLoading,
|
||||||
location,
|
|
||||||
notify,
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -79,11 +79,11 @@ export function Homepage() {
|
|||||||
}, [messages, isMessagesFetching]);
|
}, [messages, isMessagesFetching]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (weather && basicWeather) {
|
if (weather !== undefined && basicWeather !== undefined) {
|
||||||
setCurrent({
|
setCurrent({
|
||||||
icon: weather.features[0].properties.icon?.replace('medium', 'large') || '',
|
icon: weather.features[0]?.properties.icon?.replace('medium', 'large') || '',
|
||||||
temperature: Math.round(
|
temperature: Math.round(
|
||||||
(weather.features[0].properties.temperature.value * 9) / 5 + 32,
|
(weather.features[0]?.properties.temperature.value * 9) / 5 + 32,
|
||||||
),
|
),
|
||||||
highTemp: Math.round(
|
highTemp: Math.round(
|
||||||
(basicWeather.properties.maxTemperature.values[0].value * 9) / 5 + 32,
|
(basicWeather.properties.maxTemperature.values[0].value * 9) / 5 + 32,
|
||||||
@@ -92,15 +92,15 @@ export function Homepage() {
|
|||||||
(basicWeather.properties.minTemperature.values[0].value * 9) / 5 + 32,
|
(basicWeather.properties.minTemperature.values[0].value * 9) / 5 + 32,
|
||||||
),
|
),
|
||||||
precipitation:
|
precipitation:
|
||||||
weather.features[0].properties.precipitationLastHour.value || 'N/A',
|
weather.features[0]?.properties.precipitationLastHour.value || 'N/A',
|
||||||
humidity: Math.round(weather.features[0].properties.relativeHumidity.value),
|
humidity: Math.round(weather.features[0]?.properties.relativeHumidity.value),
|
||||||
heatIndex: Math.round(
|
heatIndex: Math.round(
|
||||||
weather.features[0].properties.heatIndex.value !== null
|
weather.features[0]?.properties.heatIndex.value !== null
|
||||||
? (weather.features[0].properties.heatIndex.value * 9) / 5 + 32
|
? (weather.features[0]?.properties.heatIndex.value * 9) / 5 + 32
|
||||||
: (weather.features[0].properties.temperature.value * 9) / 5 + 32,
|
: (weather.features[0]?.properties.temperature.value * 9) / 5 + 32,
|
||||||
),
|
),
|
||||||
windSpeed: Math.round(weather.features[0].properties.windSpeed.value / 1.60934),
|
windSpeed: Math.round(weather.features[0]?.properties.windSpeed.value / 1.60934),
|
||||||
windDirection: weather.features[0].properties.windDirection.value,
|
windDirection: weather.features[0]?.properties.windDirection.value,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, [weather, basicWeather]);
|
}, [weather, basicWeather]);
|
||||||
|
|||||||
@@ -31,11 +31,11 @@ function Header({
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (weather && basicWeather) {
|
if (weather !== undefined && basicWeather !== undefined) {
|
||||||
setCurrent({
|
setCurrent({
|
||||||
icon: weather.features[0].properties.icon?.replace('medium', 'large') || '',
|
icon: weather.features[0]?.properties.icon?.replace('medium', 'large') || '',
|
||||||
temperature: Math.round(
|
temperature: Math.round(
|
||||||
(weather.features[0].properties.temperature.value * 9) / 5 + 32,
|
(weather.features[0]?.properties.temperature.value * 9) / 5 + 32,
|
||||||
),
|
),
|
||||||
highTemp: Math.round(
|
highTemp: Math.round(
|
||||||
(basicWeather.properties.maxTemperature.values[0].value * 9) / 5 + 32,
|
(basicWeather.properties.maxTemperature.values[0].value * 9) / 5 + 32,
|
||||||
@@ -44,13 +44,13 @@ function Header({
|
|||||||
(basicWeather.properties.minTemperature.values[0].value * 9) / 5 + 32,
|
(basicWeather.properties.minTemperature.values[0].value * 9) / 5 + 32,
|
||||||
),
|
),
|
||||||
precipitation:
|
precipitation:
|
||||||
weather.features[0].properties.precipitationLastHour.value || 'N/A',
|
weather.features[0]?.properties.precipitationLastHour.value || 'N/A',
|
||||||
humidity: Math.round(weather.features[0].properties.relativeHumidity.value),
|
humidity: Math.round(weather.features[0]?.properties.relativeHumidity.value),
|
||||||
heatIndex: Math.round(
|
heatIndex: Math.round(
|
||||||
(weather.features[0].properties.heatIndex.value * 9) / 5 + 32,
|
(weather.features[0]?.properties.heatIndex.value * 9) / 5 + 32,
|
||||||
),
|
),
|
||||||
windSpeed: Math.round(weather.features[0].properties.windSpeed.value / 1.60934),
|
windSpeed: Math.round(weather.features[0]?.properties.windSpeed.value / 1.60934),
|
||||||
windDirection: weather.features[0].properties.windDirection.value,
|
windDirection: weather.features[0]?.properties.windDirection.value,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, [weather, basicWeather]);
|
}, [weather, basicWeather]);
|
||||||
|
|||||||
@@ -13,8 +13,9 @@ import {
|
|||||||
import { useCommonHooks, useMutationAPI, useQueryAPI } from 'hooks';
|
import { useCommonHooks, useMutationAPI, useQueryAPI } from 'hooks';
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import { FaDice } from 'react-icons/fa';
|
import { FaDice } from 'react-icons/fa';
|
||||||
import { FiMenu, FiMonitor, FiSettings, FiShuffle } from 'react-icons/fi';
|
import { FiMenu, FiPower, FiSettings, FiShuffle } from 'react-icons/fi';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
|
import { toast } from 'react-toastify';
|
||||||
import {
|
import {
|
||||||
actionIconClasses,
|
actionIconClasses,
|
||||||
buttonClasses,
|
buttonClasses,
|
||||||
@@ -40,9 +41,10 @@ function SettingsButton() {
|
|||||||
setBookmarkFilter,
|
setBookmarkFilter,
|
||||||
isMobile,
|
isMobile,
|
||||||
wolClients,
|
wolClients,
|
||||||
notify,
|
|
||||||
} = useCommonHooks();
|
} = useCommonHooks();
|
||||||
|
|
||||||
|
const notify = (notification: any) => toast(notification, { position: 'bottom-right' });
|
||||||
|
|
||||||
const [selectedClient, setSelectedClient] = useState<any>(wolClients?.[0]);
|
const [selectedClient, setSelectedClient] = useState<any>(wolClients?.[0]);
|
||||||
const [overlayOpened, setOverlayOpened] = useState(false);
|
const [overlayOpened, setOverlayOpened] = useState(false);
|
||||||
const handleWakeRequest = () => {
|
const handleWakeRequest = () => {
|
||||||
@@ -113,7 +115,7 @@ function SettingsButton() {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Stack gap={0} align='center'>
|
<Stack gap={0} align='center'>
|
||||||
<FiMonitor size={40} />
|
<FiPower size={32} />
|
||||||
</Stack>
|
</Stack>
|
||||||
</Button>
|
</Button>
|
||||||
<Select
|
<Select
|
||||||
|
|||||||
@@ -38,9 +38,9 @@
|
|||||||
&.root {
|
&.root {
|
||||||
font-size: 1em;
|
font-size: 1em;
|
||||||
font-weight:500;
|
font-weight:500;
|
||||||
margin: 10px;
|
margin-bottom: 10px;
|
||||||
width:108px;
|
width:72px;
|
||||||
height:96px;
|
height:72px;
|
||||||
line-height: 3rem;
|
line-height: 3rem;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
|
|||||||
Reference in New Issue
Block a user