11import { addDays , eachHourOfInterval , startOfDay } from "date-fns" ;
22import { findValue , NWSWeather } from "../../services/nwsWeather" ;
3- import { Weather } from "../weather/weatherSlice" ;
3+ import { timeZoneSelector , Weather } from "../weather/weatherSlice" ;
44import { OpenMeteoWeather } from "../../services/openMeteo" ;
55import { useMemo } from "react" ;
66import OutlookRow from "./OutlookRow" ;
77import compact from "lodash/fp/compact" ;
88import styled from "@emotion/styled" ;
99import Day from "./Day" ;
10+ import { TZDate } from "@date-fns/tz" ;
11+ import { useAppSelector } from "../../hooks" ;
1012
1113const Rows = styled . div `` ;
1214
@@ -15,6 +17,7 @@ interface OutlookTableProps {
1517}
1618
1719function getOutlook (
20+ timeZone : string ,
1821 mapFn : ( hour : Date , index : number ) => React . ReactNode | undefined ,
1922) {
2023 const hours = eachHourOfInterval ( {
@@ -27,26 +30,41 @@ function getOutlook(
2730 ) ;
2831
2932 return Object . entries (
30- Object . groupBy ( data , ( { hour } ) => startOfDay ( hour ) . getTime ( ) ) ,
33+ Object . groupBy ( data , ( { hour } ) =>
34+ startOfDay ( new TZDate ( hour , timeZone ) ) . getTime ( ) ,
35+ ) ,
3136 ) . map ( ( [ timeStr , hours ] ) => ( {
3237 date : new Date ( + timeStr ) ,
3338 hours : hours ! . map ( ( { node } ) => node ) ,
3439 } ) ) ;
3540}
3641
3742export default function OutlookTable ( { weather } : OutlookTableProps ) {
43+ const timeZone = useAppSelector ( timeZoneSelector ) ;
44+ if ( ! timeZone ) throw new Error ( "timeZone needed" ) ;
45+
3846 const rows = ( ( ) => {
39- if ( "properties" in weather ) return < NWSOutlookRows weather = { weather } /> ;
40- return < OpenMeteoOutlookRows weather = { weather } /> ;
47+ if ( "properties" in weather )
48+ return < NWSOutlookRows weather = { weather } timeZone = { timeZone } /> ;
49+ return < OpenMeteoOutlookRows weather = { weather } timeZone = { timeZone } /> ;
4150 } ) ( ) ;
4251
4352 return < Rows > { rows } </ Rows > ;
4453}
4554
46- function NWSOutlookRows ( { weather } : { weather : NWSWeather } ) {
55+ interface BaseOutlookRowsProps {
56+ timeZone : string ;
57+ }
58+
59+ function NWSOutlookRows ( {
60+ weather,
61+ timeZone,
62+ } : BaseOutlookRowsProps & {
63+ weather : NWSWeather ;
64+ } ) {
4765 const days = useMemo (
4866 ( ) =>
49- getOutlook ( ( hour , index ) => {
67+ getOutlook ( timeZone , ( hour , index ) => {
5068 const windDirection = findValue (
5169 hour ,
5270 weather . properties . windDirection ,
@@ -80,17 +98,23 @@ function NWSOutlookRows({ weather }: { weather: NWSWeather }) {
8098 />
8199 ) ;
82100 } ) ,
83- [ weather ] ,
101+ [ weather , timeZone ] ,
84102 ) ;
85103
86104 return days . map ( ( { date, hours } , index ) => (
87105 < Day key = { index } date = { date } hours = { hours } />
88106 ) ) ;
89107}
90- function OpenMeteoOutlookRows ( { weather } : { weather : OpenMeteoWeather } ) {
108+
109+ function OpenMeteoOutlookRows ( {
110+ weather,
111+ timeZone,
112+ } : BaseOutlookRowsProps & {
113+ weather : OpenMeteoWeather ;
114+ } ) {
91115 const days = useMemo (
92116 ( ) =>
93- getOutlook ( ( hour , index ) => {
117+ getOutlook ( timeZone , ( hour , index ) => {
94118 const data = weather . byUnixTimestamp [ hour . getTime ( ) / 1_000 ] ;
95119
96120 if ( ! data ) return ;
@@ -108,7 +132,7 @@ function OpenMeteoOutlookRows({ weather }: { weather: OpenMeteoWeather }) {
108132 />
109133 ) ;
110134 } ) ,
111- [ weather ] ,
135+ [ weather , timeZone ] ,
112136 ) ;
113137
114138 return days . map ( ( { date, hours } , index ) => (
0 commit comments