Only include category headers that actually have items assigned
to them, preventing empty categories from showing up in the app.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Always return all active menus in the response so chip selector
always appears. Show all items from all menus by default instead
of filtering by current time, which caused empty results outside
menu hours.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Returns active menus in response so mobile apps can show menu
selector chips. Accepts optional MenuID param to filter items
to a specific menu.
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>
The menuName variable was only defined in the else branch (new menu
creation) but referenced later in category logging. Now looks up the
menu name from DB when using a provided menuId.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
javaCast('null','') makes the variable truly undefined, causing
'variable doesn't exist' errors when referenced in query params.
Use empty string + len() check instead.
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>
The endpoint was missing from the public paths whitelist in
Application.cfm, causing all requests to fail with not_logged_in.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Fixes save failure when MenuStartTime/MenuEndTime are null -
Lucee couldn't determine the SQL type without explicit hints.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
saveBrandColor.cfm no longer prepends # before storing. API responses
(get.cfm, items.cfm, getForBuilder.cfm) prepend # if missing so
consumers always get a CSS-ready value.
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>
- Remove TypeID/Label from list response
- Hardcode TypeID=2 (delivery) in add endpoint
- Filter to personal addresses only (BusinessID=0 or NULL)
- Just IsDefault flag, no home/work labels
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add /addresses/types.cfm - returns address types list
- Update /addresses/list.cfm - include TypeID in response
- Update /addresses/add.cfm - accept TypeID instead of hardcoded '2'
- Fix loginOTP.cfm and sendOTP.cfm to skip Twilio SMS on dev server
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Update create.cfm to handle TaskTypeID for service bell tasks
- Update hud.js to prefer TaskTypeColor/TaskTypeName for task display
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>
Wrap numeric fields with val() to prevent "can't cast empty string to number"
errors when database values are null or empty strings.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add address list/add/delete/setDefault to public endpoint allowlist
- Switch Stripe from test to live mode for production payments
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>
Businesses with BusinessIsDemo=1 or BusinessIsHidden=1 will not appear
in the nearby restaurants list. Hidden businesses will be searchable
in a future update.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The previous approach called getBusiness which requires auth.
Now listPending returns BUSINESS_NAME and HUD uses that.
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>
- When saving a beacon, automatically create service point with same name
- Create lt_Beacon_Businesses_ServicePoints link record
- If UUID already exists, update instead of creating duplicate
- App is authoritative: reassigns beacon/servicepoint/lt_ to current business
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>