• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

jcubic / 10xDevs / 18822132356

26 Oct 2025 06:39PM UTC coverage: 24.984% (+0.02%) from 24.961%
18822132356

push

github

jcubic
add title attr to right panel

1819 of 8871 branches covered (20.51%)

Branch coverage included in aggregate %.

883 of 1944 relevant lines covered (45.42%)

1776.31 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

52.27
/src/components/notes/NotesContext.tsx
1
'use client';
2

3
import { createContext, useContext, useEffect, useCallback, type ReactNode } from 'react';
4
import { usePathname, useRouter } from 'next/navigation';
5
import type { NoteTreeNode } from '@/types/tree';
6
import type { SaveStatus } from '@/types/notes';
7
import { useNodeSelection } from '@/hooks/useNodeSelection';
8

9
interface NotesContextValue {
10
  notes: NoteTreeNode[];
11
  selectedNoteId: number | null;
12
  saveStatus: SaveStatus;
13
  setNotes: (notes: NoteTreeNode[] | ((prev: NoteTreeNode[]) => NoteTreeNode[])) => void;
14
  setSaveStatus: (status: SaveStatus) => void;
15
  updateNoteContent: (noteId: number, content: string) => void;
16
  updateNoteName: (noteId: number, name: string) => void;
17
  markNoteDirty: (noteId: number, dirty: boolean) => void;
18
  getSelectedNote: () => NoteTreeNode | null;
19
  getNote: (noteId: number) => NoteTreeNode | null;
20
  selectNote: (noteId: number | null) => void;
21
}
22

23
const NotesContext = createContext<NotesContextValue | undefined>(undefined);
4✔
24

25
export function useNotesContext() {
4✔
26
  const context = useContext(NotesContext);
38✔
27
  if (context === undefined) {
38!
28
    throw new Error('useNotesContext must be used within a NotesProvider');
×
29
  }
30
  return context;
38✔
31
}
32

33
interface NotesProviderProps {
34
  children: ReactNode;
35
  initialNotes?: NoteTreeNode[];
36
  initialSelectedNoteId?: number | null;
37
}
38

39
export function NotesProvider({
4✔
40
  children,
41
  initialNotes = [],
×
42
  initialSelectedNoteId = null
×
43
}: NotesProviderProps) {
44
  const pathname = usePathname();
22✔
45
  const router = useRouter();
22✔
46

47
  // Use the hook that manages all the state
48
  const {
49
    notes,
50
    selectedNoteId,
51
    saveStatus,
52
    setNotes,
53
    setSaveStatus,
54
    updateSelection,
55
    updateDirtyFlag,
56
    updateNoteContent,
57
    updateNoteName
58
  } = useNodeSelection(initialNotes, initialSelectedNoteId);
22✔
59

60
  const markNoteDirty = updateDirtyFlag;
22✔
61

62
  const getSelectedNote = useCallback((): NoteTreeNode | null => {
22✔
63
    if (!selectedNoteId) return null;
8!
64
    return notes.find((note) => note.id === selectedNoteId) || null;
×
65
  }, [notes, selectedNoteId]);
66

67
  const getNote = useCallback(
22✔
68
    (noteId: number): NoteTreeNode | null => {
69
      return notes.find((note) => note.id === noteId) || null;
×
70
    },
71
    [notes]
72
  );
73

74
  // Note selection with Next.js router
75
  const selectNote = useCallback(
22✔
76
    (noteId: number | null) => {
77
      // Update state immediately
78
      updateSelection(noteId);
×
79

80
      // Navigate using Next.js router
81
      if (noteId === null) {
×
82
        router.push('/');
×
83
      } else {
84
        router.push(`/note/${noteId}`);
×
85
      }
86
    },
87
    [updateSelection, router]
88
  );
89

90
  // Sync URL to state on URL changes
91
  useEffect(() => {
22✔
92
    const noteMatch = pathname.match(/\/note\/(\d+)/);
3✔
93
    const urlNoteId = noteMatch ? parseInt(noteMatch[1], 10) : null;
3!
94

95
    if (urlNoteId !== null) {
3!
96
      updateSelection(urlNoteId);
×
97
    }
98
  }, [pathname, updateSelection]);
99

100
  const value: NotesContextValue = {
22✔
101
    notes,
102
    selectedNoteId,
103
    saveStatus,
104
    setNotes,
105
    setSaveStatus,
106
    updateNoteContent,
107
    updateNoteName,
108
    markNoteDirty,
109
    getSelectedNote,
110
    getNote,
111
    selectNote
112
  };
113

114
  return <NotesContext.Provider value={value}>{children}</NotesContext.Provider>;
×
115
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc