Skip to content

feat: complete axios notes category refactoring#238

Open
SrujanTag wants to merge 4 commits intoiiitl:mainfrom
SrujanTag:feat/axios-notes-refactor
Open

feat: complete axios notes category refactoring#238
SrujanTag wants to merge 4 commits intoiiitl:mainfrom
SrujanTag:feat/axios-notes-refactor

Conversation

@SrujanTag
Copy link
Copy Markdown
Contributor

@SrujanTag SrujanTag commented Apr 12, 2026

Resolves #236

Description

  • Added Functionality to Axios Notes Section
  • Notes can be added/filtered by Wing, Subject and Year

Live Demo (if any)

Screenshot 2026-04-12 183700 Screenshot 2026-04-12 174628

Note for Maintainer

  • Due to lack of Data in local database, I was unable to test features correctly.
  • I would appreciate a thorough review or assistance with testing in a staged environment to ensure everything works as planned.

Checkout

  • I have read all the contributor guidelines for the repo.

Summary by CodeRabbit

  • New Features

    • Introduced Axios (non-academic) notes with wing, presenter name, and target audience fields.
    • Notes form and edit UI now show category-specific inputs and validation.
    • Notes page gains category-aware filtering and search (wing/presenter/targetAudience included).
    • Note cards display metadata relevant to the note category.
  • Bug Fixes / Improvements

    • Stronger upload/edit validation with clearer error responses.
    • Minor UI/formatting cleanup for consistency.

@vercel
Copy link
Copy Markdown
Contributor

vercel Bot commented Apr 12, 2026

@SrujanTag is attempting to deploy a commit to the mrimmortal09's projects Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 12, 2026

Warning

Rate limit exceeded

@SrujanTag has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 0 minutes and 0 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 0 minutes and 0 seconds.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 9a69d085-774f-4963-bc29-6572fdd60a80

📥 Commits

Reviewing files that changed from the base of the PR and between d588952 and af9f4c1.

📒 Files selected for processing (3)
  • app/api/notes/route.ts
  • app/notes/edit/[id]/page.tsx
  • app/upload-notes/page.tsx

Walkthrough

Adds an "axios" notes category alongside "academic": schema/types, API handlers, forms, listing filters, and UI components now accept and validate category-specific fields (academic: facultyName/year/semester/term; axios: wing/targetAudience/presenterName) with conditional validation and rendering.

Changes

Cohort / File(s) Summary
Schema & Types
model/note.ts, types/note.d.ts
Made academic fields optional; added axios-specific fields wing, targetAudience, presenterName; added pre-validate hook enforcing conditional required fields when category === 'academic'.
API Handlers
app/api/notes/route.ts, middleware.ts
POST now requires file and parses/validates category-specific fields; PATCH accepts/validates wing, targetAudience, presenterName; error response formatting adjusted in middleware.
Upload / Edit Forms
app/upload-notes/page.tsx, app/notes/edit/[id]/page.tsx, app/upload-papers/page.tsx
Form state and UI now include category-dependent fields and validation; payloads only include relevant fields per category; useSemesterAutofill invocation formatting changed.
Notes Listing & Card UI
app/notes/page.tsx, components/notes/note-card.tsx
Filters and search extended to use wing/targetAudience for axios; search matches presenterName/wing; NoteCard conditionally shows Faculty vs Presenter and academic badges vs wing/audience badges.
Minor Formatting & Misc
app/layout.jsx, app/quick-reads/page.tsx, components/theme-toggler.tsx, components/chat/ChatWidget.tsx, hooks/useChatMessages.ts, hooks/useSemesterAutofill.ts, lib/eventEmitter.ts, model/Message.ts
JSX/formatting and minor signature formatting adjusted; trailing-blank-line removals; no behavioral changes.
Chat / Message files (small edits)
app/api/chat/messages/route.ts, components/chat/ChatWidget.tsx, hooks/useChatMessages.ts, model/Message.ts, lib/eventEmitter.ts
Whitespace/trailing-newline cleanups only; no functional changes.

Sequence Diagram

sequenceDiagram
    participant User
    participant Browser
    participant API as Notes API
    participant DB as MongoDB

    User->>Browser: Open upload/edit form
    Browser->>Browser: User selects category (academic/axios)
    Browser->>Browser: Render category-specific fields
    User->>Browser: Fill fields + attach file
    Browser->>Browser: Client-side validation (category-dependent)
    Browser->>API: POST /api/notes (form + file)
    activate API
    API->>API: Parse multipart, check file presence
    alt category == academic
        API->>API: Validate facultyName, year, semester, term
        API->>DB: Create note with academic fields
    else category == axios
        API->>API: Validate wing against enum, parse presenter/targetAudience
        API->>DB: Create note with axios fields
    end
    DB-->>API: Persisted note
    API-->>Browser: 200 OK or 4xx validation error
    deactivate API
    Browser-->>User: Show success or validation error
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related PRs

  • #209: Extends the same notes feature and likely overlaps schema/types and pages for axios support.
  • #235: Touches useSemesterAutofill usage/signature relevant to upload/edit form changes here.
  • #228: Modifies chat-related files that received minor formatting/trailing-newline edits in this PR.

Suggested labels

accepted-75

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: complete axios notes category refactoring' accurately describes the main change—adding category-specific fields and logic for Axios notes while making academic fields conditional.
Linked Issues check ✅ Passed The PR implements the requirements from #236: sensible category-specific fields are now in place, with academic fields (facultyName, year, semester, term) optional and Axios fields (wing, targetAudience, presenterName) new, reflected across upload, edit, and filter logic.
Out of Scope Changes check ✅ Passed The PR includes minor formatting/whitespace cleanup (multi-line JSX reformatting, blank line removals) alongside core changes, but all changes relate to implementing category-specific note fields. No unrelated functionality modifications detected.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (4)
app/notes/edit/[id]/page.tsx (3)

8-8: ⚠️ Potential issue | 🟡 Minor

Remove unused import Textarea.

Pipeline flagged this as unused.

Proposed fix
-import { Textarea } from '@/components/ui/textarea'
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/notes/edit/`[id]/page.tsx at line 8, The import Textarea is unused in the
page component; remove the unused symbol from the import line (the import that
currently reads "import { Textarea } from '@/components/ui/textarea'") or delete
that entire import if nothing else is being imported from that module so the
file no longer includes the unused Textarea symbol.

20-20: ⚠️ Potential issue | 🟡 Minor

Remove unused import BookOpen.

Pipeline flagged this as unused.

Proposed fix
 import {
   Save,
   FileText,
   Calendar,
-  BookOpen,
   GraduationCap,
   CheckCircle,
   AlertCircle,
   Loader2,
 } from 'lucide-react'
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/notes/edit/`[id]/page.tsx at line 20, Remove the unused import symbol
BookOpen from the import list at the top of page.tsx; locate the import
statement that includes "BookOpen" (alongside other icons/components) and delete
just that identifier so the file no longer imports the unused symbol.

51-61: ⚠️ Potential issue | 🟡 Minor

Add missing dependency or stabilize fetchNoteDetails.

Pipeline flagged that useEffect is missing fetchNoteDetails in its dependency array. Since fetchNoteDetails is defined inside the component and references session and unwrappedParams.id, adding it directly would cause infinite re-renders.

Wrap fetchNoteDetails in useCallback with appropriate dependencies, or move the function inside the useEffect.

