| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240 |
- <template>
- <q-page class="column q-gutter-md">
- <DefaultHeaderPage />
- <q-card bordered class="q-py-md q-pr-sm" flat style="border-radius: 10px">
- <div class="column q-gutter-md">
- <div class="column q-gutter-sm">
- <div class="text-subtitle1 text-weight-bold text-primary">
- Dados pessoais
- </div>
- <q-separator />
- <div class="grid-2">
- <q-input
- :model-value="userData.name"
- bg-color="white"
- label="Nome"
- outlined
- readonly
- />
- <q-input
- :model-value="userData.document"
- bg-color="white"
- label="Número de documento"
- outlined
- readonly
- />
- </div>
- </div>
- <div class="column q-gutter-sm">
- <div class="text-subtitle1 text-weight-bold text-primary">Acesso</div>
- <q-separator />
- <div class="grid-3">
- <q-input
- :model-value="userData.email"
- bg-color="white"
- label="Email"
- outlined
- readonly
- />
- <q-input
- bg-color="white"
- label="Senha"
- outlined
- readonly
- type="password"
- />
- <q-input
- bg-color="white"
- label="Confirmar Senha"
- outlined
- readonly
- type="password"
- />
- </div>
- </div>
- <div class="row justify-end">
- <q-btn
- class="btn-custom-default"
- color="secondary"
- label="Alterar"
- text-color="primary"
- @click="openEditDialog"
- />
- </div>
- </div>
- <q-inner-loading :showing="loading">
- <q-spinner color="primary" size="40px" />
- </q-inner-loading>
- </q-card>
- <ProfileEditDialog
- v-model="editDialog"
- v-model:form="editForm"
- :input-rules="inputRules"
- :server-errors="serverErrors"
- :submitting="submitting"
- @close="closeEditDialog"
- @submit="submitProfileUpdate"
- />
- </q-page>
- </template>
- <script setup>
- import { computed, onMounted, ref, watch } from "vue";
- import { updateUser } from "src/api/user";
- import { useInputRules } from "src/composables/useInputRules";
- import { useSubmitHandler } from "src/composables/useSubmitHandler";
- import { useFormUpdateTracker } from "src/composables/useFormUpdateTracker";
- import { userStore } from "src/stores/user";
- import DefaultHeaderPage from "src/components/layout/DefaultHeaderPage.vue";
- import ProfileEditDialog from "./components/ProfileEditDialog.vue";
- defineOptions({ name: "ProfilePage" });
- const { inputRules } = useInputRules();
- const currentUserStore = userStore();
- const {
- execute,
- loading: submitting,
- serverErrors,
- } = useSubmitHandler(() => closeEditDialog());
- const {
- form: editForm,
- getUpdatedFields,
- hasUpdatedFields,
- resetUpdateForm,
- setUpdateFormAsOriginal,
- } = useFormUpdateTracker({
- name: "",
- document: "",
- email: "",
- password: "",
- confirmPassword: "",
- });
- const loading = ref(false);
- const editDialog = ref(false);
- const userData = computed(() => {
- const user = currentUserStore.user ?? {};
- return {
- id: user?.id ?? null,
- name: user?.name ?? user?.full_name ?? "",
- document: user?.document_number ?? "",
- email: user?.email ?? "",
- };
- });
- const loadUser = async () => {
- loading.value = true;
- try {
- await currentUserStore.fetchUser();
- } finally {
- loading.value = false;
- }
- };
- const syncFormWithUser = () => {
- Object.assign(editForm, {
- name: userData.value.name,
- document: userData.value.document,
- email: userData.value.email,
- password: "",
- confirmPassword: "",
- });
- setUpdateFormAsOriginal();
- };
- const openEditDialog = () => {
- syncFormWithUser();
- serverErrors.value = {};
- editDialog.value = true;
- };
- const closeEditDialog = () => {
- editDialog.value = false;
- resetUpdateForm();
- };
- const buildPayload = () => {
- const updated = { ...getUpdatedFields.value };
- if (updated.document) {
- updated.document_number = updated.document;
- delete updated.document;
- }
- if (!updated.password) {
- delete updated.password;
- }
- delete updated.confirmPassword;
- return updated;
- };
- const submitProfileUpdate = async () => {
- if (!userData.value.id) return;
- if (!hasUpdatedFields.value) {
- closeEditDialog();
- return;
- }
- await execute(async () => {
- const payload = buildPayload();
- await updateUser(payload, userData.value.id);
- await loadUser();
- setUpdateFormAsOriginal();
- });
- };
- watch(userData, syncFormWithUser, { immediate: true });
- onMounted(loadUser);
- </script>
- <style scoped>
- .grid-2 {
- display: grid;
- grid-template-columns: 1fr 240px;
- gap: 12px;
- }
- .grid-3 {
- display: grid;
- grid-template-columns: repeat(3, 1fr);
- gap: 12px;
- }
- @media (max-width: 900px) {
- .grid-2,
- .grid-3 {
- grid-template-columns: 1fr;
- }
- }
- </style>
|