Skip to content

Commit

Permalink
Added filter by date in closed deals
Browse files Browse the repository at this point in the history
  • Loading branch information
simba77 committed Dec 4, 2023
1 parent 4e87c8e commit a294794
Show file tree
Hide file tree
Showing 9 changed files with 275 additions and 23 deletions.
8 changes: 8 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,14 @@ module.exports = {
'@typescript-eslint/no-explicit-any': 'off',
'vue/no-v-text-v-html-on-component': 'off',
'vue/no-v-html': 'off',
'vue/max-attributes-per-line': ['error', {
'singleline': {
'max': 4
},
'multiline': {
'max': 1
}
}],
},
overrides: [
{
Expand Down
117 changes: 117 additions & 0 deletions assets/components/Forms/InputDateComponent.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
<script setup lang="ts">
import { computed, reactive, useSlots } from 'vue'
import { useDebounceFn } from '@vueuse/core'
import VueDatePicker from '@vuepic/vue-datepicker'
import '@vuepic/vue-datepicker/dist/main.css'
const slots = useSlots()
interface InputProps {
modelValue: string | number
label?: string
placeholder?: string
name: string
id?: string
type?: string
enterKeyHint?: string
autocomplete?: string
error?: string | number | any[] | null
help?: string
disabled?: boolean
readonly?: boolean
required?: boolean
inputDelay?: number
usePhoneFormatter?: boolean
}
const props = withDefaults(defineProps<InputProps>(), {
modelValue: '',
label: '',
placeholder: '',
name: '',
id: '',
type: 'text',
enterKeyHint: '',
autocomplete: '',
error: null,
help: '',
disabled: false,
readonly: false,
required: false,
inputDelay: 0,
usePhoneFormatter: false
})
const emits = defineEmits(['update:modelValue'])
const inputParams = reactive({
value: props.modelValue,
elementId: props.id ? props.id : props.name,
hasError: computed(() => !!props.error),
hasBefore: computed(() => !!slots.before),
errorMessage: computed(() => {
if (Array.isArray(props.error)) {
return props.error.join(',')
}
return props.error
})
})
const updateModelValue = useDebounceFn(() => {
emits('update:modelValue', inputParams.value)
}, props.inputDelay)
</script>

<template>
<div>
<label v-if="label" class="text-sm font-medium text-gray-700 block mb-1" :for="inputParams.elementId">
{{ label }} <span v-if="required" class="text-danger">*</span>
<v-menu v-if="help" placement="auto" class="d-inline-block">
<span class="badge rounded-pill bg-primary form-help-badge">?</span>
<template #popper>
<div class="form-help-text" v-html="help" />
</template>
</v-menu>
</label>
<div
:class=" {
'disabled': disabled,
'has-before-icon': inputParams.hasBefore,
'is-invalid': inputParams.hasError,
}"
>
<vue-date-picker
v-model="inputParams.value"
:class=" {
'disabled': disabled,
'has-before-icon': inputParams.hasBefore,
'is-invalid': inputParams.hasError,
}"
input-class-name="form-input"
model-type="format"
:locale="'ru'"
:format="'dd.MM.yyyy'"
:enable-time-picker="false"
:auto-apply="true"
:placeholder="placeholder"
:name="name"
:disabled="disabled"
:required="required"
:readonly="readonly"
@update:model-value="updateModelValue"
/>
</div>
<div v-if="inputParams.hasError" class="invalid-feedback" v-text="inputParams.errorMessage" />
</div>
</template>

<style lang="scss" scoped>
.help {
margin-top: 0.25rem;
}
.calendar-icon {
margin: -3px 0 0 8px;
}
</style>
10 changes: 5 additions & 5 deletions assets/composable/useAnalytics.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import {ref} from "vue";
import { ref } from "vue";
import axios from "axios";
import {ClosedDealsListItem, ClosedDealsSummary} from "@/types/analytics";
import { ClosedDealsListItem, ClosedDealsSummary } from "@/types/analytics";

const closedDeals = ref<{deals: ClosedDealsListItem[], summary: ClosedDealsSummary}>()
const closedDeals = ref<{ deals: ClosedDealsListItem[], summary: ClosedDealsSummary }>()

export default function () {
async function getClosedDeals() {
closedDeals.value = await axios.get('/api/analytics/closed-deals').then((response) => response.data);
async function getClosedDeals(filter: object = {}) {
closedDeals.value = await axios.get('/api/analytics/closed-deals', {params: filter}).then((response) => response.data);
}

return {
Expand Down
19 changes: 18 additions & 1 deletion assets/pages/Accounts/ClosedDealsPage.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,33 @@ import useAnalytics from "@/composable/useAnalytics";
import useAsync from "@/utils/use-async";
import PreloaderComponent from "@/components/Common/PreloaderComponent.vue";
import ClosedDealsTableComponent from "@/components/Analytics/ClosedDealsTableComponent.vue";
import InputDateComponent from "@/components/Forms/InputDateComponent.vue";
import { reactive } from "vue";
const {closedDeals, getClosedDeals} = useAnalytics()
const {loading, run} = useAsync(() => getClosedDeals())
const filter = reactive({
startDate: '',
endDate: '',
})
const {loading, run} = useAsync(() => getClosedDeals(filter))
run()
</script>

<template>
<page-component title="Closed Deals">
{{ filter }}
<div class="mb-6 grid grid-flow-col auto-cols-max gap-4">
<div>
<input-date-component v-model="filter.startDate" name="startDate" label="Start Date" @update:model-value="run()" />
</div>
<div>
<input-date-component v-model="filter.endDate" name="endDate" label="End Date" @update:model-value="run()" />
</div>
</div>

<preloader-component v-if="loading" />
<div v-else-if="closedDeals">
<closed-deals-table-component
Expand Down
92 changes: 91 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
"dependencies": {
"@headlessui/vue": "^1.7",
"@heroicons/vue": "^2.0",
"@vuepic/vue-datepicker": "^7.3.0",
"@vueuse/core": "^10.5",
"floating-vue": "^2.0.0-beta.20",
"pinia": "^2.1",
Expand Down
Loading

0 comments on commit a294794

Please sign in to comment.