diff --git a/app/modules/tenancy/static/merchant/js/merchant-team.js b/app/modules/tenancy/static/merchant/js/merchant-team.js index 01773130..f02176fa 100644 --- a/app/modules/tenancy/static/merchant/js/merchant-team.js +++ b/app/modules/tenancy/static/merchant/js/merchant-team.js @@ -31,6 +31,9 @@ function merchantTeam() { // Filters storeFilter: '', + // Expanded member rows + expandedMembers: [], + // Modal states showInviteModal: false, showEditModal: false, @@ -128,6 +131,39 @@ function merchantTeam() { ); }, + /** + * Toggle expand/collapse for a member's store rows + */ + toggleMemberExpand(userId) { + const idx = this.expandedMembers.indexOf(userId); + if (idx > -1) { + this.expandedMembers.splice(idx, 1); + } else { + this.expandedMembers.push(userId); + } + }, + + /** + * Resend invitation for a specific store membership + */ + async resendStoreInvitation(storeId, userId) { + this.saving = true; + try { + await apiClient.post( + `/merchants/account/team/stores/${storeId}/members/${userId}/resend` + ); + + Utils.showToast(I18n.t('tenancy.messages.invitation_resent'), 'success'); + merchantTeamLog.info('Resent invitation for store:', storeId, 'user:', userId); + await this.loadTeamData(); + } catch (error) { + merchantTeamLog.error('Failed to resend invitation:', error); + Utils.showToast(error.message || 'Failed to resend invitation', 'error'); + } finally { + this.saving = false; + } + }, + /** * Open invite modal with reset form */ diff --git a/app/modules/tenancy/templates/tenancy/merchant/team.html b/app/modules/tenancy/templates/tenancy/merchant/team.html index 758f9db9..13785994 100644 --- a/app/modules/tenancy/templates/tenancy/merchant/team.html +++ b/app/modules/tenancy/templates/tenancy/merchant/team.html @@ -81,98 +81,131 @@ {{ table_header([_('tenancy.team.member'), _('tenancy.team.stores_and_roles'), _('tenancy.team.status'), _('tenancy.team.actions')]) }}