Skip to content

agent: @U0AJM7X8FBR Admin - Privy login data.#14

Open
sweetmantech wants to merge 1 commit intomainfrom
agent/-u0ajm7x8fbr-admin---privy-log-1773755848646
Open

agent: @U0AJM7X8FBR Admin - Privy login data.#14
sweetmantech wants to merge 1 commit intomainfrom
agent/-u0ajm7x8fbr-admin---privy-log-1773755848646

Conversation

@sweetmantech
Copy link
Copy Markdown
Contributor

@sweetmantech sweetmantech commented Mar 17, 2026

Automated PR from coding agent.

Prompt: @U0AJM7X8FBR Admin - Privy login data.
• actual: I can't review the number of Privy logins on a daily, weekly and monthly basis. I can't see a total count nor a table of the results for any of those time frames.
• requires: Admin codebase has a page where I can review the number of Privy logins on a daily, weekly and monthly basis. I CAN see a total count and a table of the results for any of those time frames.

Summary by CodeRabbit

  • New Features
    • Added Privy Logins dashboard enabling administrators to view and analyze login activity with flexible period filtering options (daily, weekly, monthly).
    • Display comprehensive login statistics alongside detailed records showing user email, Privy identifier, and login creation timestamp.
    • Added "View Privy Logins" navigation link for quick access from the admin dashboard menu.

New /privy page showing daily/weekly/monthly login counts and a
table of individual logins with email, Privy DID, and timestamp.
Adds "View Privy Logins" nav button to AdminDashboard.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 17, 2026

📝 Walkthrough

Walkthrough

A new Privy Logins feature is added to the admin dashboard, including a dedicated page route, navigation link, data-fetching hook, API utility, table component, and TypeScript types for displaying Privy login statistics filtered by period (daily/weekly/monthly).

Changes

Cohort / File(s) Summary
Page & Navigation
app/privy/page.tsx, components/Home/AdminDashboard.tsx
New page route for Privy Logins with metadata title. Navigation item added to AdminDashboard linking to the new page.
PrivyLogins Components
components/PrivyLogins/PrivyLoginsPage.tsx, components/PrivyLogins/PrivyLoginsTable.tsx
New PrivyLoginsPage component with period selector, loading/error/empty states, and total logins count. New PrivyLoginsTable component renders login records with Email, Privy DID, and Created At columns.
Data Fetching Layer
hooks/usePrivyLogins.ts, lib/recoup/fetchPrivyLogins.ts
New usePrivyLogins hook uses react-query to fetch data with Privy authentication. New fetchPrivyLogins utility constructs API request to /api/admins/privy with Bearer token and period parameter.
Types
types/privy.ts
New TypeScript types: PrivyLoginsPeriod (daily/weekly/monthly), PrivyLoginRow (login record structure), PrivyLoginsResponse (API response shape).

Sequence Diagram

sequenceDiagram
    actor User
    participant PLP as PrivyLoginsPage
    participant Hook as usePrivyLogins
    participant Privy as Privy Auth
    participant API as API Server

    User->>PLP: Selects period
    PLP->>Hook: Calls usePrivyLogins(period)
    Hook->>Privy: Retrieves access token
    Privy-->>Hook: Returns token
    Hook->>API: GET /api/admins/privy?period=X<br/>(with Bearer token)
    API-->>Hook: Returns PrivyLoginsResponse
    Hook-->>PLP: Returns { data, loading, error }
    PLP->>PLP: Renders PrivyLoginsTable<br/>with logins data
    PLP-->>User: Displays table with<br/>login records
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Poem

🐰 Hoppity-hop, a new path appears,
Privy Logins tracked through the years,
Periods chosen—daily, weekly, long,
Tables of data, where users belong!
Auth tokens secure, the API's divine, 🔐✨

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title is vague and uses non-descriptive formatting (agent identifier and user mention) that doesn't clearly convey the main change of adding a Privy logins dashboard page. Consider a clearer title like 'Add Privy logins dashboard with daily/weekly/monthly analytics' that describes the feature without agent metadata.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

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

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch agent/-u0ajm7x8fbr-admin---privy-log-1773755848646
📝 Coding Plan
  • Generate coding plan for human review comments

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.

@vercel
Copy link
Copy Markdown

vercel bot commented Mar 17, 2026

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

Project Deployment Actions Updated (UTC)
admin Ready Ready Preview Mar 17, 2026 1:59pm

Request Review

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

🧹 Nitpick comments (4)
components/PrivyLogins/PrivyLoginsPage.tsx (2)

38-49: Add type="button" to prevent form submission behavior.

