work on customer editor #6

This commit is contained in:
2025-11-21 08:39:34 +01:00
parent 4e578b6cbe
commit 34fa8d6a0d
5 changed files with 291 additions and 129 deletions
+38 -39
View File
@@ -3,12 +3,12 @@
import { ref, onMounted, computed, watch } from 'vue'
import AppLayout from '@/layouts/AppLayout.vue'
import AppHeader from '@/components/AppHeader.vue'
import { Address } from '@/types'
import { Customer } from '@/types'
import { Address, Customer } from '@/types'
import { newCustomer } from '@/types/index.d'
import { bgColorForString } from '@/lib/utils'
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar'
import { Input } from '@/components/ui/input'
import { Button } from '@/components/ui/button'
import { Button } from '@/components/ui/crm-button'
import { ButtonGroup } from '@/components/ui/button-group'
import { Delete, Globe, House, LayoutGrid, Mail, Phone, Plus, Rows3, Search, Smartphone } from "lucide-vue-next"
import Fuse from 'fuse.js';
@@ -19,6 +19,7 @@ import { TooltipArrow } from 'reka-ui'
import CustomerDialog from '@/components/CustomerDialog.vue'
import { toast } from 'vue-sonner'
import { SocialIcon } from '@/components/ui/social-icon'
import { Kbd, KbdGroup } from '@/components/ui/kbd'
interface Props {
customersData: Customer[];
@@ -56,6 +57,15 @@ const filteredCustomers = computed(() => {
return fuse.value.search(searchQuery.value).map(result => result.item);
})
const createCustomer = () => {
editCustomer(newCustomer())
}
const editCustomer = (customer: Customer) => {
// make a deep copy, so the changes in the dialog wont affect the data until saved
activeCustomer.value = JSON.parse(JSON.stringify(customer))
detailDialogOpen.value = true
}
const addressToClipbard = async function (companyName: string | null, address: Address | null, event: Event) {
event.stopPropagation();
@@ -76,11 +86,6 @@ const addressToClipbard = async function (companyName: string | null, address: A
}
}
}
const showDetail = (customer: Customer) => {
// make a deep copy, so the changes in the dialog wont affect the data until saved
activeCustomer.value = JSON.parse(JSON.stringify(customer))
detailDialogOpen.value = true
}
const mail = (email: string, event: Event) => {
event.stopPropagation();
@@ -122,14 +127,14 @@ const call = (number: string, event: Event) => {
<AppHeader>
<!-- View buttons -->
<template #left>
<ButtonGroup aria-label="Button group">
<!-- <ButtonGroup aria-label="Button group">
<Button variant="pressed" size="sm">
<LayoutGrid stroke-width="1.5" />
</Button>
<Button variant="outline" size="sm">
<Rows3 stroke-width="1.5" />
</Button>
</ButtonGroup>
</ButtonGroup> -->
</template>
@@ -149,10 +154,26 @@ const call = (number: string, event: Event) => {
<!-- New button -->
<template #right>
<Button size="sm" variant="action" @click="">
<Plus stroke-width="1.5" /> Neu
</Button>
<TooltipProvider>
<Tooltip>
<TooltipTrigger>
<Button size="sm" variant="action" @click="createCustomer">
<Plus />
Neu
</Button>
</TooltipTrigger>
<TooltipContent>
<span>Neuen Kunden anlegen</span>
<KbdGroup class="ml-2">
<Kbd class="visible-mac"></Kbd>
<Kbd class="visible-pc">Ctrl</Kbd>
<Kbd>N</Kbd>
</KbdGroup>
</TooltipContent>
</Tooltip>
</TooltipProvider>
</template>
</AppHeader>
@@ -160,14 +181,14 @@ const call = (number: string, event: Event) => {
<Card v-for="customer in filteredCustomers" :key="customer.id"
class="relative mb-6 break-inside-avoid hover:border-slate-300 dark:hover:bg-neutral-800/90 dark:hover:border-neutral-600 overflow-clip"
@click="showDetail(customer)">
@click="editCustomer(customer)">
<CardHeader v-if="customer.logo" class="z-0">
<img :src="'storage/uploads/' + customer.logo" alt="Logo {{ customer.companyName }}"
class="max-h-8 max-w-[50%]">
</CardHeader>
<CardContent class="flex justify-between gap-4 flex-col sm:flex-row pr-4 z-0">
<CardContent class="flex justify-between gap-8 flex-col sm:flex-row pr-4 z-0">
<address class="not-italic">
<CardTitle>
{{ customer.companyName }}
@@ -224,7 +245,7 @@ const call = (number: string, event: Event) => {
<Tooltip v-for="contact in customer.contacts">
<TooltipTrigger>
<Avatar class="size-14 shadow -mr-2">
<Avatar class="size-14 border-2 border-background -mr-2">
<AvatarImage v-if="contact.avatar" :src="'/storage/uploads/' + contact.avatar"
loading="lazy" />
<AvatarFallback
@@ -279,26 +300,4 @@ const call = (number: string, event: Event) => {
</AppLayout>
</template>
<style>
/* Remove close X */
[data-slot=dialog-content] button.ring-offset-background {
/* display: none; */
border-radius: 100%;
position: absolute;
left: 1rem;
width: 1rem;
height: 1rem;
color: var(--color-destructive);
}
/* Backdrop */
[data-slot=dialog-overlay] {
backdrop-filter: blur(var(--blur-sm));
}
/* hover:not(:has(*:hover)) */
[data-slot="card"]:hover:has(a:hover),
[data-slot="card"]:hover:has(button:hover) {
background-color: var(--card);
}
</style>
<style></style>
-1
View File
@@ -11,7 +11,6 @@ import DocumentTable from '@/components/documents/DocumentTable.vue'
import { ChevronLeft, ChevronRight, Plus, Search, Delete } from "lucide-vue-next"
import Fuse from 'fuse.js';
import { Input } from '@/components/ui/input'
import { toast } from 'vue-sonner'
import SelectSeparator from '@/components/ui/select/SelectSeparator.vue'
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip'
import { Kbd, KbdGroup } from '@/components/ui/kbd'