| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473 |
- <template>
- <q-dialog
- ref="dialogRef"
- @hide="onDialogHide"
- >
- <q-card class="q-dialog-plugin column approval-dialog">
- <DefaultDialogHeader
- :title="() => $t('provider.approval.dialog_title')"
- @close="onDialogCancel"
- />
- <div class="col scroll q-pa-md">
- <div class="row items-center q-mb-md">
- <q-badge
- :color="statusColor"
- :label="$t(`provider.approval_status.${provider.approval_status}`)"
- class="text-body2 q-pa-sm"
- />
- </div>
- <div class="row q-col-gutter-md">
- <!-- Dados pessoais -->
- <div class="col-12 col-lg-4">
- <div class="text-subtitle1 text-weight-bold q-mb-sm">
- {{ $t("provider.approval.section_personal") }}
- </div>
- <q-list
- bordered
- separator
- class="rounded-borders"
- >
- <q-item>
- <q-item-section>
- <q-item-label caption>
- {{ $t("common.terms.name") }}
- </q-item-label>
- <q-item-label>
- {{ provider.user?.name || "—" }}
- </q-item-label>
- </q-item-section>
- </q-item>
- <q-item>
- <q-item-section>
- <q-item-label caption>
- {{ $t("common.terms.email") }}
- </q-item-label>
- <q-item-label>
- {{ provider.user?.email || "—" }}
- </q-item-label>
- </q-item-section>
- </q-item>
- <q-item>
- <q-item-section>
- <q-item-label caption>
- {{ $t("provider.fields.document") }}
- </q-item-label>
- <q-item-label>
- {{ provider.document || "—" }}
- </q-item-label>
- </q-item-section>
- </q-item>
- <q-item>
- <q-item-section>
- <q-item-label caption>
- {{ $t("provider.fields.rg") }}
- </q-item-label>
- <q-item-label>
- {{ provider.rg || "—" }}
- </q-item-label>
- </q-item-section>
- </q-item>
- <q-item>
- <q-item-section>
- <q-item-label caption>
- {{ $t("provider.fields.birth_date") }}
- </q-item-label>
- <q-item-label>
- {{ provider.birth_date || "—" }}
- </q-item-label>
- </q-item-section>
- </q-item>
- </q-list>
- </div>
- <!-- Preços -->
- <div class="col-12 col-lg-4">
- <div class="text-subtitle1 text-weight-bold q-mb-sm">
- {{ $t("provider.approval.section_pricing") }}
- </div>
- <q-list
- bordered
- separator
- class="rounded-borders"
- >
- <q-item>
- <q-item-section>
- <q-item-label caption>
- {{ $t("provider.fields.daily_price_8h") }}
- </q-item-label>
- <q-item-label>
- {{ formatCurrency(provider.daily_price_8h) }}
- </q-item-label>
- </q-item-section>
- </q-item>
- <q-item>
- <q-item-section>
- <q-item-label caption>
- {{ $t("provider.fields.daily_price_6h") }}
- </q-item-label>
- <q-item-label>
- {{ formatCurrency(provider.daily_price_6h) }}
- </q-item-label>
- </q-item-section>
- </q-item>
- <q-item>
- <q-item-section>
- <q-item-label caption>
- {{ $t("provider.fields.daily_price_4h") }}
- </q-item-label>
- <q-item-label>
- {{ formatCurrency(provider.daily_price_4h) }}
- </q-item-label>
- </q-item-section>
- </q-item>
- <q-item>
- <q-item-section>
- <q-item-label caption>
- {{ $t("provider.fields.daily_price_2h") }}
- </q-item-label>
- <q-item-label>
- {{ formatCurrency(provider.daily_price_2h) }}
- </q-item-label>
- </q-item-section>
- </q-item>
- </q-list>
- </div>
- <!-- Documentos -->
- <div class="col-12 col-lg-4">
- <div class="text-subtitle1 text-weight-bold q-mb-sm">
- {{ $t("provider.approval.section_documents") }}
- </div>
- <!-- Selfie -->
- <div class="q-mb-md">
- <div class="text-caption text-grey-6 q-mb-xs">
- {{ $t("provider.approval.selfie") }}
- </div>
- <div
- class="doc-frame"
- :class="{ 'doc-frame--clickable': avatarPreview }"
- @click="avatarPreview && (docLightbox = avatarPreview)"
- >
- <q-img
- v-if="avatarPreview"
- :src="avatarPreview"
- fit="cover"
- style="width: 100%; height: 100%;"
- />
- <div
- v-else
- class="column flex-center text-grey-5"
- >
- <q-icon
- name="mdi-account"
- size="40px"
- />
- </div>
- </div>
- </div>
- <!-- Documento Frente -->
- <div class="q-mb-md">
- <div class="text-caption text-grey-6 q-mb-xs">
- {{ $t("provider.fields.document_front") }}
- </div>
- <div
- class="doc-frame"
- :class="{ 'doc-frame--clickable': documentFrontUrl }"
- @click="documentFrontUrl && (docLightbox = documentFrontUrl)"
- >
- <q-img
- v-if="documentFrontUrl"
- :src="documentFrontUrl"
- fit="contain"
- style="width:100%;height:100%;"
- />
- <div
- v-else
- class="column flex-center text-grey-5"
- >
- <q-icon
- name="mdi-image-off-outline"
- size="36px"
- />
- </div>
- </div>
- </div>
- <!-- Documento Verso -->
- <div>
- <div class="text-caption text-grey-6 q-mb-xs">
- {{ $t("provider.fields.document_back") }}
- </div>
- <div
- class="doc-frame"
- :class="{ 'doc-frame--clickable': documentBackUrl }"
- @click="documentBackUrl && (docLightbox = documentBackUrl)"
- >
- <q-img
- v-if="documentBackUrl"
- :src="documentBackUrl"
- fit="contain"
- style="width:100%;height:100%;"
- />
- <div
- v-else
- class="column flex-center text-grey-5"
- >
- <q-icon
- name="mdi-image-off-outline"
- size="36px"
- />
- </div>
- </div>
- </div>
- </div>
- </div>
- <div class="text-caption text-grey-6 q-mt-md">
- {{ provider.created_at || "—" }}
- </div>
- </div>
- <q-card-actions class="q-pa-md row q-col-gutter-sm">
- <div class="col-12 col-sm-auto">
- <q-btn
- class="full-width"
- flat
- :label="$t('common.actions.cancel')"
- color="grey-7"
- @click="onDialogCancel"
- />
- </div>
- <div
- v-if="provider.approval_status !== 'rejected'"
- class="col-12 col-sm-auto"
- >
- <q-btn
- class="full-width"
- unelevated
- color="negative"
- :label="$t('provider.approval.btn_reject')"
- :loading="loadingReject"
- @click="onReject"
- />
- </div>
- <div
- v-if="provider.approval_status !== 'accepted'"
- class="col-12 col-sm-auto"
- >
- <q-btn
- class="full-width"
- unelevated
- color="positive"
- :label="$t('provider.approval.btn_approve')"
- :loading="loadingApprove"
- @click="onApprove"
- />
- </div>
- </q-card-actions>
- </q-card>
- </q-dialog>
- <q-dialog
- v-model="docLightboxOpen"
- maximized
- >
- <div
- class="flex flex-center bg-black"
- style="height:100%;"
- @click="docLightbox = null"
- >
- <q-img
- :src="docLightbox"
- fit="contain"
- style="max-width:100vw;max-height:100vh;"
- />
- <q-btn
- flat
- round
- color="white"
- icon="mdi-close"
- class="absolute-top-right q-ma-sm"
- @click.stop="docLightbox = null"
- />
- </div>
- </q-dialog>
- </template>
- <script setup>
- import { computed, ref, onMounted } from "vue";
- import { useDialogPluginComponent, useQuasar } from "quasar";
- import { useI18n } from "vue-i18n";
- import {
- approveProvider,
- rejectProvider,
- getProvider,
- } from "src/api/provider";
- import DefaultDialogHeader from "src/components/defaults/DefaultDialogHeader.vue";
- const props = defineProps({
- provider: {
- type: Object,
- required: true,
- },
- });
- defineEmits([...useDialogPluginComponent.emits]);
- const {
- dialogRef,
- onDialogHide,
- onDialogOK,
- onDialogCancel,
- } = useDialogPluginComponent();
- const $q = useQuasar();
- const { t } = useI18n();
- const loadingApprove = ref(false);
- const loadingReject = ref(false);
- // Imagens
- const avatarPreview = ref(null);
- const documentFrontUrl = ref(null);
- const documentBackUrl = ref(null);
- // Lightbox
- const docLightbox = ref(null);
- const docLightboxOpen = computed({
- get: () => !!docLightbox.value,
- set: (value) => {
- if (!value) {
- docLightbox.value = null;
- }
- },
- });
- const statusColor = computed(() => {
- const map = {
- pending: "warning",
- accepted: "positive",
- rejected: "negative",
- };
- return map[props.provider.approval_status] ?? "grey";
- });
- const formatCurrency = (value) => {
- if (!value) return "—";
- return new Intl.NumberFormat("pt-BR", {
- style: "currency",
- currency: "BRL",
- }).format(value);
- };
- onMounted(async () => {
- try {
- const full = await getProvider(props.provider.id);
- console.log("FULL", full);
- console.log("PROFILE", full.profile_media);
- console.log("URL", full.profile_media?.url);
- avatarPreview.value = full.profile_media?.url ?? null;
- console.log("AVATAR", avatarPreview.value);
- documentFrontUrl.value = full.document_front_media?.url ?? null;
- documentBackUrl.value = full.document_back_media?.url ?? null;
- } catch (error) {
- console.error(error);
- }
- });
- const onApprove = async () => {
- loadingApprove.value = true;
- try {
- await approveProvider(props.provider.id);
- onDialogOK({ action: "approved" });
- } catch {
- $q.notify({
- type: "negative",
- message: t("http.errors.failed"),
- position: "top",
- });
- } finally {
- loadingApprove.value = false;
- }
- };
- const onReject = async () => {
- loadingReject.value = true;
- try {
- await rejectProvider(props.provider.id);
- onDialogOK({ action: "rejected" });
- } catch {
- $q.notify({
- type: "negative",
- message: t("http.errors.failed"),
- position: "top",
- });
- } finally {
- loadingReject.value = false;
- }
- };
- </script>
- <style scoped>
- .approval-dialog {
- width: 700px;
- max-width: 95vw;
- max-height: 90vh;
- }
- @media (max-width: 768px) {
- .approval-dialog {
- width: 100vw;
- max-width: 100vw;
- height: 100vh;
- max-height: 100vh;
- border-radius: 0;
- }
- }
- </style>
|