Dev branch

This commit is contained in:
Simon Pocrnjič
2025-11-02 12:31:01 +01:00
parent 5f879c9436
commit 63e0958b66
241 changed files with 17686 additions and 7327 deletions
+76 -45
View File
@@ -23,6 +23,9 @@ import DropdownLink from "@/Components/DropdownLink.vue";
import GlobalSearch from "@/Layouts/Partials/GlobalSearch.vue";
import NotificationsBell from "@/Layouts/Partials/NotificationsBell.vue";
import ApplicationMark from "@/Components/ApplicationMark.vue";
import Breadcrumbs from "@/Components/Breadcrumbs.vue";
import ToastContainer from "@/Components/Toast/ToastContainer.vue";
import { Button } from "@/Components/ui/button";
const props = defineProps({ title: { type: String, default: "Administrator" } });
@@ -205,47 +208,69 @@ function isActive(patterns) {
<aside
:class="[
sidebarCollapsed ? 'w-16' : 'w-60',
'bg-white border-r border-gray-200 transition-all duration-200 z-50',
'bg-white border-r border-gray-200 transition-all duration-300 ease-in-out z-50',
isMobile
? 'fixed inset-y-0 left-0 transform ' +
? 'fixed inset-y-0 left-0 transform shadow-strong ' +
(mobileSidebarOpen ? 'translate-x-0' : '-translate-x-full')
: 'sticky top-0 h-screen',
: 'sticky top-0 h-screen overflow-y-auto',
]"
>
<div class="h-16 px-4 flex items-center justify-between border-b">
<Link :href="route('dashboard')" class="flex items-center gap-2">
<ApplicationMark class="h-8 w-auto" />
<span v-if="!sidebarCollapsed" class="text-sm font-semibold">Admin</span>
<div class="h-16 px-4 flex items-center justify-between border-b border-gray-200 bg-white">
<Link
:href="route('dashboard')"
class="flex items-center gap-2 hover:opacity-80 transition-opacity"
>
<ApplicationMark />
<span
v-if="!sidebarCollapsed"
class="text-sm font-semibold text-gray-900 transition-opacity"
>
Admin
</span>
</Link>
</div>
<nav class="py-4 overflow-y-auto scrollbar-thin scrollbar-thumb-gray-200">
<div v-for="group in navGroups" :key="group.key" class="mt-2 first:mt-0">
<nav class="py-4 overflow-y-auto">
<div v-for="group in navGroups" :key="group.key" class="mt-2 first:mt-0 px-2">
<p
v-if="!sidebarCollapsed"
class="px-4 mb-1 mt-4 first:mt-0 text-[10px] font-semibold uppercase tracking-wider text-gray-400"
class="px-4 py-1.5 mb-1 mt-4 first:mt-0 text-[11px] font-semibold uppercase tracking-wider text-gray-400"
>
{{ group.label }}
</p>
<ul class="space-y-1">
<ul class="space-y-0.5">
<li v-for="item in group.items" :key="item.key">
<Link
:href="route(item.route)"
:title="item.label"
:class="[
'flex items-center gap-3 px-4 py-2 text-sm hover:bg-gray-100',
isActive(item.active) ? 'bg-gray-100 text-gray-900' : 'text-gray-600',
'flex items-center gap-3 px-3 py-2.5 text-sm rounded-lg transition-all duration-150',
isActive(item.active)
? 'bg-primary-50 text-primary-700 font-medium shadow-sm'
: 'text-gray-600 hover:bg-gray-50 hover:text-gray-900',
]"
>
<FontAwesomeIcon :icon="item.icon" class="w-5 h-5 text-gray-600" />
<span v-if="!sidebarCollapsed">{{ item.label }}</span>
<FontAwesomeIcon
:icon="item.icon"
:class="[
'w-5 h-5 flex-shrink-0 transition-colors',
isActive(item.active) ? 'text-primary-600' : 'text-gray-500',
]"
/>
<span
v-if="!sidebarCollapsed"
class="truncate transition-opacity"
:class="{ 'font-medium': isActive(item.active) }"
>
{{ item.label }}
</span>
</Link>
</li>
</ul>
</div>
<div class="mt-6 border-t pt-4 space-y-2 px-4">
<div class="mt-6 border-t border-gray-200 pt-4 space-y-2 px-4">
<Link
:href="route('dashboard')"
class="text-xs text-gray-500 hover:underline flex items-center gap-1"
class="text-xs text-gray-500 hover:text-gray-700 hover:underline flex items-center gap-2 px-3 py-2 rounded-lg hover:bg-gray-50 transition-colors"
>
<FontAwesomeIcon :icon="faArrowLeft" class="w-3.5 h-3.5" />
<span v-if="!sidebarCollapsed">Nazaj na aplikacijo</span>
@@ -256,18 +281,18 @@ function isActive(patterns) {
<div class="flex-1 flex flex-col min-w-0">
<div
class="h-16 bg-white border-b border-gray-100 px-4 flex items-center justify-between sticky top-0 z-30"
class="h-16 bg-white border-b border-gray-200 px-4 flex items-center justify-between sticky top-0 z-30 backdrop-blur-sm bg-white/95 shadow-sm"
>
<div class="flex items-center gap-2">
<button
<div class="flex items-center gap-3">
<Button
variant="ghost"
size="icon"
@click="toggleSidebar"
class="inline-flex items-center justify-center w-9 h-9 rounded-md text-gray-500 hover:text-gray-700 hover:bg-gray-100"
aria-label="Toggle sidebar"
>
<!-- Replaced raw SVG with FontAwesome icon -->
<FontAwesomeIcon :icon="faBars" class="w-5 h-5" />
</button>
<h1 class="text-base font-semibold text-gray-800 hidden sm:block">
</Button>
<h1 class="text-base font-semibold text-gray-900 hidden sm:block">
{{ title }}
</h1>
</div>
@@ -279,23 +304,25 @@ function isActive(patterns) {
<template #trigger>
<button
v-if="$page.props.jetstream?.managesProfilePhotos"
class="flex text-sm border-2 border-transparent rounded-full focus:outline-none focus:border-gray-300 transition"
class="flex text-sm border-2 border-transparent rounded-full focus:outline-none focus:border-primary-500 focus:ring-2 focus:ring-primary-500 focus:ring-offset-2 transition-all hover:ring-2 hover:ring-gray-200"
>
<img
class="h-8 w-8 rounded-full object-cover"
class="h-8 w-8 rounded-full object-cover ring-2 ring-gray-100"
:src="$page.props.auth.user.profile_photo_url"
:alt="$page.props.auth.user.name"
/>
</button>
<span v-else class="inline-flex rounded-md">
<button
<span v-else class="inline-flex">
<Button
variant="outline"
size="default"
type="button"
class="inline-flex items-center px-3 py-2 border border-transparent text-sm leading-4 font-medium rounded-md text-gray-500 bg-white hover:text-gray-700 focus:outline-none focus:bg-gray-50 active:bg-gray-50 transition ease-in-out duration-150"
class="gap-2"
>
{{ $page.props.auth.user.name }}
<svg
class="ms-2 -me-0.5 h-4 w-4"
class="h-4 w-4"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
@@ -308,7 +335,7 @@ function isActive(patterns) {
d="M19.5 8.25l-7.5 7.5-7.5-7.5"
/>
</svg>
</button>
</Button>
</span>
</template>
@@ -330,25 +357,29 @@ function isActive(patterns) {
</div>
</div>
<main class="p-4">
<div
v-if="$page.props.flash?.success"
class="mb-4 rounded bg-emerald-50 border border-emerald-200 text-emerald-700 px-4 py-2 text-sm"
>
{{ $page.props.flash.success }}
</div>
<div
v-if="$page.props.errors && Object.keys($page.props.errors).length"
class="mb-4 rounded bg-rose-50 border border-rose-200 text-rose-700 px-4 py-2 text-sm"
>
<ul class="list-disc ml-5 space-y-1">
<li v-for="(err, key) in $page.props.errors" :key="key">{{ err }}</li>
</ul>
<!-- Page Heading -->
<header
v-if="$slots.header"
class="bg-white border-b border-gray-200 shadow-sm"
>
<div class="max-w-7xl mx-auto py-4 px-4 sm:px-6 lg:px-8 space-y-2">
<Breadcrumbs
v-if="$page.props.breadcrumbs && $page.props.breadcrumbs.length"
:breadcrumbs="$page.props.breadcrumbs"
/>
<slot name="header" />
</div>
</header>
<main class="flex-1 p-4 sm:p-6">
<slot />
</main>
</div>
<GlobalSearch :open="false" />
<!-- Toast Notification Container -->
<ToastContainer />
</div>
</template>