Skip to content

fix(book): loan calendar uses flatpickr on mobile (not the native picker) — shows availability#198

Open
fabiodalez-dev wants to merge 1 commit into
mainfrom
fix/mobile-loan-datepicker
Open

fix(book): loan calendar uses flatpickr on mobile (not the native picker) — shows availability#198
fabiodalez-dev wants to merge 1 commit into
mainfrom
fix/mobile-loan-datepicker

Conversation

@fabiodalez-dev

@fabiodalez-dev fabiodalez-dev commented Jun 25, 2026

Copy link
Copy Markdown
Owner

On the single-book page, on mobile, the loan/reservation calendar (flatpickr inside the SweetAlert) fell back to the native Android/iOS date picker. The native picker ignores flatpickr's disable option → fully-booked days looked selectable and availability was not shown.

Fix

Added disableMobile: true to the shared baseOpts of the two pickers (start/end) in book-detail.php: flatpickr always uses its own calendar, where unavailable dates are disabled and colored — on mobile too.

Test

tests/issue-mobile-datepicker.spec.js (Pixel 5 / Android Chrome emulation): opens the loan dialog and asserts flatpickr is used — disableMobile=true, isMobile=false, no native input[type=date], flatpickr calendar present in the DOM. ✅ green.

PHPStan L5 green.

Summary by CodeRabbit

  • Bug Fixes

    • Corrected the date picker in the mobile reservation/loan flow, keeping the custom calendar on Android and iOS devices.
    • Prevented selecting unavailable dates via the calendar component.
  • Tests

    • Added an end-to-end test to verify the mobile date-picker behavior and prevent future regressions.

… picker

On the public book page the loan/reservation date picker (a flatpickr inside the
SweetAlert) fell back to the native Android/iOS date picker on phones — and the
native picker ignores flatpickr's `disable` option, so fully-booked days looked
selectable and availability was never shown. Set disableMobile:true on the
shared baseOpts so both the start and end pickers always use flatpickr's own
calendar, where unavailable dates are disabled and styled.

Adds tests/issue-mobile-datepicker.spec.js (Pixel 5 / Android-Chrome emulation):
opens the request-loan dialog and asserts flatpickr is used (disableMobile true,
isMobile false, no native input type=date, flatpickr calendar in the DOM).
@coderabbitai

coderabbitai Bot commented Jun 25, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Viene forzato l’uso di flatpickr anche su mobile nel flusso di prenotazione/prestito. È stata aggiunta una regressione Playwright che verifica il calendario Flatpickr su dispositivo mobile e l’assenza del picker nativo.

Changes

Comportamento del date picker mobile

Layer / File(s) Summary
Config mobile di flatpickr
app/Views/frontend/book-detail.php
baseOpts imposta disableMobile: true nel picker del prestito/prenotazione.
Regressione E2E mobile
tests/issue-mobile-datepicker.spec.js
Lo spec Playwright usa un profilo Pixel 5, apre il dialogo di richiesta prestito e verifica che Flatpickr sia usato su mobile.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~15 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 60.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed Il titolo riassume correttamente il fix: il calendario prestito su mobile forza Flatpickr invece del picker nativo.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/mobile-loan-datepicker

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/issue-mobile-datepicker.spec.js`:
- Around line 63-71: The mobile datepicker spec is too permissive because the
login redirect is swallowed and the loan-request button check can silently skip
the test, creating a false green. In tests/issue-mobile-datepicker.spec.js,
update the login flow around page.waitForURL and the `#btn-request-loan` lookup so
failures surface explicitly instead of being ignored or skipped; keep the test
in the executed path and fail when the expected redirect or button is missing,
using the existing page.goto, page.waitForURL, and btn locator flow to locate
the fix.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 53289992-796a-4ae4-99c0-2d2e377dafbd

📥 Commits

Reviewing files that changed from the base of the PR and between eab030e and eea7f6a.

📒 Files selected for processing (2)
  • app/Views/frontend/book-detail.php
  • tests/issue-mobile-datepicker.spec.js

Comment on lines +63 to +71
await page.goto(`${BASE}/accedi`);
await page.fill('input[name="email"]', ADMIN_EMAIL);
await page.fill('input[name="password"]', ADMIN_PASS);
await page.locator('button[type="submit"]').click();
await page.waitForURL(/(\/$|admin|profilo|account)/, { timeout: 15000 }).catch(() => {});

await page.goto(`${BASE}/libro/${bookId}`);
const btn = page.locator('#btn-request-loan');
test.skip((await btn.count()) === 0, 'This book has no request-loan button');

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Non rendere questo spec “false green”.

Il catch(() => {}) su waitForURL e lo test.skip sul bottone permettono allo spec di passare senza verificare nulla se il login rompe, cambia il redirect o #btn-request-loan non compare. Qui dovrebbe fallire esplicitamente, altrimenti la regressione mobile resta scoperta.

Diff proposta
     await page.goto(`${BASE}/accedi`);
     await page.fill('input[name="email"]', ADMIN_EMAIL);
     await page.fill('input[name="password"]', ADMIN_PASS);
     await page.locator('button[type="submit"]').click();
-    await page.waitForURL(/(\/$|admin|profilo|account)/, { timeout: 15000 }).catch(() => {});
+    await page.waitForURL(/(\/$|admin|profilo|account)/, { timeout: 15000 });

     await page.goto(`${BASE}/libro/${bookId}`);
     const btn = page.locator('`#btn-request-loan`');
-    test.skip((await btn.count()) === 0, 'This book has no request-loan button');
+    await expect(btn).toBeVisible();

Based on learnings, negli E2E di questo repo il gating deve evitare skip silenziosi che nascondono il fatto che il flusso non è stato davvero eseguito.

📝 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
await page.goto(`${BASE}/accedi`);
await page.fill('input[name="email"]', ADMIN_EMAIL);
await page.fill('input[name="password"]', ADMIN_PASS);
await page.locator('button[type="submit"]').click();
await page.waitForURL(/(\/$|admin|profilo|account)/, { timeout: 15000 }).catch(() => {});
await page.goto(`${BASE}/libro/${bookId}`);
const btn = page.locator('#btn-request-loan');
test.skip((await btn.count()) === 0, 'This book has no request-loan button');
await page.goto(`${BASE}/accedi`);
await page.fill('input[name="email"]', ADMIN_EMAIL);
await page.fill('input[name="password"]', ADMIN_PASS);
await page.locator('button[type="submit"]').click();
await page.waitForURL(/(\/$|admin|profilo|account)/, { timeout: 15000 });
await page.goto(`${BASE}/libro/${bookId}`);
const btn = page.locator('`#btn-request-loan`');
await expect(btn).toBeVisible();
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/issue-mobile-datepicker.spec.js` around lines 63 - 71, The mobile
datepicker spec is too permissive because the login redirect is swallowed and
the loan-request button check can silently skip the test, creating a false
green. In tests/issue-mobile-datepicker.spec.js, update the login flow around
page.waitForURL and the `#btn-request-loan` lookup so failures surface explicitly
instead of being ignored or skipped; keep the test in the executed path and fail
when the expected redirect or button is missing, using the existing page.goto,
page.waitForURL, and btn locator flow to locate the fix.

Source: Learnings

@fabiodalez-dev

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 25, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@fabiodalez-dev

fabiodalez-dev commented Jun 25, 2026

Copy link
Copy Markdown
Owner Author

Code review

Branch: fix/mobile-loan-datepickermain
PR: #198 (open)

Automated 6-lens review (correctness, structure/blast-radius, CLAUDE.md compliance, comments, UX, security) over the diff.

Verdict: nothing blocking. The fix (disableMobile: true, so the loan/reservation picker uses Flatpickr's own calendar on mobile) is correct and well-scoped: baseOpts feeds both the start and end pickers, the submitted value stays Y-m-d via altInput (no regression to submit/server parsing), and there are no other flatpickr inits in the dialog to update.

Minor note (below threshold, non-blocking)

  • UX — calendar width on very narrow viewports · app/Views/frontend/book-detail.php (~2654-2667)
    With disableMobile:true the flatpickr popup (~307px) opens inside the SweetAlert2 modal: on phones < ~340px CSS it could need horizontal scrolling. Score 30/100 — negligible on modern devices (≥360px); no responsive CSS rule targets .flatpickr-calendar inside .swal2-popup. Possible future hardening: max-width:100% on the calendar within the modal.

Lenses: L1/L2/L3/L4/L6 no findings; L5 (UX) one minor finding, classified below the validation gate.

@fabiodalez-dev fabiodalez-dev changed the title fix(book): calendario prestito usa flatpickr su mobile (niente picker nativo) — mostra le disponibilità fix(book): loan calendar uses flatpickr on mobile (not the native picker) — shows availability Jun 27, 2026
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