|
|
@@ -43,8 +43,34 @@
|
|
|
<div
|
|
|
class="flex items-center q-pr-sm"
|
|
|
:class="$q.screen.lt.sm ? '' : 'q-pt-md'"
|
|
|
+ style="gap: 8px"
|
|
|
>
|
|
|
<slot name="after" />
|
|
|
+
|
|
|
+ <div class="flex items-center no-wrap" style="gap: 12px">
|
|
|
+ <template v-if="$q.screen.gt.sm && lastLoginFormatted">
|
|
|
+ <div
|
|
|
+ class="column"
|
|
|
+ style="line-height: 1.2; white-space: nowrap; flex-shrink: 0"
|
|
|
+ >
|
|
|
+ <span class="text-caption text-grey-6 text-primary text-center"
|
|
|
+ >Ultimo acesso</span
|
|
|
+ >
|
|
|
+ <span class="text-caption text-primary text-center">{{
|
|
|
+ lastLoginFormatted
|
|
|
+ }}</span>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+
|
|
|
+ <div
|
|
|
+ class="flex items-center no-wrap"
|
|
|
+ style="gap: 2px; flex-shrink: 0"
|
|
|
+ >
|
|
|
+ <q-btn flat round dense icon="mdi-bell-badge" color="secondary" />
|
|
|
+ <q-btn flat round dense icon="mdi-account" color="secondary" />
|
|
|
+ <q-btn flat round dense icon="mdi-cog-outline" color="secondary" />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
</div>
|
|
|
<q-separator class="q-my-sm" />
|
|
|
@@ -55,10 +81,11 @@
|
|
|
import { computed } from "vue";
|
|
|
import { useRoute } from "vue-router";
|
|
|
import { useI18n } from "vue-i18n";
|
|
|
+import { userStore } from "src/stores/user";
|
|
|
|
|
|
const { title, breadcrumbs } = defineProps({
|
|
|
title: {
|
|
|
- type: Object,
|
|
|
+ type: [String, Object],
|
|
|
default: null,
|
|
|
},
|
|
|
breadcrumbs: {
|
|
|
@@ -73,20 +100,32 @@ const { title, breadcrumbs } = defineProps({
|
|
|
|
|
|
const route = useRoute();
|
|
|
const { t } = useI18n();
|
|
|
+const store = userStore();
|
|
|
+
|
|
|
+const lastLoginFormatted = computed(() => {
|
|
|
+ const raw = store.user?.last_login_at;
|
|
|
+ if (!raw) return null;
|
|
|
+ const d = new Date(raw.replace(" ", "T") + "Z");
|
|
|
+ return new Intl.DateTimeFormat("pt-BR", {
|
|
|
+ day: "2-digit",
|
|
|
+ month: "2-digit",
|
|
|
+ year: "numeric",
|
|
|
+ hour: "2-digit",
|
|
|
+ minute: "2-digit",
|
|
|
+ timeZone: "America/Sao_Paulo",
|
|
|
+ }).format(d);
|
|
|
+});
|
|
|
|
|
|
const displayTitle = computed(() => {
|
|
|
if (title) {
|
|
|
- if (title.translate) {
|
|
|
- return t(title.value);
|
|
|
- } else {
|
|
|
- return title.value;
|
|
|
- }
|
|
|
+ if (typeof title === "string") return title;
|
|
|
+ if (title.translate) return t(title.value);
|
|
|
+ return title.value;
|
|
|
} else if (route.meta?.title) {
|
|
|
- if (route.meta?.title.translate) {
|
|
|
- return t(route.meta?.title.value);
|
|
|
- } else {
|
|
|
- return route.meta?.title.value;
|
|
|
- }
|
|
|
+ const metaTitle = route.meta.title;
|
|
|
+ if (typeof metaTitle === "string") return metaTitle;
|
|
|
+ if (metaTitle.translate) return t(metaTitle.value);
|
|
|
+ return metaTitle.value;
|
|
|
}
|
|
|
return null;
|
|
|
});
|