From 69695e88aae204b86f39bb51a611eae2c29f179c Mon Sep 17 00:00:00 2001 From: Daniel Stock Date: Wed, 29 Oct 2025 15:42:43 +0100 Subject: [PATCH] Move toaster component to AppLayout #33 --- resources/js/layouts/AppLayout.vue | 39 ++++++++++++++++ resources/js/lib/utils.ts | 39 ++++++++++++++-- resources/js/pages/Customers.vue | 17 ++++--- resources/js/pages/Invoices.vue | 75 ++---------------------------- 4 files changed, 89 insertions(+), 81 deletions(-) diff --git a/resources/js/layouts/AppLayout.vue b/resources/js/layouts/AppLayout.vue index 9714161..75f3a84 100644 --- a/resources/js/layouts/AppLayout.vue +++ b/resources/js/layouts/AppLayout.vue @@ -3,6 +3,9 @@ import AppLayout from '@/layouts/app/AppSidebarLayout.vue'; // import AppLayout from '@/layouts/app/AppHeaderLayout.vue'; import type { BreadcrumbItemType } from '@/types'; import { computed, onMounted } from 'vue'; +import 'vue-sonner/style.css' +import { Toaster } from 'vue-sonner' +import { Info, CircleAlert, CircleCheck, LoaderCircle, Ban } from "lucide-vue-next" interface Props { breadcrumbs?: BreadcrumbItemType[]; @@ -21,7 +24,43 @@ onMounted(() => { diff --git a/resources/js/lib/utils.ts b/resources/js/lib/utils.ts index b10f67b..5fa62b9 100644 --- a/resources/js/lib/utils.ts +++ b/resources/js/lib/utils.ts @@ -1,6 +1,7 @@ -import { InertiaLinkProps } from '@inertiajs/vue3'; -import { clsx, type ClassValue } from 'clsx'; -import { twMerge } from 'tailwind-merge'; +import { InertiaLinkProps } from '@inertiajs/vue3' +import { clsx, type ClassValue } from 'clsx' +import { twMerge } from 'tailwind-merge' +import { toast } from 'vue-sonner' export function cn(...inputs: ClassValue[]) { return twMerge(clsx(inputs)); @@ -68,4 +69,36 @@ export function bgColorForString(input: string): string { charCodeSum += input.charCodeAt(i) } return randomColors[charCodeSum % randomColors.length]; +} + +const promise = () => new Promise((resolve) => setTimeout(resolve, 2000)) +export function testToast() { + let delay = 150 + toast('Toast', { + description: "Description bjksad fkjlhsd fkjhsdf jkshdf jkashdf adskljhf ", action: { + label: 'Undo', + onClick: () => console.log('Undo') + } + }) + setTimeout(() => { + toast.info('Info', { + action: { + label: 'Undo', + onClick: () => console.log('Undo') + } + }) + }, delay * 1) + setTimeout(() => { toast.success('Success', { description: "description" }) }, delay * 2) + setTimeout(() => { toast.warning('Warning', { description: "description" }) }, delay * 3) + setTimeout(() => { toast.error('Error', { description: "description" }) }, delay * 4) + setTimeout(() => { + toast.promise(promise, { + loading: 'Loading...', + success: (data) => { + return `${data.name} toast has been added`; + }, + error: (data: any) => 'Error', + }) + }, delay * 5) + } \ No newline at end of file diff --git a/resources/js/pages/Customers.vue b/resources/js/pages/Customers.vue index 640ce2e..d241113 100644 --- a/resources/js/pages/Customers.vue +++ b/resources/js/pages/Customers.vue @@ -17,6 +17,8 @@ import { getInitials } from '@/composables/useInitials'; import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, } from '@/components/ui/card' import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip' import CustomerDialog from '@/components/CustomerDialog.vue' +import { toast } from 'vue-sonner' +import { AxiosError } from 'axios' const breadcrumbs: BreadcrumbItem[] = [ { @@ -38,8 +40,8 @@ onMounted(async () => { searchField.value = document.getElementById('search') searchField.value.focus() - } catch (error) { - // TODO: toast, depends on #33 + } catch (error: AxiosError) { + toast.error(error.name, { description: error.message }) } }) @@ -68,12 +70,13 @@ const addressToClipbard = async function (address: Address) { address.lineOne + '\n' + (address.lineTwo ? address.lineTwo + '\n' : '') + address.postalCode + ' ' + address.city - // TODO: toast, depends on #33 ) - } catch (error) { - if (error instanceof Error) - // TODO: toast, depends on #33 - console.error(error.message) + toast('Adresse kopiert', { duration: 2000 }) + + } catch (notAllowedError: DOMException) { + if (notAllowedError instanceof Error) { + toast.error(notAllowedError.name, { description: notAllowedError.message }) + } } } diff --git a/resources/js/pages/Invoices.vue b/resources/js/pages/Invoices.vue index 41af0d3..c79e359 100644 --- a/resources/js/pages/Invoices.vue +++ b/resources/js/pages/Invoices.vue @@ -10,13 +10,12 @@ import axios, { Axios, AxiosError, AxiosResponse } from 'axios' import { Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectTrigger, SelectValue, } from '@/components/ui/select' import { Button } from '@/components/ui/button' import DocumentTable from '@/components/documents/DocumentTable.vue' -import { ChevronLeft, ChevronRight, Plus, Search, Delete, LetterText, Info, Check, CircleAlert, Circle, CircleX, CircleCheck, LoaderCircle, Ban, CircleSlash, CircleMinus } from "lucide-vue-next" +import { ChevronLeft, ChevronRight, Plus, Search, Delete } from "lucide-vue-next" import InvoiceDialog from '@/components/documents/InvoiceDialog.vue' import Fuse from 'fuse.js'; import { Input } from '@/components/ui/input' - -import 'vue-sonner/style.css' -import { Toaster, toast } from 'vue-sonner' +import { toast } from 'vue-sonner' +import { testToast } from '@/lib/utils' import SelectSeparator from '@/components/ui/select/SelectSeparator.vue' const breadcrumbs: BreadcrumbItem[] = [{ @@ -181,80 +180,14 @@ const deleteInvoice = async (id: number) => { } } -const promise = () => new Promise((resolve) => setTimeout(resolve, 2000)) -const testToast = () => { - let delay = 150 - toast('Toast', { - description: "Description bjksad fkjlhsd fkjhsdf jkshdf jkashdf adskljhf ", action: { - label: 'Undo', - onClick: () => console.log('Undo') - } - }) - setTimeout(() => { - toast.info('Info', { - action: { - label: 'Undo', - onClick: () => console.log('Undo') - } - }) - }, delay * 1) - setTimeout(() => { toast.success('Success', { description: "description" }) }, delay * 2) - setTimeout(() => { toast.warning('Warning', { description: "description" }) }, delay * 3) - setTimeout(() => { toast.error('Error', { description: "description" }) }, delay * 4) - setTimeout(() => { - toast.promise(promise, { - loading: 'Loading...', - success: (data) => { - return `${data.name} toast has been added`; - }, - error: (data: any) => 'Error', - }) - }, delay * 5) - -} -