While these buttons aren't inside a form currently, explicitly setting type="button" is a defensive best practice that prevents accidental form submissions if the component is ever wrapped in a form.

🔧 Proposed fix
            <button
              key={value}
+             type="button"
              onClick={() => setPeriod(value)}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@components/PrivyLogins/PrivyLoginsPage.tsx` around lines 38 - 49, The
rendered period buttons in PrivyLoginsPage (the mapped <button> that calls
setPeriod(value) and checks period === value) should explicitly include
type="button" to avoid accidental form submission if this component is placed
inside a form; update the mapped button element to add type="button" alongside
the existing onClick, key, and className attributes.

66-70: Consider sanitizing error messages displayed to users.

Directly rendering error.message could expose internal implementation details or sensitive information from API errors. Consider using a generic message with the detailed error logged to console for debugging.

🔧 Proposed improvement
      {error && (
        <div className="rounded-md bg-red-50 p-4 text-sm text-red-700 dark:bg-red-900/20 dark:text-red-400">
-          {error instanceof Error ? error.message : "Failed to load Privy logins"}
+          Failed to load Privy logins. Please try again.
        </div>
      )}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@components/PrivyLogins/PrivyLoginsPage.tsx` around lines 66 - 70, The current
rendering in PrivyLoginsPage (the error conditional that shows {error instanceof
Error ? error.message : "Failed to load Privy logins"}) exposes raw error text;
change it to display a sanitized/generic message (e.g., "Failed to load Privy
logins. Please try again.") and move detailed information to logs for debugging
by calling console.error(error) or a logger when error is present. Optionally
implement a small helper like sanitizeErrorMessage or map known error types to
user-friendly strings and use that helper in the error render path, while
ensuring the original error object is still logged for developers.
types/privy.ts (1)

9-13: Consider a discriminated union for error handling.

The status field can be "error", but the type still requires total and logins fields. A discriminated union would provide better type safety when handling error responses:

type PrivyLoginsSuccessResponse = {
  status: "success";
  total: number;
  logins: PrivyLoginRow[];
};

type PrivyLoginsErrorResponse = {
  status: "error";
  error: string;
};

export type PrivyLoginsResponse = PrivyLoginsSuccessResponse | PrivyLoginsErrorResponse;

This is optional if the API always throws on errors before returning a response body with status: "error".

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

In `@types/privy.ts` around lines 9 - 13, Replace the current flat
PrivyLoginsResponse type with a discriminated union so callers can statically
handle success vs error cases: define PrivyLoginsSuccessResponse (status:
"success", total: number, logins: PrivyLoginRow[]) and PrivyLoginsErrorResponse
(status: "error", error: string) and export PrivyLoginsResponse =
PrivyLoginsSuccessResponse | PrivyLoginsErrorResponse; update any places that
assume total/logins exist to narrow on status first.
components/PrivyLogins/PrivyLoginsTable.tsx (1)

33-34: Date formatting is locale-dependent.

toLocaleString() without arguments produces output based on the user's browser locale, which may be inconsistent across admin users. Consider using a specific locale or a date formatting library for consistent display.

🔧 Optional: Use explicit locale
-                {new Date(login.created_at).toLocaleString()}
+                {new Date(login.created_at).toLocaleString("en-US", {
+                  dateStyle: "medium",
+                  timeStyle: "short",
+                })}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@components/PrivyLogins/PrivyLoginsTable.tsx` around lines 33 - 34, The
TableCell is rendering dates with new Date(login.created_at).toLocaleString(),
which yields locale-dependent output; update the rendering in the
PrivyLoginsTable component so the date is formatted consistently (either by
using Intl.DateTimeFormat with an explicit locale/format options or a date
library like date-fns/format) when displaying login.created_at inside the
TableCell; locate the JSX that references login.created_at and replace the
toLocaleString() call with a deterministic formatter (or a small helper
function) so all admin users see a consistent date/time format.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@components/PrivyLogins/PrivyLoginsTable.tsx`:
- Around line 27-28: The TableRow key in PrivyLoginsTable uses only
login.privy_did which can duplicate for multiple events; change the key to a
stable compound key that includes the timestamp (for example combine
login.privy_did and login.created_at) so each login event is unique. Update the
TableRow key usage in the PrivyLoginsTable (and any related PrivyLoginRow
mapping) to something like a string concat of privy_did and created_at to avoid
duplicate React keys.

---

Nitpick comments:
In `@components/PrivyLogins/PrivyLoginsPage.tsx`:
- Around line 38-49: The rendered period buttons in PrivyLoginsPage (the mapped
<button> that calls setPeriod(value) and checks period === value) should
explicitly include type="button" to avoid accidental form submission if this
component is placed inside a form; update the mapped button element to add
type="button" alongside the existing onClick, key, and className attributes.
- Around line 66-70: The current rendering in PrivyLoginsPage (the error
conditional that shows {error instanceof Error ? error.message : "Failed to load
Privy logins"}) exposes raw error text; change it to display a sanitized/generic
message (e.g., "Failed to load Privy logins. Please try again.") and move
detailed information to logs for debugging by calling console.error(error) or a
logger when error is present. Optionally implement a small helper like
sanitizeErrorMessage or map known error types to user-friendly strings and use
that helper in the error render path, while ensuring the original error object
is still logged for developers.

In `@components/PrivyLogins/PrivyLoginsTable.tsx`:
- Around line 33-34: The TableCell is rendering dates with new
Date(login.created_at).toLocaleString(), which yields locale-dependent output;
update the rendering in the PrivyLoginsTable component so the date is formatted
consistently (either by using Intl.DateTimeFormat with an explicit locale/format
options or a date library like date-fns/format) when displaying login.created_at
inside the TableCell; locate the JSX that references login.created_at and
replace the toLocaleString() call with a deterministic formatter (or a small
helper function) so all admin users see a consistent date/time format.

In `@types/privy.ts`:
- Around line 9-13: Replace the current flat PrivyLoginsResponse type with a
discriminated union so callers can statically handle success vs error cases:
define PrivyLoginsSuccessResponse (status: "success", total: number, logins:
PrivyLoginRow[]) and PrivyLoginsErrorResponse (status: "error", error: string)
and export PrivyLoginsResponse = PrivyLoginsSuccessResponse |
PrivyLoginsErrorResponse; update any places that assume total/logins exist to
narrow on status first.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: b1521ae4-a9e7-4c85-8c14-856a036d1f7d

📥 Commits

Reviewing files that changed from the base of the PR and between 71a5110 and beac422.

📒 Files selected for processing (7)
  • app/privy/page.tsx
  • components/Home/AdminDashboard.tsx
  • components/PrivyLogins/PrivyLoginsPage.tsx
  • components/PrivyLogins/PrivyLoginsTable.tsx
  • hooks/usePrivyLogins.ts
  • lib/recoup/fetchPrivyLogins.ts
  • types/privy.ts

Comment on lines +27 to +28
{logins.map((login) => (
<TableRow key={login.privy_did}>
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check if the API response could include duplicate privy_did values
# by looking at API route handler or documentation
fd -t f -e ts -e tsx "privy" | xargs rg -l "api.*admins.*privy" | head -5

Repository: recoupable/admin

Length of output: 114


🏁 Script executed:

cat -n lib/recoup/fetchPrivyLogins.ts

Repository: recoupable/admin

Length of output: 1234


🏁 Script executed:

cat -n hooks/usePrivyLogins.ts

Repository: recoupable/admin

Length of output: 1042


🏁 Script executed:

cat -n components/PrivyLogins/PrivyLoginsTable.tsx

Repository: recoupable/admin

Length of output: 1573


🏁 Script executed:

fd -t f -name "privy.ts" -o -name "privy.d.ts" | head -5

Repository: recoupable/admin

Length of output: 290


🏁 Script executed:

rg "type PrivyLoginRow|type PrivyLoginsResponse|interface PrivyLogin" --type ts

Repository: recoupable/admin

Length of output: 233


🏁 Script executed:

cat -n types/privy.ts

Repository: recoupable/admin

Length of output: 430


Using privy_did alone as the React key will cause reconciliation issues.

Since each PrivyLoginRow represents a distinct login event (note the created_at field), the same user can appear multiple times in a single period with different login timestamps. Using only privy_did as the key will produce duplicate keys, causing React reconciliation failures.

Use a compound key that includes created_at:

🔧 Proposed fix
-          {logins.map((login) => (
-            <TableRow key={login.privy_did}>
+          {logins.map((login) => (
+            <TableRow key={`${login.privy_did}-${login.created_at}`}>
📝 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
{logins.map((login) => (
<TableRow key={login.privy_did}>
{logins.map((login) => (
<TableRow key={`${login.privy_did}-${login.created_at}`}>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@components/PrivyLogins/PrivyLoginsTable.tsx` around lines 27 - 28, The
TableRow key in PrivyLoginsTable uses only login.privy_did which can duplicate
for multiple events; change the key to a stable compound key that includes the
timestamp (for example combine login.privy_did and login.created_at) so each
login event is unique. Update the TableRow key usage in the PrivyLoginsTable
(and any related PrivyLoginRow mapping) to something like a string concat of
privy_did and created_at to avoid duplicate React keys.

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.

1 participant