Skip to content

Conversation

@Thunder-Blaze
Copy link
Contributor

@Thunder-Blaze Thunder-Blaze commented Aug 16, 2025

Resolves #88.

Description

  • Removed all the Manually added PDF files (they should not be in git repository, it'll forever increase the size of the repository)
  • Classified Class Tests as one category rather than multiple
  • The files are stored in my drive https://drive.google.com/drive/folders/1WyTxfj4AMudoweGqE237mi3hP3834Z-g?usp=sharing, I'll enable editing access for IIITL if this PR gets merged. Later these files can be kept on cloudinary.
  • Added responsive Internal PDF Previewer (Later can be used to preview cloudinary files too) and direct Google Drive links for download.

Live Demo (if any)

image

Note for Maintainer

  • Please do git filter-repo --path public/question_papers/ --invert-paths && git filter-repo --path public/docs/ --invert-paths and then force push to completely remove this data from git history or I guess let it be

Checkout

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

Summary by CodeRabbit

  • New Features
    • Papers page: Added in-app PDF preview modal for quick viewing.
  • Improvements
    • Simplified exam filters to All, Mid, End, CT.
    • Standardized subject names and more reliable open-in-new-tab/download behavior.
  • Data Updates
    • Added seven new 2024 question papers.
    • Migrated 2023 papers to Google Drive with consistent preview and download links.
  • Style
    • Minor formatting cleanups across notes, newcomers, and UI components (no behavior changes).

@vercel
Copy link

vercel bot commented Aug 16, 2025

@Thunder-Blaze 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

coderabbitai bot commented Aug 16, 2025

Walkthrough

Adds a PDF preview modal to Papers page using new Dialog UI primitives and PdfModal component; integrates modal trigger from QuestionPaperCard. Updates question papers dataset (adds 2024 entries, normalizes URLs, recategorizes exams) and tightens TypeQuestionPaper types. Other files have formatting-only changes.

Changes

Cohort / File(s) Summary
Papers modal integration
app/papers/page.tsx, components/papers/pdf-modal.tsx, components/papers/question-paper-card.tsx
Introduces PdfModal; adds selectedPdfUrl state and passes setter to QuestionPaperCard; converts “View” to button to open modal via viewUrl; download links use direct URL; updates exams filter options and card key composition.
Dialog UI primitives
components/ui/dialog.tsx
Adds client-side Dialog wrapper around Radix primitives with Overlay, Content (optional close button), Header/Footer/Title/Description, Trigger/Close/Portal; provides styled, typed components.
Question papers data
data/question-papers.ts
Adds 2024 papers; migrates many entries to Google Drive URLs; standardizes subject names/codes; recategorizes exams (CT/Mid/End); ensures viewUrl present and aligned with preview links.
Types update
types/question-paper.d.ts
Narrows exam union to 'CT'
Formatting only — Notes
app/notes/page.tsx, components/notes/NoteViewer.tsx, components/notes/SidebarFolderTree.tsx, data/mock_notes.ts
Stylistic changes (spacing, quote style, JSX formatting); no logic changes.
Formatting only — Newcomers
app/newcomers/page.jsx
Reformat useEffect block; behavior unchanged.
Data formatting — Nearby
data/nearby_data.json
Whitespace normalization in category fields; removes extra blank line.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor User
  participant PapersPage
  participant QuestionPaperCard
  participant PdfModal
  participant Dialog as Dialog(UI)

  User->>PapersPage: Visit /papers
  PapersPage->>PapersPage: useState(selectedPdfUrl=null)
  PapersPage->>QuestionPaperCard: render with setSelectedPdfUrl
  User->>QuestionPaperCard: Click "View"
  QuestionPaperCard-->>PapersPage: setSelectedPdfUrl(viewUrl)
  PapersPage->>PdfModal: url=selectedPdfUrl
  PdfModal->>Dialog: open=!!url
  Dialog-->>User: Show PDF preview (embed src=url)
  User->>Dialog: Close dialog
  Dialog-->>PdfModal: onOpenChange(false)
  PdfModal-->>PapersPage: setUrl(null)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Assessment against linked issues

Objective Addressed Explanation
Add exam papers via PRs [#88]
Add newcomers content via PRs [#88] Only formatting changes; no new newcomers content added.
Add notes via PRs [#88] Only formatting/data style changes; no new notes content added.

Assessment against linked issues: Out-of-scope changes

Code Change Explanation
Introduce PdfModal and integrate modal flow (components/papers/pdf-modal.tsx; app/papers/page.tsx; components/papers/question-paper-card.tsx) Modal feature and UI behavior changes go beyond uploading content specified in #88.
Add Dialog UI primitives (components/ui/dialog.tsx) New UI library abstraction is not required for content upload per #88.
Change exam filter options to ['All','Mid','End','CT'] (app/papers/page.tsx) UI filter taxonomy change is unrelated to the content upload objective.
Make viewUrl required and narrow exam union to 'CT' 'Mid'

Possibly related PRs

Suggested labels

accepted-45

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

@Thunder-Blaze Thunder-Blaze changed the title Feat/organization and preview Added Internal PDF Preview and Organized Files Aug 16, 2025
Copy link

@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: 4

🧹 Nitpick comments (16)
app/newcomers/page.jsx (1)

23-39: Minor: avoid repeated string ops and hardening distance parsing

Current implementation repeatedly lowercases the query per item and assumes a "…km" format for distance. Small cleanups improve clarity and resilience without changing behavior.

Apply this diff:

-    const filtered = locationData.locations
-      .filter((location) => {
-        return (
-          (selectedCategory === 'All' ||
-            location.category.trim() === selectedCategory) &&
-          (location.name.toLowerCase().includes(searchQuery.toLowerCase()) ||
-            location.address.toLowerCase().includes(searchQuery.toLowerCase()))
-        )
-      })
-      .sort((a, b) => {
-        const distA = parseFloat(a.distance.replace('km', '').trim())
-        const distB = parseFloat(b.distance.replace('km', '').trim())
-        return distA - distB
-      })
+    const queryLower = searchQuery.trim().toLowerCase()
+    const cat = selectedCategory.trim()
+    const filtered = locationData.locations
+      .filter((location) => {
+        const matchesCategory =
+          cat === 'All' || location.category?.trim() === cat
+        const name = location.name?.toLowerCase() ?? ''
+        const address = location.address?.toLowerCase() ?? ''
+        const matchesSearch =
+          name.includes(queryLower) || address.includes(queryLower)
+        return matchesCategory && matchesSearch
+      })
+      .sort((a, b) => {
+        const toKm = (s) => {
+          const m = String(s).match(/[\d.]+/)
+          return m ? parseFloat(m[0]) : Number.POSITIVE_INFINITY
+        }
+        return toKm(a.distance) - toKm(b.distance)
+      })
components/notes/NoteViewer.tsx (2)

13-21: Guard the timeout when not loading to avoid scheduling no-op timers

When loading becomes false, the effect still schedules a 30s timer that does nothing. Small cleanup avoids unnecessary timers.

Apply this diff:

-    const timer = setTimeout(() => {
-      if (loading) {
-        setError(true)
-        setLoading(false)
-      }
-    }, 30000) // 30 second timeout
-
-    return () => clearTimeout(timer)
-  }, [loading])
+    if (!loading) return
+    const timer = setTimeout(() => {
+      setError(true)
+      setLoading(false)
+    }, 30000) // 30 second timeout
+    return () => clearTimeout(timer)
+  }, [loading])

