|
@@ -1,14 +1,7 @@
|
|
|
<template>
|
|
<template>
|
|
|
<q-page class="opportunities-page">
|
|
<q-page class="opportunities-page">
|
|
|
<div class="page-header">
|
|
<div class="page-header">
|
|
|
- <q-btn
|
|
|
|
|
- flat
|
|
|
|
|
- round
|
|
|
|
|
- dense
|
|
|
|
|
- icon="chevron_left"
|
|
|
|
|
- class="back-btn"
|
|
|
|
|
- @click="router.back()"
|
|
|
|
|
- />
|
|
|
|
|
|
|
+ <q-btn flat round dense icon="chevron_left" class="back-btn" @click="router.back()" />
|
|
|
<div class="page-title">
|
|
<div class="page-title">
|
|
|
{{ $t('provider.dashboard.opportunities.title') }}
|
|
{{ $t('provider.dashboard.opportunities.title') }}
|
|
|
</div>
|
|
</div>
|
|
@@ -25,24 +18,16 @@
|
|
|
<q-spinner-dots color="secondary" size="32px" />
|
|
<q-spinner-dots color="secondary" size="32px" />
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
- <div
|
|
|
|
|
- v-else-if="!opportunities.length"
|
|
|
|
|
- class="text-center q-pa-md text-grey"
|
|
|
|
|
- >
|
|
|
|
|
|
|
+ <div v-else-if="!opportunities.length" class="text-center q-pa-md text-grey">
|
|
|
{{ $t('provider.dashboard.opportunities.empty') }}
|
|
{{ $t('provider.dashboard.opportunities.empty') }}
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
<div v-else class="opportunity-list">
|
|
<div v-else class="opportunity-list">
|
|
|
- <q-card
|
|
|
|
|
- v-for="item in opportunities"
|
|
|
|
|
- :key="item.id"
|
|
|
|
|
- flat
|
|
|
|
|
- class="opportunity-card"
|
|
|
|
|
- >
|
|
|
|
|
|
|
+ <q-card v-for="item in opportunities" :key="item.id" flat class="opportunity-card">
|
|
|
<div class="avatar-column">
|
|
<div class="avatar-column">
|
|
|
<img :src="item.avatar" class="client-avatar" />
|
|
<img :src="item.avatar" class="client-avatar" />
|
|
|
<div class="service-type">
|
|
<div class="service-type">
|
|
|
- {{ item.serviceType }}
|
|
|
|
|
|
|
+ {{ item.custom_schedule?.service_type.description }}
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
@@ -67,26 +52,18 @@
|
|
|
|
|
|
|
|
<div class="right-content">
|
|
<div class="right-content">
|
|
|
<div class="price">
|
|
<div class="price">
|
|
|
- {{ $t('provider.dashboard.opportunities.currency', { value: item.price }) }}
|
|
|
|
|
|
|
+ {{ $t('provider.dashboard.opportunities.currency', { value: chooseprice(item.period_type) }) }}
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
<div class="service-address">
|
|
<div class="service-address">
|
|
|
- {{ item.address }}
|
|
|
|
|
|
|
+ {{ item.custom_schedule?.address_type }}
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
<div class="distance">
|
|
<div class="distance">
|
|
|
{{ $t('provider.dashboard.opportunities.distance_km', { distance: item.distance }) }}
|
|
{{ $t('provider.dashboard.opportunities.distance_km', { distance: item.distance }) }}
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
- <q-btn
|
|
|
|
|
- unelevated
|
|
|
|
|
- rounded
|
|
|
|
|
- no-caps
|
|
|
|
|
- color="secondary"
|
|
|
|
|
- :label="$t('provider.dashboard.opportunities.details')"
|
|
|
|
|
- class="details-btn"
|
|
|
|
|
- @click="goToOpportunityDetails(item)"
|
|
|
|
|
- />
|
|
|
|
|
|
|
+ <q-btn unelevated rounded no-caps color="secondary" :label="$t('provider.dashboard.opportunities.details')" class="details-btn" @click="goToOpportunityDetails(item)" />
|
|
|
</div>
|
|
</div>
|
|
|
</q-card>
|
|
</q-card>
|
|
|
</div>
|
|
</div>
|
|
@@ -95,58 +72,21 @@
|
|
|
<script setup>
|
|
<script setup>
|
|
|
import { ref, onMounted } from 'vue'
|
|
import { ref, onMounted } from 'vue'
|
|
|
import { useRouter } from 'vue-router'
|
|
import { useRouter } from 'vue-router'
|
|
|
-import { useI18n } from 'vue-i18n'
|
|
|
|
|
|
|
|
|
|
import { getProviderOpportunities } from 'src/api/opportunities'
|
|
import { getProviderOpportunities } from 'src/api/opportunities'
|
|
|
import { userStore } from 'src/stores/user'
|
|
import { userStore } from 'src/stores/user'
|
|
|
|
|
|
|
|
const router = useRouter()
|
|
const router = useRouter()
|
|
|
-const { t } = useI18n()
|
|
|
|
|
const user = userStore()
|
|
const user = userStore()
|
|
|
|
|
|
|
|
const opportunities = ref([])
|
|
const opportunities = ref([])
|
|
|
const loading = ref(false)
|
|
const loading = ref(false)
|
|
|
|
|
|
|
|
-const formatHour = (time) =>
|
|
|
|
|
- time ? time.slice(0, 5).replace(':', 'h') : ''
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
-const normalizeOpportunity = (item) => ({
|
|
|
|
|
- id: item.id,
|
|
|
|
|
-
|
|
|
|
|
- avatar: item.client?.user?.photo || '/icons/avatar.svg',
|
|
|
|
|
-
|
|
|
|
|
- clientName:
|
|
|
|
|
- item.client?.user?.name ||
|
|
|
|
|
- t('provider.dashboard.opportunities.client_default'),
|
|
|
|
|
-
|
|
|
|
|
- rating: item.client?.average_rating || 5.0,
|
|
|
|
|
-
|
|
|
|
|
- date: new Date(
|
|
|
|
|
- item.custom_schedule?.created_at || item.created_at
|
|
|
|
|
- ).toLocaleDateString(),
|
|
|
|
|
-
|
|
|
|
|
- hour: `${t('common.from')} ${formatHour(item.start_time)} ${t('common.to')} ${formatHour(item.end_time)}`,
|
|
|
|
|
-
|
|
|
|
|
- address:
|
|
|
|
|
- item.address?.address ||
|
|
|
|
|
- t('provider.dashboard.opportunities.address_not_found'),
|
|
|
|
|
-
|
|
|
|
|
- serviceType:
|
|
|
|
|
- item.custom_schedule?.service_type?.descritpion ||
|
|
|
|
|
- t('provider.dashboard.opportunities.client_default'),
|
|
|
|
|
-
|
|
|
|
|
- price: Number(
|
|
|
|
|
- item.custom_schedule?.max_price || 0
|
|
|
|
|
- ).toFixed(2),
|
|
|
|
|
-
|
|
|
|
|
- distance: 0
|
|
|
|
|
-})
|
|
|
|
|
|
|
|
|
|
const goToOpportunityDetails = (item) => {
|
|
const goToOpportunityDetails = (item) => {
|
|
|
|
|
|
|
|
const id = item.custom_schedule?.id || item.id
|
|
const id = item.custom_schedule?.id || item.id
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
router.push({
|
|
router.push({
|
|
|
name: 'OpportunityDetailsPage',
|
|
name: 'OpportunityDetailsPage',
|
|
|
params: { id },
|
|
params: { id },
|
|
@@ -154,6 +94,21 @@ const goToOpportunityDetails = (item) => {
|
|
|
})
|
|
})
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+const chooseprice = (periodType) => {
|
|
|
|
|
+ switch (periodType) {
|
|
|
|
|
+ case "8":
|
|
|
|
|
+ return user.user.provider_daily_price_8h
|
|
|
|
|
+ case "6":
|
|
|
|
|
+ return user.user.provider_daily_price_6h
|
|
|
|
|
+ case "4":
|
|
|
|
|
+ return user.user.provider_daily_price_4h
|
|
|
|
|
+ case "2":
|
|
|
|
|
+ return user.user.provider_daily_price_2h
|
|
|
|
|
+ default:
|
|
|
|
|
+ return 0
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
const loadOpportunities = async () => {
|
|
const loadOpportunities = async () => {
|
|
|
loading.value = true
|
|
loading.value = true
|
|
|
|
|
|
|
@@ -162,7 +117,7 @@ const loadOpportunities = async () => {
|
|
|
user.user.provider.id
|
|
user.user.provider.id
|
|
|
)
|
|
)
|
|
|
|
|
|
|
|
- opportunities.value = (response || []).map(normalizeOpportunity)
|
|
|
|
|
|
|
+ opportunities.value = (response || [])
|
|
|
} catch (error) {
|
|
} catch (error) {
|
|
|
console.error('Erro ao buscar oportunidades:', error)
|
|
console.error('Erro ao buscar oportunidades:', error)
|
|
|
opportunities.value = []
|
|
opportunities.value = []
|