Skip to content

feat(dashboard): add Bunkx shortcut in overflow menu#16

Merged
Noelithub77 merged 8 commits into
Noelithub77:masterfrom
vishnunathasuresh:feat/dashboard-bunkx-link
Mar 31, 2026
Merged

feat(dashboard): add Bunkx shortcut in overflow menu#16
Noelithub77 merged 8 commits into
Noelithub77:masterfrom
vishnunathasuresh:feat/dashboard-bunkx-link

Conversation

@vishnunathasuresh
Copy link
Copy Markdown
Contributor

Summary

  • add a new Bunkx action in dashboard overflow menu
  • place Bunkx below GPA Calculator and above Outpass entries
  • open https://bunkx-iiitk.vercel.app when tapped

Testing

  • validated file diagnostics for src/app/(tabs)/index.tsx (no editor errors)
  • CLI lint/typecheck could not run in this environment due local tooling config issues

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 29, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Dashboard FAB gains a new "Bunkx" action that closes the FAB, collects attendance data from the attendance store, builds and encodes a Bunkx-formatted attendance payload, and opens https://bunkx-iiitk.vercel.app with the encoded payload in the URL. Errors show a toast.

Changes

Cohort / File(s) Summary
FAB Menu Action
src/app/(tabs)/index.tsx
Added handleOpenBunkx FAB action: closes FAB, reads attendanceCourses and attendanceLastSyncTime from the attendance store, builds and encodes a Bunkx payload, opens the composed bunkx-iiitk.vercel.app URL via Linking.openURL, and shows an error Toast on failure.
Bunkx payload types
src/types/attendance.ts
Added exported interfaces BunkxAttendanceRow and BunkxAttendancePayload describing the row and payload shapes required by Bunkx.
Bunkx payload utilities
src/utils/bunkx-payload.ts
New utility module: parses dates and times, extracts faculty info and emails, normalizes scores, builds BunkxAttendancePayload (includes dataset_id and dataset_expires_at based on lastSyncTime), and provides encodeBunkxPayload to URI-encode + Base64 the payload for URL embedding.

Sequence Diagram(s)

sequenceDiagram
  participant UI as Dashboard (FAB)
  participant Store as Attendance Store
  participant Utils as Bunkx Utils
  participant OS as Linking / External Browser

  UI->>UI: User taps "Bunkx" FAB action
  UI->>UI: Close FAB menu
  UI->>Store: read courses & lastSyncTime
  Store-->>UI: courses, lastSyncTime
  UI->>Utils: buildBunkxAttendancePayload(courses, lastSyncTime)
  Utils-->>UI: BunkxAttendancePayload
  UI->>Utils: encodeBunkxPayload(payload)
  Utils-->>UI: encodedString
  UI->>OS: Linking.openURL("https://bunkx-iiitk.vercel.app/?payload="+encodedString)
  OS-->>UI: success / error
  alt error
    UI->>UI: Toast.show(error.message)
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Poem

🐰 I nibble rows and stitch them tight,
Into a payload wrapped just right.
Encoded hops through URL air,
Off to Bunkx with a joyful flair.
Hooray — a bunny's export prayer!

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

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.
Description check ❓ Inconclusive The PR description covers the summary and testing, but is missing the 'Changes', 'Risks', and 'Validation' sections from the template. Add missing template sections: explicitly list all changes made, document any potential risks, and confirm validation steps (typecheck and relevant tests).
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main change: adding a Bunkx shortcut to the dashboard overflow menu, which aligns with all modified files.

✏️ 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.

@coderabbitai coderabbitai Bot added the codex label Mar 29, 2026
@github-actions
Copy link
Copy Markdown

Preview

QR Code

@github-actions
Copy link
Copy Markdown

Preview

QR Code

