Fix portal login: use normalized DB column names, fix business dropdown

- 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>
This commit is contained in:
John Mizerek 2026-01-31 14:15:37 -08:00
parent 94ee89d1f3
commit c5a332b04e
3 changed files with 14 additions and 12 deletions

View file

@ -42,23 +42,20 @@ try {
abort; abort;
} }
// Get businesses for this user // Get businesses for this user (owner only)
// Users are linked to businesses via UserID field (owner)
q = queryExecute(" q = queryExecute("
SELECT SELECT b.BusinessID, b.BusinessName
b.ID,
b.Name
FROM Businesses b FROM Businesses b
WHERE b.UserID = :userID WHERE b.BusinessUserID = :userID
ORDER BY b.Name ORDER BY b.BusinessName
", { userID: userID }, { datasource: "payfrit" }); ", { userID: userID }, { datasource: "payfrit" });
businesses = []; businesses = [];
for (row in q) { for (row in q) {
arrayAppend(businesses, { arrayAppend(businesses, {
"BusinessID": row.ID, "BusinessID": row.BusinessID,
"Name": row.Name "Name": row.BusinessName
}); });
} }

View file

@ -342,7 +342,12 @@
this.showStep('business'); this.showStep('business');
} }
} else { } else {
errorEl.textContent = data.ERROR || data.MESSAGE || 'Invalid credentials'; const friendlyErrors = {
'bad_credentials': 'Incorrect email/phone or password. Please try again.',
'not_found': 'No account found with that email or phone number.',
'account_disabled': 'This account has been disabled. Please contact support.'
};
errorEl.textContent = friendlyErrors[data.ERROR] || data.MESSAGE || 'Invalid credentials';
errorEl.classList.add('show'); errorEl.classList.add('show');
} }
} catch (err) { } catch (err) {
@ -407,7 +412,7 @@
this.businesses.forEach(biz => { this.businesses.forEach(biz => {
const option = document.createElement('option'); const option = document.createElement('option');
option.value = biz.BusinessID; option.value = biz.BusinessID;
option.textContent = biz.BusinessName; option.textContent = biz.Name;
select.appendChild(option); select.appendChild(option);
}); });

View file

@ -83,7 +83,7 @@ const Portal = {
const data = await response.json(); const data = await response.json();
if (data.OK && data.BUSINESSES) { if (data.OK && data.BUSINESSES) {
const hasAccess = data.BUSINESSES.some(b => b.ID === this.config.businessId); const hasAccess = data.BUSINESSES.some(b => b.BusinessID === this.config.businessId);
if (!hasAccess && data.BUSINESSES.length > 0) { if (!hasAccess && data.BUSINESSES.length > 0) {
// User doesn't have access to requested business, use their first business // User doesn't have access to requested business, use their first business
this.config.businessId = data.BUSINESSES[0].BusinessID; this.config.businessId = data.BUSINESSES[0].BusinessID;