-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #18 from MarceloVichar/develop
Develop
- Loading branch information
Showing
27 changed files
with
776 additions
and
16 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
<template> | ||
<VeeForm v-slot="{ meta }" class="flex justify-end items-center gap-2 w-full" @submit="onSubmit"> | ||
<VeeField | ||
v-slot="{ field, errors }" | ||
v-model="mutableForm.startDate" | ||
name="startDate" | ||
:rules="() => ({ required: true, minDate: minDate, maxDate: mutableForm.endDate })" | ||
> | ||
<CustomDatePicker | ||
v-bind="field" | ||
v-model="field.value" | ||
required | ||
class="w-full md:w-56" | ||
:max-date="mutableForm.endDate || null" | ||
placeholder="Data inicial" | ||
label="A partir de" | ||
:errors="errors" | ||
/> | ||
</VeeField> | ||
<VeeField | ||
v-slot="{ field, errors }" | ||
v-model="mutableForm.endDate" | ||
name="endDate" | ||
:rules="() => ({ required: true, minDate: mutableForm.startDate, maxDate: maxDate })" | ||
> | ||
<CustomDatePicker | ||
v-bind="field" | ||
v-model="field.value" | ||
required | ||
class="w-full md:w-56" | ||
:min-date="mutableForm.startDate || null" | ||
:max-date="maxDate" | ||
end-of-day | ||
placeholder="Data final" | ||
label="Até" | ||
:errors="errors" | ||
/> | ||
</VeeField> | ||
<button | ||
:disabled="!meta.valid || !datesAreValid" | ||
type="submit" | ||
class="btn btn-primary" | ||
> | ||
Buscar | ||
</button> | ||
</VeeForm> | ||
</template> | ||
|
||
<script setup> | ||
import CustomDatePicker from '~/components/shared/form/CustomDatePicker.vue'; | ||
const props = defineProps({ | ||
modelValue: { | ||
type: Object, | ||
required: true, | ||
}, | ||
}) | ||
const emit = defineEmits(['submit', 'update:modelValue']) | ||
const form = _cloneDeep(props.modelValue) | ||
const mutableForm = reactive(form) | ||
watch( | ||
() => props.modelValue, | ||
(newValue) => { | ||
Object.assign(mutableForm, newValue) | ||
}, | ||
{ immediate: true, deep: true }, | ||
) | ||
const onSubmit = () => { | ||
if (props.sending) return | ||
emit('update:modelValue', mutableForm) | ||
emit('submit') | ||
} | ||
const minDate = computed(() => { | ||
return mutableForm.endDate ? useDayjs()(mutableForm.endDate).subtract(31, 'day').toISOString() : undefined | ||
}) | ||
const maxDate = computed(() => { | ||
return mutableForm.startDate ? useDayjs()(mutableForm.startDate).add(31, 'day').toISOString() : undefined | ||
}) | ||
const datesAreValid = computed(() => { | ||
const startDate = useDayjs()(mutableForm.startDate) | ||
const endDate = useDayjs()(mutableForm.endDate) | ||
return startDate.diff(endDate, 'day') <= 31 && endDate.diff(startDate, 'day') <= 31 | ||
}) | ||
</script> |
64 changes: 64 additions & 0 deletions
64
components/app/company/dashboard/events/EventInfosPieChart.vue
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
<template> | ||
<div class="grid w-full p-2 overflow-hidden bg-base-100 shadow rounded-lg"> | ||
<p class="text-sm"> | ||
Ocupação em eventos | ||
</p> | ||
<VChart :option="chartOptions" class="h-72" /> | ||
</div> | ||
</template> | ||
|
||
<script setup> | ||
import VChart from 'vue-echarts'; | ||
const props = defineProps({ | ||
availableSeats: { | ||
type: Number, | ||
required: true, | ||
}, | ||
occupiedSeats: { | ||
type: Number, | ||
required: true, | ||
}, | ||
}); | ||
const chartOptions = ref({ | ||
tooltip: { | ||
trigger: 'item', | ||
}, | ||
series: [ | ||
{ | ||
radius: ['50%', '90%'], | ||
name: 'Lugares', | ||
type: 'pie', | ||
avoidLabelOverlap: true, | ||
emphasis: { | ||
label: { | ||
show: true, | ||
fontSize: 16, | ||
}, | ||
}, | ||
label: { | ||
show: false, | ||
position: 'center', | ||
}, | ||
data: [], | ||
color: ['#10B981', '#F59E0B'], | ||
}, | ||
], | ||
}); | ||
watch(() => props.availableSeats, () => setChartData()); | ||
watch(() => props.occupiedSeats, () => setChartData()); | ||
onMounted( | ||
() => setChartData(), | ||
) | ||
const setChartData = () => { | ||
chartOptions.value.series[0].data = [ | ||
{value: props.availableSeats, name: 'Disponíveis'}, | ||
{value: props.occupiedSeats, name: 'Ocupados'}, | ||
]; | ||
}; | ||
</script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
<template> | ||
<div> | ||
<span>Eventos</span> | ||
<div v-if="pending" class="flex justify-center items-center py-12"> | ||
<Loader /> | ||
</div> | ||
<div v-else class="grid gap-4"> | ||
<div class="grid sm:grid-cols-2 lg:grid-cols-3 gap-4"> | ||
<Card | ||
title="Total de eventos" | ||
type="info" | ||
:text="data?.totalEvents" | ||
class="sm:col-span-2 lg:col-span-1" | ||
/> | ||
<Card title="Total de lugares" type="warning" :text="data?.totalSeats" /> | ||
<Card title="Lugares disponíveis" type="success" :text="data?.totalAvailableSeats" /> | ||
</div> | ||
<div class="grid lg:grid-cols-3 gap-4 w-full"> | ||
<EventsPerDayBarChart class="lg:col-span-2" :events="data?.datesWithEvents" /> | ||
<EventSalesPieChart | ||
:available-seats="data?.totalAvailableSeats" | ||
:occupied-seats="data?.totalSeats - data?.totalAvailableSeats" | ||
/> | ||
</div> | ||
</div> | ||
</div> | ||
</template> | ||
|
||
<script setup> | ||
import Card from '~/components/shared/Card.vue'; | ||
import DashboardService from '~/services/api/company/dashboard/DashboardService'; | ||
import EventSalesPieChart from '~/components/app/company/dashboard/events/EventInfosPieChart.vue'; | ||
import EventsPerDayBarChart from '~/components/app/company/dashboard/events/EventsPerDayBarChart.vue'; | ||
import Loader from '~/components/shared/Loader.vue'; | ||
const dashboardService = new DashboardService(); | ||
const route = useRoute() | ||
async function fetchEvents() { | ||
if (!route.query.startDate || !route.query.endDate) { | ||
return | ||
} | ||
return dashboardService.getEventsInfos(route.query) | ||
.catch(() => { | ||
useNotify('error', 'Ops! Ocorreu algum erro, tente novamente mais tarde.') | ||
}) | ||
} | ||
const {pending, data, refresh} = useLazyAsyncData('eventsInfos', await fetchEvents) | ||
useRouteQueryWatcher(refresh) | ||
</script> |
63 changes: 63 additions & 0 deletions
63
components/app/company/dashboard/events/EventsPerDayBarChart.vue
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
<template> | ||
<div class="grid w-full p-2 overflow-hidden bg-base-100 shadow rounded-lg"> | ||
<p class="text-sm"> | ||
Eventos por dia | ||
</p> | ||
<VChart :option="chartOptions" class="h-72" /> | ||
</div> | ||
</template> | ||
|
||
<script setup> | ||
import VChart from 'vue-echarts'; | ||
const props = defineProps({ | ||
events: { | ||
type: Array, | ||
required: true, | ||
}, | ||
}); | ||
const chartOptions = ref({ | ||
tooltip: { | ||
trigger: 'item', | ||
axisPointer: { | ||
type: 'shadow', | ||
}, | ||
}, | ||
color: '#33C8B6', | ||
xAxis: [ | ||
{ | ||
type: 'category', | ||
data: [], | ||
axisTick: { | ||
alignWithLabel: true, | ||
}, | ||
}, | ||
], | ||
yAxis: [ | ||
{ | ||
type: 'value', | ||
}, | ||
], | ||
series: [ | ||
{ | ||
name: 'Eventos', | ||
type: 'bar', | ||
barWidth: '60%', | ||
data: [], | ||
}, | ||
], | ||
}); | ||
watch(() => props.events, () => setChartData()); | ||
onMounted( | ||
() => setChartData(), | ||
) | ||
const setChartData = () => { | ||
chartOptions.value.xAxis[0].data = props.events?.map(event => useDayjs()(event?.date).format('DD/MM')) | ||
chartOptions.value.series[0].data = props.events?.map(event => event?.count) | ||
}; | ||
</script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
<template> | ||
<div> | ||
<span>Vendas</span> | ||
<div v-if="pending" class="flex justify-center items-center py-12"> | ||
<Loader /> | ||
</div> | ||
<div v-else class="grid gap-4"> | ||
<div class="grid sm:grid-cols-2 lg:grid-cols-3 gap-4"> | ||
<Card | ||
title="Total confirmado" | ||
type="success" | ||
:text="useFormattedRealMoney(confirmedSales?.amountCents || 0)" | ||
class="sm:col-span-2 lg:col-span-1" | ||
/> | ||
<Card | ||
title="Vendas confirmadas" | ||
type="success" | ||
:text="confirmedSales?.count || 0" | ||
/> | ||
<Card | ||
title="Vendas pendentes" | ||
type="info" | ||
:text="pendingSales?.count || 0" | ||
/> | ||
</div> | ||
<div class="grid lg:grid-cols-3 gap-4 w-full"> | ||
<SalesPerDayBarChart :sales="data?.salesByDate" class="lg:col-span-2" /> | ||
<SalesInfosPieChart :sales-by-status="data?.salesByStatus" /> | ||
</div> | ||
</div> | ||
</div> | ||
</template> | ||
|
||
<script setup> | ||
import Card from '~/components/shared/Card.vue'; | ||
import DashboardService from '~/services/api/company/dashboard/DashboardService'; | ||
import Loader from '~/components/shared/Loader.vue'; | ||
import {SaleStatusEnum} from '~/enums/SaleStatusEnum'; | ||
import SalesInfosPieChart from '~/components/app/company/dashboard/sales/SalesInfosPieChart.vue'; | ||
import SalesPerDayBarChart from '~/components/app/company/dashboard/sales/SalesPerDayBarChart.vue'; | ||
const dashboardService = new DashboardService(); | ||
const route = useRoute() | ||
async function fetchEvents() { | ||
if (!route.query.startDate || !route.query.endDate) { | ||
return | ||
} | ||
return dashboardService.getSalesInfos(route.query) | ||
.catch(() => { | ||
useNotify('error', 'Ops! Ocorreu algum erro, tente novamente mais tarde.') | ||
}) | ||
} | ||
const {pending, data, refresh} = useLazyAsyncData('salesInfo', await fetchEvents) | ||
const confirmedSales = computed(() => { | ||
return data.value?.salesByStatus?.find(sale => sale?.status === SaleStatusEnum.CONFIRMED) | ||
}) | ||
const pendingSales = computed(() => { | ||
return data.value?.salesByStatus?.find(sale => sale?.status === SaleStatusEnum.PENDING) | ||
}) | ||
useRouteQueryWatcher(refresh) | ||
</script> |
Oops, something went wrong.