|
|
@@ -0,0 +1,137 @@
|
|
|
+<template>
|
|
|
+ <q-dialog ref="dialogRef" @hide="onDialogHide">
|
|
|
+ <q-card class="notif-detail-card">
|
|
|
+ <q-card-section class="row items-center q-pb-none">
|
|
|
+ <div class="text-h6 text-violet-normal ellipsis" style="max-width: calc(100% - 48px)">
|
|
|
+ {{ item.notification?.title }}
|
|
|
+ </div>
|
|
|
+ <q-space />
|
|
|
+ <q-btn icon="mdi-close" flat round dense @click="handleClose" />
|
|
|
+ </q-card-section>
|
|
|
+
|
|
|
+ <q-separator class="q-mt-sm" />
|
|
|
+
|
|
|
+ <q-card-section class="q-pt-md notif-detail-card__scroll">
|
|
|
+ <div v-if="imageUrl" class="notif-detail-card__image q-mb-md">
|
|
|
+ <img :src="imageUrl" alt="" class="notif-detail-card__img" />
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="text-body2 text-grey-8 notif-detail-card__message">
|
|
|
+ {{ item.notification?.message }}
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="text-caption text-grey-5 q-mt-md">
|
|
|
+ {{ formatDate(item.created_at) }}
|
|
|
+ </div>
|
|
|
+ </q-card-section>
|
|
|
+
|
|
|
+ <q-separator />
|
|
|
+
|
|
|
+ <q-card-actions align="right" class="q-pa-sm">
|
|
|
+ <q-btn
|
|
|
+ flat
|
|
|
+ color="violet-normal"
|
|
|
+ :label="$t('common.actions.close')"
|
|
|
+ @click="handleClose"
|
|
|
+ />
|
|
|
+ </q-card-actions>
|
|
|
+ </q-card>
|
|
|
+ </q-dialog>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script setup>
|
|
|
+import { ref, computed, onMounted } from "vue";
|
|
|
+import { useI18n } from "vue-i18n";
|
|
|
+import { useDialogPluginComponent } from "quasar";
|
|
|
+import { userStore } from "src/stores/user";
|
|
|
+import {
|
|
|
+ markNotificationAsReadAssociado,
|
|
|
+ markNotificationAsReadParceiro,
|
|
|
+} from "src/api/notification";
|
|
|
+
|
|
|
+const props = defineProps({
|
|
|
+ item: { type: Object, required: true },
|
|
|
+});
|
|
|
+
|
|
|
+defineEmits([...useDialogPluginComponent.emits]);
|
|
|
+
|
|
|
+const { dialogRef, onDialogHide, onDialogOK } = useDialogPluginComponent();
|
|
|
+
|
|
|
+const { t } = useI18n();
|
|
|
+const store = userStore();
|
|
|
+const markedReadId = ref(null);
|
|
|
+
|
|
|
+const imageUrl = computed(() => {
|
|
|
+ const media = props.item.notification?.media?.[0]?.url;
|
|
|
+ if (media) return media;
|
|
|
+ const direct = props.item.notification?.image_url;
|
|
|
+ if (!direct) return null;
|
|
|
+ return direct.startsWith("http") ? direct : (process.env.API_URL ?? "") + direct;
|
|
|
+});
|
|
|
+
|
|
|
+const formatDate = (dateStr) => {
|
|
|
+ if (!dateStr) return "";
|
|
|
+ const date = new Date(dateStr);
|
|
|
+ const today = new Date();
|
|
|
+ const isToday =
|
|
|
+ date.getDate() === today.getDate() &&
|
|
|
+ date.getMonth() === today.getMonth() &&
|
|
|
+ date.getFullYear() === today.getFullYear();
|
|
|
+ if (isToday) return t("common.terms.today");
|
|
|
+ return date.toLocaleDateString("pt-BR", { day: "2-digit", month: "2-digit", year: "numeric" });
|
|
|
+};
|
|
|
+
|
|
|
+const handleClose = () => {
|
|
|
+ onDialogOK(markedReadId.value);
|
|
|
+};
|
|
|
+
|
|
|
+onMounted(async () => {
|
|
|
+ if (props.item.read) return;
|
|
|
+ try {
|
|
|
+ if (store.isAssociado) {
|
|
|
+ await markNotificationAsReadAssociado(props.item.id);
|
|
|
+ } else if (store.isParceiro) {
|
|
|
+ await markNotificationAsReadParceiro(props.item.id);
|
|
|
+ }
|
|
|
+ markedReadId.value = props.item.id;
|
|
|
+ } catch (e) {
|
|
|
+ console.error(e);
|
|
|
+ }
|
|
|
+});
|
|
|
+</script>
|
|
|
+
|
|
|
+<style scoped lang="scss">
|
|
|
+.notif-detail-card {
|
|
|
+ width: 90vw;
|
|
|
+ max-width: 600px;
|
|
|
+ min-width: 300px;
|
|
|
+
|
|
|
+ &__scroll {
|
|
|
+ max-height: 70vh;
|
|
|
+ overflow-y: auto;
|
|
|
+ }
|
|
|
+
|
|
|
+ &__image {
|
|
|
+ width: 100%;
|
|
|
+ border-radius: 8px;
|
|
|
+ overflow: hidden;
|
|
|
+ background: #f0e8f1;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ }
|
|
|
+
|
|
|
+ &__img {
|
|
|
+ width: 100%;
|
|
|
+ max-height: 350px;
|
|
|
+ object-fit: contain;
|
|
|
+ display: block;
|
|
|
+ }
|
|
|
+
|
|
|
+ &__message {
|
|
|
+ white-space: pre-wrap;
|
|
|
+ word-break: break-word;
|
|
|
+ line-height: 1.6;
|
|
|
+ }
|
|
|
+}
|
|
|
+</style>
|