@@ -34,6 +34,11 @@ interface DevlogContextType {
3434 filters : DevlogFilter ;
3535 connected : boolean ;
3636
37+ // Selected devlog state (for detail views)
38+ selectedDevlog : DevlogEntry | null ;
39+ selectedDevlogLoading : boolean ;
40+ selectedDevlogError : string | null ;
41+
3742 // Stats state
3843 stats : DevlogStats | null ;
3944 statsLoading : boolean ;
@@ -49,8 +54,11 @@ interface DevlogContextType {
4954 fetchDevlogs : ( ) => Promise < void > ;
5055 fetchStats : ( ) => Promise < void > ;
5156 fetchTimeSeriesStats : ( ) => Promise < void > ;
57+ fetchSelectedDevlog : ( id : DevlogId ) => Promise < void > ;
58+ clearSelectedDevlog : ( ) => void ;
5259 createDevlog : ( data : Partial < DevlogEntry > ) => Promise < any > ;
5360 updateDevlog : ( data : Partial < DevlogEntry > & { id : DevlogId } ) => Promise < any > ;
61+ updateSelectedDevlog : ( data : Partial < DevlogEntry > & { id : DevlogId } ) => Promise < DevlogEntry > ;
5462 deleteDevlog : ( id : DevlogId ) => Promise < void > ;
5563 batchUpdate : ( ids : DevlogId [ ] , updates : any ) => Promise < any > ;
5664 batchDelete : ( ids : DevlogId [ ] ) => Promise < void > ;
@@ -92,6 +100,11 @@ export function DevlogProvider({ children }: { children: React.ReactNode }) {
92100 const [ timeSeriesError , setTimeSeriesError ] = useState < string | null > ( null ) ;
93101 const hasTimeSeriesFetched = useRef ( false ) ;
94102
103+ // Selected devlog state (for detail views)
104+ const [ selectedDevlog , setSelectedDevlog ] = useState < DevlogEntry | null > ( null ) ;
105+ const [ selectedDevlogLoading , setSelectedDevlogLoading ] = useState ( false ) ;
106+ const [ selectedDevlogError , setSelectedDevlogError ] = useState < string | null > ( null ) ;
107+
95108 const { connected, subscribe, unsubscribe } = useServerSentEvents ( ) ;
96109
97110 // Create DevlogApiClient instance
@@ -355,6 +368,64 @@ export function DevlogProvider({ children }: { children: React.ReactNode }) {
355368 }
356369 } , [ ] ) ;
357370
371+ // Selected devlog operations
372+ const fetchSelectedDevlog = useCallback (
373+ async ( id : DevlogId ) => {
374+ if ( ! currentProject || ! devlogApiClient ) {
375+ setSelectedDevlogError ( 'No project selected or API client unavailable' ) ;
376+ setSelectedDevlogLoading ( false ) ;
377+ return ;
378+ }
379+
380+ try {
381+ setSelectedDevlogLoading ( true ) ;
382+ setSelectedDevlogError ( null ) ;
383+
384+ const devlog = await devlogApiClient . get ( id ) ;
385+ setSelectedDevlog ( devlog ) ;
386+ } catch ( err ) {
387+ const errorMessage = handleApiError ( err ) ;
388+ console . error ( 'Failed to fetch selected devlog:' , err ) ;
389+ setSelectedDevlogError ( errorMessage ) ;
390+ } finally {
391+ setSelectedDevlogLoading ( false ) ;
392+ }
393+ } ,
394+ [ currentProject , devlogApiClient ] ,
395+ ) ;
396+
397+ const clearSelectedDevlog = useCallback ( ( ) => {
398+ setSelectedDevlog ( null ) ;
399+ setSelectedDevlogError ( null ) ;
400+ setSelectedDevlogLoading ( false ) ;
401+ } , [ ] ) ;
402+
403+ const updateSelectedDevlog = useCallback (
404+ async ( data : Partial < DevlogEntry > & { id : DevlogId } ) => {
405+ if ( ! currentProject || ! devlogApiClient ) {
406+ throw new Error ( 'No project selected or API client unavailable' ) ;
407+ }
408+
409+ const { id, ...updateData } = data ;
410+ const updatedDevlog = await devlogApiClient . update ( id , updateData as any ) ;
411+
412+ // Update both selected devlog and list if the devlog exists in the list
413+ setSelectedDevlog ( updatedDevlog ) ;
414+ setDevlogs ( ( current ) => {
415+ const index = current . findIndex ( ( devlog ) => devlog . id === updatedDevlog . id ) ;
416+ if ( index >= 0 ) {
417+ const updated = [ ...current ] ;
418+ updated [ index ] = updatedDevlog ;
419+ return updated ;
420+ }
421+ return current ;
422+ } ) ;
423+
424+ return updatedDevlog ;
425+ } ,
426+ [ currentProject , devlogApiClient ] ,
427+ ) ;
428+
358429 // Fetch data on mount and filter changes
359430 useEffect ( ( ) => {
360431 fetchDevlogs ( ) ;
@@ -393,10 +464,26 @@ export function DevlogProvider({ children }: { children: React.ReactNode }) {
393464 fetchDevlogs ( ) ;
394465 return current ;
395466 } ) ;
467+
468+ // Also update selected devlog if it matches
469+ setSelectedDevlog ( ( current ) => {
470+ if ( current && current . id === updatedDevlog . id ) {
471+ return updatedDevlog ;
472+ }
473+ return current ;
474+ } ) ;
396475 } ;
397476
398477 const handleDevlogDeleted = ( deletedData : { id : DevlogId } ) => {
399478 setDevlogs ( ( current ) => current . filter ( ( devlog ) => devlog . id !== deletedData . id ) ) ;
479+
480+ // Clear selected devlog if it was deleted
481+ setSelectedDevlog ( ( current ) => {
482+ if ( current && current . id === deletedData . id ) {
483+ return null ;
484+ }
485+ return current ;
486+ } ) ;
400487 } ;
401488
402489 subscribe ( 'devlog-created' , handleDevlogCreated ) ;
@@ -417,6 +504,9 @@ export function DevlogProvider({ children }: { children: React.ReactNode }) {
417504 error,
418505 filters,
419506 connected,
507+ selectedDevlog,
508+ selectedDevlogLoading,
509+ selectedDevlogError,
420510 stats,
421511 statsLoading,
422512 statsError,
@@ -427,8 +517,11 @@ export function DevlogProvider({ children }: { children: React.ReactNode }) {
427517 fetchDevlogs,
428518 fetchStats,
429519 fetchTimeSeriesStats,
520+ fetchSelectedDevlog,
521+ clearSelectedDevlog,
430522 createDevlog,
431523 updateDevlog,
524+ updateSelectedDevlog,
432525 deleteDevlog,
433526 batchUpdate,
434527 batchDelete,
0 commit comments