Skip to content

Calendar sync dashboard mock data #3299

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 19 commits into from
Jul 22, 2025
Merged

Calendar sync dashboard mock data #3299

merged 19 commits into from
Jul 22, 2025

Conversation

DennieDan
Copy link
Collaborator

@DennieDan DennieDan commented Jul 21, 2025

Summary by CodeRabbit

  • New Features

    • Introduced a comprehensive Calendar Sync Dashboard for monitoring synchronization activity, analytics, and logs across workspaces.
    • Added detailed analytics charts and summary cards for calendar sync performance and trends.
    • Implemented a sync logs table with filtering and search capabilities.
    • Added new navigation submenu for calendar sync dashboard and history.
  • Localization

    • Added English and Vietnamese translations for new calendar sync dashboard and history tabs.
  • Bug Fixes

    • Improved navigation structure by flattening single-child navigation links for a cleaner sidebar experience.
  • Chores

    • Updated TypeScript configuration to include additional files for testing.
    • Removed unused global error page component.

@DennieDan DennieDan self-assigned this Jul 21, 2025
Copy link
Contributor

coderabbitai bot commented Jul 21, 2025

Warning

Rate limit exceeded

@vhpx has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 7 minutes and 50 seconds before requesting another review.

⌛ How to resolve this issue?

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

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

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

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

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 231b9cc and f1a15c2.

📒 Files selected for processing (1)
  • packages/types/src/supabase.ts (19 hunks)

Walkthrough

This update introduces a calendar sync dashboard feature, including new React components for analytics, summary cards, and sync logs. It adds supporting TypeScript types, localization strings, navigation structure changes for submenu handling, and a new exports alias. The update also removes a global error component and modifies TypeScript and navigation configurations.

Changes

File(s) Change Summary
apps/web/messages/en.json, apps/web/messages/vi.json Added two new translation keys ("sync-dashboard", "sync-history") to the "calendar-tabs" section in both English and Vietnamese localization files.
apps/web/src/app/[locale]/(dashboard)/[wsId]/layout.tsx Updated navigation: removed null entries, replaced calendar tab with submenu containing main calendar and sync history views, added Activity icon.
apps/web/src/app/[locale]/(dashboard)/[wsId]/structure.tsx Refactored navigation logic to flatten single-child links, using flatMap and recursive flattening for consistent navigation structure.
apps/web/src/app/[locale]/(dashboard)/[wsId]/calendar/history/sync/page.tsx Added new page component rendering the CalendarSyncDashboard.
packages/ui/package.json Added export path alias for ./calendar-settings in the exports field.
packages/ui/src/components/ui/legacy/calendar/settings/analytics-charts.tsx Introduced AnalyticsCharts React component for displaying multiple analytics charts related to calendar sync.
packages/ui/src/components/ui/legacy/calendar/settings/calendar-sync-dashboard.tsx Added CalendarSyncDashboard React component, providing a dashboard for calendar sync activity, metrics, and analytics.
packages/ui/src/components/ui/legacy/calendar/settings/summary-cards.tsx Added SummaryCards React component for displaying summary statistics on sync and event changes.
packages/ui/src/components/ui/legacy/calendar/settings/sync-logs-table.tsx Added SyncLogsTable React component for displaying sync activity logs with filtering and search.
packages/ui/src/components/ui/legacy/calendar/settings/types.ts Introduced TypeScript interfaces for workspace, user, sync log, time series, event type, workspace activity, and calendar source data.
packages/ui/src/components/ui/legacy/calendar/settings/index.ts Added export for CalendarSyncDashboard component.
packages/trigger/tsconfig.json Updated TypeScript include patterns to add root and test files for compilation.
apps/web/src/app/global-error.tsx Deleted the GlobalError React component file.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant DashboardPage
    participant CalendarSyncDashboard
    participant AnalyticsCharts
    participant SummaryCards
    participant SyncLogsTable

    User->>DashboardPage: Navigate to Sync Dashboard page
    DashboardPage->>CalendarSyncDashboard: Render dashboard
    CalendarSyncDashboard->>SummaryCards: Render summary metrics
    CalendarSyncDashboard->>AnalyticsCharts: Render analytics charts
    CalendarSyncDashboard->>SyncLogsTable: Render sync logs table
Loading

Estimated code review effort

4 (~90 minutes)

Suggested labels

calendar

Poem

In the warren of code, a dashboard appears,
With charts and with logs to calm all your fears.
Syncs now tracked, events counted true,
Colors and badges in every hue.
Navigation’s smarter, translations anew—
A bunny’s delight in each feature for you! 🐇📊

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/calendar-sync-dashboard

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

graphite-app bot commented Jul 21, 2025

How to use the Graphite Merge Queue

Add either label to this PR to merge it via the merge queue:

  • merge-queue - adds this PR to the back of the merge queue
  • hotfix - for urgent hot fixes, skip the queue and merge this PR next

You must have a Graphite account in order to use the merge queue. Sign up using this link.

An organization admin has enabled the Graphite Merge Queue in this repository.

