Skip to content

feat: date range picker for charts#29

Merged
hmbanan666 merged 1 commit into
mainfrom
date-range
Jul 30, 2025
Merged

feat: date range picker for charts#29
hmbanan666 merged 1 commit into
mainfrom
date-range

Conversation

@hmbanan666
Copy link
Copy Markdown
Collaborator

@hmbanan666 hmbanan666 commented Jul 30, 2025

Summary by CodeRabbit

  • New Features

    • Introduced a new date range picker component with support for predefined ranges and a calendar selector, featuring Russian locale formatting.
  • Enhancements

    • Added the date range picker to the kitchen finance page, allowing users to select custom or predefined date ranges.
    • Updated the initial date range on the finance page to the last 14 days for more relevant data selection.
    • Enhanced kitchen revenue charts to display average check values in tooltips and data.
    • Improved kitchen checks chart by refining average calculation and updating tooltip wording for clarity.
  • Style

    • Reduced the height of chart containers for a more compact layout.

@hmbanan666 hmbanan666 self-assigned this Jul 30, 2025
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jul 30, 2025

Walkthrough

A new DateRangePicker Vue component was introduced for date range selection, including predefined ranges and a calendar. Chart components (KitchenChecks, KitchenRevenue) were updated for height, tooltip text, and calculation logic, with KitchenRevenue now supporting an averageCheck field. The kitchen finance page now uses the new date picker and a 14-day default range.

Changes

Cohort / File(s) Change Summary
New Date Range Picker Component
apps/web-app/app/components/DateRangePicker.vue
Added a Vue component for selecting date ranges, supporting both predefined options and manual calendar selection, with Russian date formatting and utility functions for date conversion and range selection.
Kitchen Checks Chart Adjustments
apps/web-app/app/components/chart/KitchenChecks.client.vue
Reduced chart height, improved calculation of the total average check (with zero checks), and updated tooltip label wording.
Kitchen Revenue Chart Enhancements
apps/web-app/app/components/chart/KitchenRevenue.client.vue
Reduced chart height, extended data types and props to include averageCheck, mapped and displayed averageCheck in tooltips, and adjusted data handling accordingly.
Finance Page Integration
apps/web-app/app/pages/kitchen/[id]/finance.vue
Integrated the new DateRangePicker component, changed the default date range to the last 14 days, and optimized date initialization by storing today in a constant.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant DateRangePicker
    participant ChartComponent

    User->>DateRangePicker: Open popover / select date range
    DateRangePicker->>DateRangePicker: Update selected range (predefined or manual)
    DateRangePicker-->>User: Display updated range
    DateRangePicker-->>ChartComponent: Emit new date range
    ChartComponent->>ChartComponent: Fetch and display data for selected range
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~15–20 minutes

Poem

🐇
A picker for dates, so sleek and new,
With charts that show a clearer view.
Numbers checked and averages right,
Tooltips shining with data bright.
Fourteen days to start the dance—
In this garden, reports enhance!
🌱📊

Note

⚡️ Unit Test Generation is now available in beta!

Learn more here, or try it out under "Finishing Touches" below.

✨ Finishing Touches
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch date-range

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

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

Support

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

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

CodeRabbit Commands (Invoked using PR comments)

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

Other keywords and placeholders

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

CodeRabbit Configuration File (.coderabbit.yaml)

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

Documentation and Community

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

@sonarqubecloud
Copy link
Copy Markdown

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
apps/web-app/app/components/DateRangePicker.vue (1)

1-54: Template structure looks good with minor internationalization concern.

The template is well-structured with proper conditional rendering and responsive design. However, consider making the placeholder text "Выберите даты" (line 20) configurable or use an internationalization system for better localization support.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 9344da9 and 8bffac4.

📒 Files selected for processing (4)
  • apps/web-app/app/components/DateRangePicker.vue (1 hunks)
  • apps/web-app/app/components/chart/KitchenChecks.client.vue (3 hunks)
  • apps/web-app/app/components/chart/KitchenRevenue.client.vue (4 hunks)
  • apps/web-app/app/pages/kitchen/[id]/finance.vue (2 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (2)
apps/web-app/app/pages/kitchen/[id]/finance.vue (1)
apps/web-app/shared/types/index.ts (1)
  • Range (50-53)
apps/web-app/app/components/DateRangePicker.vue (1)
apps/web-app/shared/types/index.ts (1)
  • Range (50-53)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build
🔇 Additional comments (19)
apps/web-app/app/components/DateRangePicker.vue (9)

1-54: LGTM! Well-structured template with good UX.

The template properly handles conditional rendering for date display, provides clear visual feedback, and follows good practices with truncation and accessibility considerations.


56-63: LGTM! Proper imports and locale setup.

The imports are appropriate, and the Russian locale setup for DateFormatter aligns well with the UI text.


66-73: LGTM! Well-defined predefined ranges.

The predefined ranges cover common use cases and the (n - 1) calculation properly creates inclusive date ranges.


75-94: Review the default date fallback in calendarRange setter.

The toCalendarDate function is correct, but the setter in calendarRange has a potential issue: when newValue.start or newValue.end is null, it defaults to new Date(). This could create unexpected behavior during partial range selection.

Consider handling null values more explicitly:

  set: (newValue: { start: CalendarDate | null, end: CalendarDate | null }) => {
    selected.value = {
-      start: newValue.start ? newValue.start.toDate(getLocalTimeZone()) : new Date(),
-      end: newValue.end ? newValue.end.toDate(getLocalTimeZone()) : new Date(),
+      start: newValue.start ? newValue.start.toDate(getLocalTimeZone()) : selected.value.start,
+      end: newValue.end ? newValue.end.toDate(getLocalTimeZone()) : selected.value.end,
    }
  },

96-134: LGTM! Solid range selection logic.

The range comparison and selection logic is well-implemented. The code properly handles date arithmetic and comparisons using the @internationalized/date library, and shows good forward compatibility by supporting months/years options.


56-73: LGTM! Clean imports and setup.

The imports, DateFormatter setup, and predefined ranges are well-implemented. The "days - 1" pattern in the ranges array correctly implements "last N days" to include today as part of the range.


75-81: LGTM! Correct date conversion.

The function properly handles the month index conversion (JavaScript's 0-indexed months to CalendarDate's 1-indexed months).


96-116: LGTM! Correct range comparison logic.

The function properly validates whether the current selection matches a predefined range, with consistent logic that matches the selectRange function.


118-134: LGTM! Clean range selection implementation.

The function correctly calculates and sets date ranges, with logic that's consistent with the isRangeSelected function.

apps/web-app/app/pages/kitchen/[id]/finance.vue (2)

3-5: LGTM! Clean integration of DateRangePicker.

The component is properly integrated with correct v-model binding.


29-33: LGTM! Improved default range and date consistency.

The change to 14 days provides a more focused initial view, and using const today ensures consistent date references throughout the initialization.

apps/web-app/app/components/chart/KitchenChecks.client.vue (3)

18-18: LGTM! Consistent height alignment across chart components.

The height reduction aligns with similar changes in other chart components for visual consistency.


104-108: LGTM! Improved calculation with proper zero checks.

The updated calculation logic properly handles edge cases and prevents division by zero, making the code more robust.


128-128: LGTM! Grammatical correction in Russian text.

The change from "Среднее" to "Средний" correctly matches the grammatical gender of "чек" in Russian.

apps/web-app/app/components/chart/KitchenRevenue.client.vue (5)

18-18: LGTM! Consistent height with other chart components.

Matches the height change in KitchenChecks for visual consistency.


59-59: LGTM! Proper type extension.

The DataRecord type is correctly extended with the averageCheck field.


66-66: LGTM! Props type updated consistently.

The values prop type correctly includes the new averageCheck field.


90-90: LGTM! Consistent data mapping pattern.

The averageCheck field is properly mapped following the same pattern as other fields.


126-126: LGTM! Enhanced tooltip with average check information.

The tooltip now provides more comprehensive information by including the average check value alongside the existing data.

Comment on lines +83 to +94
const calendarRange = computed({
get: () => ({
start: selected.value.start ? toCalendarDate(selected.value.start) : undefined,
end: selected.value.end ? toCalendarDate(selected.value.end) : undefined,
}),
set: (newValue: { start: CalendarDate | null, end: CalendarDate | null }) => {
selected.value = {
start: newValue.start ? newValue.start.toDate(getLocalTimeZone()) : new Date(),
end: newValue.end ? newValue.end.toDate(getLocalTimeZone()) : new Date(),
}
},
})
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix null value handling in calendarRange setter.

The setter logic has an issue: when newValue.start or newValue.end is null, it defaults to new Date(). This means clearing a date selection unexpectedly sets it to the current date instead of keeping it unselected.

Consider this fix to handle null values properly:

  set: (newValue: { start: CalendarDate | null, end: CalendarDate | null }) => {
    selected.value = {
-     start: newValue.start ? newValue.start.toDate(getLocalTimeZone()) : new Date(),
-     end: newValue.end ? newValue.end.toDate(getLocalTimeZone()) : new Date(),
+     start: newValue.start ? newValue.start.toDate(getLocalTimeZone()) : null as any,
+     end: newValue.end ? newValue.end.toDate(getLocalTimeZone()) : null as any,
    }
  },

Or update the Range interface to allow null values if that's the intended behavior.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const calendarRange = computed({
get: () => ({
start: selected.value.start ? toCalendarDate(selected.value.start) : undefined,
end: selected.value.end ? toCalendarDate(selected.value.end) : undefined,
}),
set: (newValue: { start: CalendarDate | null, end: CalendarDate | null }) => {
selected.value = {
start: newValue.start ? newValue.start.toDate(getLocalTimeZone()) : new Date(),
end: newValue.end ? newValue.end.toDate(getLocalTimeZone()) : new Date(),
}
},
})
const calendarRange = computed({
get: () => ({
start: selected.value.start ? toCalendarDate(selected.value.start) : undefined,
end: selected.value.end ? toCalendarDate(selected.value.end) : undefined,
}),
set: (newValue: { start: CalendarDate | null, end: CalendarDate | null }) => {
selected.value = {
start: newValue.start ? newValue.start.toDate(getLocalTimeZone()) : null as any,
end: newValue.end ? newValue.end.toDate(getLocalTimeZone()) : null as any,
}
},
})
🤖 Prompt for AI Agents
In apps/web-app/app/components/DateRangePicker.vue around lines 83 to 94, the
setter for calendarRange incorrectly assigns new Date() when newValue.start or
newValue.end is null, causing cleared dates to reset to the current date. To fix
this, update the setter to assign undefined or null instead of new Date() when
the values are null, preserving the cleared state properly without defaulting to
the current date.

@hmbanan666 hmbanan666 merged commit 3c94343 into main Jul 30, 2025
8 checks passed
@hmbanan666 hmbanan666 deleted the date-range branch July 30, 2025 10:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant