|
|
@@ -169,8 +169,104 @@
|
|
|
</div>
|
|
|
</q-menu>
|
|
|
</q-btn>
|
|
|
- <q-btn flat round dense icon="mdi-account" color="secondary" />
|
|
|
- <q-btn flat round dense icon="mdi-cog-outline" color="secondary" />
|
|
|
+
|
|
|
+ <!-- Perfil do usuário -->
|
|
|
+ <q-btn flat round dense icon="mdi-account" color="secondary">
|
|
|
+ <q-menu
|
|
|
+ anchor="bottom right"
|
|
|
+ self="top right"
|
|
|
+ :offset="[0, 8]"
|
|
|
+ class="header-menu"
|
|
|
+ >
|
|
|
+ <div class="profile-panel q-pa-md">
|
|
|
+ <div class="row items-center no-wrap q-gutter-x-md">
|
|
|
+ <q-img
|
|
|
+ :src="user?.avatar_url || 'icons/user-icon.jpg'"
|
|
|
+ class="avatar-circle"
|
|
|
+ />
|
|
|
+ <div class="column" style="min-width: 0">
|
|
|
+ <span class="text-body2 text-primary text-weight-medium ellipsis">
|
|
|
+ {{ user?.name || "Usuário" }}
|
|
|
+ </span>
|
|
|
+ <span class="text-caption text-grey-6 ellipsis">
|
|
|
+ {{ user?.email }}
|
|
|
+ </span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <q-separator class="q-my-md" />
|
|
|
+ <q-btn
|
|
|
+ v-close-popup
|
|
|
+ flat
|
|
|
+ no-caps
|
|
|
+ align="left"
|
|
|
+ class="full-width"
|
|
|
+ color="primary"
|
|
|
+ icon="mdi-account-edit-outline"
|
|
|
+ label="Editar perfil"
|
|
|
+ @click="goToEditProfile"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ </q-menu>
|
|
|
+ </q-btn>
|
|
|
+
|
|
|
+ <!-- Configurações -->
|
|
|
+ <q-btn flat round dense icon="mdi-cog-outline" color="secondary">
|
|
|
+ <q-menu
|
|
|
+ anchor="bottom right"
|
|
|
+ self="top right"
|
|
|
+ :offset="[0, 8]"
|
|
|
+ class="header-menu"
|
|
|
+ @before-show="loadUnitDetails"
|
|
|
+ >
|
|
|
+ <div class="settings-panel q-pa-md">
|
|
|
+ <div class="column q-gutter-y-sm">
|
|
|
+ <div>
|
|
|
+ <span class="text-caption text-grey-6">Nome fantasia</span>
|
|
|
+ <div class="text-body2 text-primary text-weight-medium ellipsis">
|
|
|
+ {{ unitInfo.fantasy_name || "Não informado" }}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div>
|
|
|
+ <span class="text-caption text-grey-6">Razão social</span>
|
|
|
+ <div class="text-body2 text-primary text-weight-medium ellipsis">
|
|
|
+ {{ unitInfo.social_reason || "Não informado" }}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div>
|
|
|
+ <span class="text-caption text-grey-6">Responsável pela unidade</span>
|
|
|
+ <div class="text-body2 text-primary text-weight-medium ellipsis">
|
|
|
+ {{ unitInfo.name_responsible || "Não informado" }}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <q-separator class="q-my-md" />
|
|
|
+
|
|
|
+ <q-btn
|
|
|
+ v-close-popup
|
|
|
+ flat
|
|
|
+ no-caps
|
|
|
+ align="left"
|
|
|
+ class="full-width"
|
|
|
+ color="primary"
|
|
|
+ icon="mdi-store-edit-outline"
|
|
|
+ label="Editar unidade"
|
|
|
+ @click="goToEditUnit"
|
|
|
+ />
|
|
|
+ <q-btn
|
|
|
+ v-close-popup
|
|
|
+ flat
|
|
|
+ no-caps
|
|
|
+ align="left"
|
|
|
+ class="full-width q-mt-xs"
|
|
|
+ color="negative"
|
|
|
+ icon="mdi-logout"
|
|
|
+ label="Sair"
|
|
|
+ @click="logoutFn"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ </q-menu>
|
|
|
+ </q-btn>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
@@ -184,7 +280,9 @@ import { computed, ref, watch, onMounted, onBeforeUnmount } from "vue";
|
|
|
import { useRoute, useRouter } from "vue-router";
|
|
|
import { useI18n } from "vue-i18n";
|
|
|
import { userStore } from "src/stores/user";
|
|
|
+import { useAuth } from "src/composables/useAuth";
|
|
|
import DefaultSelect from "src/components/defaults/DefaultSelect.vue";
|
|
|
+import { getUnitMe } from "src/api/unit";
|
|
|
import {
|
|
|
getMyNotifications,
|
|
|
getUnreadCount,
|
|
|
@@ -212,8 +310,12 @@ const route = useRoute();
|
|
|
const router = useRouter();
|
|
|
const { t } = useI18n();
|
|
|
const store = userStore();
|
|
|
+const { logout } = useAuth();
|
|
|
|
|
|
const userUnits = computed(() => store.user?.units ?? []);
|
|
|
+const user = computed(() => store.user);
|
|
|
+const unitDetails = ref(null);
|
|
|
+const unitInfo = computed(() => unitDetails.value || store.selectedUnit || {});
|
|
|
|
|
|
// ------------------- Notificações (sino) -------------------
|
|
|
const notifications = ref([]);
|
|
|
@@ -335,6 +437,29 @@ const lastLoginFormatted = computed(() => {
|
|
|
}).format(d);
|
|
|
});
|
|
|
|
|
|
+const loadUnitDetails = async () => {
|
|
|
+ try {
|
|
|
+ unitDetails.value = await getUnitMe();
|
|
|
+ } catch (e) {
|
|
|
+ unitDetails.value = store.selectedUnit;
|
|
|
+ console.error("Falha ao carregar dados da unidade:", e);
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+const goToEditProfile = () => {
|
|
|
+ if (!user.value?.id) return;
|
|
|
+ router.push({ name: "UserEditPage", params: { id: user.value.id } });
|
|
|
+};
|
|
|
+
|
|
|
+const goToEditUnit = () => {
|
|
|
+ router.push({ name: "UnitDataPage" });
|
|
|
+};
|
|
|
+
|
|
|
+const logoutFn = async () => {
|
|
|
+ await logout();
|
|
|
+ router.push({ name: "LoginPage" });
|
|
|
+};
|
|
|
+
|
|
|
const displayTitle = computed(() => {
|
|
|
if (title) {
|
|
|
if (typeof title === "string") return title;
|
|
|
@@ -387,4 +512,17 @@ const displayBreadcrumbs = computed(() => {
|
|
|
width: 340px;
|
|
|
max-width: 90vw;
|
|
|
}
|
|
|
+
|
|
|
+.avatar-circle {
|
|
|
+ width: 36px;
|
|
|
+ height: 36px;
|
|
|
+ border-radius: 50%;
|
|
|
+ flex-shrink: 0;
|
|
|
+}
|
|
|
+
|
|
|
+.profile-panel,
|
|
|
+.settings-panel {
|
|
|
+ width: 280px;
|
|
|
+ max-width: 90vw;
|
|
|
+}
|
|
|
</style>
|