Option: Move function inside useEffect
   useEffect(() => {
     if (status === 'unauthenticated') {
       router.push('/auth/signin?callbackUrl=/notes')
       return
     }

     if (status === 'authenticated') {
-      fetchNoteDetails()
+      const fetchNoteDetails = async () => {
+        try {
+          setIsLoading(true)
+          setError(null)
+          // ... rest of fetchNoteDetails implementation
+        } catch (err) {
+          // ... error handling
+        } finally {
+          setIsLoading(false)
+        }
+      }
+      fetchNoteDetails()
     }
-  }, [status, unwrappedParams.id, router])
+  }, [status, unwrappedParams.id, router, session])
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/notes/edit/`[id]/page.tsx around lines 51 - 61, The effect depends on a
locally declared function fetchNoteDetails but doesn't include it, causing a
lint warning; fix by stabilizing fetchNoteDetails: either move the
fetchNoteDetails implementation inside the useEffect (so useEffect only depends
on status, unwrappedParams.id, router) or wrap fetchNoteDetails in useCallback
with the correct dependencies (session and unwrappedParams.id) and then include
fetchNoteDetails in the useEffect dependency array; update the useEffect
dependency list accordingly to prevent infinite re-renders (useCallback ensures
a stable identity) and ensure fetchNoteDetails references are to the memoized
function.
app/notes/page.tsx (1)

114-117: ⚠️ Potential issue | 🟡 Minor

Fix ESLint warning by wrapping fetchNotes in useCallback or restructuring.

The eslint-disable directive is reported as unused, and the exhaustive-deps warning persists. The fetchNotes function should be wrapped in useCallback and added to the dependency array, or the fetch logic should be moved inside the effect.

Option 1: Move fetch logic inside useEffect
-  // eslint-disable-next-line react-hooks/exhaustive-deps
   useEffect(() => {
-    fetchNotes()
+    const fetchNotes = async () => {
+      try {
+        setIsLoading(true)
+        setError(null)
+
+        const PAGE_SIZE = 100
+        let page = 1
+        let hasNextPage = true
+        const collected: TypeNote[] = []
+
+        while (hasNextPage) {
+          const response = await fetch(
+            `/api/notes?limit=${PAGE_SIZE}&page=${page}`
+          )
+          const data = await response.json()
+          if (!response.ok)
+            throw new Error(data.message || 'Failed to fetch notes')
+
+          const pageNotes: TypeNote[] = (data.notes.notes as RawNote[]).map(
+            transformNote
+          )
+          collected.push(...pageNotes)
+
+          hasNextPage = data.notes.hasNextPage ?? false
+          page += 1
+        }
+
+        setAllNotes(collected)
+      } catch (err) {
+        setError(err instanceof Error ? err.message : 'Failed to load notes')
+      } finally {
+        setIsLoading(false)
+      }
+    }
+    fetchNotes()
   }, [])
Option 2: Use useCallback for fetchNotes
-  const fetchNotes = async () => {
+  const fetchNotes = useCallback(async () => {
     // ... existing implementation
-  }
+  }, [])

-  // eslint-disable-next-line react-hooks/exhaustive-deps
   useEffect(() => {
     fetchNotes()
-  }, [])
+  }, [fetchNotes])
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/notes/page.tsx` around lines 114 - 117, The ESLint warning comes from
calling fetchNotes inside useEffect with an empty deps array and silencing
exhaustive-deps; remove the eslint-disable and either (A) move the fetch logic
into the effect body (put the code currently in fetchNotes directly inside the
useEffect and call it there) or (B) wrap fetchNotes in useCallback (import
useCallback, define fetchNotes = useCallback(async () => { ... },
[anyDependencies]) ) and then include fetchNotes in the useEffect dependency
array so useEffect(() => { fetchNotes() }, [fetchNotes]); pick one approach and
remove the eslint-disable comment.
🧹 Nitpick comments (4)
app/api/notes/route.ts (1)

524-524: Consider validating targetAudience against allowed values.

wing is validated against validWings, but targetAudience is set without validation. An invalid value would fail at the schema level, but returning an explicit 400 error would be more consistent.

Proposed fix
+    if (targetAudience) {
+      const validAudiences = ['1st Year', '2nd Year', '3rd Year', '4th Year', 'All']
+      if (!validAudiences.includes(targetAudience)) {
+        return NextResponse.json({ message: 'Invalid target audience' }, { status: 400 })
+      }
+      updateData.targetAudience = targetAudience
+    }
-    if (targetAudience) updateData.targetAudience = targetAudience
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/api/notes/route.ts` at line 524, The code sets updateData.targetAudience
without validating it, unlike wing which checks validWings; add a validation
step for targetAudience before assigning to updateData so invalid values return
a 400. Specifically, introduce or use a validTargetAudiences array (analogous to
validWings) and, in the same block where you check targetAudience (around the if
(targetAudience) updateData.targetAudience = targetAudience), validate that
targetAudience is in validTargetAudiences and call the same error-handling path
used for wing (return a 400 with a clear message) if it is not; only assign to
updateData.targetAudience when the value passes validation.
components/notes/note-card.tsx (1)

64-64: Consider using isAxios consistently throughout the component.

The isAxios variable is defined but only used for the border styling (line 69). Lines 79, 114, and 154 repeat note.category === 'axios' instead.

Proposed refactor for consistency
-        {note.category === 'axios' ? (
+        {isAxios ? (

Apply similarly at lines 114 and 154.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@components/notes/note-card.tsx` at line 64, The component defines const
isAxios = note.category === 'axios' but then re-evaluates note.category ===
'axios' in multiple places; replace those repeated checks by using isAxios
consistently across the component (e.g., where border styling currently uses
isAxios and in the other JSX/logic locations that compare note.category ===
'axios') so all conditional rendering/props use the single isAxios variable
(update any ternaries, className conditions and event-handler conditionals to
reference isAxios).
model/note.ts (1)

125-140: The comment mentions axios notes require wing, but validation is not enforced.

