From b79d93fede7a575c244bb7b4fd493ec1ece98e74 Mon Sep 17 00:00:00 2001 From: Twyco Date: Sat, 19 Sep 2026 01:09:55 +0200 Subject: [PATCH] formatted, added team index, create, show --- app/Http/Controllers/TeamController.php | 34 +- app/Http/Requests/StoreTeamRequest.php | 10 + app/Http/Resources/TeamMemberResource.php | 1 + app/Http/Resources/TeamResource.php | 3 +- components.json | 2 +- composer.json | 5 - package.json | 2 +- phpstan.neon | 13 - resources/css/app.css | 251 +++--- resources/js/app.ts | 32 +- resources/js/components/AlertError.vue | 28 +- resources/js/components/AppContent.vue | 26 +- resources/js/components/AppHeader.vue | 433 +++++---- resources/js/components/AppLogo.vue | 18 +- resources/js/components/AppLogoIcon.vue | 30 +- resources/js/components/AppShell.vue | 16 +- resources/js/components/AppSidebar.vue | 71 +- resources/js/components/AppSidebarHeader.vue | 32 +- resources/js/components/AppearanceTabs.vue | 40 +- resources/js/components/Breadcrumbs.vue | 48 +- resources/js/components/DeleteUser.vue | 179 ++-- resources/js/components/Heading.vue | 36 +- resources/js/components/InputError.vue | 12 +- resources/js/components/ManagePasskeys.vue | 74 +- resources/js/components/ManageTwoFactor.vue | 123 ++- resources/js/components/NavFooter.vue | 60 +- resources/js/components/NavMain.vue | 46 +- resources/js/components/NavUser.vue | 70 +- resources/js/components/PasskeyItem.vue | 142 +-- resources/js/components/PasskeyRegister.vue | 130 +-- resources/js/components/PasskeyVerify.vue | 100 +-- resources/js/components/PasswordInput.vue | 50 +- .../js/components/PlaceholderPattern.vue | 46 +- resources/js/components/TextLink.vue | 26 +- .../js/components/TwoFactorRecoveryCodes.vue | 176 ++-- .../js/components/TwoFactorSetupModal.vue | 459 +++++----- resources/js/components/UserInfo.vue | 32 +- resources/js/components/UserMenuContent.vue | 62 +- resources/js/composables/useAppearance.ts | 147 ++- resources/js/composables/useCurrentUrl.ts | 120 +-- resources/js/composables/useInitials.ts | 28 +- resources/js/composables/useTwoFactorAuth.ts | 168 ++-- resources/js/layouts/AppLayout.vue | 8 +- resources/js/layouts/AuthLayout.vue | 10 +- resources/js/layouts/app/AppHeaderLayout.vue | 18 +- resources/js/layouts/app/AppSidebarLayout.vue | 20 +- resources/js/layouts/auth/AuthCardLayout.vue | 68 +- .../js/layouts/auth/AuthSimpleLayout.vue | 58 +- resources/js/layouts/auth/AuthSplitLayout.vue | 60 +- resources/js/layouts/settings/Layout.vue | 91 +- resources/js/lib/flashToast.ts | 16 +- resources/js/lib/utils.ts | 6 +- resources/js/pages/Dashboard.vue | 66 +- resources/js/pages/Welcome.vue | 837 +++++++++--------- resources/js/pages/auth/ConfirmPassword.vue | 90 +- resources/js/pages/auth/ForgotPassword.vue | 82 +- resources/js/pages/auth/Login.vue | 166 ++-- resources/js/pages/auth/Register.vue | 174 ++-- resources/js/pages/auth/ResetPassword.vue | 128 +-- .../js/pages/auth/TwoFactorChallenge.vue | 202 ++--- resources/js/pages/auth/VerifyEmail.vue | 54 +- resources/js/pages/settings/Appearance.vue | 36 +- resources/js/pages/settings/Profile.vue | 150 ++-- resources/js/pages/settings/Security.vue | 162 ++-- resources/js/pages/team/Create.vue | 63 +- resources/js/pages/team/Edit.vue | 70 +- resources/js/pages/team/Index.vue | 72 +- resources/js/pages/team/Show.vue | 90 ++ resources/js/types/auth.ts | 36 +- resources/js/types/global.d.ts | 42 +- resources/js/types/models.ts | 5 +- resources/js/types/navigation.ts | 12 +- resources/js/types/ui.ts | 4 +- resources/js/types/vue-shims.d.ts | 6 +- routes/web.php | 6 +- vite.config.ts | 147 +-- 76 files changed, 3290 insertions(+), 3146 deletions(-) delete mode 100644 phpstan.neon create mode 100644 resources/js/pages/team/Show.vue diff --git a/app/Http/Controllers/TeamController.php b/app/Http/Controllers/TeamController.php index b713d88..3ee18c6 100644 --- a/app/Http/Controllers/TeamController.php +++ b/app/Http/Controllers/TeamController.php @@ -2,11 +2,13 @@ namespace App\Http\Controllers; +use App\Enums\TeamMemberRole; use App\Http\Requests\StoreTeamRequest; use App\Http\Requests\UpdateTeamRequest; use App\Http\Resources\TeamResource; use App\Models\Team; use Illuminate\Http\Request; +use Illuminate\Support\Facades\DB; use Inertia\Inertia; class TeamController extends Controller @@ -17,13 +19,17 @@ class TeamController extends Controller public function index(Request $request) { return Inertia::render('team/Index', [ - 'teams' => TeamResource::collection(Team::visibleTo($request->user())->get())->resolve($request), + 'teams' => TeamResource::collection(Team::visibleTo(auth()->user())->get())->resolve($request), + 'canCreateTeam' => auth()->user()->can('create', Team::class), ]); } - public function create() + public function show(Request$request, Team $team) { - // + return Inertia::render('team/Show', [ + 'team' => TeamResource::make($team)->resolve($request), + 'canManageTeam' => auth()->user()->can('manage', $team), + ]); } /** @@ -31,9 +37,29 @@ class TeamController extends Controller */ public function store(StoreTeamRequest $request) { - // + $validated = $request->validated(); + + try { + DB::transaction(function () use ($validated) { + $team = Team::create($validated); + $team->members()->attach( + request()->user()->id, + ['role' => TeamMemberRole::Admin] + ); + }); + Inertia::flash('success', 'Team successfully created.'); + return to_route('teams.index'); + } catch (\Exception $exception) { + Inertia::flash('error', 'Team could not be created.'); + DB::rollBack(); + return back(); + } } + public function create() + { + return Inertia::render('team/Create'); + } /** * Show the form for editing the specified resource. diff --git a/app/Http/Requests/StoreTeamRequest.php b/app/Http/Requests/StoreTeamRequest.php index a43e0e8..f4f65b0 100644 --- a/app/Http/Requests/StoreTeamRequest.php +++ b/app/Http/Requests/StoreTeamRequest.php @@ -28,4 +28,14 @@ class StoreTeamRequest extends FormRequest 'slug' => Str::slug($this->name), ]); } + + public function messages(): array + { + return [ + 'slug.string' => '', + 'slug.required' => '', + 'slug.max' => '', + 'slug.unique' => 'The name has already been taken.', + ]; + } } diff --git a/app/Http/Resources/TeamMemberResource.php b/app/Http/Resources/TeamMemberResource.php index 2cae29d..c960e9e 100644 --- a/app/Http/Resources/TeamMemberResource.php +++ b/app/Http/Resources/TeamMemberResource.php @@ -18,6 +18,7 @@ class TeamMemberResource extends JsonResource 'email' => $this->email, 'has_multi_factor' => $this->hasVerifiedEmail() || $this->hasEnabledTwoFactorAuthentication(), 'role' => $this->pivot->role, + 'joined_at' => $this->pivot->created_at->toDateTimeString(), ]; } } diff --git a/app/Http/Resources/TeamResource.php b/app/Http/Resources/TeamResource.php index 4462d2c..50845e4 100644 --- a/app/Http/Resources/TeamResource.php +++ b/app/Http/Resources/TeamResource.php @@ -21,8 +21,9 @@ class TeamResource extends JsonResource return [ 'name' => $this->name, 'slug' => $this->slug, - 'members' => TeamMemberResource::collection($this->members), + 'members' => TeamMemberResource::collection($this->members)->resolve($request), 'multi_factor_required' => $this->require_2fa, + 'created_at' => $this->created_at->toDateTimeString(), ]; } } diff --git a/components.json b/components.json index 88dfd1d..a6cbe6f 100644 --- a/components.json +++ b/components.json @@ -1,6 +1,6 @@ { "$schema": "https://shadcn-vue.com/schema.json", - "style": "new-york-v4", + "style": "new-york", "tailwind": { "config": "tailwind.config.js", "css": "resources/css/app.css", diff --git a/composer.json b/composer.json index 947a07c..cb04086 100644 --- a/composer.json +++ b/composer.json @@ -20,7 +20,6 @@ "require-dev": { "barryvdh/laravel-ide-helper": "^3.7", "fakerphp/faker": "^1.24", - "larastan/larastan": "^3.9", "laravel/boost": "^2.2", "laravel/pail": "^1.2.5", "laravel/pao": "^1.0.6", @@ -69,13 +68,9 @@ "pnpm run types:check", "@test" ], - "types:check": [ - "phpstan analyse --memory-limit=512M" - ], "test": [ "@php artisan config:clear --ansi", "@lint:check", - "@types:check", "@php artisan test" ], "post-autoload-dump": [ diff --git a/package.json b/package.json index b8115ba..0fc5381 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "build:ssr": "vp build && vp build --ssr", "dev": "vp dev", "check": "vp check", - "check:fix": "vp check --fix", + "format": "vp check --fix", "types:check": "vue-tsc --noEmit" }, "dependencies": { diff --git a/phpstan.neon b/phpstan.neon deleted file mode 100644 index 1ca23a4..0000000 --- a/phpstan.neon +++ /dev/null @@ -1,13 +0,0 @@ -includes: - - vendor/larastan/larastan/extension.neon - - vendor/nesbot/carbon/extension.neon - -parameters: - paths: - - app/ - - bootstrap/app.php - - config/ - - database/ - - routes/ - - level: 7 diff --git a/resources/css/app.css b/resources/css/app.css index 6f9d1f5..058669d 100644 --- a/resources/css/app.css +++ b/resources/css/app.css @@ -8,57 +8,56 @@ @custom-variant dark (&:is(.dark *)); @theme inline { - --font-sans: - Instrument Sans, ui-sans-serif, system-ui, sans-serif, - 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', - 'Noto Color Emoji'; + --font-sans: + Instrument Sans, ui-sans-serif, system-ui, sans-serif, 'Apple Color Emoji', + 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'; - --radius-lg: var(--radius); - --radius-md: calc(var(--radius) - 2px); - --radius-sm: calc(var(--radius) - 4px); + --radius-lg: var(--radius); + --radius-md: calc(var(--radius) - 2px); + --radius-sm: calc(var(--radius) - 4px); - --color-background: var(--background); - --color-foreground: var(--foreground); + --color-background: var(--background); + --color-foreground: var(--foreground); - --color-card: var(--card); - --color-card-foreground: var(--card-foreground); + --color-card: var(--card); + --color-card-foreground: var(--card-foreground); - --color-popover: var(--popover); - --color-popover-foreground: var(--popover-foreground); + --color-popover: var(--popover); + --color-popover-foreground: var(--popover-foreground); - --color-primary: var(--primary); - --color-primary-foreground: var(--primary-foreground); + --color-primary: var(--primary); + --color-primary-foreground: var(--primary-foreground); - --color-secondary: var(--secondary); - --color-secondary-foreground: var(--secondary-foreground); + --color-secondary: var(--secondary); + --color-secondary-foreground: var(--secondary-foreground); - --color-muted: var(--muted); - --color-muted-foreground: var(--muted-foreground); + --color-muted: var(--muted); + --color-muted-foreground: var(--muted-foreground); - --color-accent: var(--accent); - --color-accent-foreground: var(--accent-foreground); + --color-accent: var(--accent); + --color-accent-foreground: var(--accent-foreground); - --color-destructive: var(--destructive); - --color-destructive-foreground: var(--destructive-foreground); + --color-destructive: var(--destructive); + --color-destructive-foreground: var(--destructive-foreground); - --color-border: var(--border); - --color-input: var(--input); - --color-ring: var(--ring); + --color-border: var(--border); + --color-input: var(--input); + --color-ring: var(--ring); - --color-chart-1: var(--chart-1); - --color-chart-2: var(--chart-2); - --color-chart-3: var(--chart-3); - --color-chart-4: var(--chart-4); - --color-chart-5: var(--chart-5); + --color-chart-1: var(--chart-1); + --color-chart-2: var(--chart-2); + --color-chart-3: var(--chart-3); + --color-chart-4: var(--chart-4); + --color-chart-5: var(--chart-5); - --color-sidebar: var(--sidebar-background); - --color-sidebar-foreground: var(--sidebar-foreground); - --color-sidebar-primary: var(--sidebar-primary); - --color-sidebar-primary-foreground: var(--sidebar-primary-foreground); - --color-sidebar-accent: var(--sidebar-accent); - --color-sidebar-accent-foreground: var(--sidebar-accent-foreground); - --color-sidebar-border: var(--sidebar-border); - --color-sidebar-ring: var(--sidebar-ring); + --color-sidebar: var(--sidebar-background); + --color-sidebar-foreground: var(--sidebar-foreground); + --color-sidebar-primary: var(--sidebar-primary); + --color-sidebar-primary-foreground: var(--sidebar-primary-foreground); + --color-sidebar-accent: var(--sidebar-accent); + --color-sidebar-accent-foreground: var(--sidebar-accent-foreground); + --color-sidebar-border: var(--sidebar-border); + --color-sidebar-ring: var(--sidebar-ring); } /* @@ -70,103 +69,103 @@ color utility to any element that depends on these defaults. */ @layer base { - *, - ::after, - ::before, - ::backdrop, - ::file-selector-button { - border-color: var(--color-gray-200, currentColor); - } + *, + ::after, + ::before, + ::backdrop, + ::file-selector-button { + border-color: var(--color-gray-200, currentColor); + } } @layer utilities { - body, - html { - --font-sans: - 'Instrument Sans', ui-sans-serif, system-ui, sans-serif, - 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', - 'Noto Color Emoji'; - } + body, + html { + --font-sans: + 'Instrument Sans', ui-sans-serif, system-ui, sans-serif, + 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', + 'Noto Color Emoji'; + } } :root { - --background: hsl(0 0% 100%); - --foreground: hsl(0 0% 3.9%); - --card: hsl(0 0% 100%); - --card-foreground: hsl(0 0% 3.9%); - --popover: hsl(0 0% 100%); - --popover-foreground: hsl(0 0% 3.9%); - --primary: hsl(0 0% 9%); - --primary-foreground: hsl(0 0% 98%); - --secondary: hsl(0 0% 92.1%); - --secondary-foreground: hsl(0 0% 9%); - --muted: hsl(0 0% 96.1%); - --muted-foreground: hsl(0 0% 45.1%); - --accent: hsl(0 0% 96.1%); - --accent-foreground: hsl(0 0% 9%); - --destructive: hsl(0 84.2% 60.2%); - --destructive-foreground: hsl(0 0% 98%); - --border: hsl(0 0% 92.8%); - --input: hsl(0 0% 89.8%); - --ring: hsl(0 0% 3.9%); - --chart-1: hsl(12 76% 61%); - --chart-2: hsl(173 58% 39%); - --chart-3: hsl(197 37% 24%); - --chart-4: hsl(43 74% 66%); - --chart-5: hsl(27 87% 67%); - --radius: 0.5rem; - --sidebar-background: hsl(0 0% 98%); - --sidebar-foreground: hsl(240 5.3% 26.1%); - --sidebar-primary: hsl(0 0% 10%); - --sidebar-primary-foreground: hsl(0 0% 98%); - --sidebar-accent: hsl(0 0% 94%); - --sidebar-accent-foreground: hsl(0 0% 30%); - --sidebar-border: hsl(0 0% 91%); - --sidebar-ring: hsl(217.2 91.2% 59.8%); - --sidebar: hsl(0 0% 98%); + --background: hsl(0 0% 100%); + --foreground: hsl(0 0% 3.9%); + --card: hsl(0 0% 100%); + --card-foreground: hsl(0 0% 3.9%); + --popover: hsl(0 0% 100%); + --popover-foreground: hsl(0 0% 3.9%); + --primary: hsl(0 0% 9%); + --primary-foreground: hsl(0 0% 98%); + --secondary: hsl(0 0% 92.1%); + --secondary-foreground: hsl(0 0% 9%); + --muted: hsl(0 0% 96.1%); + --muted-foreground: hsl(0 0% 45.1%); + --accent: hsl(0 0% 96.1%); + --accent-foreground: hsl(0 0% 9%); + --destructive: hsl(0 84.2% 60.2%); + --destructive-foreground: hsl(0 0% 98%); + --border: hsl(0 0% 92.8%); + --input: hsl(0 0% 89.8%); + --ring: hsl(0 0% 3.9%); + --chart-1: hsl(12 76% 61%); + --chart-2: hsl(173 58% 39%); + --chart-3: hsl(197 37% 24%); + --chart-4: hsl(43 74% 66%); + --chart-5: hsl(27 87% 67%); + --radius: 0.5rem; + --sidebar-background: hsl(0 0% 98%); + --sidebar-foreground: hsl(240 5.3% 26.1%); + --sidebar-primary: hsl(0 0% 10%); + --sidebar-primary-foreground: hsl(0 0% 98%); + --sidebar-accent: hsl(0 0% 94%); + --sidebar-accent-foreground: hsl(0 0% 30%); + --sidebar-border: hsl(0 0% 91%); + --sidebar-ring: hsl(217.2 91.2% 59.8%); + --sidebar: hsl(0 0% 98%); } .dark { - --background: hsl(0 0% 3.9%); - --foreground: hsl(0 0% 98%); - --card: hsl(0 0% 3.9%); - --card-foreground: hsl(0 0% 98%); - --popover: hsl(0 0% 3.9%); - --popover-foreground: hsl(0 0% 98%); - --primary: hsl(0 0% 98%); - --primary-foreground: hsl(0 0% 9%); - --secondary: hsl(0 0% 14.9%); - --secondary-foreground: hsl(0 0% 98%); - --muted: hsl(0 0% 16.08%); - --muted-foreground: hsl(0 0% 63.9%); - --accent: hsl(0 0% 14.9%); - --accent-foreground: hsl(0 0% 98%); - --destructive: hsl(0 84% 60%); - --destructive-foreground: hsl(0 0% 98%); - --border: hsl(0 0% 14.9%); - --input: hsl(0 0% 14.9%); - --ring: hsl(0 0% 83.1%); - --chart-1: hsl(220 70% 50%); - --chart-2: hsl(160 60% 45%); - --chart-3: hsl(30 80% 55%); - --chart-4: hsl(280 65% 60%); - --chart-5: hsl(340 75% 55%); - --sidebar-background: hsl(0 0% 7%); - --sidebar-foreground: hsl(0 0% 95.9%); - --sidebar-primary: hsl(360, 100%, 100%); - --sidebar-primary-foreground: hsl(0 0% 100%); - --sidebar-accent: hsl(0 0% 15.9%); - --sidebar-accent-foreground: hsl(240 4.8% 95.9%); - --sidebar-border: hsl(0 0% 15.9%); - --sidebar-ring: hsl(217.2 91.2% 59.8%); - --sidebar: hsl(240 5.9% 10%); + --background: hsl(0 0% 3.9%); + --foreground: hsl(0 0% 98%); + --card: hsl(0 0% 3.9%); + --card-foreground: hsl(0 0% 98%); + --popover: hsl(0 0% 3.9%); + --popover-foreground: hsl(0 0% 98%); + --primary: hsl(0 0% 98%); + --primary-foreground: hsl(0 0% 9%); + --secondary: hsl(0 0% 14.9%); + --secondary-foreground: hsl(0 0% 98%); + --muted: hsl(0 0% 16.08%); + --muted-foreground: hsl(0 0% 63.9%); + --accent: hsl(0 0% 14.9%); + --accent-foreground: hsl(0 0% 98%); + --destructive: hsl(0 84% 60%); + --destructive-foreground: hsl(0 0% 98%); + --border: hsl(0 0% 14.9%); + --input: hsl(0 0% 14.9%); + --ring: hsl(0 0% 83.1%); + --chart-1: hsl(220 70% 50%); + --chart-2: hsl(160 60% 45%); + --chart-3: hsl(30 80% 55%); + --chart-4: hsl(280 65% 60%); + --chart-5: hsl(340 75% 55%); + --sidebar-background: hsl(0 0% 7%); + --sidebar-foreground: hsl(0 0% 95.9%); + --sidebar-primary: hsl(360, 100%, 100%); + --sidebar-primary-foreground: hsl(0 0% 100%); + --sidebar-accent: hsl(0 0% 15.9%); + --sidebar-accent-foreground: hsl(240 4.8% 95.9%); + --sidebar-border: hsl(0 0% 15.9%); + --sidebar-ring: hsl(217.2 91.2% 59.8%); + --sidebar: hsl(240 5.9% 10%); } @layer base { - * { - @apply border-border outline-ring/50; - } - body { - @apply bg-background text-foreground; - } + * { + @apply border-border outline-ring/50; + } + body { + @apply bg-background text-foreground; + } } diff --git a/resources/js/app.ts b/resources/js/app.ts index 5872d1e..786e3c1 100644 --- a/resources/js/app.ts +++ b/resources/js/app.ts @@ -8,22 +8,22 @@ import { initializeFlashToast } from '@/lib/flashToast'; const appName = import.meta.env.VITE_APP_NAME || 'Laravel'; void createInertiaApp({ - title: (title) => (title ? `${title} - ${appName}` : appName), - layout: (name) => { - switch (true) { - case name === 'Welcome': - return null; - case name.startsWith('auth/'): - return AuthLayout; - case name.startsWith('settings/'): - return [AppLayout, SettingsLayout]; - default: - return AppLayout; - } - }, - progress: { - color: '#4B5563', - }, + title: (title) => (title ? `${title} - ${appName}` : appName), + layout: (name) => { + switch (true) { + case name === 'Welcome': + return null; + case name.startsWith('auth/'): + return AuthLayout; + case name.startsWith('settings/'): + return [AppLayout, SettingsLayout]; + default: + return AppLayout; + } + }, + progress: { + color: '#4B5563', + }, }); // This will set light / dark mode on page load... diff --git a/resources/js/components/AlertError.vue b/resources/js/components/AlertError.vue index b2de005..8ffd794 100644 --- a/resources/js/components/AlertError.vue +++ b/resources/js/components/AlertError.vue @@ -4,27 +4,27 @@ import { computed } from 'vue'; import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert'; type Props = { - errors: string[]; - title?: string; + errors: string[]; + title?: string; }; const props = withDefaults(defineProps(), { - title: 'Something went wrong.', + title: 'Something went wrong.', }); const uniqueErrors = computed(() => Array.from(new Set(props.errors))); diff --git a/resources/js/components/AppContent.vue b/resources/js/components/AppContent.vue index 555a1a6..666b56e 100644 --- a/resources/js/components/AppContent.vue +++ b/resources/js/components/AppContent.vue @@ -4,25 +4,25 @@ import { SidebarInset } from '@/components/ui/sidebar'; import type { AppVariant } from '@/types'; type Props = { - variant?: AppVariant; - class?: string; + variant?: AppVariant; + class?: string; }; const props = withDefaults(defineProps(), { - variant: 'sidebar', + variant: 'sidebar', }); const className = computed(() => props.class); diff --git a/resources/js/components/AppHeader.vue b/resources/js/components/AppHeader.vue index d58773b..15f257e 100644 --- a/resources/js/components/AppHeader.vue +++ b/resources/js/components/AppHeader.vue @@ -8,28 +8,28 @@ import Breadcrumbs from '@/components/Breadcrumbs.vue'; import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar'; import { Button } from '@/components/ui/button'; import { - DropdownMenu, - DropdownMenuContent, - DropdownMenuTrigger, + DropdownMenu, + DropdownMenuContent, + DropdownMenuTrigger, } from '@/components/ui/dropdown-menu'; import { - NavigationMenu, - NavigationMenuItem, - NavigationMenuList, - navigationMenuTriggerStyle, + NavigationMenu, + NavigationMenuItem, + NavigationMenuList, + navigationMenuTriggerStyle, } from '@/components/ui/navigation-menu'; import { - Sheet, - SheetContent, - SheetHeader, - SheetTitle, - SheetTrigger, + Sheet, + SheetContent, + SheetHeader, + SheetTitle, + SheetTrigger, } from '@/components/ui/sheet'; import { - Tooltip, - TooltipContent, - TooltipProvider, - TooltipTrigger, + Tooltip, + TooltipContent, + TooltipProvider, + TooltipTrigger, } from '@/components/ui/tooltip'; import UserMenuContent from '@/components/UserMenuContent.vue'; import { useCurrentUrl } from '@/composables/useCurrentUrl'; @@ -39,11 +39,11 @@ import { dashboard } from '@/routes'; import type { BreadcrumbItem, NavItem } from '@/types'; type Props = { - breadcrumbs?: BreadcrumbItem[]; + breadcrumbs?: BreadcrumbItem[]; }; const props = withDefaults(defineProps(), { - breadcrumbs: () => [], + breadcrumbs: () => [], }); const page = usePage(); @@ -51,233 +51,208 @@ const auth = computed(() => page.props.auth); const { isCurrentUrl, whenCurrentUrl } = useCurrentUrl(); const activeItemStyles = - 'text-neutral-900 dark:bg-neutral-800 dark:text-neutral-100'; + 'text-neutral-900 dark:bg-neutral-800 dark:text-neutral-100'; const mainNavItems: NavItem[] = [ - { - title: 'Dashboard', - href: dashboard(), - icon: LayoutGrid, - }, + { + title: 'Dashboard', + href: dashboard(), + icon: LayoutGrid, + }, ]; 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, - }, + { + title: 'Repository', + href: 'https://github.com/laravel/vue-starter-kit', + icon: Folder, + }, + { + title: 'Documentation', + href: 'https://laravel.com/docs/starter-kits#vue', + icon: BookOpen, + }, ]; diff --git a/resources/js/components/AppLogo.vue b/resources/js/components/AppLogo.vue index a64288f..ebf39f6 100644 --- a/resources/js/components/AppLogo.vue +++ b/resources/js/components/AppLogo.vue @@ -6,14 +6,12 @@ const name = usePage().props.name; diff --git a/resources/js/components/AppLogoIcon.vue b/resources/js/components/AppLogoIcon.vue index 9a26231..5da547d 100644 --- a/resources/js/components/AppLogoIcon.vue +++ b/resources/js/components/AppLogoIcon.vue @@ -2,28 +2,28 @@ import type { HTMLAttributes } from 'vue'; defineOptions({ - inheritAttrs: false, + inheritAttrs: false, }); type Props = { - className?: HTMLAttributes['class']; + className?: HTMLAttributes['class']; }; defineProps(); diff --git a/resources/js/components/AppShell.vue b/resources/js/components/AppShell.vue index e76af0b..3057c62 100644 --- a/resources/js/components/AppShell.vue +++ b/resources/js/components/AppShell.vue @@ -4,21 +4,21 @@ import { SidebarProvider } from '@/components/ui/sidebar'; import type { AppVariant } from '@/types'; type Props = { - variant?: AppVariant; + variant?: AppVariant; }; withDefaults(defineProps(), { - variant: 'sidebar', + variant: 'sidebar', }); const isOpen = usePage().props.sidebarOpen; diff --git a/resources/js/components/AppSidebar.vue b/resources/js/components/AppSidebar.vue index a5e29a8..09391d5 100644 --- a/resources/js/components/AppSidebar.vue +++ b/resources/js/components/AppSidebar.vue @@ -6,52 +6,51 @@ import NavFooter from '@/components/NavFooter.vue'; import NavMain from '@/components/NavMain.vue'; import NavUser from '@/components/NavUser.vue'; import { - Sidebar, - SidebarContent, - SidebarFooter, - SidebarHeader, - SidebarMenu, - SidebarMenuButton, - SidebarMenuItem, + Sidebar, + SidebarContent, + SidebarFooter, + SidebarHeader, + SidebarMenu, + SidebarMenuButton, + SidebarMenuItem, } from '@/components/ui/sidebar'; import { dashboard } from '@/routes'; import type { NavItem } from '@/types'; -import teams from "@/routes/teams"; +import teams from '@/routes/teams'; const mainNavItems: NavItem[] = [ - { - title: 'Meine Teams', - href: teams.index(), - icon: UserGroup, - }, + { + title: 'Meine Teams', + href: teams.index(), + icon: UserGroup, + }, ]; -const footerNavItems: NavItem[] = [ -]; +const footerNavItems: NavItem[] = []; diff --git a/resources/js/components/AppSidebarHeader.vue b/resources/js/components/AppSidebarHeader.vue index 2559c59..7160f87 100644 --- a/resources/js/components/AppSidebarHeader.vue +++ b/resources/js/components/AppSidebarHeader.vue @@ -4,24 +4,24 @@ import { SidebarTrigger } from '@/components/ui/sidebar'; import type { BreadcrumbItem } from '@/types'; withDefaults( - defineProps<{ - breadcrumbs?: BreadcrumbItem[]; - }>(), - { - breadcrumbs: () => [], - }, + defineProps<{ + breadcrumbs?: BreadcrumbItem[]; + }>(), + { + breadcrumbs: () => [], + }, ); diff --git a/resources/js/components/AppearanceTabs.vue b/resources/js/components/AppearanceTabs.vue index 1b0f9ef..1597db9 100644 --- a/resources/js/components/AppearanceTabs.vue +++ b/resources/js/components/AppearanceTabs.vue @@ -5,29 +5,29 @@ import { useAppearance } from '@/composables/useAppearance'; const { appearance, updateAppearance } = useAppearance(); const tabs = [ - { value: 'light', Icon: Sun, label: 'Light' }, - { value: 'dark', Icon: Moon, label: 'Dark' }, - { value: 'system', Icon: Monitor, label: 'System' }, + { value: 'light', Icon: Sun, label: 'Light' }, + { value: 'dark', Icon: Moon, label: 'Dark' }, + { value: 'system', Icon: Monitor, label: 'System' }, ] as const; diff --git a/resources/js/components/Breadcrumbs.vue b/resources/js/components/Breadcrumbs.vue index 0f96ff4..da67655 100644 --- a/resources/js/components/Breadcrumbs.vue +++ b/resources/js/components/Breadcrumbs.vue @@ -1,38 +1,38 @@ diff --git a/resources/js/components/DeleteUser.vue b/resources/js/components/DeleteUser.vue index 871fb5e..6214157 100644 --- a/resources/js/components/DeleteUser.vue +++ b/resources/js/components/DeleteUser.vue @@ -7,14 +7,14 @@ import InputError from '@/components/InputError.vue'; import PasswordInput from '@/components/PasswordInput.vue'; import { Button } from '@/components/ui/button'; import { - Dialog, - DialogClose, - DialogContent, - DialogDescription, - DialogFooter, - DialogHeader, - DialogTitle, - DialogTrigger, + Dialog, + DialogClose, + DialogContent, + DialogDescription, + DialogFooter, + DialogHeader, + DialogTitle, + DialogTrigger, } from '@/components/ui/dialog'; import { Label } from '@/components/ui/label'; @@ -22,92 +22,87 @@ const passwordInput = useTemplateRef('passwordInput'); diff --git a/resources/js/components/Heading.vue b/resources/js/components/Heading.vue index 10da049..eba9c62 100644 --- a/resources/js/components/Heading.vue +++ b/resources/js/components/Heading.vue @@ -1,28 +1,28 @@ diff --git a/resources/js/components/InputError.vue b/resources/js/components/InputError.vue index 3db9519..bdb98ac 100644 --- a/resources/js/components/InputError.vue +++ b/resources/js/components/InputError.vue @@ -1,13 +1,13 @@ diff --git a/resources/js/components/ManagePasskeys.vue b/resources/js/components/ManagePasskeys.vue index 90aa1a5..53a9f2b 100644 --- a/resources/js/components/ManagePasskeys.vue +++ b/resources/js/components/ManagePasskeys.vue @@ -8,58 +8,58 @@ import PasskeyRegister from '@/components/PasskeyRegister.vue'; import { destroy } from '@/actions/Laravel/Passkeys/Http/Controllers/PasskeyRegistrationController'; export type Props = { - canManagePasskeys?: boolean; - passkeys?: Passkey[]; + canManagePasskeys?: boolean; + passkeys?: Passkey[]; }; withDefaults(defineProps(), { - canManagePasskeys: false, - passkeys: () => [], + canManagePasskeys: false, + passkeys: () => [], }); const handleDelete = (id: number, onError: () => void) => { - router.delete(destroy.url(id), { - preserveScroll: true, - onError, - }); + router.delete(destroy.url(id), { + preserveScroll: true, + onError, + }); }; const handleRegisterSuccess = () => { - router.reload(); + router.reload(); }; diff --git a/resources/js/components/ManageTwoFactor.vue b/resources/js/components/ManageTwoFactor.vue index 9451007..e4a215c 100644 --- a/resources/js/components/ManageTwoFactor.vue +++ b/resources/js/components/ManageTwoFactor.vue @@ -10,15 +10,15 @@ import { useTwoFactorAuth } from '@/composables/useTwoFactorAuth'; import { disable, enable } from '@/routes/two-factor'; export type Props = { - canManageTwoFactor?: boolean; - requiresConfirmation?: boolean; - twoFactorEnabled?: boolean; + canManageTwoFactor?: boolean; + requiresConfirmation?: boolean; + twoFactorEnabled?: boolean; }; withDefaults(defineProps(), { - canManageTwoFactor: false, - requiresConfirmation: false, - twoFactorEnabled: false, + canManageTwoFactor: false, + requiresConfirmation: false, + twoFactorEnabled: false, }); const { hasSetupData, clearTwoFactorAuthData } = useTwoFactorAuth(); @@ -28,66 +28,59 @@ onUnmounted(() => clearTwoFactorAuthData()); diff --git a/resources/js/components/NavFooter.vue b/resources/js/components/NavFooter.vue index 4827492..bf07f99 100644 --- a/resources/js/components/NavFooter.vue +++ b/resources/js/components/NavFooter.vue @@ -1,44 +1,44 @@ diff --git a/resources/js/components/NavMain.vue b/resources/js/components/NavMain.vue index cf2a635..609592f 100644 --- a/resources/js/components/NavMain.vue +++ b/resources/js/components/NavMain.vue @@ -1,38 +1,38 @@ diff --git a/resources/js/components/NavUser.vue b/resources/js/components/NavUser.vue index 6ab6723..b74c4cf 100644 --- a/resources/js/components/NavUser.vue +++ b/resources/js/components/NavUser.vue @@ -3,15 +3,15 @@ import { usePage } from '@inertiajs/vue3'; import { ChevronsUpDown } from '@lucide/vue'; import { computed } from 'vue'; import { - DropdownMenu, - DropdownMenuContent, - DropdownMenuTrigger, + DropdownMenu, + DropdownMenuContent, + DropdownMenuTrigger, } from '@/components/ui/dropdown-menu'; import { - SidebarMenu, - SidebarMenuButton, - SidebarMenuItem, - useSidebar, + SidebarMenu, + SidebarMenuButton, + SidebarMenuItem, + useSidebar, } from '@/components/ui/sidebar'; import UserInfo from '@/components/UserInfo.vue'; import UserMenuContent from '@/components/UserMenuContent.vue'; @@ -22,34 +22,30 @@ const { isMobile, state } = useSidebar(); diff --git a/resources/js/components/PasskeyItem.vue b/resources/js/components/PasskeyItem.vue index 4ba94d9..fc95d6f 100644 --- a/resources/js/components/PasskeyItem.vue +++ b/resources/js/components/PasskeyItem.vue @@ -3,93 +3,93 @@ import { KeyRound, Trash2 } from '@lucide/vue'; import { ref } from 'vue'; import { Button } from '@/components/ui/button'; import { - Dialog, - DialogClose, - DialogContent, - DialogDescription, - DialogFooter, - DialogTitle, - DialogTrigger, + Dialog, + DialogClose, + DialogContent, + DialogDescription, + DialogFooter, + DialogTitle, + DialogTrigger, } from '@/components/ui/dialog'; import type { Passkey } from '@/types/auth'; const props = defineProps<{ - passkey: Passkey; + passkey: Passkey; }>(); const emit = defineEmits<{ - remove: [id: number, onError: () => void]; + remove: [id: number, onError: () => void]; }>(); const isDeleting = ref(false); const handleDelete = () => { - isDeleting.value = true; - emit('remove', props.passkey.id, () => { - isDeleting.value = false; - }); + isDeleting.value = true; + emit('remove', props.passkey.id, () => { + isDeleting.value = false; + }); }; diff --git a/resources/js/components/PasskeyRegister.vue b/resources/js/components/PasskeyRegister.vue index a897ddb..d52e4ca 100644 --- a/resources/js/components/PasskeyRegister.vue +++ b/resources/js/components/PasskeyRegister.vue @@ -7,96 +7,96 @@ import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; const emit = defineEmits<{ - success: []; + success: []; }>(); const getDefaultPasskeyName = () => { - const ua = navigator.userAgent; + const ua = navigator.userAgent; - const browser = [ - { pattern: /Edg|Edge/, name: 'Edge' }, - { pattern: /OPR|Opera|OPiOS/, name: 'Opera' }, - { pattern: /Firefox|FxiOS/, name: 'Firefox' }, - { pattern: /Chrome|CriOS/, name: 'Chrome' }, - { pattern: /Safari/, name: 'Safari' }, - ].find(({ pattern }) => pattern.test(ua))?.name; + const browser = [ + { pattern: /Edg|Edge/, name: 'Edge' }, + { pattern: /OPR|Opera|OPiOS/, name: 'Opera' }, + { pattern: /Firefox|FxiOS/, name: 'Firefox' }, + { pattern: /Chrome|CriOS/, name: 'Chrome' }, + { pattern: /Safari/, name: 'Safari' }, + ].find(({ pattern }) => pattern.test(ua))?.name; - const os = [ - { pattern: /iPhone/, name: 'iPhone' }, - { pattern: /iPad|Macintosh(?=.*Mobile)/, name: 'iPad' }, - { pattern: /Android/, name: 'Android' }, - { pattern: /Mac/, name: 'Mac' }, - { pattern: /Windows/, name: 'Windows' }, - ].find(({ pattern }) => pattern.test(ua))?.name; + const os = [ + { pattern: /iPhone/, name: 'iPhone' }, + { pattern: /iPad|Macintosh(?=.*Mobile)/, name: 'iPad' }, + { pattern: /Android/, name: 'Android' }, + { pattern: /Mac/, name: 'Mac' }, + { pattern: /Windows/, name: 'Windows' }, + ].find(({ pattern }) => pattern.test(ua))?.name; - return [browser, os].filter(Boolean).join(' on ') || ''; + return [browser, os].filter(Boolean).join(' on ') || ''; }; const name = ref(getDefaultPasskeyName()); const showForm = ref(false); const { register, isLoading, error, isSupported } = usePasskeyRegister({ - onSuccess: () => { - name.value = ''; - showForm.value = false; - emit('success'); - }, + onSuccess: () => { + name.value = ''; + showForm.value = false; + emit('success'); + }, }); const handleSubmit = async (event: Event) => { - event.preventDefault(); + event.preventDefault(); - if (!name.value.trim()) { - return; - } + if (!name.value.trim()) { + return; + } - await register(name.value); + await register(name.value); }; const handleCancel = () => { - showForm.value = false; - name.value = ''; + showForm.value = false; + name.value = ''; }; diff --git a/resources/js/components/PasskeyVerify.vue b/resources/js/components/PasskeyVerify.vue index 4bf565e..9aa25a1 100644 --- a/resources/js/components/PasskeyVerify.vue +++ b/resources/js/components/PasskeyVerify.vue @@ -9,65 +9,65 @@ import { Separator } from '@/components/ui/separator'; import { Spinner } from '@/components/ui/spinner'; type Props = { - routes?: { - options: UrlMethodPair; - submit: UrlMethodPair; - }; - label?: string; - loadingLabel?: string; - separator?: string; + routes?: { + options: UrlMethodPair; + submit: UrlMethodPair; + }; + label?: string; + loadingLabel?: string; + separator?: string; }; const props = defineProps(); const { verify, isLoading, error, isSupported } = usePasskeyVerify({ - ...(props.routes - ? { - routes: { - options: props.routes.options.url, - submit: props.routes.submit.url, - }, - } - : {}), - onSuccess: (response) => { - router.visit(response.redirect ?? '/dashboard'); - }, + ...(props.routes + ? { + routes: { + options: props.routes.options.url, + submit: props.routes.submit.url, + }, + } + : {}), + onSuccess: (response) => { + router.visit(response.redirect ?? '/dashboard'); + }, }); diff --git a/resources/js/components/PasswordInput.vue b/resources/js/components/PasswordInput.vue index d7d5a09..2b2fd3a 100644 --- a/resources/js/components/PasswordInput.vue +++ b/resources/js/components/PasswordInput.vue @@ -8,39 +8,39 @@ import { cn } from '@/lib/utils'; defineOptions({ inheritAttrs: false }); const props = defineProps<{ - class?: HTMLAttributes['class']; + class?: HTMLAttributes['class']; }>(); const showPassword = ref(false); const inputRef = useTemplateRef('inputRef'); defineExpose({ - $el: inputRef, - focus: () => inputRef.value?.$el?.focus(), + $el: inputRef, + focus: () => inputRef.value?.$el?.focus(), }); diff --git a/resources/js/components/PlaceholderPattern.vue b/resources/js/components/PlaceholderPattern.vue index 19ea375..15ede81 100644 --- a/resources/js/components/PlaceholderPattern.vue +++ b/resources/js/components/PlaceholderPattern.vue @@ -5,27 +5,27 @@ const patternId = `pattern-${useId()}`; diff --git a/resources/js/components/TextLink.vue b/resources/js/components/TextLink.vue index 06fdfcb..4fb3148 100644 --- a/resources/js/components/TextLink.vue +++ b/resources/js/components/TextLink.vue @@ -3,23 +3,23 @@ import type { LinkComponentBaseProps, Method } from '@inertiajs/core'; import { Link } from '@inertiajs/vue3'; type Props = { - href: LinkComponentBaseProps['href']; - tabindex?: number; - method?: Method; - as?: string; + href: LinkComponentBaseProps['href']; + tabindex?: number; + method?: Method; + as?: string; }; defineProps(); diff --git a/resources/js/components/TwoFactorRecoveryCodes.vue b/resources/js/components/TwoFactorRecoveryCodes.vue index 5bbf53c..f0414f8 100644 --- a/resources/js/components/TwoFactorRecoveryCodes.vue +++ b/resources/js/components/TwoFactorRecoveryCodes.vue @@ -5,11 +5,11 @@ import { nextTick, onMounted, ref, useTemplateRef } from 'vue'; import AlertError from '@/components/AlertError.vue'; import { Button } from '@/components/ui/button'; import { - Card, - CardContent, - CardDescription, - CardHeader, - CardTitle, + Card, + CardContent, + CardDescription, + CardHeader, + CardTitle, } from '@/components/ui/card'; import { useTwoFactorAuth } from '@/composables/useTwoFactorAuth'; import { regenerateRecoveryCodes } from '@/routes/two-factor'; @@ -19,105 +19,93 @@ const isRecoveryCodesVisible = ref(false); const recoveryCodeSectionRef = useTemplateRef('recoveryCodeSectionRef'); const toggleRecoveryCodesVisibility = async () => { - if (!isRecoveryCodesVisible.value && !recoveryCodesList.value.length) { - await fetchRecoveryCodes(); - } + if (!isRecoveryCodesVisible.value && !recoveryCodesList.value.length) { + await fetchRecoveryCodes(); + } - isRecoveryCodesVisible.value = !isRecoveryCodesVisible.value; + isRecoveryCodesVisible.value = !isRecoveryCodesVisible.value; - if (isRecoveryCodesVisible.value) { - await nextTick(); - recoveryCodeSectionRef.value?.scrollIntoView({ behavior: 'smooth' }); - } + if (isRecoveryCodesVisible.value) { + await nextTick(); + recoveryCodeSectionRef.value?.scrollIntoView({ behavior: 'smooth' }); + } }; onMounted(async () => { - if (!recoveryCodesList.value.length) { - await fetchRecoveryCodes(); - } + if (!recoveryCodesList.value.length) { + await fetchRecoveryCodes(); + } }); diff --git a/resources/js/components/TwoFactorSetupModal.vue b/resources/js/components/TwoFactorSetupModal.vue index 06f29c4..5b8f868 100644 --- a/resources/js/components/TwoFactorSetupModal.vue +++ b/resources/js/components/TwoFactorSetupModal.vue @@ -7,16 +7,16 @@ import AlertError from '@/components/AlertError.vue'; import InputError from '@/components/InputError.vue'; import { Button } from '@/components/ui/button'; import { - Dialog, - DialogContent, - DialogDescription, - DialogHeader, - DialogTitle, + Dialog, + DialogContent, + DialogDescription, + DialogHeader, + DialogTitle, } from '@/components/ui/dialog'; import { - InputOTP, - InputOTPGroup, - InputOTPSlot, + InputOTP, + InputOTPGroup, + InputOTPSlot, } from '@/components/ui/input-otp'; import { Spinner } from '@/components/ui/spinner'; import { useAppearance } from '@/composables/useAppearance'; @@ -25,8 +25,8 @@ import { confirm } from '@/routes/two-factor'; import type { TwoFactorConfigContent } from '@/types'; type Props = { - requiresConfirmation: boolean; - twoFactorEnabled: boolean; + requiresConfirmation: boolean; + twoFactorEnabled: boolean; }; const { resolvedAppearance } = useAppearance(); @@ -36,7 +36,7 @@ const isOpen = defineModel('isOpen'); const { copy, copied } = useClipboard(); const { qrCodeSvg, manualSetupKey, clearSetupData, fetchSetupData, errors } = - useTwoFactorAuth(); + useTwoFactorAuth(); const showVerificationStep = ref(false); const code = ref(''); @@ -44,255 +44,234 @@ const code = ref(''); const pinInputContainerRef = useTemplateRef('pinInputContainerRef'); const modalConfig = computed(() => { - if (props.twoFactorEnabled) { - return { - title: 'Two-factor authentication enabled', - description: - 'Two-factor authentication is now enabled. Scan the QR code or enter the setup key in your authenticator app.', - buttonText: 'Close', - }; - } - - if (showVerificationStep.value) { - return { - title: 'Verify authentication code', - description: 'Enter the 6-digit code from your authenticator app', - buttonText: 'Continue', - }; - } - + if (props.twoFactorEnabled) { return { - title: 'Enable two-factor authentication', - description: - 'To finish enabling two-factor authentication, scan the QR code or enter the setup key in your authenticator app', - buttonText: 'Continue', + title: 'Two-factor authentication enabled', + description: + 'Two-factor authentication is now enabled. Scan the QR code or enter the setup key in your authenticator app.', + buttonText: 'Close', }; + } + + if (showVerificationStep.value) { + return { + title: 'Verify authentication code', + description: 'Enter the 6-digit code from your authenticator app', + buttonText: 'Continue', + }; + } + + return { + title: 'Enable two-factor authentication', + description: + 'To finish enabling two-factor authentication, scan the QR code or enter the setup key in your authenticator app', + buttonText: 'Continue', + }; }); const handleModalNextStep = () => { - if (props.requiresConfirmation) { - showVerificationStep.value = true; + if (props.requiresConfirmation) { + showVerificationStep.value = true; - nextTick(() => { - pinInputContainerRef.value?.querySelector('input')?.focus(); - }); + nextTick(() => { + pinInputContainerRef.value?.querySelector('input')?.focus(); + }); - return; - } + return; + } - clearSetupData(); - isOpen.value = false; + clearSetupData(); + isOpen.value = false; }; const resetModalState = () => { - if (props.twoFactorEnabled) { - clearSetupData(); - } + if (props.twoFactorEnabled) { + clearSetupData(); + } - showVerificationStep.value = false; - code.value = ''; + showVerificationStep.value = false; + code.value = ''; }; watch( - () => isOpen.value, - async (isOpen) => { - if (!isOpen) { - resetModalState(); + () => isOpen.value, + async (isOpen) => { + if (!isOpen) { + resetModalState(); - return; - } + return; + } - if (!qrCodeSvg.value) { - await fetchSetupData(); - } - }, + if (!qrCodeSvg.value) { + await fetchSetupData(); + } + }, ); diff --git a/resources/js/components/UserInfo.vue b/resources/js/components/UserInfo.vue index bdae50b..4eb0b25 100644 --- a/resources/js/components/UserInfo.vue +++ b/resources/js/components/UserInfo.vue @@ -5,34 +5,34 @@ import { useInitials } from '@/composables/useInitials'; import type { User } from '@/types'; type Props = { - user: User; - showEmail?: boolean; + user: User; + showEmail?: boolean; }; const props = withDefaults(defineProps(), { - showEmail: false, + showEmail: false, }); const { getInitials } = useInitials(); // Compute whether we should show the avatar image const showAvatar = computed( - () => props.user.avatar && props.user.avatar !== '', + () => props.user.avatar && props.user.avatar !== '', ); diff --git a/resources/js/components/UserMenuContent.vue b/resources/js/components/UserMenuContent.vue index ddd51db..57c4912 100644 --- a/resources/js/components/UserMenuContent.vue +++ b/resources/js/components/UserMenuContent.vue @@ -2,10 +2,10 @@ import { Link, router } from '@inertiajs/vue3'; import { LogOut, Settings } from '@lucide/vue'; import { - DropdownMenuGroup, - DropdownMenuItem, - DropdownMenuLabel, - DropdownMenuSeparator, + DropdownMenuGroup, + DropdownMenuItem, + DropdownMenuLabel, + DropdownMenuSeparator, } from '@/components/ui/dropdown-menu'; import UserInfo from '@/components/UserInfo.vue'; import { logout } from '@/routes'; @@ -13,42 +13,42 @@ import { edit } from '@/routes/profile'; import type { User } from '@/types'; type Props = { - user: User; + user: User; }; const handleLogout = () => { - router.flushAll(); + router.flushAll(); }; defineProps(); diff --git a/resources/js/composables/useAppearance.ts b/resources/js/composables/useAppearance.ts index 0568774..eddb73a 100644 --- a/resources/js/composables/useAppearance.ts +++ b/resources/js/composables/useAppearance.ts @@ -5,120 +5,115 @@ import type { Appearance, ResolvedAppearance } from '@/types'; export type { Appearance, ResolvedAppearance }; export type UseAppearanceReturn = { - appearance: Ref; - resolvedAppearance: ComputedRef; - updateAppearance: (value: Appearance) => void; + appearance: Ref; + resolvedAppearance: ComputedRef; + updateAppearance: (value: Appearance) => void; }; export function updateTheme(value: Appearance): void { - if (typeof window === 'undefined') { - return; - } + if (typeof window === 'undefined') { + return; + } - if (value === 'system') { - const mediaQueryList = window.matchMedia( - '(prefers-color-scheme: dark)', - ); - const systemTheme = mediaQueryList.matches ? 'dark' : 'light'; + if (value === 'system') { + const mediaQueryList = window.matchMedia('(prefers-color-scheme: dark)'); + const systemTheme = mediaQueryList.matches ? 'dark' : 'light'; - document.documentElement.classList.toggle( - 'dark', - systemTheme === 'dark', - ); - } else { - document.documentElement.classList.toggle('dark', value === 'dark'); - } + document.documentElement.classList.toggle('dark', systemTheme === 'dark'); + } else { + document.documentElement.classList.toggle('dark', value === 'dark'); + } } const setCookie = (name: string, value: string, days = 365) => { - if (typeof document === 'undefined') { - return; - } + if (typeof document === 'undefined') { + return; + } - const maxAge = days * 24 * 60 * 60; + const maxAge = days * 24 * 60 * 60; - document.cookie = `${name}=${value};path=/;max-age=${maxAge};SameSite=Lax`; + document.cookie = `${name}=${value};path=/;max-age=${maxAge};SameSite=Lax`; }; const mediaQuery = () => { - if (typeof window === 'undefined') { - return null; - } + if (typeof window === 'undefined') { + return null; + } - return window.matchMedia('(prefers-color-scheme: dark)'); + return window.matchMedia('(prefers-color-scheme: dark)'); }; const getStoredAppearance = () => { - if (typeof window === 'undefined') { - return null; - } + if (typeof window === 'undefined') { + return null; + } - return localStorage.getItem('appearance') as Appearance | null; + return localStorage.getItem('appearance') as Appearance | null; }; const prefersDark = (): boolean => { - if (typeof window === 'undefined') { - return false; - } + if (typeof window === 'undefined') { + return false; + } - return window.matchMedia('(prefers-color-scheme: dark)').matches; + return window.matchMedia('(prefers-color-scheme: dark)').matches; }; const handleSystemThemeChange = () => { - const currentAppearance = getStoredAppearance(); + const currentAppearance = getStoredAppearance(); - updateTheme(currentAppearance || 'system'); + updateTheme(currentAppearance || 'system'); }; export function initializeTheme(): void { - if (typeof window === 'undefined') { - return; - } + if (typeof window === 'undefined') { + return; + } - // Initialize theme from saved preference or default to system... - const savedAppearance = getStoredAppearance(); - updateTheme(savedAppearance || 'system'); + // Initialize theme from saved preference or default to system... + const savedAppearance = getStoredAppearance(); + updateTheme(savedAppearance || 'system'); - // Set up system theme change listener... - mediaQuery()?.addEventListener('change', handleSystemThemeChange); + // Set up system theme change listener... + mediaQuery()?.addEventListener('change', handleSystemThemeChange); } const appearance = ref('system'); export function useAppearance(): UseAppearanceReturn { - onMounted(() => { - const savedAppearance = localStorage.getItem( - 'appearance', - ) as Appearance | null; + onMounted(() => { + const savedAppearance = localStorage.getItem( + 'appearance', + ) as Appearance | null; - if (savedAppearance) { - appearance.value = savedAppearance; - } - }); + if (savedAppearance) { + appearance.value = savedAppearance; + } + }); - const resolvedAppearance = computed(() => { - if (appearance.value === 'system') { - return prefersDark() ? 'dark' : 'light'; - } - - return appearance.value; - }); - - function updateAppearance(value: Appearance) { - appearance.value = value; - - // Store in localStorage for client-side persistence... - localStorage.setItem('appearance', value); - - // Store in cookie for SSR... - setCookie('appearance', value); - - updateTheme(value); + const resolvedAppearance = computed(() => { + if (appearance.value === 'system') { + return prefersDark() ? 'dark' : 'light'; } - return { - appearance, - resolvedAppearance, - updateAppearance, - }; + return appearance.value; + }); + + function updateAppearance(value: Appearance) { + appearance.value = value; + + // Store in localStorage for client-side persistence... + localStorage.setItem('appearance', value); + + // Store in cookie for SSR... + setCookie('appearance', value); + + updateTheme(value); + } + + return { + appearance, + resolvedAppearance, + updateAppearance, + }; } diff --git a/resources/js/composables/useCurrentUrl.ts b/resources/js/composables/useCurrentUrl.ts index 6e0c310..d640931 100644 --- a/resources/js/composables/useCurrentUrl.ts +++ b/resources/js/composables/useCurrentUrl.ts @@ -5,78 +5,78 @@ import { computed, readonly } from 'vue'; import { toUrl } from '@/lib/utils'; export type UseCurrentUrlReturn = { - currentUrl: DeepReadonly>; - isCurrentUrl: ( - urlToCheck: NonNullable, - currentUrl?: string, - startsWith?: boolean, - ) => boolean; - isCurrentOrParentUrl: ( - urlToCheck: NonNullable, - currentUrl?: string, - ) => boolean; - whenCurrentUrl: ( - urlToCheck: NonNullable, - ifTrue: T, - ifFalse?: F, - ) => T | F; + currentUrl: DeepReadonly>; + isCurrentUrl: ( + urlToCheck: NonNullable, + currentUrl?: string, + startsWith?: boolean, + ) => boolean; + isCurrentOrParentUrl: ( + urlToCheck: NonNullable, + currentUrl?: string, + ) => boolean; + whenCurrentUrl: ( + urlToCheck: NonNullable, + ifTrue: T, + ifFalse?: F, + ) => T | F; }; const page = usePage(); const currentUrlReactive = computed( - () => - new URL( - page.url, - typeof window !== 'undefined' - ? window.location.origin - : 'http://localhost', - ).pathname, + () => + new URL( + page.url, + typeof window !== 'undefined' + ? window.location.origin + : 'http://localhost', + ).pathname, ); export function useCurrentUrl(): UseCurrentUrlReturn { - function isCurrentUrl( - urlToCheck: NonNullable, - currentUrl?: string, - startsWith: boolean = false, - ) { - const urlToCompare = currentUrl ?? currentUrlReactive.value; - const urlString = toUrl(urlToCheck); + function isCurrentUrl( + urlToCheck: NonNullable, + currentUrl?: string, + startsWith: boolean = false, + ) { + const urlToCompare = currentUrl ?? currentUrlReactive.value; + const urlString = toUrl(urlToCheck); - const comparePath = (path: string): boolean => - startsWith ? urlToCompare.startsWith(path) : path === urlToCompare; + const comparePath = (path: string): boolean => + startsWith ? urlToCompare.startsWith(path) : path === urlToCompare; - if (!urlString.startsWith('http')) { - return comparePath(urlString); - } - - try { - const absoluteUrl = new URL(urlString); - - return comparePath(absoluteUrl.pathname); - } catch { - return false; - } + if (!urlString.startsWith('http')) { + return comparePath(urlString); } - function isCurrentOrParentUrl( - urlToCheck: NonNullable, - currentUrl?: string, - ) { - return isCurrentUrl(urlToCheck, currentUrl, true); - } + try { + const absoluteUrl = new URL(urlString); - function whenCurrentUrl( - urlToCheck: NonNullable, - ifTrue: any, - ifFalse: any = null, - ) { - return isCurrentUrl(urlToCheck) ? ifTrue : ifFalse; + return comparePath(absoluteUrl.pathname); + } catch { + return false; } + } - return { - currentUrl: readonly(currentUrlReactive), - isCurrentUrl, - isCurrentOrParentUrl, - whenCurrentUrl, - }; + function isCurrentOrParentUrl( + urlToCheck: NonNullable, + currentUrl?: string, + ) { + return isCurrentUrl(urlToCheck, currentUrl, true); + } + + function whenCurrentUrl( + urlToCheck: NonNullable, + ifTrue: any, + ifFalse: any = null, + ) { + return isCurrentUrl(urlToCheck) ? ifTrue : ifFalse; + } + + return { + currentUrl: readonly(currentUrlReactive), + isCurrentUrl, + isCurrentOrParentUrl, + whenCurrentUrl, + }; } diff --git a/resources/js/composables/useInitials.ts b/resources/js/composables/useInitials.ts index bfbbeea..9cb4af8 100644 --- a/resources/js/composables/useInitials.ts +++ b/resources/js/composables/useInitials.ts @@ -1,29 +1,29 @@ export type UseInitialsReturn = { - getInitials: (fullName?: string) => string; + getInitials: (fullName?: string) => string; }; function getInitial(name: string): string { - return Array.from(name)[0] ?? ''; + return Array.from(name)[0] ?? ''; } export function getInitials(fullName?: string): string { - if (!fullName) { - return ''; - } + if (!fullName) { + return ''; + } - const names = fullName.trim().split(/\s+/u).filter(Boolean); + const names = fullName.trim().split(/\s+/u).filter(Boolean); - if (names.length === 0) { - return ''; - } + if (names.length === 0) { + return ''; + } - if (names.length === 1) { - return getInitial(names[0]).toUpperCase(); - } + if (names.length === 1) { + return getInitial(names[0]).toUpperCase(); + } - return `${getInitial(names[0])}${getInitial(names[names.length - 1])}`.toUpperCase(); + return `${getInitial(names[0])}${getInitial(names[names.length - 1])}`.toUpperCase(); } export function useInitials(): UseInitialsReturn { - return { getInitials }; + return { getInitials }; } diff --git a/resources/js/composables/useTwoFactorAuth.ts b/resources/js/composables/useTwoFactorAuth.ts index a93b198..54ac99b 100644 --- a/resources/js/composables/useTwoFactorAuth.ts +++ b/resources/js/composables/useTwoFactorAuth.ts @@ -4,18 +4,18 @@ import { computed, ref } from 'vue'; import { qrCode, recoveryCodes, secretKey } from '@/routes/two-factor'; export type UseTwoFactorAuthReturn = { - qrCodeSvg: Ref; - manualSetupKey: Ref; - recoveryCodesList: Ref; - errors: Ref; - hasSetupData: ComputedRef; - clearSetupData: () => void; - clearErrors: () => void; - clearTwoFactorAuthData: () => void; - fetchQrCode: () => Promise; - fetchSetupKey: () => Promise; - fetchSetupData: () => Promise; - fetchRecoveryCodes: () => Promise; + qrCodeSvg: Ref; + manualSetupKey: Ref; + recoveryCodesList: Ref; + errors: Ref; + hasSetupData: ComputedRef; + clearSetupData: () => void; + clearErrors: () => void; + clearTwoFactorAuthData: () => void; + fetchQrCode: () => Promise; + fetchSetupKey: () => Promise; + fetchSetupData: () => Promise; + fetchRecoveryCodes: () => Promise; }; const errors = ref([]); @@ -24,89 +24,89 @@ const qrCodeSvg = ref(null); const recoveryCodesList = ref([]); const hasSetupData = computed( - () => qrCodeSvg.value !== null && manualSetupKey.value !== null, + () => qrCodeSvg.value !== null && manualSetupKey.value !== null, ); export const useTwoFactorAuth = (): UseTwoFactorAuthReturn => { - const http = useHttp(); + const http = useHttp(); - const fetchQrCode = async (): Promise => { - try { - const { svg } = (await http.submit(qrCode())) as { - svg: string; - url: string; - }; + const fetchQrCode = async (): Promise => { + try { + const { svg } = (await http.submit(qrCode())) as { + svg: string; + url: string; + }; - qrCodeSvg.value = svg; - } catch { - errors.value.push('Failed to fetch QR code'); - qrCodeSvg.value = null; - } - }; + qrCodeSvg.value = svg; + } catch { + errors.value.push('Failed to fetch QR code'); + qrCodeSvg.value = null; + } + }; - const fetchSetupKey = async (): Promise => { - try { - const { secretKey: key } = (await http.submit(secretKey())) as { - secretKey: string; - }; + const fetchSetupKey = async (): Promise => { + try { + const { secretKey: key } = (await http.submit(secretKey())) as { + secretKey: string; + }; - manualSetupKey.value = key; - } catch { - errors.value.push('Failed to fetch a setup key'); - manualSetupKey.value = null; - } - }; + manualSetupKey.value = key; + } catch { + errors.value.push('Failed to fetch a setup key'); + manualSetupKey.value = null; + } + }; - const clearSetupData = (): void => { - manualSetupKey.value = null; - qrCodeSvg.value = null; - clearErrors(); - }; + const clearSetupData = (): void => { + manualSetupKey.value = null; + qrCodeSvg.value = null; + clearErrors(); + }; - const clearErrors = (): void => { - errors.value = []; - }; + const clearErrors = (): void => { + errors.value = []; + }; - const clearTwoFactorAuthData = (): void => { - clearSetupData(); - clearErrors(); - recoveryCodesList.value = []; - }; + const clearTwoFactorAuthData = (): void => { + clearSetupData(); + clearErrors(); + recoveryCodesList.value = []; + }; - const fetchRecoveryCodes = async (): Promise => { - try { - clearErrors(); - recoveryCodesList.value = (await http.submit( - recoveryCodes(), - )) as string[]; - } catch { - errors.value.push('Failed to fetch recovery codes'); - recoveryCodesList.value = []; - } - }; + const fetchRecoveryCodes = async (): Promise => { + try { + clearErrors(); + recoveryCodesList.value = (await http.submit( + recoveryCodes(), + )) as string[]; + } catch { + errors.value.push('Failed to fetch recovery codes'); + recoveryCodesList.value = []; + } + }; - const fetchSetupData = async (): Promise => { - try { - clearErrors(); - await Promise.all([fetchQrCode(), fetchSetupKey()]); - } catch { - qrCodeSvg.value = null; - manualSetupKey.value = null; - } - }; + const fetchSetupData = async (): Promise => { + try { + clearErrors(); + await Promise.all([fetchQrCode(), fetchSetupKey()]); + } catch { + qrCodeSvg.value = null; + manualSetupKey.value = null; + } + }; - return { - qrCodeSvg, - manualSetupKey, - recoveryCodesList, - errors, - hasSetupData, - clearSetupData, - clearErrors, - clearTwoFactorAuthData, - fetchQrCode, - fetchSetupKey, - fetchSetupData, - fetchRecoveryCodes, - }; + return { + qrCodeSvg, + manualSetupKey, + recoveryCodesList, + errors, + hasSetupData, + clearSetupData, + clearErrors, + clearTwoFactorAuthData, + fetchQrCode, + fetchSetupKey, + fetchSetupData, + fetchRecoveryCodes, + }; }; diff --git a/resources/js/layouts/AppLayout.vue b/resources/js/layouts/AppLayout.vue index 627449c..d303c8a 100644 --- a/resources/js/layouts/AppLayout.vue +++ b/resources/js/layouts/AppLayout.vue @@ -3,12 +3,12 @@ import AppLayout from '@/layouts/app/AppSidebarLayout.vue'; import type { BreadcrumbItem } from '@/types'; const { breadcrumbs = [] } = defineProps<{ - breadcrumbs?: BreadcrumbItem[]; + breadcrumbs?: BreadcrumbItem[]; }>(); diff --git a/resources/js/layouts/AuthLayout.vue b/resources/js/layouts/AuthLayout.vue index f496cf0..06ec8ab 100644 --- a/resources/js/layouts/AuthLayout.vue +++ b/resources/js/layouts/AuthLayout.vue @@ -2,13 +2,13 @@ import AuthLayout from '@/layouts/auth/AuthSimpleLayout.vue'; const { title = '', description = '' } = defineProps<{ - title?: string; - description?: string; + title?: string; + description?: string; }>(); diff --git a/resources/js/layouts/app/AppHeaderLayout.vue b/resources/js/layouts/app/AppHeaderLayout.vue index 6275201..e6212af 100644 --- a/resources/js/layouts/app/AppHeaderLayout.vue +++ b/resources/js/layouts/app/AppHeaderLayout.vue @@ -6,20 +6,20 @@ import { Toaster } from '@/components/ui/sonner'; import type { BreadcrumbItem } from '@/types'; type Props = { - breadcrumbs?: BreadcrumbItem[]; + breadcrumbs?: BreadcrumbItem[]; }; withDefaults(defineProps(), { - breadcrumbs: () => [], + breadcrumbs: () => [], }); diff --git a/resources/js/layouts/app/AppSidebarLayout.vue b/resources/js/layouts/app/AppSidebarLayout.vue index f69c07b..954df94 100644 --- a/resources/js/layouts/app/AppSidebarLayout.vue +++ b/resources/js/layouts/app/AppSidebarLayout.vue @@ -7,21 +7,21 @@ import { Toaster } from '@/components/ui/sonner'; import type { BreadcrumbItem } from '@/types'; type Props = { - breadcrumbs?: BreadcrumbItem[]; + breadcrumbs?: BreadcrumbItem[]; }; withDefaults(defineProps(), { - breadcrumbs: () => [], + breadcrumbs: () => [], }); diff --git a/resources/js/layouts/auth/AuthCardLayout.vue b/resources/js/layouts/auth/AuthCardLayout.vue index eeabf89..9e2836a 100644 --- a/resources/js/layouts/auth/AuthCardLayout.vue +++ b/resources/js/layouts/auth/AuthCardLayout.vue @@ -2,49 +2,47 @@ import { Link } from '@inertiajs/vue3'; import AppLogoIcon from '@/components/AppLogoIcon.vue'; import { - Card, - CardContent, - CardDescription, - CardHeader, - CardTitle, + Card, + CardContent, + CardDescription, + CardHeader, + CardTitle, } from '@/components/ui/card'; import { home } from '@/routes'; defineProps<{ - title?: string; - description?: string; + title?: string; + description?: string; }>(); diff --git a/resources/js/layouts/auth/AuthSimpleLayout.vue b/resources/js/layouts/auth/AuthSimpleLayout.vue index e4cdfa2..9e01a48 100644 --- a/resources/js/layouts/auth/AuthSimpleLayout.vue +++ b/resources/js/layouts/auth/AuthSimpleLayout.vue @@ -4,40 +4,40 @@ import AppLogoIcon from '@/components/AppLogoIcon.vue'; import { home } from '@/routes'; defineProps<{ - title?: string; - description?: string; + title?: string; + description?: string; }>(); diff --git a/resources/js/layouts/auth/AuthSplitLayout.vue b/resources/js/layouts/auth/AuthSplitLayout.vue index 5238902..baee4a1 100644 --- a/resources/js/layouts/auth/AuthSplitLayout.vue +++ b/resources/js/layouts/auth/AuthSplitLayout.vue @@ -7,41 +7,41 @@ const page = usePage(); const name = page.props.name; defineProps<{ - title?: string; - description?: string; + title?: string; + description?: string; }>(); diff --git a/resources/js/layouts/settings/Layout.vue b/resources/js/layouts/settings/Layout.vue index ff4e1af..f85f6a2 100644 --- a/resources/js/layouts/settings/Layout.vue +++ b/resources/js/layouts/settings/Layout.vue @@ -11,61 +11,58 @@ import { edit as editSecurity } from '@/routes/security'; import type { NavItem } from '@/types'; const sidebarNavItems: NavItem[] = [ - { - title: 'Profile', - href: editProfile(), - }, - { - title: 'Security', - href: editSecurity(), - }, - { - title: 'Appearance', - href: editAppearance(), - }, + { + title: 'Profile', + href: editProfile(), + }, + { + title: 'Security', + href: editSecurity(), + }, + { + title: 'Appearance', + href: editAppearance(), + }, ]; const { isCurrentOrParentUrl } = useCurrentUrl(); diff --git a/resources/js/lib/flashToast.ts b/resources/js/lib/flashToast.ts index a9e61ac..a3d0d47 100644 --- a/resources/js/lib/flashToast.ts +++ b/resources/js/lib/flashToast.ts @@ -3,14 +3,14 @@ import { toast } from 'vue-sonner'; import type { FlashToast } from '@/types/ui'; export function initializeFlashToast(): void { - router.on('flash', (event) => { - const flash = (event as CustomEvent).detail?.flash; - const data = flash?.toast as FlashToast | undefined; + router.on('flash', (event) => { + const flash = (event as CustomEvent).detail?.flash; + const data = flash?.toast as FlashToast | undefined; - if (!data) { - return; - } + if (!data) { + return; + } - toast[data.type](data.message); - }); + toast[data.type](data.message); + }); } diff --git a/resources/js/lib/utils.ts b/resources/js/lib/utils.ts index c6249d3..a94c982 100644 --- a/resources/js/lib/utils.ts +++ b/resources/js/lib/utils.ts @@ -1,12 +1,12 @@ import type { InertiaLinkProps } from '@inertiajs/vue3'; -import { clsx } from 'clsx'; import type { ClassValue } from 'clsx'; +import { clsx } from 'clsx'; import { twMerge } from 'tailwind-merge'; export function cn(...inputs: ClassValue[]) { - return twMerge(clsx(inputs)); + return twMerge(clsx(inputs)); } export function toUrl(href: NonNullable) { - return typeof href === 'string' ? href : href?.url; + return typeof href === 'string' ? href : href?.url; } diff --git a/resources/js/pages/Dashboard.vue b/resources/js/pages/Dashboard.vue index 42ca0c3..8530113 100644 --- a/resources/js/pages/Dashboard.vue +++ b/resources/js/pages/Dashboard.vue @@ -4,44 +4,42 @@ import PlaceholderPattern from '@/components/PlaceholderPattern.vue'; import { dashboard } from '@/routes'; defineOptions({ - layout: { - breadcrumbs: [ - { - title: 'Dashboard', - href: dashboard(), - }, - ], - }, + layout: { + breadcrumbs: [ + { + title: 'Dashboard', + href: dashboard(), + }, + ], + }, }); diff --git a/resources/js/pages/Welcome.vue b/resources/js/pages/Welcome.vue index e345578..cc6e357 100644 --- a/resources/js/pages/Welcome.vue +++ b/resources/js/pages/Welcome.vue @@ -5,439 +5,424 @@ import { register } from '@/routes'; diff --git a/resources/js/pages/auth/ConfirmPassword.vue b/resources/js/pages/auth/ConfirmPassword.vue index 5f7ede9..3b2c3e5 100644 --- a/resources/js/pages/auth/ConfirmPassword.vue +++ b/resources/js/pages/auth/ConfirmPassword.vue @@ -7,63 +7,59 @@ import { Label } from '@/components/ui/label'; import { Spinner } from '@/components/ui/spinner'; import { store } from '@/routes/password/confirm'; import { - index as confirmOptions, - store as confirmStore, + index as confirmOptions, + store as confirmStore, } from '@/actions/Laravel/Passkeys/Http/Controllers/PasskeyConfirmationController'; import PasskeyVerify from '@/components/PasskeyVerify.vue'; defineOptions({ - layout: { - title: 'Confirm password', - description: - 'This is a secure area of the application. Please confirm your password before continuing.', - }, + layout: { + title: 'Confirm password', + description: + 'This is a secure area of the application. Please confirm your password before continuing.', + }, }); diff --git a/resources/js/pages/auth/ForgotPassword.vue b/resources/js/pages/auth/ForgotPassword.vue index 683becf..960f4ce 100644 --- a/resources/js/pages/auth/ForgotPassword.vue +++ b/resources/js/pages/auth/ForgotPassword.vue @@ -10,57 +10,57 @@ import { login } from '@/routes'; import { email } from '@/routes/password'; defineOptions({ - layout: { - title: 'Forgot password', - description: 'Enter your email to receive a password reset link', - }, + layout: { + title: 'Forgot password', + description: 'Enter your email to receive a password reset link', + }, }); defineProps<{ - status?: string; + status?: string; }>(); diff --git a/resources/js/pages/auth/Login.vue b/resources/js/pages/auth/Login.vue index f3effcb..348843f 100644 --- a/resources/js/pages/auth/Login.vue +++ b/resources/js/pages/auth/Login.vue @@ -14,97 +14,97 @@ import { request } from '@/routes/password'; import PasskeyVerify from '@/components/PasskeyVerify.vue'; defineOptions({ - layout: { - title: 'Log in to your account', - description: 'Enter your email and password below to log in', - }, + layout: { + title: 'Log in to your account', + description: 'Enter your email and password below to log in', + }, }); defineProps<{ - status?: string; - canResetPassword: boolean; + status?: string; + canResetPassword: boolean; }>(); diff --git a/resources/js/pages/auth/Register.vue b/resources/js/pages/auth/Register.vue index 765aba7..4767b57 100644 --- a/resources/js/pages/auth/Register.vue +++ b/resources/js/pages/auth/Register.vue @@ -11,104 +11,104 @@ import { login } from '@/routes'; import { store } from '@/routes/register'; defineProps<{ - passwordRules: string; + passwordRules: string; }>(); defineOptions({ - layout: { - title: 'Create an account', - description: 'Enter your details below to create your account', - }, + layout: { + title: 'Create an account', + description: 'Enter your details below to create your account', + }, }); diff --git a/resources/js/pages/auth/ResetPassword.vue b/resources/js/pages/auth/ResetPassword.vue index 0ae9fd6..4b2a3d1 100644 --- a/resources/js/pages/auth/ResetPassword.vue +++ b/resources/js/pages/auth/ResetPassword.vue @@ -10,81 +10,81 @@ import { Spinner } from '@/components/ui/spinner'; import { update } from '@/routes/password'; defineOptions({ - layout: { - title: 'Reset password', - description: 'Please enter your new password below', - }, + layout: { + title: 'Reset password', + description: 'Please enter your new password below', + }, }); const props = defineProps<{ - token: string; - email: string; - passwordRules: string; + token: string; + email: string; + passwordRules: string; }>(); const inputEmail = ref(props.email); diff --git a/resources/js/pages/auth/TwoFactorChallenge.vue b/resources/js/pages/auth/TwoFactorChallenge.vue index b9f68b3..123fca2 100644 --- a/resources/js/pages/auth/TwoFactorChallenge.vue +++ b/resources/js/pages/auth/TwoFactorChallenge.vue @@ -5,9 +5,9 @@ import InputError from '@/components/InputError.vue'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { - InputOTP, - InputOTPGroup, - InputOTPSlot, + InputOTP, + InputOTPGroup, + InputOTPSlot, } from '@/components/ui/input-otp'; import { store } from '@/routes/two-factor/login'; import type { TwoFactorConfigContent } from '@/types'; @@ -16,118 +16,118 @@ const showRecoveryInput = ref(false); const code = ref(''); const authConfigContent = computed(() => { - if (showRecoveryInput.value) { - return { - title: 'Recovery code', - description: - 'Please confirm access to your account by entering one of your emergency recovery codes.', - buttonText: 'login using an authentication code', - }; - } - + if (showRecoveryInput.value) { return { - title: 'Authentication code', - description: - 'Enter the authentication code provided by your authenticator application.', - buttonText: 'login using a recovery code', + title: 'Recovery code', + description: + 'Please confirm access to your account by entering one of your emergency recovery codes.', + buttonText: 'login using an authentication code', }; + } + + return { + title: 'Authentication code', + description: + 'Enter the authentication code provided by your authenticator application.', + buttonText: 'login using a recovery code', + }; }); watchEffect(() => { - setLayoutProps({ - title: authConfigContent.value.title, - description: authConfigContent.value.description, - }); + setLayoutProps({ + title: authConfigContent.value.title, + description: authConfigContent.value.description, + }); }); const toggleRecoveryMode = (clearErrors: () => void): void => { - showRecoveryInput.value = !showRecoveryInput.value; - clearErrors(); - code.value = ''; + showRecoveryInput.value = !showRecoveryInput.value; + clearErrors(); + code.value = ''; }; diff --git a/resources/js/pages/auth/VerifyEmail.vue b/resources/js/pages/auth/VerifyEmail.vue index e40b6fd..971552c 100644 --- a/resources/js/pages/auth/VerifyEmail.vue +++ b/resources/js/pages/auth/VerifyEmail.vue @@ -7,41 +7,41 @@ import { logout } from '@/routes'; import { send } from '@/routes/verification'; defineOptions({ - layout: { - title: 'Email verification', - description: - 'Please verify your email address by clicking on the link we just emailed to you.', - }, + layout: { + title: 'Email verification', + description: + 'Please verify your email address by clicking on the link we just emailed to you.', + }, }); defineProps<{ - status?: string; + status?: string; }>(); diff --git a/resources/js/pages/settings/Appearance.vue b/resources/js/pages/settings/Appearance.vue index 8142818..c59df6f 100644 --- a/resources/js/pages/settings/Appearance.vue +++ b/resources/js/pages/settings/Appearance.vue @@ -5,28 +5,28 @@ import Heading from '@/components/Heading.vue'; import { edit } from '@/routes/appearance'; defineOptions({ - layout: { - breadcrumbs: [ - { - title: 'Appearance settings', - href: edit(), - }, - ], - }, + layout: { + breadcrumbs: [ + { + title: 'Appearance settings', + href: edit(), + }, + ], + }, }); diff --git a/resources/js/pages/settings/Profile.vue b/resources/js/pages/settings/Profile.vue index b4498e8..9c08e78 100644 --- a/resources/js/pages/settings/Profile.vue +++ b/resources/js/pages/settings/Profile.vue @@ -13,14 +13,14 @@ import { edit } from '@/routes/profile'; import { send } from '@/routes/verification'; defineOptions({ - layout: { - breadcrumbs: [ - { - title: 'Profile settings', - href: edit(), - }, - ], - }, + layout: { + breadcrumbs: [ + { + title: 'Profile settings', + href: edit(), + }, + ], + }, }); const page = usePage(); @@ -28,78 +28,78 @@ const user = computed(() => page.props.auth.user); diff --git a/resources/js/pages/settings/Security.vue b/resources/js/pages/settings/Security.vue index 0280e28..94dd4d6 100644 --- a/resources/js/pages/settings/Security.vue +++ b/resources/js/pages/settings/Security.vue @@ -21,100 +21,94 @@ type Props = { const props = defineProps(); defineOptions({ - layout: { - breadcrumbs: [ - { - title: 'Security settings', - href: edit(), - }, - ], - }, + layout: { + breadcrumbs: [ + { + title: 'Security settings', + href: edit(), + }, + ], + }, }); diff --git a/resources/js/pages/team/Create.vue b/resources/js/pages/team/Create.vue index 85af715..73b7fae 100644 --- a/resources/js/pages/team/Create.vue +++ b/resources/js/pages/team/Create.vue @@ -1,11 +1,66 @@ - - diff --git a/resources/js/pages/team/Edit.vue b/resources/js/pages/team/Edit.vue index 85af715..809cc24 100644 --- a/resources/js/pages/team/Edit.vue +++ b/resources/js/pages/team/Edit.vue @@ -1,11 +1,71 @@ - - - diff --git a/resources/js/pages/team/Index.vue b/resources/js/pages/team/Index.vue index 0809a74..367fb8b 100644 --- a/resources/js/pages/team/Index.vue +++ b/resources/js/pages/team/Index.vue @@ -1,25 +1,18 @@ -