- Brand color: add # prefix when loading from DB (stored without #,
CSS needs it for backgroundColor)
- Header upload: delete destination file before rename to prevent
collision when re-uploading same extension
- Header preview: prepend BASE_PATH to image URL for local dev
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replace default password login with email-based OTP flow. User enters
email, receives 6-digit code, enters it to log in. Password login
retained as fallback via link. On dev, magic OTP code is shown directly
for easy testing.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The user icon in the top-right header now opens a dropdown
with Settings and Logout links, making both accessible on mobile
where the sidebar is hidden.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Lucee serializeJSON casing varies by server config (preserveCaseForStructKey).
Normalize all biz object keys to uppercase on the JS side so lookups
work regardless of server config.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Hide wrapper div instead of img (avoids mobile empty-src issues)
- Use img onload handler to show wrapper after image loads
- Use backgroundColor instead of background shorthand for swatch
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Header preview: max-width 1200px, white background, no border-radius on img
- Brand color swatch: change span to div with min-width/min-height and
flex-shrink:0 to prevent collapse on mobile flex layouts
- Remove headerPreviewWrapper brand color tinting (wrapper stays white)
- Fix swatch border from white-alpha to black-alpha for visibility on white cards
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
CSS background-image with padding-bottom trick for aspect ratio was not
rendering on mobile. Using an actual <img> element with width:100% is
universally reliable across all browsers and devices.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Replace fixed 120px height with aspect-ratio padding (33.3%) so image
scales properly on narrow mobile screens
- Use background-size: cover instead of contain for better fill
- Add wrapper div that shows brand color behind the header image
- Update saveBrandColor to also update the header wrapper background
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
settingName -> settingBusinessName, settingLine1 -> settingAddressLine1
to match actual HTML element IDs. The mismatch caused null reference
errors that broke the entire settings page load.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- saveBrandColor.cfm: BrandColor -> BusinessBrandColor (normalized column name)
- portal.js: Accept hex colors with or without # prefix in validation
- portal.js: Auto-prepend # when typing bare hex in color input
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- loginOTP.cfm/sendOTP.cfm: Use magic OTP code (123456) on dev instead of random
- portal/login.html: Hide login card until auth check completes to prevent flash of login form when redirecting to business selection
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- myBusinesses.cfm: Use BusinessID/BusinessName/BusinessUserID instead of
ID/Name/UserID (post-normalization column names)
- login.html: Fix biz.BusinessName -> biz.Name to match API response key
- login.html: Add friendly error messages for bad_credentials
- portal.js: Fix b.ID -> b.BusinessID in access check
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Update all SQL queries, query result references, and ColdFusion code to match
the renamed database schema. Tables use plural CamelCase, PKs are all `ID`,
column prefixes stripped (e.g. BusinessName→Name, UserFirstName→FirstName).
Key changes:
- Strip table-name prefixes from all column references (Businesses, Users,
Addresses, Hours, Menus, Categories, Items, Stations, Orders,
OrderLineItems, Tasks, TaskCategories, TaskRatings, QuickTaskTemplates,
ScheduledTaskDefinitions, ChatMessages, Beacons, ServicePoints, Employees,
VisitorTrackings, ApiPerfLogs, tt_States, tt_Days, tt_AddressTypes,
tt_OrderTypes, tt_TaskTypes)
- Rename PK references from {TableName}ID to ID in all queries
- Rewrite 7 admin beacon files to use ServicePoints.BeaconID instead of
dropped lt_Beacon_Businesses_ServicePoints link table
- Rewrite beacon assignment files (list, save, delete) for new schema
- Fix FK references incorrectly changed to ID (OrderLineItems.OrderID,
Categories.MenuID, Tasks.CategoryID, ServicePoints.BeaconID)
- Update Addresses: AddressLat→Latitude, AddressLng→Longitude
- Update Users: UserPassword→Password, UserIsEmailVerified→IsEmailVerified,
UserIsActive→IsActive, UserBalance→Balance, etc.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When multiple menus exist, checks current time and day against menu
schedules. If exactly one menu matches, auto-selects it. If times
overlap or none match, shows all categories. User can still manually
select any menu or 'All Menus' from the dropdown.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Pass menuName in redirect URL from menu-builder
- Show menu name in wizard header and final review
- Skip hours validation in both JS and backend for add-menu mode
- Hide menu name, hours, and community meal fields in final step
- Add id to community meal card for toggling
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When a new menu is created in Manage Menus, the user is now redirected
to the setup wizard with businessId and menuId params. The wizard skips
business info/header steps and goes straight to photo upload + category
extraction. Backend uses the provided menuId instead of creating a new
menu. Also removes temp debug from menus.cfm.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
showMenuManager() was passing arguments to showModal() which accepts
none, so the modal content was silently discarded. Now follows the
same pattern as all other modal callers in the file.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Move menu manager button to toolbar next to Save Menu for visibility
- Implement server-side photo upload for menu items
- Strip base64 data URLs from save payload to reduce size
- Add scheduled tasks, quick tasks, ratings, and task categories APIs
- Add vertical support and brand color features
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Skip business selection for users with only one business
- Add Switch Business and Add New Business links in portal sidebar
- Handle returning users switching businesses (token + no business)
- HUD reads businessId from localStorage instead of ?b= param
- Portal opens HUD/quick-tasks without URL params
- Business select auto-proceeds on selection (no button needed)
- Quick tasks reads from payfrit_portal_business localStorage
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- New portal/signup.html with phone → OTP → profile flow
- Handle both new users (signup) and existing users (login)
- Auto-detect user type and use appropriate API endpoints
- Show DEV_OTP on page for local testing
- Updated sendOTP.cfm to gracefully handle missing Twilio
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Features:
- Multi-menu support with time-based availability
- Menu hours validation against business operating hours
- Setup wizard now creates Menu records and links categories
- New menus.cfm API for menu CRUD operations
- Category schedule filtering (day/time based visibility)
- Beacon UUID lookup API for customer app
- Parent/child business relationships for franchises
- Category listing API for menu builder
Portal improvements:
- Menu builder theming to match admin UI
- Brand color picker fix
- Header image preview improvements
API fixes:
- Filter demo/hidden businesses from restaurant list
- Improved error handling throughout
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Lucee's serializeJSON converts all struct keys to UPPERCASE.
Updated loadBusinessInfo to check for uppercase key variants.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Added portal sidebar navigation to menu builder
- Updated color scheme to use portal CSS variables (gray-* instead of custom vars)
- Fixed header image preview to use HeaderImageURL from API response
- Fixed upload handler to use correct extension from response
- Added sidebar toggle and logout functionality
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- HUD now displays "Payfrit Tasks - <BusinessName>" by fetching from getBusiness API
- Fixed portal Task HUD button to link to /hud/index.html instead of /hud/
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Changed hideModal() to closeModal() in color picker
- Simplified queryExecute parameter handling
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add uploadHeader.cfm API for 1200px header images
- Add saveBrandColor.cfm API for hex color storage
- Add Branding section to menu builder sidebar
- Fix header upload path and permissions
- Various beacon and service point API improvements
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Fix for...in loops on query results in getForBuilder.cfm (only iterated once)
- Remove illegal var keyword from loop variables in saveWizard.cfm
- Only create food running tasks for dine-in orders (skip takeaway/delivery)
- Add image preview modal for modifier source images in wizard
- Add data clearing utilities (clearAllData, clearOrders)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Major Changes:
1. Fixed infinite loop in wizard flow - uncertain modifiers step now correctly advances to final review instead of looping back to items
2. Moved uncertain modifier assignment to AFTER items review (makes more sense for user to see items first)
3. Added detailed modifier visualization on uncertain modifiers step showing:
- Source image indicator (which image the modifier was extracted from)
- Full list of all options with prices
- Required/optional status
- Option count summary
Technical Details:
- Backend: Added sourceImageIndex tracking in analyzeMenuImages.cfm to record which image each modifier came from
- Frontend: Enhanced uncertain modifiers step with inline detailed view showing complete modifier structure
- Flow correction: showUncertainModifiersStep() now calls showFinalStep() instead of showItemsStep() to prevent loop
- Improved error handling in API calls with detailed error messages from Claude API
Flow Changes:
- Old: Upload → Business → Categories → Modifiers → Uncertain Modifiers → Items → [LOOP]
- New: Upload → Business → Categories → Modifiers → Items → Uncertain Modifiers → Final Review
Model Configuration:
- Using claude-sonnet-4-20250514 for menu image analysis
- Added better error reporting to surface API issues (auth, credits, etc.)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>