Skip to content

Conversation

@21prnv
Copy link
Contributor

@21prnv 21prnv commented Apr 1, 2025

What does this PR do?

  • Fixed date range selection to maintain end date when selecting earlier dates

  • Added toggle functionality: clicking start date again converts range to single-day range

  • Ensured single date selections automatically set both start and end dates to the same day

  • Updated range behavior: clicking start date in a range (e.g., 2-9) now sets it to single-day range (e.g., 2-2) instead of clearing end date ( it will fix the end date issue ex: start date comes after end date )

Fixes #20464

Visual Demo (For contributors especially)

Screen.Recording.2025-04-01.194432.mp4

Mandatory Tasks (DO NOT REMOVE)

  • I have self-reviewed the code (A decent size PR without self-review might be rejected).
  • I have updated the developer docs in /docs if this PR makes changes that would require a documentation change. If N/A, write N/A here and check the checkbox.
  • I confirm automated tests are in place that prove my fix is effective or that my feature works.

How should this be tested?

  • Go to Event types > click on any event > go to limit future bookings toggle
  • Set an initial range (e.g., April 2nd - April 9th).
  • Click on the date picker to open it.
  • Select a new start date before the end date (e.g., April 4th).
    • Check that the UI shows the updated start date with the original end date intact (e.g., April 4th - April 9th).
  • Click the start date again (e.g., April 4th).
    • Verify it converts to a single-day range (e.g., April 4th - April 4th) instead of clearing the end date.
  • Select a single date initially (e.g., April 2nd).
    • Confirm it automatically sets as both start and end date (e.g., April 2nd - April 2nd).
  • Set a range again (e.g., April 2nd - April 9th), then pick a start date after the end date (e.g., April 10th).
    • Confirm it starts a new single-day range (e.g., April 10th - April 10th) instead of keeping the old end date.
  • Close the date picker and click "Save."
  • Refresh the page and verify the saved range matches the last selection.
  • Reopen the date picker, pick a new date, close without saving.
    • Ensure the original saved range remains unchanged.
  • Save a valid range (e.g., April 4th - April 9th), refresh, and verify the result persists correctly.

@CLAassistant
Copy link

CLAassistant commented Apr 1, 2025

CLA assistant check
All committers have signed the CLA.

@vercel
Copy link

vercel bot commented Apr 1, 2025

@21prnv is attempting to deploy a commit to the cal Team on Vercel.

A member of the Team first needs to authorize it.

@graphite-app graphite-app bot added the community Created by Linear-GitHub Sync label Apr 1, 2025
@graphite-app graphite-app bot requested a review from a team April 1, 2025 14:37
@github-actions github-actions bot added event-types area: event types, event-types ui area: UI, frontend, button, form, input 🐛 bug Something isn't working labels Apr 1, 2025
@graphite-app
Copy link

graphite-app bot commented Apr 1, 2025

Graphite Automations

"Add consumer team as reviewer" took an action on this PR • (04/01/25)

1 reviewer was added to this PR based on Keith Williams's automation.

"Add community label" took an action on this PR • (04/01/25)

1 label was added to this PR based on Keith Williams's automation.

"Add ready-for-e2e label" took an action on this PR • (04/01/25)

1 label was added to this PR based on Keith Williams's automation.

Copy link
Contributor

@retrogtx retrogtx left a comment

Choose a reason for hiding this comment

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

the comments seem unnecessary, one summarized line or nothing at all will do

rest looks good to me 🙏

retrogtx
retrogtx previously approved these changes Apr 1, 2025
@github-actions
Copy link
Contributor

github-actions bot commented Apr 1, 2025

E2E results are ready!