Copy link
Copy Markdown

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

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/app/`(tabs)/index.tsx:
- Around line 243-257: The handleOpenBunkx flow currently closes the FAB and
calls getCredentials() and Linking.openURL() without error handling; wrap the
async IIFE inside handleOpenBunkx in a try/catch, call setShowFabMenu(false)
before the try, and on any error call Toast.show(...) with a user-friendly
message (and optionally include error.message for debugging), and ensure the
error does not leave the app in an inconsistent state; reference
handleOpenBunkx, getCredentials, Linking.openURL, setShowFabMenu, and Toast.show
when making the change.
- Line 12: The code currently embeds the raw LMS password returned by
getCredentials() into the Bunkx URL (https://username:password@...), leaking
secrets; change the flow so you never serialize the password into a URL—use a
short‑lived token, OAuth callback, auth header, or an API gateway token instead
(generate/exchange the credential server‑side or request a temp token and append
only that token or perform a POST auth flow). Also wrap the getCredentials()
call and Linking.openURL(...) in try/catch, surface failures via the app
toast/user feedback system, and handle errors (e.g., fallback UI or copy link)
so failures don’t fail silently; update the code around getCredentials, the URL
construction, and the Linking.openURL invocation to implement these changes.
🪄 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: a86ec913-1e0b-4d85-87ca-057ba32f0634

📥 Commits

Reviewing files that changed from the base of the PR and between 54a2238 and 75e48d6.

📒 Files selected for processing (1)
  • src/app/(tabs)/index.tsx

Comment thread src/app/(tabs)/index.tsx Outdated
Comment thread src/app/(tabs)/index.tsx
@github-actions
Copy link
Copy Markdown

Preview

QR Code

Copy link
Copy Markdown
Owner

@Noelithub77 Noelithub77 left a comment

Choose a reason for hiding this comment

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

pass the bunk data as a base4 encoded url parameter instead of username password

@Noelithub77 Noelithub77 self-requested a review March 30, 2026 04:34
Copy link
Copy Markdown
Owner

@Noelithub77 Noelithub77 left a comment

Choose a reason for hiding this comment

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

pass the bunk data as a base4 encoded url parameter instead of passing username password over url parameters, you won't have to handle auth again too
/bunkialo?bunkdata={$base64 from bunkialo}

@github-actions
Copy link
Copy Markdown

Preview

QR Code

Copy link
Copy Markdown

@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

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/utils/bunkx-payload.ts`:
- Around line 71-85: parseFacultyDetails is currently extracting and returning
raw email-like tokens (faculty_email) from free text, which then gets serialized
by toAttendanceRows; remove this disclosure by stopping extraction/storage of
email addresses and ensuring the faculty value contains no email. Modify
parseFacultyDetails to not populate or return faculty_email (remove the
faculty_email variable from the returned object) and sanitize
facultyFromLabel/facultyFromEmail by stripping any email-like substrings before
returning (use the existing parsing logic but drop anything matching
/[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}/i). Also update toAttendanceRows (and any
serializer that consumes parseFacultyDetails) to stop including faculty_email in
the exported payload and only use the sanitized faculty string.
- Around line 138-145: The payload uses referenceMs = lastSyncTime ?? nowMs
which can make dataset_expires_at immediately expired when lastSyncTime is old;
change referenceMs to the later of nowMs and lastSyncTime (e.g. referenceMs =
Math.max(nowMs, lastSyncTime ?? nowMs)) so dataset_expires_at = new
Date(referenceMs + 30*60*1000).toISOString() (and keep dataset_id based on that
same referenceMs) to guarantee the dataset expires 30 minutes from "now" rather
than from an old sync timestamp.
- Around line 45-50: The code using new Date(year, month, day) (see variables
parsed and fallbackMs and the toIsoDate return) should detect silent
normalization of overflowed dates — after constructing parsed, verify that
parsed.getFullYear() === year, parsed.getMonth() === month, and parsed.getDate()
=== day (and use Number.isNaN(parsed.getTime()) for strict TypeScript checks);
if any check fails, treat it as invalid and return toIsoDate(new
Date(fallbackMs)), otherwise return toIsoDate(parsed).
🪄 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: afa54560-824a-4249-9b77-db97a6ce9259

📥 Commits

Reviewing files that changed from the base of the PR and between 25ae910 and 1cbf366.

📒 Files selected for processing (3)
  • src/app/(tabs)/index.tsx
  • src/types/attendance.ts
  • src/utils/bunkx-payload.ts
✅ Files skipped from review due to trivial changes (1)
  • src/types/attendance.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/app/(tabs)/index.tsx

Comment thread src/utils/bunkx-payload.ts
Comment thread src/utils/bunkx-payload.ts Outdated
Comment thread src/utils/bunkx-payload.ts
@github-actions
Copy link
Copy Markdown

Preview

QR Code

Copy link
Copy Markdown

@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.

♻️ Duplicate comments (2)
src/utils/bunkx-payload.ts (2)

45-50: ⚠️ Potential issue | 🟠 Major

Validate overflowed calendar dates after Date construction.

Line 45 can silently normalize invalid dates (e.g., Feb 31), and Line 46 won’t catch that. This can shift attendance to the wrong day.

🩹 Proposed fix
   const parsed = new Date(year, month, day);
