@@ -29,7 +29,12 @@ export default function PDLCard({ pdl, onViewDetails, onDelete, isDemo = false,
2929 const saveTimeoutRef = useRef < ReturnType < typeof setTimeout > | null > ( null )
3030 const mobileMenuRef = useRef < HTMLDivElement | null > ( null )
3131 const [ offpeakRanges , setOffpeakRanges ] = useState < Array < { startHour : string , startMin : string , endHour : string , endMin : string } > > ( ( ) => {
32- const parseRange = ( range : string ) => {
32+ const defaultRange = { startHour : '00' , startMin : '00' , endHour : '00' , endMin : '00' }
33+
34+ const parseRange = ( range : unknown ) => {
35+ // Safety check: ensure range is a string
36+ if ( typeof range !== 'string' ) return defaultRange
37+
3338 // Try format "HH:MM-HH:MM" (array format)
3439 let match = range . match ( / ^ ( \d { 1 , 2 } ) : ( \d { 2 } ) - ( \d { 1 , 2 } ) : ( \d { 2 } ) $ / )
3540 if ( match ) {
@@ -60,10 +65,13 @@ export default function PDLCard({ pdl, onViewDetails, onDelete, isDemo = false,
6065 }
6166 }
6267
63- return { startHour : '00' , startMin : '00' , endHour : '00' , endMin : '00' }
68+ return defaultRange
6469 }
6570
66- const parseAllRanges = ( str : string ) => {
71+ const parseAllRanges = ( str : unknown ) => {
72+ // Safety check: ensure str is a string
73+ if ( typeof str !== 'string' ) return [ defaultRange ]
74+
6775 const results = [ ]
6876 // Check if it's Enedis format with parentheses
6977 const enedisMatch = str . match ( / H C \s * \( ( [ ^ ) ] + ) \) / i)
@@ -87,30 +95,40 @@ export default function PDLCard({ pdl, onViewDetails, onDelete, isDemo = false,
8795 return [ parseRange ( str ) ]
8896 }
8997
90- if ( ! pdl . offpeak_hours ) return [ { startHour : '00' , startMin : '00' , endHour : '00' , endMin : '00' } ]
98+ if ( ! pdl . offpeak_hours ) return [ defaultRange ]
9199
92- if ( Array . isArray ( pdl . offpeak_hours ) ) {
93- // Filter to only strings and parse
94- const stringValues = pdl . offpeak_hours . filter ( ( v ) : v is string => typeof v === 'string' )
95- return stringValues . length > 0
96- ? stringValues . flatMap ( parseAllRanges )
97- : [ { startHour : '00' , startMin : '00' , endHour : '00' , endMin : '00' } ]
98- }
100+ try {
101+ if ( Array . isArray ( pdl . offpeak_hours ) ) {
102+ // Filter to only strings and parse
103+ const stringValues = pdl . offpeak_hours . filter ( ( v ) : v is string => typeof v === 'string' )
104+ return stringValues . length > 0
105+ ? stringValues . flatMap ( parseAllRanges )
106+ : [ defaultRange ]
107+ }
99108
100- // Legacy format: convert object to array and deduplicate
101- // Handle nested arrays (e.g., {"ranges": ["22:00-06:00"]})
102- const rawValues = Object . values ( pdl . offpeak_hours ) . filter ( Boolean )
103- const values = rawValues . flatMap ( v => Array . isArray ( v ) ? v : [ v ] ) . filter ( ( v ) : v is string => typeof v === 'string' )
104- const uniqueValues = Array . from ( new Set ( values ) )
105- return uniqueValues . length > 0
106- ? uniqueValues . flatMap ( parseAllRanges )
107- : [ { startHour : '00' , startMin : '00' , endHour : '00' , endMin : '00' } ]
109+ // Legacy format: convert object to array and deduplicate
110+ // Handle nested arrays (e.g., {"ranges": ["22:00-06:00"]})
111+ const rawValues = Object . values ( pdl . offpeak_hours ) . filter ( Boolean )
112+ const values = rawValues . flatMap ( v => Array . isArray ( v ) ? v : [ v ] ) . filter ( ( v ) : v is string => typeof v === 'string' )
113+ const uniqueValues = Array . from ( new Set ( values ) )
114+ return uniqueValues . length > 0
115+ ? uniqueValues . flatMap ( parseAllRanges )
116+ : [ defaultRange ]
117+ } catch ( error ) {
118+ console . error ( '[PDLCard] Error parsing offpeak_hours:' , error , pdl . offpeak_hours )
119+ return [ defaultRange ]
120+ }
108121 } )
109122 const queryClient = useQueryClient ( )
110123
111124 // Sync edited values with PDL changes
112125 useEffect ( ( ) => {
113- const parseAllRanges = ( str : string ) => {
126+ const defaultRange = { startHour : '00' , startMin : '00' , endHour : '00' , endMin : '00' }
127+
128+ const parseAllRanges = ( str : unknown ) => {
129+ // Safety check: ensure str is a string
130+ if ( typeof str !== 'string' ) return [ defaultRange ]
131+
114132 const results = [ ]
115133 // Check if it's Enedis format with parentheses
116134 const enedisMatch = str . match ( / H C \s * \( ( [ ^ ) ] + ) \) / i)
@@ -128,7 +146,7 @@ export default function PDLCard({ pdl, onViewDetails, onDelete, isDemo = false,
128146 } )
129147 }
130148 }
131- return results . length > 0 ? results : [ { startHour : '00' , startMin : '00' , endHour : '00' , endMin : '00' } ]
149+ return results . length > 0 ? results : [ defaultRange ]
132150 }
133151
134152 // Try format "HH:MM-HH:MM" (array format)
@@ -142,27 +160,32 @@ export default function PDLCard({ pdl, onViewDetails, onDelete, isDemo = false,
142160 } ]
143161 }
144162
145- return [ { startHour : '00' , startMin : '00' , endHour : '00' , endMin : '00' } ]
163+ return [ defaultRange ]
146164 }
147165
148166 setEditedName ( pdl . name || '' )
149167 setEditedPower ( pdl . subscribed_power ?. toString ( ) || '' )
150168
151- if ( ! pdl . offpeak_hours ) {
152- setOffpeakRanges ( [ { startHour : '00' , startMin : '00' , endHour : '00' , endMin : '00' } ] )
153- } else if ( Array . isArray ( pdl . offpeak_hours ) ) {
154- // Filter to only strings and parse
155- const stringValues = pdl . offpeak_hours . filter ( ( v ) : v is string => typeof v === 'string' )
156- const parsed = stringValues . flatMap ( parseAllRanges )
157- setOffpeakRanges ( parsed . length > 0 ? parsed : [ { startHour : '00' , startMin : '00' , endHour : '00' , endMin : '00' } ] )
158- } else {
159- // Legacy format: convert object to array and deduplicate
160- // Handle nested arrays (e.g., {"ranges": ["22:00-06:00"]})
161- const rawValues = Object . values ( pdl . offpeak_hours ) . filter ( Boolean )
162- const values = rawValues . flatMap ( v => Array . isArray ( v ) ? v : [ v ] ) . filter ( ( v ) : v is string => typeof v === 'string' )
163- const uniqueValues = Array . from ( new Set ( values ) )
164- const parsed = uniqueValues . flatMap ( parseAllRanges )
165- setOffpeakRanges ( parsed . length > 0 ? parsed : [ { startHour : '00' , startMin : '00' , endHour : '00' , endMin : '00' } ] )
169+ try {
170+ if ( ! pdl . offpeak_hours ) {
171+ setOffpeakRanges ( [ defaultRange ] )
172+ } else if ( Array . isArray ( pdl . offpeak_hours ) ) {
173+ // Filter to only strings and parse
174+ const stringValues = pdl . offpeak_hours . filter ( ( v ) : v is string => typeof v === 'string' )
175+ const parsed = stringValues . flatMap ( parseAllRanges )
176+ setOffpeakRanges ( parsed . length > 0 ? parsed : [ defaultRange ] )
177+ } else {
178+ // Legacy format: convert object to array and deduplicate
179+ // Handle nested arrays (e.g., {"ranges": ["22:00-06:00"]})
180+ const rawValues = Object . values ( pdl . offpeak_hours ) . filter ( Boolean )
181+ const values = rawValues . flatMap ( v => Array . isArray ( v ) ? v : [ v ] ) . filter ( ( v ) : v is string => typeof v === 'string' )
182+ const uniqueValues = Array . from ( new Set ( values ) )
183+ const parsed = uniqueValues . flatMap ( parseAllRanges )
184+ setOffpeakRanges ( parsed . length > 0 ? parsed : [ defaultRange ] )
185+ }
186+ } catch ( error ) {
187+ console . error ( '[PDLCard] Error parsing offpeak_hours in effect:' , error , pdl . offpeak_hours )
188+ setOffpeakRanges ( [ defaultRange ] )
166189 }
167190 } , [ pdl . id , pdl . name , pdl . subscribed_power , pdl . offpeak_hours ] )
168191
0 commit comments