Files
event-manager/plans/Completed/login-modal.md
T
xadm 786cbc724f
CI / Server (push) Has been cancelled
Linters / Frappe Linter (push) Has been cancelled
Linters / Vulnerable Dependency Check (push) Has been cancelled
UI Tests / Playwright E2E Tests (push) Has been cancelled
Initialize fork and rebrand app to event_manager
2026-05-11 09:56:57 +02:00

61 lines
4.8 KiB
Markdown

# Plan: In-App Login Modal
## Status: Implemented ✓
## Goal
Replace the redirect to Frappe's `/login` page with an in-app modal dialog that supports all login features. Users stay on the current page (booking, custom form, etc.) and authenticate without leaving context.
## What Was Done
### New Files Created
1. **`event_manager/api/auth.py`** — `get_login_context()` whitelisted API (allow_guest) returning login settings (disable_signup, disable_user_pass_login, login_with_email_link), Google OAuth URL, and login_banner from Pohodex Event Manager Settings
2. **`dashboard/src/components/LoginDialog.vue`** — Multi-view modal with 4 views: login, signup, forgot-password, email-link. Uses native HTML `<form>` validation with `required` attributes. Each view wrapped in `<form @submit.prevent>`. Google OAuth with SVG icon. Banner with localStorage hash persistence.
3. **`dashboard/src/composables/useLoginDialog.ts`** — Shared composable with `open(onSuccess?)` and `close()` to control the modal from anywhere
### Files Modified
1. **`event_manager/events/doctype/buzz_settings/buzz_settings.json`** — Added new "Login" tab with `login_banner` Markdown Editor field
2. **`dashboard/src/App.vue`** — Mounted `<LoginDialog />` globally inside `<FrappeUIProvider>`
3. **`dashboard/src/layouts/Layout.vue`** — Added auth gate: shows `<LoginRequired />` instead of page content for non-public routes when user is not logged in
4. **`dashboard/src/components/LoginRequired.vue`** — Changed "Log In" button to open login modal via `useLoginDialog().open()`. Fixed `__()` in `defineProps` default (was causing app crash at module load time before `window.__` was defined)
5. **`dashboard/src/components/Navbar.vue`** — "Log In" button opens login modal instead of redirecting
6. **`dashboard/src/components/BookingForm.vue`** — "Log In" link opens login modal. Submit button shows "Login to Checkout" when user is not logged in and event doesn't allow guest booking. On submit with login required, opens login modal with callback to reload page (form data persisted via `useBookingFormStorage` localStorage)
7. **`dashboard/src/pages/BookTickets.vue`** — Removed `LoginRequired` gate that blocked the entire booking form. Users can now fill in the form and are only prompted to login at checkout time
8. **`dashboard/src/data/session.ts`** — Removed auto-redirect on login success (modal handles post-login flow). Logout now reloads page instead of redirecting to `/login`
9. **`dashboard/src/data/user.ts`** — Removed redirect to `/login` on AuthenticationError
10. **`dashboard/src/router.ts`** — Simplified guard to just fetch user data. Removed redirect to `/login` for unauthenticated users (Layout handles showing LoginRequired). Removed unused `session` import
11. **`dashboard/src/utils/index.ts`** — Removed unused `redirectToLogin()` function
## Key Behaviors
### Booking Flow (non-guest events)
- Form shows fully for all users, even unauthenticated
- Submit button says **"Login to Checkout"** when login is required
- Clicking it opens the login modal on top of the filled form
- After login, page reloads — form data is preserved via `useBookingFormStorage` (localStorage)
### Protected Routes (account, bookings, tickets, etc.)
- Layout shows `LoginRequired` component with "Log In" button
- Button opens login modal instead of redirecting to Frappe's `/login`
- After login, page re-renders with authenticated state
### Login Modal Features
- **Login**: email + password (required, native validation), "Forgot Password?" link
- **Social OAuth**: "Continue with {Provider}" buttons for all enabled Social Login Keys (shown on both login and signup views)
- **Email Link**: "Login with Email Link" button (conditional on system setting)
- **Signup**: full name + email (conditional on disable_signup setting), social login buttons shown here too
- **Forgot Password**: email field, sends reset link
- **Banner**: configurable via Pohodex Event Manager Settings → Login tab, always visible when modal opens (no dismiss/timer logic)
### Form Validation
- All views use `<form @submit.prevent>` with native HTML validation
- Email fields use `type="email"` + `required`
- Password field uses `required`
- Full Name field uses `required` in signup view
- No custom JS validation for empty checks — browser handles it
## Notes
1. **Social login redirect**: OAuth requires a full page redirect to Google. After auth, Frappe redirects back to `/dashboard`. No way around this.
2. **`__()` in defineProps**: Using `__()` in prop defaults causes crashes because it runs at module-load time before the translation plugin installs `window.__`. Fixed by using plain strings for defaults and wrapping with `__()` in the template.
3. **Logout behavior**: Changed from redirecting to `/login` to `window.location.reload()` — the Layout auth gate handles showing LoginRequired after reload.