@@ -30,7 +30,20 @@ export function Event() {
3030 const [ loading , setLoading ] = useState ( false ) ;
3131 const [ error , setError ] = useState < string | null > ( null ) ;
3232
33- // Early validation of required params
33+ // Title reflects state
34+ useEffect ( ( ) => {
35+ if ( error && ! conference ) {
36+ document . title = "Error · Event | Hacker Tracker" ;
37+ } else if ( loading ) {
38+ document . title = "Loading event… | Hacker Tracker" ;
39+ } else if ( conference && event ) {
40+ document . title = `${ event . title } · ${ conference . name } | Hacker Tracker` ;
41+ } else {
42+ document . title = "Event | Hacker Tracker" ;
43+ }
44+ } , [ loading , conference , event , error ] ) ;
45+
46+ // Validate required params early
3447 useEffect ( ( ) => {
3548 if ( ! confCode || ! eventId ) {
3649 setError ( "Missing required URL parameters." ) ;
@@ -44,49 +57,49 @@ export function Event() {
4457
4558 async function run ( ) {
4659 if ( ! confCode || ! eventId ) return ;
60+
4761 setLoading ( true ) ;
4862 setError ( null ) ;
63+ setEvent ( null ) ;
64+ setPeople ( [ ] ) ;
65+ setConference ( null ) ;
4966
5067 try {
51- const [ conf , evt , tags ] = await Promise . all ( [
52- getConferenceByCode ( confCode ) ,
53- getEventById ( confCode , Number ( eventId ) ) ,
54- getTags ( confCode ) ,
55- ] ) ;
68+ const conf = await getConferenceByCode ( confCode ) ;
5669 if ( cancelled ) return ;
57-
5870 if ( ! conf ) {
59- setConference ( null ) ;
60- setEvent ( null ) ;
6171 setError ( "Conference not found" ) ;
6272 return ;
6373 }
74+ setConference ( conf ) ;
75+
76+ const evt = await getEventById ( confCode , Number ( eventId ) ) ;
77+ if ( cancelled ) return ;
6478 if ( ! evt ) {
65- setConference ( conf ) ;
66- setEvent ( null ) ;
6779 setError ( "Event not found" ) ;
6880 return ;
6981 }
7082
71- // Safe extraction of speaker ids
72- const speakerIds = ( evt as HTEvent ) . speakers ?. map ( ( s ) => s . id ) ?? [ ] ;
73- const speakers = speakerIds . length
74- ? await getSpeakersByIds ( confCode , speakerIds )
75- : [ ] ;
83+ const [ tags , speakers ] = await Promise . all ( [
84+ getTags ( confCode ) ,
85+ ( evt as HTEvent ) . speakers ?. length
86+ ? getSpeakersByIds (
87+ confCode ,
88+ ( evt as HTEvent ) . speakers ! . map ( ( s ) => s . id )
89+ )
90+ : Promise . resolve ( [ ] as HTPerson [ ] ) ,
91+ ] ) ;
92+ if ( cancelled ) return ;
7693
7794 const tagMap = new Map < number , HTTag > ( ) ;
7895 ( tags as HTTagGroup [ ] ) . forEach ( ( group ) => {
79- group . tags ?. forEach ( ( tag ) => tagMap . set ( tag . id , tag ) ) ;
96+ group . tags ?. forEach ( ( t ) => tagMap . set ( t . id , t ) ) ;
8097 } ) ;
8198
8299 const processed = toProcessedEvent ( evt as HTEvent , tagMap ) ;
83100
84101 setPeople ( speakers ) ;
85- setConference ( conf ) ;
86102 setEvent ( processed ) ;
87-
88- // Set title without creating a fetch re-run dependency loop
89- document . title = `${ processed . title } - ${ conf . name } ` ;
90103 } catch ( e ) {
91104 if ( ! cancelled ) {
92105 const msg = e instanceof Error ? e . message : "Failed to load event" ;
@@ -103,7 +116,6 @@ export function Event() {
103116 } ;
104117 } , [ confCode , eventId ] ) ;
105118
106- // Loading
107119 if ( loading ) {
108120 return (
109121 < div className = "min-h-screen flex flex-col bg-gray-950" >
@@ -115,7 +127,6 @@ export function Event() {
115127 ) ;
116128 }
117129
118- // Fatal errors (no conference context)
119130 if ( error && ! conference ) {
120131 return (
121132 < div className = "min-h-screen flex flex-col bg-gray-950" >
@@ -127,7 +138,6 @@ export function Event() {
127138 ) ;
128139 }
129140
130- // Success (or event-specific error with conference present)
131141 return (
132142 < div className = "min-h-screen flex flex-col bg-gray-950" >
133143 < main className = "flex-1" >
0 commit comments