Remove unused features from starter kit, #35
This commit is contained in:
@@ -36,12 +36,9 @@ public function version(Request $request): ?string
|
||||
*/
|
||||
public function share(Request $request): array
|
||||
{
|
||||
[$message, $author] = str(Inspiring::quotes()->random())->explode('-');
|
||||
|
||||
return [
|
||||
...parent::share($request),
|
||||
'name' => config('app.name'),
|
||||
'quote' => ['message' => trim($message), 'author' => trim($author)],
|
||||
'auth' => [
|
||||
'user' => $request->user(),
|
||||
],
|
||||
|
||||
@@ -1,204 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import AppLogo from '@/components/AppLogo.vue';
|
||||
import AppLogoIcon from '@/components/AppLogoIcon.vue';
|
||||
import Breadcrumbs from '@/components/Breadcrumbs.vue';
|
||||
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { DropdownMenu, DropdownMenuContent, DropdownMenuTrigger } from '@/components/ui/dropdown-menu';
|
||||
import { NavigationMenu, NavigationMenuItem, NavigationMenuList, navigationMenuTriggerStyle } from '@/components/ui/navigation-menu';
|
||||
import { Sheet, SheetContent, SheetHeader, SheetTitle, SheetTrigger } from '@/components/ui/sheet';
|
||||
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip';
|
||||
import UserMenuContent from '@/components/UserMenuContent.vue';
|
||||
import { getInitials } from '@/composables/useInitials';
|
||||
import { toUrl, urlIsActive } from '@/lib/utils';
|
||||
import { dashboard, crm, invoices, customers } from '@/routes';
|
||||
import type { BreadcrumbItem, NavItem } from '@/types';
|
||||
import { InertiaLinkProps, Link, usePage } from '@inertiajs/vue3';
|
||||
import { BookOpen, Folder, LayoutGrid, Kanban, Euro, Contact, Search } from 'lucide-vue-next';
|
||||
import { computed } from 'vue';
|
||||
|
||||
interface Props {
|
||||
breadcrumbs?: BreadcrumbItem[];
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
breadcrumbs: () => [],
|
||||
});
|
||||
|
||||
const page = usePage();
|
||||
const auth = computed(() => page.props.auth);
|
||||
|
||||
const isCurrentRoute = computed(() => (url: NonNullable<InertiaLinkProps['href']>) => urlIsActive(url, page.url));
|
||||
|
||||
const activeItemStyles = computed(
|
||||
() => (url: NonNullable<InertiaLinkProps['href']>) =>
|
||||
isCurrentRoute.value(toUrl(url)) ? 'text-neutral-900 dark:bg-neutral-800 dark:text-neutral-100' : '',
|
||||
);
|
||||
|
||||
const mainNavItems: NavItem[] = [
|
||||
{
|
||||
title: 'Dashboard',
|
||||
href: dashboard(),
|
||||
icon: LayoutGrid,
|
||||
},
|
||||
{
|
||||
title: 'CRM',
|
||||
href: crm(),
|
||||
icon: Kanban,
|
||||
},
|
||||
{
|
||||
title: 'Rechnungsstellung',
|
||||
href: invoices(),
|
||||
icon: Euro,
|
||||
},
|
||||
{
|
||||
title: 'Kunden',
|
||||
href: customers(),
|
||||
icon: Contact,
|
||||
},
|
||||
];
|
||||
|
||||
const rightNavItems: NavItem[] = [
|
||||
// {
|
||||
// title: 'Repository',
|
||||
// href: 'https://github.com/laravel/vue-starter-kit',
|
||||
// icon: Folder,
|
||||
// },
|
||||
// {
|
||||
// title: 'Documentation',
|
||||
// href: 'https://laravel.com/docs/starter-kits#vue',
|
||||
// icon: BookOpen,
|
||||
// },
|
||||
];
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<div class="border-b border-sidebar-border/80">
|
||||
<div class="mx-auto flex h-16 items-center px-4 md:max-w-7xl">
|
||||
<!-- Mobile Menu -->
|
||||
<div class="lg:hidden">
|
||||
<Sheet>
|
||||
<SheetTrigger :as-child="true">
|
||||
<Button variant="ghost" size="icon" class="mr-2 h-9 w-9">
|
||||
<Menu class="h-5 w-5" />
|
||||
</Button>
|
||||
</SheetTrigger>
|
||||
<SheetContent side="left" class="w-[300px] p-6">
|
||||
<SheetTitle class="sr-only">Navigation Menu</SheetTitle>
|
||||
<SheetHeader class="flex justify-start text-left">
|
||||
<AppLogoIcon class="size-6 fill-current text-black dark:text-white" />
|
||||
</SheetHeader>
|
||||
<div class="flex h-full flex-1 flex-col justify-between space-y-4 py-6">
|
||||
<nav class="-mx-3 space-y-1">
|
||||
<Link
|
||||
v-for="item in mainNavItems"
|
||||
:key="item.title"
|
||||
:href="item.href"
|
||||
class="flex items-center gap-x-3 rounded-lg px-3 py-2 text-sm font-medium hover:bg-accent"
|
||||
:class="activeItemStyles(item.href)"
|
||||
>
|
||||
<component v-if="item.icon" :is="item.icon" class="h-5 w-5" />
|
||||
{{ item.title }}
|
||||
</Link>
|
||||
</nav>
|
||||
<div class="flex flex-col space-y-4">
|
||||
<a
|
||||
v-for="item in rightNavItems"
|
||||
:key="item.title"
|
||||
:href="toUrl(item.href)"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="flex items-center space-x-2 text-sm font-medium"
|
||||
>
|
||||
<component v-if="item.icon" :is="item.icon" class="h-5 w-5" />
|
||||
<span>{{ item.title }}</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</SheetContent>
|
||||
</Sheet>
|
||||
</div>
|
||||
|
||||
<Link :href="dashboard()" class="flex items-center gap-x-2">
|
||||
<AppLogo />
|
||||
</Link>
|
||||
|
||||
<!-- Desktop Menu -->
|
||||
<div class="hidden h-full lg:flex lg:flex-1">
|
||||
<NavigationMenu class="ml-10 flex h-full items-stretch">
|
||||
<NavigationMenuList class="flex h-full items-stretch space-x-2">
|
||||
<NavigationMenuItem v-for="(item, index) in mainNavItems" :key="index" class="relative flex h-full items-center">
|
||||
<Link
|
||||
:class="[navigationMenuTriggerStyle(), activeItemStyles(item.href), 'h-9 cursor-pointer px-3']"
|
||||
:href="item.href"
|
||||
>
|
||||
<component v-if="item.icon" :is="item.icon" class="mr-2 h-4 w-4" />
|
||||
{{ item.title }}
|
||||
</Link>
|
||||
<div
|
||||
v-if="isCurrentRoute(item.href)"
|
||||
class="absolute bottom-0 left-0 h-0.5 w-full translate-y-px bg-black dark:bg-white"
|
||||
></div>
|
||||
</NavigationMenuItem>
|
||||
</NavigationMenuList>
|
||||
</NavigationMenu>
|
||||
</div>
|
||||
|
||||
<div class="ml-auto flex items-center space-x-2">
|
||||
<div class="relative flex items-center space-x-1">
|
||||
<Button variant="ghost" size="icon" class="group h-9 w-9 cursor-pointer">
|
||||
<Search class="size-5 opacity-80 group-hover:opacity-100" />
|
||||
</Button>
|
||||
|
||||
<div class="hidden space-x-1 lg:flex">
|
||||
<template v-for="item in rightNavItems" :key="item.title">
|
||||
<TooltipProvider :delay-duration="0">
|
||||
<Tooltip>
|
||||
<TooltipTrigger>
|
||||
<Button variant="ghost" size="icon" as-child class="group h-9 w-9 cursor-pointer">
|
||||
<a :href="toUrl(item.href)" target="_blank" rel="noopener noreferrer">
|
||||
<span class="sr-only">{{ item.title }}</span>
|
||||
<component :is="item.icon" class="size-5 opacity-80 group-hover:opacity-100" />
|
||||
</a>
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>
|
||||
<p>{{ item.title }}</p>
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
</TooltipProvider>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger :as-child="true">
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
class="relative size-10 w-auto rounded-full p-1 focus-within:ring-2 focus-within:ring-primary"
|
||||
>
|
||||
<Avatar class="size-8 overflow-hidden rounded-full">
|
||||
<AvatarImage v-if="auth.user.avatar" :src="auth.user.avatar" :alt="auth.user.name" />
|
||||
<AvatarFallback class="rounded-lg bg-neutral-200 font-semibold text-black dark:bg-neutral-700 dark:text-white">
|
||||
{{ getInitials(auth.user?.name) }}
|
||||
</AvatarFallback>
|
||||
</Avatar>
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent align="end" class="w-56">
|
||||
<UserMenuContent :user="auth.user" />
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="props.breadcrumbs.length > 1" class="flex w-full border-b border-sidebar-border/70">
|
||||
<div class="mx-auto flex h-12 w-full items-center justify-start px-4 text-neutral-500 md:max-w-7xl">
|
||||
<Breadcrumbs :breadcrumbs="breadcrumbs" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -1,21 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import { SidebarProvider } from '@/components/ui/sidebar';
|
||||
import { usePage } from '@inertiajs/vue3';
|
||||
|
||||
interface Props {
|
||||
variant?: 'header' | 'sidebar';
|
||||
}
|
||||
|
||||
defineProps<Props>();
|
||||
|
||||
const isOpen = usePage().props.sidebarOpen;
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div v-if="variant === 'header'" class="flex min-h-screen w-full flex-col">
|
||||
<slot />
|
||||
</div>
|
||||
<SidebarProvider v-else :default-open="isOpen">
|
||||
<slot />
|
||||
</SidebarProvider>
|
||||
</template>
|
||||
@@ -105,7 +105,6 @@ const footerNavItems: NavItem[] = [
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
</TooltipProvider>
|
||||
|
||||
</SidebarHeader>
|
||||
|
||||
<SidebarContent>
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import Breadcrumbs from '@/components/Breadcrumbs.vue';
|
||||
import { SidebarTrigger } from '@/components/ui/sidebar';
|
||||
import type { BreadcrumbItemType } from '@/types';
|
||||
import NavUser from '@/components/NavUser.vue';
|
||||
|
||||
withDefaults(
|
||||
defineProps<{
|
||||
breadcrumbs?: BreadcrumbItemType[];
|
||||
}>(),
|
||||
{
|
||||
breadcrumbs: () => [],
|
||||
},
|
||||
);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
<header
|
||||
class="flex md:hidden bg-background justify-between shrink-0 items-center gap-2 border-b border-sidebar-border/70 px-4 transition-[width,height] ease-linear z-10">
|
||||
|
||||
|
||||
<div class="flex items-center gap-2">
|
||||
<SidebarTrigger class="-ml-1 text-primary-foreground" />
|
||||
|
||||
<template v-if="breadcrumbs && breadcrumbs.length > 0">
|
||||
<Breadcrumbs :breadcrumbs="breadcrumbs" />
|
||||
</template>
|
||||
</div>
|
||||
|
||||
<NavUser />
|
||||
</header>
|
||||
</template>
|
||||
@@ -1,33 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import { Breadcrumb, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator } from '@/components/ui/breadcrumb';
|
||||
import { Link } from '@inertiajs/vue3';
|
||||
|
||||
interface BreadcrumbItemType {
|
||||
title: string;
|
||||
href?: string;
|
||||
}
|
||||
|
||||
defineProps<{
|
||||
breadcrumbs: BreadcrumbItemType[];
|
||||
}>();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Breadcrumb>
|
||||
<BreadcrumbList>
|
||||
<template v-for="(item, index) in breadcrumbs" :key="index">
|
||||
<BreadcrumbItem>
|
||||
<template v-if="index === breadcrumbs.length - 1">
|
||||
<BreadcrumbPage>{{ item.title }}</BreadcrumbPage>
|
||||
</template>
|
||||
<template v-else>
|
||||
<BreadcrumbLink as-child>
|
||||
<Link :href="item.href ?? '#'">{{ item.title }}</Link>
|
||||
</BreadcrumbLink>
|
||||
</template>
|
||||
</BreadcrumbItem>
|
||||
<BreadcrumbSeparator v-if="index !== breadcrumbs.length - 1" />
|
||||
</template>
|
||||
</BreadcrumbList>
|
||||
</Breadcrumb>
|
||||
</template>
|
||||
@@ -1,17 +0,0 @@
|
||||
<script lang="ts" setup>
|
||||
import type { HTMLAttributes } from 'vue'
|
||||
|
||||
const props = defineProps<{
|
||||
class?: HTMLAttributes['class']
|
||||
}>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<nav
|
||||
aria-label="breadcrumb"
|
||||
data-slot="breadcrumb"
|
||||
:class="props.class"
|
||||
>
|
||||
<slot />
|
||||
</nav>
|
||||
</template>
|
||||
@@ -1,23 +0,0 @@
|
||||
<script lang="ts" setup>
|
||||
import type { HTMLAttributes } from 'vue'
|
||||
import { cn } from '@/lib/utils'
|
||||
import { MoreHorizontal } from 'lucide-vue-next'
|
||||
|
||||
const props = defineProps<{
|
||||
class?: HTMLAttributes['class']
|
||||
}>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<span
|
||||
data-slot="breadcrumb-ellipsis"
|
||||
role="presentation"
|
||||
aria-hidden="true"
|
||||
:class="cn('flex size-9 items-center justify-center', props.class)"
|
||||
>
|
||||
<slot>
|
||||
<MoreHorizontal class="size-4" />
|
||||
</slot>
|
||||
<span class="sr-only">More</span>
|
||||
</span>
|
||||
</template>
|
||||
@@ -1,17 +0,0 @@
|
||||
<script lang="ts" setup>
|
||||
import type { HTMLAttributes } from 'vue'
|
||||
import { cn } from '@/lib/utils'
|
||||
|
||||
const props = defineProps<{
|
||||
class?: HTMLAttributes['class']
|
||||
}>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<li
|
||||
data-slot="breadcrumb-item"
|
||||
:class="cn('inline-flex items-center gap-1.5', props.class)"
|
||||
>
|
||||
<slot />
|
||||
</li>
|
||||
</template>
|
||||
@@ -1,20 +0,0 @@
|
||||
<script lang="ts" setup>
|
||||
import type { HTMLAttributes } from 'vue'
|
||||
import { cn } from '@/lib/utils'
|
||||
import { Primitive, type PrimitiveProps } from 'reka-ui'
|
||||
|
||||
const props = withDefaults(defineProps<PrimitiveProps & { class?: HTMLAttributes['class'] }>(), {
|
||||
as: 'a',
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Primitive
|
||||
data-slot="breadcrumb-link"
|
||||
:as="as"
|
||||
:as-child="asChild"
|
||||
:class="cn('hover:text-foreground transition-colors', props.class)"
|
||||
>
|
||||
<slot />
|
||||
</Primitive>
|
||||
</template>
|
||||
@@ -1,17 +0,0 @@
|
||||
<script lang="ts" setup>
|
||||
import type { HTMLAttributes } from 'vue'
|
||||
import { cn } from '@/lib/utils'
|
||||
|
||||
const props = defineProps<{
|
||||
class?: HTMLAttributes['class']
|
||||
}>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ol
|
||||
data-slot="breadcrumb-list"
|
||||
:class="cn('text-muted-foreground flex flex-wrap items-center gap-1.5 text-sm break-words sm:gap-2.5', props.class)"
|
||||
>
|
||||
<slot />
|
||||
</ol>
|
||||
</template>
|
||||
@@ -1,20 +0,0 @@
|
||||
<script lang="ts" setup>
|
||||
import type { HTMLAttributes } from 'vue'
|
||||
import { cn } from '@/lib/utils'
|
||||
|
||||
const props = defineProps<{
|
||||
class?: HTMLAttributes['class']
|
||||
}>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<span
|
||||
data-slot="breadcrumb-page"
|
||||
role="link"
|
||||
aria-disabled="true"
|
||||
aria-current="page"
|
||||
:class="cn('text-foreground font-normal', props.class)"
|
||||
>
|
||||
<slot />
|
||||
</span>
|
||||
</template>
|
||||
@@ -1,22 +0,0 @@
|
||||
<script lang="ts" setup>
|
||||
import type { HTMLAttributes } from 'vue'
|
||||
import { cn } from '@/lib/utils'
|
||||
import { ChevronRight } from 'lucide-vue-next'
|
||||
|
||||
const props = defineProps<{
|
||||
class?: HTMLAttributes['class']
|
||||
}>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<li
|
||||
data-slot="breadcrumb-separator"
|
||||
role="presentation"
|
||||
aria-hidden="true"
|
||||
:class="cn('[&>svg]:size-3.5', props.class)"
|
||||
>
|
||||
<slot>
|
||||
<ChevronRight />
|
||||
</slot>
|
||||
</li>
|
||||
</template>
|
||||
@@ -1,7 +0,0 @@
|
||||
export { default as Breadcrumb } from './Breadcrumb.vue'
|
||||
export { default as BreadcrumbEllipsis } from './BreadcrumbEllipsis.vue'
|
||||
export { default as BreadcrumbItem } from './BreadcrumbItem.vue'
|
||||
export { default as BreadcrumbLink } from './BreadcrumbLink.vue'
|
||||
export { default as BreadcrumbList } from './BreadcrumbList.vue'
|
||||
export { default as BreadcrumbPage } from './BreadcrumbPage.vue'
|
||||
export { default as BreadcrumbSeparator } from './BreadcrumbSeparator.vue'
|
||||
@@ -1,24 +1,19 @@
|
||||
<script setup lang="ts">
|
||||
import AppLayout from '@/layouts/app/AppSidebarLayout.vue';
|
||||
// import AppLayout from '@/layouts/app/AppHeaderLayout.vue';
|
||||
import type { BreadcrumbItemType } from '@/types';
|
||||
import { ref, onMounted } from 'vue';
|
||||
import AppContent from '@/components/AppContent.vue';
|
||||
import AppSidebar from '@/components/AppSidebar.vue';
|
||||
import { onMounted } from 'vue';
|
||||
import 'vue-sonner/style.css'
|
||||
import { Toaster } from 'vue-sonner'
|
||||
import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, AlertDialogTrigger, } from '@/components/ui/alert-dialog'
|
||||
import { AlertDialog, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, } from '@/components/ui/alert-dialog'
|
||||
import { Info, CircleAlert, CircleCheck, LoaderCircle, Ban } from "lucide-vue-next"
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { alertStore } from '@/stores/alertStore';
|
||||
import { SidebarProvider } from '@/components/ui/sidebar';
|
||||
import { usePage } from '@inertiajs/vue3';
|
||||
|
||||
interface Props {
|
||||
breadcrumbs?: BreadcrumbItemType[];
|
||||
}
|
||||
const isOpen = usePage().props.sidebarOpen;
|
||||
const alert = alertStore()
|
||||
|
||||
withDefaults(defineProps<Props>(), {
|
||||
breadcrumbs: () => [],
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
if (navigator.platform.toUpperCase().indexOf('MAC') >= 0) {
|
||||
document.body.classList.add('is-mac')
|
||||
@@ -62,9 +57,12 @@ onMounted(() => {
|
||||
</template>
|
||||
</Toaster>
|
||||
|
||||
<AppLayout :breadcrumbs="breadcrumbs">
|
||||
<slot />
|
||||
</AppLayout>
|
||||
<SidebarProvider :default-open="isOpen">
|
||||
<AppSidebar />
|
||||
<AppContent variant="sidebar" class="overflow-x-hidden bg-main">
|
||||
<slot />
|
||||
</AppContent>
|
||||
</SidebarProvider>
|
||||
|
||||
<AlertDialog v-model:open="alert.open">
|
||||
<AlertDialogContent>
|
||||
@@ -79,6 +77,32 @@ onMounted(() => {
|
||||
</AlertDialogContent>
|
||||
</AlertDialog>
|
||||
|
||||
|
||||
|
||||
</template>
|
||||
|
||||
<style>
|
||||
@media print {
|
||||
|
||||
header,
|
||||
[data-slot="sidebar"] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 25mm;
|
||||
}
|
||||
|
||||
html,
|
||||
body,
|
||||
[data-slot-sidebar-wrapper] {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
main {
|
||||
margin: 0;
|
||||
background-color: transparent;
|
||||
border-radius: 0;
|
||||
box-shadow: none;
|
||||
outline: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,23 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import AppContent from '@/components/AppContent.vue';
|
||||
import AppHeader from '@/components/AppHeader.vue';
|
||||
import AppShell from '@/components/AppShell.vue';
|
||||
import type { BreadcrumbItemType } from '@/types';
|
||||
|
||||
interface Props {
|
||||
breadcrumbs?: BreadcrumbItemType[];
|
||||
}
|
||||
|
||||
withDefaults(defineProps<Props>(), {
|
||||
breadcrumbs: () => [],
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<AppShell class="flex-col">
|
||||
<AppHeader :breadcrumbs="breadcrumbs"/>
|
||||
<AppContent>
|
||||
<slot />
|
||||
</AppContent>
|
||||
</AppShell>
|
||||
</template>
|
||||
@@ -1,49 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import AppContent from '@/components/AppContent.vue';
|
||||
import AppShell from '@/components/AppShell.vue';
|
||||
import AppSidebar from '@/components/AppSidebar.vue';
|
||||
import AppSidebarHeader from '@/components/AppSidebarHeader.vue';
|
||||
import type { BreadcrumbItemType } from '@/types';
|
||||
|
||||
interface Props {
|
||||
breadcrumbs?: BreadcrumbItemType[];
|
||||
}
|
||||
|
||||
withDefaults(defineProps<Props>(), {
|
||||
breadcrumbs: () => [],
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<AppShell variant="sidebar">
|
||||
<AppSidebar />
|
||||
<AppContent variant="sidebar" class="overflow-x-hidden bg-main">
|
||||
<AppSidebarHeader :breadcrumbs="breadcrumbs" />
|
||||
<slot />
|
||||
</AppContent>
|
||||
</AppShell>
|
||||
</template>
|
||||
|
||||
<style>
|
||||
@media print {
|
||||
header,
|
||||
[data-slot="sidebar"]
|
||||
{
|
||||
display: none;
|
||||
}
|
||||
body {
|
||||
margin: 25mm;
|
||||
}
|
||||
html, body,
|
||||
[data-slot-sidebar-wrapper] {
|
||||
background-color: transparent;
|
||||
}
|
||||
main {
|
||||
margin: 0;
|
||||
background-color: transparent;
|
||||
border-radius: 0;
|
||||
box-shadow: none;
|
||||
outline: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,11 +1,10 @@
|
||||
<script setup lang="ts">
|
||||
import AppLogoIcon from '@/components/AppLogoIcon.vue';
|
||||
import { home } from '@/routes';
|
||||
import { Link, usePage } from '@inertiajs/vue3';
|
||||
import { usePage } from '@inertiajs/vue3';
|
||||
|
||||
const page = usePage();
|
||||
const name = page.props.name;
|
||||
const quote = page.props.quote;
|
||||
|
||||
defineProps<{
|
||||
title?: string;
|
||||
|
||||
@@ -1,23 +1,15 @@
|
||||
<script setup lang="ts">
|
||||
import AppLayout from '@/layouts/AppLayout.vue';
|
||||
import { achievements } from '@/routes';
|
||||
import { type BreadcrumbItem } from '@/types';
|
||||
import { Head } from '@inertiajs/vue3';
|
||||
import PlaceholderPattern from '../components/PlaceholderPattern.vue';
|
||||
const breadcrumbs: BreadcrumbItem[] = [
|
||||
{
|
||||
title: 'Erfolge',
|
||||
href: achievements().url,
|
||||
},
|
||||
];
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
<Head title="Erfolge" />
|
||||
|
||||
<AppLayout :breadcrumbs="breadcrumbs">
|
||||
<AppLayout>
|
||||
<div class="flex h-full flex-1 flex-col gap-4 overflow-x-auto rounded-xl p-4">
|
||||
|
||||
<div>
|
||||
|
||||
@@ -1,37 +1,13 @@
|
||||
<script setup lang="ts">
|
||||
import AppLayout from '@/layouts/AppLayout.vue';
|
||||
import { crm } from '@/routes';
|
||||
import { type BreadcrumbItem } from '@/types';
|
||||
import { Head } from '@inertiajs/vue3';
|
||||
import PlaceholderPattern from '../components/PlaceholderPattern.vue';
|
||||
|
||||
const breadcrumbs: BreadcrumbItem[] = [
|
||||
{
|
||||
title: 'CRM',
|
||||
href: crm().url,
|
||||
},
|
||||
];
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
<Head title="Dashboard" />
|
||||
|
||||
<AppLayout :breadcrumbs="breadcrumbs">
|
||||
<div class="flex h-full flex-1 flex-col gap-4 overflow-x-auto rounded-xl p-4">
|
||||
<!-- <div class="grid auto-rows-min gap-4 md:grid-cols-3">
|
||||
<div class="relative aspect-video overflow-hidden rounded-xl border border-sidebar-border/70 dark:border-sidebar-border">
|
||||
<PlaceholderPattern />
|
||||
</div>
|
||||
<div class="relative aspect-video overflow-hidden rounded-xl border border-sidebar-border/70 dark:border-sidebar-border">
|
||||
<PlaceholderPattern />
|
||||
</div>
|
||||
<div class="relative aspect-video overflow-hidden rounded-xl border border-sidebar-border/70 dark:border-sidebar-border">
|
||||
<PlaceholderPattern />
|
||||
</div>
|
||||
</div>
|
||||
<div class="relative min-h-[100vh] flex-1 rounded-xl border border-sidebar-border/70 md:min-h-min dark:border-sidebar-border">
|
||||
<PlaceholderPattern />
|
||||
</div> -->
|
||||
</div>
|
||||
<AppLayout>
|
||||
</AppLayout>
|
||||
</template>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
import { ref, onMounted, computed, useTemplateRef, watch } from 'vue'
|
||||
import AppLayout from '@/layouts/AppLayout.vue'
|
||||
import { customers } from '@/routes'
|
||||
import { Address, type BreadcrumbItem } from '@/types'
|
||||
import { Address } from '@/types'
|
||||
import { Head } from '@inertiajs/vue3'
|
||||
import api from '@/axios'
|
||||
import { Customer, Contact } from '@/types'
|
||||
@@ -24,13 +24,6 @@ import { toast } from 'vue-sonner'
|
||||
import { SocialIcon } from '@/components/ui/social-icon'
|
||||
import { AxiosError } from 'axios'
|
||||
|
||||
const breadcrumbs: BreadcrumbItem[] = [
|
||||
{
|
||||
title: 'Kunden',
|
||||
href: customers().url,
|
||||
},
|
||||
]
|
||||
|
||||
const customersData = ref([] as Customer[])
|
||||
const searchQuery = ref('')
|
||||
const searchField = ref()
|
||||
@@ -130,7 +123,7 @@ const call = (number: string, event: Event) => {
|
||||
|
||||
<Head title="Dashboard" />
|
||||
|
||||
<AppLayout :breadcrumbs="breadcrumbs">
|
||||
<AppLayout>
|
||||
<div
|
||||
class="flex h-full flex-1 flex-col gap-4 overflow-x-auto p-4 lg:p-8 print:bg-transparent print:p-0 print:m-0">
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import AppLayout from '@/layouts/AppLayout.vue';
|
||||
import { dashboard } from '@/routes';
|
||||
import { type BreadcrumbItem } from '@/types';
|
||||
import { Head } from '@inertiajs/vue3';
|
||||
import PlaceholderPattern from '../components/PlaceholderPattern.vue';
|
||||
import { usePage } from '@inertiajs/vue3';
|
||||
@@ -17,13 +16,6 @@ import {
|
||||
TableRow,
|
||||
} from '@/components/ui/table';
|
||||
|
||||
|
||||
const breadcrumbs: BreadcrumbItem[] = [
|
||||
{
|
||||
title: 'Dashboard',
|
||||
href: dashboard().url,
|
||||
},
|
||||
];
|
||||
const page = usePage();
|
||||
const token = page.props.flash?.token;
|
||||
|
||||
@@ -37,7 +29,7 @@ if (token) {
|
||||
|
||||
<Head title="Dashboard" />
|
||||
|
||||
<AppLayout :breadcrumbs="breadcrumbs">
|
||||
<AppLayout>
|
||||
<div class="grid gap-12 md:grid-cols-2 h-full p-6 md:p-8">
|
||||
|
||||
<div class="relative overflow-y-auto">
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
import AppLayout from '@/layouts/AppLayout.vue'
|
||||
import { invoices } from '@/routes'
|
||||
import { type Invoice, type BreadcrumbItem, type Customer, type Address } from '@/types'
|
||||
import { type Invoice, type Customer, type Address } from '@/types'
|
||||
import { newInvoice } from '@/types/index.d'
|
||||
import { Head } from '@inertiajs/vue3'
|
||||
import { computed, ref, onMounted, watch } from 'vue'
|
||||
@@ -21,10 +21,6 @@ import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/comp
|
||||
import { Kbd, KbdGroup } from '@/components/ui/kbd'
|
||||
import { statusBadgeLabels } from '@/components/ui/status-badge'
|
||||
|
||||
const breadcrumbs: BreadcrumbItem[] = [{
|
||||
title: 'Rechnungsstellung',
|
||||
href: invoices().url,
|
||||
}]
|
||||
const invoicesData = ref([] as Invoice[])
|
||||
const activeInvoice = ref<Invoice | null>(null)
|
||||
const customersData = ref([] as Customer[])
|
||||
@@ -198,7 +194,7 @@ const deleteInvoice = async (id: number) => {
|
||||
<Head title="Rechnungen" />
|
||||
|
||||
<!-- Function Header -->
|
||||
<AppLayout :breadcrumbs="breadcrumbs">
|
||||
<AppLayout>
|
||||
|
||||
<div
|
||||
class="flex h-full flex-1 flex-col gap-4 overflow-x-auto p-4 lg:p-8 lg:pl-4 print:bg-transparent print:p-0 print:m-0">
|
||||
|
||||
@@ -1,24 +1,13 @@
|
||||
<script setup lang="ts">
|
||||
import { Head } from '@inertiajs/vue3';
|
||||
|
||||
import AppearanceTabs from '@/components/AppearanceTabs.vue';
|
||||
import HeadingSmall from '@/components/HeadingSmall.vue';
|
||||
import { type BreadcrumbItem } from '@/types';
|
||||
|
||||
import AppLayout from '@/layouts/AppLayout.vue';
|
||||
import SettingsLayout from '@/layouts/settings/Layout.vue';
|
||||
import { edit } from '@/routes/appearance';
|
||||
|
||||
const breadcrumbItems: BreadcrumbItem[] = [
|
||||
{
|
||||
title: 'Appearance settings',
|
||||
href: edit().url,
|
||||
},
|
||||
];
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<AppLayout :breadcrumbs="breadcrumbItems">
|
||||
<AppLayout>
|
||||
<Head title="Erscheinungsbild" />
|
||||
|
||||
<SettingsLayout>
|
||||
|
||||
@@ -3,29 +3,19 @@ import PasswordController from '@/actions/App/Http/Controllers/Settings/Password
|
||||
import InputError from '@/components/InputError.vue';
|
||||
import AppLayout from '@/layouts/AppLayout.vue';
|
||||
import SettingsLayout from '@/layouts/settings/Layout.vue';
|
||||
import { edit } from '@/routes/password';
|
||||
import { Form, Head } from '@inertiajs/vue3';
|
||||
import { ref } from 'vue';
|
||||
|
||||
import HeadingSmall from '@/components/HeadingSmall.vue';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Input } from '@/components/ui/input';
|
||||
import { Label } from '@/components/ui/label';
|
||||
import { type BreadcrumbItem } from '@/types';
|
||||
|
||||
const breadcrumbItems: BreadcrumbItem[] = [
|
||||
{
|
||||
title: 'Password settings',
|
||||
href: edit().url,
|
||||
},
|
||||
];
|
||||
|
||||
const passwordInput = ref<HTMLInputElement | null>(null);
|
||||
const currentPasswordInput = ref<HTMLInputElement | null>(null);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<AppLayout :breadcrumbs="breadcrumbItems">
|
||||
<AppLayout>
|
||||
<Head title="Password settings" />
|
||||
|
||||
<SettingsLayout>
|
||||
|
||||
@@ -12,7 +12,6 @@ import { Input } from '@/components/ui/input';
|
||||
import { Label } from '@/components/ui/label';
|
||||
import AppLayout from '@/layouts/AppLayout.vue';
|
||||
import SettingsLayout from '@/layouts/settings/Layout.vue';
|
||||
import { type BreadcrumbItem } from '@/types';
|
||||
|
||||
interface Props {
|
||||
mustVerifyEmail: boolean;
|
||||
@@ -21,19 +20,12 @@ interface Props {
|
||||
|
||||
defineProps<Props>();
|
||||
|
||||
const breadcrumbItems: BreadcrumbItem[] = [
|
||||
{
|
||||
title: 'Profile settings',
|
||||
href: edit().url,
|
||||
},
|
||||
];
|
||||
|
||||
const page = usePage();
|
||||
const user = page.props.auth.user;
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<AppLayout :breadcrumbs="breadcrumbItems">
|
||||
<AppLayout>
|
||||
<Head title="Profile settings" />
|
||||
|
||||
<SettingsLayout>
|
||||
|
||||
@@ -8,7 +8,6 @@ import { useTwoFactorAuth } from '@/composables/useTwoFactorAuth';
|
||||
import AppLayout from '@/layouts/AppLayout.vue';
|
||||
import SettingsLayout from '@/layouts/settings/Layout.vue';
|
||||
import { disable, enable, show } from '@/routes/two-factor';
|
||||
import { BreadcrumbItem } from '@/types';
|
||||
import { Form, Head } from '@inertiajs/vue3';
|
||||
import { ShieldBan, ShieldCheck } from 'lucide-vue-next';
|
||||
import { onUnmounted, ref } from 'vue';
|
||||
@@ -23,13 +22,6 @@ withDefaults(defineProps<Props>(), {
|
||||
twoFactorEnabled: false,
|
||||
});
|
||||
|
||||
const breadcrumbs: BreadcrumbItem[] = [
|
||||
{
|
||||
title: 'Two-Factor Authentication',
|
||||
href: show.url(),
|
||||
},
|
||||
];
|
||||
|
||||
const { hasSetupData, clearTwoFactorAuthData } = useTwoFactorAuth();
|
||||
const showSetupModal = ref<boolean>(false);
|
||||
|
||||
@@ -39,7 +31,7 @@ onUnmounted(() => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<AppLayout :breadcrumbs="breadcrumbs">
|
||||
<AppLayout>
|
||||
<Head title="Two-Factor Authentication" />
|
||||
<SettingsLayout>
|
||||
<div class="space-y-6">
|
||||
|
||||
Vendored
+1
-9
@@ -6,13 +6,6 @@ export interface Auth {
|
||||
user: User;
|
||||
}
|
||||
|
||||
export interface BreadcrumbItem {
|
||||
title: string;
|
||||
href: string;
|
||||
}
|
||||
|
||||
export type BreadcrumbItemType = BreadcrumbItem;
|
||||
|
||||
export interface NavGroup {
|
||||
title: string;
|
||||
items: NavItem[];
|
||||
@@ -26,6 +19,7 @@ export interface NavItem {
|
||||
isActive?: boolean;
|
||||
action?: NavAction
|
||||
}
|
||||
|
||||
export interface NavAction {
|
||||
title: string;
|
||||
href: NonNullable<InertiaLinkProps['href']>;
|
||||
@@ -33,10 +27,8 @@ export interface NavAction {
|
||||
color?: string;
|
||||
}
|
||||
|
||||
|
||||
export type AppPageProps<T extends Record<string, unknown> = Record<string, unknown>> = T & {
|
||||
name: string;
|
||||
quote: { message: string; author: string };
|
||||
auth: Auth;
|
||||
sidebarOpen: boolean;
|
||||
}
|
||||
|
||||
+1
-8
@@ -1,8 +1 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Foundation\Inspiring;
|
||||
use Illuminate\Support\Facades\Artisan;
|
||||
|
||||
Artisan::command('inspire', function () {
|
||||
$this->comment(Inspiring::quote());
|
||||
})->purpose('Display an inspiring quote');
|
||||
<?php
|
||||
Reference in New Issue
Block a user