// If both dates exist
if (date.getTime() === dates.startDate.getTime() && dates.endDate) {
onDatesChange({ startDate: date, endDate: date });
} else if (date <= dates.endDate) {
Copy link
Contributor

@shawnCaza shawnCaza Apr 1, 2025

Choose a reason for hiding this comment

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

With this logic we can only change the start date. We can't change the end date unless we pick a date past the current end date. Makes for a confusing UX.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

hey @shawnCaza thx for giving more clarity I'm working on this issue

@shawnCaza
Copy link
Contributor

shawnCaza commented Apr 1, 2025

I think we need state to keep track of the previous click. To handle the logic correctly we need to know if the last click set a start date or an end date.

As a user in a date picker, my expectation is that my first date click will set the start date. The next date click should set the end date. Subsequent clicks should follow the same pattern.

We only want to deviate from that in special circumstances, such as picking an end date that is before the start date. In any case where the start date is reset, the next click should set the end date IMO. If we close the date picker and re-open then then next click should be a 'start' click.

@21prnv
Copy link
Contributor Author

21prnv commented Apr 2, 2025

Hey @shawnCaza I understand exactly what you're saying so for better UX the date picker should follow this flow.let me know if I'm wrong here!

  1. The first click always sets the start date.

  2. The second click always sets the end date.

  3. If the user selects an earlier date than the start date, we assume they want to restart the selection.

  4. If the picker is closed and reopened, the next click should always be a start date selection.

@shawnCaza
Copy link
Contributor

shawnCaza commented Apr 2, 2025

@21prnv Yes, that's how I would do it.

Others might have different opinions about 3. There's probably even clearer ways to do it that would require a more drastic ui change. Like choosing start and end date in a separate picker. But I think doing it as mentioned in 3 will provide a quick improvement over the existing UX.

Of course, you should:

  • Still do the same thing as you're doing now if the start date click is after the current end date.
  • Anticipate that the user may click more than 2 times.

@21prnv
Copy link
Contributor Author

21prnv commented Apr 2, 2025

@shawnCaza fixed the issue please check

Screen.Recording.2025-04-02.113111.mp4

@shawnCaza
Copy link
Contributor

shawnCaza commented Apr 2, 2025

@21prnv That looks like the same problem as before but in reverse. It's now hard to change the start date. You won't be able to solve this problem with that complicated nested if/else logic alone.

I would suggest tracking the state of the previous date selection type like this:
const [lastDayClickType, setLastDayClickType] = useState<"start" | "end" | null>(null);

Then we can be clearer in the logic about what we want to do based on what happened with the previous date selection.

If you like this idea you'd need to complete the missing parts in the second nested if statement.

    if (lastDayClickType === "start") {
      if (date >= dates.startDate) {
        onDatesChange({ ...dates, endDate: date });
        setLastDayClickType("end");
      } else if (date < dates.startDate) {
        onDatesChange({ ...dates, startDate: date });
        setLastDayClickType("start");
      }
    } else if (lastDayClickType === "end" || lastDayClickType === null) {
      if (date <= dates.endDate) {
          // Change dates and setLastDayClickType here
      } else if (date > dates.endDate) {
         // Change dates and setLastDayClickType here
      }
    }
  }

Note I took out the logic for handling the scenario where dates.startDate and Dates.endDate are undefined. I'm not sure in what scenario the values would come in undefined. Is there any problem in just setting default values if they are undefined?

In the scenario where I make a new event. The range seems to default to current day for both start and end.

@21prnv
Copy link
Contributor Author

21prnv commented Apr 2, 2025

hey @shawnCaza may be im wrong here but I think we don't need any extra hook here but still I can optimise that nested loops logic but before here the current code logic goes, in the previous video its just small recoding may be that's you didn't get the clarity:
here the complete flow:

  1. The user opens the date picker and selects date 2. I update this date to be both the start and end date. If the end date is marked as undefined, it will lead to a misalignment, such as having the end date before the start date.

  2. After this, if the user selects date 9, the range will be from 2 to 9. The user can also adjust the start date; for instance, if they select date 3, the range will now be from 3 to 9, which poses no issue for selecting the start date.

  3. If the user clicks again on either the start or end date, that single date will be set as both the start and end date. This eliminates the possibility of having an undefined date, which could cause mismatch issues when saving.

  4. For example, if the user clicks on date 9 again (as in the third step) and then clicks on date 4, the range will change to 4 to 9. This ensures there are no mismatched dates, where the end date comes before the start date.

I hope this clarifies things!)

@shawnCaza
Copy link
Contributor

shawnCaza commented Apr 2, 2025

@21prnv I tested your branch locally.

