-
Notifications
You must be signed in to change notification settings - Fork 74
[Feat]: time and activity #3635
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
Conversation
- Add new time and activity tracking page component - Implement basic page structure and routing - Set up component organization for time tracking feature
- Rename components for better clarity (TimeAndActivity, TimectivityComponents) - Update sidebar navigation path for time and activity - Add new group by options (daily, weekly, member) - Create time activity header and group select components - Implement card layout with header section - Update breadcrumb navigation
- Create new date range picker component for time activity - Setup component structure for time activity header - Add index file for time activity components
- Create new ViewSelect component for controlling column visibility - Add checkbox options for Member, Project, Task, Tracked Hours, Earnings, and Activity Level - Update date range picker with All Times option - Improve styling and layout of dropdown menu
Warning Rate limit exceeded@Innocent-Akim has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 14 minutes and 23 seconds before requesting another review. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the 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. 📒 Files selected for processing (4)
WalkthroughThis pull request introduces several new UI components for the time and activity section of the web application. It adds interactive features such as view selection with checkboxes, a date range picker with a calendar and predefined ranges, grouping options for activity data, and statistical cards with progress indicators. Additionally, the routing for the “TIME AND ACTIVITY” sidebar item has been updated, and type definitions have been extended for more granular reporting. These changes are organized and exported via an index file to streamline modular usage. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant ViewSelect
participant State
User->>ViewSelect: Click "View" button
ViewSelect->>ViewSelect: Open dropdown menu
User->>ViewSelect: Toggle a checkbox option
ViewSelect->>State: Update viewOptions state
ViewSelect-->>User: Rerender with updated options
sequenceDiagram
participant User
participant DateRangePicker
participant CalendarPopover
participant State
User->>DateRangePicker: Click date picker button
DateRangePicker->>CalendarPopover: Display calendar with predefined ranges
User->>CalendarPopover: Select desired date range
DateRangePicker->>State: Update selected date range and displayed month
DateRangePicker-->>User: Show formatted date range
Possibly related PRs
Suggested labels
Suggested reviewers
Poem
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:
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 (
|
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 (1)
apps/web/app/hooks/features/useReportActivity.ts (1)
268-269
: 💡 Verification agent🧩 Analysis chain
Update the conditional check to include new GroupByType values
The
handleGroupByChange
function only handles the 'application' special case, but with the new types added ('daily', 'weekly', 'member'), you may need to update this logic to ensure proper handling of all types.
🏁 Script executed:
#!/bin/bash # Check where handleGroupByChange is called to understand the impact of new types # Search for usages of handleGroupByChange rg -A 2 "handleGroupByChange" --type tsx --type ts # Search for places using GroupByType to see if they handle all cases rg -A 5 "GroupByType" --type tsx --type tsLength of output: 149
I'll re-run the verification search using file pattern filters instead of file type flags to gather more meaningful output. Please execute the script below:
Once we have the updated results, we can assess whether the new GroupByType values ('daily', 'weekly', 'member') are being handled correctly, or if the conditional needs to be updated further.
🏁 Script executed:
#!/bin/bash # Re-run search for references to 'handleGroupByChange' and 'GroupByType' using glob patterns for .ts and .tsx files echo "Searching for references to handleGroupByChange:" rg "handleGroupByChange" -g "*.ts" -g "*.tsx" echo "---" echo "Searching for references to GroupByType:" rg "GroupByType" -g "*.ts" -g "*.tsx"Length of output: 2583
Action Required: Update mapping logic for new GroupByType values
The current implementation only remaps
'application'
to'date'
and passes through all other values unchanged. Since the enum now also includes'daily'
,'weekly'
, and'member'
, you should update the conditional logic to handle these cases appropriately. For example, if'daily'
should also map to'date'
, or if'weekly'
and'member'
require their own specific mappings (possibly to'week'
or'employee'
), refactor this section—potentially using a switch or mapping object—to cover all valid types.
- Location:
apps/web/app/hooks/features/useReportActivity.ts
(lines 268–269)- Suggestion: Replace the existing ternary with logic that explicitly maps each GroupByType value to the intended group value before calling
fetchActivityReport
.
🧹 Nitpick comments (11)
apps/web/app/[locale]/time-and-activity/page.tsx (1)
1-8
: Consider renaming the component for better clarity and to resolve spelling issuesThe component name "TimectivityComponents" is flagged as an unknown word by the static analysis tools. This appears to be a portmanteau of "Time" and "Activity", but may cause confusion for other developers.
-import TimectivityComponents from './Components/page-component' +import TimeActivityComponents from './Components/page-component' function TimeAndActivity() { - return (<TimectivityComponents/> ) + return (<TimeActivityComponents />) } export default TimeAndActivityAdditionally, you'll need to update the component name in the page-component.tsx file.
🧰 Tools
🪛 GitHub Check: Cspell
[warning] 2-2:
Unknown word (Timectivity)
[warning] 5-5:
Unknown word (Timectivity)🪛 GitHub Actions: Check Spelling and Typos with cspell
[warning] 2-2: Unknown word (Timectivity)
[warning] 5-5: Unknown word (Timectivity)
apps/web/app/hooks/features/useReportActivity.ts (1)
70-70
: Improve type definition formatting for better readabilityThe
GroupByType
type definition has been expanded with new options but lacks consistent spacing between options.-export type GroupByType = 'date' | 'project' | 'employee' | 'application'|'daily'|'weekly'|'member'; +export type GroupByType = 'date' | 'project' | 'employee' | 'application' | 'daily' | 'weekly' | 'member';apps/web/app/[locale]/time-and-activity/Components/GroupBySelect.tsx (2)
13-13
: Consider using controlled component pattern for better state managementThe component uses
defaultValue
which won't react to changes in thegroupByType
prop after initial render. For a more reactive component, consider usingvalue
instead ofdefaultValue
.- <Select defaultValue={groupByType} onValueChange={onGroupByChange}> + <Select value={groupByType} onValueChange={onGroupByChange}>This change ensures the component will always reflect the current value from props.
6-9
: Enhance prop interface with default valuesThe component accepts
groupByType
but doesn't specify a default value when not provided. Consider adding a default value to avoid undefined behavior.interface GroupBySelectProps { onGroupByChange?: (value: GroupByType) => void; - groupByType?: GroupByType; + groupByType?: GroupByType; } -export function GroupBySelectTimeActivity({ onGroupByChange, groupByType }: GroupBySelectProps) { +export function GroupBySelectTimeActivity({ + onGroupByChange, + groupByType = 'daily' +}: GroupBySelectProps) {apps/web/app/[locale]/time-and-activity/Components/page-component.tsx (2)
27-27
: Use translation for consistency with other breadcrumb itemsThe first breadcrumb title uses translations, but the "Time and Activity" title is hardcoded. For internationalization consistency, consider using the translation function for all UI text.
- { title: 'Time and Activity', href: `/${currentLocale}/time-and-activity` } + { title: JSON.parse(t('pages.timeActivity.BREADCRUMB')), href: `/${currentLocale}/time-and-activity` }Make sure to add the corresponding translation key to your localization files.
54-56
: Missing implementation of time activity UI controlsThe header area inside the Card (with h-[105px] height) is empty. This appears to be where the time period selector and grouping controls should be placed.
It appears that there's a missing implementation of the UI controls for time activity tracking. Would you like me to provide a suggestion for implementing this section using the GroupBySelectTimeActivity component and other necessary controls?
apps/web/app/[locale]/time-and-activity/Components/ViewSelect.tsx (3)
1-79
: Component implementation looks good but could benefit from internationalization improvements.The ViewSelect component is well-structured with proper state management, but the hardcoded English labels should use translations for consistency.
You're already importing the translation hook but not using it for the labels. Consider updating the labels to use translations:
- { id: 'member', label: 'Member', checked: true }, - { id: 'project', label: 'Project', checked: true }, - { id: 'task', label: 'Task', checked: true }, - { id: 'trackedHours', label: 'Tracked Hours', checked: true }, - { id: 'earnings', label: 'Earnings', checked: true }, - { id: 'activityLevel', label: 'Activity Level', checked: true }, + { id: 'member', label: t('timeActivity.MEMBER'), checked: true }, + { id: 'project', label: t('timeActivity.PROJECT'), checked: true }, + { id: 'task', label: t('timeActivity.TASK'), checked: true }, + { id: 'trackedHours', label: t('timeActivity.TRACKED_HOURS'), checked: true }, + { id: 'earnings', label: t('timeActivity.EARNINGS'), checked: true }, + { id: 'activityLevel', label: t('timeActivity.ACTIVITY_LEVEL'), checked: true },Also on line 57, replace:
- View + {t('timeActivity.VIEW')}
36-78
: Consider adding props to make the component more reusable.The component doesn't expose any way to control or read the selected view options from outside, limiting its reusability.
Consider adding props to make the component more flexible:
+ interface ViewSelectProps { + defaultOptions?: ViewOption[]; + onChange?: (options: ViewOption[]) => void; + } + - export default function ViewSelect() { + export default function ViewSelect({ defaultOptions, onChange }: ViewSelectProps = {}) { const t = useTranslations(); - const [viewOptions, setViewOptions] = React.useState<ViewOption[]>([ + const defaultViewOptions = [ { id: 'member', label: 'Member', checked: true }, { id: 'project', label: 'Project', checked: true }, { id: 'task', label: 'Task', checked: true }, { id: 'trackedHours', label: 'Tracked Hours', checked: true }, { id: 'earnings', label: 'Earnings', checked: true }, { id: 'activityLevel', label: 'Activity Level', checked: true }, - ]); + ]; + const [viewOptions, setViewOptions] = React.useState<ViewOption[]>(defaultOptions || defaultViewOptions); const handleCheckChange = (id: string) => { - setViewOptions(prev => - prev.map(option => + setViewOptions(prev => { + const newOptions = prev.map(option => option.id === id ? { ...option, checked: !option.checked } : option - ) - ); + ); + onChange?.(newOptions); + return newOptions; + }); };
41-57
: Extract SVG icon to a separate component.Consider extracting the SVG icon into a separate component for better maintainability and reusability.
+// In a separate file or at the top of this file +const ViewIcon = ({ className }: { className?: string }) => ( + <svg + width="24" + height="24" + viewBox="0 0 24 24" + fill="none" + xmlns="http://www.w3.org/2000/svg" + className={className} + > + <path + d="M4 5C4 4.44772 4.44772 4 5 4H19C19.5523 4 20 4.44772 20 5V7C20 7.55228 19.5523 8 19 8H5C4.44772 8 4 7.55228 4 7V5Z" + className="fill-current" + /> + <path + d="M4 13C4 12.4477 4.44772 12 5 12H19C19.5523 12 20 12.4477 20 13V15C20 15.5523 19.5523 16 19 16H5C4.44772 16 4 15.5523 4 15V13Z" + className="fill-current" + /> + </svg> +); // Then in your Button: <Button variant="outline" className="gap-2"> - <svg - width="24" - height="24" - viewBox="0 0 24 24" - fill="none" - xmlns="http://www.w3.org/2000/svg" - className="w-4 h-4" - > - <path - d="M4 5C4 4.44772 4.44772 4 5 4H19C19.5523 4 20 4.44772 20 5V7C20 7.55228 19.5523 8 19 8H5C4.44772 8 4 7.55228 4 7V5Z" - className="fill-current" - /> - <path - d="M4 13C4 12.4477 4.44772 12 5 12H19C19.5523 12 20 12.4477 20 13V15C20 15.5523 19.5523 16 19 16H5C4.44772 16 4 15.5523 4 15V13Z" - className="fill-current" - /> - </svg> + <ViewIcon className="w-4 h-4" /> View </Button>apps/web/app/[locale]/time-and-activity/Components/date-range-picker-time-activity.tsx (2)
3-31
: Inconsistent indentation style.The file uses a mix of tabs and spaces for indentation, which can lead to formatting inconsistencies.
Consider standardizing on a single indentation style throughout the file (either tabs or spaces, but not both).
For example, lines 8-25 use tabs, while other parts of the file might be using spaces.
109-111
: Multiple stopPropagation calls may indicate underlying event handling issues.The component uses three separate event stopPropagation calls which might indicate an underlying issue with event bubbling.
A single event handler could likely handle all three cases:
- onClick={(e) => e.stopPropagation()} - onMouseDown={(e) => e.stopPropagation()} - onChange={(e) => e.stopPropagation()} + onClick={(e) => e.stopPropagation()} + onMouseDown={(e) => e.stopPropagation()}The
onChange
event on a div is unusual and likely unnecessary since divs don't typically have change events.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (8)
apps/web/app/[locale]/time-and-activity/Components/GroupBySelect.tsx
(1 hunks)apps/web/app/[locale]/time-and-activity/Components/ViewSelect.tsx
(1 hunks)apps/web/app/[locale]/time-and-activity/Components/date-range-picker-time-activity.tsx
(1 hunks)apps/web/app/[locale]/time-and-activity/Components/page-component.tsx
(1 hunks)apps/web/app/[locale]/time-and-activity/Components/time-activity-header.tsx
(1 hunks)apps/web/app/[locale]/time-and-activity/page.tsx
(1 hunks)apps/web/app/hooks/features/useReportActivity.ts
(1 hunks)apps/web/components/app-sidebar.tsx
(2 hunks)
✅ Files skipped from review due to trivial changes (1)
- apps/web/app/[locale]/time-and-activity/Components/time-activity-header.tsx
🧰 Additional context used
🧠 Learnings (1)
apps/web/app/[locale]/time-and-activity/Components/GroupBySelect.tsx (1)
Learnt from: CREDO23
PR: ever-co/ever-teams#3392
File: apps/web/app/[locale]/reports/weekly-limit/components/group-by-select.tsx:42-51
Timestamp: 2024-12-05T09:04:08.049Z
Learning: In the `GroupBySelect` component (`apps/web/app/[locale]/reports/weekly-limit/components/group-by-select.tsx`), only one option can be selected at a time; two options cannot be selected simultaneously.
🪛 GitHub Check: Cspell
apps/web/app/[locale]/time-and-activity/Components/page-component.tsx
[warning] 16-16:
Unknown word (Timectivity)
[warning] 70-70:
Unknown word (Timectivity)
apps/web/app/[locale]/time-and-activity/page.tsx
[warning] 2-2:
Unknown word (Timectivity)
[warning] 5-5:
Unknown word (Timectivity)
🪛 GitHub Actions: Check Spelling and Typos with cspell
apps/web/app/[locale]/time-and-activity/Components/page-component.tsx
[warning] 16-16: Unknown word (Timectivity)
[warning] 70-70: Unknown word (Timectivity)
apps/web/app/[locale]/time-and-activity/page.tsx
[warning] 2-2: Unknown word (Timectivity)
[warning] 5-5: Unknown word (Timectivity)
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: deploy
🔇 Additional comments (5)
apps/web/app/[locale]/time-and-activity/Components/GroupBySelect.tsx (1)
21-24
:❓ Verification inconclusive
Ensure consistency with GroupByType values
While you've added "daily", "weekly", and "member" to the GroupByType in useReportActivity.ts, the select includes "project" but not other original values like "date", "employee", and "application". Ensure the options here align with the intended available values.
🏁 Script executed:
#!/bin/bash # Check other GroupBySelect components for consistency in approach # Search for other GroupBySelect components fd -e tsx -e ts "GroupBySelect" --exec grep -l "SelectItem" {} \; # Check how GroupByType values are used elsewhere rg "'date' | 'project' | 'employee' | 'application'" --type tsx --type ts -A 2 -B 2Length of output: 346
Ensure consistency between GroupBySelect options and GroupByType values
TheGroupBySelect
component inapps/web/app/[locale]/time-and-activity/Components/GroupBySelect.tsx
still includes the"project"
option—even though the updatedGroupByType
inuseReportActivity.ts
now only includes"daily"
,"weekly"
, and"member"
. Additionally, previous options such as"date"
,"employee"
, and"application"
have been removed. Please verify that the options presented in the select element exactly match the intended values defined inGroupByType
and update one or the other accordingly.
- Check the definition of
GroupByType
inuseReportActivity.ts
to confirm which values should be supported.- Adjust the dropdown options in
GroupBySelect.tsx
to mirror those values or update the type if"project"
is intended to be included.apps/web/app/[locale]/time-and-activity/Components/page-component.tsx (1)
52-60
:❓ Verification inconclusive
Implement content within the card component
The Card component contains empty div containers. The implementation appears incomplete as there's no actual content displayed for time activity tracking.
I notice the Card has nested div containers but no actual content is rendered. This component structure seems incomplete:
🏁 Script executed:
#!/bin/bash # Check if there are other components that should be imported here # Look for possible components related to time and activity # Search for components in the same directory fd -e tsx -p "time-and-activity/Components" --exec grep -l "export" {} \; # Look for GroupBySelectTimeActivity usage rg "GroupBySelectTimeActivity" --type tsxLength of output: 522
Attention: Incomplete Card Content Implementation
- The
Card
component inapps/web/app/[locale]/time-and-activity/Components/page-component.tsx
(lines 52-60) still contains empty container elements.- It is unclear whether these divs are simply placeholders or if they should host interactive components—for instance, one of the components available in this directory (such as
GroupBySelect.tsx
,ViewSelect.tsx
,date-range-picker-time-activity.tsx
, ortime-activity-header.tsx
) to provide time activity tracking functionality.- Please verify whether the missing content should involve integrating one or more of these components. If so, update the implementation accordingly; otherwise, remove the unnecessary markup.
apps/web/components/app-sidebar.tsx (2)
225-225
: Reordering CSS classes maintains identical styling.The CSS classes have been reordered but maintain the same styling and functionality. This change is harmless but doesn't provide any functional improvement.
312-312
: Updated URL for time and activity navigation.Good update replacing the placeholder '#' with the actual route '/time-and-activity', enabling proper navigation to the new time and activity feature.
apps/web/app/[locale]/time-and-activity/Components/date-range-picker-time-activity.tsx (1)
129-129
:✅ Verification successful
Calendar disable logic restricts future dates.
The calendar component disables future dates, which is appropriate for time tracking and reporting but should be documented.
🌐 Web query:
Is it a common practice to disable future dates in time tracking applications?
💡 Result:
Disabling future dates in time tracking applications is a practice implemented in some systems, though its prevalence depends on the specific tool and use case. Here’s a breakdown of how this feature is approached across platforms:
Common Use Cases for Disabling Future Dates
- Preventing Inaccurate Entries: Some platforms, like monday.com, restrict future date selections in time tracking columns to avoid premature or speculative logging, ensuring entries reflect actual work hours[4].
- Compliance and Accuracy: Apps like Clockify allow administrators to lock past timesheets but explicitly cannot lock future dates, highlighting a focus on historical accuracy rather than restricting future planning[5].
- Form Validation: In form-building tools like Caspio, disabling future dates in calendars ensures users select valid dates (e.g., preventing return dates earlier than departure dates)[1].
Platform-Specific Implementations
- monday.com: Users have requested future date enablement for tracking planned leave, indicating that the platform currently disables future dates by default in time tracking columns[4].
- Clockify: While past dates can be locked to prevent edits, future dates remain editable, reflecting a balance between accountability and flexibility[5].
- Pega Systems: Developers can disable future dates in DateTime controls via configuration settings, catering to specific business rules[9].
Workarounds and Limitations
- Manual Enforcement: Some tools lack built-in future date restrictions, requiring organizations to enforce policies manually (e.g., rejecting future entries during approvals)[5].
- Technical Customization: Platforms like Caspio and Pega allow custom JavaScript or settings adjustments to disable future dates, but this often requires technical expertise[1][9].
User Needs and Trends
- Employee Autonomy vs. Control: While disabling future dates can reduce errors, overly restrictive systems may hinder flexibility for remote or gig workers[8].
- Emerging Features: Predictive analytics and blockchain-backed timestamping are evolving to enhance accuracy without rigid date restrictions[8].
Key Takeaway
Disabling future dates is common in applications prioritizing data integrity (e.g., project management or compliance tools) but less so in flexible workforce platforms. Organizations often balance this feature with user needs, leveraging technical configurations or policy enforcement where native options are limited[4][5][9].
Citations:
- 1: https://howto.caspio.com/tech-tips-and-articles/disabling-past-or-future-dates-in-calendar/
- 2: https://www.timegram.io/resources/trick-employee-monitoring-software
- 3: https://community.atlassian.com/t5/Jira-questions/How-do-you-deactivate-Time-Tracking/qaq-p/1273114
- 4: https://community.monday.com/t/future-date-selections-available-when-using-time-tracking-column/101662
- 5: https://clockify.me/help/track-time-and-expenses/lock-timesheets
- 6: https://getuku.com/articles/time-tracking-only-wastes-time-in-my-accounting-firm
- 7: https://www.usemotion.com/blog/best-time-blocking-apps
- 8: https://www.nowsta.com/blog/the-future-of-time-tracking-trends-and-predictions/
- 9: https://support.pega.com/question/disable-pastfuture-date-datetime-control-including-days
- 10: http://www.markwk.com/time-tracking-guide.html
Calendar disable logic for future dates is correctly implemented.
The current logic on line 129 in
apps/web/app/[locale]/time-and-activity/Components/date-range-picker-time-activity.tsx
uses a standard approach to disable future dates (i.e., dates equal to or after the start of today). As confirmed by our research, restricting future date selection is a common pattern in time tracking applications to prevent premature or inaccurate time entries. While the implementation is correct, it is recommended to add an inline comment explaining this design choice for improved clarity and maintainability.
apps/web/app/[locale]/time-and-activity/Components/GroupBySelect.tsx
Outdated
Show resolved
Hide resolved
apps/web/app/[locale]/time-and-activity/Components/page-component.tsx
Outdated
Show resolved
Hide resolved
apps/web/app/[locale]/time-and-activity/Components/page-component.tsx
Outdated
Show resolved
Hide resolved
apps/web/app/[locale]/time-and-activity/Components/date-range-picker-time-activity.tsx
Show resolved
Hide resolved
- Update ViewSelect component with custom checkbox style and hover effects - Integrate TimeActivityHeader with export options - Add GroupBySelectTimeActivity component - Update page layout and component organization - Remove unused GroupBySelect component
- Create reusable CardTimeandActivity component with TypeScript support - Add three statistics cards for Total Hours, Average Activity, and Total Earnings - Implement progress bar functionality for activity metrics - Fix code formatting and improve component organization
- Create new reusable ProgressBar component - Update CardTimeandActivity to use the new ProgressBar - Add TypeScript interfaces for better type safety - Improve component modularity and reusability
- Set exact height and colors for progress bar - Update background color to #E4E4E7 - Set progress color to #0088CC - Refine progress bar container styles
- Move weekOptions object into useMemo hook to maintain stable reference - Prevent unnecessary re-renders in predefinedRanges useMemo - Fix React performance warning about object literals in dependencies
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: 5
🧹 Nitpick comments (11)
apps/web/app/[locale]/time-and-activity/Components/time-activity-header.tsx (2)
6-31
: Remove commented code and implement missing functionality.The component looks well-structured, but there's a commented-out line referring to
TeamDashboardFilter
with an undefinedisManage
prop. Also, the Export dropdown doesn't have any functionality implemented - there's no handler for selection changes.- {/* <TeamDashboardFilter isManage={isManage} /> */}
For the export functionality, consider adding an event handler:
- <Select defaultValue="export"> + <Select defaultValue="export" onValueChange={(value) => handleExport(value)}>And add the handler function above the return statement:
const handleExport = (format: string) => { // Implement export functionality based on format console.log(`Exporting in ${format} format`); };
6-6
: Add TypeScript type annotation for the component.The component should have a TypeScript interface or type definition to improve type safety and documentation.
-function TimeActivityHeader() { +interface TimeActivityHeaderProps { + // Add any props the component might need in the future +} + +function TimeActivityHeader({}: TimeActivityHeaderProps) {apps/web/app/[locale]/time-and-activity/Components/progress-bar.tsx (2)
9-26
: Implement progress value validation.While the component works correctly, there's no validation to ensure the progress value stays within the expected 0-100% range. This could lead to visual bugs if an invalid value is passed.
const ProgressBar: React.FC<ProgressBarProps> = ({ progress, color = 'bg-[#0088CC]', isLoading = false, }) => { + // Ensure progress is between 0 and 100 + const validProgress = isLoading ? 0 : Math.min(Math.max(progress, 0), 100); + return ( <div className="mt-4"> <div className="w-full h-1 bg-[#E4E4E7] dark:bg-gray-700 rounded-full overflow-hidden"> <div className={`h-full transition-all duration-300 ${color}`} style={{ - width: `${isLoading ? 0 : progress}%`, + width: `${validProgress}%`, }} /> </div> </div> ); };
16-23
: Consider adding an accessible ARIA attribute for screen readers.For better accessibility, adding an ARIA role and label to the progress bar would be beneficial.
<div className="w-full h-1 bg-[#E4E4E7] dark:bg-gray-700 rounded-full overflow-hidden"> <div + role="progressbar" + aria-valuenow={isLoading ? 0 : progress} + aria-valuemin={0} + aria-valuemax={100} className={`h-full transition-all duration-300 ${color}`} style={{ width: `${isLoading ? 0 : progress}%`, }} /> </div>apps/web/app/[locale]/time-and-activity/Components/card-time-and-activity.tsx (1)
27-33
: Consider adding value formatting.The component accepts both string and number values but doesn't apply any formatting. This could lead to inconsistent display, especially for numerical values.
<span className="text-[32px] leading-[38px] font-semibold text-gray-900 dark:text-white"> - {value} + {typeof value === 'number' ? value.toLocaleString() : value} </span>This would ensure numbers are formatted with appropriate thousands separators according to the user's locale.
apps/web/app/[locale]/time-and-activity/Components/GroupBySelectTimeActivity.tsx (2)
13-13
: Set a default value to prevent undefined selection.The component doesn't specify a default value if
groupByType
is not provided. This could lead to an undefined selection initially.-<Select defaultValue={groupByType} onValueChange={onGroupByChange}> +<Select defaultValue={groupByType || "daily"} onValueChange={onGroupByChange}>
17-17
: Review placeholder text and default value consistency.The SelectValue component has a placeholder "Date" which doesn't align with any of the actual values in the dropdown (daily, weekly, etc.). This might confuse users if they see "Date" without making a selection.
-<SelectValue placeholder="Date" className="text-blue-600 dark:text-blue-500" /> +<SelectValue placeholder="Select grouping" className="text-blue-600 dark:text-blue-500" />apps/web/app/[locale]/time-and-activity/Components/page-component.tsx (2)
28-28
: Use translation for consistency.The breadcrumb title "Time and Activity" should use the translation system for consistency with other translated content.
-{ title: 'Time and Activity', href: `/${currentLocale}/time-and-activity` } +{ title: JSON.parse(t('pages.timeAndActivity.BREADCRUMB')), href: `/${currentLocale}/time-and-activity` }
37-39
: Remove unnecessary!
operator in className.Using the
!important
flag (via the!
prefix in Tailwind) should generally be avoided as it can lead to CSS specificity issues.-className="items-start pb-1 !overflow-hidden w-full" +className="items-start pb-1 overflow-hidden w-full"apps/web/app/[locale]/time-and-activity/Components/ViewSelect.tsx (2)
34-56
: Improve accessibility and add visual indication of selection state.The current implementation lacks proper accessibility attributes and doesn't show how many options are selected.
return ( <DropdownMenu> <DropdownMenuTrigger asChild> - <Button variant="outline" className="gap-2"> + <Button variant="outline" className="gap-2" aria-label="Select view options"> <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" className="w-4 h-4" + aria-hidden="true" > <path d="M4 5C4 4.44772 4.44772 4 5 4H19C19.5523 4 20 4.44772 20 5V7C20 7.55228 19.5523 8 19 8H5C4.44772 8 4 7.55228 4 7V5Z" className="fill-current" /> <path d="M4 13C4 12.4477 4.44772 12 5 12H19C19.5523 12 20 12.4477 20 13V15C20 15.5523 19.5523 16 19 16H5C4.44772 16 4 15.5523 4 15V13Z" className="fill-current" /> </svg> - View + View ({viewOptions.filter(opt => opt.checked).length}/{viewOptions.length}) </Button> </DropdownMenuTrigger>
58-71
: Add "Select All" and "Clear All" functionality.Providing options to select or clear all checkboxes at once improves user experience.
<DropdownMenuContent className="p-2 w-56"> + <div className="flex justify-between mb-2 pb-2 border-b"> + <button + className="text-xs text-blue-600 hover:text-blue-800 dark:text-blue-400 dark:hover:text-blue-300" + onClick={() => { + const allSelected = viewOptions.map(opt => ({ ...opt, checked: true })); + setViewOptions(allSelected); + if (onViewOptionsChange) onViewOptionsChange(allSelected); + }} + > + Select All + </button> + <button + className="text-xs text-blue-600 hover:text-blue-800 dark:text-blue-400 dark:hover:text-blue-300" + onClick={() => { + const noneSelected = viewOptions.map(opt => ({ ...opt, checked: false })); + setViewOptions(noneSelected); + if (onViewOptionsChange) onViewOptionsChange(noneSelected); + }} + > + Clear All + </button> + </div> {viewOptions.map((option) => ( // ... existing code ))} </DropdownMenuContent>
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (7)
apps/web/app/[locale]/time-and-activity/Components/GroupBySelectTimeActivity.tsx
(1 hunks)apps/web/app/[locale]/time-and-activity/Components/ViewSelect.tsx
(1 hunks)apps/web/app/[locale]/time-and-activity/Components/card-time-and-activity.tsx
(1 hunks)apps/web/app/[locale]/time-and-activity/Components/index.tsx
(1 hunks)apps/web/app/[locale]/time-and-activity/Components/page-component.tsx
(1 hunks)apps/web/app/[locale]/time-and-activity/Components/progress-bar.tsx
(1 hunks)apps/web/app/[locale]/time-and-activity/Components/time-activity-header.tsx
(1 hunks)
✅ Files skipped from review due to trivial changes (1)
- apps/web/app/[locale]/time-and-activity/Components/index.tsx
🧰 Additional context used
🪛 GitHub Check: Cspell
apps/web/app/[locale]/time-and-activity/Components/card-time-and-activity.tsx
[warning] 14-14:
Unknown word (Timeand)
[warning] 47-47:
Unknown word (Timeand)
apps/web/app/[locale]/time-and-activity/Components/page-component.tsx
[warning] 15-15:
Unknown word (Timeand)
[warning] 17-17:
Unknown word (Timectivity)
[warning] 55-55:
Unknown word (Timeand)
[warning] 60-60:
Unknown word (Timeand)
[warning] 68-68:
Unknown word (Timeand)
[warning] 82-82:
Unknown word (Timectivity)
🪛 GitHub Actions: Check Spelling and Typos with cspell
apps/web/app/[locale]/time-and-activity/Components/card-time-and-activity.tsx
[warning] 14-14: Unknown word (Timeand)
[warning] 47-47: Unknown word (Timeand)
apps/web/app/[locale]/time-and-activity/Components/page-component.tsx
[warning] 15-15: Unknown word (Timeand)
[warning] 17-17: Unknown word (Timectivity)
[warning] 55-55: Unknown word (Timeand)
[warning] 60-60: Unknown word (Timeand)
[warning] 68-68: Unknown word (Timeand)
[warning] 82-82: Unknown word (Timectivity)
⏰ Context from checks skipped due to timeout of 90000ms (2)
- GitHub Check: Codacy Static Code Analysis
- GitHub Check: deploy
🔇 Additional comments (9)
apps/web/app/[locale]/time-and-activity/Components/time-activity-header.tsx (1)
1-5
: Imports are correctly organized and relevant.The component imports all necessary UI components and related custom components for the time activity header.
apps/web/app/[locale]/time-and-activity/Components/progress-bar.tsx (1)
3-7
: Props interface correctly defines component parameters.The interface clearly defines the expected props with appropriate types.
apps/web/app/[locale]/time-and-activity/Components/card-time-and-activity.tsx (1)
5-12
: The props interface is well-defined and includes all necessary properties.The StatisticCardProps interface properly defines all the required and optional properties with appropriate types.
apps/web/app/[locale]/time-and-activity/Components/GroupBySelectTimeActivity.tsx (3)
6-9
: Props interface is well-defined with optional callbacks.The interface correctly defines optional props with appropriate types.
1-2
: The 'use client' directive is correctly placed.The 'use client' directive is necessary for client-side interactivity and is correctly placed at the top of the file.
21-24
:✅ Verification successful
Verify the data attribute for styling selected items.
The className for SelectItems uses
data-[state=checked]:text-blue-600
, but for SelectItem components, the state is typically "selected", not "checked". Verify that this styling works as intended.
🏁 Script executed:
#!/bin/bash # Look for references to SelectItem with data-[state=...] to verify correct attribute rg -A 2 -B 2 "data-\[state=" --glob "*.tsx" | grep -i "select"Length of output: 3782
Attribute Check: Confirmed Usage of
data-[state=checked]
is IntentionalAfter reviewing similar implementations in the codebase, we found that the
SelectItem
components consistently usedata-[state=checked]:text-blue-600
(e.g., in bothapps/web/app/[locale]/dashboard/app-url/components/GroupBySelect.tsx
andapps/web/app/[locale]/time-and-activity/Components/GroupBySelectTimeActivity.tsx
). This indicates that the use of the "checked" state is intentional in our implementation rather than an oversight.No changes are needed here, but please ensure that any UI tests validate that the styling applies correctly under the expected interactive states.
apps/web/app/[locale]/time-and-activity/Components/page-component.tsx (3)
17-17
: Rename component for consistency and to fix spelling issue.The component name "TimectivityComponents" appears to be a spelling error. It's flagged by cspell checks and doesn't follow conventional naming patterns.
-const TimectivityComponents = () => { +const TimeActivityComponents = () => {🧰 Tools
🪛 GitHub Check: Cspell
[warning] 17-17:
Unknown word (Timectivity)🪛 GitHub Actions: Check Spelling and Typos with cspell
[warning] 17-17: Unknown word (Timectivity)
78-78
: Missing children in MainLayout component.The MainLayout component is closed immediately without any children elements. If this is intentional, consider adding a comment explaining why, otherwise add the expected children.
-</MainLayout> +</MainLayout> +{/* TODO: Add main content here */}
82-82
: Update component name in withAuthentication wrapper.Update the component name in the withAuthentication wrapper to match your component name.
-export default withAuthentication(TimectivityComponents, { displayName: 'Time and Activity' }); +export default withAuthentication(TimeActivityComponents, { displayName: 'Time and Activity' });🧰 Tools
🪛 GitHub Check: Cspell
[warning] 82-82:
Unknown word (Timectivity)🪛 GitHub Actions: Check Spelling and Typos with cspell
[warning] 82-82: Unknown word (Timectivity)
apps/web/app/[locale]/time-and-activity/Components/card-time-and-activity.tsx
Outdated
Show resolved
Hide resolved
apps/web/app/[locale]/time-and-activity/Components/page-component.tsx
Outdated
Show resolved
Hide resolved
apps/web/app/[locale]/time-and-activity/Components/page-component.tsx
Outdated
Show resolved
Hide resolved
- Rename CardTimeandActivity to CardTimeAndActivity - Rename TimectivityComponents to TimeActivityComponents - Fix camelCase naming in imports and usage
- Rename TimectivityComponents import to TimeActivityComponents - Update component usage to match new name
Description
Please include a summary of the changes and the related issues.
Type of Change
Checklist
Previous screenshots
Please add here videos or images of the previous status
Current screenshots
Please add here videos or images of the current (new) status
Summary by CodeRabbit
New Features
Refactor / Style