Files
tgCrewAdmin/src/components/companyBlock.vue
2025-08-02 11:20:01 +03:00

127 lines
3.4 KiB
Vue

<template>
<pn-page-card>
<template #title>
{{ $t(title) }}
</template>
<template #footer>
<q-btn
rounded color="primary"
class="w100 q-mt-md q-mb-xs fix-disabled-btn"
:disable="!isFormValid"
@click = "onSubmit"
>
{{ $t(btnText) }}
</q-btn>
</template>
<pn-scroll-list>
<div class="flex column items-center q-pa-md q-pb-sm">
<slot name="myCompany"/>
<pn-image-selector
v-model="modelValue.logo"
:size="100"
:iconsize="80"
class="q-pb-lg"
/>
<div class="q-gutter-y-lg w100">
<q-input
v-for="input in textInputs"
:key="input.id"
v-model.trim="modelValue[input.val]"
dense
filled
class="w100"
:autogrow="input.val === 'description' || input.val === 'address'"
:class="input.val === 'name'
? 'fix-bottom-padding'
: input.val === 'address'
? 'input-fix q-pt-sm'
: 'q-pt-sm'"
:label="input.label ? $t(input.label) : void 0"
:rules="input.val === 'name' ? [rules[input.val]] : []"
no-error-icon
:label-slot="Boolean(input.label)"
>
<template #prepend>
<q-icon v-if="input.icon" :name="input.icon"/>
</template>
<template #label v-if="input.label">
{{$t(input.label) }}
<span v-if="input.val === 'name'" class="text-red">*</span>
</template>
</q-input>
</div>
</div>
</pn-scroll-list>
</pn-page-card>
</template>
<script setup lang="ts">
import { computed } from 'vue'
import { useI18n } from 'vue-i18n'
import type { CompanyParams } from 'types/Company'
import { convertEmptyStringsToNull } from 'helpers/helpers'
const { t }= useI18n()
const modelValue = defineModel<CompanyParams>({
required: true
})
defineProps<{
title: string,
btnText: string
}>()
const emit = defineEmits(['update'])
interface TextInput {
id: number
label?: string
icon?: string
val: keyof CompanyParams
rules: ((value: string) => boolean | string)[]
}
const textInputs: TextInput[] = [
{ id: 1, val: 'name', label: 'company_block__name', rules: [] },
{ id: 2, val: 'description', label: 'company_block__description', rules: [] },
{ id: 3, val: 'site', icon: 'mdi-web', rules: [] },
{ id: 4, val: 'address', icon: 'mdi-map-marker-outline', rules: [] },
{ id: 5, val: 'phone', icon: 'mdi-phone-outline', rules: [] },
{ id: 6, val: 'email', icon: 'mdi-email-outline', rules: [] }
]
const rulesErrorMessage = {
name: t('company_block__error_name')
}
const rules = {
name: (val: CompanyParams['name']) => !!val?.trim() || rulesErrorMessage['name']
}
const isFormValid = computed(() => {
const validations = {
name: rules.name(modelValue.value.name) === true
}
return Object.values(validations).every(Boolean)
})
function onSubmit() {
const cleanedData = convertEmptyStringsToNull(modelValue.value)
emit('update', cleanedData)
}
</script>
<style scoped>
.q-field--with-bottom.fix-bottom-padding {
padding-bottom: 0 !important
}
.input-fix :deep(.q-field__prepend.q-field__marginal) {
height: auto !important;
}
</style>