ModalRedefinirSenha.vue 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. <template>
  2. <Teleport to="body">
  3. <div class="fixed inset-0 z-[9999] flex items-center justify-center p-4" @click="!salvando && $emit('close')">
  4. <div class="absolute inset-0 bg-black/40 dark:bg-black/60" />
  5. <div
  6. class="relative w-full max-w-md overflow-hidden rounded-2xl border border-gray-200 bg-background text-foreground shadow-xl dark:border-gray-700"
  7. @click.stop
  8. >
  9. <div class="flex items-center justify-between gap-3 border-b border-gray-200 px-5 py-4 dark:border-gray-700">
  10. <h3 class="text-base font-semibold text-gray-900 dark:text-gray-100">
  11. Redefinir senha de {{ usuario.Nome || usuario.Login }}
  12. </h3>
  13. <button
  14. type="button"
  15. :disabled="salvando"
  16. class="rounded-lg border border-transparent p-1.5 text-gray-500 transition-colors hover:border-gray-200 hover:bg-gray-100 disabled:opacity-50 dark:text-gray-400 dark:hover:border-gray-700 dark:hover:bg-white/5"
  17. @click="$emit('close')"
  18. >
  19. <svg class="h-4 w-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
  20. <path stroke-linecap="round" stroke-linejoin="round" d="M6 18 18 6M6 6l12 12" />
  21. </svg>
  22. </button>
  23. </div>
  24. <form class="grid gap-4 p-5" @submit.prevent="onSubmit">
  25. <div class="grid gap-1.5">
  26. <label for="mrs-senha" class="text-sm font-medium text-gray-700 dark:text-gray-300">Nova senha</label>
  27. <input
  28. id="mrs-senha"
  29. v-model="senhaNova"
  30. type="password"
  31. placeholder="Mínimo 6 caracteres"
  32. required
  33. minlength="6"
  34. :disabled="salvando"
  35. autocomplete="new-password"
  36. />
  37. </div>
  38. <div class="grid gap-1.5">
  39. <label for="mrs-confirmacao" class="text-sm font-medium text-gray-700 dark:text-gray-300">Confirmar nova senha</label>
  40. <input
  41. id="mrs-confirmacao"
  42. v-model="confirmacao"
  43. type="password"
  44. placeholder="Repita a nova senha"
  45. required
  46. :disabled="salvando"
  47. autocomplete="new-password"
  48. />
  49. </div>
  50. <div v-if="erroForm" class="rounded-xl border border-red-200 bg-red-50 px-3 py-2 text-sm text-red-600 dark:border-red-500/30 dark:bg-red-500/10 dark:text-red-300">
  51. {{ erroForm }}
  52. </div>
  53. <p class="text-xs text-gray-500 dark:text-gray-400">
  54. Comunique a nova senha ao usuário por canal interno.
  55. </p>
  56. <div class="flex justify-end gap-2 pt-1">
  57. <BaseButton variant="secondary" :disabled="salvando" @click="$emit('close')">
  58. Cancelar
  59. </BaseButton>
  60. <BaseButton type="submit" :disabled="salvando" :loading="salvando">
  61. Redefinir senha
  62. </BaseButton>
  63. </div>
  64. </form>
  65. </div>
  66. </div>
  67. </Teleport>
  68. </template>
  69. <script setup>
  70. import { ref } from "vue";
  71. import { alterarSenhaUsuario } from "../api/users.js";
  72. import BaseButton from "./base/BaseButton.vue";
  73. const props = defineProps({
  74. usuario: { type: Object, required: true }
  75. });
  76. const emit = defineEmits(["close", "saved"]);
  77. const senhaNova = ref("");
  78. const confirmacao = ref("");
  79. const salvando = ref(false);
  80. const erroForm = ref("");
  81. async function onSubmit() {
  82. erroForm.value = "";
  83. if (senhaNova.value.length < 6) {
  84. erroForm.value = "A nova senha deve ter no mínimo 6 caracteres.";
  85. return;
  86. }
  87. if (senhaNova.value !== confirmacao.value) {
  88. erroForm.value = "As senhas não conferem.";
  89. return;
  90. }
  91. salvando.value = true;
  92. try {
  93. await alterarSenhaUsuario(props.usuario.Id, { senhaNova: senhaNova.value });
  94. emit("saved");
  95. } catch (e) {
  96. erroForm.value = e?.message || "Erro ao redefinir a senha.";
  97. } finally {
  98. salvando.value = false;
  99. }
  100. }
  101. </script>