Skip to content

Add telemetry privacy module and UI optimizations#33

Merged
Ross1116 merged 2 commits into
mainfrom
staging
Feb 20, 2026
Merged

Add telemetry privacy module and UI optimizations#33
Ross1116 merged 2 commits into
mainfrom
staging

Conversation

@Ross1116

@Ross1116 Ross1116 commented Feb 20, 2026

Copy link
Copy Markdown
Owner

Summary by CodeRabbit

  • Bug Fixes

    • Fixed grammar in landing page footer
    • Added a guard to improve project selection reliability
  • Style

    • Adjusted hero illustration placeholder height
  • Refactor

    • Improved selection logic and list filtering with memoization for more efficient UI updates
  • Chores

    • Added telemetry privacy options with email hashing support
    • Made date formatting locale-aware
  • Tests

    • Updated tests to account for locale-aware grouping/formatting

@vercel

vercel Bot commented Feb 20, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
sitespace-app Ready Ready Preview, Comment Feb 20, 2026 4:11am

@coderabbitai

coderabbitai Bot commented Feb 20, 2026

Copy link
Copy Markdown

No actionable comments were generated in the recent review. 🎉


📝 Walkthrough

Walkthrough

Adds a telemetry privacy module and integrates telemetry-safe user identification into AuthContext, guards project persistence when userId is absent, memoizes project filtering in RadioToggle, makes small UI/content tweaks, and adds locale support to booking grouping.

Changes

Cohort / File(s) Summary
Telemetry privacy & auth
src/lib/telemetryPrivacy.ts, src/app/context/AuthContext.tsx
New telemetry privacy utilities (email mode + async SHA‑256 hashing). AuthContext now centralizes telemetry identification via an identifyTelemetryUser helper, calls it during init/login flows, and wraps telemetry calls in non-blocking error handling.
Project selection & toggle optimizations
src/app/(dashboard)/home/page.tsx, src/components/home/RadioToggle.tsx
Guarded saveStoredProject to run only when userId is truthy. RadioToggle adds useCallback/useMemo for initial/filtered project logic and tightens effect fallbacks to avoid redundant selection.
UI text & presentation
src/components/landing/LandingPageOneToOne.tsx, src/components/ui/hero/hero-illustration.tsx
Minor copy fix in landing footer; increased placeholder skeleton height in non-client rendering from 500px to 600px.
Booking helpers & tests
src/lib/bookingHelpers.ts, src/lib/bookingHelpers.test.ts
groupBookingsByMonth gained an optional locale?: Intl.LocalesArgument parameter; tests updated to pass "en-US" to assert stable month formatting.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant AuthContext
    participant TelemetryLib as telemetryPrivacy
    participant Sentry
    participant PostHog

    Client->>AuthContext: init / login (userData)
    AuthContext->>TelemetryLib: getTelemetryEmailMode()
    TelemetryLib-->>AuthContext: mode ("none"|"hash")
    alt mode == "hash"
        AuthContext->>TelemetryLib: hashEmailForTelemetry(email)
        TelemetryLib-->>AuthContext: hashedEmail or null
        AuthContext->>Sentry: setUser({id, email: hashedEmail?, name, role})
        AuthContext->>PostHog: identify(hashedEmail?, {name, role})
    else mode == "none"
        AuthContext->>Sentry: setUser({id, name, role})
        AuthContext->>PostHog: identify(id, {name, role})
    end
    Note right of AuthContext: telemetry errors are caught and reported\nwithout blocking auth flow
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Possibly related PRs

Poem

🐰 I hopped through code with careful paws,
I hashed the emails, minding laws,
Projects saved when users show,
Toggles sped where filters grow,
A little height, a sentence mended — cheers from rabbit cause! 🎉

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed Title check skipped as CodeRabbit has written the PR title.

✏️ 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
  • Post copyable unit tests in a comment
  • Commit unit tests in branch staging

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

@coderabbitai coderabbitai Bot changed the title @coderabbitai Add telemetry privacy module and UI optimizations Feb 20, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (1)
src/components/home/RadioToggle.tsx (1)

48-60: Consider useMemo instead of useCallback for filtered results.

useCallback memoizes the function reference, but every invocation still recomputes the filtered array. When other useEffect dependencies change (e.g., selectedProject, onChange), the effect re-runs and calls getFilteredProjects() again unnecessarily.

Using useMemo would memoize the computed result directly, avoiding redundant filtering.