45-46: More robust aria-label (strip query and decode filename)

If the URL contains query params or encoding, the current label can be noisy. The inline version below strips the query and decodes the last path segment.

Apply this diff:

-        aria-label={`PDF document viewer for ${url.split('/').pop()}`}
+        aria-label={`PDF document viewer for ${
+          decodeURIComponent((url.split('?')[0] || '').split('/').pop() || 'document.pdf')
+        }`}
components/notes/SidebarFolderTree.tsx (1)

35-38: Optional: add basic tree semantics for accessibility.

Since this renders a hierarchical tree, consider adding role and aria-level to the list item for better screen reader support.

Apply within this range:

-          <li
+          <li
+            role="treeitem"
+            aria-level={depth + 1}
             key={`${node.type}-${node.name}-${depth}-${node.type === 'note' ? node.id : ''}`}
             className="text-sm"
           >

Additionally (outside this range), consider adding role="tree" to the wrapping

    where you render the nodes.

    <ul className="ml-2 space-y-1" role="tree">
app/notes/page.tsx (1)

21-23: Prop formatting only — OK. Optional: stabilize the callback.

Passing a stable handleNoteClick can avoid unnecessary re-renders if SidebarFolderTree memoizes. Not critical here.

Outside this range, you can do:

import { useCallback, useState } from 'react'
// ...
const handleNoteClick = useCallback((id: string | null) => {
  setSelectedNoteId((prevId) => (prevId === id ? null : id))
}, [])
types/question-paper.d.ts (2)

11-11: Docstring no longer matches enum values.

The comment “The paper is of which semester half” doesn’t reflect CT entries. Update to describe the exam type (CT/Mid/End).

-  /** The paper is of which semester half */
+  /** The exam type (CT, Mid, or End) */
   exam: 'Mid' | 'End' | 'CT'

15-15: All question-papers entries define viewUrl – remove the fallback

  • data/question-papers.ts contains 31 entries and each one defines a viewUrl.
  • In consumers (e.g. question-paper-card.tsx), you can safely remove the viewUrl || url fallback and reference viewUrl directly.
  • (Optional) If you’re embedding Google Drive links, make sure they include /preview or end with .pdf so they render correctly.
    [optional_refactors_recommended]
components/papers/question-paper-card.tsx (2)

28-32: Download link: cross-origin note.

Using target="_blank" with rel="noopener noreferrer" is correct. Note: the HTML download attribute is ignored for cross-origin URLs (e.g., Google Drive). That’s fine if your provided URLs already force download; otherwise, the file may open in a new tab.

Would you like me to propose a helper to transform Drive share links into direct download links when possible?


36-44: Minor cleanups: remove fallback and add explicit type to button.

  • Since viewUrl is required by type, the fallback to url is no longer needed.
  • Add type="button" to avoid accidental form submission if this card is ever placed in a form.
-        <button
+        <button
+          type="button"
           className="cursor-pointer bg-green-500 text-white px-4 py-2 rounded hover:bg-green-600 transition-colors duration-200"
-          onClick={() =>
-            setSelectedPdfUrl(questionPaper.viewUrl || questionPaper.url)
-          }
+          onClick={() => setSelectedPdfUrl(questionPaper.viewUrl)}
           aria-label={`View ${questionPaper.subject} question paper`}
         >
components/papers/pdf-modal.tsx (1)

16-33: Solid modal control with Dialog; consider a small UX enhancement.

Open state tied to url and clearing it on close is clean. Adding a secondary action to open in a new tab provides a fallback when the embed fails or is blocked.

-    <Dialog open={!!url} onOpenChange={(open) => !open && setUrl(null)}>
-      <DialogContent className="max-w-5xl w-full h-[80vh] p-0 overflow-hidden gap-0 flex flex-col">
-        <DialogHeader className="px-4 py-2 border-b h-fit">
-          <DialogTitle className="text-lg font-semibold">
+    <Dialog open={!!url} onOpenChange={(open) => !open && setUrl(null)}>
+      <DialogContent className="max-w-5xl w-full h-[80vh] p-0 overflow-hidden gap-0 flex flex-col">
+        <DialogHeader className="px-4 py-2 border-b h-fit flex items-center justify-between">
+          <DialogTitle className="text-lg font-semibold">
             PDF Preview
           </DialogTitle>
+          {url ? (
+            <a
+              href={url}
+              target="_blank"
+              rel="noopener noreferrer"
+              className="text-sm text-primary underline"
+            >
+              Open in new tab
+            </a>
+          ) : null}
         </DialogHeader>
         {url ? (
           <div className="flex flex-1">
             <embed src={url} type="application/pdf" className="w-full h-full" />
           </div>
         ) : null}
       </DialogContent>
app/papers/page.tsx (3)

2-2: Drop default React import (nit).

You're using the new JSX runtime; the default React import is unnecessary here.

Apply this diff:

-import React, { useState, useEffect } from 'react'
+import { useState, useEffect } from 'react'

26-31: Narrow the selectedExam type to prevent typos at compile time.

This prevents accidental values and keeps it consistent with your exams list and TypeQuestionPaper['exam'].

Apply this diff:

-const [selectedExam, setSelectedExam] = useState<string>('All')
+const [selectedExam, setSelectedExam] =
+  useState<'All' | 'Mid' | 'End' | 'CT'>('All')

32-34: Avoid derived state; compute filtered papers via useMemo.

userQuestionPapers is fully derived from filters and questionPapers. Using useMemo removes the effect + setter, simplifying logic and avoiding extra renders.

Apply this diff:

-const [userQuestionPapers, setUserQuestionPapers] =
-  useState<TypeQuestionPaper[]>(questionPapers)
-
-useEffect(() => {
-  const filteredQuestionPapers = questionPapers.filter(
-    (questionPaper: TypeQuestionPaper) => {
-      if (
-        selectedBatch !== 'All' &&
-        questionPaper.batch.toString() !== selectedBatch
-      )
-        return false
-      if (
-        selectedSemester !== 'All' &&
-        questionPaper.semester.toString() !== selectedSemester
-      )
-        return false
-      if (
-        selectedSubject !== 'All' &&
-        questionPaper.subjectCode !== selectedSubject
-      )
-        return false
-      if (selectedExam !== 'All' && questionPaper.exam !== selectedExam)
-        return false
-      return true
-    }
-  )
-  setUserQuestionPapers(filteredQuestionPapers)
-}, [selectedBatch, selectedSemester, selectedSubject, selectedExam])
+const userQuestionPapers = React.useMemo(() => {
+  return questionPapers.filter((questionPaper: TypeQuestionPaper) => {
+    if (
+      selectedBatch !== 'All' &&
+      questionPaper.batch.toString() !== selectedBatch
+    )
+      return false
+    if (
+      selectedSemester !== 'All' &&
+      questionPaper.semester.toString() !== selectedSemester
+    )
+      return false
+    if (
+      selectedSubject !== 'All' &&
+      questionPaper.subjectCode !== selectedSubject
+    )
+      return false
+    if (selectedExam !== 'All' && questionPaper.exam !== selectedExam)
+      return false
+    return true
+  })
+}, [selectedBatch, selectedSemester, selectedSubject, selectedExam])

Also applies to: 35-59

data/question-papers.ts (2)

25-33: Normalize subject naming for WDA-I.

Two entries for the same subject code (WDA-I) use different casing/wording. Standardize to reduce visual noise and improve consistency.

Apply this diff:

-    subject: 'Web Design and Application development - I',
+    subject: 'Web Design and Application Development - I',

Also applies to: 65-73


3-3: Optional: reduce duplication by generating Drive URLs from an ID.

A helper avoids copy mistakes (http vs https, /preview vs /download) and eases future migrations (e.g., to Cloudinary).

Example utility (can live near this data file):

type DriveRef = { id: string }
const drive = ({ id }: DriveRef) => ({
  url: `https://drive.google.com/uc?export=download&id=${id}`,
  viewUrl: `https://drive.google.com/file/d/${id}/preview`,
})
// Usage:
// const { url, viewUrl } = drive({ id: '1CUsMqcj_A69...' })

I can help refactor the dataset if you’d like.

components/ui/dialog.tsx (1)

69-77: Verify Tailwind class names: rounded-xs and outline-hidden.

Tailwind doesn’t include rounded-xs or outline-hidden by default. If not configured via plugin/theme, these will be no-ops.

Apply this diff if you aren’t extending Tailwind:

-            className="ring-offset-background focus:ring-ring data-[state=open]:bg-accent data-[state=open]:text-muted-foreground absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4"
+            className="ring-offset-background focus:ring-ring data-[state=open]:bg-accent data-[state=open]:text-muted-foreground absolute top-4 right-4 rounded-sm opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-none disabled:pointer-events-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4"
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 6e7d9dc and 6521748.

