Skip to content

Commit

Permalink
Merge pull request #22 from daithihearn/react-query
Browse files Browse the repository at this point in the history
feat: using react-query
  • Loading branch information
daithihearn authored Feb 7, 2024
2 parents 42bd6e0 + caeab3e commit ab8582e
Show file tree
Hide file tree
Showing 16 changed files with 744 additions and 29,867 deletions.
2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v18.18.0
v20.11.0
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# build
FROM node:18.18 AS builder
FROM node:20.11 AS builder

WORKDIR /app

Expand Down
29,136 changes: 0 additions & 29,136 deletions package-lock.json

This file was deleted.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
{
"name": "daithi-dashboard",
"version": "2.9.2",
"version": "2.10.0",
"private": true,
"dependencies": {
"@emotion/react": "^11.11.3",
"@emotion/styled": "^11.11.0",
"@mui/icons-material": "^5.15.4",
"@mui/material": "^5.15.4",
"@mui/x-date-pickers": "^6.18.7",
"@tanstack/react-query": "^5.18.1",
"@testing-library/jest-dom": "^6.2.0",
"@testing-library/react": "^14.1.2",
"@testing-library/user-event": "^14.5.2",
Expand Down
2 changes: 1 addition & 1 deletion public/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"sizes": "512x512"
}
],
"version": "2.9.2",
"version": "2.10.0",
"start_url": ".",
"display": "standalone",
"theme_color": "#000000",
Expand Down
6 changes: 4 additions & 2 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@ import { Box, CssBaseline, createTheme, useMediaQuery } from "@mui/material"
import TypesafeI18n from "i18n/i18n-react"
import { loadLocale } from "i18n/i18n-util.sync"
import { Locales } from "i18n/i18n-types"
import { QueryClient, QueryClientProvider } from "@tanstack/react-query"
import mixpanel from "mixpanel-browser"

mixpanel.init("c22c74cac287fb74387b7ce250f1548f")

function App() {
const prefersDarkMode = useMediaQuery("(prefers-color-scheme: dark)")
const locale: Locales = navigator?.language.startsWith("en") ? "en" : "es"
const queryClient = new QueryClient()

useEffect(() => {
mixpanel.track("Website Accessed")
Expand All @@ -27,7 +29,7 @@ function App() {
)
loadLocale(locale)
return (
<>
<QueryClientProvider client={queryClient}>
<ThemeProvider theme={theme}>
<Box sx={{ display: "flex" }}>
<CssBaseline />
Expand All @@ -36,7 +38,7 @@ function App() {
</TypesafeI18n>
</Box>
</ThemeProvider>
</>
</QueryClientProvider>
)
}

Expand Down
36 changes: 25 additions & 11 deletions src/components/DailyAverageChart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ import Annotation from "chartjs-plugin-annotation"
import { useTheme } from "@mui/material/styles"
import { useI18nContext } from "i18n/i18n-react"
import { useDateTime } from "hooks/RegionalDateTime"
import { DailyAverage } from "models/DailyAverage"
import { usePriceInfo } from "hooks/usePriceInfo"
import WithLoading from "./WithLoading"
import { Container, Typography } from "@mui/material"

Chart.register(Annotation)

Expand All @@ -19,19 +21,16 @@ const hexToRGBA = (hex: string, alpha: number) => {
}

export interface DailyAverageChartProps {
averages: DailyAverage[]
average: number
chartId: string
dateFormat: string
}

const DailyAverageChart: React.FC<DailyAverageChartProps> = ({
averages,
average,
chartId,
dateFormat,
}) => {
const { LL } = useI18nContext()
const { isLoading, dailyAverages, thirtyDayAverage } = usePriceInfo("today")
const { fromISO } = useDateTime()
const theme = useTheme()
const chartRef = useRef<Chart | null>(null)
Expand Down Expand Up @@ -108,8 +107,8 @@ const DailyAverageChart: React.FC<DailyAverageChartProps> = ({
}, [theme])

const averageDataset = useMemo(
() => Array<number>(averages.length).fill(average),
[averages, average],
() => Array<number>(dailyAverages.length).fill(thirtyDayAverage),
[dailyAverages, thirtyDayAverage],
)

const chartData: ChartData<"line", (number | null)[]> = useMemo(() => {
Expand All @@ -118,7 +117,7 @@ const DailyAverageChart: React.FC<DailyAverageChartProps> = ({
datasets.push(
{
label: LL.MEDIAN(),
data: averages.map(item => item.average),
data: dailyAverages.map(item => item.average),
borderColor: theme.palette.info.main,
backgroundColor: hexToRGBA(theme.palette.info.main, 0.4),
pointRadius: 0,
Expand All @@ -133,14 +132,14 @@ const DailyAverageChart: React.FC<DailyAverageChartProps> = ({
)

return {
labels: averages.map(item =>
labels: dailyAverages.map(item =>
fromISO(item.date).toFormat(dateFormat),
),
datasets: datasets,
}
}, [
LL,
averages,
dailyAverages,
theme.palette.info.main,
theme.palette.secondary.main,
averageDataset,
Expand Down Expand Up @@ -172,7 +171,22 @@ const DailyAverageChart: React.FC<DailyAverageChartProps> = ({
}
}, [chartData, chartOptions, chartId])

return <canvas id={ID_PREFIX + chartId} />
return (
<WithLoading isLoading={isLoading}>
<Container sx={{ p: 2 }}>
<Typography
variant="h2"
component="h2"
align="left"
gutterBottom>
{LL.LAST_THIRTY_DAYS()}
</Typography>
</Container>
<Container sx={{ p: 2, height: "400px" }}>
<canvas id={ID_PREFIX + chartId} />
</Container>
</WithLoading>
)
}

export default DailyAverageChart
117 changes: 117 additions & 0 deletions src/components/PricesWrapper.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
import { Container, Typography } from "@mui/material"
import React, { useCallback, useMemo } from "react"
import PriceChart from "./PriceChart"
import { DayType } from "models/DayType"
import { useI18nContext } from "i18n/i18n-react"
import { DayRating } from "models/DayRating"
import { usePriceInfo } from "hooks/usePriceInfo"
import DailyInfo from "./DailyInfo"
import { useDateTime } from "hooks/RegionalDateTime"
import WithLoading from "./WithLoading"

export const PricesWrapper: React.FC<{ day: DayType }> = ({ day }) => {
const { LL } = useI18nContext()
const { now } = useDateTime()
const { isLoading, dailyInfo, thirtyDayAverage } = usePriceInfo(day)

const isToday = useMemo(() => {
if (day === "today") {
return true
}
if (day === "tomorrow") {
return false
}
return day.hasSame(now(), "day")
}, [day, now])

const isTomorrow = useMemo(() => {
if (day === "tomorrow") {
return true
}
return false
}, [day])

const parseDateText = useCallback(
(dayType: DayType) => {
if (dayType === "today" || isToday) {
return LL.TODAY()
}
if (dayType === "tomorrow") {
return LL.TOMORROW()
}
return dayType.toFormat("dd/MM")
},
[LL, isToday],
)

const ratingText = useMemo(() => {
const date = parseDateText(day)

switch (dailyInfo?.dayRating) {
case DayRating.BAD:
return LL.CURRENT_RATING_BAD({
currentDate: date,
})
case DayRating.GOOD:
return LL.CURRENT_RATING_GOOD({
currentDate: date,
})
default:
return LL.CURRENT_RATING_NORMAL({
currentDate: date,
})
}
}, [parseDateText, day, dailyInfo?.dayRating, LL])

if (isTomorrow && !dailyInfo) {
return (
<WithLoading isLoading={isLoading}>
<Container sx={{ p: 2 }}>
<Typography
variant="h2"
component="h2"
align="left"
gutterBottom>
{LL.TOMORROW_NO_DATA()}
</Typography>
</Container>
</WithLoading>
)
}
return (
<WithLoading isLoading={isLoading}>
<Container sx={{ p: 2 }}>
<Typography
variant="h2"
component="h2"
align="left"
gutterBottom>
{ratingText}
</Typography>
</Container>

<Container sx={{ p: 2 }}>
{dailyInfo && (
<DailyInfo
dailyInfo={dailyInfo}
thirtyDayAverage={thirtyDayAverage}
/>
)}
</Container>

<Container sx={{ p: 2, height: "400px" }}>
{dailyInfo && (
<PriceChart
prices={dailyInfo.prices}
average={thirtyDayAverage}
chartId={`price-chart-${parseDateText(day)}`}
dateFormat="HH:mm"
showCurrentPrice={isToday}
cheapestPeriods={dailyInfo.cheapestPeriods}
expensivePeriods={dailyInfo.expensivePeriods}
/>
)}
</Container>
</WithLoading>
)
}
52 changes: 52 additions & 0 deletions src/hooks/usePriceInfo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { useQuery } from "@tanstack/react-query"
import { useDateTime } from "./RegionalDateTime"
import { getDailyAverages, getDailyPriceInfo } from "services/PriceService"
import { useCallback, useMemo } from "react"
import { DailyPriceInfo } from "models/DailyPriceInfo"
import { DailyAverage } from "models/DailyAverage"
import { DayType } from "models/DayType"

export const usePriceInfo = (day: DayType) => {
const { now } = useDateTime()

const getDateTime = useCallback(() => {
if (day === "today") {
return now()
}
if (day === "tomorrow") {
return now().plus({ days: 1 })
}
return day
}, [day, now])

const dailyInfoResp = useQuery<DailyPriceInfo | null>({
queryKey: ["dailyInfo", day],
queryFn: async () => getDailyPriceInfo(getDateTime()),
refetchInterval: 5 * 60_000,
})

const averagesResp = useQuery<DailyAverage[]>({
queryKey: ["dailyAverages", day],
queryFn: async () => getDailyAverages(getDateTime()),
refetchInterval: 5 * 60_000,
})

const thirtyDayAverage = useMemo(() => {
if (averagesResp.isLoading || !averagesResp.data) {
return 0
}
return (
averagesResp.data.reduce(
(accumulator, med) => accumulator + med.average,
0,
) / averagesResp.data.length
)
}, [averagesResp])

return {
isLoading: dailyInfoResp.isLoading || averagesResp.isLoading,
dailyInfo: dailyInfoResp.data,
dailyAverages: averagesResp.data ?? [],
thirtyDayAverage,
}
}
5 changes: 2 additions & 3 deletions src/i18n/en/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,8 @@ const en = {
MIN_PRICE: "Min price - {minPrice}",
MAX_PRICE: "Max price - {maxPrice}",
THIRTY_DAY_AVG: "30 day average",
TOMORROW_RATING_GOOD: "Tomorrow {currentDate} is a GOOD day",
TOMORROW_RATING_BAD: "Tomorrow {currentDate} is a BAD day",
TOMORROW_RATING_NORMAL: "Tomorrow {currentDate} is a NORMAL day",
TODAY: "Today",
TOMORROW: "Tomorrow",
TOMORROW_NO_DATA:
"Tomorrow's prices are not available yet. Prices are usually available after 20:30",
LAST_THIRTY_DAYS: "Last 30 days",
Expand Down
5 changes: 2 additions & 3 deletions src/i18n/es/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,8 @@ const es = {
MIN_PRICE: "Precio min - {minPrice:string}",
MAX_PRICE: "Precio max - {maxPrice:string}",
THIRTY_DAY_AVG: "Precio promedio de 30 días",
TOMORROW_RATING_GOOD: "Mañana {currentDate:string} es un día BUENO",
TOMORROW_RATING_BAD: "Mañana {currentDate:string} es un día MALO",
TOMORROW_RATING_NORMAL: "Mañana {currentDate:string} es un día NORMAL",
TODAY: "Hoy",
TOMORROW: "Mañana",
TOMORROW_NO_DATA:
"Los datos de mañana aún no están disponibles. Los precios suelen estar disponibles después de las 20:30",
LAST_THIRTY_DAYS: "Últimos 30 días",
Expand Down
Loading

0 comments on commit ab8582e

Please sign in to comment.