♻️ Proposed refactor using useMemo
-  const getFilteredProjects = useCallback(() => {
-    const trimmedLower = searchQuery.trim().toLowerCase();
-
-    if (!trimmedLower) {
-      return projects;
-    }
-
-    return projects.filter(
-      (project) =>
-        project.name.toLowerCase().includes(trimmedLower) ||
-        project.id.toLowerCase().includes(trimmedLower),
-    );
-  }, [projects, searchQuery]);
+  const filteredProjects = useMemo(() => {
+    const trimmedLower = searchQuery.trim().toLowerCase();
+
+    if (!trimmedLower) {
+      return projects;
+    }
+
+    return projects.filter(
+      (project) =>
+        project.name.toLowerCase().includes(trimmedLower) ||
+        project.id.toLowerCase().includes(trimmedLower),
+    );
+  }, [projects, searchQuery]);

Then update the import and useEffect accordingly:

-import { useCallback, useEffect, useState } from "react";
+import { useCallback, useEffect, useMemo, useState } from "react";
   useEffect(() => {
-    const filteredProjects = getFilteredProjects();
     setVisibleProjects(filteredProjects);
     // ... rest of effect
-  }, [projects, selectedProject, onChange, userId, getFilteredProjects, getInitialProject]);
+  }, [projects, selectedProject, onChange, userId, filteredProjects, getInitialProject]);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/home/RadioToggle.tsx` around lines 48 - 60, The current
getFilteredProjects function is memoized with useCallback but still recomputes
the filtered array on every invocation; replace useCallback with useMemo to
memoize the computed filteredProjects value (based on projects and searchQuery)
and return that memoized array, then update any uses (e.g., useEffect that
references getFilteredProjects(), selectedProject, onChange) to consume the
memoized filteredProjects value instead of calling the function; update imports
accordingly and ensure the dependency array for useMemo includes [projects,
searchQuery].
🤖 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/context/AuthContext.tsx`:
- Around line 66-86: The identifyTelemetryUser function can throw and it’s
currently awaited by init/login callers which can block setIsInitialized; modify
the code so telemetry identification cannot interrupt auth flow by either
wrapping calls to identifyTelemetryUser in a try/catch (in the init and login
call sites) or making identifyTelemetryUser itself swallow and log errors
internally (e.g., catch inside the useCallback and return). Specifically locate
the identifyTelemetryUser useCallback in AuthContext.tsx and update either the
function body to handle exceptions or change each await
identifyTelemetryUser(...) call to a fire-and-forget try { await
identifyTelemetryUser(...) } catch (e) { /* log */ } pattern so auth
initialization/login always proceeds.

In `@src/lib/bookingHelpers.ts`:
- Around line 155-158: The monthFormatter is hardcoded to "en-US" inside
groupBookingsByMonth, causing locale mismatch; update groupBookingsByMonth to
accept an optional locale parameter (e.g., locale?: string) or default to the
runtime locale (Intl.DateTimeFormat(undefined...)) and use that when
constructing monthFormatter instead of the fixed "en-US"; locate the
monthFormatter creation in groupBookingsByMonth and replace the literal with the
passed-in locale or undefined so month names follow the app/browser i18n
settings.

In `@src/lib/telemetryPrivacy.ts`:
- Around line 25-35: The client-exposed module telemetryPrivacy.ts must not
dynamically import Node's crypto; remove the fallback that calls createHash from
"crypto" and instead return null when WebCrypto (webCrypto?.subtle) is
unavailable. Update the function's return type to allow null (e.g., string |
null) and adjust any callers (e.g., AuthContext.tsx) to handle a null
fingerprint, keeping the existing toHex/webCrypto.subtle path intact and
deleting the createHash import/usage (search for createHash and the Node
fallback block).

---

Nitpick comments:
In `@src/components/home/RadioToggle.tsx`:
- Around line 48-60: The current getFilteredProjects function is memoized with
useCallback but still recomputes the filtered array on every invocation; replace
useCallback with useMemo to memoize the computed filteredProjects value (based
on projects and searchQuery) and return that memoized array, then update any
uses (e.g., useEffect that references getFilteredProjects(), selectedProject,
onChange) to consume the memoized filteredProjects value instead of calling the
function; update imports accordingly and ensure the dependency array for useMemo
includes [projects, searchQuery].

Comment thread src/app/context/AuthContext.tsx
Comment thread src/lib/bookingHelpers.ts Outdated
Comment thread src/lib/telemetryPrivacy.ts Outdated
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant