diff --git a/src/components/views/UsersCrud.vue b/src/components/views/UsersCrud.vue index 7db42758..bd56b37f 100644 --- a/src/components/views/UsersCrud.vue +++ b/src/components/views/UsersCrud.vue @@ -6,12 +6,18 @@
- {{ $t('pedidosDeEliminacionDeCuenta') }} - + :to="{ name: 'admin-users-delete-list' }" + class="btn btn-link" + style=" + display: block; + text-align: center; + margin-top: -10px; + margin-bottom: 10px; + font-size: 16px; + " + > + {{ $t('pedidosDeEliminacionDeCuenta') }} +
@@ -23,7 +29,11 @@ v-on:keyup="onSearchUsers" type="text" class="form-control" - :placeholder="$t('escribeUnNombreYPresionaBuscar')" + :placeholder=" + $t( + 'escribeUnNombreYPresionaBuscar' + ) + " />
@@ -89,23 +99,31 @@
- - {{ $t('noSeEncontroNingunUsuario') }} - - - - {{ $t('cargandoUsuarios') }} - @@ -117,9 +135,9 @@ >
- +
- +
- +
- + {{ dniError.message }} @@ -192,9 +216,9 @@
- + {{ phoneError.message }} @@ -211,9 +237,9 @@
- +
- +
@@ -424,37 +450,93 @@

-
+
+
+ +

{{ $t('referencias') }}

+ +
+ {{ $t('noReferences') }} +
+ +
+
+
+
+
+
+
+
+

+ + {{ reference.from.name }} + +

+ + {{ reference.from.email }} + +
+ + {{ + reference.created_at.split( + 'T' + )[0] + }} + +

+ {{ reference.comment }} +