Please do not merge from GitHub as this will restart CI on PRs being processed by the merge queue.

Copy link
Contributor

github-actions bot commented Jul 21, 2025

🔧 Biome Check Report

Issues Found: 0

📊 Analysis Summary

Metric Value Status
📁 Files Checked ✅ Complete
⚠️ Total Issues 0 ✅ All clear

🔍 Issue Breakdown

Issue Type Count Status
Errors ✅ None
⚠️ Warnings ✅ None
📝 Total Issues NaN 🎯 Perfect!

🎉 All Issues Resolved!

Your code is now 100% clean! Great job! 🏆


🤖 Auto-generated by Biome Check workflow • Last updated: 7/22/2025, 4:42:02 PM

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Summary of Changes

Hello @DennieDan, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request introduces a new 'Calendar Sync Dashboard' feature, designed to provide users with a comprehensive overview and detailed logs of calendar synchronization activities across different workspaces. The goal is to enhance monitoring and provide insights into the performance and status of calendar integrations.

Highlights

  • New Dashboard Page: A dedicated page for the Calendar Sync Dashboard has been added at /calendar/sync-dashboard, providing a centralized view of synchronization activities.
  • Comprehensive UI Component: A new CalendarSyncDashboard React component has been implemented, featuring summary cards, interactive analytics charts (for sync activity, event changes, duration, success rates, workspace comparison, and source distribution), and a detailed table of synchronization logs with filtering and search functionalities. This component uses mock data for demonstration.
  • Sidebar Navigation Integration: The main application sidebar has been updated. The existing 'Calendar' entry is now a parent item that expands to reveal child links, including the original 'Calendar' view and the new 'Sync Dashboard' page.
  • Localization Support: New localization strings for 'Sync Dashboard' have been added for both English and Vietnamese languages.
  • UI Package Export: The newly created CalendarSyncDashboard component is now exported from the @tuturuuu/ui package, making it reusable across the application.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in issue comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist is currently in preview and may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments to provide feedback.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

codecov bot commented Jul 21, 2025

Codecov Report

Attention: Patch coverage is 0.50352% with 988 lines in your changes missing coverage. Please review.

Project coverage is 1.50%. Comparing base (96616b8) to head (1706e25).
Report is 7 commits behind head on main.

Files with missing lines Patch % Lines
...s/ui/legacy/calendar/settings/analytics-charts.tsx 0.28% 350 Missing ⚠️
...gacy/calendar/settings/calendar-sync-dashboard.tsx 0.37% 264 Missing ⚠️
...ts/ui/legacy/calendar/settings/sync-logs-table.tsx 0.40% 244 Missing ⚠️
...ents/ui/legacy/calendar/settings/summary-cards.tsx 1.33% 74 Missing ⚠️
.../src/app/[locale]/(dashboard)/[wsId]/structure.tsx 0.00% 35 Missing ⚠️
...web/src/app/[locale]/(dashboard)/[wsId]/layout.tsx 0.00% 15 Missing ⚠️
.../(dashboard)/[wsId]/calendar/history/sync/page.tsx 0.00% 4 Missing and 1 partial ⚠️
...rc/components/ui/legacy/calendar/settings/index.ts 0.00% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3299      +/-   ##
==========================================
- Coverage    1.50%    1.50%   -0.01%     
==========================================
  Files        1910     1916       +6     
  Lines      246872   247828     +956     
  Branches     2594     2600       +6     
==========================================
+ Hits         3714     3718       +4     
- Misses     241596   242546     +950     
- Partials     1562     1564       +2     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a new Calendar Sync Dashboard. It adds the necessary page, navigation links, and a UI component for the dashboard. The dashboard component is well-structured visually but has areas for improvement regarding performance and maintainability before it's ready for production.

@DennieDan DennieDan changed the title Calendar sync dashboard Calendar sync dashboard mock data Jul 21, 2025
@DennieDan DennieDan marked this pull request as ready for review July 22, 2025 14:28
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (8)
packages/ui/src/components/ui/legacy/calendar/settings/sync-logs-table.tsx (2)

83-83: Remove unused parameter.

The error parameter in the getStatusBadge function is defined but never used, as indicated by the static analysis tool.

-  const getStatusBadge = (status: string, error?: string) => {
+  const getStatusBadge = (status: string) => {

You'll also need to update the call site at line 300:

-                  <TableCell>{getStatusBadge(log.status, log.error)}</TableCell>
+                  <TableCell>{getStatusBadge(log.status)}</TableCell>

63-77: Consider using a date library for more robust timestamp formatting.

While the current implementation works, consider using a library like date-fns or dayjs for more reliable and consistent date formatting, especially for internationalization support.

+import { formatDistanceToNow, format } from 'date-fns';

  const formatTimestamp = (timestamp: string) => {
    const date = new Date(timestamp);
-    const now = new Date();
-    const diffMs = now.getTime() - date.getTime();
-    const diffMins = Math.floor(diffMs / (1000 * 60));
-
-    if (diffMins < 1) return 'Just now';
-    if (diffMins < 60) return `${diffMins}m ago`;
-    if (diffMins < 1440) return `${Math.floor(diffMins / 60)}h ago`;
-    return (
-      date.toLocaleDateString() +
-      ' ' +
-      date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })
-    );
+    const now = new Date();
+    const diffHours = (now.getTime() - date.getTime()) / (1000 * 60 * 60);
+    
+    if (diffHours < 24) {
+      return formatDistanceToNow(date, { addSuffix: true });
+    }
+    return format(date, 'MMM d, yyyy HH:mm');
  };
packages/ui/src/components/ui/legacy/calendar/settings/calendar-sync-dashboard.tsx (2)

25-25: Avoid non-null assertions on array access

Using the non-null assertion operator (!) when accessing array elements can lead to runtime errors if the indices don't exist. Consider using a safer approach.

Instead of:

workspace: workspaces[0]!,

Use:

workspace: workspaces[0] ?? workspaces[0],

Or better yet, create the workspaces first and reference them directly:

const marketingTeam = { id: 'ws_1', name: 'Marketing Team', color: 'bg-blue-500' };
const engineering = { id: 'ws_2', name: 'Engineering', color: 'bg-green-500' };
// ... then use in syncLogs
workspace: marketingTeam,

Also applies to: 45-45, 60-60, 81-81, 96-96, 116-116


180-180: Make color extraction more robust

The current approach assumes all colors follow the 'bg-' prefix pattern, which is fragile.

Consider using a more explicit color mapping:

-color: workspace.color.replace('bg-', ''),
+color: workspace.color.startsWith('bg-') ? workspace.color.replace('bg-', '') : workspace.color,

Or better yet, store the actual color values separately from the Tailwind classes in your Workspace interface.

packages/ui/src/components/ui/legacy/calendar/settings/analytics-charts.tsx (2)

393-395: Use stable keys instead of array indices

Using array indices as keys can cause issues if the data order changes.

