Files
InvoiceShelf/resources/scripts-v2/features/company/customers/views/CustomerDetailView.vue
Darko Gjorgjijoski a46cca5cd8 Complete scripts-v2 TypeScript migration — all imports resolved,
build passes

Create all missing components (modals, dropdowns, icons, tabs, mail
drivers, customer partials), fix all @/scripts/ imports to @v2/,
wire up vite entry point and blade template. 382 files, 48883 lines.

- 27 settings components: modals (tax, payment, custom field, note,
  category, role, exchange rate, unit, mail test), dropdowns (6),
  customization tabs (4), mail driver forms (4)
- 22 icon components: 5 utility icons, 4 dashboard icons, 13 editor
  toolbar icons with typed barrel export
- 3 customer components: info, chart placeholder, custom fields single
- Fixed usePopper composable, client/format-money import patterns
- Zero remaining @/scripts/ imports in scripts-v2/

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 09:30:00 +02:00

147 lines
4.4 KiB
Vue

<script setup lang="ts">
import { computed } from 'vue'
import { useRouter, useRoute } from 'vue-router'
import { useI18n } from 'vue-i18n'
import { useCustomerStore } from '../store'
import { useUserStore } from '../../../../stores/user.store'
import CustomerDropdown from '../components/CustomerDropdown.vue'
import CustomerViewSidebar from '@v2/features/company/customers/components/CustomerViewSidebar.vue'
import CustomerChart from '@v2/features/company/customers/components/CustomerChart.vue'
const ABILITIES = {
EDIT_CUSTOMER: 'edit-customer',
DELETE_CUSTOMER: 'delete-customer',
CREATE_ESTIMATE: 'create-estimate',
CREATE_INVOICE: 'create-invoice',
CREATE_PAYMENT: 'create-payment',
CREATE_EXPENSE: 'create-expense',
} as const
const customerStore = useCustomerStore()
const userStore = useUserStore()
const { t } = useI18n()
const router = useRouter()
const route = useRoute()
const pageTitle = computed<string>(() => {
return customerStore.selectedViewCustomer.customer
? (customerStore.selectedViewCustomer.customer as { name: string }).name
: ''
})
const isLoading = computed<boolean>(() => customerStore.isFetchingViewData)
function canCreateTransaction(): boolean {
return userStore.hasAbilities([
ABILITIES.CREATE_ESTIMATE,
ABILITIES.CREATE_INVOICE,
ABILITIES.CREATE_PAYMENT,
ABILITIES.CREATE_EXPENSE,
])
}
function hasAtleastOneAbility(): boolean {
return userStore.hasAbilities([
ABILITIES.DELETE_CUSTOMER,
ABILITIES.EDIT_CUSTOMER,
])
}
function refreshData(): void {
router.push('/admin/customers')
}
</script>
<template>
<BasePage class="xl:pl-96">
<BasePageHeader :title="pageTitle">
<template #actions>
<router-link
v-if="userStore.hasAbilities(ABILITIES.EDIT_CUSTOMER)"
:to="`/admin/customers/${route.params.id}/edit`"
>
<BaseButton
class="mr-3"
variant="primary-outline"
:content-loading="isLoading"
>
{{ $t('general.edit') }}
</BaseButton>
</router-link>
<BaseDropdown
v-if="canCreateTransaction()"
position="bottom-end"
:content-loading="isLoading"
>
<template #activator>
<BaseButton
class="mr-3"
variant="primary"
:content-loading="isLoading"
>
{{ $t('customers.new_transaction') }}
</BaseButton>
</template>
<router-link
v-if="userStore.hasAbilities(ABILITIES.CREATE_ESTIMATE)"
:to="`/admin/estimates/create?customer=${$route.params.id}`"
>
<BaseDropdownItem>
<BaseIcon name="DocumentIcon" class="mr-3 text-body" />
{{ $t('estimates.new_estimate') }}
</BaseDropdownItem>
</router-link>
<router-link
v-if="userStore.hasAbilities(ABILITIES.CREATE_INVOICE)"
:to="`/admin/invoices/create?customer=${$route.params.id}`"
>
<BaseDropdownItem>
<BaseIcon name="DocumentTextIcon" class="mr-3 text-body" />
{{ $t('invoices.new_invoice') }}
</BaseDropdownItem>
</router-link>
<router-link
v-if="userStore.hasAbilities(ABILITIES.CREATE_PAYMENT)"
:to="`/admin/payments/create?customer=${$route.params.id}`"
>
<BaseDropdownItem>
<BaseIcon name="CreditCardIcon" class="mr-3 text-body" />
{{ $t('payments.new_payment') }}
</BaseDropdownItem>
</router-link>
<router-link
v-if="userStore.hasAbilities(ABILITIES.CREATE_EXPENSE)"
:to="`/admin/expenses/create?customer=${$route.params.id}`"
>
<BaseDropdownItem>
<BaseIcon name="CalculatorIcon" class="mr-3 text-body" />
{{ $t('expenses.new_expense') }}
</BaseDropdownItem>
</router-link>
</BaseDropdown>
<CustomerDropdown
v-if="hasAtleastOneAbility()"
:class="{
'ml-3': isLoading,
}"
:row="customerStore.selectedViewCustomer"
:load-data="refreshData"
/>
</template>
</BasePageHeader>
<!-- Customer View Sidebar -->
<CustomerViewSidebar />
<!-- Chart -->
<CustomerChart />
</BasePage>
</template>