diff --git a/api/portal/addTeamMember.cfm b/api/portal/addTeamMember.cfm index 225394e..1e29494 100644 --- a/api/portal/addTeamMember.cfm +++ b/api/portal/addTeamMember.cfm @@ -22,6 +22,8 @@ function readJsonBody() { data = readJsonBody(); businessId = structKeyExists(data, "BusinessID") ? val(data.BusinessID) : 0; userId = structKeyExists(data, "UserID") ? val(data.UserID) : 0; +roleId = structKeyExists(data, "RoleID") ? val(data.RoleID) : 1; +if (roleId < 1 || roleId > 3) roleId = 1; if (businessId <= 0) { apiAbort({ "OK": false, "ERROR": "missing_business_id" }); @@ -41,12 +43,13 @@ try { ], { datasource: "payfrit" }); if (qCheck.recordCount > 0) { - // Update to active + // Update to active with role queryTimed(" UPDATE Employees - SET IsActive = 1, StatusID = 2 + SET IsActive = 1, StatusID = 2, RoleID = ? WHERE BusinessID = ? AND UserID = ? ", [ + { value: roleId, cfsqltype: "cf_sql_integer" }, { value: businessId, cfsqltype: "cf_sql_integer" }, { value: userId, cfsqltype: "cf_sql_integer" } ], { datasource: "payfrit" }); @@ -58,11 +61,12 @@ try { // the business relationship is established via ServicePoint -> Beacon chain. // Kept for legacy/convenience but could be derived from context. queryTimed(" - INSERT INTO Employees (BusinessID, UserID, StatusID, IsActive) - VALUES (?, ?, 2, 1) + INSERT INTO Employees (BusinessID, UserID, StatusID, IsActive, RoleID) + VALUES (?, ?, 2, 1, ?) ", [ { value: businessId, cfsqltype: "cf_sql_integer" }, - { value: userId, cfsqltype: "cf_sql_integer" } + { value: userId, cfsqltype: "cf_sql_integer" }, + { value: roleId, cfsqltype: "cf_sql_integer" } ], { datasource: "payfrit" }); qNew = queryTimed("SELECT LAST_INSERT_ID() AS EmployeeID", {}, { datasource: "payfrit" }); diff --git a/api/portal/team.cfm b/api/portal/team.cfm index f1c8e4a..9dfbfbf 100644 --- a/api/portal/team.cfm +++ b/api/portal/team.cfm @@ -45,11 +45,13 @@ try { e.ID, e.UserID, e.StatusID, + e.RoleID, CAST(e.IsActive AS UNSIGNED) AS IsActive, u.FirstName, u.LastName, u.EmailAddress, u.ContactNumber, + COALESCE(sr.Name, 'Staff') AS RoleName, CASE e.StatusID WHEN 0 THEN 'Pending' WHEN 1 THEN 'Invited' @@ -59,6 +61,7 @@ try { END AS StatusName FROM Employees e JOIN Users u ON e.UserID = u.ID + LEFT JOIN tt_StaffRoles sr ON sr.ID = e.RoleID WHERE e.BusinessID = ? ORDER BY e.IsActive DESC, u.FirstName ASC ", [ @@ -75,6 +78,8 @@ try { "LastName": row.LastName, "Email": row.EmailAddress, "Phone": row.ContactNumber, + "RoleID": row.RoleID, + "RoleName": row.RoleName, "StatusID": row.StatusID, "StatusName": row.StatusName, "IsActive": val(row.IsActive) == 1 diff --git a/api/tasks/complete.cfm b/api/tasks/complete.cfm index c18e4ea..2f51966 100644 --- a/api/tasks/complete.cfm +++ b/api/tasks/complete.cfm @@ -50,11 +50,13 @@ SELECT t.ID, t.ClaimedByUserID, t.CompletedOn, t.OrderID, t.TaskTypeID, t.BusinessID, o.UserID AS CustomerUserID, o.ServicePointID, tt.Name AS TaskTypeName, - b.UserID AS BusinessOwnerUserID + b.UserID AS BusinessOwnerUserID, + COALESCE(emp.RoleID, 1) AS WorkerRoleID FROM Tasks t LEFT JOIN Orders o ON o.ID = t.OrderID LEFT JOIN tt_TaskTypes tt ON tt.ID = t.TaskTypeID LEFT JOIN Businesses b ON b.ID = t.BusinessID + LEFT JOIN Employees emp ON emp.BusinessID = t.BusinessID AND emp.UserID = t.ClaimedByUserID AND emp.IsActive = 1 WHERE t.ID = ? ", [ { value = TaskID, cfsqltype = "cf_sql_integer" } ], { datasource = "payfrit" })> @@ -65,6 +67,8 @@ + + @@ -221,9 +225,10 @@ + - + - + + diff --git a/portal/index.html b/portal/index.html index abc3724..7895df4 100644 --- a/portal/index.html +++ b/portal/index.html @@ -372,12 +372,13 @@ Name Email Phone + Role Status Actions - Loading team... + Loading team... diff --git a/portal/portal.js b/portal/portal.js index 80db7f8..ca27356 100644 --- a/portal/portal.js +++ b/portal/portal.js @@ -625,7 +625,7 @@ const Portal = { async loadTeam() { console.log('[Portal] Loading team for business:', this.config.businessId); const tbody = document.getElementById('teamTableBody'); - tbody.innerHTML = 'Loading team...'; + tbody.innerHTML = 'Loading team...'; // Load hiring toggle state from business data this.loadHiringToggle(); @@ -643,7 +643,7 @@ const Portal = { if (data.OK && data.TEAM) { if (data.TEAM.length === 0) { - tbody.innerHTML = 'No team members yet'; + tbody.innerHTML = 'No team members yet'; return; } @@ -657,6 +657,7 @@ const Portal = { ${member.Email || '-'} ${this.formatPhone(member.Phone)} + ${member.RoleName || 'Staff'} ${member.StatusName || 'Unknown'} @@ -668,11 +669,11 @@ const Portal = { `).join(''); } else { - tbody.innerHTML = 'Failed to load team'; + tbody.innerHTML = 'Failed to load team'; } } catch (err) { console.error('[Portal] Error loading team:', err); - tbody.innerHTML = 'Error loading team'; + tbody.innerHTML = 'Error loading team'; } }, @@ -1604,7 +1605,8 @@ const Portal = { headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ BusinessID: this.config.businessId, - UserID: foundUserId + UserID: foundUserId, + RoleID: { staff: 1, manager: 2, admin: 3 }[document.getElementById('inviteRole').value] || 1 }) }); const data = await response.json();