Demo Mode: you're exploring a live BackupMGR panel with sample data. Everything is read-only. Get BackupMGR →

License Key Required

No license key entered. Enter or update your key with php artisan realestate:license <key>, or purchase one at scriptgain.com.

Dashboard

admin.dashboard

Status Shipped Default Shipped File resources/views/admin/dashboard.blade.php
admin.dashboard 184 lines
Not Checked Yet

Optional. Shown in the version history so the next person knows why.

Saving runs the same check. An invalid template is refused, not stored.

Compiled PHP

What Blade turns your template into. This is what the syntax check parses.

Loading…

Available Variables And Components

A guide to what this template can use, derived from the shipped source. Click any item to insert it at your cursor. It is a helpful reference, not a runtime guarantee.

Always Available

Shared with the admin panel by the staff layout.
Validation error bag. Always present. Pairs with @error('field').
The admin sidebar navigation structure.
Sub-items of the currently open nav group.
Breadcrumb trail for the current page.
Signed-in staffer's initials, for the avatar.
Signed-in staffer's name.
Signed-in staffer's email address.
The staffer's role, e.g. "Administrator".
True when the signed-in staffer is an administrator.
Number of open service requests, for the badge.
Number of unread form submissions, for the badge.
The configured admin-shell width class.
URL of the uploaded site logo, or null.
URL of the uploaded favicon, or null.

In This Template

Activity.
Attention.
Content.
The current emergency alert, or null when none is live.
Recent Requests.
Stats.
Upcoming Events.
Upcoming Meetings.

Drop any of these in. Click to insert the opening tag at your cursor.

General

type, info, title
initials, src, name, size, md
color, neutral, dot
action, label, Record, modal
variant, primary, size, md, href, …
title, subtitle, padding, flush
name, action, method, POST, title, …
action, name, title, message, confirm, …
href, icon, danger
align, right, width
icon, folder, title, description
label, for, hint, error, required
href, icon, title, variant, secondary, …
name
type, text
name, title, subtitle, icon, tone, …
href, icon, active
title, subtitle, icon, back
title, subtitle, href, linkLabel
ids
id, label, Row
items
label, value, icon, trend, trendColor, …
color, neutral, pulse, label
name
flush
tabs, default
name, checked, label, description

Admin Panel

title, message, icon, folder, href, …
tree, active, rootLabel, rootHref
title, subtitle, icon, edit, action, …
title, icon, folder, subtitle, records, …
search, placeholder, createHref, createLabel
edit, delete, preview, name, title, …
record, kind, Page

Layouts

title, shellMaxWidth
title, description, heroless, maxWidth

Records

name, action, reference, trigger, icon

Site (Public)

href, title, description, icon, meta, …
title, message, icon, folder
title, subtitle, eyebrow, icon, crumbs, …
supportEmail, supportPhone
disclaimer, takedownContact, retentionDays, compact
title, subtitle, href, linkLabel, tone, …
maxWidth

Common Blade

Print a value, safely escaped. The default choice.
Print raw HTML. Only for content you trust.
Show something conditionally.
Loop over a collection.
Loop, with a fallback when the collection is empty.
Show a validation message for a field.
A small block of PHP. Never on line 1. Keep logic out of templates.
A comment that never reaches the browser.

Civic Helpers

Build a URL to a named route, e.g. a department page.
Link to a single news post.
Turn a stored upload path into a public URL.
A cache-busted URL for a bundled asset.
Read a config value, e.g. the site width class.
Build an absolute URL to a path.

No History Yet

Every save, revert, and reset of this template is recorded here, with a one-click way back to any of them.

The Template That Shipped With The Product

Read only. This is what Reset To Default puts back.

<x-layouts.app title="Dashboard">
    <x-page-header title="Staff Dashboard" icon="dashboard"
                   subtitle="What needs attention, what goes public next, and what residents just sent in.">
        <x-slot:actions>
            <x-button variant="secondary" icon="globe" href="{{ route('site.home') }}" target="_blank" rel="noopener">View Public Site</x-button>
            <x-button icon="plus" href="{{ route('news.create') }}">Post An Announcement</x-button>
        </x-slot:actions>
    </x-page-header>

    @if ($liveAlert)
        <div class="mb-6 rounded-xl bg-amber-50 px-5 py-4 ring-1 ring-amber-200">
            <div class="flex items-start gap-3">
                <x-icon name="bolt" class="mt-0.5 w-5 h-5 shrink-0 text-amber-600" />
                <div class="min-w-0 flex-1">
                    <p class="font-semibold text-amber-900">An Alert Banner Is Live On The Public Site</p>
                    <p class="mt-0.5 text-sm text-amber-800">{{ $liveAlert->title }}</p>
                </div>
                <x-button variant="secondary" size="sm" :href="route('alerts.edit', $liveAlert)">Manage Alert</x-button>
            </div>
        </div>
    @endif

    {{-- Attention row --}}
    <div class="grid gap-4 sm:grid-cols-2 lg:grid-cols-4">
        <x-stat label="Open Service Requests" :value="$stats['open_requests']" icon="bolt"
                :href="route('service-requests.index')" />
        <x-stat label="Unassigned Requests" :value="$stats['unassigned_requests']" icon="warning"
                :href="route('service-requests.index')" />
        <x-stat label="Open Over A Week" :value="$stats['overdue_requests']" icon="clock"
                :href="route('service-requests.index')" />
        <x-stat label="Unread Form Submissions" :value="$stats['unread_submissions']" icon="clipboard"
                :href="route('forms.index')" />
    </div>

    <div class="section-divider my-8"></div>

    {{-- Tabs keep the dashboard to one screen instead of a long scroll. --}}
    <x-tabs :tabs="[
        'attention' => ['label' => 'Needs Attention', 'icon' => 'warning'],
        'requests' => ['label' => 'Recent Requests', 'icon' => 'bolt', 'count' => $recentRequests->count()],
        'upcoming' => ['label' => 'Coming Up', 'icon' => 'clock'],
        'content' => ['label' => 'Content Overview', 'icon' => 'book'],
    ]">
        <x-tab-panel name="attention">
            <div class="grid gap-4 sm:grid-cols-2">
                <x-card title="Postings About To Lapse">
                    <ul class="divide-y divide-slate-100 text-sm">
                        <li class="flex items-center justify-between gap-3 py-3">
                            <span class="text-slate-600">Notices Expiring Within 7 Days</span>
                            <a href="{{ route('notices.index') }}" class="font-semibold text-brand-700 tabular hover:underline">{{ $attention['expiring_notices'] }}</a>
                        </li>
                        <li class="flex items-center justify-between gap-3 py-3">
                            <span class="text-slate-600">Bids Closing Within 7 Days</span>
                            <a href="{{ route('bids.index') }}" class="font-semibold text-brand-700 tabular hover:underline">{{ $attention['closing_bids'] }}</a>
                        </li>
                        <li class="flex items-center justify-between gap-3 py-3">
                            <span class="text-slate-600">Job Postings Closing Within 7 Days</span>
                            <a href="{{ route('jobs.index') }}" class="font-semibold text-brand-700 tabular hover:underline">{{ $attention['closing_jobs'] }}</a>
                        </li>
                    </ul>
                </x-card>

                <x-card title="Public Records Gaps">
                    <div class="flex items-start gap-3 rounded-lg bg-slate-50 px-4 py-3">
                        <x-icon name="clock" class="mt-0.5 w-5 h-5 shrink-0 text-slate-400" />
                        <div class="min-w-0">
                            <p class="text-sm font-medium text-slate-900">
                                {{ $attention['meetings_missing_minutes'] }} Recent Meeting(s) Have No Minutes Posted
                            </p>
                            <p class="mt-1 text-sm text-slate-500">
                                Minutes are a public record. Posting them promptly is the single easiest
                                transparency win a municipality has.
                            </p>
                            <a href="{{ route('meetings.index') }}" class="mt-2 inline-flex items-center gap-1.5 text-sm font-semibold text-brand-700 hover:underline">
                                Review Meetings <x-icon name="chevron-right" class="w-4 h-4" />
                            </a>
                        </div>
                    </div>
                </x-card>
            </div>
        </x-tab-panel>

        <x-tab-panel name="requests">
            <x-card title="Recently Reported Issues" flush>
                @if ($recentRequests->count())
                    <x-table flush>
                        <thead>
                            <tr>
                                <th>Reference</th>
                                <th>Category</th>
                                <th>Department</th>
                                <th>Status</th>
                                <th>Received</th>
                                <th class="text-right">Actions</th>
                            </tr>
                        </thead>
                        <tbody>
                            @foreach ($recentRequests as $request)
                                <tr>
                                    <td class="font-medium text-slate-900 tabular">{{ $request->reference }}</td>
                                    <td>{{ $request->category }}</td>
                                    <td>{{ $request->department?->name ?? 'Unassigned' }}</td>
                                    <td><x-badge :color="$request->statusColor()" dot>{{ $request->statusLabel() }}</x-badge></td>
                                    <td class="text-slate-500">{{ $request->created_at->diffForHumans() }}</td>
                                    <td class="text-right">
                                        <x-button size="sm" variant="secondary" :href="route('service-requests.show', $request)">Open</x-button>
                                    </td>
                                </tr>
                            @endforeach
                        </tbody>
                    </x-table>
                @else
                    <x-admin.empty title="No Requests Yet" icon="bolt"
                                   message="Reports submitted from the public Report An Issue form appear here." />
                @endif
            </x-card>
        </x-tab-panel>

        <x-tab-panel name="upcoming">
            <div class="grid gap-4 lg:grid-cols-2">
                <x-card title="Upcoming Meetings" flush>
                    @if ($upcomingMeetings->count())
                        <ul class="divide-y divide-slate-100">
                            @foreach ($upcomingMeetings as $meeting)
                                <li class="flex items-center justify-between gap-4 px-5 py-3.5">
                                    <div class="min-w-0">
                                        <p class="truncate text-sm font-medium text-slate-900">{{ $meeting->displayTitle() }}</p>
                                        <p class="text-xs text-slate-500">{{ $meeting->meets_at->format(config('realestate.date_format') . ', ' . config('realestate.time_format')) }}</p>
                                    </div>
                                    @if ($meeting->agenda)
                                        <x-badge color="success" class="shrink-0">Agenda Posted</x-badge>
                                    @else
                                        <x-badge color="warn" class="shrink-0">No Agenda</x-badge>
                                    @endif
                                </li>
                            @endforeach
                        </ul>
                    @else
                        <x-admin.empty title="No Meetings Scheduled" icon="clock" :href="route('meetings.create')" label="Schedule A Meeting" />
                    @endif
                </x-card>

                <x-card title="Upcoming Events" flush>
                    @if ($upcomingEvents->count())
                        <ul class="divide-y divide-slate-100">
                            @foreach ($upcomingEvents as $event)
                                <li class="px-5 py-3.5">
                                    <p class="truncate text-sm font-medium text-slate-900">{{ $event->title }}</p>
                                    <p class="text-xs text-slate-500">{{ $event->whenDisplay() }}</p>
                                </li>
                            @endforeach
                        </ul>
                    @else
                        <x-admin.empty title="No Events Scheduled" icon="clock" :href="route('events.create')" label="Add An Event" />
                    @endif
                </x-card>
            </div>
        </x-tab-panel>

        <x-tab-panel name="content">
            <div class="grid gap-4 sm:grid-cols-2 lg:grid-cols-4">
                <x-stat label="Published Pages" :value="$content['pages']" icon="book" :href="route('pages.index')" />
                <x-stat label="Draft Pages" :value="$content['drafts']" icon="edit" :href="route('pages.index')" />
                <x-stat label="Published Documents" :value="$content['documents']" icon="archive" :href="route('files.index')" />
                <x-stat label="Published News Posts" :value="$content['news']" icon="bell" :href="route('news.index')" />
            </div>

            <div class="mt-6">
                <x-card title="Service Request Volume" subtitle="Reports received over the last fourteen days.">
                    <div class="flex items-end gap-1.5" role="img" aria-label="Bar chart of service requests received over the last fourteen days">
                        @foreach ($activity as $day)
                            <div class="flex-1" data-tip="{{ $day['label'] }}: {{ $day['total'] }} received, {{ $day['resolved'] }} resolved">
                                <div class="mx-auto w-full rounded-t bg-brand-500/80"
                                     style="height: {{ max(4, $day['total'] * 12) }}px"></div>
                                <p class="mt-1.5 text-center text-[10px] text-slate-400">{{ $day['label'] }}</p>
                            </div>
                        @endforeach
                    </div>
                </x-card>
            </div>
        </x-tab-panel>
    </x-tabs>
</x-layouts.app>

Blade In One Screen

The directives you will use most.

{{ $variable }}
Print a value, escaped. Safe by default.
{!! $html !!}
Print raw HTML. Only for content you trust.
@if / @else / @endif
Show something conditionally.
@foreach / @endforeach
Loop over a collection.
<x-card>
Use a shared component. Every component in Shared Components is available.
{{-- comment --}}
A comment that never reaches the browser.

House Rules

Follow these and your edits will survive updates.

  • Never start line 1 with @php. Blade mis-parses it and the page fails. The editor refuses to save it.
  • Keep logic out of templates. If you need a calculation, it belongs in a composer or component class, not here.
  • The shipped file is never modified. Reset To Default always gets you back.
  • Every save is versioned. You can revert to any earlier version in one click.
  • Press Tab inside the editor to indent rather than jump to the next field.