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

jcubic / 10xDevs / 18821921866

26 Oct 2025 06:20PM UTC coverage: 24.961% (+0.003%) from 24.958%
18821921866

push

github

jcubic
refactor NotesContext

1817 of 8869 branches covered (20.49%)

Branch coverage included in aggregate %.

4 of 5 new or added lines in 1 file covered. (80.0%)

1 existing line in 1 file now uncovered.

882 of 1944 relevant lines covered (45.37%)

1776.33 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 {
4
  createContext,
5
  useContext,
6
  useEffect,
7
  useCallback,
8
  useRef,
9
  type ReactNode
10
} from 'react';
11
import { usePathname, useRouter } from 'next/navigation';
12
import type { NoteTreeNode } from '@/types/tree';
13
import type { SaveStatus } from '@/types/notes';
14
import { useNodeSelection } from '@/hooks/useNodeSelection';
15

16
interface NotesContextValue {
17
  notes: NoteTreeNode[];
18
  selectedNoteId: number | null;
19
  saveStatus: SaveStatus;
20
  setNotes: (notes: NoteTreeNode[] | ((prev: NoteTreeNode[]) => NoteTreeNode[])) => void;
21
  setSaveStatus: (status: SaveStatus) => void;
22
  updateNoteContent: (noteId: number, content: string) => void;
23
  updateNoteName: (noteId: number, name: string) => void;
24
  markNoteDirty: (noteId: number, dirty: boolean) => void;
25
  getSelectedNote: () => NoteTreeNode | null;
26
  getNote: (noteId: number) => NoteTreeNode | null;
27
  selectNote: (noteId: number | null) => void;
28
}
29

30
const NotesContext = createContext<NotesContextValue | undefined>(undefined);
4✔
31

32
export function useNotesContext() {
4✔
33
  const context = useContext(NotesContext);
38✔
34
  if (context === undefined) {
38!
35
    throw new Error('useNotesContext must be used within a NotesProvider');
×
36
  }
37
  return context;
38✔
38
}
39

40
interface NotesProviderProps {
41
  children: ReactNode;
42
  initialNotes?: NoteTreeNode[];
43
  initialSelectedNoteId?: number | null;
44
}
45

46
export function NotesProvider({
4✔
47
  children,
48
  initialNotes = [],
×
49
  initialSelectedNoteId = null
×
50
}: NotesProviderProps) {
51
  const pathname = usePathname();
24✔
52
  const router = useRouter();
24✔
53

54
  // Use the hook that manages all the state
55
  const {
56
    notes,
57
    selectedNoteId,
58
    saveStatus,
59
    setNotes,
60
    setSaveStatus,
61
    updateSelection,
62
    updateDirtyFlag,
63
    updateNoteContent,
64
    updateNoteName
65
  } = useNodeSelection(initialNotes, initialSelectedNoteId);
24✔
66

67
  const markNoteDirty = updateDirtyFlag;
24✔
68

69
  const getSelectedNote = useCallback((): NoteTreeNode | null => {
24✔
70
    if (!selectedNoteId) return null;
8!
71
    return notes.find((note) => note.id === selectedNoteId) || null;
×
72
  }, [notes, selectedNoteId]);
73

74
  const getNote = useCallback(
24✔
75
    (noteId: number): NoteTreeNode | null => {
76
      return notes.find((note) => note.id === noteId) || null;
×
77
    },
78
    [notes]
79
  );
80

81
  // Note selection with Next.js router
82
  const selectNote = useCallback(
24✔
83
    (noteId: number | null) => {
84
      // Update state immediately
85
      updateSelection(noteId);
×
86

87
      // Navigate using Next.js router
88
      if (noteId === null) {
×
89
        router.push('/');
×
90
      } else {
91
        router.push(`/note/${noteId}`);
×
92
      }
93
    },
94
    [updateSelection, router]
95
  );
96

97
  // Sync URL to state on URL changes
98
  useEffect(() => {
24✔
99
    const noteMatch = pathname.match(/\/note\/(\d+)/);
3✔
100
    const urlNoteId = noteMatch ? parseInt(noteMatch[1], 10) : null;
3!
101

102
    if (urlNoteId !== null) {
3!
NEW
103
      updateSelection(urlNoteId);
×
104
    }
105
  }, [pathname, updateSelection]);
106

107
  const value: NotesContextValue = {
24✔
108
    notes,
109
    selectedNoteId,
110
    saveStatus,
111
    setNotes,
112
    setSaveStatus,
113
    updateNoteContent,
114
    updateNoteName,
115
    markNoteDirty,
116
    getSelectedNote,
117
    getNote,
118
    selectNote
119
  };
120

121
  return <NotesContext.Provider value={value}>{children}</NotesContext.Provider>;
×
122
}
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