-{calendarSourceData.map((entry, index) => (
-  <Cell key={`cell-${index}`} fill={entry.color} />
+{calendarSourceData.map((entry) => (
+  <Cell key={`cell-${entry.name}`} fill={entry.color} />
))}

410-433: Use stable keys and validate percentage display

Similar key issue and the percentage display assumes the value is already a percentage.

-{calendarSourceData.map((source, index) => (
+{calendarSourceData.map((source) => (
   <div
-    key={index}
+    key={source.name}
     className="flex items-center justify-between rounded-lg bg-slate-50 p-3"
   >

Also consider validating that the percentage values sum to 100 or formatting them appropriately.

packages/ui/src/components/ui/legacy/calendar/settings/types.ts (2)

1-5: Consider using a more specific type for color

The color field is currently a generic string but appears to store Tailwind CSS classes.

export interface Workspace {
  id: string;
  name: string;
-  color: string;
+  color: `bg-${string}-${number}` | string; // Tailwind pattern or custom color
}

Or create a union type of allowed colors for better type safety.


55-59: Add JSDoc to clarify the value field represents a percentage

The value field appears to represent a percentage based on usage, but this isn't clear from the type definition.

export interface CalendarSourceData {
  name: string;
+  /** Percentage value (0-100) representing the source's share of total syncs */
  value: number;
  color: string;
}
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 96616b8 and 7a504c7.

⛔ Files ignored due to path filters (1)
  • bun.lock is excluded by !**/*.lock
📒 Files selected for processing (12)
  • apps/web/messages/en.json (1 hunks)
  • apps/web/messages/vi.json (1 hunks)
  • apps/web/src/app/[locale]/(dashboard)/[wsId]/calendar/sync-dashboard/page.tsx (1 hunks)
  • apps/web/src/app/[locale]/(dashboard)/[wsId]/layout.tsx (2 hunks)
  • packages/trigger/tsconfig.json (1 hunks)
  • packages/ui/package.json (1 hunks)
  • packages/ui/src/components/ui/legacy/calendar/settings/analytics-charts.tsx (1 hunks)
  • packages/ui/src/components/ui/legacy/calendar/settings/calendar-sync-dashboard.tsx (1 hunks)
  • packages/ui/src/components/ui/legacy/calendar/settings/index.ts (1 hunks)
  • packages/ui/src/components/ui/legacy/calendar/settings/summary-cards.tsx (1 hunks)
  • packages/ui/src/components/ui/legacy/calendar/settings/sync-logs-table.tsx (1 hunks)
  • packages/ui/src/components/ui/legacy/calendar/settings/types.ts (1 hunks)
🧠 Learnings (6)
📓 Common learnings
Learnt from: DennieDan
PR: tutur3u/platform#2891
File: packages/ui/src/hooks/use-calendar.tsx:1511-1513
Timestamp: 2025-05-21T09:22:15.348Z
Learning: In the `GoogleCalendarSettings` component's `handleSyncNow` function, the boolean return value from `syncGoogleCalendarNow` is used to determine if changes were made during a successful sync, while errors are handled through a separate try/catch block with detailed error messages.
packages/ui/src/components/ui/legacy/calendar/settings/index.ts (1)

Learnt from: DennieDan
PR: #2891
File: packages/ui/src/hooks/use-calendar.tsx:1511-1513
Timestamp: 2025-05-21T09:22:15.348Z
Learning: In the GoogleCalendarSettings component's handleSyncNow function, the boolean return value from syncGoogleCalendarNow is used to determine if changes were made during a successful sync, while errors are handled through a separate try/catch block with detailed error messages.

apps/web/src/app/[locale]/(dashboard)/[wsId]/calendar/sync-dashboard/page.tsx (1)

Learnt from: DennieDan
PR: #2891
File: packages/ui/src/hooks/use-calendar.tsx:1511-1513
Timestamp: 2025-05-21T09:22:15.348Z
Learning: In the GoogleCalendarSettings component's handleSyncNow function, the boolean return value from syncGoogleCalendarNow is used to determine if changes were made during a successful sync, while errors are handled through a separate try/catch block with detailed error messages.

packages/ui/src/components/ui/legacy/calendar/settings/summary-cards.tsx (1)

Learnt from: DennieDan
PR: #2891
File: packages/ui/src/hooks/use-calendar.tsx:1511-1513
Timestamp: 2025-05-21T09:22:15.348Z
Learning: In the GoogleCalendarSettings component's handleSyncNow function, the boolean return value from syncGoogleCalendarNow is used to determine if changes were made during a successful sync, while errors are handled through a separate try/catch block with detailed error messages.

packages/ui/src/components/ui/legacy/calendar/settings/sync-logs-table.tsx (1)

Learnt from: DennieDan
PR: #2891
File: packages/ui/src/hooks/use-calendar.tsx:1511-1513
Timestamp: 2025-05-21T09:22:15.348Z
Learning: In the GoogleCalendarSettings component's handleSyncNow function, the boolean return value from syncGoogleCalendarNow is used to determine if changes were made during a successful sync, while errors are handled through a separate try/catch block with detailed error messages.

packages/ui/src/components/ui/legacy/calendar/settings/calendar-sync-dashboard.tsx (1)

Learnt from: DennieDan
PR: #2891
File: packages/ui/src/hooks/use-calendar.tsx:1511-1513
Timestamp: 2025-05-21T09:22:15.348Z
Learning: In the GoogleCalendarSettings component's handleSyncNow function, the boolean return value from syncGoogleCalendarNow is used to determine if changes were made during a successful sync, while errors are handled through a separate try/catch block with detailed error messages.

🧬 Code Graph Analysis (2)
packages/ui/src/components/ui/legacy/calendar/settings/sync-logs-table.tsx (4)
packages/ui/src/components/ui/legacy/calendar/settings/types.ts (2)
  • SyncLog (14-29)
  • Workspace (1-5)
packages/ui/src/components/ui/badge.tsx (1)
  • Badge (49-49)
packages/ui/src/components/ui/select.tsx (5)
  • Select (170-170)
  • SelectTrigger (178-178)
  • SelectValue (179-179)
  • SelectContent (171-171)
  • SelectItem (173-173)
packages/ui/src/components/ui/avatar.tsx (3)
  • Avatar (52-52)
  • AvatarImage (52-52)
  • AvatarFallback (52-52)
packages/ui/src/components/ui/legacy/calendar/settings/calendar-sync-dashboard.tsx (4)
packages/ui/src/components/ui/legacy/calendar/settings/types.ts (2)
  • Workspace (1-5)
  • SyncLog (14-29)
packages/ui/src/components/ui/legacy/calendar/settings/summary-cards.tsx (1)
  • SummaryCards (17-101)
packages/ui/src/components/ui/legacy/calendar/settings/analytics-charts.tsx (1)
  • AnalyticsCharts (48-442)
packages/ui/src/components/ui/legacy/calendar/settings/sync-logs-table.tsx (1)
  • SyncLogsTable (53-350)
🪛 GitHub Check: CodeFactor
packages/ui/src/components/ui/legacy/calendar/settings/sync-logs-table.tsx

[notice] 83-83: packages/ui/src/components/ui/legacy/calendar/settings/sync-logs-table.tsx#L83
'error' is defined but never used. (@typescript-eslint/no-unused-vars)

🧰 Additional context used
🧠 Learnings (6)
📓 Common learnings
Learnt from: DennieDan
PR: tutur3u/platform#2891
File: packages/ui/src/hooks/use-calendar.tsx:1511-1513
Timestamp: 2025-05-21T09:22:15.348Z
Learning: In the `GoogleCalendarSettings` component's `handleSyncNow` function, the boolean return value from `syncGoogleCalendarNow` is used to determine if changes were made during a successful sync, while errors are handled through a separate try/catch block with detailed error messages.
packages/ui/src/components/ui/legacy/calendar/settings/index.ts (1)

Learnt from: DennieDan
PR: #2891
File: packages/ui/src/hooks/use-calendar.tsx:1511-1513
Timestamp: 2025-05-21T09:22:15.348Z
Learning: In the GoogleCalendarSettings component's handleSyncNow function, the boolean return value from syncGoogleCalendarNow is used to determine if changes were made during a successful sync, while errors are handled through a separate try/catch block with detailed error messages.

apps/web/src/app/[locale]/(dashboard)/[wsId]/calendar/sync-dashboard/page.tsx (1)

Learnt from: DennieDan
PR: #2891
File: packages/ui/src/hooks/use-calendar.tsx:1511-1513
Timestamp: 2025-05-21T09:22:15.348Z
Learning: In the GoogleCalendarSettings component's handleSyncNow function, the boolean return value from syncGoogleCalendarNow is used to determine if changes were made during a successful sync, while errors are handled through a separate try/catch block with detailed error messages.

packages/ui/src/components/ui/legacy/calendar/settings/summary-cards.tsx (1)

Learnt from: DennieDan
PR: #2891
File: packages/ui/src/hooks/use-calendar.tsx:1511-1513
Timestamp: 2025-05-21T09:22:15.348Z
Learning: In the GoogleCalendarSettings component's handleSyncNow function, the boolean return value from syncGoogleCalendarNow is used to determine if changes were made during a successful sync, while errors are handled through a separate try/catch block with detailed error messages.

packages/ui/src/components/ui/legacy/calendar/settings/sync-logs-table.tsx (1)

Learnt from: DennieDan
PR: #2891
File: packages/ui/src/hooks/use-calendar.tsx:1511-1513
Timestamp: 2025-05-21T09:22:15.348Z
Learning: In the GoogleCalendarSettings component's handleSyncNow function, the boolean return value from syncGoogleCalendarNow is used to determine if changes were made during a successful sync, while errors are handled through a separate try/catch block with detailed error messages.

packages/ui/src/components/ui/legacy/calendar/settings/calendar-sync-dashboard.tsx (1)

Learnt from: DennieDan
PR: #2891
File: packages/ui/src/hooks/use-calendar.tsx:1511-1513
Timestamp: 2025-05-21T09:22:15.348Z
Learning: In the GoogleCalendarSettings component's handleSyncNow function, the boolean return value from syncGoogleCalendarNow is used to determine if changes were made during a successful sync, while errors are handled through a separate try/catch block with detailed error messages.

🧬 Code Graph Analysis (2)
packages/ui/src/components/ui/legacy/calendar/settings/sync-logs-table.tsx (4)
packages/ui/src/components/ui/legacy/calendar/settings/types.ts (2)
  • SyncLog (14-29)
  • Workspace (1-5)
packages/ui/src/components/ui/badge.tsx (1)
  • Badge (49-49)
packages/ui/src/components/ui/select.tsx (5)
  • Select (170-170)
  • SelectTrigger (178-178)
  • SelectValue (179-179)
  • SelectContent (171-171)
  • SelectItem (173-173)
packages/ui/src/components/ui/avatar.tsx (3)
  • Avatar (52-52)
  • AvatarImage (52-52)
  • AvatarFallback (52-52)
packages/ui/src/components/ui/legacy/calendar/settings/calendar-sync-dashboard.tsx (4)
packages/ui/src/components/ui/legacy/calendar/settings/types.ts (2)
  • Workspace (1-5)
  • SyncLog (14-29)
packages/ui/src/components/ui/legacy/calendar/settings/summary-cards.tsx (1)
  • SummaryCards (17-101)
packages/ui/src/components/ui/legacy/calendar/settings/analytics-charts.tsx (1)
  • AnalyticsCharts (48-442)
packages/ui/src/components/ui/legacy/calendar/settings/sync-logs-table.tsx (1)
  • SyncLogsTable (53-350)
🪛 GitHub Check: CodeFactor
packages/ui/src/components/ui/legacy/calendar/settings/sync-logs-table.tsx

[notice] 83-83: packages/ui/src/components/ui/legacy/calendar/settings/sync-logs-table.tsx#L83
'error' is defined but never used. (@typescript-eslint/no-unused-vars)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: codecov/project
🔇 Additional comments (12)
apps/web/messages/en.json (2)

973-974: LGTM – syntax & style

Comma placement and key-naming are consistent with adjacent entries. No other issues spotted.


973-974: Locale parity confirmed for “sync-dashboard”
I ran a recursive grep (grep -RL '"sync-dashboard"' --include='*.json' apps/web/messages) and found no JSON files missing the new key. No further action needed here.

packages/ui/src/components/ui/legacy/calendar/settings/index.ts (1)

1-1: No changes needed for CalendarSyncDashboard re-export

The calendar-sync-dashboard.tsx file defines and exports CalendarSyncDashboard as a named function (line 201), so the existing re-export

export { CalendarSyncDashboard } from './calendar-sync-dashboard';

is correct.

apps/web/messages/vi.json (1)

984-985: Translation entry added correctly

The new sync-dashboard key is present and the Vietnamese wording (“Bảng điều khiển đồng bộ”) is clear and context-appropriate. No further action needed.

packages/ui/package.json (1)

114-114: LGTM! Clean export alias addition.

The new export path alias follows the established pattern and provides clean access to the calendar settings components for external consumption.

apps/web/src/app/[locale]/(dashboard)/[wsId]/calendar/sync-dashboard/page.tsx (1)

1-5: Clean page component implementation.

The page component correctly imports and renders the CalendarSyncDashboard from the new export alias. The implementation is minimal and appropriate for a page-level component.

apps/web/src/app/[locale]/(dashboard)/[wsId]/layout.tsx (2)

14-14: Good addition of Activity icon.

The Activity icon import supports the new sync-dashboard submenu item.


223-234: Well-structured submenu implementation.

The calendar navigation properly converts from a direct link to a submenu structure. The icon sizing follows the correct hierarchy (h-4 w-4 for submenu items vs h-5 w-5 for main items), and the translation keys suggest proper internationalization support.

packages/ui/src/components/ui/legacy/calendar/settings/summary-cards.tsx (2)

6-15: Well-defined TypeScript interface.

The props interface clearly defines the expected data structure with appropriate types for summary metrics.


17-101: Excellent visual design and implementation.

The component features:

  • Responsive grid layout that adapts to different screen sizes
  • Consistent card styling with subtle backdrop blur effects
  • Appropriate semantic color coding (green for success, blue for updates, red for deletions)
  • Smart conditional rendering that only shows failed sync count when failures exist
  • Good accessibility with descriptive text and icons

The implementation is clean and follows React best practices.

packages/ui/src/components/ui/legacy/calendar/settings/sync-logs-table.tsx (1)

140-349: Comprehensive and well-structured table implementation.

The component successfully implements:

  • Comprehensive filtering and search functionality
  • Proper table structure with appropriate styling
  • Smart badge rendering for status and sync types
  • User avatar handling with fallbacks
  • Empty state with helpful messaging
  • Responsive design considerations

The code is well-organized and follows React best practices.

packages/ui/src/components/ui/legacy/calendar/settings/analytics-charts.tsx (1)

108-116: Document CSS variable dependencies

The chart configurations rely on CSS variables (e.g., --chart-1, --chart-2) that must be defined in your CSS.

Ensure these CSS variables are defined in your global styles or theme:

:root {
  --chart-1: /* color value */;
  --chart-2: /* color value */;
  --chart-3: /* color value */;
  --chart-4: /* color value */;
  --chart-5: /* color value */;
}

Also applies to: 160-172, 218-223, 258-267, 312-321, 367-379

@@ -6,6 +6,6 @@
"@tuturuuu/trigger/*": ["./src/*"]
}
},
"include": ["src"],
"include": ["*.ts", "__tests__/**/*.ts"],
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

src sources are no longer compiled – add the pattern back

Replacing the previous "src" include with only "*.ts" and "__tests__/**/*.ts" narrows the compile scope to:
• root-level .ts files
• any file under __tests__/

All implementation code under src/ is now silently excluded, so tsc will not type-check or emit those files.
Restore the original pattern (and optionally .tsx support) to avoid build breakage:

-  "include": ["*.ts", "__tests__/**/*.ts"],
+  "include": ["src/**/*.{ts,tsx}", "*.ts", "__tests__/**/*.ts"],
🤖 Prompt for AI Agents
In packages/trigger/tsconfig.json at line 9, the current "include" array
excludes the "src" directory, causing implementation files there to be ignored
by the TypeScript compiler. To fix this, add "src/**/*" back into the "include"
array to ensure all source files under "src" are compiled and type-checked.
Optionally, include "*.tsx" files if your project uses them.

Comment on lines +7 to +12
export interface User {
id: string;
name: string;
email: string;
avatar: string;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Make avatar field optional

Not all users may have avatars, so this field should be optional to prevent runtime issues.

export interface User {
  id: string;
  name: string;
  email: string;
-  avatar: string;
+  avatar?: string;
}
📝 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 interface User {
id: string;
name: string;
email: string;
avatar: string;
}
export interface User {
id: string;
name: string;
email: string;
avatar?: string;
}
🤖 Prompt for AI Agents
In packages/ui/src/components/ui/legacy/calendar/settings/types.ts between lines
7 and 12, the User interface defines the avatar field as required, but since not
all users have avatars, this field should be made optional. Update the User
interface by adding a question mark after the avatar field name to make it
optional, preventing runtime issues when the avatar is missing.

vhpx added 3 commits July 22, 2025 23:04
…e link flattening logic

This update introduces a `requireRootWorkspace` flag for the sync-dashboard link in the layout, ensuring that only users with the appropriate workspace access can view it. Additionally, the logic for flattening links with a single child has been enhanced in the Structure component, improving navigation efficiency.
This commit deletes the GlobalError component and introduces a new CalendarSyncDashboard page that utilizes the CalendarSyncDashboard component from the UI library.
This commit refines the styling of various components in the calendar settings, including AnalyticsCharts, CalendarSyncDashboard, SummaryCards, and SyncLogsTable. Changes include adjustments to background colors, text opacity, and layout properties to enhance visual coherence and user experience.
vhpx
vhpx previously approved these changes Jul 22, 2025
Copy link
Member

@vhpx vhpx left a comment

Choose a reason for hiding this comment

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

LGTM! Thanks @DennieDan.

This commit improves the link flattening logic in the Structure component by ensuring that single child links are correctly typed as NavLink and filtered for null values. This change enhances type safety and maintains the integrity of the navigation structure.
Copy link

vercel bot commented Jul 22, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

3 Skipped Deployments
Name Status Preview Updated (UTC)
calendar ⬜️ Skipped (Inspect) Jul 22, 2025 4:39pm
nova ⬜️ Skipped (Inspect) Jul 22, 2025 4:39pm
rewise ⬜️ Skipped (Inspect) Jul 22, 2025 4:39pm

@vercel vercel bot temporarily deployed to Preview – calendar July 22, 2025 16:39 Inactive
@vercel vercel bot temporarily deployed to Preview – rewise July 22, 2025 16:39 Inactive
@vercel vercel bot temporarily deployed to Preview – nova July 22, 2025 16:39 Inactive
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
apps/web/src/app/[locale]/(dashboard)/[wsId]/structure.tsx (1)

83-89: Extract duplicated flattening logic into a helper function.

The link flattening logic is duplicated. Consider extracting it into a reusable function to improve maintainability:

+  const flattenSingleChildLinks = (links: (NavLink | null)[]): (NavLink | null)[] => {
+    return links
+      .flatMap((link) =>
+        link?.children && link.children.length === 1
+          ? [link.children[0] as NavLink]
+          : [link]
+      )
+      .filter(Boolean) as (NavLink | null)[];
+  };

   // In the initial state:
-    const flattenedLinks = links
-      .flatMap((link) =>
-        link?.children && link.children.length === 1
-          ? [link.children[0] as NavLink]
-          : [link]
-      )
-      .filter(Boolean) as (NavLink | null)[];
+    const flattenedLinks = flattenSingleChildLinks(links);

   // In the useEffect:
-        const flattenedLinks = links
-          .flatMap((link) =>
-            link?.children && link.children.length === 1
-              ? [link.children[0] as NavLink]
-              : [link]
-          )
-          .filter(Boolean) as (NavLink | null)[];
+        const flattenedLinks = flattenSingleChildLinks(links);

Also applies to: 133-139

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 7a504c7 and 231b9cc.

📒 Files selected for processing (10)
  • apps/web/messages/en.json (1 hunks)
  • apps/web/messages/vi.json (1 hunks)
  • apps/web/src/app/[locale]/(dashboard)/[wsId]/calendar/history/sync/page.tsx (1 hunks)
  • apps/web/src/app/[locale]/(dashboard)/[wsId]/layout.tsx (2 hunks)
  • apps/web/src/app/[locale]/(dashboard)/[wsId]/structure.tsx (6 hunks)
  • apps/web/src/app/global-error.tsx (0 hunks)
  • packages/ui/src/components/ui/legacy/calendar/settings/analytics-charts.tsx (1 hunks)
  • packages/ui/src/components/ui/legacy/calendar/settings/calendar-sync-dashboard.tsx (1 hunks)
  • packages/ui/src/components/ui/legacy/calendar/settings/summary-cards.tsx (1 hunks)
  • packages/ui/src/components/ui/legacy/calendar/settings/sync-logs-table.tsx (1 hunks)
🧠 Learnings (1)
📓 Common learnings
Learnt from: DennieDan
PR: tutur3u/platform#2891
File: packages/ui/src/hooks/use-calendar.tsx:1511-1513
Timestamp: 2025-05-21T09:22:15.348Z
Learning: In the `GoogleCalendarSettings` component's `handleSyncNow` function, the boolean return value from `syncGoogleCalendarNow` is used to determine if changes were made during a successful sync, while errors are handled through a separate try/catch block with detailed error messages.
💤 Files with no reviewable changes (1)
  • apps/web/src/app/global-error.tsx
✅ Files skipped from review due to trivial changes (3)
  • apps/web/src/app/[locale]/(dashboard)/[wsId]/calendar/history/sync/page.tsx
  • packages/ui/src/components/ui/legacy/calendar/settings/sync-logs-table.tsx
  • apps/web/messages/vi.json
🚧 Files skipped from review as they are similar to previous changes (5)
  • apps/web/src/app/[locale]/(dashboard)/[wsId]/layout.tsx
  • apps/web/messages/en.json
  • packages/ui/src/components/ui/legacy/calendar/settings/summary-cards.tsx
  • packages/ui/src/components/ui/legacy/calendar/settings/calendar-sync-dashboard.tsx
  • packages/ui/src/components/ui/legacy/calendar/settings/analytics-charts.tsx
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: DennieDan
PR: tutur3u/platform#2891
File: packages/ui/src/hooks/use-calendar.tsx:1511-1513
Timestamp: 2025-05-21T09:22:15.348Z
Learning: In the `GoogleCalendarSettings` component's `handleSyncNow` function, the boolean return value from `syncGoogleCalendarNow` is used to determine if changes were made during a successful sync, while errors are handled through a separate try/catch block with detailed error messages.
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
  • GitHub Check: Analyze (javascript-typescript)
  • GitHub Check: Deploy-Preview
  • GitHub Check: Deploy-Preview
  • GitHub Check: Verify generated types
  • GitHub Check: Deploy-Preview
  • GitHub Check: Deploy-Preview
  • GitHub Check: Prettier Check (24)
🔇 Additional comments (3)
apps/web/src/app/[locale]/(dashboard)/[wsId]/structure.tsx (3)

65-96: LGTM! Clean implementation of single-child link flattening.

The logic correctly identifies links with multiple children as submenus and flattens single-child links during initial state setup. The use of flatMap with filter(Boolean) ensures proper handling of null values.


195-222: Excellent refactoring of the filtering logic!

The use of flatMap with empty array returns is cleaner than the previous map + filter approach. The recursive flattening of single-child links ensures consistent behavior throughout the navigation hierarchy.


274-274: Good removal of unnecessary type cast.

Removing the as any cast improves type safety and allows proper TypeScript validation.

@@ -62,7 +62,7 @@ export function Structure({
direction: 'forward' | 'backward';
}>(() => {
for (const link of links) {
if (link?.children) {
if (link?.children && link.children.length > 1) {
Copy link
Contributor

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 the impact of single-child link flattening on existing navigation.

This change globally flattens all navigation links with a single child, which could be a breaking change for existing navigation structures. Please ensure this behavior is intended for all navigation items, not just the new calendar sync feature.

Consider adding a flag to NavLink type (e.g., preventFlattening?: boolean) to allow opting out of this behavior for specific links if needed.

Also applies to: 102-102, 208-218


🏁 Script executed:

#!/bin/bash
# Description: Search for navigation link definitions to identify potential single-child submenus that might be affected

# Find all navigation link definitions
echo "=== Searching for navigation link definitions ==="
rg -A 10 "children:\s*\[" --type tsx --type ts

# Look for specific patterns where single-child submenus might be intentional
echo -e "\n=== Searching for links with exactly one child ==="
ast-grep --pattern 'children: [$_]'

Length of output: 340


To get a clearer picture of how widespread single-child submenus are and where NavLink (or similar) is defined, let’s locate all children definitions and the NavLink type/interface. This will help us see if existing links rely on exactly one child.


🏁 Script executed:

#!/bin/bash
echo "=== NavLink type/interface definitions ==="
rg -n "interface NavLink" -A5 --glob '*.ts' --glob '*.tsx'
rg -n "type NavLink" -A5 --glob '*.ts' --glob '*.tsx'

echo -e "\n=== All 'children:' occurrences in source ==="
rg -n "children\s*:" -A5 --glob '*.ts' --glob '*.tsx'

Length of output: 70256


Restrict or opt out of single-child flattening

The new flattening rule in
apps/web/src/app/[locale]/(dashboard)/[wsId]/structure.tsx
currently applies to every link whose children.length === 1. In your dashboard layout (layout.tsx), the “Chat”, “Models”, “Calendar”, “Users” and “Settings” sections each define exactly one child, so all of those will be flattened too—removing their parent icon/label and any grouping behavior.

Please decide whether you intended this global change. If you only want to flatten the calendar submenu, add an opt-out flag (e.g. preventFlattening?: boolean) to the NavLink type and guard the flattening logic:

• NavLink type in apps/web/src/components/navigation.tsx (line 10):

 export interface NavLink {
   title: string;
+  /** skip automatic flatten when only one child */
+  preventFlattening?: boolean;
   trailing?: string;
   icon?: ReactNode;
   href?: string;
   newTab?: boolean;
 }

• In apps/web/src/app/[locale]/(dashboard)/[wsId]/structure.tsx (around line 215):

- // Flatten links with a single child
- if (link.children && link.children.length === 1) {
-   return getFilteredLinks([link.children[0] as NavLink]);
- }
+ // Flatten only when not opted out
+ if (!link.preventFlattening && link.children?.length === 1) {
+   return getFilteredLinks([link.children[0] as NavLink]);
+ }

Then, in your layout.tsx, set preventFlattening: true on any top-level menus you want to keep grouped (e.g. Chat, Models, Users, Settings).

🤖 Prompt for AI Agents
In apps/web/src/app/[locale]/(dashboard)/[wsId]/structure.tsx at line 65, the
current flattening logic applies to all links with exactly one child, which
unintentionally flattens important dashboard sections like Chat, Models,
Calendar, Users, and Settings. To fix this, add an optional boolean property
preventFlattening to the NavLink type in apps/web/src/components/navigation.tsx
around line 10. Then update the flattening condition in structure.tsx around
line 215 to skip flattening if preventFlattening is true. Finally, in
layout.tsx, set preventFlattening: true on the top-level menus you want to keep
grouped, such as Chat, Models, Users, and Settings, to preserve their icons and
grouping behavior.

@vhpx vhpx merged commit d991cc8 into main Jul 22, 2025
19 checks passed
@vhpx vhpx deleted the feat/calendar-sync-dashboard branch July 22, 2025 16:45
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.

2 participants