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

jcubic / 10xDevs / 18621254025

18 Oct 2025 09:32PM UTC coverage: 19.473% (+0.2%) from 19.299%
18621254025

push

github

jcubic
replace History API with Next.js routes system

77 of 109 branches covered (70.64%)

Branch coverage included in aggregate %.

0 of 33 new or added lines in 5 files covered. (0.0%)

118 existing lines in 9 files now uncovered.

462 of 2659 relevant lines covered (17.37%)

2.69 hits per line

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

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

3
import {
×
4
  createContext,
5
  useContext,
6
  useEffect,
7
  useCallback,
8
  useMemo,
9
  type ReactNode
10
} from 'react';
NEW
11
import { usePathname, useRouter } from 'next/navigation';
×
12
import type { NoteTreeNode } from '@/types/tree';
13
import type { SaveStatus } from '@/types/notes';
UNCOV
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
  syncUrlToState: () => void;
29
}
30

UNCOV
31
const NotesContext = createContext<NotesContextValue | undefined>(undefined);
×
32

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

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

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

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

68
  const markNoteDirty = updateDirtyFlag;
×
69

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

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

82
  // URL synchronization - extract note ID from current URL
UNCOV
83
  const syncUrlToState = useCallback(() => {
×
84
    const noteMatch = pathname.match(/\/note\/(\d+)/);
×
85
    const urlNoteId = noteMatch ? parseInt(noteMatch[1], 10) : null;
×
86

87
    if (urlNoteId !== selectedNoteId) {
×
UNCOV
88
      updateSelection(urlNoteId);
×
89
    }
×
UNCOV
90
  }, [pathname, selectedNoteId, updateSelection]);
×
91

92
  // Note selection with Next.js router
UNCOV
93
  const selectNote = useCallback(
×
94
    (noteId: number | null) => {
×
95
      // Update state immediately
96
      updateSelection(noteId);
×
97

98
      // Navigate using Next.js router
NEW
99
      if (noteId === null) {
×
NEW
100
        router.push('/');
×
NEW
101
      } else {
×
NEW
102
        router.push(`/note/${noteId}`);
×
NEW
103
      }
×
104
    },
×
NEW
105
    [updateSelection, router]
×
106
  );
×
107

108
  // Sync URL to state on URL changes
109
  useEffect(() => {
×
110
    syncUrlToState();
×
111
  }, [syncUrlToState]);
×
112

113
  const value: NotesContextValue = useMemo(
×
114
    () => ({
×
UNCOV
115
      notes,
×
UNCOV
116
      selectedNoteId,
×
117
      saveStatus,
×
UNCOV
118
      setNotes,
×
119
      setSaveStatus,
×
120
      updateNoteContent,
×
UNCOV
121
      updateNoteName,
×
UNCOV
122
      markNoteDirty,
×
123
      getSelectedNote,
×
UNCOV
124
      getNote,
×
UNCOV
125
      selectNote,
×
126
      syncUrlToState
×
127
    }),
×
128
    [
×
129
      notes,
×
130
      selectedNoteId,
×
131
      saveStatus,
×
UNCOV
132
      setNotes,
×
UNCOV
133
      setSaveStatus,
×
134
      updateNoteContent,
×
135
      updateNoteName,
×
136
      markNoteDirty,
×
UNCOV
137
      getSelectedNote,
×
UNCOV
138
      getNote,
×
139
      selectNote,
×
140
      syncUrlToState
×
141
    ]
×
UNCOV
142
  );
×
143

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