| @@ -228,9 +228,13 @@ app.core.Controller = (function(){ | |||
| { | |||
| app.core.StateManager.switchTo( new app.state.GroupMemberManagement(), r.params ); | |||
| }); | |||
| // rlite.add( 'group/:groupId/membermanagement/:memberId', function( r ) | |||
| // { | |||
| // app.core.StateManager.switchTo( new app.state.GroupMemberManagement(), r.params ); | |||
| // }); | |||
| rlite.add( 'group/:groupId/membermanagement/:memberId', function( r ) | |||
| { | |||
| app.core.StateManager.switchTo( new app.state.GroupMemberManagement(), r.params ); | |||
| app.core.StateManager.switchTo( new app.state.GroupMemberManagementMember(), r.params ); | |||
| }); | |||
| rlite.add( 'group/:groupId/members', function( r ) | |||
| { | |||
| @@ -544,6 +544,10 @@ app.core.Dict = { | |||
| "STATS_REPORTING" : 'Reporting', | |||
| 'STATS_PLANNING' : 'Planung', | |||
| "DO_YOU_REALLY_WANT_TO_DELETE_THIS_CONTRACT" : "Möchtest Du diesen Vertrag wirklich löschen?", | |||
| "GROUP_MANAGEMENT_MEMBERS_ACTIVE" : "Aktiv", | |||
| "GROUP_MANAGEMENT_MEMBERS_INACTIVE" : "Inaktiv", | |||
| "GROUP_MANAGEMENT_MEMBERS_NOT_APPROVED" : "Unbestätigt", | |||
| "GROUP_MANAGEMENT_MEMBERS_CHANGE_STATUS" : "Gruppenstatus ändern" | |||
| }, | |||
| "en" : { | |||
| } | |||
| @@ -12,135 +12,15 @@ app.state.GroupMemberManagement = function() | |||
| state.onEnter = function( p ) | |||
| { | |||
| let $content = app.core.View.getContent(), | |||
| fnRenderMemberForm = null, | |||
| fnGetMemberById = null, | |||
| fnUpdateMemberById = null, | |||
| group = null, | |||
| adminNoteXhr = null, | |||
| playerHistoryXhr = null, | |||
| memberToEdit = null, | |||
| currentMember, | |||
| members = [], | |||
| membersActive = [], | |||
| membersInactive = [], | |||
| membersNotApproved = [], | |||
| groupId = p.groupId, | |||
| memberId = p.hasOwnProperty( 'memberId' ) ? p.memberId : null; | |||
| fnRenderMemberForm = function( profile ) | |||
| { | |||
| $memberContainer = $content.find( '[data-id="member-container"]' ).first(); | |||
| $memberContainer.html( | |||
| app.core.View.getTemplate( | |||
| 'group-member-management-body', | |||
| { | |||
| p : profile, | |||
| g : group | |||
| } | |||
| ) | |||
| ); | |||
| }; | |||
| fnUpdateAppointmentLog = function() | |||
| { | |||
| if ( !memberToEdit ) | |||
| { | |||
| return; | |||
| } | |||
| if ( playerHistoryXhr ) | |||
| { | |||
| playerHistoryXhr.abort(); | |||
| } | |||
| playerHistoryXhr = app.core.Rpc.call( | |||
| 'Team', | |||
| 'getProfileAppointmentLog', | |||
| { | |||
| groupId : group.getId(), | |||
| profileId : memberToEdit.getId(), | |||
| startDt : $content.find( '[data-id="input-appointment-log-from"]' ).first().val(), | |||
| endDt : $content.find( '[data-id="input-appointment-log-until"]' ).first().val() | |||
| }, | |||
| function( res) | |||
| { | |||
| $content.find( '[data-id="container-appointment-log"]' ).first().html( | |||
| app.core.View.getTemplate( | |||
| 'group-member-management-body-appointment-log', | |||
| { | |||
| logs : res.appointmentLog | |||
| } | |||
| ) | |||
| ); | |||
| }, | |||
| function() | |||
| { | |||
| // Do nothing. | |||
| } | |||
| ); | |||
| }; | |||
| fnGetMemberById = function( profileId ) | |||
| { | |||
| var p = null; | |||
| for ( var mi = 0; mi < members.length; mi++ ) | |||
| { | |||
| if ( members[ mi ].getId() == profileId ) | |||
| { | |||
| p = members[ mi ]; | |||
| break; | |||
| } | |||
| } | |||
| return p; | |||
| }; | |||
| fnUpdateMemberById = function( newMember ) | |||
| { | |||
| for ( var mi = 0; mi < members.length; mi++ ) | |||
| { | |||
| if ( members[ mi ].getId() == newMember.getId() ) | |||
| { | |||
| members[ mi ] = newMember; | |||
| break; | |||
| } | |||
| } | |||
| }; | |||
| fnUpdateMemberToEdit = function( mmid ) | |||
| { | |||
| memberToEdit = fnGetMemberById( mmid ); | |||
| fnRenderMemberForm( memberToEdit ); | |||
| if ( memberToEdit ) | |||
| { | |||
| if ( adminNoteXhr ) | |||
| { | |||
| adminNoteXhr.abort(); | |||
| } | |||
| adminNoteXhr = app.core.Rpc.call( | |||
| 'Team', | |||
| 'getAdminNote', | |||
| { | |||
| groupId : group.getId(), | |||
| profileId : memberToEdit.getId() | |||
| }, | |||
| function( res ) | |||
| { | |||
| $content.find( '[data-id="admin-note"]' ).first().html( | |||
| app.core.View.getTemplate( | |||
| 'group-member-management-body-adminnote', | |||
| { | |||
| adminNote : res.adminNote ? res.adminNote : '' | |||
| } | |||
| ) | |||
| ); | |||
| }, | |||
| function() | |||
| { | |||
| // Do nothing | |||
| } | |||
| ); | |||
| } | |||
| fnUpdateAppointmentLog(); | |||
| }; | |||
| memberId = p.hasOwnProperty( 'memberId' ) ? p.memberId : null, | |||
| activeTab = 'inactive'; | |||
| app.gui.PageLoader.show(); | |||
| @@ -150,7 +30,7 @@ app.state.GroupMemberManagement = function() | |||
| { teamId : groupId, includeEmails : true, includeMembers: true }, | |||
| function( res ) | |||
| { | |||
| members.push( res ); | |||
| var member = null, | |||
| $memberContainer = null, | |||
| emails = res.emails ? res.emails : []; | |||
| @@ -168,11 +48,23 @@ app.state.GroupMemberManagement = function() | |||
| break; | |||
| } | |||
| } | |||
| members.push( member ); | |||
| if ( member.getId() == app.model.SessionUser.getProfileId() ) | |||
| { | |||
| currentProfile = member; | |||
| } | |||
| switch (member.getGroupData(groupId).status) { | |||
| case 'active': | |||
| membersActive.push(member); | |||
| break; | |||
| case 'inactive': | |||
| membersInactive.push(member); | |||
| break; | |||
| case 'not_approved': | |||
| membersNotApproved.push(member); | |||
| break; | |||
| } | |||
| } | |||
| app.core.View.setContent( | |||
| @@ -180,9 +72,13 @@ app.state.GroupMemberManagement = function() | |||
| 'group-member-management', | |||
| { | |||
| members : members, | |||
| membersActive: membersActive, | |||
| membersInactive: membersInactive, | |||
| membersNotApproved: membersNotApproved, | |||
| group : group, | |||
| groups : app.model.SessionUser.getAdminGroups(), | |||
| currentProfile : currentProfile | |||
| currentProfile : currentProfile, | |||
| activeTab: activeTab | |||
| } ) | |||
| ); | |||
| @@ -191,142 +87,17 @@ app.state.GroupMemberManagement = function() | |||
| app.core.Controller.redirect( '#/group/' + $(this).val() + '/membermanagement' ); | |||
| }); | |||
| $content.on( 'click', '[data-id="btn-update-role"]', function() | |||
| { | |||
| var newRole = $content.find( '[data-id="select-member-role"]' ).first().val(); | |||
| if ( memberToEdit.getRoleInGroup( group.getId() ) === newRole ) | |||
| { | |||
| return; | |||
| } | |||
| app.gui.PageLoader.show(); | |||
| app.core.Rpc.call( | |||
| 'Team', | |||
| 'changeMemberRole', | |||
| { | |||
| groupId : group.getId(), | |||
| memberId : memberToEdit.getId(), | |||
| newRole : newRole | |||
| }, | |||
| function( res ) | |||
| { | |||
| app.core.View.toastSuccess( _lc( 'MEMBER_ROLE_CHANGED' ) ); | |||
| if ( app.model.SessionUser.isOwnProfile( memberToEdit ) ) | |||
| { | |||
| app.core.Controller.redirect( '#/group/' + group.getId() ); | |||
| } | |||
| app.gui.PageLoader.hide(); | |||
| } | |||
| ); | |||
| }); | |||
| $content.on( 'click', '[data-id="btn-update-contract"]', function() | |||
| { | |||
| var contractUnix = null; | |||
| if ( $content.find( '[data-id="input-contract-moment"]' ).first().val().length ) | |||
| { | |||
| contractUnix = app.util.Helper.getMomentFromInputDate( $content.find( '[data-id="input-contract-moment"]' ).first() ).unix(); | |||
| } | |||
| app.gui.PageLoader.show(); | |||
| app.core.Rpc.call( | |||
| 'Team', | |||
| 'changeMemberContract', | |||
| { | |||
| groupId : group.getId(), | |||
| memberId : memberToEdit.getId(), | |||
| contract : $content.find( '[data-id="input-contract"]' ).first().val(), | |||
| contractDate : contractUnix | |||
| }, | |||
| function( res ) | |||
| { | |||
| app.core.View.toastSuccess( _lc( 'MEMBER_CONTRACT_UPDATED' ) ); | |||
| app.gui.PageLoader.hide(); | |||
| if ( res && res.hasOwnProperty( 'updated_member' ) ) | |||
| { | |||
| memberToEdit.setGroupData( res.updated_member.teams_js ); | |||
| } | |||
| } | |||
| ); | |||
| }); | |||
| $content.on( 'click', '[data-type="appointment-log-item"]', function() | |||
| { | |||
| app.core.Controller.redirect( '#/appointment/' + $(this).attr( 'data-appointment-id' ) ); | |||
| }); | |||
| $content.on( 'click', '[data-id="btn-update-appointment-log"]', function() | |||
| { | |||
| app.core.View.setContentLoader( | |||
| $content.find( '[data-id="container-appointment-log"]' ).first() | |||
| ); | |||
| fnUpdateAppointmentLog(); | |||
| }); | |||
| $content.on( 'click', '[data-id="btn-save-admin-note"]', function() | |||
| { | |||
| app.gui.PageLoader.show(); | |||
| app.core.Rpc.call( | |||
| 'Team', | |||
| 'updateAdminNote', | |||
| { | |||
| groupId : group.getId(), | |||
| profileId : memberToEdit.getId(), | |||
| adminNote : $content.find( '[data-id="textarea-admin-note"]' ).first().val() | |||
| }, | |||
| function() | |||
| { | |||
| app.core.View.toastSuccess( _lc( 'ADMIN_NOTE_SAVED' ) ); | |||
| app.gui.PageLoader.hide(); | |||
| } | |||
| ); | |||
| $content.find( '[data-id=""]' ).first().val() | |||
| }); | |||
| $content.find( '[data-id="select-profil-id"]' ).first().change( function() | |||
| { | |||
| app.core.Controller.redirect( '#/group/' + group.getId() + '/membermanagement/' + $(this).val() ); | |||
| }); | |||
| $content.find( '[data-id="btn-remove-member"]' ).first().click( function() | |||
| $content.on( 'click', '[data-type="member-link"]', function() | |||
| { | |||
| if ( !memberToEdit ) | |||
| { | |||
| app.core.View.toastInfo( _lc( 'PLEASE_SELECT_MEMBER' ) ); | |||
| return; | |||
| } | |||
| if ( 'trainer' == memberToEdit.getRoleInGroup( group.getId() ) ) | |||
| { | |||
| app.core.View.toastInfo( _lc( 'GROUP_OWNER_CANNOT_BE_REMOVED_FROM_GROUP' ) ); | |||
| return; | |||
| } | |||
| app.core.View.confirm( | |||
| _lc( 'DO_YOU_REALLY_WANT_TO_REMOVE_THIS_MEMBER_FROM_TEAM' ), | |||
| function() | |||
| { | |||
| app.gui.PageLoader.show(); | |||
| app.core.Rpc.call( | |||
| 'Team', | |||
| 'removeMember', | |||
| { | |||
| groupId : group.getId(), | |||
| profileId : memberToEdit.getId() | |||
| }, | |||
| function( res ) | |||
| { | |||
| app.core.Controller.redirect( '#/group/' + group.getId() + '/members' ); | |||
| app.core.View.toastSuccess( _lc( 'MEMBER_REMOVED' ) ); | |||
| } | |||
| ); | |||
| }, | |||
| _lc( 'YES_REMOVE' ) | |||
| ); | |||
| var memberId = $(this).attr( 'data-member-id' ); | |||
| app.core.Controller.redirect( '#/group/' + group.getId() + '/membermanagement/' + memberId ); | |||
| }); | |||
| fnRenderMemberForm( null ); | |||
| if ( memberId ) | |||
| { | |||
| @@ -0,0 +1,348 @@ | |||
| /** | |||
| * (c) by aheadware.com | |||
| */ | |||
| var app = app || {}; | |||
| app.state = app.state || {}; | |||
| app.state.GroupMemberManagementMember = function() | |||
| { | |||
| var state = app.core.StateManager.createState( 'group-member-management-member' ); | |||
| state.onEnter = function( p ) | |||
| { | |||
| let $content = app.core.View.getContent(), | |||
| fnRenderMemberForm = null, | |||
| fnGetMemberById = null, | |||
| fnUpdateMemberById = null, | |||
| group = null, | |||
| adminNoteXhr = null, | |||
| playerHistoryXhr = null, | |||
| memberToEdit = null, | |||
| currentMember, | |||
| members = [], | |||
| groupId = p.groupId, | |||
| memberId = p.hasOwnProperty( 'memberId' ) ? p.memberId : null; | |||
| fnRenderMemberForm = function( profile ) | |||
| { | |||
| console.log(profile); | |||
| //console.log(profile.getGroupData(groupId)); | |||
| // console.log(group); | |||
| //console.log(profile.getGroupData(groupId).status); | |||
| $memberContainer = $content.find( '[data-id="member-container"]' ).first(); | |||
| $memberContainer.html( | |||
| app.core.View.getTemplate( | |||
| 'group-member-management-member-body', | |||
| { | |||
| p : profile, | |||
| g : group, | |||
| } | |||
| ) | |||
| ); | |||
| }; | |||
| fnUpdateAppointmentLog = function() | |||
| { | |||
| if ( !memberToEdit ) | |||
| { | |||
| return; | |||
| } | |||
| if ( playerHistoryXhr ) | |||
| { | |||
| playerHistoryXhr.abort(); | |||
| } | |||
| playerHistoryXhr = app.core.Rpc.call( | |||
| 'Team', | |||
| 'getProfileAppointmentLog', | |||
| { | |||
| groupId : group.getId(), | |||
| profileId : memberToEdit.getId(), | |||
| startDt : $content.find( '[data-id="input-appointment-log-from"]' ).first().val(), | |||
| endDt : $content.find( '[data-id="input-appointment-log-until"]' ).first().val() | |||
| }, | |||
| function( res) | |||
| { | |||
| $content.find( '[data-id="container-appointment-log"]' ).first().html( | |||
| app.core.View.getTemplate( | |||
| 'group-member-management-member-body-appointment-log', | |||
| { | |||
| logs : res.appointmentLog | |||
| } | |||
| ) | |||
| ); | |||
| }, | |||
| function() | |||
| { | |||
| // Do nothing. | |||
| } | |||
| ); | |||
| }; | |||
| fnGetMemberById = function( profileId ) | |||
| { | |||
| var p = null; | |||
| for ( var mi = 0; mi < members.length; mi++ ) | |||
| { | |||
| if ( members[ mi ].getId() == profileId ) | |||
| { | |||
| p = members[ mi ]; | |||
| break; | |||
| } | |||
| } | |||
| return p; | |||
| }; | |||
| fnUpdateMemberById = function( newMember ) | |||
| { | |||
| for ( var mi = 0; mi < members.length; mi++ ) | |||
| { | |||
| if ( members[ mi ].getId() == newMember.getId() ) | |||
| { | |||
| members[ mi ] = newMember; | |||
| break; | |||
| } | |||
| } | |||
| }; | |||
| fnUpdateMemberToEdit = function( mmid ) | |||
| { | |||
| memberToEdit = fnGetMemberById( mmid ); | |||
| fnRenderMemberForm( memberToEdit ); | |||
| if ( memberToEdit ) | |||
| { | |||
| if ( adminNoteXhr ) | |||
| { | |||
| adminNoteXhr.abort(); | |||
| } | |||
| adminNoteXhr = app.core.Rpc.call( | |||
| 'Team', | |||
| 'getAdminNote', | |||
| { | |||
| groupId : group.getId(), | |||
| profileId : memberToEdit.getId() | |||
| }, | |||
| function( res ) | |||
| { | |||
| $content.find( '[data-id="admin-note"]' ).first().html( | |||
| app.core.View.getTemplate( | |||
| 'group-member-management-member-body-adminnote', | |||
| { | |||
| adminNote : res.adminNote ? res.adminNote : '' | |||
| } | |||
| ) | |||
| ); | |||
| }, | |||
| function() | |||
| { | |||
| // Do nothing | |||
| } | |||
| ); | |||
| } | |||
| fnUpdateAppointmentLog(); | |||
| }; | |||
| app.gui.PageLoader.show(); | |||
| app.core.Rpc.call( | |||
| 'Team', | |||
| 'getDetails', | |||
| { teamId : groupId, includeEmails : true, includeMembers: true }, | |||
| function( res ) | |||
| { | |||
| var member = null, | |||
| $memberContainer = null, | |||
| emails = res.emails ? res.emails : []; | |||
| group = new app.model.Group( res.team ); | |||
| for ( var mi = 0; mi < res.members.length; mi++ ) | |||
| { | |||
| member = new app.model.Profile( res.members[ mi ] ); | |||
| for ( var ei = 0; ei < emails.length; ei++ ) | |||
| { | |||
| if ( member.getAccountId() == emails[ ei ].id ) | |||
| { | |||
| member.setEmail( emails[ ei ].email ); | |||
| break; | |||
| } | |||
| } | |||
| members.push( member ); | |||
| if ( member.getId() == app.model.SessionUser.getProfileId() ) | |||
| { | |||
| currentProfile = member; | |||
| } | |||
| } | |||
| app.core.View.setContent( | |||
| app.core.View.getTemplate( | |||
| 'group-member-management-member', | |||
| { | |||
| members : members, | |||
| group : group, | |||
| groups : app.model.SessionUser.getAdminGroups(), | |||
| currentProfile : currentProfile | |||
| } ) | |||
| ); | |||
| $content.find( '[data-id="select-group-id"]' ).first().change( function() | |||
| { | |||
| app.core.Controller.redirect( '#/group/' + $(this).val() + '/membermanagement' ); | |||
| }); | |||
| $content.on( 'click', '[data-id="btn-update-role"]', function() | |||
| { | |||
| var newRole = $content.find( '[data-id="select-member-role"]' ).first().val(); | |||
| if ( memberToEdit.getRoleInGroup( group.getId() ) === newRole ) | |||
| { | |||
| return; | |||
| } | |||
| app.gui.PageLoader.show(); | |||
| app.core.Rpc.call( | |||
| 'Team', | |||
| 'changeMemberRole', | |||
| { | |||
| groupId : group.getId(), | |||
| memberId : memberToEdit.getId(), | |||
| newRole : newRole | |||
| }, | |||
| function( res ) | |||
| { | |||
| app.core.View.toastSuccess( _lc( 'MEMBER_ROLE_CHANGED' ) ); | |||
| if ( app.model.SessionUser.isOwnProfile( memberToEdit ) ) | |||
| { | |||
| app.core.Controller.redirect( '#/group/' + group.getId() ); | |||
| } | |||
| app.gui.PageLoader.hide(); | |||
| } | |||
| ); | |||
| }); | |||
| $content.on( 'click', '[data-id="btn-update-contract"]', function() | |||
| { | |||
| var contractUnix = null; | |||
| if ( $content.find( '[data-id="input-contract-moment"]' ).first().val().length ) | |||
| { | |||
| contractUnix = app.util.Helper.getMomentFromInputDate( $content.find( '[data-id="input-contract-moment"]' ).first() ).unix(); | |||
| } | |||
| app.gui.PageLoader.show(); | |||
| app.core.Rpc.call( | |||
| 'Team', | |||
| 'changeMemberContract', | |||
| { | |||
| groupId : group.getId(), | |||
| memberId : memberToEdit.getId(), | |||
| contract : $content.find( '[data-id="input-contract"]' ).first().val(), | |||
| contractDate : contractUnix | |||
| }, | |||
| function( res ) | |||
| { | |||
| app.core.View.toastSuccess( _lc( 'MEMBER_CONTRACT_UPDATED' ) ); | |||
| app.gui.PageLoader.hide(); | |||
| if ( res && res.hasOwnProperty( 'updated_member' ) ) | |||
| { | |||
| memberToEdit.setGroupData( res.updated_member.teams_js ); | |||
| } | |||
| } | |||
| ); | |||
| }); | |||
| $content.on( 'click', '[data-type="appointment-log-item"]', function() | |||
| { | |||
| app.core.Controller.redirect( '#/appointment/' + $(this).attr( 'data-appointment-id' ) ); | |||
| }); | |||
| $content.on( 'click', '[data-id="btn-update-appointment-log"]', function() | |||
| { | |||
| app.core.View.setContentLoader( | |||
| $content.find( '[data-id="container-appointment-log"]' ).first() | |||
| ); | |||
| fnUpdateAppointmentLog(); | |||
| }); | |||
| $content.on( 'click', '[data-id="btn-save-admin-note"]', function() | |||
| { | |||
| app.gui.PageLoader.show(); | |||
| app.core.Rpc.call( | |||
| 'Team', | |||
| 'updateAdminNote', | |||
| { | |||
| groupId : group.getId(), | |||
| profileId : memberToEdit.getId(), | |||
| adminNote : $content.find( '[data-id="textarea-admin-note"]' ).first().val() | |||
| }, | |||
| function() | |||
| { | |||
| app.core.View.toastSuccess( _lc( 'ADMIN_NOTE_SAVED' ) ); | |||
| app.gui.PageLoader.hide(); | |||
| } | |||
| ); | |||
| $content.find( '[data-id=""]' ).first().val() | |||
| }); | |||
| $content.find( '[data-id="select-profil-id"]' ).first().change( function() | |||
| { | |||
| app.core.Controller.redirect( '#/group/' + group.getId() + '/membermanagement/' + $(this).val() ); | |||
| }); | |||
| $content.find( '[data-id="btn-remove-member"]' ).first().click( function() | |||
| { | |||
| if ( !memberToEdit ) | |||
| { | |||
| app.core.View.toastInfo( _lc( 'PLEASE_SELECT_MEMBER' ) ); | |||
| return; | |||
| } | |||
| if ( 'trainer' == memberToEdit.getRoleInGroup( group.getId() ) ) | |||
| { | |||
| app.core.View.toastInfo( _lc( 'GROUP_OWNER_CANNOT_BE_REMOVED_FROM_GROUP' ) ); | |||
| return; | |||
| } | |||
| app.core.View.confirm( | |||
| _lc( 'DO_YOU_REALLY_WANT_TO_REMOVE_THIS_MEMBER_FROM_TEAM' ), | |||
| function() | |||
| { | |||
| app.gui.PageLoader.show(); | |||
| app.core.Rpc.call( | |||
| 'Team', | |||
| 'removeMember', | |||
| { | |||
| groupId : group.getId(), | |||
| profileId : memberToEdit.getId() | |||
| }, | |||
| function( res ) | |||
| { | |||
| app.core.Controller.redirect( '#/group/' + group.getId() + '/members' ); | |||
| app.core.View.toastSuccess( _lc( 'MEMBER_REMOVED' ) ); | |||
| } | |||
| ); | |||
| }, | |||
| _lc( 'YES_REMOVE' ) | |||
| ); | |||
| }); | |||
| fnRenderMemberForm( null ); | |||
| if ( memberId ) | |||
| { | |||
| $content.find( '[data-id="select-profil-id"]' ).first().val( memberId ); | |||
| $content.find( '[data-id="select-profil-id"]' ).first().trigger( 'change' ); | |||
| fnUpdateMemberToEdit( memberId ) | |||
| } | |||
| app.gui.PageLoader.hide(); | |||
| } | |||
| ); | |||
| }; | |||
| return state; | |||
| }; | |||
| @@ -0,0 +1,3 @@ | |||
| <textarea class="form-control" | |||
| style="height: 120px" | |||
| data-id="textarea-admin-note"><%= adminNote %></textarea> | |||
| @@ -0,0 +1,62 @@ | |||
| <div class="table-responsive"> | |||
| <table class="table"> | |||
| <thead> | |||
| <tr> | |||
| <th style="border-top: none"> | |||
| <%= _lc( 'COURSE' ) %> | |||
| </th> | |||
| <th style="border-top: none"> | |||
| <%= _lc( 'STARTTIME' ) %> | |||
| </th> | |||
| <th style="border-top: none"> | |||
| <%= _lc( 'ENDTIME' ) %> | |||
| </th> | |||
| <th style="border-top: none"> | |||
| | |||
| </th> | |||
| </tr> | |||
| </thead> | |||
| <tbody> | |||
| <% if ( logs && logs.length > 0 ) { %> | |||
| <% for ( var li = 0; li < logs.length; li++ ) { %> | |||
| <tr data-appointment-id="<%= logs[ li ].appointment_id %>" | |||
| data-type="appointment-log-item" | |||
| class="clickable"> | |||
| <td> | |||
| <%= logs[ li ].subject %><br /> | |||
| <small> | |||
| <%= _lc( 'ATTENDANCE' ) %> | |||
| <% if ( 'accepted' === logs[ li ].status ) { %> | |||
| (<%= _lc( 'WITH_ACCEPTED_FEEDBACK' ) %>) | |||
| <% } else { %> | |||
| (<%= _lc( 'WITHOUT_ACCEPTED_FEEDBACK' ) %>) | |||
| <% } %> | |||
| </small> | |||
| </td> | |||
| <td> | |||
| <%= app.util.Helper.getMomentFromUTCTime( logs[ li ].start_dt ).format( 'DD.MM.YYYY [-] HH:mm' ) %> | |||
| </td> | |||
| <td> | |||
| <%= app.util.Helper.getMomentFromUTCTime( logs[ li ].end_dt ).format( 'DD.MM.YYYY [-] HH:mm' ) %> | |||
| </td> | |||
| <td> | |||
| <i class="fas fa-chevron-right"></i> | |||
| </td> | |||
| </tr> | |||
| <% } %> | |||
| <% } else { %> | |||
| <tr> | |||
| <td colspan="4"> | |||
| <%= _lc( 'NO_LOG_ENTRIES_FOUND' ) %> | |||
| </td> | |||
| </tr> | |||
| <% } %> | |||
| </tbody> | |||
| </table> | |||
| </div> | |||
| @@ -0,0 +1,283 @@ | |||
| <% if ( p ) { %> | |||
| <div class="row"> | |||
| <div class="col text-center"> | |||
| <img class="img-fluid rounded-circle profile-image-big img-thumbnail" | |||
| style="margin-bottom: 12px; padding: 6px" | |||
| src="<%= p.getProfileImg() %>" /> | |||
| </div> | |||
| </div> | |||
| <div class="row"> | |||
| <div class="col text-center"> | |||
| <div style="font-size: 1.4rem"> | |||
| <%=raw p.getName() %> | |||
| </div> | |||
| <% if ( p.isInGroupCategory( 'DOGSCHOOL' ) ) { %> | |||
| <div class="profile-header"> | |||
| <%= _lc( 'PROFILE_DOGNAME' ) %> | |||
| </div> | |||
| <div class="profile-content"> | |||
| <%= p.getCustomGroupProperty( 'DOGSCHOOL', 'dogname' ) ? p.getCustomGroupProperty( 'DOGSCHOOL', 'dogname' ) : '---' %> | |||
| </div> | |||
| <% } %> | |||
| <div class="profile-header"> | |||
| <%= _lc( 'PROFILE_STATUS' ) %> | |||
| </div> | |||
| <div class="profile-content"> | |||
| <%= p.getStatus() %> | |||
| </div> | |||
| <div class="profile-header"> | |||
| <%= _lc( 'ADDRESS' ) %> | |||
| </div> | |||
| <div class="profile-content"> | |||
| <%= p.getStreet() ? p.getStreet() : '---' %><br /> | |||
| <%= p.getZipCode() ? p.getZipCode() : '' %> <%= p.getCity() ? p.getCity() : '' %> | |||
| </div> | |||
| <div class="profile-header"> | |||
| <%= _lc( 'PHONE' ) %> | |||
| </div> | |||
| <div class="profile-content"> | |||
| <% if ( p.getMobile() ) { %> | |||
| <a href="tel:<%= p.getMobile() %>"><%= p.getMobile() %></a> | |||
| <% } else { %> | |||
| --- | |||
| <% } %> | |||
| <br /> | |||
| <% if ( p.getPhone() ) { %> | |||
| <a href="tel:<%= p.getPhone() %>"><%= p.getPhone() %></a> | |||
| <% } else { %> | |||
| --- | |||
| <% } %> | |||
| </div> | |||
| <div class="profile-header"> | |||
| <%= _lc( 'EMAIL' ) %> | |||
| </div> | |||
| <div class="profile-content"> | |||
| <% if ( p.getEmail() ) { %> | |||
| <a href="mailto:<%= p.getEmail() %>"><%= p.getEmail() %></a> | |||
| <% } else { %> | |||
| --- | |||
| <% } %> | |||
| </div> | |||
| <div class="profile-header"> | |||
| <%= _lc( 'BIRTHDAY' ) %> | |||
| </div> | |||
| <div class="profile-content"> | |||
| <%= ( null != p.getMomentBirthday() ) ? p.getMomentBirthday().format( 'DD.MM.YYYY' ) : '---' %> | |||
| </div> | |||
| <div class="profile-header"> | |||
| <%= _lc( 'JOIN_DT' ) %> | |||
| </div> | |||
| <div class="profile-content"> | |||
| <% var momentJoin = p.getMomentJoinInGroup( g.getId() ); %> | |||
| <%= ( null != momentJoin ) ? momentJoin.format( 'DD.MM.YYYY' ) : '---' %> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| <hr /> | |||
| <div class="row"> | |||
| <div class="col"> | |||
| <strong><%= _lc( 'CHANGE_ROLE' ) %></strong> | |||
| </div> | |||
| </div> | |||
| <div class="row"> | |||
| <div class="col-6"> | |||
| <select class="form-control form-control-sm" | |||
| <%= ( 'trainer' === p.getRoleInGroup( g.getId() ) ) ? 'disabled="disabled"' : '' %> | |||
| data-id="select-member-role"> | |||
| <option value="player" <%= ( 'player' === p.getRoleInGroup( g.getId() ) ) ? 'selected="selected"' : '' %> > | |||
| <%= _lc( 'GROUP_MEMBER' ) %> | |||
| </option> | |||
| <option value="cotrainer" <%= ( 'cotrainer' === p.getRoleInGroup( g.getId() ) ) ? 'selected="selected"' : '' %> > | |||
| <%= _lc( 'GROUP_ADMIN' ) %> | |||
| </option> | |||
| <% if ( 'trainer' === p.getRoleInGroup( g.getId() ) ) { %> | |||
| <option value="trainer" <%= ( 'trainer' === p.getRoleInGroup( g.getId() ) ) ? 'selected="selected"' : '' %> > | |||
| <%= _lc( 'GROUP_OWNER' ) %> | |||
| </option> | |||
| <% } %> | |||
| </select> | |||
| </div> | |||
| <div class="col"> | |||
| <button class="btn btn-primary btn-sm" | |||
| data-id="btn-update-role"> | |||
| <%= _lc( 'BTN_SAVE_NEW_ROLE' ) %> | |||
| </button> | |||
| </div> | |||
| <% if ( 'trainer' === p.getRoleInGroup( g.getId() ) ) { %> | |||
| <div class="col-sm-12"> | |||
| <small><i><%= _lc( 'CANNOT_CHANGE_GROUP_OWNER_ROLE_INFO' ) %></i></small> | |||
| </div> | |||
| <% } %> | |||
| </div> | |||
| <hr /> | |||
| <div class="row"> | |||
| <div class="col"> | |||
| <strong><%= _lc( 'GROUP_MANAGEMENT_MEMBERS_CHANGE_STATUS' ) %></strong> | |||
| </div> | |||
| </div> | |||
| <div class="row"> | |||
| <div class="col-6"> | |||
| <select class="form-control form-control-sm" data-id="select-member-status"> | |||
| <option value="active" <%= ( 'active' === p.getGroupData( g.getId() ).status ) ? 'selected="selected"' : '' %> > | |||
| <%= _lc( 'GROUP_MANAGEMENT_MEMBERS_ACTIVE' ) %> | |||
| </option> | |||
| <option value="inactive" <%= ( 'inactive' === p.getGroupData( g.getId() ).status ) ? 'selected="selected"' : '' %> > | |||
| <%= _lc( 'GROUP_MANAGEMENT_MEMBERS_INACTIVE' ) %> | |||
| </option> | |||
| <option value="not_approved" <%= ( 'not_approved' === p.getGroupData( g.getId() ).status ) ? 'selected="selected"' : '' %> > | |||
| <%= _lc( 'GROUP_MANAGEMENT_MEMBERS_NOT_APPROVED' ) %> | |||
| </option> | |||
| </select> | |||
| </div> | |||
| <div class="col"> | |||
| <button class="btn btn-primary btn-sm" | |||
| data-id="btn-update-role"> | |||
| <%= _lc( 'BTN_SAVE_NEW_ROLE' ) %> | |||
| </button> | |||
| </div> | |||
| <% if ( 'trainer' === p.getRoleInGroup( g.getId() ) ) { %> | |||
| <div class="col-sm-12"> | |||
| <small><i><%= _lc( 'CANNOT_CHANGE_GROUP_OWNER_ROLE_INFO' ) %></i></small> | |||
| </div> | |||
| <% } %> | |||
| </div> | |||
| <hr /> | |||
| <div class="row"> | |||
| <div class="col"> | |||
| <strong><%= _lc( 'ASSIGNED_MEMBER_GROUP_CATEGORIES' ) %></strong> | |||
| </div> | |||
| </div> | |||
| <div class="row"> | |||
| <div class="col"> | |||
| <% var cgs = g.getCourseCategoriesForProfile( p ); %> | |||
| <% for ( var cgsi = 0; cgsi < cgs.length; cgsi++ ) { %> | |||
| <% if ( cgsi > 0 ) { %> | |||
| <%= ' ' %> | |||
| <% } %> | |||
| <span class="badge badge-pill badge-primary"><%= cgs[ cgsi ].name %></span> | |||
| <% } %> | |||
| </div> | |||
| <div class="col-sm-12"> | |||
| <small><i><%= _lc( 'ASSIGNED_MEMBER_CATEOGORY_INFO' ) %></i></small> | |||
| </div> | |||
| <div class="col"> | |||
| <a href="#/course/categories/<%= g.getId() %>" | |||
| class="btn btn-primary btn-sm"> | |||
| <%= _lc( 'BTN_NAVIGATE_TO_CATEGORY_MANAGEMENT' ) %> | |||
| </a> | |||
| </div> | |||
| </div> | |||
| <hr /> | |||
| <div class="row"> | |||
| <div class="col"> | |||
| <strong><%= _lc( 'MEMBER_CONTRACT' ) %></strong> | |||
| </div> | |||
| </div> | |||
| <div class="row"> | |||
| <div class="col-6"> | |||
| <div class="form-group" style="margin-bottom:0;"> | |||
| <label for="appointment-log-until"> | |||
| <%= _lc( 'CONTRACT_NAME' ) %> | |||
| </label> | |||
| <input type="text" | |||
| class="form-control" | |||
| maxlength="128" | |||
| value="<%= p.getContractInGroup( g.getId() ) ? p.getContractInGroup( g.getId() ) : '' %>" | |||
| data-id="input-contract" /> | |||
| </div> | |||
| </div> | |||
| <div class="col-6"> | |||
| <div class="form-group" style="margin-bottom:0;"> | |||
| <label for="contract-date"> | |||
| <%= _lc( 'CONTRACT_DATE' ) %> | |||
| </label> | |||
| <input type="date" | |||
| id="contract-date" | |||
| value="<%= p.getContractMomentInGroup( g.getId() ) ? p.getContractMomentInGroup( g.getId() ).format( 'YYYY-MM-DD' ) : '' %>" | |||
| data-id="input-contract-moment" | |||
| class="form-control" /> | |||
| </div> | |||
| </div> | |||
| <div class="col"> | |||
| <button class="btn btn-primary btn-sm" | |||
| data-id="btn-update-contract"> | |||
| <%= _lc( 'BTN_SAVE_MEMBER_CONTRACT' ) %> | |||
| </button> | |||
| </div> | |||
| </div> | |||
| <hr /> | |||
| <div class="row"> | |||
| <div class="col"> | |||
| <strong><%= _lc( 'APPOINTMENT_LOG' ) %></strong> | |||
| </div> | |||
| </div> | |||
| <div class="row"> | |||
| <div class="col-lg-6 col-md-12"> | |||
| <div class="form-group" style="margin-bottom:0;"> | |||
| <label for="appointment-log-from"> | |||
| <%= _lc( 'FROM' ) %> | |||
| </label> | |||
| <input type="date" | |||
| id="appointment-log-from" | |||
| value="<%= p.getContractMomentInGroup( g.getId() ) ? p.getContractMomentInGroup( g.getId() ).format( 'YYYY-MM-DD' ) : moment().subtract( 30, 'days' ).format( 'YYYY-MM-DD' ) %>" | |||
| data-id="input-appointment-log-from" | |||
| class="form-control" /> | |||
| </div> | |||
| </div> | |||
| <div class="col-lg-6 col-md-12"> | |||
| <div class="form-group" style="margin-bottom:0;"> | |||
| <label for="appointment-log-until"> | |||
| <%= _lc( 'UNTIL' ) %> | |||
| </label> | |||
| <input type="date" | |||
| id="appointment-log-until" | |||
| value="<%= moment().format( 'YYYY-MM-DD' ) %>" | |||
| data-id="input-appointment-log-until" | |||
| class="form-control" /> | |||
| </div> | |||
| </div> | |||
| <div class="col"> | |||
| <button class="btn btn-primary btn-sm" | |||
| data-id="btn-update-appointment-log"> | |||
| <%= _lc( 'BTN_UPDATE_APPOINTMENT_LOG' ) %> | |||
| </button> | |||
| </div> | |||
| </div> | |||
| <div class="row"> | |||
| <div class="col" | |||
| data-id="container-appointment-log"> | |||
| <i class="fas fa-spinner fa-spin"></i> | |||
| </div> | |||
| </div> | |||
| <hr /> | |||
| <div class="row"> | |||
| <div class="col"> | |||
| <strong><%= _lc( 'ADMIN_NOTES' ) %></strong><small> - <%= _lc( 'ADMIN_NOTES_INFO' ) %></small> | |||
| </div> | |||
| </div> | |||
| <div class="row"> | |||
| <div class="col" | |||
| data-id="admin-note"> | |||
| <i class="fas fa-spinner fa-spin"></i> | |||
| </div> | |||
| </div> | |||
| <div class="row"> | |||
| <div class="col"> | |||
| <button class="btn btn-primary btn-sm" | |||
| data-id="btn-save-admin-note"> | |||
| <%= _lc( 'BTN_SAVE_ADMIN_NOTE' ) %> | |||
| </button> | |||
| </div> | |||
| </div> | |||
| <% } else { %> | |||
| <div class="row"> | |||
| <div class="col"> | |||
| <%= _lc( 'SELECT_MEMBER_TO_EDIT' ) %> | |||
| </div> | |||
| </div> | |||
| <% } %> | |||
| @@ -0,0 +1,20 @@ | |||
| <h4><a href="#/group/<%= group.getId() %>/membermanagement"><i class="fas fa-chevron-left"></i></a> <%= _lc( 'GROUP_EDIT_MEMBERS' ) %></h4> | |||
| <div class="row"> | |||
| <div class="col-sm-12"> | |||
| <div class="card"> | |||
| <div class="card-header"></div> | |||
| <div class="card-body" | |||
| data-id="member-container"> | |||
| </div> | |||
| <div class="card-footer"> | |||
| <a href="#/group/<%= group.getId() %>/members" | |||
| class="btn btn-sm btn-secondary"> | |||
| <%= _lc( 'BTN_CANCEL' ) %> | |||
| </a> | |||
| <button data-id="btn-remove-member" | |||
| class="float-right btn btn-sm btn-danger"><%= _lc( 'BTN_REMOVE_MEMBER' ) %></button> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| @@ -0,0 +1,34 @@ | |||
| <tr class="<%= m.isAccessible() ? 'clickable' : '' %>" data-type=member-link data-member-id="<%= m.getId() %>"> | |||
| <td> | |||
| <img class="img-fluid rounded-circle profile-image-table img-thumbnail" | |||
| src="<%= m.getProfileImg() %>"> | |||
| </td> | |||
| <td class="align-middle"> | |||
| <div> | |||
| <% if ( m.isOwnerOfGroup( g.getId() ) ) { %> | |||
| <span class="badge badge-primary"><%= _lc( 'GROUP_OWNER' ) %></span> | |||
| <% } else if ( m.isAdminOfGroup( g.getId() ) ) { %> | |||
| <span class="badge badge-primary"><%= _lc( 'GROUP_ADMIN' ) %></span> | |||
| <% } %> | |||
| <% if ( m.isOwn() ) { %> | |||
| <strong><%=raw m.getName( g.getId() ) %></strong> | |||
| <% } else { %> | |||
| <%=raw m.getName( g.getId() ) %> | |||
| <% } %> | |||
| </div> | |||
| <div class="appointment-original-status"> | |||
| <small> | |||
| <% if ( g.getCategory() === "DOGSCHOOL" && !m.isAnonymousInGroup( g.getId() ) ) { %> | |||
| <i class="fas fa-paw"></i> <%= m.getCustomGroupProperty( 'DOGSCHOOL', 'dogname' ) ? m.getCustomGroupProperty( 'DOGSCHOOL', 'dogname' ) : '---' %> | |||
| <% } %> | |||
| </small> | |||
| </div> | |||
| </td> | |||
| <td class="align-middle"> | |||
| <% if ( m.isAccessible() ) { %> | |||
| <i class="fas fa-chevron-right"></i> | |||
| <% } else { %> | |||
| | |||
| <% } %> | |||
| </td> | |||
| </tr> | |||
| @@ -1,4 +1,4 @@ | |||
| <h4><a href="#/group/<%= group.getId() %>/members"><i class="fas fa-chevron-left"></i></a> <%= _lc( 'GROUP_EDIT_MEMBERS' ) %></h4> | |||
| <h4><a href="#/home"><i class="fas fa-chevron-left"></i></a> <%= _lc( 'BTN_BACK_TO_HOME' ) %></h4> | |||
| <div class="row"> | |||
| <div class="col-sm-12"> | |||
| <div class="card"> | |||
| @@ -17,33 +17,69 @@ | |||
| <% } %> | |||
| </select> | |||
| </div> | |||
| <div class="col"> | |||
| <label><%= _lc( 'MEMBER' ) %></label> | |||
| <select class="form-control form-control-sm" | |||
| data-id="select-profil-id"> | |||
| <option value="0"> | |||
| <%= _lc( 'PLEASE_SELECT_MEMBER_TO_EDIT' ) %> | |||
| </option> | |||
| <% for ( var mi = 0; mi < members.length; mi++ ) { %> | |||
| <option value="<%= members[ mi ].getId() %>"> | |||
| <%= members[ mi ].getName() %> | |||
| </option> | |||
| </div> | |||
| </div> | |||
| <div class="card-body" data-id="member-container"> | |||
| <!-- tab bar --> | |||
| <ul class="nav nav-tabs page-nav <%= ( activeTab == 'active' ) ? 'active' : '' %>"> | |||
| <li class="nav-item"> | |||
| <a class="nav-link"> | |||
| <i class="fas fa-users"></i> | |||
| <%= _lc( 'GROUP_MANAGEMENT_MEMBERS_ACTIVE' ) %> (<%= membersActive.length %>) | |||
| </a> | |||
| </li> | |||
| <li class="nav-item <%= ( activeTab == 'inactive' ) ? 'active' : '' %>"> | |||
| <a class="nav-link"> | |||
| <i class="fas fa-users"></i> | |||
| <%= _lc( 'GROUP_MANAGEMENT_MEMBERS_INACTIVE' ) %> (<%= membersInactive.length %>) | |||
| </a> | |||
| </li> | |||
| <li class="nav-item <%= ( activeTab == 'not_approved' ) ? 'active' : '' %>"> | |||
| <a class="nav-link"> | |||
| <i class="fas fa-users"></i> | |||
| <%= _lc( 'GROUP_MANAGEMENT_MEMBERS_NOT_APPROVED' ) %> (<%= membersNotApproved.length %>) | |||
| </a> | |||
| </li> | |||
| </ul> | |||
| <!-- active members --> | |||
| <div class="group-members-active-content <%= ( activeTab == 'active' ) ? 'show' : 'hide' %>"> | |||
| <div class="table-responsive"> | |||
| <table class="table table-profiles"> | |||
| <tbody> | |||
| <% for ( var mi = 0; mi < membersActive.length; mi++ ) { %> | |||
| <%=raw app.core.View.getTemplate( 'group-member-management-row', { m : membersActive[ mi ], g : group } ) %> | |||
| <% } %> | |||
| </select> | |||
| </tbody> | |||
| </table> | |||
| </div> | |||
| </div> | |||
| <!-- inactive members --> | |||
| <div class="group-members-inactive-content <%= ( activeTab == 'inactive' ) ? 'show' : 'hide' %>"> | |||
| <div class="table-responsive"> | |||
| <table class="table table-profiles"> | |||
| <tbody> | |||
| <% for ( var mi = 0; mi < membersInactive.length; mi++ ) { %> | |||
| <%=raw app.core.View.getTemplate( 'group-member-management-row', { m : membersInactive[ mi ], g : group } ) %> | |||
| <% } %> | |||
| </tbody> | |||
| </table> | |||
| </div> | |||
| </div> | |||
| <div class="group-members-not-approved-content <%= ( activeTab == 'not_approved' ) ? 'show' : 'hide' %>"> | |||
| <div class="table-responsive"> | |||
| <table class="table table-profiles"> | |||
| <tbody> | |||
| <% for ( var mi = 0; mi < membersNotApproved.length; mi++ ) { %> | |||
| <%=raw app.core.View.getTemplate( 'group-member-management-row', { m : membersNotApproved[ mi ], g : group } ) %> | |||
| <% } %> | |||
| </tbody> | |||
| </table> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| <div class="card-body" | |||
| data-id="member-container"> | |||
| </div> | |||
| <div class="card-footer"> | |||
| <a href="#/group/<%= group.getId() %>/members" | |||
| class="btn btn-sm btn-secondary"> | |||
| <%= _lc( 'BTN_CANCEL' ) %> | |||
| </a> | |||
| <button data-id="btn-remove-member" | |||
| class="float-right btn btn-sm btn-danger"><%= _lc( 'BTN_REMOVE_MEMBER' ) %></button> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| @@ -34,12 +34,6 @@ | |||
| </div> | |||
| </div> | |||
| <div class="card-footer"> | |||
| <% if ( currentProfile.isAdminOfGroup( group.getId() ) ) { %> | |||
| <a href="#/group/<%= group.getId() %>/membermanagement" | |||
| class="btn btn-sm btn-primary"> | |||
| <%= _lc( 'EDIT_MEMBERS' ) %> | |||
| </a> | |||
| <% } %> | |||
| <% if ( false === currentProfile.isOwnerOfGroup( group.getId() ) ) { %> | |||
| <a href="#/group/<%= group.getId() %>/leave" | |||
| class="float-right btn btn-sm btn-danger"> | |||