4.8 KiB
4.8 KiB
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
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 Settingsdashboard/src/components/LoginDialog.vue— Multi-view modal with 4 views: login, signup, forgot-password, email-link. Uses native HTML<form>validation withrequiredattributes. Each view wrapped in<form @submit.prevent>. Google OAuth with SVG icon. Banner with localStorage hash persistence.dashboard/src/composables/useLoginDialog.ts— Shared composable withopen(onSuccess?)andclose()to control the modal from anywhere
Files Modified
event_manager/events/doctype/buzz_settings/buzz_settings.json— Added new "Login" tab withlogin_bannerMarkdown Editor fielddashboard/src/App.vue— Mounted<LoginDialog />globally inside<FrappeUIProvider>dashboard/src/layouts/Layout.vue— Added auth gate: shows<LoginRequired />instead of page content for non-public routes when user is not logged indashboard/src/components/LoginRequired.vue— Changed "Log In" button to open login modal viauseLoginDialog().open(). Fixed__()indefinePropsdefault (was causing app crash at module load time beforewindow.__was defined)dashboard/src/components/Navbar.vue— "Log In" button opens login modal instead of redirectingdashboard/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 viauseBookingFormStoragelocalStorage)dashboard/src/pages/BookTickets.vue— RemovedLoginRequiredgate that blocked the entire booking form. Users can now fill in the form and are only prompted to login at checkout timedashboard/src/data/session.ts— Removed auto-redirect on login success (modal handles post-login flow). Logout now reloads page instead of redirecting to/logindashboard/src/data/user.ts— Removed redirect to/loginon AuthenticationErrordashboard/src/router.ts— Simplified guard to just fetch user data. Removed redirect to/loginfor unauthenticated users (Layout handles showing LoginRequired). Removed unusedsessionimportdashboard/src/utils/index.ts— Removed unusedredirectToLogin()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
LoginRequiredcomponent 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
requiredin signup view - No custom JS validation for empty checks — browser handles it
Notes
- Social login redirect: OAuth requires a full page redirect to Google. After auth, Frappe redirects back to
/dashboard. No way around this. __()in defineProps: Using__()in prop defaults causes crashes because it runs at module-load time before the translation plugin installswindow.__. Fixed by using plain strings for defaults and wrapping with__()in the template.- Logout behavior: Changed from redirecting to
/logintowindow.location.reload()— the Layout auth gate handles showing LoginRequired after reload.