Add Ladill Link URL shortener on ladl.link.
Management UI at link.ladill.com with GHS 0.05 per link wallet billing, click analytics, and legacy fallback to ladill.com/q for QR ecosystem codes. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,24 +1,19 @@
|
||||
@php
|
||||
$mobileFullScreenPage = request()->routeIs('account.settings')
|
||||
|| request()->routeIs('user.qr-codes.create')
|
||||
|| request()->routeIs('user.qr-codes.show')
|
||||
|| request()->routeIs('qr.search');
|
||||
|
||||
$qrMobilePage = request()->routeIs('user.qr-codes.create') || request()->routeIs('user.qr-codes.show');
|
||||
$mobileFullScreenPage = false;
|
||||
@endphp
|
||||
<!DOCTYPE html>
|
||||
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}" @class(['qr-mobile-page' => $qrMobilePage])>
|
||||
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||
<meta name="csrf-token" content="{{ csrf_token() }}">
|
||||
@include('partials.favicon')
|
||||
<title>{{ $title ?? 'Dashboard' }} - Ladill</title>
|
||||
<title>{{ $title ?? 'Dashboard' }} - Ladill Link</title>
|
||||
<link rel="preconnect" href="https://fonts.bunny.net">
|
||||
<link href="https://fonts.bunny.net/css?family=figtree:400,500,600&display=swap" rel="stylesheet" />
|
||||
@vite(['resources/css/app.css', 'resources/js/app.js'])
|
||||
</head>
|
||||
<body class="font-sans antialiased bg-slate-100" x-data="{ sidebarOpen: false }" data-ladill-search-url="{{ route('qr.search') }}">
|
||||
<body class="font-sans antialiased bg-slate-100" x-data="{ sidebarOpen: false }">
|
||||
<div class="min-h-screen max-lg:min-h-dvh">
|
||||
{{-- Mobile sidebar overlay --}}
|
||||
<div x-show="sidebarOpen" x-cloak class="fixed inset-0 z-30 bg-black/50 lg:hidden" @click="sidebarOpen = false"></div>
|
||||
@@ -44,45 +39,34 @@
|
||||
@include('partials.flash')
|
||||
</div>
|
||||
|
||||
<main @class([
|
||||
'flex-1 lg:p-6 lg:pb-6',
|
||||
'px-4 pt-4 max-lg:pb-[calc(4rem+max(env(safe-area-inset-bottom,0px),20px))]' => $qrMobilePage,
|
||||
'p-0 pb-24 lg:p-6 lg:pb-6' => $mobileFullScreenPage && ! $qrMobilePage,
|
||||
'p-6 pb-24 lg:pb-6' => ! $mobileFullScreenPage,
|
||||
])>
|
||||
<main class="flex-1 p-6 pb-24 lg:pb-6">
|
||||
{{ $slot }}
|
||||
</main>
|
||||
</div>
|
||||
|
||||
{{-- Mobile Bottom Navigation (hidden on QR create/show which have their own action bar) --}}
|
||||
@unless(request()->routeIs('user.qr-codes.create') || request()->routeIs('user.qr-codes.show'))
|
||||
@php
|
||||
$navUser = auth()->user();
|
||||
$navInitials = collect(explode(' ', trim((string) $navUser?->name)))
|
||||
->filter()->take(2)
|
||||
->map(fn ($part) => strtoupper(substr($part, 0, 1)))
|
||||
->implode('');
|
||||
@endphp
|
||||
@include('partials.mobile-bottom-nav', [
|
||||
'homeUrl' => route('qr.dashboard'),
|
||||
'homeActive' => request()->routeIs('qr.dashboard'),
|
||||
'searchUrl' => route('qr.search'),
|
||||
'searchActive' => request()->routeIs('qr.search'),
|
||||
'notificationsUrl' => route('notifications.index'),
|
||||
'notificationsActive' => request()->routeIs('notifications.*'),
|
||||
'unreadUrl' => route('notifications.unread'),
|
||||
'profileActive' => request()->routeIs('account.settings'),
|
||||
'profileName' => $navUser?->name ?? '',
|
||||
'profileSubtitle' => $navUser?->email ?? '',
|
||||
'profileMenuItems' => \App\Support\UserProfileMenu::items($navUser),
|
||||
'avatarUrl' => $navUser?->avatarUrl(),
|
||||
'initials' => $navInitials !== '' ? $navInitials : 'U',
|
||||
])
|
||||
@endunless
|
||||
|
||||
@if ($qrMobilePage)
|
||||
<div class="qr-mobile-bottom-bleed lg:hidden" aria-hidden="true"></div>
|
||||
@endif
|
||||
@php
|
||||
$navUser = auth()->user();
|
||||
$navInitials = collect(explode(' ', trim((string) $navUser?->name)))
|
||||
->filter()->take(2)
|
||||
->map(fn ($part) => strtoupper(substr($part, 0, 1)))
|
||||
->implode('');
|
||||
@endphp
|
||||
@include('partials.mobile-bottom-nav', [
|
||||
'homeUrl' => route('link.dashboard'),
|
||||
'homeActive' => request()->routeIs('link.dashboard'),
|
||||
'searchUrl' => route('user.links.index'),
|
||||
'searchActive' => request()->routeIs('user.links.*'),
|
||||
'notificationsUrl' => route('notifications.index'),
|
||||
'notificationsActive' => request()->routeIs('notifications.*'),
|
||||
'unreadUrl' => route('notifications.unread'),
|
||||
'profileActive' => request()->routeIs('account.settings'),
|
||||
'profileName' => $navUser?->name ?? '',
|
||||
'profileSubtitle' => $navUser?->email ?? '',
|
||||
'profileMenuItems' => \App\Support\UserProfileMenu::items($navUser),
|
||||
'avatarUrl' => $navUser?->avatarUrl(),
|
||||
'initials' => $navInitials !== '' ? $navInitials : 'U',
|
||||
])
|
||||
</div>
|
||||
<script>
|
||||
document.addEventListener('alpine:init', () => {
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
<x-layouts.user :title="'Create Link'">
|
||||
<div class="mx-auto max-w-xl space-y-6">
|
||||
<div>
|
||||
<h1 class="text-2xl font-semibold text-slate-900">Create short link</h1>
|
||||
<p class="mt-1 text-sm text-slate-500">
|
||||
Your link will be published on <span class="font-medium text-emerald-700">ladl.link</span>.
|
||||
GHS {{ number_format($pricePerLink, 2) }} will be debited from your wallet.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@if($errors->has('balance'))
|
||||
<div class="rounded-lg border border-amber-200 bg-amber-50 px-4 py-3 text-sm text-amber-800">
|
||||
{{ $errors->first('balance') }}
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<form method="POST" action="{{ route('user.links.store') }}" class="space-y-5 rounded-xl border border-slate-200 bg-white p-6">
|
||||
@csrf
|
||||
|
||||
<div>
|
||||
<label for="destination_url" class="block text-sm font-medium text-slate-700">Destination URL</label>
|
||||
<input type="url" name="destination_url" id="destination_url" value="{{ old('destination_url') }}" required
|
||||
placeholder="https://example.com/page"
|
||||
class="mt-1 block w-full rounded-lg border-slate-300 shadow-sm focus:border-emerald-500 focus:ring-emerald-500">
|
||||
@error('destination_url')<p class="mt-1 text-sm text-red-600">{{ $message }}</p>@enderror
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="label" class="block text-sm font-medium text-slate-700">Label (optional)</label>
|
||||
<input type="text" name="label" id="label" value="{{ old('label') }}"
|
||||
class="mt-1 block w-full rounded-lg border-slate-300 shadow-sm focus:border-emerald-500 focus:ring-emerald-500">
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="custom_slug" class="block text-sm font-medium text-slate-700">Custom slug (optional)</label>
|
||||
<div class="mt-1 flex rounded-lg shadow-sm">
|
||||
<span class="inline-flex items-center rounded-l-lg border border-r-0 border-slate-300 bg-slate-50 px-3 text-sm text-slate-500">ladl.link/</span>
|
||||
<input type="text" name="custom_slug" id="custom_slug" value="{{ old('custom_slug') }}"
|
||||
pattern="[a-z0-9][a-z0-9-]{1,18}[a-z0-9]"
|
||||
class="block w-full rounded-r-lg border-slate-300 focus:border-emerald-500 focus:ring-emerald-500">
|
||||
</div>
|
||||
@error('custom_slug')<p class="mt-1 text-sm text-red-600">{{ $message }}</p>@enderror
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end gap-3">
|
||||
<a href="{{ route('user.links.index') }}" class="rounded-lg px-4 py-2 text-sm font-medium text-slate-600 hover:bg-slate-50">Cancel</a>
|
||||
<button type="submit" class="rounded-lg bg-emerald-600 px-4 py-2 text-sm font-semibold text-white hover:bg-emerald-700">
|
||||
Create link — GHS {{ number_format($pricePerLink, 2) }}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</x-layouts.user>
|
||||
@@ -0,0 +1,50 @@
|
||||
<x-layouts.user :title="'Dashboard'">
|
||||
<div class="mx-auto max-w-5xl space-y-6">
|
||||
<div class="flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between">
|
||||
<div>
|
||||
<h1 class="text-2xl font-semibold text-slate-900">Overview</h1>
|
||||
<p class="mt-1 text-sm text-slate-500">Short links on <span class="font-medium text-emerald-700">ladl.link</span> — GHS {{ number_format($pricePerLink, 2) }} per link</p>
|
||||
</div>
|
||||
<a href="{{ route('user.links.create') }}"
|
||||
class="inline-flex items-center justify-center rounded-lg bg-emerald-600 px-4 py-2 text-sm font-semibold text-white hover:bg-emerald-700">
|
||||
Create link
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="grid gap-4 sm:grid-cols-3">
|
||||
<div class="rounded-xl border border-slate-200 bg-white p-5">
|
||||
<p class="text-sm text-slate-500">Links created</p>
|
||||
<p class="mt-1 text-3xl font-semibold text-slate-900">{{ number_format($wallet->links_total) }}</p>
|
||||
</div>
|
||||
<div class="rounded-xl border border-slate-200 bg-white p-5">
|
||||
<p class="text-sm text-slate-500">Total clicks</p>
|
||||
<p class="mt-1 text-3xl font-semibold text-slate-900">{{ number_format($wallet->clicks_total) }}</p>
|
||||
</div>
|
||||
<div class="rounded-xl border border-slate-200 bg-white p-5">
|
||||
<p class="text-sm text-slate-500">Price per link</p>
|
||||
<p class="mt-1 text-3xl font-semibold text-emerald-700">GHS {{ number_format($pricePerLink, 2) }}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@if($recentLinks->isNotEmpty())
|
||||
<div class="rounded-xl border border-slate-200 bg-white">
|
||||
<div class="border-b border-slate-100 px-5 py-4">
|
||||
<h2 class="font-semibold text-slate-900">Recent links</h2>
|
||||
</div>
|
||||
<ul class="divide-y divide-slate-100">
|
||||
@foreach($recentLinks as $link)
|
||||
<li class="flex items-center justify-between gap-4 px-5 py-3">
|
||||
<div class="min-w-0">
|
||||
<a href="{{ route('user.links.show', $link) }}" class="font-medium text-slate-900 hover:text-emerald-700">
|
||||
{{ $link->label ?: $link->slug }}
|
||||
</a>
|
||||
<p class="truncate text-sm text-emerald-600">{{ $link->publicUrl() }}</p>
|
||||
</div>
|
||||
<span class="shrink-0 text-sm text-slate-500">{{ number_format($link->clicks_total) }} clicks</span>
|
||||
</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</x-layouts.user>
|
||||
@@ -0,0 +1,55 @@
|
||||
<x-layouts.user :title="'My Links'">
|
||||
<div class="mx-auto max-w-5xl space-y-6">
|
||||
<div class="flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between">
|
||||
<div>
|
||||
<h1 class="text-2xl font-semibold text-slate-900">My Links</h1>
|
||||
<p class="mt-1 text-sm text-slate-500">GHS {{ number_format($pricePerLink, 2) }} debited from your wallet per link</p>
|
||||
</div>
|
||||
<a href="{{ route('user.links.create') }}"
|
||||
class="inline-flex items-center justify-center rounded-lg bg-emerald-600 px-4 py-2 text-sm font-semibold text-white hover:bg-emerald-700">
|
||||
Create link
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="overflow-hidden rounded-xl border border-slate-200 bg-white">
|
||||
@if($links->isEmpty())
|
||||
<div class="px-6 py-12 text-center">
|
||||
<p class="text-slate-500">No links yet. Create your first short link on ladl.link.</p>
|
||||
</div>
|
||||
@else
|
||||
<table class="min-w-full divide-y divide-slate-100">
|
||||
<thead class="bg-slate-50 text-left text-xs font-semibold uppercase tracking-wide text-slate-500">
|
||||
<tr>
|
||||
<th class="px-5 py-3">Link</th>
|
||||
<th class="px-5 py-3">Destination</th>
|
||||
<th class="px-5 py-3">Clicks</th>
|
||||
<th class="px-5 py-3">Status</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-slate-100 text-sm">
|
||||
@foreach($links as $link)
|
||||
<tr class="hover:bg-slate-50">
|
||||
<td class="px-5 py-3">
|
||||
<a href="{{ route('user.links.show', $link) }}" class="font-medium text-slate-900 hover:text-emerald-700">
|
||||
{{ $link->label ?: $link->slug }}
|
||||
</a>
|
||||
<p class="text-emerald-600">{{ $link->publicUrl() }}</p>
|
||||
</td>
|
||||
<td class="max-w-xs truncate px-5 py-3 text-slate-500">{{ $link->destination_url }}</td>
|
||||
<td class="px-5 py-3 text-slate-700">{{ number_format($link->clicks_total) }}</td>
|
||||
<td class="px-5 py-3">
|
||||
@if($link->is_active && ! $link->isExpired())
|
||||
<span class="rounded-full bg-emerald-50 px-2 py-0.5 text-xs font-medium text-emerald-700">Active</span>
|
||||
@else
|
||||
<span class="rounded-full bg-slate-100 px-2 py-0.5 text-xs font-medium text-slate-600">Inactive</span>
|
||||
@endif
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="border-t border-slate-100 px-5 py-3">{{ $links->links() }}</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</x-layouts.user>
|
||||
@@ -0,0 +1,58 @@
|
||||
<x-layouts.user :title="$link->label ?: $link->slug">
|
||||
<div class="mx-auto max-w-3xl space-y-6">
|
||||
<div class="flex flex-col gap-4 sm:flex-row sm:items-start sm:justify-between">
|
||||
<div>
|
||||
<h1 class="text-2xl font-semibold text-slate-900">{{ $link->label ?: $link->slug }}</h1>
|
||||
<a href="{{ $link->publicUrl() }}" target="_blank" rel="noopener"
|
||||
class="mt-1 inline-flex items-center gap-1 text-emerald-600 hover:text-emerald-700">
|
||||
{{ $link->publicUrl() }}
|
||||
<svg class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M13.5 6H5.25A2.25 2.25 0 0 0 3 8.25v10.5A2.25 2.25 0 0 0 5.25 21h10.5A2.25 2.25 0 0 0 18 18.75V10.5m-10.5 6L21 3m0 0h-5.25M21 3v5.25" /></svg>
|
||||
</a>
|
||||
</div>
|
||||
<form method="POST" action="{{ route('user.links.destroy', $link) }}" onsubmit="return confirm('Delete this link?')">
|
||||
@csrf @method('DELETE')
|
||||
<button type="submit" class="text-sm text-red-600 hover:text-red-700">Delete</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="grid gap-4 sm:grid-cols-3">
|
||||
<div class="rounded-xl border border-slate-200 bg-white p-4">
|
||||
<p class="text-sm text-slate-500">Total clicks</p>
|
||||
<p class="text-2xl font-semibold">{{ number_format($link->clicks_total) }}</p>
|
||||
</div>
|
||||
<div class="rounded-xl border border-slate-200 bg-white p-4">
|
||||
<p class="text-sm text-slate-500">Unique clicks</p>
|
||||
<p class="text-2xl font-semibold">{{ number_format($link->unique_clicks_total) }}</p>
|
||||
</div>
|
||||
<div class="rounded-xl border border-slate-200 bg-white p-4">
|
||||
<p class="text-sm text-slate-500">Last clicked</p>
|
||||
<p class="text-sm font-medium">{{ $link->last_clicked_at?->diffForHumans() ?? 'Never' }}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<form method="POST" action="{{ route('user.links.update', $link) }}" class="space-y-4 rounded-xl border border-slate-200 bg-white p-6">
|
||||
@csrf @method('PATCH')
|
||||
|
||||
<div>
|
||||
<label for="destination_url" class="block text-sm font-medium text-slate-700">Destination URL</label>
|
||||
<input type="url" name="destination_url" id="destination_url" value="{{ old('destination_url', $link->destination_url) }}" required
|
||||
class="mt-1 block w-full rounded-lg border-slate-300 shadow-sm focus:border-emerald-500 focus:ring-emerald-500">
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="label" class="block text-sm font-medium text-slate-700">Label</label>
|
||||
<input type="text" name="label" id="label" value="{{ old('label', $link->label) }}"
|
||||
class="mt-1 block w-full rounded-lg border-slate-300 shadow-sm focus:border-emerald-500 focus:ring-emerald-500">
|
||||
</div>
|
||||
|
||||
<label class="flex items-center gap-2 text-sm text-slate-700">
|
||||
<input type="hidden" name="is_active" value="0">
|
||||
<input type="checkbox" name="is_active" value="1" @checked(old('is_active', $link->is_active))
|
||||
class="rounded border-slate-300 text-emerald-600 focus:ring-emerald-500">
|
||||
Link is active
|
||||
</label>
|
||||
|
||||
<button type="submit" class="rounded-lg bg-emerald-600 px-4 py-2 text-sm font-semibold text-white hover:bg-emerald-700">Save changes</button>
|
||||
</form>
|
||||
</div>
|
||||
</x-layouts.user>
|
||||
@@ -0,0 +1,16 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Signed out — Ladill Link</title>
|
||||
@vite(['resources/css/app.css'])
|
||||
</head>
|
||||
<body class="flex min-h-screen items-center justify-center bg-slate-100 font-sans antialiased">
|
||||
<div class="text-center">
|
||||
<img src="{{ asset('images/logo/ladilllink-logo.svg') }}" alt="Ladill Link" class="mx-auto h-8">
|
||||
<p class="mt-6 text-slate-600">You have been signed out.</p>
|
||||
<a href="{{ route('sso.connect') }}" class="mt-4 inline-block text-sm font-medium text-emerald-600 hover:text-emerald-700">Sign in again</a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,35 +1,23 @@
|
||||
<div class="flex h-full flex-col bg-white border-r border-slate-200 text-slate-700">
|
||||
<div class="flex h-16 shrink-0 items-center border-b border-slate-200 px-6">
|
||||
<a href="{{ route('qr.dashboard') }}" class="flex items-center">
|
||||
<img src="{{ asset('images/logo/ladillqrplus-logo.svg') }}?v={{ @filemtime(public_path('images/logo/ladillqrplus-logo.svg')) ?: '1' }}" alt="Ladill QR Plus" class="h-6 w-auto">
|
||||
<a href="{{ route('link.dashboard') }}" class="flex items-center">
|
||||
<img src="{{ asset('images/logo/ladilllink-logo.svg') }}?v={{ @filemtime(public_path('images/logo/ladilllink-logo.svg')) ?: '1' }}" alt="Ladill Link" class="h-6 w-auto">
|
||||
</a>
|
||||
</div>
|
||||
@php
|
||||
$main = [
|
||||
['name' => 'Overview', 'route' => route('qr.dashboard'), 'active' => request()->routeIs('qr.dashboard'),
|
||||
['name' => 'Overview', 'route' => route('link.dashboard'), 'active' => request()->routeIs('link.dashboard'),
|
||||
'icon' => '<path stroke-linecap="round" stroke-linejoin="round" d="M2.25 12 11.2 3.05c.44-.44 1.15-.44 1.59 0L21.75 12M4.5 9.75v10.5a.75.75 0 0 0 .75.75H9.75v-6a.75.75 0 0 1 .75-.75h3a.75.75 0 0 1 .75.75v6h4.5a.75.75 0 0 0 .75-.75V9.75" />'],
|
||||
['name' => 'My Codes', 'route' => route('user.qr-codes.index'), 'active' => request()->routeIs('user.qr-codes.*'),
|
||||
'icon' => '<path stroke-linecap="round" stroke-linejoin="round" d="M3.75 4.875c0-.621.504-1.125 1.125-1.125h4.5c.621 0 1.125.504 1.125 1.125v4.5c0 .621-.504 1.125-1.125 1.125h-4.5A1.125 1.125 0 0 1 3.75 9.375v-4.5ZM3.75 14.625c0-.621.504-1.125 1.125-1.125h4.5c.621 0 1.125.504 1.125 1.125v4.5c0 .621-.504 1.125-1.125 1.125h-4.5a1.125 1.125 0 0 1-1.125-1.125v-4.5ZM13.5 4.875c0-.621.504-1.125 1.125-1.125h4.5c.621 0 1.125.504 1.125 1.125v4.5c0 .621-.504 1.125-1.125 1.125h-4.5A1.125 1.125 0 0 1 13.5 9.375v-4.5Z" /><path stroke-linecap="round" stroke-linejoin="round" d="M6.75 6.75h.75v.75h-.75v-.75ZM6.75 16.5h.75v.75h-.75v-.75ZM16.5 6.75h.75v.75h-.75v-.75ZM13.5 13.5h.75v.75h-.75v-.75ZM16.5 16.5h.75v.75h-.75v-.75ZM13.5 19.5h.75v.75h-.75v-.75ZM19.5 13.5h.75v.75h-.75v-.75ZM19.5 19.5h.75v.75h-.75v-.75ZM22.5 18.75a2.25 2.25 0 0 0-2.25-2.25h-1.5a2.25 2.25 0 0 0-2.25 2.25v1.5a2.25 2.25 0 0 0 2.25 2.25h1.5a2.25 2.25 0 0 0 2.25-2.25v-1.5Z" />'],
|
||||
['name' => 'Analytics', 'route' => route('qr.analytics.index'), 'active' => request()->routeIs('qr.analytics.*'),
|
||||
'icon' => '<path stroke-linecap="round" stroke-linejoin="round" d="M3 13.125C3 12.504 3.504 12 4.125 12h2.25c.621 0 1.125.504 1.125 1.125v6.75C7.5 20.496 6.996 21 6.375 21h-2.25A1.125 1.125 0 0 1 3 19.875v-6.75ZM9.75 8.625c0-.621.504-1.125 1.125-1.125h2.25c.621 0 1.125.504 1.125 1.125v11.25c0 .621-.504 1.125-1.125 1.125h-2.25a1.125 1.125 0 0 1-1.125-1.125V8.625ZM16.5 4.125c0-.621.504-1.125 1.125-1.125h2.25C20.496 3 21 3.504 21 4.125v15.75c0 .621-.504 1.125-1.125 1.125h-2.25a1.125 1.125 0 0 1-1.125-1.125V4.125Z" />'],
|
||||
['name' => 'My Links', 'route' => route('user.links.index'), 'active' => request()->routeIs('user.links.*'),
|
||||
'icon' => '<path stroke-linecap="round" stroke-linejoin="round" d="M13.19 8.688a4.5 4.5 0 0 1 1.242 7.244l-4.5 4.5a4.5 4.5 0 0 1-6.364-6.364l1.757-1.757m13.35-.622 1.757-1.757a4.5 4.5 0 0 0-6.364-6.364l-4.5 4.5a4.5 4.5 0 0 0 1.242 7.244" />'],
|
||||
];
|
||||
@endphp
|
||||
<nav class="flex-1 space-y-0.5 overflow-y-auto px-3 py-4">
|
||||
@foreach($main as $item)
|
||||
<a href="{{ $item['route'] }}" class="group flex items-center gap-3 rounded-lg px-3 py-2 text-[13px] transition {{ $item['active'] ? 'bg-indigo-50 text-indigo-700 font-semibold' : 'text-slate-600 hover:bg-slate-50 hover:text-slate-900' }}">
|
||||
<svg class="h-[18px] w-[18px] shrink-0 {{ $item['active'] ? 'text-indigo-600' : 'text-slate-400' }}" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">{!! $item['icon'] !!}</svg>
|
||||
<a href="{{ $item['route'] }}" class="group flex items-center gap-3 rounded-lg px-3 py-2 text-[13px] transition {{ $item['active'] ? 'bg-emerald-50 text-emerald-700 font-semibold' : 'text-slate-600 hover:bg-slate-50 hover:text-slate-900' }}">
|
||||
<svg class="h-[18px] w-[18px] shrink-0 {{ $item['active'] ? 'text-emerald-600' : 'text-slate-400' }}" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">{!! $item['icon'] !!}</svg>
|
||||
<span>{{ $item['name'] }}</span>
|
||||
</a>
|
||||
@endforeach
|
||||
</nav>
|
||||
|
||||
<div class="shrink-0 border-t border-slate-100 px-3 py-3">
|
||||
<a href="{{ route('account.settings') }}"
|
||||
class="group flex items-center gap-3 rounded-lg px-3 py-2 text-[13px] transition {{ request()->routeIs('account.settings') ? 'bg-indigo-50 text-indigo-700 font-semibold' : 'text-slate-600 hover:bg-slate-50 hover:text-slate-900' }}">
|
||||
<svg class="h-[18px] w-[18px] shrink-0 {{ request()->routeIs('account.settings') ? 'text-indigo-600' : 'text-slate-400' }}" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M9.594 3.94c.09-.542.56-.94 1.11-.94h2.593c.55 0 1.02.398 1.11.94l.213 1.281c.063.374.313.686.645.87.074.04.147.083.22.127.325.196.72.257 1.075.124l1.217-.456a1.125 1.125 0 0 1 1.37.49l1.296 2.247a1.125 1.125 0 0 1-.26 1.431l-1.003.827c-.293.241-.438.613-.43.992a7.723 7.723 0 0 1 0 .255c-.008.378.137.75.43.991l1.004.827c.424.35.534.955.26 1.43l-1.298 2.247a1.125 1.125 0 0 1-1.369.491l-1.217-.456c-.355-.133-.75-.072-1.076.124a6.47 6.47 0 0 1-.22.128c-.331.183-.581.495-.644.869l-.213 1.281c-.09.543-.56.94-1.11.94h-2.594c-.55 0-1.019-.398-1.11-.94l-.213-1.281c-.062-.374-.312-.686-.644-.87a6.52 6.52 0 0 1-.22-.127c-.325-.196-.72-.257-1.076-.124l-1.217.456a1.125 1.125 0 0 1-1.369-.49l-1.297-2.247a1.125 1.125 0 0 1 .26-1.431l1.004-.827c.292-.241.437-.613.43-.992a6.932 6.932 0 0 1 0-.255c.007-.378-.138-.75-.43-.991l-1.004-.827a1.125 1.125 0 0 1-.26-1.43l1.297-2.247a1.125 1.125 0 0 1 1.37-.491l1.216.456c.356.133.751.072 1.076-.124.072-.044.146-.086.22-.128.332-.183.582-.495.644-.869l.214-1.281Z" /><path stroke-linecap="round" stroke-linejoin="round" d="M15 12a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z" />
|
||||
</svg>
|
||||
<span class="flex-1 truncate">Settings</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user