Add InvoiceService and initial invoice dashboard widget
This commit is contained in:
@@ -2,31 +2,38 @@
|
||||
import Heading from '@/components/Heading.vue';
|
||||
import { onMounted, ref } from "vue"
|
||||
import AppLayout from '@/layouts/AppLayout.vue';
|
||||
import { Trophy, UserCheck2, X, ChevronRight } from 'lucide-vue-next';
|
||||
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"
|
||||
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, } from '@/components/ui/card'
|
||||
import Button from '@/components/ui/crm-button/Button.vue';
|
||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle, } from '@/components/ui/card'
|
||||
import { invoices } from '@/routes';
|
||||
import { toRoundedCurrency } from '@/lib/utils'
|
||||
import { toRoundedCurrency, toLocalDate } from '@/lib/utils'
|
||||
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, } from '@/components/ui/tooltip'
|
||||
import { Label } from '@/components/ui/label'
|
||||
import { Switch } from '@/components/ui/switch'
|
||||
import { Link, usePage } from '@inertiajs/vue3';
|
||||
import { usePage, router } from '@inertiajs/vue3';
|
||||
import axios, { AxiosError } from "axios";
|
||||
import { toast } from "vue-sonner";
|
||||
import { AppPageProps, Todo } from "@/types";
|
||||
import { SalesStatistics, Todo, Invoice } from "@/types";
|
||||
import Todos from '@/components/Todos.vue';
|
||||
import InvoiceService from '@/services/InvoiceService';
|
||||
import { Table, TableRow, TableCell } from '@/components/ui/crm-table';
|
||||
|
||||
const salesStatistics = ref({
|
||||
interface Props {
|
||||
dueInvoices: Invoice[];
|
||||
}
|
||||
const props = defineProps<Props>();
|
||||
const salesStatistics = ref<SalesStatistics>({
|
||||
year: new Date().getFullYear(),
|
||||
totalRevenue: 0,
|
||||
paid: 0,
|
||||
paidPercent: 0,
|
||||
draft: 0,
|
||||
draftPercent: 0,
|
||||
issued: 0,
|
||||
issuedPercent: 0,
|
||||
due: 0,
|
||||
duePercent: 0,
|
||||
reminded: 0,
|
||||
remindedPercent: 0
|
||||
})
|
||||
|
||||
const salesTarget = ref(60000) // TODO: aus settings
|
||||
const todos = ref<Todo[]>([])
|
||||
const showCompleted = ref(false)
|
||||
@@ -48,8 +55,7 @@ onMounted(async () => {
|
||||
|
||||
// Load sales statistics
|
||||
try {
|
||||
let response = await axios.get('/api/invoices/salesStatistics')
|
||||
salesStatistics.value = response.data
|
||||
salesStatistics.value = await InvoiceService.getSalesStatistics()
|
||||
} catch (error) {
|
||||
toast.error('Fehler beim Laden der Daten', { description: (error as AxiosError).message })
|
||||
}
|
||||
@@ -67,7 +73,7 @@ onMounted(async () => {
|
||||
|
||||
|
||||
<!-- Nachrichten -->
|
||||
<Card class="break-inside-avoid mb-12">
|
||||
<!-- <Card class="break-inside-avoid mb-12">
|
||||
<CardHeader>
|
||||
<CardTitle>Benachrichtigungen</CardTitle>
|
||||
<CardDescription>Card Description</CardDescription>
|
||||
@@ -104,11 +110,11 @@ onMounted(async () => {
|
||||
<CardFooter>
|
||||
<Button>Alles leeren</Button>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
</Card> -->
|
||||
|
||||
|
||||
<!-- Aufgaben -->
|
||||
<Card class="break-inside-avoid mb-8">
|
||||
<Card class="break-inside-avoid mb-8 ">
|
||||
<CardHeader class="flex justify-between flex-wrap">
|
||||
<div>
|
||||
<CardTitle class="mb-1.5">Aufgaben</CardTitle>
|
||||
@@ -120,7 +126,7 @@ onMounted(async () => {
|
||||
<Label for="show-completed" class="text-muted-foreground">Erledigte</Label>
|
||||
</div>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<CardContent class="max-h-[600px] overflow-y-auto">
|
||||
<Todos :modelValue="todos" :show-completed="showCompleted" :show-todoable="true" />
|
||||
</CardContent>
|
||||
</Card>
|
||||
@@ -132,11 +138,21 @@ onMounted(async () => {
|
||||
<CardDescription>Card Description</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
|
||||
<Table class="text-sm">
|
||||
<TableRow v-for="invoice in props.dueInvoices" @mouseover="router.prefetch(invoices())" @click="router.visit(invoices())">
|
||||
<TableCell class="align-top">
|
||||
<span class="whitespace-nowrap" v-if="invoice.dueDate">{{ toLocalDate(invoice.dueDate)
|
||||
}}</span>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<span class="font-semibold">{{ invoice.nr }}</span> {{ invoice.title }}<br>
|
||||
<span class="text-muted-foreground">{{ invoice.billingData?.companyName }}</span>
|
||||
</TableCell>
|
||||
<TableCell class="align-top text-right">{{ toRoundedCurrency(invoice.totalAmount) }}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
</Table>
|
||||
</CardContent>
|
||||
<CardFooter>
|
||||
<Link :href="invoices()" prefetch><Button>Zu den Rechnungen</Button></Link>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
import { computed, ref, onMounted } from 'vue'
|
||||
import { type Invoice } from '@/types'
|
||||
import { newInvoice } from '@/types/index.d'
|
||||
import axios from 'axios'
|
||||
import AppLayout from '@/layouts/AppLayout.vue'
|
||||
import AppHeader from '@/components/AppHeader.vue'
|
||||
import { Button } from '@/components/ui/crm-button'
|
||||
@@ -18,6 +17,7 @@ import { Kbd, KbdGroup } from '@/components/ui/kbd'
|
||||
import { statusBadgeLabels } from '@/components/ui/status-badge'
|
||||
import InvoiceDialog from '@/components/documents/InvoiceDialog.vue'
|
||||
import { hotkey, getPlatformModifierSymbol } from '@/lib/utils'
|
||||
import InvoiceService from '@/services/InvoiceService'
|
||||
|
||||
// Initial invoice data from inertia (see InvoiceController::show)
|
||||
interface Props {
|
||||
@@ -34,8 +34,8 @@ const searchField = ref()
|
||||
onMounted(async () => {
|
||||
// Load older invoices after initial page load
|
||||
try {
|
||||
const invoiceBeforeThisYearResponse = await axios.get('/api/invoices/summaryBeforeThisYear')
|
||||
invoicesData.value = invoicesData.value.concat(invoiceBeforeThisYearResponse.data as Invoice[])
|
||||
const invoiceBeforeThisYearResponse = await InvoiceService.getSummaryBeforeThisYear()
|
||||
invoicesData.value = invoicesData.value.concat(invoiceBeforeThisYearResponse)
|
||||
invoicesData.value = invoicesData.value.sort(
|
||||
(a, b) => new Date(a.invoiceDate).getTime() - new Date(b.invoiceDate).getTime()
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user