-  if (isNaN(parsed.getTime())) {
+  if (
+    Number.isNaN(parsed.getTime()) ||
+    parsed.getFullYear() !== year ||
+    parsed.getMonth() !== month ||
+    parsed.getDate() !== day
+  ) {
     return toIsoDate(new Date(fallbackMs));
   }
In JavaScript, does `new Date(year, monthIndex, day)` normalize overflow dates (like February 31) instead of returning `Invalid Date`, and is comparing the resulting year/month/day the recommended way to validate strict calendar input?
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/utils/bunkx-payload.ts` around lines 45 - 50, The code currently
constructs parsed = new Date(year, month, day) which silently normalizes
overflow dates (e.g., Feb 31 -> Mar 3); instead after creating parsed compare
parsed.getFullYear(), parsed.getMonth(), and parsed.getDate() against the
original year, month, and day inputs and if any component differs return
toIsoDate(new Date(fallbackMs)); otherwise return toIsoDate(parsed). Update the
block that sets parsed and the conditional to perform this strict component
validation so invalid calendar inputs don't get normalized into wrong dates
(referencing parsed, toIsoDate, and fallbackMs).

66-89: ⚠️ Potential issue | 🟠 Major

Stop exporting email addresses in the Bunkx payload.

Line 71 extracts email-like tokens from free text, and Line 127 exports them. Since this payload is sent to an external site, this creates a new PII disclosure path.

🩹 Minimal mitigation
 const parseFacultyDetails = (
   description: string,
   remarks?: string,
 ): { faculty: string; faculty_email: string } => {
   const source = `${description} ${remarks ?? ""}`.trim();
-  const emailMatch = source.match(/[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}/i);
-  const faculty_email = emailMatch?.[0] ?? "";
+  const emailMatch = source.match(/[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}/i);

   const facultyLabelMatch = source.match(
     /(?:faculty|teacher|staff|by)\s*[:\-]\s*([^,;|]+)/i,
   );
-  const facultyFromLabel = facultyLabelMatch?.[1]?.trim();
+  const facultyFromLabel = (facultyLabelMatch?.[1] ?? "")
+    .replace(/[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}/gi, "")
+    .trim();

-  const facultyFromEmail = faculty_email
+  const facultyFromEmail = emailMatch?.[0]
     ? faculty_email
         .split("@")[0]
         .replace(/[._-]+/g, " ")
         .trim()
     : "";

   return {
     faculty: facultyFromLabel || facultyFromEmail || "Unknown",
-    faculty_email,
+    faculty_email: "",
   };
 };

Also applies to: 116-127

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

In `@src/utils/bunkx-payload.ts` around lines 66 - 89, The function
parseFacultyDetails currently extracts and returns an email (emailMatch ->
faculty_email) and builds a fallback faculty name from it (facultyFromEmail);
remove any email extraction/export to avoid PII leakage by eliminating the use
of emailMatch and faculty_email, always returning faculty_email as an empty
string, and stop deriving facultyFromEmail from an address—only use
facultyLabelMatch (from description/remarks) as the source of faculty name and
otherwise fall back to "Unknown". Update references in parseFacultyDetails and
any callers that expect a non-empty faculty_email so they handle an empty string
safely.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@src/utils/bunkx-payload.ts`:
- Around line 45-50: The code currently constructs parsed = new Date(year,
month, day) which silently normalizes overflow dates (e.g., Feb 31 -> Mar 3);
instead after creating parsed compare parsed.getFullYear(), parsed.getMonth(),
and parsed.getDate() against the original year, month, and day inputs and if any
component differs return toIsoDate(new Date(fallbackMs)); otherwise return
toIsoDate(parsed). Update the block that sets parsed and the conditional to
perform this strict component validation so invalid calendar inputs don't get
normalized into wrong dates (referencing parsed, toIsoDate, and fallbackMs).
- Around line 66-89: The function parseFacultyDetails currently extracts and
returns an email (emailMatch -> faculty_email) and builds a fallback faculty
name from it (facultyFromEmail); remove any email extraction/export to avoid PII
leakage by eliminating the use of emailMatch and faculty_email, always returning
faculty_email as an empty string, and stop deriving facultyFromEmail from an
address—only use facultyLabelMatch (from description/remarks) as the source of
faculty name and otherwise fall back to "Unknown". Update references in
parseFacultyDetails and any callers that expect a non-empty faculty_email so
they handle an empty string safely.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 2bdc9ca6-3411-49c9-851b-f42ccdaae673

📥 Commits

Reviewing files that changed from the base of the PR and between 1cbf366 and 7adadb2.

📒 Files selected for processing (1)
  • src/utils/bunkx-payload.ts

@github-actions
Copy link
Copy Markdown

Preview

QR Code

@github-actions
Copy link
Copy Markdown

Preview

QR Code

@github-actions
Copy link
Copy Markdown

Preview

QR Code

@vishnunathasuresh
Copy link
Copy Markdown
Contributor Author

Da tested... works

@Noelithub77 Noelithub77 merged commit 997459c into Noelithub77:master Mar 31, 2026
3 of 4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants