@extends('admin.layout') @section('title', 'Dashboard') @section('content') @php use Illuminate\Support\Str; $max = max(1, max(array_column($series, 'n'))); $chartTotal = array_sum(array_column($series, 'n')); $trend = $counts['previous30'] ? (int) round(100 * ($counts['submissions30'] - $counts['previous30']) / $counts['previous30']) : null; // sparkline of the last 14 days $smax = max(1, max($spark)); $sparkPts = collect($spark)->map(fn ($n, $i) => round($i * (100 / 13), 1).','.round(28 - ($n / $smax) * 24, 1))->implode(' '); $ranges = [30 => '30 days', 90 => '90 days', 365 => '12 months']; $okChecks = collect($checks)->filter(fn ($c) => $c[1])->count(); $circ = 2 * M_PI * 34; $scoreColor = $seo['score'] >= 85 ? 'var(--ok)' : ($seo['score'] >= 60 ? 'var(--accent-dark)' : 'var(--err)'); @endphp

{{ now()->format('l, j F Y') }}

{{ $greeting }}, {{ Str::before(auth()->user()->name, ' ') }} 👋

@if ($counts['unread']) You have {{ $counts['unread'] }} unread {{ Str::plural('enquiry', $counts['unread']) }} waiting. @else All enquiries are read. Nice work! @endif

@include('admin._icon', ['i' => 'plus'])New post @include('admin._icon', ['i' => 'file'])Pages @include('admin._icon', ['i' => 'upload'])Upload media @include('admin._icon', ['i' => 'globe'])View website
@include('admin._icon', ['i' => 'inbox']) Enquiries · 30 days {{ $counts['submissions30'] }} @if ($trend !== null) $trend >= 0, 'down' => $trend < 0])>@include('admin._icon', ['i' => $trend >= 0 ? 'up' : 'down', 'class' => 'i-xs']){{ abs($trend) }}% vs previous 30 days @endif @include('admin._icon', ['i' => 'mail']) Unread enquiries $counts['unread'] > 0])>{{ $counts['unread'] }} {{ $counts['unread'] ? 'Open the inbox →' : 'Inbox zero' }} @include('admin._icon', ['i' => 'news']) Posts & news {{ $counts['posts'] }} {{ $counts['postsMonth'] }} published in the last 30 days @include('admin._icon', ['i' => 'eye']) Post views (all time) {{ number_format($counts['views']) }} {{ $counts['pages'] }} pages · {{ $counts['drafts'] }} {{ Str::plural('draft', $counts['drafts']) }} @include('admin._icon', ['i' => 'image']) Media files {{ number_format($counts['media']) }} Images, PDFs & videos

Enquiries

Form submissions per {{ $range === 365 ? 'month, last 12 months' : 'day, last '.$range.' days' }} · click a bar to see them

@foreach ($ranges as $r => $label) $range === $r])>{{ $label }} @endforeach
{{ $chartTotal }}total
{{ $max }}{{ $max >= 2 ? (int) round($max / 2) : '' }}0
@foreach ($series as $i => $d) @endforeach
{{ $series[0]['short'] }}{{ $series[intdiv(count($series), 2)]['short'] }}{{ $range === 365 ? 'This month' : 'Today' }}
@if ($byForm->isNotEmpty())
@php($fmax = max(1, $byForm->max())) @foreach ($byForm as $name => $n)
{{ $name ?: 'Form' }}{{ $n }}
@endforeach
@endif

SEO health

Published pages with a meta description

{{ $seo['score'] }}%

{{ $seo['live'] - $seo['missing'] }} of {{ $seo['live'] }} pages are ready for Google.

@if ($seo['list']->isNotEmpty()) @if ($seo['missing'] > $seo['list']->count())

and {{ $seo['missing'] - $seo['list']->count() }} more

@endif @endif

Setup checklist

{{ $okChecks }}/{{ count($checks) }}

Unpublished visual-editor changes

@if ($drafts->isEmpty())
@include('admin._icon', ['i' => 'sparkles'])

Everything is published.

Changes made in the visual editor wait here until you press Update.
@else @endif
@php($vmax = max(1, $topPosts->max('views')))
@include('admin._icon', ['i' => 'wand'])
Visual editor

Click any text, image or button on the page and edit it in place — like Elementor. Drag widgets in from the panel.

@include('admin._icon', ['i' => 'command'])
Find anything fast

Press Ctrl K to search pages, posts, enquiries and media, or jump to any screen.

@include('admin._icon', ['i' => 'shield'])
Safe to experiment

Visual-editor changes stay a draft until you press Update, and every update keeps a version you can restore.

@endsection