-
Notifications
You must be signed in to change notification settings - Fork 73
[Feat]-Web: improve kanban and dashboard with pdf export and skeletons #3911
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
[Feat]-Web: improve kanban and dashboard with pdf export and skeletons #3911
Conversation
…an page - Refactored the Kanban page to utilize dynamic imports for various components, enhancing performance and user experience during loading states. - Introduced skeleton components for Kanban cards, filters, and views to provide visual feedback while data is being fetched. - Updated the Kanban card and filters to use lazy loading, ensuring smoother transitions and reduced initial load times. - Enhanced the overall structure and readability of the Kanban component, improving maintainability.
…ban component - Updated Kanban page and related components to utilize ModalSkeleton for better user experience during modal loading. - Replaced fallback divs in Suspense components with ModalSkeleton, enhancing visual feedback while modals are being loaded. - Ensured consistent loading states across various modals within the Kanban interface, improving overall responsiveness and user interaction.
…s in Kanban component - Introduced a new KanbanColumnLoadingSkeleton component to provide visual feedback during loading states in the Kanban view. - Updated InnerItemList to utilize the new skeleton component, enhancing user experience by clearly indicating loading conditions. - Enhanced conditional rendering logic to handle loading states more effectively, ensuring a smoother user interaction while data is being fetched.
…components - Implemented lazy loading for `TeamStatsChart`, `TeamStatsTable`, and various dashboard components to enhance performance during data fetching. - Introduced new skeleton components: `ChartSkeleton` and `TeamStatsTableSkeleton` to provide visual feedback while data is loading. - Updated `DashboardHeader` and `TeamStatsTable` to utilize dynamic imports, improving user experience by reducing initial load times and ensuring smoother transitions. - Enhanced conditional rendering for modals and loading states, ensuring a consistent and responsive interface.
…components - Implemented lazy loading for various components in the dashboard and settings pages, including `TeamStatsChart`, `TeamStatsTable`, and personal settings components, to improve performance during data fetching. - Introduced new skeleton components such as `AccordionContentSkeleton`, `PersonalSettingFormSkeleton`, and `WorkingHoursSkeleton` to provide visual feedback while data is loading. - Updated the `DashboardHeader` and `ExportMenu` to utilize dynamic imports and skeletons, ensuring a smoother user experience and reducing initial load times. - Enhanced conditional rendering for loading states across multiple components, improving overall responsiveness and user interaction.
…ed UI consistency - Adjusted margin and padding values across multiple components, including `UserProfileTask`, `DataTable`, and skeleton components, to enhance visual alignment and spacing. - Updated class names to ensure consistent styling, particularly in loading states and skeletons, improving user experience during data fetching. - Enhanced the structure of flexbox properties in components like `SettingsPersonalSkeleton` and `UserTeamCard` for better responsiveness and layout coherence.
…ts and dynamic imports - Introduced multiple skeleton components for improved loading states, including `ProductivityApplicationTableSkeleton`, `ProductivityEmployeeTableSkeleton`, and `ProductivityProjectTableSkeleton`, enhancing user experience during data fetching. - Implemented lazy loading for the `DashboardHeader` and `ProductivityChart` components, optimizing performance and reducing initial load times. - Updated the `ExportButtons` component to handle empty data gracefully, ensuring a smoother user experience when generating reports. - Refactored the `ProductivityPDF` and `ProductivityApplicationPDF` components to manage empty data scenarios, providing clear feedback to users when no data is available. - Enhanced the `ProductivityHeader` component to accept a string for the year, improving flexibility in displaying date information.
…components - Removed unused `DashboardHeaderSkeleton` import from the team dashboard page for better code clarity. - Adjusted flexbox properties in `ProductivityTableSkeleton` to enhance layout consistency and responsiveness. - Streamlined class names for improved readability and maintainability across skeleton components.
… states - Registered Helvetica font for improved PDF styling in `ProductivityPDF` and `ProductivityApplicationPDF` components. - Updated `ProductivityApplicationPDF` to use Helvetica font for consistent typography. - Added a new loading state for the `ProductivityEmployeeTable` in the dashboard, enhancing user experience during data fetching.
…ration - Added user authentication hook to retrieve current user information for PDF exports. - Updated PDF-compatible data structure to include real user details such as full name, first name, last name, employee ID, and user ID. - Enhanced debugging output for PDF export data to include user information, aiding in development and troubleshooting.
WalkthroughThis update introduces extensive use of lazy loading and React Suspense for dashboard, kanban, and settings components to optimize performance and loading states. Numerous skeleton components are added for visual feedback during loading. The dashboard export logic is enhanced with a PDF-compatible data transformation function and improved handling of empty or malformed data. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant DashboardPage
participant LazyDashboardHeader
participant ProductivityTable
participant Skeletons
User->>DashboardPage: Load dashboard
DashboardPage->>LazyDashboardHeader: Render (Suspense)
LazyDashboardHeader-->>Skeletons: Show DashboardHeaderSkeleton while loading
LazyDashboardHeader-->>DashboardPage: Rendered header (with pdfCompatibleData)
DashboardPage->>ProductivityTable: Render table (Suspense)
ProductivityTable-->>Skeletons: Show ProductivityTableSkeleton while loading
ProductivityTable-->>DashboardPage: Rendered productivity table
Possibly related issues
Possibly related PRs
Suggested labels
Suggested reviewers
Poem
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ESLint
yarn install v1.22.22 ✨ Finishing Touches
🧪 Generate 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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed 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)
Other keywords and placeholders
CodeRabbit Configuration File (
|
Please review these files and clean up the unused code. |
Please review these files and clean up the unused code. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PR Summary
Major enhancement to application-wide loading states and PDF export functionality, introducing 16+ new skeleton components and fixing critical rendering issues.
- Added comprehensive skeleton loading system in
apps/web/core/components/common/skeleton/
with unified shimmer animations and dark mode support - Fixed PDF export by switching to Helvetica font and adding proper data validation in
apps/web/core/components/pages/dashboard/app-url/productivity-pdf.tsx
- Optimized performance through lazy loading with Next.js dynamic imports in dashboard and kanban components
- Improved date handling and validation across productivity reports and dashboard components
- Enhanced timer status display with proper constants and type safety in
apps/web/core/components/timer/timer-status.tsx
50 files reviewed, 38 comments
Edit PR Review Bot Settings | Greptile
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
🔭 Outside diff range comments (2)
apps/web/core/constants/config/constants.tsx (1)
749-755
: New constant appears unused, causing pipeline failure.
TIMER_STATUS_CONSTANTS
is defined but not referenced anywhere in this module—Knip flagged it as unused. Please either import and use it in your updated timer-status logic or remove it if redundant.apps/web/core/components/pages/dashboard/team-dashboard/team-stats-grid.tsx (1)
97-105
: Remove redundant loading logic for consistency.Since the component now renders
StatsCardSkeleton
whenloadingTimesheetStatisticsCounts
is true, the individual loader logic inside each card is redundant and will never be reached. This creates maintenance overhead and potential confusion.Remove the individual loading logic since the skeleton handles the entire loading state:
- <div className="mt-2 h-9"> - {loadingTimesheetStatisticsCounts ? ( - <Loader2 className="w-6 h-6 text-gray-500 animate-spin" /> - ) : ( - <span - className={`text-2xl font-semibold ${stat.color || 'text-gray-900 dark:text-white'}`} - > - {stat.value} - </span> - )} - </div> + <div className="mt-2 h-9"> + <span + className={`text-2xl font-semibold ${stat.color || 'text-gray-900 dark:text-white'}`} + > + {stat.value} + </span> + </div>
🧹 Nitpick comments (14)
apps/web/core/components/tasks/task-times.tsx (2)
117-121
: Use correct spacing utility and remove invalid CSS classThe switch from
space-x-4
togap-x-4
is spot on for modern Tailwind layouts. However,text-nowrap
isn’t a default Tailwind utility and has no effect. You can droptext-nowrap
—whitespace-nowrap
already enforces no wrapping (or usetruncate
for overflow).
135-141
: Consistent spacing update and invalid class cleanupAgain, replacing
space-x-4
withgap-x-4
is correct. Thetext-nowrap
class here should also be removed since it’s not a standard Tailwind utility. Rely onwhitespace-nowrap
or addtruncate
if needed.apps/web/core/components/common/skeleton/kanban-view-skeleton.tsx (1)
8-39
: Well-implemented skeleton component with responsive considerationsThe KanbanViewSkeleton component effectively provides loading state feedback with appropriate styling and animations. The fixed layout with 5 columns and responsive width classes aligns well with typical Kanban board implementations.
Consider making the number of columns configurable via props to increase reusability across different Kanban layouts.
-export function KanbanViewSkeleton({ className, fullWidth = true }: KanbanViewSkeletonProps) { - const columns = Array.from(Array(5)); +export function KanbanViewSkeleton({ className, fullWidth = true, columnCount = 5 }: KanbanViewSkeletonProps) { + const columns = Array.from(Array(columnCount));interface KanbanViewSkeletonProps { className?: string; fullWidth?: boolean; + columnCount?: number; }
apps/web/core/components/pages/dashboard/team-dashboard/team-stats-grid.tsx (1)
113-114
: Consider removing loading-dependent width calculation.The progress bar width is set to 0 when loading, but since the skeleton handles the loading state, this logic is now redundant.
Simplify the width calculation:
- style={{ - width: `${loadingTimesheetStatisticsCounts ? 0 : stat.progress}%` - }} + style={{ + width: `${stat.progress}%` + }}apps/web/core/components/common/skeleton/working-hours-skeleton.tsx (1)
14-34
: Good implementation with minor suggestionThe working hours skeleton is well-implemented. The conditional rendering for time slots (
index < 5
) makes sense for business days, but consider making this more explicit.- {/* Time Slots (only for enabled days) */} - {index < 5 && ( + {/* Time Slots (only for weekdays) */} + {index < 5 && (Or even better, define a constant:
+const WEEKDAYS_COUNT = 5; + export const WorkingHoursSkeleton = () => { return ( <div className="space-y-6 mt-6"> {/* Timezone Section */} <div className="space-y-4"> <div className="w-32 h-4 bg-[#F0F0F0] dark:bg-[#353741] animate-pulse rounded" /> <div className="w-64 h-10 bg-[#F0F0F0] dark:bg-[#353741] animate-pulse rounded" /> </div> {/* Working Days */} <div className="space-y-4"> {Array.from({ length: 7 }).map((_, index) => ( <div key={index} className="relative rounded-lg border border-gray-200 dark:border-gray-700 p-4"> {/* Day Toggle */} <div className="flex items-center justify-between mb-4"> <div className="flex items-center gap-3"> <div className="w-12 h-6 bg-[#F0F0F0] dark:bg-[#353741] animate-pulse rounded-full" /> <div className="w-20 h-4 bg-[#F0F0F0] dark:bg-[#353741] animate-pulse rounded" /> </div> <div className="w-6 h-6 bg-[#F0F0F0] dark:bg-[#353741] animate-pulse rounded" /> </div> {/* Time Slots (only for weekdays) */} - {index < 5 && ( + {index < WEEKDAYS_COUNT && ( <div className="flex items-center gap-4 pl-[180px]"> <div className="w-24 h-8 bg-[#F0F0F0] dark:bg-[#353741] animate-pulse rounded" /> <div className="w-4 h-1 bg-[#F0F0F0] dark:bg-[#353741] animate-pulse rounded" /> <div className="w-24 h-8 bg-[#F0F0F0] dark:bg-[#353741] animate-pulse rounded" /> </div> )} </div> ))} </div>apps/web/core/components/pages/dashboard/app-url/productivity-pdf.tsx (1)
9-13
: Consider font loading reliability.The font registration improves PDF rendering consistency. However, loading fonts from external URLs could cause issues if the CDN is unavailable.
Consider hosting the font locally or providing a fallback mechanism:
Font.register({ family: 'Helvetica', - src: 'https://fonts.gstatic.com/s/helveticaneue/v70/1Ptsg8zYS_SKggPNyC0IT0kLW-43aMEzIO6XUTLjad8.ttf' + src: 'https://fonts.gstatic.com/s/helveticaneue/v70/1Ptsg8zYS_SKggPNyC0IT0kLW-43aMEzIO6XUTLjad8.ttf', + fontWeight: 'normal' });apps/web/core/components/pages/dashboard/team-dashboard/team-stats-table.tsx (1)
159-166
: Verify the lazy component usage without Suspense wrapper.The
LazyAnimatedEmptyState
is used here without a Suspense boundary, which could cause issues if the component fails to load. Since this component has its own loading state defined in the dynamic import, it should work, but consider wrapping it in Suspense for consistency.Consider wrapping with Suspense for consistency:
<div className="grow w-full min-h-[600px] flex items-center justify-center flex-col"> + <Suspense fallback={ + <div className="grow w-full min-h-[600px] flex items-center justify-center flex-col"> + <div className="w-32 h-32 bg-[#F0F0F0] dark:bg-[#353741] animate-pulse rounded-full mb-4" /> + <div className="w-48 h-6 bg-[#F0F0F0] dark:bg-[#353741] animate-pulse rounded mb-2" /> + <div className="w-64 h-4 bg-[#F0F0F0] dark:bg-[#353741] animate-pulse rounded" /> + </div> + }> <LazyAnimatedEmptyState title={t('common.NO_ACTIVITY_DATA')} message={t('common.SELECT_DIFFERENT_DATE')} showBorder={true} /> + </Suspense> </div>apps/web/core/components/common/skeleton/accordion-content-skeleton.tsx (1)
13-14
: Consider extracting color values to constants.The color values
#F0F0F0
and#353741
are repeated throughout the component. Consider extracting them to constants or CSS variables for better maintainability.+const SKELETON_COLORS = { + light: '#F0F0F0', + dark: '#353741' +} as const; export const AccordionContentSkeleton = ({ type = 'form', className = '' }: AccordionContentSkeletonProps) => {Then use them like:
-<div className="w-20 h-4 bg-[#F0F0F0] dark:bg-[#353741] animate-pulse rounded" /> +<div className={`w-20 h-4 bg-[${SKELETON_COLORS.light}] dark:bg-[${SKELETON_COLORS.dark}] animate-pulse rounded`} />Also applies to: 24-25, 34-36, 46-49, 52-52
apps/web/core/components/common/skeleton/productivity-employee-table-skeleton.tsx (1)
31-35
: Simplify key prop usage in employee groups.The Fragment and its first TableRow child both use similar key patterns, which could be confusing. Consider using a more distinct key pattern or removing the key from the Fragment since React 18+ doesn't require keys on Fragments when children have keys.
-<Fragment key={`employee-group-${employeeIndex}`}> +<Fragment key={employeeIndex}> {/* Employee Header Row */} <TableRow - key={`employee-header-${employeeIndex}`} + key={`header-${employeeIndex}`}apps/web/app/[locale]/(main)/kanban/page.tsx (1)
29-36
: Consider simplifying the KanbanView import.The dynamic import can be simplified by using a named export directly.
-const LazyKanbanView = dynamic( - () => - import('@/core/components/pages/kanban/team-members-kanban-view').then((mod) => ({ default: mod.KanbanView })), +const LazyKanbanView = dynamic( + () => import('@/core/components/pages/kanban/team-members-kanban-view').then((mod) => mod.KanbanView),Note: This assumes
KanbanView
is a named export. If it's the default export, the current pattern is correct.apps/web/core/components/pages/dashboard/export-dialog.tsx (1)
42-51
: Good development-only debug logging!The debug logging is properly gated behind NODE_ENV check. Consider using a more structured logging approach for better debugging experience.
-console.log('ExportButtons Debug:', { +console.debug('[ExportButtons]', { reportData: reportData?.length, exportType, groupByType, startDate, endDate });apps/web/app/[locale]/(main)/dashboard/app-url/[teamId]/page.tsx (1)
190-204
: Consider removing or redacting sensitive user information from debug logs.Even in development, logging user PII (fullName, employeeId) could be problematic if logs are persisted or shared.
Consider logging only non-sensitive debugging information:
console.log('📄 PDF Export Data Debug:', { originalActivityReport: activityReport?.length, pdfCompatibleDataLength: pdfCompatibleData?.length, - pdfCompatibleDataStructure: pdfCompatibleData?.[0], + hasData: pdfCompatibleData?.length > 0, reportDataType: typeof pdfCompatibleData, reportDataIsArray: Array.isArray(pdfCompatibleData), - userInfo: { - fullName: user?.fullName, - firstName: user?.firstName, - lastName: user?.lastName, - employeeId: user?.employee?.id - } + hasUserInfo: !!user });apps/web/core/components/tasks/kanban.tsx (2)
101-103
: Consider adding a comment to explain the loading state logic.The
isActuallyLoading
calculation handles important edge cases but could benefit from documentation.// Check if we're in a "false loading" state where isLoading=false but no data is actually available yet const isActuallyLoading = useMemo(() => { + // Show loading state if: + // 1. Explicitly loading + // 2. Items is not a valid array (data not yet received) + // 3. Items is empty but we know there should be data (allColumnsData exists) return isLoading || !Array.isArray(items) || (items.length === 0 && allColumnsData); }, [isLoading, items, allColumnsData]);
165-177
: Consider extracting modal implementations to reduce code duplication.The same modal patterns are repeated multiple times throughout the file. This violates the DRY principle.
Consider creating reusable modal wrapper components:
// Add these components at the top of the file const CreateTaskModalWrapper = ({ isOpen, closeModal, title }: { isOpen: boolean; closeModal: () => void; title: string; }) => { if (!isOpen) return null; return ( <Suspense fallback={<ModalSkeleton size="lg" />}> <Modal isOpen={isOpen} closeModal={closeModal}> <LazyCreateTaskModal onClose={closeModal} title={title} initEditMode={false} task={null} tasks={[]} /> </Modal> </Suspense> ); }; const EditStatusModalWrapper = ({ isOpen, closeModal, status, setColumn }: { isOpen: boolean; closeModal: () => void; status: any; setColumn: any; }) => { if (!isOpen) return null; return ( <Suspense fallback={<ModalSkeleton size="md" />}> <Modal isOpen={isOpen} closeModal={closeModal}> <LazyEditStatusModal status={status} onClose={closeModal} setColumn={setColumn} /> </Modal> </Suspense> ); };Then replace all instances with these wrapper components.
Also applies to: 388-398, 426-445, 535-541, 640-652
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (51)
apps/web/app/[locale]/(main)/dashboard/app-url/[teamId]/page.tsx
(7 hunks)apps/web/app/[locale]/(main)/dashboard/team-dashboard/[teamId]/page.tsx
(5 hunks)apps/web/app/[locale]/(main)/kanban/page.tsx
(8 hunks)apps/web/app/[locale]/(main)/settings/personal/page.tsx
(2 hunks)apps/web/core/components/common/data-table.tsx
(2 hunks)apps/web/core/components/common/skeleton/accordion-content-skeleton.tsx
(1 hunks)apps/web/core/components/common/skeleton/auth-user-task-input-skeleton.tsx
(0 hunks)apps/web/core/components/common/skeleton/chart-skeleton.tsx
(1 hunks)apps/web/core/components/common/skeleton/dashboard-header-skeleton.tsx
(1 hunks)apps/web/core/components/common/skeleton/export-pdf-skeleton.tsx
(1 hunks)apps/web/core/components/common/skeleton/kanban-card-skeleton.tsx
(1 hunks)apps/web/core/components/common/skeleton/kanban-column-loading-skeleton.tsx
(1 hunks)apps/web/core/components/common/skeleton/kanban-filters-skeleton.tsx
(1 hunks)apps/web/core/components/common/skeleton/kanban-view-skeleton.tsx
(1 hunks)apps/web/core/components/common/skeleton/no-team-skeleton.tsx
(1 hunks)apps/web/core/components/common/skeleton/personal-setting-form-skeleton.tsx
(1 hunks)apps/web/core/components/common/skeleton/productivity-application-table-skeleton.tsx
(1 hunks)apps/web/core/components/common/skeleton/productivity-employee-table-skeleton.tsx
(1 hunks)apps/web/core/components/common/skeleton/productivity-project-table-skeleton.tsx
(1 hunks)apps/web/core/components/common/skeleton/productivity-skeletons.tsx
(1 hunks)apps/web/core/components/common/skeleton/productivity-table-skeleton.tsx
(1 hunks)apps/web/core/components/common/skeleton/settings-personal-skeleton.tsx
(9 hunks)apps/web/core/components/common/skeleton/stats-card-skeleton.tsx
(1 hunks)apps/web/core/components/common/skeleton/task-timer-section-skeleton.tsx
(0 hunks)apps/web/core/components/common/skeleton/team-stats-table-skeleton.tsx
(1 hunks)apps/web/core/components/common/skeleton/working-hours-skeleton.tsx
(1 hunks)apps/web/core/components/icons/icons.tsx
(1 hunks)apps/web/core/components/pages/dashboard/app-url/productivity-application/productivity-application-pdf.tsx
(2 hunks)apps/web/core/components/pages/dashboard/app-url/productivity-header.tsx
(1 hunks)apps/web/core/components/pages/dashboard/app-url/productivity-pdf.tsx
(2 hunks)apps/web/core/components/pages/dashboard/dashboard-header.tsx
(2 hunks)apps/web/core/components/pages/dashboard/export-dialog.tsx
(2 hunks)apps/web/core/components/pages/dashboard/export-menu.tsx
(2 hunks)apps/web/core/components/pages/dashboard/team-dashboard/lazy-components.tsx
(1 hunks)apps/web/core/components/pages/dashboard/team-dashboard/team-stats-grid.tsx
(2 hunks)apps/web/core/components/pages/dashboard/team-dashboard/team-stats-table.tsx
(8 hunks)apps/web/core/components/pages/kanban/team-members-kanban-view.tsx
(1 hunks)apps/web/core/components/pages/profile/screenshots/screenshoots-per-hour-skeleton.tsx
(1 hunks)apps/web/core/components/pages/profile/user-profile-tasks.tsx
(1 hunks)apps/web/core/components/pages/teams/team/team-members-views/user-team-card/index.tsx
(7 hunks)apps/web/core/components/tasks/daily-plan/past-tasks.tsx
(2 hunks)apps/web/core/components/tasks/kanban-card.tsx
(5 hunks)apps/web/core/components/tasks/kanban.tsx
(14 hunks)apps/web/core/components/tasks/task-block-card.tsx
(5 hunks)apps/web/core/components/tasks/task-times.tsx
(2 hunks)apps/web/core/components/timer/timer-status.tsx
(3 hunks)apps/web/core/components/users/user-nav-menu.tsx
(10 hunks)apps/web/core/components/users/user-profile-plans.tsx
(12 hunks)apps/web/core/constants/config/constants.tsx
(1 hunks)apps/web/core/hooks/activities/use-report-activity.ts
(1 hunks)apps/web/styles/globals.css
(1 hunks)
💤 Files with no reviewable changes (2)
- apps/web/core/components/common/skeleton/task-timer-section-skeleton.tsx
- apps/web/core/components/common/skeleton/auth-user-task-input-skeleton.tsx
🧰 Additional context used
🪛 GitHub Actions: Knip Review - Cleanup Unused Code - WEB
apps/web/core/constants/config/constants.tsx
[error] 1-1: Unused code detected in this file.
apps/web/core/hooks/activities/use-report-activity.ts
[error] 1-1: Unused code detected in this file.
apps/web/core/components/icons/icons.tsx
[error] 1-1: Unused code detected in this file.
apps/web/core/components/common/skeleton/kanban-filters-skeleton.tsx
[error] 1-1: Unused code detected in this file.
apps/web/core/components/tasks/kanban-card.tsx
[error] 1-1: Unused code detected in this file.
apps/web/core/components/tasks/kanban.tsx
[error] 1-1: Unused code detected in this file.
apps/web/core/components/timer/timer-status.tsx
[error] 1-1: Unused code detected in this file.
apps/web/core/components/common/skeleton/kanban-card-skeleton.tsx
[error] 1-1: Unused code detected in this file.
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: deploy
🔇 Additional comments (74)
apps/web/core/components/pages/profile/screenshots/screenshoots-per-hour-skeleton.tsx (1)
31-31
: Minor spacing adjustment approved.The bottom margin on the
<p>
element has been fine-tuned frommb-6
tomb-5
to align with surrounding components.apps/web/core/components/pages/profile/user-profile-tasks.tsx (1)
59-59
: Margin-top refinement is consistent.Updating the container’s
mt-12
tomt-5
reduces vertical spacing to match other UI tweaks in this PR.apps/web/core/components/common/skeleton/dashboard-header-skeleton.tsx (1)
1-17
: Dashboard header skeleton implemented correctly.The new
DashboardHeaderSkeleton
provides a clear loading fallback for the lazy-loaded header. Layout, classes, and structure align with existing skeleton patterns.apps/web/core/components/common/skeleton/export-pdf-skeleton.tsx (1)
1-13
: PDF export skeleton looks good.
ExportPDFSkeleton
offers a simple, centered loading UI for PDF export actions, consistent with design guidelines.apps/web/core/components/tasks/daily-plan/past-tasks.tsx (2)
71-72
: LGTM: Class ordering consistency improvementThe reordering of CSS classes maintains consistent styling patterns across the codebase without affecting functionality.
103-105
: Enhanced drag state visual feedbackGood improvement to the droppable container styling. The explicit border color definitions provide clearer visual feedback during drag operations.
apps/web/core/components/pages/teams/team/team-members-views/user-team-card/index.tsx (2)
150-157
: Excellent performance optimization with proper memoizationGood use of
useMemo
to optimize expensive boolean calculations. The dependency arrays are correctly configured to ensure the memoized values update when the underlying data changes.
179-184
: Consistent usage of memoized values and cn utilityThe implementation correctly uses the memoized values throughout the component and the
cn
utility for conditional class application, maintaining the same functionality while improving performance.Also applies to: 196-196, 203-203, 277-277, 301-301
apps/web/core/components/common/skeleton/chart-skeleton.tsx (1)
1-47
: Comprehensive and well-designed chart skeleton componentExcellent implementation that covers all typical chart elements including controls, axis labels, data points, and legend. The skeleton provides realistic visual feedback during chart loading with proper dark mode support and animations.
apps/web/core/components/users/user-profile-plans.tsx (2)
187-187
: CSS class ordering consistency improvementsThe reordering of CSS classes throughout the component maintains consistent styling patterns across the codebase. These changes improve code maintainability without affecting functionality.
Also applies to: 234-234, 273-273, 276-276, 406-407, 435-435, 439-441, 565-565, 609-609, 618-618, 629-629, 633-633, 637-637, 649-649, 660-660
559-559
: Minor spacing adjustment in PlanHeaderThe margin change from
mb-6
tomb-5
provides slightly tighter spacing that aligns with the overall design improvements.apps/web/core/components/pages/kanban/team-members-kanban-view.tsx (1)
251-251
: LGTM! Supporting enhanced loading states.The addition of
allColumnsData={items}
prop toKanbanDraggable
aligns well with the PR's objective to improve loading states and skeleton animations. This provides the component with access to all column data to make informed decisions about when to display loading skeletons versus empty states.apps/web/styles/globals.css (1)
774-781
: Excellent refactoring! Centralizing shimmer animation.Moving the shimmer animation to global CSS is a great improvement for maintainability. This eliminates duplication across skeleton components and ensures consistent shimmer effects throughout the application.
apps/web/core/components/common/skeleton/no-team-skeleton.tsx (1)
18-18
: LGTM! Improved spacing consistency.The margin reduction from
mb-6
tomb-5
on the icon and description skeleton elements provides better visual hierarchy and aligns with the overall spacing improvements across the application's skeleton components.Also applies to: 25-25
apps/web/core/components/pages/dashboard/app-url/productivity-header.tsx (1)
5-5
: Good type flexibility improvement.Changing the
year
prop type tonumber | string
provides better flexibility for handling different data formats, particularly useful for the enhanced PDF export functionality mentioned in the PR objectives. The component logic remains unchanged while becoming more permissive.apps/web/core/components/icons/icons.tsx (1)
637-648
: ```shell
#!/bin/bashBroad search for any reference to OnlineIcon across the repository
echo "Searching for any usage or import of OnlineIcon..."
rg -i "OnlineIcon" -A2 -B2Also specifically check TSX files
echo "Searching for OnlineIcon in TSX files..."
rg -i "OnlineIcon" -g "*.tsx" -A2 -B2 || true</details> <details> <summary>apps/web/core/components/common/data-table.tsx (1)</summary> `70-70`: **LGTM! Good styling refinements.** The CSS class reordering, margin reduction from `mt-8` to `mt-5`, and removal of duplicate `divide-y` classes improve visual consistency and code cleanliness. These changes align well with the UI improvements mentioned in the PR objectives. Also applies to: 103-103, 106-106 </details> <details> <summary>apps/web/core/components/pages/dashboard/team-dashboard/team-stats-grid.tsx (2)</summary> `9-9`: **Good addition of skeleton loading component.** The import of `StatsCardSkeleton` supports the improved loading experience mentioned in the PR objectives. --- `88-90`: **Excellent improvement to loading UX.** Rendering the `StatsCardSkeleton` for the entire grid provides a better loading experience than individual card loaders. </details> <details> <summary>apps/web/core/hooks/activities/use-report-activity.ts (2)</summary> `324-324`: **Excellent type safety improvement.** Adding the `Array.isArray()` check ensures `activityReport` is always an array, preventing potential runtime errors when the API response is malformed or unexpected. This aligns well with the broader data handling improvements mentioned in the PR objectives for PDF export functionality. --- `1-1`: ```shell #!/bin/bash # Check usage of imported symbols excluding import statements file="apps/web/core/hooks/activities/use-report-activity.ts" symbols=(useCallback useEffect useState useMemo useQuery useAtom useTimelogFilterOptions activityService statisticsService timeLogService useAuthenticateUser ETimeLogType queryKeys ITimeLogReportDailyChartProps) for s in "${symbols[@]}"; do echo -n "$s: " # List usages excluding the import lines usages=$(grep -E -n "\b$s\b" "$file" | grep -v "^import") if [ -z "$usages" ]; then echo "none" else echo "$usages" fi done
apps/web/core/components/pages/dashboard/team-dashboard/lazy-components.tsx (1)
1-13
: Excellent lazy loading implementation.This component perfectly aligns with the PR objectives of improving dashboard performance and loading states. The implementation follows Next.js best practices:
- Proper dynamic import with destructured default export
- SSR disabled for client-dependent dashboard components
- Skeleton loading fallback for better UX during code splitting
The lazy loading will reduce initial bundle size and improve page load performance.
apps/web/core/components/common/skeleton/productivity-skeletons.tsx (1)
1-5
: Good centralization of skeleton exports.This barrel export file provides a clean way to import related productivity skeleton components from a single location. The structure aligns well with the PR's goal of adding 16+ loading animations across the application.
apps/web/app/[locale]/(main)/settings/personal/page.tsx (1)
32-68
: LGTM! Consistent lazy loading implementationThe lazy loading pattern is implemented consistently across all components with appropriate skeleton fallbacks. The ProfileAvatar component correctly includes a custom loading placeholder since it's not wrapped in Suspense.
apps/web/core/components/common/skeleton/personal-setting-form-skeleton.tsx (1)
1-62
: Excellent skeleton implementationThe PersonalSettingFormSkeleton component is well-structured with logical sections that mirror the actual form layout. The consistent use of styling classes, proper dark mode support, and appropriate spacing make this a high-quality loading placeholder.
apps/web/core/components/common/skeleton/stats-card-skeleton.tsx (2)
65-81
: Well-designed skeleton grid layoutThe StatsCardSkeleton component effectively composes multiple skeleton cards with varied configurations. The grid layout and different progress bar colors create a realistic loading preview.
9-64
: Sophisticated skeleton implementation with shimmer effectsThe StatCardSkeleton implementation is excellent with advanced shimmer animations and proper TypeScript interfaces. The shimmer effect adds professional visual polish to the loading state.
Ensure the
shimmer
animation is properly defined in the global CSS file:#!/bin/bash # Description: Verify shimmer animation is defined in global CSS # Search for shimmer keyframe definition rg -A 10 "@keyframes shimmer" apps/web/styles/apps/web/core/components/tasks/kanban-card.tsx (2)
22-51
: Excellent lazy loading implementationThe dynamic import pattern is consistently implemented across all components with appropriate loading placeholders. The
ssr: false
configuration is correct for these UI-heavy components, and the simple skeleton placeholders provide good visual feedback during loading.
221-303
: LGTM! Proper usage of lazy componentsThe lazy components are correctly integrated into the JSX with the same props and behavior as the original static imports. The conversion maintains all existing functionality while improving performance through code splitting.
apps/web/core/components/tasks/task-block-card.tsx (3)
80-80
: LGTM! Border addition improves visual definition.The addition of the border enhances the card's visual separation and aligns with the overall UI improvements mentioned in the PR objectives.
120-136
: Good text overflow handling improvements.The changes to constrain width and improve text wrapping are well-implemented. The use of
text-ellipsis
withoverflow-hidden
and the structured span elements for task number and title provide better control over text display.
150-166
: Approve flex container improvements.The addition of
gap-2
anditems-center
classes improves the layout consistency and spacing of the timer display elements.apps/web/core/components/common/skeleton/settings-personal-skeleton.tsx (1)
29-170
: LGTM! CSS class reordering improves consistency.The systematic reordering of CSS classes in flex containers enhances code consistency and readability without affecting functionality.
apps/web/core/components/common/skeleton/kanban-filters-skeleton.tsx (1)
1-42
: Well-implemented skeleton component with unused code concern.The component is excellently structured with:
- Proper TypeScript interface
- Comprehensive filter placeholders
- Good dark/light theme support
- Consistent animation usage
However, the pipeline failure indicates unused code. Please ensure this component is properly imported and used in the kanban page.
#!/bin/bash # Description: Check if KanbanFiltersSkeleton is being used in the codebase # Expected: Find imports and usage of this component echo "Searching for KanbanFiltersSkeleton usage..." rg -A 3 -B 3 "KanbanFiltersSkeleton" echo -e "\nSearching for imports of kanban-filters-skeleton..." rg -A 2 -B 2 "kanban-filters-skeleton"apps/web/core/components/common/skeleton/kanban-column-loading-skeleton.tsx (1)
1-33
: Excellent skeleton component implementation.The component demonstrates excellent practices:
- Loading spinner with proper animation
- Comprehensive placeholder content representing the actual UI structure
- Consistent dark/light theme support
- Well-structured TypeScript interface
- Proper use of Tailwind classes for animations and responsive design
The component effectively mimics the actual kanban column structure during loading states.
apps/web/core/components/pages/dashboard/app-url/productivity-application/productivity-application-pdf.tsx (3)
19-19
: Good font change for PDF compatibility.Switching from Inter to Helvetica for PDF rendering is a good choice as Helvetica is more universally supported in PDF generation.
117-144
: Excellent empty data handling implementation.The comprehensive empty data handling prevents crashes and provides meaningful user feedback. The fallback UI with proper headers and "No Data Available" message maintains a professional appearance even when data is missing.
149-171
: Outstanding defensive programming practices.The defensive checks for nested properties (
dayData?.employees
,Array.isArray()
checks,activity?.title
) prevent runtime errors when data structure is unexpected or malformed. This robust approach significantly improves the reliability of PDF generation.apps/web/core/components/common/skeleton/team-stats-table-skeleton.tsx (1)
1-84
: LGTM! Well-structured skeleton component.The skeleton component is well-implemented with proper TypeScript interface, consistent dark mode support, and semantic table structure. The layout effectively mimics a real team stats table with appropriate placeholders.
apps/web/core/components/common/skeleton/kanban-card-skeleton.tsx (1)
1-68
: The previous search failed due to unsupported file-type filters. Let’s retry across all files:#!/bin/bash # Search for any references to KanbanCardSkeleton in the repo rg "KanbanCardSkeleton" -n .apps/web/core/components/pages/dashboard/app-url/productivity-pdf.tsx (1)
225-255
: Excellent error handling for empty data.The implementation properly handles empty or invalid data by providing a clear "No Data Available" message and maintaining the PDF structure. This prevents crashes and provides good user feedback.
apps/web/core/components/common/skeleton/productivity-project-table-skeleton.tsx (1)
1-111
: LGTM! Comprehensive skeleton with proper internationalization.The skeleton component effectively mimics the hierarchical structure of a productivity project table with proper nesting of project groups, date groups, and activity rows. The use of translations and consistent styling patterns are well-implemented.
apps/web/app/[locale]/(main)/dashboard/team-dashboard/[teamId]/page.tsx (2)
21-42
: Excellent lazy loading implementation for performance optimization.The dynamic imports with proper loading states and SSR configuration are well-implemented. Disabling SSR for the chart component is appropriate given that charts often have client-side dependencies.
155-159
: Proper Suspense integration with skeleton fallback.The Suspense wrapper with TeamStatsTableSkeleton provides a smooth loading experience while the table component loads asynchronously.
apps/web/core/components/pages/dashboard/team-dashboard/team-stats-table.tsx (3)
12-20
: LGTM! Clean lazy loading implementation with proper pattern.The dynamic import for
ActivityModal
follows best practices by using Next.js dynamic imports with SSR disabled. The comment referencing "Medium article pattern" is helpful for understanding the approach.
26-39
: Well-implemented lazy loading with custom skeleton fallback.The
LazyAnimatedEmptyState
implementation is excellent:
- Uses appropriate skeleton dimensions that match the final content
- Provides proper dark mode support
- Maintains consistent loading experience
170-174
: Proper Suspense boundary implementation.The conditional rendering of the modal with Suspense wrapper is correctly implemented:
- Only renders when
employeeLog
exists- Uses appropriate
ModalSkeleton
fallback- Maintains the existing modal functionality
apps/web/core/components/common/skeleton/productivity-application-table-skeleton.tsx (4)
7-9
: Simple and effective interface design.The props interface is clean and minimal, accepting only an optional
className
for styling customization. This follows good component design principles.
11-27
: Excellent skeleton table structure with proper internationalization.The component effectively uses:
useTranslations
for localized table headers- Proper table structure with semantic HTML
- Consistent styling with theme support
30-69
: Well-structured skeleton data simulation.The nested loops effectively simulate the grouped application data structure:
- 3 application groups with header rows
- 5 activity rows per group
- Proper skeleton placeholders for avatars, text, and progress indicators
- Consistent spacing and alignment
73-87
: Comprehensive pagination skeleton.The pagination skeleton includes all necessary elements:
- Navigation controls
- Page indicators
- Consistent spacing and alignment
- Proper dark mode support
apps/web/core/components/pages/dashboard/dashboard-header.tsx (4)
6-16
: Proper lazy loading implementation for GroupBySelectTimeActivity.The dynamic import follows best practices:
- Uses Next.js dynamic imports
- SSR disabled for performance
- Appropriate loading skeleton with matching dimensions
- Clear comment explaining the optimization
25-49
: Excellent lazy loading pattern for multiple components.All lazy-loaded components follow consistent patterns:
- DateRangePicker, TeamDashboardFilter, and ExportDialog properly configured
- Appropriate loading skeletons with matching dimensions
- SSR disabled where appropriate
- Good comment explaining conditional component pattern
105-117
: Proper conditional Suspense boundary for ExportDialog.The modal rendering is correctly implemented:
- Only renders when
isOpen
is true- Uses appropriate
ModalSkeleton
fallback- Passes all required props to the lazy component
132-140
: Effective Suspense usage for PDF generation.The TeamStatsPDF component is properly wrapped in Suspense with an appropriate fallback skeleton, which is important for PDF generation that can be computationally expensive.
apps/web/core/components/pages/dashboard/export-menu.tsx (3)
9-16
: Good addition of Suspense and proper imports.The imports are well-organized and include the necessary components for the refactored dropdown implementation.
72-117
: Excellent dropdown refactoring with improved UX.The component has been successfully refactored with several improvements:
- Custom DropdownMenu replaces @headlessui/react dependency
- Suspense wrapper for PDF export provides better loading feedback
- Proper conditional rendering based on
showModal
prop- Enhanced accessibility with proper ARIA attributes
- Disabled state handling for CSV export
87-103
: Proper Suspense implementation for PDF export.The PDF export is correctly wrapped in Suspense:
- Uses
ExportPDFSkeleton
as fallback- Provides loading state feedback
- Maintains existing PDF generation functionality
apps/web/core/components/common/skeleton/productivity-table-skeleton.tsx (4)
6-8
: Clean and minimal props interface.The interface follows good component design principles with only the necessary
className
prop for customization.
10-49
: Excellent table header skeleton structure.The header implementation is well-designed:
- Proper table structure with semantic HTML
- Consistent skeleton placeholders for sortable headers
- Good use of flexbox for alignment
- Appropriate skeleton dimensions
52-95
: Comprehensive table body skeleton simulation.The table body effectively simulates the real data structure:
- 3 date groups with proper header rows
- 4 employee activity rows per group
- Consistent skeleton placeholders for all data types
- Proper spacing and alignment
- Good use of Fragment for grouping
98-113
: Complete pagination skeleton implementation.The pagination skeleton includes all necessary elements:
- Navigation controls
- Page indicators
- Consistent spacing and layout
- Proper dark mode support
apps/web/core/components/common/skeleton/accordion-content-skeleton.tsx (1)
1-77
: Well-implemented skeleton component!The component is well-structured with clear separation of concerns for each skeleton type. The TypeScript interface is properly defined, and the implementation follows React best practices.
apps/web/core/components/common/skeleton/productivity-employee-table-skeleton.tsx (1)
85-102
: Good implementation of pagination skeleton!The pagination skeleton properly represents the expected layout with appropriate placeholder elements for page controls and information.
apps/web/core/components/users/user-nav-menu.tsx (1)
62-65
: Good CSS class refactoring!The refactoring improves code consistency by:
- Using
size-*
utility classes instead of separate width/height classes- Logically grouping related classes (flex, positioning, styling)
- Following Tailwind CSS best practices
These changes enhance readability without affecting functionality.
Also applies to: 81-81, 86-86, 90-90, 122-127, 168-176
apps/web/app/[locale]/(main)/kanban/page.tsx (1)
22-117
: Excellent implementation of lazy loading and code-splitting!The dynamic imports with loading skeletons significantly improve the initial page load performance. The Suspense boundary for the modal is properly implemented, and the loading states provide good user feedback.
Also applies to: 466-470
apps/web/core/components/pages/dashboard/export-dialog.tsx (2)
53-69
: Excellent error handling and data validation!The implementation properly handles edge cases:
- Allows export of empty datasets (good UX)
- Prevents errors with invalid data formats
- Provides clear user feedback for all states
- Uses safe fallbacks for PDF components
This effectively addresses the PDF export errors mentioned in the PR objectives.
Also applies to: 78-79, 85-86
139-139
: Good defensive programming for closeModal!The fallback to empty function prevents potential runtime errors if onClose is undefined.
apps/web/app/[locale]/(main)/dashboard/app-url/[teamId]/page.tsx (2)
38-47
: Good implementation of lazy loading for the chart component.The dynamic import with SSR disabled and skeleton fallback is well-implemented for improving initial page load performance.
233-259
: Well-structured refactoring with proper loading states.The groupByMap implementation with Suspense boundaries and appropriate skeleton fallbacks improves code maintainability and user experience.
apps/web/core/components/timer/timer-status.tsx (2)
21-41
: Excellent refactoring using mapping objects.The centralized status mappings improve maintainability and make the component more readable. The separation of concerns (styles, icons, tooltips) is well-structured.
1-1
: I’ll broaden the search to include all.ts
and.tsx
files and drop the unrecognized type filter:#!/bin/bash # Search all .ts/.tsx files for TimerStatus (excluding its own file) echo "🔍 TimerStatus usages (excluding timer-status.tsx):" rg -n "TimerStatus" -g "*.ts*" | grep -v "timer-status.tsx" || echo "— none found —" echo -e "\n🔍 getTimerStatusValue usages (excluding timer-status.tsx):" rg -n "getTimerStatusValue" -g "*.ts*" | grep -v "timer-status.tsx" || echo "— none found —" echo -e "\n🔍 getTimerStatusValueWithValidation usages (excluding timer-status.tsx):" rg -n "getTimerStatusValueWithValidation" -g "*.ts*" | grep -v "timer-status.tsx" || echo "— none found —"apps/web/core/components/tasks/kanban.tsx (2)
34-44
: Good implementation of unified loading states.The approach of removing individual loading props and relying on Suspense fallbacks prevents double loading states and provides a consistent UX.
1-1
: ```shell
#!/bin/bashCheck for ThreeDotIcon usage in kanban.tsx
rg -n "ThreeDotIcon" apps/web/core/components/tasks/kanban.tsx || true
</details> </blockquote></details> </details> <!-- This is an auto-generated comment by CodeRabbit for review status -->
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Improve Kanban and Dashboard performances and fix PDF Export and Loading Skeletons
What was done?
Improved the user experience across multiple pages by adding smooth loading animations and fixing broken features.
Main improvements
Kanban Board
Dashboards
Loading Experience
Settings & Profile Pages
Files changed
What users will notice
Before
After
How to test
Type of changes
Ready for review
ever-teams-update.mp4
Summary by CodeRabbit
New Features
Improvements
Bug Fixes
Style
Chores
Documentation