The comment on line 126 states "Axios notes require wing", but the pre-validate hook only validates academic note fields. If you want schema-level enforcement of wing for axios notes, add the validation here. Otherwise, the requirement is only enforced at the API layer (app/api/notes/route.ts POST handler).

Proposed fix to enforce wing requirement for axios notes
 NoteSchema.pre('validate', function (next) {
   if (this.category === 'academic') {
     if (!this.year) {
       this.invalidate('year', 'Year is required for academic notes')
     }
     if (!this.semester) {
       this.invalidate('semester', 'Semester is required for academic notes')
     }
     if (!this.term) {
       this.invalidate('term', 'Exam type is required for academic notes')
     }
+  } else if (this.category === 'axios') {
+    if (!this.wing) {
+      this.invalidate('wing', 'Wing is required for axios notes')
+    }
   }
   next()
 })
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@model/note.ts` around lines 125 - 140, The pre-validate hook on NoteSchema
(NoteSchema.pre('validate', function (next) { ... })) enforces fields for
academic notes but does not validate that axios-category notes have a wing; add
a conditional branch checking if this.category === 'axios' and call
this.invalidate('wing', 'Wing is required for axios notes') when this.wing is
missing so the schema-level validation mirrors the API-layer check in
app/api/notes/route.ts.
app/upload-notes/page.tsx (1)

489-502: Consider extracting wing options to a shared constant.

The wing values are hardcoded here and in the backend (app/api/notes/route.ts). While they match currently, extracting them to a shared constant (e.g., in @/types/note.ts or a constants file) would reduce the risk of drift and simplify maintenance.

Example shared constant
// In a shared constants file, e.g., lib/constants.ts
export const AXIOS_WINGS = [
  'ML',
  'Web3',
  'Web',
  'FOSS',
  'InfoSec',
  'Design',
  'App',
  'CP',
] as const;

export type AxiosWing = (typeof AXIOS_WINGS)[number];

Then import and use in both frontend and backend.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/upload-notes/page.tsx` around lines 489 - 502, The wing options are
duplicated and should be centralized: create a shared constant (e.g., export
AXIOS_WINGS and its string union type AxiosWing from a shared module such as
"@/types/note" or "lib/constants") and replace the inline array in
upload-notes/page.tsx (the map that renders <SelectItem> items) and the backend
array in app/api/notes/route.ts to import and use AXIOS_WINGS and the AxiosWing
type; ensure the frontend uses the imported AXIOS_WINGS for mapping and the
backend validates/uses the same constant so the two cannot drift.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@app/api/notes/route.ts`:
- Around line 69-80: The route handler currently treats facultyName as required
by pushing it into the missingFields array when empty; update the validation in
app/api/notes/route.ts to match the UI by removing the facultyName check (remove
or skip the line that inspects facultyName and pushes 'facultyName' into
missingFields) so facultyName is optional, ensuring only subject, year,
semester, and term are enforced; keep the rest of the missingFields logic and
error response intact.

In `@app/notes/edit/`[id]/page.tsx:
- Around line 283-476: The edit form is missing an editable Subject field even
though formData.subject is validated and sent in the payload; add a Subject
input above the category-specific conditional so users can edit it. Insert a
labeled Input (id="subject") bound to value={formData.subject} and onChange
calling handleInputChange('subject', e.target.value) (same pattern as
presenterName/facultyName), and ensure its label/placeholder matches other
fields so validation that checks formData.subject will work when submitting.

In `@app/notes/page.tsx`:
- Around line 156-158: The code is casting missing properties (wing,
targetAudience, presenterName) to any when mapping into your note shape; update
the RawNote type to include these optional properties (wing?: string,
targetAudience?: string, presenterName?: string) if the API can return them, or
remove those three fields from the transformation in page.tsx (the mapping that
uses note.wing, note.targetAudience, note.presenterName) so you no longer rely
on non-existent properties; ensure changes touch the RawNote type definition and
the mapping logic that constructs the note object.

---

Outside diff comments:
In `@app/notes/edit/`[id]/page.tsx:
- Line 8: The import Textarea is unused in the page component; remove the unused
symbol from the import line (the import that currently reads "import { Textarea
} from '@/components/ui/textarea'") or delete that entire import if nothing else
is being imported from that module so the file no longer includes the unused
Textarea symbol.
- Line 20: Remove the unused import symbol BookOpen from the import list at the
top of page.tsx; locate the import statement that includes "BookOpen" (alongside
other icons/components) and delete just that identifier so the file no longer
imports the unused symbol.
- Around line 51-61: The effect depends on a locally declared function
fetchNoteDetails but doesn't include it, causing a lint warning; fix by
stabilizing fetchNoteDetails: either move the fetchNoteDetails implementation
inside the useEffect (so useEffect only depends on status, unwrappedParams.id,
router) or wrap fetchNoteDetails in useCallback with the correct dependencies
(session and unwrappedParams.id) and then include fetchNoteDetails in the
useEffect dependency array; update the useEffect dependency list accordingly to
prevent infinite re-renders (useCallback ensures a stable identity) and ensure
fetchNoteDetails references are to the memoized function.

In `@app/notes/page.tsx`:
- Around line 114-117: The ESLint warning comes from calling fetchNotes inside
useEffect with an empty deps array and silencing exhaustive-deps; remove the
eslint-disable and either (A) move the fetch logic into the effect body (put the
code currently in fetchNotes directly inside the useEffect and call it there) or
(B) wrap fetchNotes in useCallback (import useCallback, define fetchNotes =
useCallback(async () => { ... }, [anyDependencies]) ) and then include
fetchNotes in the useEffect dependency array so useEffect(() => { fetchNotes()
}, [fetchNotes]); pick one approach and remove the eslint-disable comment.

---

Nitpick comments:
In `@app/api/notes/route.ts`:
- Line 524: The code sets updateData.targetAudience without validating it,
unlike wing which checks validWings; add a validation step for targetAudience
before assigning to updateData so invalid values return a 400. Specifically,
introduce or use a validTargetAudiences array (analogous to validWings) and, in
the same block where you check targetAudience (around the if (targetAudience)
updateData.targetAudience = targetAudience), validate that targetAudience is in
validTargetAudiences and call the same error-handling path used for wing (return
a 400 with a clear message) if it is not; only assign to
updateData.targetAudience when the value passes validation.

In `@app/upload-notes/page.tsx`:
- Around line 489-502: The wing options are duplicated and should be
centralized: create a shared constant (e.g., export AXIOS_WINGS and its string
union type AxiosWing from a shared module such as "@/types/note" or
"lib/constants") and replace the inline array in upload-notes/page.tsx (the map
that renders <SelectItem> items) and the backend array in app/api/notes/route.ts
to import and use AXIOS_WINGS and the AxiosWing type; ensure the frontend uses
the imported AXIOS_WINGS for mapping and the backend validates/uses the same
constant so the two cannot drift.

In `@components/notes/note-card.tsx`:
- Line 64: The component defines const isAxios = note.category === 'axios' but
then re-evaluates note.category === 'axios' in multiple places; replace those
repeated checks by using isAxios consistently across the component (e.g., where
border styling currently uses isAxios and in the other JSX/logic locations that
compare note.category === 'axios') so all conditional rendering/props use the
single isAxios variable (update any ternaries, className conditions and
event-handler conditionals to reference isAxios).

In `@model/note.ts`:
- Around line 125-140: The pre-validate hook on NoteSchema
(NoteSchema.pre('validate', function (next) { ... })) enforces fields for
academic notes but does not validate that axios-category notes have a wing; add
a conditional branch checking if this.category === 'axios' and call
this.invalidate('wing', 'Wing is required for axios notes') when this.wing is
missing so the schema-level validation mirrors the API-layer check in
app/api/notes/route.ts.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 997d4316-efdb-4861-acf1-a47a2d417f15

📥 Commits

Reviewing files that changed from the base of the PR and between 00e129c and b27bc39.

📒 Files selected for processing (18)
  • app/api/chat/messages/route.ts
  • app/api/notes/route.ts
  • app/layout.jsx
  • app/notes/edit/[id]/page.tsx
  • app/notes/page.tsx
  • app/quick-reads/page.tsx
  • app/upload-notes/page.tsx
  • app/upload-papers/page.tsx
  • components/chat/ChatWidget.tsx
  • components/notes/note-card.tsx
  • components/theme-toggler.tsx
  • hooks/useChatMessages.ts
  • hooks/useSemesterAutofill.ts
  • lib/eventEmitter.ts
  • middleware.ts
  • model/Message.ts
  • model/note.ts
  • types/note.d.ts
💤 Files with no reviewable changes (5)
  • hooks/useChatMessages.ts
  • model/Message.ts
  • components/chat/ChatWidget.tsx
  • app/api/chat/messages/route.ts
  • lib/eventEmitter.ts

Comment thread app/api/notes/route.ts
Comment thread app/notes/edit/[id]/page.tsx
Comment thread app/notes/page.tsx Outdated
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[feat]: Add sensible options in notes.

1 participant