|
@@ -0,0 +1,155 @@
|
|
|
|
|
+<template>
|
|
|
|
|
+ <q-dialog ref="dialogRef" persistent maximized transition-show="slide-left" transition-hide="slide-right">
|
|
|
|
|
+ <div class="bg-page full-height column no-shadow">
|
|
|
|
|
+
|
|
|
|
|
+ <div class="row items-center q-px-md q-pt-md q-pb-sm bg-white shadow-profile bg-surface">
|
|
|
|
|
+ <q-btn v-close-popup icon="mdi-chevron-left" flat round dense color="primary" />
|
|
|
|
|
+ <q-space />
|
|
|
|
|
+ <span class="text-subtitle1 text-weight-bold text-primary">{{ $t('profile.privacy.title') }}</span>
|
|
|
|
|
+ <q-space />
|
|
|
|
|
+ <div style="width: 32px"></div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <div v-if="loading" class="col flex flex-center">
|
|
|
|
|
+ <q-spinner color="primary" size="3em" />
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <div v-else-if="blocks.length === 0" class="col column items-center justify-center q-px-xl q-pb-xl">
|
|
|
|
|
+ <q-img
|
|
|
|
|
+ :src="diarinho"
|
|
|
|
|
+ style="width: 220px; height: 220px;"
|
|
|
|
|
+ fit="contain"
|
|
|
|
|
+ class="q-mb-lg"
|
|
|
|
|
+ />
|
|
|
|
|
+ <p class="text-text text-center text-weight-bold q-mb-xs" style="font-size: 15px;">
|
|
|
|
|
+ {{ $t('profile.privacy.empty_message') }}
|
|
|
|
|
+ </p>
|
|
|
|
|
+ <p class="text-grey-6 text-center q-mb-xl" style="font-size: 13px;">
|
|
|
|
|
+ {{ $t('profile.privacy.empty_sub') }}
|
|
|
|
|
+ </p>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <div v-else class="col overflow-auto q-pb-xl">
|
|
|
|
|
+ <div class="q-px-md q-mt-md">
|
|
|
|
|
+ <p class="text-weight-bold text-primary q-mb-md blocked-title">
|
|
|
|
|
+ {{ $t('profile.privacy.blocked_title') }}
|
|
|
|
|
+ </p>
|
|
|
|
|
+
|
|
|
|
|
+ <div
|
|
|
|
|
+ v-for="block in blocks"
|
|
|
|
|
+ :key="block.id"
|
|
|
|
|
+ class="block-item row items-center no-wrap q-mb-md"
|
|
|
|
|
+ >
|
|
|
|
|
+ <q-avatar size="48px" class="flex-shrink-0 q-mr-sm">
|
|
|
|
|
+ <span
|
|
|
|
|
+ :style="avatarStyle(block)"
|
|
|
|
|
+ class="text-weight-bold full-width full-height flex flex-center"
|
|
|
|
|
+ style="font-size: 16px; border-radius: 50%;"
|
|
|
|
|
+ >
|
|
|
|
|
+ {{ block.client_name?.slice(0, 2).toUpperCase() ?? '??' }}
|
|
|
|
|
+ </span>
|
|
|
|
|
+ </q-avatar>
|
|
|
|
|
+
|
|
|
|
|
+ <div class="col column no-wrap overflow-hidden">
|
|
|
|
|
+ <span class="text-weight-bold text-text" style="font-size: 14px; line-height: 1.3;">
|
|
|
|
|
+ {{ block.client_name }}
|
|
|
|
|
+ </span>
|
|
|
|
|
+ <div v-if="block.client_rating" class="row items-center q-mt-xs">
|
|
|
|
|
+ <q-icon name="mdi-star" color="amber" size="13px" class="q-mr-xs" />
|
|
|
|
|
+ <span class="text-grey-7" style="font-size: 12px;">{{ Number(block.client_rating).toFixed(1) }}</span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <q-btn
|
|
|
|
|
+ outline
|
|
|
|
|
+ no-caps
|
|
|
|
|
+ rounded
|
|
|
|
|
+ color="primary"
|
|
|
|
|
+ size="sm"
|
|
|
|
|
+ class="flex-shrink-0 unblock-btn"
|
|
|
|
|
+ :loading="unblockingId === block.id"
|
|
|
|
|
+ :label="$t('profile.privacy.unblock_btn')"
|
|
|
|
|
+ @click="unblock(block)"
|
|
|
|
|
+ />
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </q-dialog>
|
|
|
|
|
+</template>
|
|
|
|
|
+
|
|
|
|
|
+<script setup>
|
|
|
|
|
+import { ref, onMounted } from 'vue'
|
|
|
|
|
+import { useDialogPluginComponent } from 'quasar'
|
|
|
|
|
+import { userStore } from 'src/stores/user'
|
|
|
|
|
+import { getProviderClientBlocks, deleteProviderClientBlock } from 'src/api/providerClientBlock'
|
|
|
|
|
+import diarinho from 'src/assets/diarinho_perfil_cliente_favoritos.svg'
|
|
|
|
|
+
|
|
|
|
|
+defineEmits([...useDialogPluginComponent.emits])
|
|
|
|
|
+const { dialogRef } = useDialogPluginComponent()
|
|
|
|
|
+const store = userStore()
|
|
|
|
|
+
|
|
|
|
|
+const blocks = ref([])
|
|
|
|
|
+const loading = ref(false)
|
|
|
|
|
+const unblockingId = ref(null)
|
|
|
|
|
+
|
|
|
|
|
+const avatarColors = [
|
|
|
|
|
+ { background: '#ffd5df', color: '#932e57' },
|
|
|
|
|
+ { background: '#d7e8ff', color: '#2158a8' },
|
|
|
|
|
+ { background: '#dfd', color: '#2a7a3b' },
|
|
|
|
|
+ { background: '#ffe5cc', color: '#8a4500' },
|
|
|
|
|
+ { background: '#ede0ff', color: '#6200ea' },
|
|
|
|
|
+]
|
|
|
|
|
+
|
|
|
|
|
+const avatarStyle = (block) => {
|
|
|
|
|
+ const idx = (block?.client_id ?? 0) % avatarColors.length
|
|
|
|
|
+ return avatarColors[idx]
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const unblock = async (block) => {
|
|
|
|
|
+ unblockingId.value = block.id
|
|
|
|
|
+ try {
|
|
|
|
|
+ await deleteProviderClientBlock(block.id)
|
|
|
|
|
+ blocks.value = blocks.value.filter(b => b.id !== block.id)
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ unblockingId.value = null
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+onMounted(async () => {
|
|
|
|
|
+ loading.value = true
|
|
|
|
|
+ try {
|
|
|
|
|
+ blocks.value = await getProviderClientBlocks(store.user.provider.id) ?? []
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ loading.value = false
|
|
|
|
|
+ }
|
|
|
|
|
+})
|
|
|
|
|
+</script>
|
|
|
|
|
+
|
|
|
|
|
+<style scoped lang="scss">
|
|
|
|
|
+.shadow-profile {
|
|
|
|
|
+ box-shadow: 0px 1px 8px rgba(0, 0, 0, 0.1);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.blocked-title {
|
|
|
|
|
+ font-size: 18px;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.block-item {
|
|
|
|
|
+ background: white;
|
|
|
|
|
+ border-radius: 12px;
|
|
|
|
|
+ padding: 12px;
|
|
|
|
|
+ box-shadow: 0 1px 6px rgba(0,0,0,0.07);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.unblock-btn {
|
|
|
|
|
+ font-size: 12px;
|
|
|
|
|
+ font-weight: 600;
|
|
|
|
|
+ padding: 4px 14px;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.flex-shrink-0 {
|
|
|
|
|
+ flex-shrink: 0;
|
|
|
|
|
+}
|
|
|
|
|
+</style>
|