[Customer Portal][FE][Web] Introduce createdByMe filters, improve UX empty states, and make charts responsive - #488
Conversation
Import PRODUCT_CLASS and add a 'class' query parameter set to PRODUCT_CLASS.PRODUCT_MODEL in useGetProducts.ts. This ensures the products API request is filtered by the correct product model class when fetching product lists.
Introduce PRODUCT_CLASS in commonConstants.ts to mirror the backend entity ProductClass. Adds PRODUCT_MODEL = "product_model" with a const assertion so the frontend uses the same literal value as the backend for product class checks.
Add an explicit type check for assignedEngineer before accessing .name to avoid runtime errors when assignedEngineer is not an object (e.g., a string or null). Keeps the existing logic of splitting the name and falling back to an empty string if no initial is available.
Only derive engineerInitials when assignedEngineer is an object with a name. The code now checks typeof data.assignedEngineer === "object" and that a name exists before splitting to get the first initial, otherwise it falls back to an empty string. This prevents unsafe property access for cases where assignedEngineer may be a non-object or missing name.
Update apps/customer-portal/webapp/package.json version from 1.0.0-rc.2 to 1.0.0-rc.3 to mark the next release candidate for the webapp. No other changes were made.
Introduce UseGetConversationStatsOptions with createdByMe and enabled flags and accept an optional options parameter in useGetConversationStats. The queryKey now includes createdByMe, and the request URL appends ?createdBy=me when createdByMe is true. The hook's enabled condition is also controllable via options.enabled (defaults to true). These changes allow fetching user-filtered stats and optionally disabling the query.
Replace the plain text message for an empty outstanding cases list with a centered empty state UI. Imports EmptyIcon and wraps the message in a Box with vertical layout, padding, and an icon (120px width) above the typography to improve visual feedback when there are no cases.
Improve the empty state for the chat history list by adding an EmptyIcon and centering it. The change imports EmptyIcon, wraps the message in a Box with column layout, centered alignment and vertical padding, and displays a responsive icon above the existing "No chat history." text to provide a clearer visual cue when there are no items.
Adjust USAGE_LINE_CHART_MARGIN.bottom from 5 to 40 to provide extra space for x-axis labels/ticks and prevent clipping in the customer portal usage charts.
When there are no chat history items, render a centered empty-state view instead of plain text. Imports EmptyIcon and wraps the message in a Box with column-centered layout and spacing; the icon is sized and placed above the "No chat history." text to improve UX. (apps/customer-portal/webapp/src/components/support/support-overview-cards/ChatHistoryList.tsx)
Add formatDateForChart to render human-friendly chart labels (e.g. "Jan 1" or "Jan 1\n2024") and make labels responsive to small screens. Replace prior date.slice(5) usage in buildTrendFromUsages and buildDailyCoreTrend with this formatter. The new function parses ISO YYYY-MM-DD, outputs month-name/day and places the year on a new line for larger screens, with a safe fallback to MM-DD on parse error.
Adjust USAGE_LINE_CHART_MARGIN in usageMetricsConstants.ts: right margin increased from 30 to 40 and bottom margin from 5 to 40. This provides extra spacing for labels/axis/legend on the usage line chart.
📝 WalkthroughWalkthroughAdds optional Changes
Sequence Diagram(s)sequenceDiagram
participant Page as Page (AllConversations / AllCases / ServiceRequests)
participant Hook as Hook (useGetConversationStats / useGetProjectCasesStats)
participant Fetch as Fetch layer
participant API as Backend API
Page->>Hook: call hook(projectId, { createdByMe })
Hook->>Hook: build queryKey [..., createdByMe] and build URL (append ?createdBy=me if true)
Hook->>Fetch: fetch(URL)
Fetch->>API: HTTP GET /...stats?createdBy=me
API-->>Fetch: 200 OK (stats payload)
Fetch-->>Hook: response JSON
Hook-->>Page: supply stats data (react-query cache keyed by createdByMe)
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
apps/customer-portal/webapp/src/components/support/support-overview-cards/OutstandingCasesList.tsx (1)
75-89: Consider extracting a shared overview empty-state component.This layout is now duplicated across support overview cards (
ChatHistoryListandOutstandingCasesList). A small shared component would reduce repetition and keep spacing/icon behavior consistent.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/customer-portal/webapp/src/components/support/support-overview-cards/OutstandingCasesList.tsx` around lines 75 - 89, Extract the duplicated empty-state Box into a reusable component (e.g., OverviewEmptyState) and replace the inline JSX in OutstandingCasesList and ChatHistoryList with that component; the new component should accept props for the icon (pass EmptyIcon), message text ("No outstanding cases." / whatever ChatHistoryList uses) and optional styling overrides, and preserve the existing layout (flex column, centered, py:2 and icon sizing/margin). Update OutstandingCasesList to render <OverviewEmptyState icon={EmptyIcon} message="No outstanding cases." /> and do the analogous replacement in ChatHistoryList.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In
`@apps/customer-portal/webapp/src/components/project-details/usage-metrics/UsageOverviewPanel.tsx`:
- Around line 64-82: The function formatDateForChart currently relies on
try/catch but new Date(...) can produce an "Invalid Date" without throwing, so
you must validate the date after construction and before calling
getUTCMonth/getUTCDate/getUTCFullYear; update formatDateForChart to create the
Date, check Number.isNaN(date.getTime()) (or date.getTime() === NaN check via
Number.isNaN), and if invalid return the fallback (isoDate.slice(5))
immediately; otherwise compute month/day/year and return the small-screen or
large-screen formatted string as before (preserve the isSmallScreen behavior and
the existing monthNames array) so chart labels never receive NaN values.
---
Nitpick comments:
In
`@apps/customer-portal/webapp/src/components/support/support-overview-cards/OutstandingCasesList.tsx`:
- Around line 75-89: Extract the duplicated empty-state Box into a reusable
component (e.g., OverviewEmptyState) and replace the inline JSX in
OutstandingCasesList and ChatHistoryList with that component; the new component
should accept props for the icon (pass EmptyIcon), message text ("No outstanding
cases." / whatever ChatHistoryList uses) and optional styling overrides, and
preserve the existing layout (flex column, centered, py:2 and icon
sizing/margin). Update OutstandingCasesList to render <OverviewEmptyState
icon={EmptyIcon} message="No outstanding cases." /> and do the analogous
replacement in ChatHistoryList.
🪄 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: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: e2317b88-26c8-4901-9278-0ec0aa8f74b4
📒 Files selected for processing (13)
apps/customer-portal/webapp/package.jsonapps/customer-portal/webapp/src/api/useGetConversationStats.tsapps/customer-portal/webapp/src/api/useGetProducts.tsapps/customer-portal/webapp/src/api/useGetProjectCasesStats.tsapps/customer-portal/webapp/src/components/project-details/usage-metrics/UsageOverviewPanel.tsxapps/customer-portal/webapp/src/components/support/announcements/AnnouncementDetailsPanel.tsxapps/customer-portal/webapp/src/components/support/support-overview-cards/ChatHistoryList.tsxapps/customer-portal/webapp/src/components/support/support-overview-cards/OutstandingCasesList.tsxapps/customer-portal/webapp/src/constants/commonConstants.tsapps/customer-portal/webapp/src/constants/usageMetricsConstants.tsapps/customer-portal/webapp/src/pages/AllCasesPage.tsxapps/customer-portal/webapp/src/pages/AllConversationsPage.tsxapps/customer-portal/webapp/src/pages/ServiceRequestsPage.tsx
Render a CallsListSkeleton when isFetchingNextPage is true instead of immediately showing CallRequestList. The change conditionally wraps CallRequestList with an isFetchingNextPage check so the skeleton displays during pagination loads; pagination UI remains unchanged.
Description
This pull request introduces several improvements and enhancements to the customer portal webapp, focusing on API flexibility, UI responsiveness, and user experience. The most notable changes include adding filtering options to API hooks, improving the display of empty states in support components, and making usage metric charts responsive to screen size.
API Enhancements and Filtering
createdByMefilter option and improved theenabledflag in theuseGetConversationStatsanduseGetProjectCasesStatshooks, allowing consumers to filter statistics by the current user's created items and control query activation. The query keys and request URLs are updated accordingly. [1] [2] [3] [4] [5] [6] [7] [8] [9]useGetProductshook now always requests only products of classproduct_modelby default, using a new constant incommonConstants.ts. [1] [2] [3]UI/UX Improvements
EmptyIconand improved the empty state display for chat history and outstanding cases lists, providing a more visually engaging and consistent user experience when there is no data. [1] [2] [3] [4]AnnouncementDetailsPanelwhere engineer initials could display incorrectly if the assigned engineer was not an object.Usage Metrics and Chart Responsiveness
Miscellaneous
1.0.0-rc.2to1.0.0-rc.3inpackage.json.Summary by CodeRabbit
New Features
Bug Fixes