+
+
+ + +
+
-
@@ -467,32 +549,56 @@ :name="'modal-confirm-admin-action'" @close="closeConfirmModal" > - - + +
@@ -555,7 +661,8 @@ export default { loadingAction: false, adminApi: null, banNote: '', - clearingIdentity: false + clearingIdentity: false, + references: [] }; }, @@ -565,15 +672,21 @@ export default { settings: 'auth/appConfig' }), confirmModalTitle() { - if (this.pendingAction === 'delete') return this.$t('confirmarEliminarUsuario'); - if (this.pendingAction === 'anonymize') return this.$t('confirmarAnonimizarUsuario'); - if (this.pendingAction === 'banAndAnonymize') return this.$t('confirmarAnonimizarYBloquearUsuario'); + if (this.pendingAction === 'delete') + return this.$t('confirmarEliminarUsuario'); + if (this.pendingAction === 'anonymize') + return this.$t('confirmarAnonimizarUsuario'); + if (this.pendingAction === 'banAndAnonymize') + return this.$t('confirmarAnonimizarYBloquearUsuario'); return ''; }, confirmModalMessage() { - if (this.pendingAction === 'delete') return this.$t('confirmarEliminarUsuarioMensaje'); - if (this.pendingAction === 'anonymize') return this.$t('confirmarAnonimizarUsuarioMensaje'); - if (this.pendingAction === 'banAndAnonymize') return this.$t('confirmarAnonimizarYBloquearUsuarioMensaje'); + if (this.pendingAction === 'delete') + return this.$t('confirmarEliminarUsuarioMensaje'); + if (this.pendingAction === 'anonymize') + return this.$t('confirmarAnonimizarUsuarioMensaje'); + if (this.pendingAction === 'banAndAnonymize') + return this.$t('confirmarAnonimizarYBloquearUsuarioMensaje'); return ''; } }, @@ -600,7 +713,8 @@ export default { }, confirmClearIdentityValidation() { if (!this.currentUser || !this.currentUser.id) return; - if (!confirm(this.$t('confirmarRemoverValidacionIdentidad'))) return; + if (!confirm(this.$t('confirmarRemoverValidacionIdentidad'))) + return; this.doClearIdentityValidation(); }, doClearIdentityValidation() { @@ -616,7 +730,9 @@ export default { dialogs.message(this.$t('validacionIdentidadRemovida')); }) .catch(() => { - dialogs.message(this.$t('resultError'), { estado: 'error' }); + dialogs.message(this.$t('resultError'), { + estado: 'error' + }); }) .finally(() => { this.clearingIdentity = false; @@ -627,7 +743,10 @@ export default { console.log('selectUser', user); // Ensure nro_doc is stored as raw value (no dots) when loaded from backend const nroDocRaw = this.currentUser.nro_doc - ? cleanId(this.currentUser.nro_doc, this.settings.profile_id_format) + ? cleanId( + this.currentUser.nro_doc, + this.settings.profile_id_format + ) : ''; this.newInfo = { name: this.currentUser.name, @@ -646,14 +765,46 @@ export default { banned: this.currentUser.banned > 0, active: this.currentUser.active > 0, cars: this.currentUser.cars || [], - patente: this.currentUser.cars && this.currentUser.cars.length > 0 ? this.currentUser.cars[0].patente : '', + patente: + this.currentUser.cars && this.currentUser.cars.length > 0 + ? this.currentUser.cars[0].patente + : '', identity_validated: this.currentUser.identity_validated, identity_validated_at: this.currentUser.identity_validated_at }; // Format nro_doc for display after loading if (this.newInfo.nro_doc) { - this.newInfo.nro_doc = formatId(this.newInfo.nro_doc, this.settings.profile_id_format); + this.newInfo.nro_doc = formatId( + this.newInfo.nro_doc, + this.settings.profile_id_format + ); } + this.loadReferences(user.id); + }, + loadReferences(userId) { + this.adminApi + .getUserReferences(userId) + .then((response) => { + console.log('references:', response); + this.references = response.references; + }) + .catch((err) => console.error(err)); + }, + deleteReference(referenceId) { + if (!confirm('¿Eliminar referencia?')) { + return; + } + + this.adminApi + .deleteUserReference(referenceId, this.currentUser.id) + .then(() => { + this.references = this.references.filter( + (r) => r.id !== referenceId + ); + }) + .catch((err) => { + console.error(err); + }); }, toUserMessages(user) { console.log('toUserMessages'); @@ -674,7 +825,10 @@ export default { // Handle DNI input - format using pattern handleDniInput(event) { - const formatted = formatId(event.target.value, this.settings.profile_id_format); + const formatted = formatId( + event.target.value, + this.settings.profile_id_format + ); event.target.value = formatted; // Update the Vue data model with the formatted value this.newInfo.nro_doc = formatted; @@ -704,16 +858,21 @@ export default { loadUserFromQuery() { const userId = this.$route.query.userId; if (!userId) return; - this.userApi.show(userId).then((response) => { - const user = response.data; - if (user) { - this.selectUser(user); - this.textSearch = user.name || ''; - this.userList = [user]; - } - }).catch(() => { - dialogs.message(this.$t('noSeEncontroNingunUsuario'), { estado: 'error' }); - }); + this.userApi + .show(userId) + .then((response) => { + const user = response.data; + if (user) { + this.selectUser(user); + this.textSearch = user.name || ''; + this.userList = [user]; + } + }) + .catch(() => { + dialogs.message(this.$t('noSeEncontroNingunUsuario'), { + estado: 'error' + }); + }); }, conversationsSearch() { // Placeholder method - may be implemented later @@ -748,7 +907,10 @@ export default { } else if (this.pendingAction === 'anonymize') { promise = api.anonymizeUser(this.currentUser.id); } else if (this.pendingAction === 'banAndAnonymize') { - promise = api.banAndAnonymizeUser(this.currentUser.id, this.banNote); + promise = api.banAndAnonymizeUser( + this.currentUser.id, + this.banNote + ); } else { this.loadingAction = false; return; @@ -759,7 +921,9 @@ export default { this.loadingAction = false; this.closeConfirmModal(); this.clear(); - this.userList = this.userList.filter((u) => u.id !== userId); + this.userList = this.userList.filter( + (u) => u.id !== userId + ); dialogs.message(this.$t('accionCompletadaExitosamente'), { duration: 5, estado: 'success' @@ -767,12 +931,21 @@ export default { }) .catch((err) => { this.loadingAction = false; - const msg = (err.response && err.response.data && err.response.data.message) || err.message || this.$t('errorAlActualizar'); + const msg = + (err.response && + err.response.data && + err.response.data.message) || + err.message || + this.$t('errorAlActualizar'); dialogs.message(msg, { duration: 5, estado: 'error' }); - if (err.response && err.response.data && err.response.data.error === 'requires_ban') { + if ( + err.response && + err.response.data && + err.response.data.error === 'requires_ban' + ) { this.closeConfirmModal(); } }); @@ -848,11 +1021,17 @@ export default { if (!this.validate()) { // DNI: send raw value without dots (backend expects digits only) const nroDocRaw = this.newInfo.nro_doc - ? cleanId(this.newInfo.nro_doc, this.settings.profile_id_format) + ? cleanId( + this.newInfo.nro_doc, + this.settings.profile_id_format + ) : this.newInfo.nro_doc; // Patente: trim whitespace before sending - const patenteValue = (this.newInfo.patente && this.newInfo.patente.trim) ? this.newInfo.patente.trim() : (this.newInfo.patente || ''); + const patenteValue = + this.newInfo.patente && this.newInfo.patente.trim + ? this.newInfo.patente.trim() + : this.newInfo.patente || ''; // Only send properties from the admin form (backend allows these for admin) const payload = { @@ -874,12 +1053,15 @@ export default { if (this.newInfo.pass && this.newInfo.pass.password) { payload.password = this.newInfo.pass.password; - payload.password_confirmation = this.newInfo.pass.password_confirmation; + payload.password_confirmation = + this.newInfo.pass.password_confirmation; } this.update(payload) .then(() => { - dialogs.message(this.$t('perfilActualizadoCorrectamente')); + dialogs.message( + this.$t('perfilActualizadoCorrectamente') + ); }) .catch((err) => { console.log(err); @@ -896,7 +1078,9 @@ export default { }); this.onSearchUsers(); } else { - dialogs.message(this.$t('verifiqueLosCampos'), { estado: 'error' }); + dialogs.message(this.$t('verifiqueLosCampos'), { + estado: 'error' + }); } } }, diff --git a/src/services/api/Admin.js b/src/services/api/Admin.js index 95cebbf5..b2ee6a39 100644 --- a/src/services/api/Admin.js +++ b/src/services/api/Admin.js @@ -44,7 +44,9 @@ class AdminApi extends TaggedApi { } banAndAnonymizeUser(userId, note = '') { - return this.post(`/api/admin/users/${userId}/ban-and-anonymize`, { note }); + return this.post(`/api/admin/users/${userId}/ban-and-anonymize`, { + note + }); } clearIdentityValidation(userId) { @@ -103,6 +105,16 @@ class AdminApi extends TaggedApi { {} ); } + + getUserReferences(userId) { + return this.get(`/api/admin/users/${userId}/references`); + } + + deleteUserReference(referenceId, userId) { + return this.delete( + `/api/admin/users/${userId}/references/${referenceId}` + ); + } } export { AdminApi as default }; diff --git a/src/store/modules/admin.js b/src/store/modules/admin.js index 1c4793e4..b44e3f92 100644 --- a/src/store/modules/admin.js +++ b/src/store/modules/admin.js @@ -32,12 +32,21 @@ function getSeats(store) { function getUserStats(store) { return adminApi.getUserStats(); } +function getUserReferences(store, userId) { + return adminApi.getUserReferences(userId); +} + +function deleteUserReference(store, { userId, referenceId }) { + return adminApi.deleteUserReference(userId, referenceId); +} const actions = { searchUsers, adminUpdate, getTrips, getSeats, - getUserStats + getUserStats, + getUserReferences, + deleteUserReference }; // const state = {