This is my experience:

  • I opened date picker with initial range set to apr 02 - apr 02
  • I click on the 17. Range is now set to apr 02 - 17. OK.
  • I click on the 10th. Range is now set to apr 02 - 10. I was expecting 10 - 17.
  • I click on the 4th. Range is now set to apr 02 -4th. It now feels like I can't change the start date.
  • I click on the 2nd. Range is now set to apr 02 - apr 02. Ok.
  • I click on the 10th. range is now set to apr 02 - apr 10th. but I really still want the 10-17 range.
  • I click on the 10th again. range is now set to apr 10 - 10th.
  • I click on the 17th, Range is now set to apr 10 - 17th. I finally got what I want but that wasn't a good experience. I didn't need that many clicks to achieve my goal, but it took some time to understand what I needed to do.

The only way for me to change the start date, if the desired start date is between the current start date and end date, is to first change the end date to the new start date, then click that date again so end and start are the same, then re-select my end-date.

I'm not saying my method with useState is perfect UX, but I think it's less confusing.

@shawnCaza
Copy link
Contributor

shawnCaza commented Apr 2, 2025

With the useState approach it might even be more intuitive for the user if we handled the case where nothing has been clicked yet slightly differently

  function handleDayClick(date: Date) {
    if (lastDayClickType === "start") {
      if (date >= dates.startDate) {
        onDatesChange({ ...dates, endDate: date });
        setLastDayClickType("end");
      } else if (date < dates.startDate) {
        onDatesChange({ ...dates, startDate: date });
        setLastDayClickType("start");
      }
    } else if (lastDayClickType === "end") {
      if (date <= dates.endDate) {
        onDatesChange({ ...dates, startDate: date });
        setLastDayClickType("start");
      } else if (date > dates.endDate) {
        onDatesChange({ startDate: date, endDate: date });
        setLastDayClickType("start");
      }
    } else if (lastDayClickType === null) {
      if (date <= dates.endDate) {
        onDatesChange({ ...dates, startDate: date });
        setLastDayClickType("start");
      } else if (date > dates.endDate) {
        onDatesChange({ ...dates, endDate: date });
        setLastDayClickType("end");
      }
    }
  }

@shawnCaza
Copy link
Contributor

shawnCaza commented Apr 2, 2025

A separate input box, that user can type in, for both start and end range, likely provides the simplest ux.

02-expedia

@21prnv
Copy link
Contributor Author

21prnv commented Apr 2, 2025

Hey @shawnCaza , I tested your code and now understand everything. It has nothing to do with our code the issue is caused by that single date picker field.

I tried my logic and changed the code multiple times, but the user can still move either the start date or the end date. I also tested your code, but in the end, the issue of changing the end date still persists.

You're correct that we need two date pickers, but for that, we need to add another date picker, which requires raising a new issue and waiting for approval. That will take time.

So, my suggestion is to add my logic for now and close this PR.

@shawnCaza
Copy link
Contributor

shawnCaza commented Apr 2, 2025

@21prnv I'm not sure if we are seeing the same things when we are testing out these options or if we just have different preferences. In either case I don't feel I have anything new to add to explain my perspective. If you are confident with your PR you should stick with it for review.

Thanks for looking into this with me and working on a solution.

@21prnv
Copy link
Contributor Author

21prnv commented Apr 3, 2025

Hey @shawnCaza , thanks for communicating and elaborating on this. I would say that the single date picker is causing all the issues, but don't worry I will raise a new issue, and once it's approved, we will add the new end date picker.

@retrogtx retrogtx merged commit c2cf55f into calcom:main Apr 4, 2025
32 of 37 checks passed
alishaz-polymath pushed a commit that referenced this pull request May 9, 2025
* fix: Updated DateRangePicker in limit future booking

* removed unnecessary comments

* minor changes in end date selection

* final changes in end date selection

* minor changes in end date selection

* fixed issue of logs

* added allowPastDates props for out of office data selection
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🐛 bug Something isn't working community Created by Linear-GitHub Sync event-types area: event types, event-types ready-for-e2e ui area: UI, frontend, button, form, input

Projects

None yet

Development

Successfully merging this pull request may close these issues.

When selecting a range limit for an event it is not always clear what end date will be saved

4 participants