⛔ Files ignored due to path filters (21)
  • bun.lock is excluded by !**/*.lock
  • public/docs/sample1.pdf is excluded by !**/*.pdf
  • public/docs/sample2.pdf is excluded by !**/*.pdf
  • public/docs/sample3.pdf is excluded by !**/*.pdf
  • public/docs/sample4.pdf is excluded by !**/*.pdf
  • public/question_papers/btech/2nd_sem/2023/end/COA.pdf is excluded by !**/*.pdf
  • public/question_papers/btech/2nd_sem/2023/end/DS.jpg is excluded by !**/*.jpg
  • public/question_papers/btech/2nd_sem/2023/end/OOPSD.jpg is excluded by !**/*.jpg
  • public/question_papers/btech/2nd_sem/2023/end/PC.pdf is excluded by !**/*.pdf
  • public/question_papers/btech/2nd_sem/2023/end/WDA.jpg is excluded by !**/*.jpg
  • public/question_papers/btech/4th_sem/2023/DM_Test/Test1.pdf is excluded by !**/*.pdf
  • public/question_papers/btech/4th_sem/2023/DM_Test/Test2.pdf is excluded by !**/*.pdf
  • public/question_papers/btech/4th_sem/2023/DM_Test/Test3.pdf is excluded by !**/*.pdf
  • public/question_papers/btech/4th_sem/2023/end/CD.pdf is excluded by !**/*.pdf
  • public/question_papers/btech/4th_sem/2023/end/CN.pdf is excluded by !**/*.pdf
  • public/question_papers/btech/4th_sem/2023/end/DM.pdf is excluded by !**/*.pdf
  • public/question_papers/btech/4th_sem/2023/end/PY.pdf is excluded by !**/*.pdf
  • public/question_papers/btech/4th_sem/2023/mid/CD.pdf is excluded by !**/*.pdf
  • public/question_papers/btech/4th_sem/2023/mid/CN.pdf is excluded by !**/*.pdf
  • public/question_papers/btech/4th_sem/2023/mid/DM.pdf is excluded by !**/*.pdf
  • public/question_papers/btech/4th_sem/2023/mid/PY.pdf is excluded by !**/*.pdf
📒 Files selected for processing (13)
  • app/newcomers/page.jsx (1 hunks)
  • app/notes/page.tsx (2 hunks)
  • app/papers/page.tsx (3 hunks)
  • components/notes/NoteViewer.tsx (3 hunks)
  • components/notes/SidebarFolderTree.tsx (1 hunks)
  • components/papers/pdf-modal.tsx (1 hunks)
  • components/papers/question-paper-card.tsx (2 hunks)
  • components/ui/dialog.tsx (1 hunks)
  • data/mock_notes.ts (2 hunks)
  • data/nearby_data.json (1 hunks)
  • data/question-papers.ts (1 hunks)
  • package.json (2 hunks)
  • types/question-paper.d.ts (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (3)
components/papers/pdf-modal.tsx (1)
components/ui/dialog.tsx (4)
  • Dialog (133-133)
  • DialogContent (135-135)
  • DialogHeader (138-138)
  • DialogTitle (141-141)
components/ui/dialog.tsx (3)
lib/utils.ts (1)
  • cn (4-6)
components/ui/sheet.tsx (5)
  • SheetOverlay (31-45)
  • SheetDescription (117-128)
  • SheetTrigger (13-17)
  • SheetClose (19-23)
  • Sheet (9-11)
components/ui/dropdown-menu.tsx (5)
  • DropdownMenuGroup (54-60)
  • DropdownMenuItem (62-83)
  • DropdownMenuLabel (146-164)
  • DropdownMenuCheckboxItem (85-109)
  • DropdownMenuPortal (15-21)
app/papers/page.tsx (2)
types/question-paper.d.ts (1)
  • TypeQuestionPaper (1-16)
components/papers/pdf-modal.tsx (1)
  • PdfModal (16-33)
🔇 Additional comments (12)
data/nearby_data.json (1)

68-74: LGTM: JSON key spacing normalized

The spacing after the "category" key has been normalized consistently. No functional impact; improves readability.

Also applies to: 76-82, 84-90

package.json (1)

17-17: Confirm Dialog imports and runtime compatibility

We’ve verified that the bump to @radix-ui/react-dialog@^1.1.15 didn’t break any imports:

• components/ui/sheet.tsx:
import * as SheetPrimitive from '@radix-ui/react-dialog'
• components/ui/dialog.tsx:
import * as DialogPrimitive from '@radix-ui/react-dialog'

Please run the app and exercise all dialogs (e.g. the new PDF modal) to ensure there are no console warnings or runtime errors under React 19/Next 15.

data/mock_notes.ts (1)

5-56: LGTM: stylistic quote changes only

Switching to single quotes and minor comma tweaks are consistent and non-functional.

components/notes/SidebarFolderTree.tsx (1)

35-38: Formatting-only change looks good.

No functional impact. The multi-line

  • improves readability.

  • app/notes/page.tsx (1)

    12-12: No-op formatting change.

    The arrow function parentheses change doesn’t alter behavior. Safe.

    components/papers/question-paper-card.tsx (1)

    7-10: Prop addition for modal flow is good.

    Typing setSelectedPdfUrl as (url: string | null) => void is correct and aligns with the new PdfModal API.

    app/papers/page.tsx (3)

    23-23: Exam filter options simplification looks good.

    Consolidating to ['All', 'Mid', 'End', 'CT'] aligns with the new data/type model and keeps the UI simple.


    123-123: Stronger key entropy by including subject.

    Good call. This reduces the risk of collisions when codes/batches overlap.


    7-7: PDF modal integration is cohesive and minimal.

    Passing setSelectedPdfUrl to cards and controlling PdfModal at the page level keeps ownership clear; the open/close flow is predictable.

    Also applies to: 30-31, 126-129, 134-134

    components/ui/dialog.tsx (3)

    33-47: Overlay implementation matches existing UI primitives.

    Consistent animation and backdrop styling with other primitives (e.g., Sheet). Good reuse of cn.


    49-81: Dialog composition and API look solid.

    Wrapping portal/overlay inside DialogContent is ergonomic; showCloseButton is a nice touch, and data-slot attributes make styling predictable.


    132-143: Export surface is cohesive and mirrors Radix primitives.

    This keeps consumers’ mental model simple and aligns with your other UI wrappers.

    Comment on lines +26 to +28
    <div className="flex flex-1">
    <embed src={url} type="application/pdf" className="w-full h-full" />
    </div>
    Copy link

    Choose a reason for hiding this comment

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

    💡 Verification agent

    🧩 Analysis chain

    Verify Drive URLs are embeddable.

    Google Drive “file/d/.../view” or plain sharing links may refuse to render in embed due to X-Frame-Options. Prefer “file/d/FILE_ID/preview” or direct .pdf links.

    Run this to flag any viewUrl that doesn’t look embeddable:


    🏁 Script executed:

    #!/bin/bash
    rg -nP 'viewUrl\s*:\s*["'\'']https?://drive\.google\.com/[^"'\'']*["'\'']' data/question-papers.* -o -r '$0' | awk -F: '{print $1 ":" $2}' | while IFS=: read -r file line; do
      url=$(sed -n "${line}p" "$file" | sed -nE "s/.*viewUrl\s*:\s*['\"]([^'\"]+)['\"].*/\1/p")
      if ! grep -qE '/preview|\.pdf($|\?)' <<<"$url"; then
        echo "Potentially non-embeddable viewUrl at $file:$line -> $url"
      fi
    done

    Length of output: 169


    🏁 Script executed:

    #!/bin/bash
    # Print the beginning of the PdfModal component
    if [ -f components/papers/pdf-modal.tsx ]; then
      echo "=== components/papers/pdf-modal.tsx (first 200 lines) ==="
      sed -n '1,200p' components/papers/pdf-modal.tsx
    else
      echo "=== Searching for pdf-modal.tsx ==="
      fd pdf-modal.tsx -x sh -c 'echo "=== {} ==="; sed -n "1,200p" {}'
    fi
    
    # Search the entire codebase for any Drive URLs
    echo "=== drive.google.com references in codebase ==="
    rg -n -C2 'drive\.google\.com' .

    Length of output: 14970


    Fix non-embeddable Drive link in data/question-papers.ts

    One of the viewUrl entries uses /view?usp=drive_link, which will be blocked by Google’s X-Frame-Options. Update it to the /preview endpoint so it can be embedded.

    • File: data/question-papers.ts
    Line ~312
    Change this:

    - viewUrl: 'https://drive.google.com/file/d/1a0lDv31buwdoGl73uP9Sy_Rss0pCpTZr/view?usp=drive_link',
    + viewUrl: 'https://drive.google.com/file/d/1a0lDv31buwdoGl73uP9Sy_Rss0pCpTZr/preview',
    📝 Committable suggestion

    ‼️ IMPORTANT
    Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

    Suggested change
    <div className="flex flex-1">
    <embed src={url} type="application/pdf" className="w-full h-full" />
    </div>
    // In data/question-papers.ts (around line 312), update the Drive link so it uses /preview:
    viewUrl: 'https://drive.google.com/file/d/1a0lDv31buwdoGl73uP9Sy_Rss0pCpTZr/preview',
    🤖 Prompt for AI Agents
    In data/question-papers.ts around line ~312, one of the Google Drive viewUrl
    entries uses the non-embeddable "/view?usp=drive_link" path; update that string
    to use the "/preview" endpoint instead (e.g., replace ".../view?usp=drive_link"
    with the corresponding ".../preview") so the PDF can be embedded in the modal,
    and then verify any consumers (like components/papers/pdf-modal.tsx) use that
    updated URL as the embed/src.
    

    Comment on lines 67 to 73
    export const notesContent: { [id: string]: NoteContent } = {
    ds1: {
    title: "Stacks and Queues",
    type: "pdf",
    url: "/docs/sample1.pdf",
    updatedAt: "2025-06-20"
    title: 'Stacks and Queues',
    type: 'pdf',
    url: '/docs/sample1.pdf',
    updatedAt: '2025-06-20',
    },
    Copy link

    Choose a reason for hiding this comment

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

    💡 Verification agent

    🧩 Analysis chain

    Verify note PDF URLs aren’t broken by removing /public/docs

    These URLs still point to /docs/sample*.pdf. Given this PR removes public/docs/ from the repo history, these links will 404 and the NoteViewer will show an error.

    Run this to confirm whether the files still exist:

    If the files are gone, consider switching these to a stable external dummy PDF so the notes page stays functional. For example:

       ds1: {
    -    url: '/docs/sample1.pdf',
    +    url: 'https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf',
       },
       oops1: {
    -    url: '/docs/sample2.pdf',
    +    url: 'https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf',
       },
       coa1: {
    -    url: '/docs/sample3.pdf',
    +    url: 'https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf',
       },
       wda1: {
    -    url: '/docs/sample4.pdf',
    +    url: 'https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf',
       },

    Alternatively, migrate these to Drive “preview” URLs similar to the question papers to match the new preview flow.

    Also applies to: 75-79, 81-85, 87-91


    🏁 Script executed:

    #!/bin/bash
    # Check if /public/docs exists and whether sample PDFs are present.
    fd -t d -a docs | rg -nP '(^|/)public/docs$' || echo "public/docs directory not found"
    fd -t f -a 'sample[1-4]\.pdf' | sed 's/^/FOUND: /' || echo "No sample PDFs found"

    Length of output: 172


    Replace broken sample PDF URLs in data/mock_notes.ts

    The public/docs directory and sample1-4.pdf files no longer exist, so all /docs/sample*.pdf links will 404 in the NoteViewer.

    • File: data/mock_notes.ts
    – ds1 (lines 67–73)
    – oops1 (75–79)
    – coa1 (81–85)
    – wda1 (87–91)

    Example replacement diff:

       ds1: {
    -    url: '/docs/sample1.pdf',
    +    url: 'https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf',
       },

    You can either use a stable external dummy PDF for all entries or switch to Drive “preview” URLs to match the new preview flow.

    📝 Committable suggestion

    ‼️ IMPORTANT
    Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

    Suggested change
    export const notesContent: { [id: string]: NoteContent } = {
    ds1: {
    title: "Stacks and Queues",
    type: "pdf",
    url: "/docs/sample1.pdf",
    updatedAt: "2025-06-20"
    title: 'Stacks and Queues',
    type: 'pdf',
    url: '/docs/sample1.pdf',
    updatedAt: '2025-06-20',
    },
    export const notesContent: { [id: string]: NoteContent } = {
    ds1: {
    title: 'Stacks and Queues',
    type: 'pdf',
    url: 'https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf',
    updatedAt: '2025-06-20',
    },
    🤖 Prompt for AI Agents
    In data/mock_notes.ts around lines 67–91 (entries ds1 67–73, oops1 75–79, coa1
    81–85, wda1 87–91) the url fields point to non-existent /docs/sample*.pdf files
    and will 404; update each url to a valid, stable PDF (either a single external
    dummy PDF URL or a Google Drive “preview” URL matching the app's preview flow)
    so NoteViewer can load them, ensuring the new URLs are reachable over HTTPS and
    kept consistent across all four entries.
    

    Copy link

    @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: 0

    ♻️ Duplicate comments (1)
    data/question-papers.ts (1)

    110-113: HTTPS + /preview adoption resolves mixed-content and embed issues

    The Drive links now use HTTPS and embeddable /preview endpoints. This addresses prior blockers for downloads/embeds. Good job closing this out.

    Also applies to: 160-163, 200-203

    🧹 Nitpick comments (3)
    data/question-papers.ts (3)

    25-33: Normalize subject casing for WDA-I

    Subject label casing is inconsistent with the later entry (Line 65). Standardize to “Web Design and Application Development - I” for consistency in filters/UI.

    Apply this diff:

    -    subject: 'Web Design and Application development - I',
    +    subject: 'Web Design and Application Development - I',

    285-313: Avoid fragmenting CTs by embedding “Class Test N” in subject

    You already classify CTs via exam: 'CT'. Keeping “Class Test 1/2/3” in the subject will fragment filters/grouping and contradicts the PR objective to classify CTs as a single category. Consider normalizing the subject to just “Discrete Mathematics”.

    Apply this diff:

    -    subject: 'Discrete Mathematics - Class Test 1',
    +    subject: 'Discrete Mathematics',
    -    subject: 'Discrete Mathematics - Class Test 2',
    +    subject: 'Discrete Mathematics',
    -    subject: 'Discrete Mathematics - Class Test 3',
    +    subject: 'Discrete Mathematics',

    3-4: DRY the Drive URLs: derive url and viewUrl from a single fileId

    Each entry repeats the same ID twice, increasing the chance of drift. Centralize URL construction to reduce duplication and make future provider migration (e.g., Cloudinary) simpler.

    Example approach:

    // helper
    const drive = (id: string) => ({
      url: `https://drive.google.com/uc?export=download&id=${id}`,
      viewUrl: `https://drive.google.com/file/d/${id}/preview`,
    });
    
    // usage
    {
      subject: 'Database Management System',
      subjectCode: 'DBMS',
      batch: 2024,
      semester: 1,
      exam: 'Mid',
      ...drive('1CUsMqcj_A69hl8nBCAmwpVIKQUiZxtOS'),
    }

    If you anticipate multiple backends, you could later swap drive() with a provider-aware factory without touching the data rows.

    📜 Review details

    Configuration used: CodeRabbit UI
    Review profile: CHILL
    Plan: Pro

    💡 Knowledge Base configuration:

    • MCP integration is disabled by default for public repositories
    • Jira integration is disabled by default for public repositories
    • Linear integration is disabled by default for public repositories

    You can enable these sources in your CodeRabbit configuration.

    📥 Commits

    Reviewing files that changed from the base of the PR and between 6521748 and fdf5ae7.

    📒 Files selected for processing (4)
    • components/papers/pdf-modal.tsx (1 hunks)
    • components/papers/question-paper-card.tsx (2 hunks)
    • data/question-papers.ts (1 hunks)
    • types/question-paper.d.ts (1 hunks)
    🚧 Files skipped from review as they are similar to previous changes (3)
    • types/question-paper.d.ts
    • components/papers/pdf-modal.tsx
    • components/papers/question-paper-card.tsx
    🔇 Additional comments (1)
    data/question-papers.ts (1)

    3-316: All Google Drive links verified OK

    • No insecure HTTP links found.
    • All viewUrl entries use /preview.
    • 31 url/viewUrl pairs have matching file IDs.
    • (Optional) Three “Class Test” entries detected for Discrete Mathematics (lines 285, 295, 305) – ensure your filtering logic handles these if needed.

    @MrImmortal09
    Copy link
    Collaborator

    @Thunder-Blaze Always ping the maintainers once, if you are done with your code.

    @vercel
    Copy link

    vercel bot commented Aug 19, 2025

    The latest updates on your projects. Learn more about Vercel for GitHub.

    Project Deployment Preview Comments Updated (UTC)
    student-hub Ready Ready Preview Comment Sep 6, 2025 9:33am

    @MrImmortal09
    Copy link
    Collaborator

    MrImmortal09 commented Aug 19, 2025

    @Thunder-Blaze PDF preview is still dependent on external drive link, if possible could you please remove the dependency on external links and integrate something so that we can read the local PDFs or the PDFs on our dedicated storage provider (in future).

    As of now the external drive links are not trust able.

    @Thunder-Blaze
    Copy link
    Contributor Author

    @Thunder-Blaze PDF preview is still dependent on external drive link, if possible could you please remove the dependency on external links and integrate something so that we can read the local PDFs or the PDFs on our dedicated storage provider (in future).

    As of now the external drive links are not trust able.

    Sorry about the request for access, sent by mistake
    and this supports internal ones too so no worries there, It can preview from cloudinary or raw links too

    @Thunder-Blaze
    Copy link
    Contributor Author

    I'll rebase and fix the merge conflicts

    @Thunder-Blaze Thunder-Blaze force-pushed the feat/OrganizationAndPreview branch from fdf5ae7 to 22e8512 Compare August 19, 2025 20:35
    Copy link

    @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: 0

    🧹 Nitpick comments (4)
    data/question-papers.ts (4)

    25-33: Capitalize “Development” consistently in WDA-I subject

    Minor naming inconsistency with the other WDA-I entries. Use a consistent subject string for reliable grouping/filtering.

    Apply this diff:

    -    subject: 'Web Design and Application development - I',
    +    subject: 'Web Design and Application Development - I',

    1-3: Reduce duplication and mismatch risk with a small Drive URL helper

    A lot of repeated string construction for url/viewUrl can drift over time. Centralize it to eliminate mismatch risk and simplify maintenance.

    Add a helper right after the import:

     import { TypeQuestionPaper } from '../types/question-paper'
     
    +const driveUrls = (
    +  id: string,
    +): Pick<TypeQuestionPaper, 'url' | 'viewUrl'> => ({
    +  url: `https://drive.google.com/uc?export=download&id=${id}`,
    +  viewUrl: `https://drive.google.com/file/d/${id}/preview`,
    +})
    +
     const questionPapers: TypeQuestionPaper[] = [

    Example usage on the first entry:

       {
         subject: 'Database Management System',
         subjectCode: 'DBMS',
         batch: 2024,
         semester: 1,
         exam: 'Mid',
    -    url: 'https://drive.google.com/uc?export=download&id=1CUsMqcj_A69hl8nBCAmwpVIKQUiZxtOS',
    -    viewUrl:
    -      'https://drive.google.com/file/d/1CUsMqcj_A69hl8nBCAmwpVIKQUiZxtOS/preview',
    +    ...driveUrls('1CUsMqcj_A69hl8nBCAmwpVIKQUiZxtOS'),
       },

    If you like this direction, I can generate a follow-up patch that updates all entries.


    285-313: Normalize “subject” field; prefer keeping assessment label separate (CT-1/2/3)

    Current entries append “- Class Test n” in subject while exam already encodes CT. This can fragment grouping/filtering by subject. Consider:

    • Keep subject = 'Discrete Mathematics'
    • Add an optional displayLabel like 'CT-1', 'CT-2', 'CT-3' (or 'Class Test 1/2/3') for UI display.

    If feasible, extend the type to support a label (outside this file):

    // types/question-paper.d.ts
    export type TypeQuestionPaper = {
      subject: string
      subjectCode: string
      batch: number
      semester: number
      exam: 'Mid' | 'End' | 'CT'
      url: string
      viewUrl: string
      label?: string // optional UI label like 'CT-1', 'CT-2'
    }

    Then, update CT entries here to:

    -    subject: 'Discrete Mathematics - Class Test 1',
    +    subject: 'Discrete Mathematics',
    +    label: 'CT-1',

    If changing the type isn’t desirable now, the current approach is acceptable; this is a future-proofing suggestion.


    11-12: Heads-up: ensure CSP permits embedding Drive previews

    Since the modal embeds Drive preview pages, confirm your Content Security Policy allows framing from Drive. In Next.js, add headers to permit frame-src for Drive; without this, previews can fail in production.

    For example, in next.config.js:

    // next.config.js
    const securityHeaders = [
      {
        key: 'Content-Security-Policy',
        value: [
          "default-src 'self'",
          "script-src 'self' 'unsafe-inline' 'unsafe-eval' https://www.googletagmanager.com",
          "style-src 'self' 'unsafe-inline'",
          "img-src 'self' data: https:",
          "connect-src 'self' https:",
          "frame-src https://drive.google.com https://*.google.com", // allow Drive previews
          "frame-ancestors 'self'",
        ].join('; ')
      }
    ]
    
    module.exports = {
      async headers() {
        return [
          {
            source: '/(.*)',
            headers: securityHeaders,
          },
        ]
      },
    }

    If you want, I can adjust this snippet to align with your existing headers setup.

    📜 Review details

    Configuration used: CodeRabbit UI
    Review profile: CHILL
    Plan: Pro

    💡 Knowledge Base configuration:

    • MCP integration is disabled by default for public repositories
    • Jira integration is disabled by default for public repositories
    • Linear integration is disabled by default for public repositories

    You can enable these sources in your CodeRabbit configuration.

    📥 Commits

    Reviewing files that changed from the base of the PR and between fdf5ae7 and 22e8512.

    ⛔ Files ignored due to path filters (21)
    • bun.lock is excluded by !**/*.lock
    • public/docs/sample1.pdf is excluded by !**/*.pdf
    • public/docs/sample2.pdf is excluded by !**/*.pdf
    • public/docs/sample3.pdf is excluded by !**/*.pdf
    • public/docs/sample4.pdf is excluded by !**/*.pdf
    • public/question_papers/btech/2nd_sem/2023/end/COA.pdf is excluded by !**/*.pdf
    • public/question_papers/btech/2nd_sem/2023/end/DS.jpg is excluded by !**/*.jpg
    • public/question_papers/btech/2nd_sem/2023/end/OOPSD.jpg is excluded by !**/*.jpg
    • public/question_papers/btech/2nd_sem/2023/end/PC.pdf is excluded by !**/*.pdf
    • public/question_papers/btech/2nd_sem/2023/end/WDA.jpg is excluded by !**/*.jpg
    • public/question_papers/btech/4th_sem/2023/DM_Test/Test1.pdf is excluded by !**/*.pdf
    • public/question_papers/btech/4th_sem/2023/DM_Test/Test2.pdf is excluded by !**/*.pdf
    • public/question_papers/btech/4th_sem/2023/DM_Test/Test3.pdf is excluded by !**/*.pdf
    • public/question_papers/btech/4th_sem/2023/end/CD.pdf is excluded by !**/*.pdf
    • public/question_papers/btech/4th_sem/2023/end/CN.pdf is excluded by !**/*.pdf
    • public/question_papers/btech/4th_sem/2023/end/DM.pdf is excluded by !**/*.pdf
    • public/question_papers/btech/4th_sem/2023/end/PY.pdf is excluded by !**/*.pdf
    • public/question_papers/btech/4th_sem/2023/mid/CD.pdf is excluded by !**/*.pdf
    • public/question_papers/btech/4th_sem/2023/mid/CN.pdf is excluded by !**/*.pdf
    • public/question_papers/btech/4th_sem/2023/mid/DM.pdf is excluded by !**/*.pdf
    • public/question_papers/btech/4th_sem/2023/mid/PY.pdf is excluded by !**/*.pdf
    📒 Files selected for processing (13)
    • app/newcomers/page.jsx (1 hunks)
    • app/notes/page.tsx (2 hunks)
    • app/papers/page.tsx (3 hunks)
    • components/notes/NoteViewer.tsx (3 hunks)
    • components/notes/SidebarFolderTree.tsx (1 hunks)
    • components/papers/pdf-modal.tsx (1 hunks)
    • components/papers/question-paper-card.tsx (2 hunks)
    • components/ui/dialog.tsx (1 hunks)
    • data/mock_notes.ts (2 hunks)
    • data/nearby_data.json (1 hunks)
    • data/question-papers.ts (1 hunks)
    • package.json (2 hunks)
    • types/question-paper.d.ts (1 hunks)
    ✅ Files skipped from review due to trivial changes (3)
    • components/notes/SidebarFolderTree.tsx
    • data/nearby_data.json
    • app/newcomers/page.jsx
    🚧 Files skipped from review as they are similar to previous changes (9)
    • app/notes/page.tsx
    • data/mock_notes.ts
    • components/papers/question-paper-card.tsx
    • components/notes/NoteViewer.tsx
    • package.json
    • components/ui/dialog.tsx
    • types/question-paper.d.ts
    • components/papers/pdf-modal.tsx
    • app/papers/page.tsx
    🔇 Additional comments (3)
    data/question-papers.ts (3)

    4-73: Good data hygiene: consistent Drive download/preview pairing for new 2024 (Sem 1) entries

    All new records correctly use:

    • https Drive download URLs (uc?export=download&id=...)
    • Matching /file/d//preview view URLs
      This aligns with the PdfModal embed expectations and avoids mixed-content issues.

    55-63: Verify subject-code mapping for “SPS”

    Confirm that the subject “Systems Programming” should indeed use the code “SPS”. If the official name is “System Programming and Scripting” (or similar), or the code is “SP”, please correct accordingly for consistency across data and UI filters.


    4-313: Manual verification required: sanity-check Drive link IDs

    The automated script failed due to the shell environment, so please manually confirm the following in data/question-papers.ts:

    • Every url ID (the value after …download&id=) exactly matches its corresponding viewUrl ID (the value between /d/ and /preview).
    • No links use http://drive.google.com.
    • All viewUrl entries use /preview (no view?, edit?, open?, or download?).

    You can extract and compare IDs with these simple commands:

    # in repository root
    grep -oP "url:\s*'https://drive\.google\.com/uc\?export=download&id=\K[A-Za-z0-9_-]+" data/question-papers.ts \
      > url_ids.txt
    
    grep -oP "viewUrl:\s*'https://drive\.google\.com/file/d/\K[A-Za-z0-9_-]+(?=/preview)" data/question-papers.ts \
      > view_ids.txt
    
    # Compare the two lists
    diff --side-by-side url_ids.txt view_ids.txt || echo "Mismatch found"
    
    # Check for insecure or non-preview links
    grep -nE "http://drive\.google\.com|drive\.google\.com/file/.*/(view\?|edit\?|open\?|download\?)" data/question-papers.ts

    Ensure there are no mismatches or insecure/non-preview links before merging.

    @Thunder-Blaze
    Copy link
    Contributor Author

    @MrImmortal09 I have finished my work on this

    Copy link

    @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: 1

    🧹 Nitpick comments (1)
    package.json (1)

    37-37: Add an engines field (and lock your package manager) to prevent CI/prod drift with Next 15.4

    Next 15.4 requires a modern Node; specifying engines prevents accidental deploys on older runtimes. Also declare your package manager to avoid lockfile mismatches.

    Add these at the top-level of package.json:

    {
      "engines": {
        "node": ">=18.18.0"
      },
      "packageManager": "pnpm@9"
    }
    • If you use npm or yarn, adjust packageManager accordingly.
    • If you rely on pnpm “trustedDependencies”, locking to pnpm explicitly helps collaborators.
    📜 Review details

    Configuration used: CodeRabbit UI
    Review profile: CHILL
    Plan: Pro

    💡 Knowledge Base configuration:

    • MCP integration is disabled by default for public repositories
    • Jira integration is disabled by default for public repositories
    • Linear integration is disabled by default for public repositories

    You can enable these sources in your CodeRabbit configuration.

    📥 Commits

    Reviewing files that changed from the base of the PR and between 22e8512 and 0b77cb7.

    ⛔ Files ignored due to path filters (2)
    • bun.lock is excluded by !**/*.lock
    • package-lock.json is excluded by !**/package-lock.json
    📒 Files selected for processing (1)
    • package.json (2 hunks)
    🔇 Additional comments (3)
    package.json (3)

    13-25: Radix UI upgrades look fine; validate peer-compat and Dialog behavior with React 19/Next 15

    Nice sweep of Radix bumps. These minor/patch upgrades typically include React 19 compatibility and bug fixes, but they can subtly affect focus management, portals, and aria attributes—especially for Dialog/Popover/Tooltip.

    • Manually verify: focus-trap, initialFocus, escape-to-close, scroll-lock, and nested portals for the new PDF modal (components/papers/pdf-modal.tsx) on mobile and desktop.
    • Ensure any shadcn/ui wrappers or custom wrappers for Dialog/Tooltip haven’t pinned older Radix versions or relied on internal classNames that changed.

    35-37: Bumps to lucide-react, mongoose, and next look aligned; watch for runtime environment constraints

    • lucide-react: compatible with React 19 in recent releases—LGTM.
    • mongoose 8.17.x: safe minor within 8.x; ensure your deployed Node version meets mongoose’s minimum (commonly Node 16.20+; typically OK if you’re on Node 18/20).
    • next 15.4.7: Good to keep in sync with eslint-config-next (see Line 55). Validate the new turbopack dev flow and that server actions/pages render as expected.

    55-55: eslint-config-next aligned with Next 15.4.7—LGTM

    Staying in lockstep with Next here avoids lint rule drift. No action needed.

    package.json Outdated
    Comment on lines 32 to 33
    "dompurify": "^3.2.6",
    "dotenv": "^17.2.1",
    Copy link

    Choose a reason for hiding this comment

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

    💡 Verification agent

    ❓ Verification inconclusive

    dotenv v17 is a breaking change and is usually unnecessary in Next 15—consider removing or pinning

    Next automatically loads .env files; pulling in dotenv often adds no value and can break when imported on the client. v17 also has breaking changes (and may require newer Node versions).

    Options:

    • Preferred: remove dotenv entirely if you only need env vars in Next. Apply:
    -    "dompurify": "^3.2.6",
    -    "dotenv": "^17.2.1",
    +    "dompurify": "^3.2.6",
    • If you must keep it (server-only scripts): pin to v16 to avoid surprises or ensure v17 usage is server-only and loaded via “dotenv/config” at the process entrypoint (never in client bundles).

    Run this to see if dotenv is actually used and where (server vs. client):


    🏁 Script executed:

    #!/bin/bash
    rg -nP -C2 '(import\s+["'\'']dotenv["'\'']|from\s+["'\'']dotenv["'\'']|require\(\s*["'\'']dotenv["'\'']\s*\))'

    Length of output: 112


    I’ll broaden the search to catch any dotenv imports or .config() calls with more robust regex:


    🏁 Script executed:

    #!/bin/bash
    # Check for any import/require of dotenv
    rg -nP "(import\s+['\"]dotenv['\"]|from\s+['\"]dotenv['\"]|require\(\s*['\"]dotenv['\"]\s*\))" -C2
    # Check for any usage of dotenv.config()
    rg -nP "dotenv\s*\.config\s*\(" -C2

    Length of output: 150


    Remove unused dotenv dependency

    I confirmed there are no imports or uses of dotenv (no import, require, or .config() calls anywhere). Since Next.js 15 auto-loads .env files, you can safely drop this unused dependency to avoid surprises.

    • File to update:
    – package.json (remove the dotenv line)

    Suggested diff:

       "dependencies": {
         "dompurify": "^3.2.6",
    -    "dotenv": "^17.2.1",
       }
    🤖 Prompt for AI Agents
    In package.json around lines 32-33, the project lists "dotenv": "^17.2.1" but
    there are no imports/uses and Next.js auto-loads env files; remove the "dotenv"
    entry from dependencies in package.json, then run your package manager (npm
    install or yarn install) to update package-lock.json / yarn.lock and ensure no
    other references to dotenv exist in the repo.
    

    Copy link

    @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: 0

    🧹 Nitpick comments (2)
    package.json (2)

    32-34: Review dotenv usage in package.json

    Next.js automatically loads .env* files at runtime, so you can safely remove the dotenv dependency unless you use it for non-Next scripts (e.g., tooling, custom scripts, tests).

    • File: package.json
    Lines 32–34: drop the "dotenv" entry if it isn’t used at runtime.
    • If you still need env-loading in standalone scripts:
    – Use Next’s built-in loader:
    js const { loadEnvConfig } = require('@next/env'); loadEnvConfig(process.cwd());
    – Or keep dotenv but suppress its informational log:
    js require('dotenv').config({ quiet: true });
    – On Node 20+, you can also run scripts with native support (node --env-file=.env).

       "dompurify": "^3.2.6",
    -  "dotenv": "^17.2.1",
       "jsdom": "^26.1.0",

    35-38: Add Node engine and confirm Next.js 15.4.7 / React 19.1.x compatibility

    Next.js 15.x requires React 19 (minimum) and raises its Node.js requirement to ≥18.18.0 (or ^19.8.0 ∥ ≥20.0.0). To ensure consistency across environments:

    • In package.json (anywhere near the top level), add:

    "engines": {
      "node": ">=18.18.0"
    }

    • Verify your React stack:
    – Ensure react and react-dom are both set to 19.1.x (or any 19.x).
    – Run your CI/build with Node 18.18+, Node 19.8+, or Node 20+.

    • Double-check lucide-react imports:
    – Icons occasionally get renamed between major bumps. Confirm your custom icon imports compile without errors.

    • Mongoose 8.17.2:
    – Works on Node 18+. No version changes needed, but verify your runtime meets the above engine requirements.

    (optional) Consider adding an npm script or CI guard to enforce the correct Node version at install/run time.

    📜 Review details

    Configuration used: CodeRabbit UI
    Review profile: CHILL
    Plan: Pro

    💡 Knowledge Base configuration:

    • MCP integration is disabled by default for public repositories
    • Jira integration is disabled by default for public repositories
    • Linear integration is disabled by default for public repositories

    You can enable these sources in your CodeRabbit configuration.

    📥 Commits

    Reviewing files that changed from the base of the PR and between 22e8512 and 0b77cb7.

    ⛔ Files ignored due to path filters (2)
    • bun.lock is excluded by !**/*.lock
    • package-lock.json is excluded by !**/package-lock.json
    📒 Files selected for processing (1)
    • package.json (2 hunks)
    🔇 Additional comments (2)
    package.json (2)

    13-25: Radix UI upgrades look good; confirm peer-compatibility at runtime.

    Patch/minor bumps across Radix packages are typically safe. Since several primitives are used by the new Dialog/PDF modal, please sanity-check peers at runtime for any warnings or behavior changes, especially focus trapping and aria attributes.

    You can verify peer warnings quickly by running a local dev session and inspecting the console:

    • Start: npm run dev
    • Navigate to pages using Dialog/Tooltip/DropdownMenu and inspect console for peer dep warnings or prop deprecations.

    55-55: ESLint config aligns with Next version.

    eslint-config-next 15.4.7 matching Next 15.4.7 is correct. If you encounter ESLint 9 rule changes, run the linter once and autofix to settle new defaults.

    Run: npm run lint and skim for any new rule violations introduced by the bump.

    @0PrashantYadav0
    Copy link
    Member

    @Thunder-Blaze resolve the conflict and also take the latest pull to use pnpm instead of bun.

    @Thunder-Blaze
    Copy link
    Contributor Author

    Got it 👍🏻

    Copy link

    @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: 0

    🧹 Nitpick comments (4)
    data/question-papers.ts (4)

    25-26: Normalize WDA-I subject casing for consistency.

    Use “Web Design and Application Development - I” (capital D) to match other entries and avoid duplicate grouping in UI/search.

    -    subject: 'Web Design and Application development - I',
    +    subject: 'Web Design and Application Development - I',

    105-113: Standardize OOPS subject name.

    Use a single subject label across years to prevent duplicate buckets; elsewhere you use “Object Oriented Programming”.

    -    subject: 'Object-Oriented Programming System',
    +    subject: 'Object Oriented Programming',

    285-313: Subject should not encode assessment instance (“Class Test 1/2/3”).

    Putting “- Class Test N” in subject makes filtering/grouping noisy. Prefer a stable subject (“Discrete Mathematics”) and carry instance in a separate field (e.g., ctNumber: 1|2|3) or in a displayTitle derived at render-time. If the type doesn’t yet support it, consider adding an optional metadata field.

    Can the consuming UI distinguish CT 1/2/3 without overloading subject? If not, I can propose a small type + UI tweak.


    3-314: Reduce duplication: derive url/viewUrl from a single Drive ID.

    To prevent future mismatches and speed data entry, factor helpers:

    -import { TypeQuestionPaper } from '../types/question-paper'
    +import { TypeQuestionPaper } from '../types/question-paper'
    +
    +const drive = (id: string) => ({
    +  url: `https://drive.google.com/uc?export=download&id=${id}`,
    +  viewUrl: `https://drive.google.com/file/d/${id}/preview`,
    +})

    Example usage for one item (apply gradually as you touch entries):

    -    url: 'https://drive.google.com/uc?export=download&id=1CUsMqcj_A69hl8nBCAmwpVIKQUiZxtOS',
    -    viewUrl:
    -      'https://drive.google.com/file/d/1CUsMqcj_A69hl8nBCAmwpVIKQUiZxtOS/preview',
    +    ...drive('1CUsMqcj_A69hl8nBCAmwpVIKQUiZxtOS'),
    📜 Review details

    Configuration used: CodeRabbit UI

    Review profile: CHILL

    Plan: Pro

    📥 Commits

    Reviewing files that changed from the base of the PR and between 0b77cb7 and e56681e.

    📒 Files selected for processing (1)
    • data/question-papers.ts (1 hunks)
    🔇 Additional comments (2)
    data/question-papers.ts (2)

    7-9: Confirm “batch” semantics (exam year vs. cohort) across semesters.

    Some 2024 entries are semester 2; ensure “batch” is the intended dimension used in filters/sorting so users don’t see surprising groupings.

    Also applies to: 17-20, 27-29, 37-39, 47-49, 57-59, 67-69, 77-80, 87-90, 97-100, 107-110, 117-120, 127-130, 137-140, 147-150, 157-160, 167-170, 177-180, 187-190, 197-200, 207-210, 217-220, 227-230, 237-240, 247-250, 257-260, 267-270, 277-280, 287-290, 297-300, 307-310


    10-13: Approve drive link consistency
    Script verification passed for all 31 entries: no http Drive links, all viewUrls use /preview, and IDs match.

    @0PrashantYadav0
    Copy link
    Member

    You removed all the question paper. why?

    @Thunder-Blaze
    Copy link
    Contributor Author

    They should be on cloud storage or something as per the question paper backend and not in git

    Currently they're on my drive, I'll upload em on cloudinary or whichever cloud storage will be in use once backend is completed by arham

    @MrImmortal09 MrImmortal09 force-pushed the main branch 2 times, most recently from 0d218de to a1d8e6b Compare December 1, 2025 18:52
    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.

    [chore]: Temporary Content Upload via PRs Until Upload Functionality Is Ready

    3 participants