From 8854604593ef16d70f95df4828b3928089546f56 Mon Sep 17 00:00:00 2001 From: Mark Gregory Date: Tue, 20 Oct 2026 10:40:24 +0100 Subject: [PATCH] added theme support --- .../views/admin/cms/form.blade.php | 24 ++ .../views/admin/cms/index.blade.php | 9 + .../admin/download-products/index.blade.php | 15 + .../views/admin/index.blade.php | 6 + .../views/admin/license.blade.php | 1 + .../views/admin/licenses.blade.php | 1 + .../views/admin/releases/form.blade.php | 9 + .../views/admin/releases/index.blade.php | 7 + .../views/admin/releases/settings.blade.php | 5 + .../views/admin/seo/edit.blade.php | 39 +++ .../views/admin/support/index.blade.php | 24 ++ .../views/admin/support/show.blade.php | 14 + .../views/admin/users/index.blade.php | 31 ++ .../views/admin/users/show.blade.php | 57 ++++ .../views/auth/forgot-password.blade.php | 1 + .../views/auth/login.blade.php | 1 + .../views/auth/register.blade.php | 1 + .../views/auth/reset-password.blade.php | 1 + .../views/auth/verify-email.blade.php | 1 + .../views/auth/forgot-password.blade.php | 1 + .../sonardesk/views/auth/login.blade.php | 1 + .../sonardesk/views/auth/register.blade.php | 1 + .../views/auth/reset-password.blade.php | 1 + .../views/auth/verify-email.blade.php | 1 + .../sonardesk/views/checkout/buy.blade.php | 301 ++++++++++++++++++ .../themes/sonardesk/views/cms/show.blade.php | 14 + .../views/downloads/appcast.blade.php | 2 + .../sonardesk/views/downloads/index.blade.php | 18 ++ .../views/downloads/product.blade.php | 13 + .../views/downloads/sonardesk.blade.php | 4 + .../themes/sonardesk/views/features.blade.php | 15 + .../sonardesk/views/legal/cookies.blade.php | 16 + .../sonardesk/views/legal/privacy.blade.php | 39 +++ .../sonardesk/views/legal/refund.blade.php | 102 ++++++ .../sonardesk/views/legal/terms.blade.php | 146 +++++++++ .../sonardesk/views/portal/index.blade.php | 114 +++++++ .../sonardesk/views/portal/show.blade.php | 81 +++++ .../themes/sonardesk/views/release.blade.php | 16 + .../sonardesk/views/seo/sitemap.blade.php | 18 ++ .../themes/sonardesk/views/support.blade.php | 100 ++++++ .../themes/sonardesk/views/welcome.blade.php | 223 +++++++++++++ 41 files changed, 1474 insertions(+) create mode 100644 resources/themes/sonardesk-admin/views/admin/cms/form.blade.php create mode 100644 resources/themes/sonardesk-admin/views/admin/cms/index.blade.php create mode 100644 resources/themes/sonardesk-admin/views/admin/download-products/index.blade.php create mode 100755 resources/themes/sonardesk-admin/views/admin/index.blade.php create mode 100755 resources/themes/sonardesk-admin/views/admin/license.blade.php create mode 100755 resources/themes/sonardesk-admin/views/admin/licenses.blade.php create mode 100644 resources/themes/sonardesk-admin/views/admin/releases/form.blade.php create mode 100644 resources/themes/sonardesk-admin/views/admin/releases/index.blade.php create mode 100644 resources/themes/sonardesk-admin/views/admin/releases/settings.blade.php create mode 100644 resources/themes/sonardesk-admin/views/admin/seo/edit.blade.php create mode 100755 resources/themes/sonardesk-admin/views/admin/support/index.blade.php create mode 100755 resources/themes/sonardesk-admin/views/admin/support/show.blade.php create mode 100644 resources/themes/sonardesk-admin/views/admin/users/index.blade.php create mode 100644 resources/themes/sonardesk-admin/views/admin/users/show.blade.php create mode 100755 resources/themes/sonardesk-admin/views/auth/forgot-password.blade.php create mode 100755 resources/themes/sonardesk-admin/views/auth/login.blade.php create mode 100755 resources/themes/sonardesk-admin/views/auth/register.blade.php create mode 100755 resources/themes/sonardesk-admin/views/auth/reset-password.blade.php create mode 100755 resources/themes/sonardesk-admin/views/auth/verify-email.blade.php create mode 100755 resources/themes/sonardesk/views/auth/forgot-password.blade.php create mode 100755 resources/themes/sonardesk/views/auth/login.blade.php create mode 100755 resources/themes/sonardesk/views/auth/register.blade.php create mode 100755 resources/themes/sonardesk/views/auth/reset-password.blade.php create mode 100755 resources/themes/sonardesk/views/auth/verify-email.blade.php create mode 100755 resources/themes/sonardesk/views/checkout/buy.blade.php create mode 100644 resources/themes/sonardesk/views/cms/show.blade.php create mode 100644 resources/themes/sonardesk/views/downloads/appcast.blade.php create mode 100644 resources/themes/sonardesk/views/downloads/index.blade.php create mode 100644 resources/themes/sonardesk/views/downloads/product.blade.php create mode 100644 resources/themes/sonardesk/views/downloads/sonardesk.blade.php create mode 100644 resources/themes/sonardesk/views/features.blade.php create mode 100755 resources/themes/sonardesk/views/legal/cookies.blade.php create mode 100755 resources/themes/sonardesk/views/legal/privacy.blade.php create mode 100644 resources/themes/sonardesk/views/legal/refund.blade.php create mode 100755 resources/themes/sonardesk/views/legal/terms.blade.php create mode 100755 resources/themes/sonardesk/views/portal/index.blade.php create mode 100755 resources/themes/sonardesk/views/portal/show.blade.php create mode 100644 resources/themes/sonardesk/views/release.blade.php create mode 100644 resources/themes/sonardesk/views/seo/sitemap.blade.php create mode 100755 resources/themes/sonardesk/views/support.blade.php create mode 100755 resources/themes/sonardesk/views/welcome.blade.php diff --git a/resources/themes/sonardesk-admin/views/admin/cms/form.blade.php b/resources/themes/sonardesk-admin/views/admin/cms/form.blade.php new file mode 100644 index 0000000..9df446c --- /dev/null +++ b/resources/themes/sonardesk-admin/views/admin/cms/form.blade.php @@ -0,0 +1,24 @@ +@extends('layouts.app') +@section('content') +
CMS

{{ $page->exists ? 'Edit page' : 'New page' }}

Back to pages
+
@csrf @if($page->exists) @method('PUT') @endif + + + + +
+
Search appearance

Page SEO

Override global defaults only where this page needs specific search or social metadata.

Global SEO settings
+
+ + +
+ +
+
+ +
+ +
@if($page->exists && $page->is_published)View page@endif
+
+@if($page->exists)
@csrf @method('DELETE')
@endif +@endsection diff --git a/resources/themes/sonardesk-admin/views/admin/cms/index.blade.php b/resources/themes/sonardesk-admin/views/admin/cms/index.blade.php new file mode 100644 index 0000000..52037c8 --- /dev/null +++ b/resources/themes/sonardesk-admin/views/admin/cms/index.blade.php @@ -0,0 +1,9 @@ +@extends('layouts.app') +@section('content') +
CMS

Content pages

Manage SonarDesk website content.

New page
+
{{ $pages->links() }}
+@endsection diff --git a/resources/themes/sonardesk-admin/views/admin/download-products/index.blade.php b/resources/themes/sonardesk-admin/views/admin/download-products/index.blade.php new file mode 100644 index 0000000..6740f7f --- /dev/null +++ b/resources/themes/sonardesk-admin/views/admin/download-products/index.blade.php @@ -0,0 +1,15 @@ +@extends('layouts.app', ['title' => 'Download products — Admin']) +@section('content') +
+
Distribution / Product management

Download products

Manage installers, releases and publication status in one place.

+ @if(session('status'))
{{ session('status') }}
@endif + @if($errors->any())@endif +
Total products{{ $products->count() }}
Published{{ $products->where('is_published', true)->count() }}
Drafts{{ $products->where('is_published', false)->count() }}
Total downloads{{ number_format($products->sum('download_count')) }}
+

Product catalogue

Publish or unpublish products instantly, or edit their details.

+ @forelse($products as $product) + @empty@endforelse +
ProductVersion / PlatformDownloadsStatusActions
{{ $product->name }}{{ \Illuminate\Support\Str::limit($product->description ?: $product->original_filename, 70) }}{{ $product->version ?: '—' }}{{ $product->platform ?: 'Unspecified' }} · {{ $product->formatted_size }}{{ number_format($product->download_count) }}{{ $product->is_published ? 'Published' : 'Draft' }}
@csrf @method('PATCH')
No additional products yet. Add your first installer below.
+
any() && !old('_method')) open @endif>Add a new productUpload an installer and choose whether to publish it.+
@csrf
+ @foreach($products as $product)
Edit {{ $product->name }}{{ $product->original_filename }} · {{ $product->formatted_size }}+
@csrf @method('PUT')
@csrf @method('DELETE')
@endforeach +
+@endsection diff --git a/resources/themes/sonardesk-admin/views/admin/index.blade.php b/resources/themes/sonardesk-admin/views/admin/index.blade.php new file mode 100755 index 0000000..29bdf82 --- /dev/null +++ b/resources/themes/sonardesk-admin/views/admin/index.blade.php @@ -0,0 +1,6 @@ +@extends('layouts.app') +@section('content') +
Admin

Licensing administration

Manage licences, activations and customer support.

+
{{ $licenseCount ?? '—' }}

Licences

{{ $activeCount ?? '—' }}

Not revoked

{{ $activationCount ?? '—' }}

Active installations

{{ $userCount ?? '—' }}

Portal users

+
Manage releasesManage licencesManage usersManage contentManage themesSEO & searchSupport inbox
+@endsection diff --git a/resources/themes/sonardesk-admin/views/admin/license.blade.php b/resources/themes/sonardesk-admin/views/admin/license.blade.php new file mode 100755 index 0000000..9a2ac70 --- /dev/null +++ b/resources/themes/sonardesk-admin/views/admin/license.blade.php @@ -0,0 +1 @@ +@extends('layouts.app') @section('content')

Licence •••• {{ $license->license_key_last4 }}

{{ $license->customer_name }} · {{ $license->customer_email }}

{{ $license->edition }} · {{ $license->activation_limit }} seats

@if($license->revoked_at)
@csrf
@else
@csrf
@endif

Activations

@foreach($license->activations as $a)@endforeach
IDPlatformVersionStatus
{{ $a->installation_name ?: $a->installation_id }}{{ $a->platform }}{{ $a->app_version }}{{ $a->deactivated_at ? 'Released':'Active' }}
@endsection diff --git a/resources/themes/sonardesk-admin/views/admin/licenses.blade.php b/resources/themes/sonardesk-admin/views/admin/licenses.blade.php new file mode 100755 index 0000000..8ff6b69 --- /dev/null +++ b/resources/themes/sonardesk-admin/views/admin/licenses.blade.php @@ -0,0 +1 @@ +@extends('layouts.app') @section('content')

Licences

@foreach($licenses as $l)@endforeach
CustomerEditionKeyStatus
{{ $l->customer_email ?: 'Manual' }}{{ $l->edition }}•••• {{ $l->license_key_last4 }}{{ $l->revoked_at ? 'Revoked':'Active' }}
{{ $licenses->links() }}
@endsection diff --git a/resources/themes/sonardesk-admin/views/admin/releases/form.blade.php b/resources/themes/sonardesk-admin/views/admin/releases/form.blade.php new file mode 100644 index 0000000..458dc97 --- /dev/null +++ b/resources/themes/sonardesk-admin/views/admin/releases/form.blade.php @@ -0,0 +1,9 @@ +@extends('layouts.app', ['title' => ($release->exists ? 'Edit release' : 'New release').' — SonarDesk Admin']) +@section('content') +
Distribution

{{ $release->exists ? 'Edit SonarDesk '.$release->version : 'Create a release' }}

Upload the notarized distribution package and control exactly when it becomes public.

Back to releases
+
@csrf @if($release->exists) @method('PUT') @endif +
01

Release identity

Version and compatibility information shown to customers.

+
02

Distribution package

DMG or ZIP. SHA-256 is calculated automatically after upload.

@if($release->file_path)
{{ $release->original_filename }}{{ $release->formatted_size }} · SHA-256 {{ $release->sha256 }}
@endif
+
03

Release notes

Professional customer-facing notes. Plain text is rendered safely with line breaks.

+
+@endsection diff --git a/resources/themes/sonardesk-admin/views/admin/releases/index.blade.php b/resources/themes/sonardesk-admin/views/admin/releases/index.blade.php new file mode 100644 index 0000000..a8caa71 --- /dev/null +++ b/resources/themes/sonardesk-admin/views/admin/releases/index.blade.php @@ -0,0 +1,7 @@ +@extends('layouts.app', ['title' => 'Releases — SonarDesk Admin']) +@section('content') +
Distribution

Release management

Publish SonarDesk builds, manage the public download experience and keep Sparkle updates under control.

+
{{ $releases->total() }}

Total releases

{{ $publishedCount }}

Published

{{ number_format($downloadCount) }}

Total downloads

Live

Sparkle feed

+

SonarDesk builds

Only published builds with an uploaded package are available publicly.

View public page
@forelse($releases as $release)@empty@endforelse
ReleaseChannelStatusPackageDownloadsPublished
SonarDesk {{ $release->version }}Build {{ $release->build_number }} · macOS {{ $release->minimum_macos ?: 'Any supported' }}{{ ucfirst($release->channel) }}@if($release->is_published)Published@elseDraft@endif{{ $release->file_path ? $release->formatted_size : 'No package' }}{{ number_format($release->download_count) }}{{ $release->published_at?->format('j M Y H:i') ?: '—' }}Edit
@csrf @method('DELETE')
No releases yet. Create your first signed SonarDesk build.
+{{ $releases->links() }} +@endsection diff --git a/resources/themes/sonardesk-admin/views/admin/releases/settings.blade.php b/resources/themes/sonardesk-admin/views/admin/releases/settings.blade.php new file mode 100644 index 0000000..bddc7ac --- /dev/null +++ b/resources/themes/sonardesk-admin/views/admin/releases/settings.blade.php @@ -0,0 +1,5 @@ +@extends('layouts.app', ['title' => 'Download page — SonarDesk Admin']) +@section('content') +
Website

Download page content

Control the customer-facing download area without editing a template or deploying code.

Back to releases
+
@csrf @method('PUT')
Preview page
+@endsection diff --git a/resources/themes/sonardesk-admin/views/admin/seo/edit.blade.php b/resources/themes/sonardesk-admin/views/admin/seo/edit.blade.php new file mode 100644 index 0000000..67fcb35 --- /dev/null +++ b/resources/themes/sonardesk-admin/views/admin/seo/edit.blade.php @@ -0,0 +1,39 @@ +@extends('layouts.app') +@section('content') +
+
Search & discovery

SEO settings

Control how SonarDesk appears in search engines and when pages are shared.

+ +
+
@csrf @method('PUT') +
+
Search appearance

Site defaults

Fallback metadata used whenever a page does not provide its own SEO values.

Global
+
+ + +
+ + + + +
+ +
+
Social sharing

Open Graph & social

Professional defaults for link previews across social networks and messaging applications.

+ +
+ +
+ +
+
Google Search Console

Domain verification

Use a Domain property in Google Search Console. Google will provide a TXT value that you add at your DNS provider.

DNS TXT
+
Recommended verification methodAdd Google’s google-site-verification=… TXT record to the root domain. DNS verification covers all protocols and subdomains.
+ +
+ +
+
Crawler control

Indexing

Production crawler controls. Non-production environments remain blocked automatically.

+ +
+
Search configurationChanges apply to public metadata immediately.
+
+@endsection diff --git a/resources/themes/sonardesk-admin/views/admin/support/index.blade.php b/resources/themes/sonardesk-admin/views/admin/support/index.blade.php new file mode 100755 index 0000000..ae56c8a --- /dev/null +++ b/resources/themes/sonardesk-admin/views/admin/support/index.blade.php @@ -0,0 +1,24 @@ +@extends('layouts.app', ['title' => 'Support Inbox — SonarDesk']) +@section('content') +
Admin

Support inbox

Customer, licence, billing and privacy requests.

+
+ + +
+
+@forelse($tickets as $ticket) + +
{{ $ticket->reference }}{{ $ticket->subject }}{{ $ticket->name }} · {{ $ticket->email }}
+ {{ ucfirst($ticket->category) }} + {{ ucfirst($ticket->status) }} + +
+@empty +

No support requests

The support inbox is empty.

+@endforelse +
+{{ $tickets->links() }} +@endsection diff --git a/resources/themes/sonardesk-admin/views/admin/support/show.blade.php b/resources/themes/sonardesk-admin/views/admin/support/show.blade.php new file mode 100755 index 0000000..4248c64 --- /dev/null +++ b/resources/themes/sonardesk-admin/views/admin/support/show.blade.php @@ -0,0 +1,14 @@ +@extends('layouts.app', ['title' => $ticket->reference.' — Support']) +@section('content') +← Support inbox +
{{ $ticket->reference }}

{{ $ticket->subject }}

{{ $ticket->name }} · {{ $ticket->email }}

{{ ucfirst($ticket->status) }}
+
+

Request

{{ ucfirst($ticket->category) }}{{ $ticket->created_at->format('j M Y H:i') }}
{!! nl2br(e($ticket->message)) !!}
Reply by email
+ +
+@endsection diff --git a/resources/themes/sonardesk-admin/views/admin/users/index.blade.php b/resources/themes/sonardesk-admin/views/admin/users/index.blade.php new file mode 100644 index 0000000..9b6d9ef --- /dev/null +++ b/resources/themes/sonardesk-admin/views/admin/users/index.blade.php @@ -0,0 +1,31 @@ +@extends('layouts.app') +@section('content') +
+
Admin

Users

Manage portal accounts, access and customer licences.

+ Admin dashboard +
+ +
+ + + + @if(request()->hasAny(['q','status']))Clear@endif +
+ +
+

Portal users

{{ $users->total() }} account{{ $users->total() === 1 ? '' : 's' }}

+
+ @forelse($users as $user) + + + + + + + + + @empty@endforelse +
UserAccessEmailLicencesJoined
{{ $user->name }}#{{ $user->id }}@if($user->disabled_at)Suspended@elseif($user->is_admin)Admin@elseActive@endif{{ $user->email }}{{ $user->hasVerifiedEmail() ? 'Verified' : 'Not verified' }}{{ $licenseCounts[strtolower($user->email)] ?? 0 }}{{ $user->created_at?->format('d M Y') }}
No users found.
+
+
{{ $users->links() }}
+@endsection diff --git a/resources/themes/sonardesk-admin/views/admin/users/show.blade.php b/resources/themes/sonardesk-admin/views/admin/users/show.blade.php new file mode 100644 index 0000000..825a9e1 --- /dev/null +++ b/resources/themes/sonardesk-admin/views/admin/users/show.blade.php @@ -0,0 +1,57 @@ +@extends('layouts.app') +@section('content') +
+
Admin · User

{{ $user->name }}

{{ $user->email }}

+ Back to users +
+ +@if($errors->any())
Could not save changes
@endif + +
+
+
+
01

Account details

Edit the portal identity and administrator access.

+
@csrf @method('PUT') +
+ + @if(auth()->user()->is($user))

Your own administrator access is protected.

@endif + +
+
+ +
+
02

Licences

Licences linked to this user's email address.

+ @forelse($licenses as $license) +
+
+
{{ $license->edition }} · •••• {{ $license->license_key_last4 }}{{ $license->subscription_status ?: 'No subscription status' }} · {{ $license->payment_provider ?: 'manual' }}
+ +
+
@csrf @method('PATCH')
+ @if($license->activations->isNotEmpty()) +
+ @foreach($license->activations as $activation)@endforeach +
DevicePlatformVersionStatus
{{ $activation->installation_name ?: $activation->installation_id }}{{ $activation->platform ?: '—' }}{{ $activation->app_version ?: '—' }}{{ $activation->deactivated_at ? 'Released' : 'Active' }}@if(!$activation->deactivated_at)
@csrf @method('DELETE')
@endif
+ @endif +
+ @empty

No licences are linked to this email address.

@endforelse +
+
+ + +
+@endsection diff --git a/resources/themes/sonardesk-admin/views/auth/forgot-password.blade.php b/resources/themes/sonardesk-admin/views/auth/forgot-password.blade.php new file mode 100755 index 0000000..21c04c9 --- /dev/null +++ b/resources/themes/sonardesk-admin/views/auth/forgot-password.blade.php @@ -0,0 +1 @@ +@extends('layouts.app') @section('content')

Reset password

@csrf
@endsection diff --git a/resources/themes/sonardesk-admin/views/auth/login.blade.php b/resources/themes/sonardesk-admin/views/auth/login.blade.php new file mode 100755 index 0000000..0701f4d --- /dev/null +++ b/resources/themes/sonardesk-admin/views/auth/login.blade.php @@ -0,0 +1 @@ +@extends('layouts.app') @section('content')

Sign in

@csrf
Forgot password?
@endsection diff --git a/resources/themes/sonardesk-admin/views/auth/register.blade.php b/resources/themes/sonardesk-admin/views/auth/register.blade.php new file mode 100755 index 0000000..64b5aa0 --- /dev/null +++ b/resources/themes/sonardesk-admin/views/auth/register.blade.php @@ -0,0 +1 @@ +@extends('layouts.app') @section('content')

Create account

Use the same email address used to purchase SonarDesk.

@csrf
@endsection diff --git a/resources/themes/sonardesk-admin/views/auth/reset-password.blade.php b/resources/themes/sonardesk-admin/views/auth/reset-password.blade.php new file mode 100755 index 0000000..d11d1a7 --- /dev/null +++ b/resources/themes/sonardesk-admin/views/auth/reset-password.blade.php @@ -0,0 +1 @@ +@extends('layouts.app') @section('content')

Choose a new password

@csrf
@endsection diff --git a/resources/themes/sonardesk-admin/views/auth/verify-email.blade.php b/resources/themes/sonardesk-admin/views/auth/verify-email.blade.php new file mode 100755 index 0000000..bde6474 --- /dev/null +++ b/resources/themes/sonardesk-admin/views/auth/verify-email.blade.php @@ -0,0 +1 @@ +@extends('layouts.app') @section('content')

Verify your email

For security, licence ownership is only shown after the account email has been verified.

@csrf
@endsection diff --git a/resources/themes/sonardesk/views/auth/forgot-password.blade.php b/resources/themes/sonardesk/views/auth/forgot-password.blade.php new file mode 100755 index 0000000..21c04c9 --- /dev/null +++ b/resources/themes/sonardesk/views/auth/forgot-password.blade.php @@ -0,0 +1 @@ +@extends('layouts.app') @section('content')

Reset password

@csrf
@endsection diff --git a/resources/themes/sonardesk/views/auth/login.blade.php b/resources/themes/sonardesk/views/auth/login.blade.php new file mode 100755 index 0000000..0701f4d --- /dev/null +++ b/resources/themes/sonardesk/views/auth/login.blade.php @@ -0,0 +1 @@ +@extends('layouts.app') @section('content')

Sign in

@csrf
Forgot password?
@endsection diff --git a/resources/themes/sonardesk/views/auth/register.blade.php b/resources/themes/sonardesk/views/auth/register.blade.php new file mode 100755 index 0000000..64b5aa0 --- /dev/null +++ b/resources/themes/sonardesk/views/auth/register.blade.php @@ -0,0 +1 @@ +@extends('layouts.app') @section('content')

Create account

Use the same email address used to purchase SonarDesk.

@csrf
@endsection diff --git a/resources/themes/sonardesk/views/auth/reset-password.blade.php b/resources/themes/sonardesk/views/auth/reset-password.blade.php new file mode 100755 index 0000000..d11d1a7 --- /dev/null +++ b/resources/themes/sonardesk/views/auth/reset-password.blade.php @@ -0,0 +1 @@ +@extends('layouts.app') @section('content')

Choose a new password

@csrf
@endsection diff --git a/resources/themes/sonardesk/views/auth/verify-email.blade.php b/resources/themes/sonardesk/views/auth/verify-email.blade.php new file mode 100755 index 0000000..bde6474 --- /dev/null +++ b/resources/themes/sonardesk/views/auth/verify-email.blade.php @@ -0,0 +1 @@ +@extends('layouts.app') @section('content')

Verify your email

For security, licence ownership is only shown after the account email has been verified.

@csrf
@endsection diff --git a/resources/themes/sonardesk/views/checkout/buy.blade.php b/resources/themes/sonardesk/views/checkout/buy.blade.php new file mode 100755 index 0000000..525fc4c --- /dev/null +++ b/resources/themes/sonardesk/views/checkout/buy.blade.php @@ -0,0 +1,301 @@ +@extends('layouts.app') + +@section('content') +
+ SonarDesk +

Choose your licence

+

+ Every subscription starts with a 7-day free trial. + Cancel before the trial ends and you won't be charged. +

+ + @if($paddleEnvironment === 'sandbox') +
+ Sandbox checkout — no real payment is taken +
+ @endif +
+ +
+ @foreach($plans as $code => $plan) +
+
+
+
+

{{ $plan['name'] }}

+
{{ $plan['billing'] }} billing
+
+ + @if($plan['billing'] === 'Annual') + Best value + @endif +
+ +
+ {{ $plan['display_price'] }} +
+ +
    +
  • 7-day free trial
  • +
  • + {{ $plan['activation_limit'] }} + active Mac{{ $plan['activation_limit'] === 1 ? '' : 's' }} +
  • +
  • Secure online activation
  • +
  • Licence management portal
  • +
+
+ + +
+ @endforeach +
+ + + + + + + + +@endsection diff --git a/resources/themes/sonardesk/views/cms/show.blade.php b/resources/themes/sonardesk/views/cms/show.blade.php new file mode 100644 index 0000000..35da777 --- /dev/null +++ b/resources/themes/sonardesk/views/cms/show.blade.php @@ -0,0 +1,14 @@ +@extends('layouts.app', [ + 'title' => $page->meta_title ?: $page->title.' — '.\App\Models\SiteSetting::valueFor('seo_site_name', 'SonarDesk'), + 'description' => $page->meta_description ?: $page->excerpt, + 'keywords' => $page->meta_keywords, + 'canonical' => $page->canonical_url ?: null, + 'ogTitle' => $page->og_title ?: null, + 'ogDescription' => $page->og_description ?: null, + 'ogImage' => $page->og_image ?: null, + 'robotsIndex' => $page->robots_index, + 'robotsFollow' => $page->robots_follow, +]) +@section('content') + +@endsection diff --git a/resources/themes/sonardesk/views/downloads/appcast.blade.php b/resources/themes/sonardesk/views/downloads/appcast.blade.php new file mode 100644 index 0000000..a7060d9 --- /dev/null +++ b/resources/themes/sonardesk/views/downloads/appcast.blade.php @@ -0,0 +1,2 @@ +@php echo ''; @endphp +SonarDesk Updates{{ route('updates.appcast') }}SonarDesk stable release feed@foreach($releases as $release)SonarDesk {{ $release->version }}{{ $release->published_at?->toRfc2822String() }}{{ $release->build_number }}{{ $release->version }}@if($release->minimum_macos){{ $release->minimum_macos }}@endifrelease_notes ?: 'SonarDesk update')) !!}]]>sparkle_signature) sparkle:edSignature="{{ $release->sparkle_signature }}"@endif />@endforeach diff --git a/resources/themes/sonardesk/views/downloads/index.blade.php b/resources/themes/sonardesk/views/downloads/index.blade.php new file mode 100644 index 0000000..ca4aa38 --- /dev/null +++ b/resources/themes/sonardesk/views/downloads/index.blade.php @@ -0,0 +1,18 @@ +@extends('layouts.app', ['title' => 'Downloads — SonarDesk and developer tools', 'description' => 'Browse SonarDesk and other macOS developer utilities. View release details or download installers.']) +@section('fullbleed') +
+
Software downloads

Downloads

Find the latest releases of SonarDesk and our developer tools. View details, check requirements or download directly.

+
Available software

Product catalogue

All downloads in one place.

+
+@if($latest) +
macOSv{{ $latest->version }}

SonarDesk

{{ \Illuminate\Support\Str::limit(trim(preg_replace('/\s+/', ' ', strip_tags(\Illuminate\Support\Str::markdown($latest->release_notes ?: $settings['intro'], ['html_input'=>'strip','allow_unsafe_links'=>false])))), 175) }}

+@endif +@foreach($products as $product) +
{{ $product->platform ?: 'Software' }}{{ $product->version ? 'v'.$product->version : 'Latest' }}

{{ $product->name }}

{{ \Illuminate\Support\Str::limit(trim(preg_replace('/\s+/', ' ', strip_tags(\Illuminate\Support\Str::markdown($product->description ?: 'Download the latest available package.', ['html_input'=>'strip','allow_unsafe_links'=>false])))), 175) }}

+@endforeach +
+@if(!$latest && $products->isEmpty())

No published downloads are available yet.

@endif +
+@if($releases->isNotEmpty())
SonarDesk archive

Previous SonarDesk versions

Older published installers, grouped separately from current products.

@foreach($releases as $release)
SonarDesk {{ $release->version }}Build {{ $release->build_number }} · {{ ucfirst($release->channel) }} · {{ $release->published_at?->format('j M Y') }}
{{ $release->formatted_size }}Download
@endforeach
{{ $releases->links() }}
@endif +
+@endsection diff --git a/resources/themes/sonardesk/views/downloads/product.blade.php b/resources/themes/sonardesk/views/downloads/product.blade.php new file mode 100644 index 0000000..11903d4 --- /dev/null +++ b/resources/themes/sonardesk/views/downloads/product.blade.php @@ -0,0 +1,13 @@ +@extends('layouts.app', ['title' => $product->name.' — Downloads', 'description' => 'Download '.$product->name.' and read product information and release notes.']) +@section('fullbleed') +
+
+← All downloads +
{{ $product->platform ?: 'Software' }}{{ $product->version ? 'v'.$product->version : 'Latest' }}
+

{{ $product->name }}

+

{{ $product->formatted_size }} · {{ $product->platform ?: 'Software' }}

+Download {{ $product->name }} ↓ +
{!! \Illuminate\Support\Str::markdown($product->description ?: 'Download the latest available package.', ['html_input' => 'strip', 'allow_unsafe_links' => false]) !!}
+Download ↓ +
+@endsection diff --git a/resources/themes/sonardesk/views/downloads/sonardesk.blade.php b/resources/themes/sonardesk/views/downloads/sonardesk.blade.php new file mode 100644 index 0000000..a454983 --- /dev/null +++ b/resources/themes/sonardesk/views/downloads/sonardesk.blade.php @@ -0,0 +1,4 @@ +@extends('layouts.app', ['title' => 'SonarDesk — Details and download', 'description' => 'SonarDesk release notes, system requirements and macOS installer.']) +@section('fullbleed') +
← All downloads
macOSv{{ $latest->version }}

SonarDesk

{{ $settings['intro'] }}

Version {{ $latest->version }} · Build {{ $latest->build_number }} · {{ $latest->formatted_size }} · Released {{ $latest->published_at?->format('j F Y') }}

Download SonarDesk ↓

Release notes

{!! \Illuminate\Support\Str::markdown($latest->release_notes ?: 'Latest maintenance and improvements.', ['html_input'=>'strip','allow_unsafe_links'=>false]) !!}

System requirements

{{ $settings['requirements'] }}

@if($latest->minimum_macos)

Minimum macOS version: {{ $latest->minimum_macos }}

@endif

Installation

  1. Download the signed installer.
  2. Open the DMG and move SonarDesk to Applications.
  3. Launch SonarDesk and activate with your licence.
@if($latest->sha256)
SHA-256 checksum{{ $latest->sha256 }}
@endif
+@endsection diff --git a/resources/themes/sonardesk/views/features.blade.php b/resources/themes/sonardesk/views/features.blade.php new file mode 100644 index 0000000..5602e8a --- /dev/null +++ b/resources/themes/sonardesk/views/features.blade.php @@ -0,0 +1,15 @@ +@extends('layouts.app', ['title' => 'Features — SonarDesk', 'description' => 'Explore SonarDesk features for monitoring SonarQube projects, quality gates, issues and measures from macOS.']) +@section('content') +
Features

A focused desktop companion for SonarQube.

Built around the checks developers make every day: project status, quality gates, issues, security findings and measures.

+
+
Projects

Project dashboard

Keep configured SonarQube projects together and scan project health without opening a collection of browser tabs.

+
Quality

Quality gates and measures

Surface the status and metrics that tell you whether a project needs attention, in a layout designed for quick review.

+
Issues

Bugs, vulnerabilities and code smells

Browse the major SonarQube issue categories, filter the list and open an issue to inspect its details and context.

+
Scale

Server-side pagination

Issue browsing is designed to remain practical on projects with larger result sets by paging data from the server.

+
Connections

Multiple SonarQube servers

Configure the environments you work with and keep them available from the same SonarDesk workspace.

+
Security

macOS Keychain

SonarQube tokens are stored using macOS Keychain rather than being treated as ordinary application preferences.

+
Licensing

Email delivery and self-service portal

After checkout, the licence key is emailed to the customer. The SonarDesk portal can resend the key and manage licence information and Mac activations.

+
Distribution

Built for direct Mac distribution

SonarDesk is distributed directly for macOS, giving the product a focused release and support channel outside the Mac App Store.

+
+
7-day free trial

Try the complete app.

Choose Personal for one active Mac or Professional for up to three.

View pricing
+@endsection diff --git a/resources/themes/sonardesk/views/legal/cookies.blade.php b/resources/themes/sonardesk/views/legal/cookies.blade.php new file mode 100755 index 0000000..06981ab --- /dev/null +++ b/resources/themes/sonardesk/views/legal/cookies.blade.php @@ -0,0 +1,16 @@ +@extends('layouts.app', ['title' => 'Cookie Policy — SonarDesk']) + +@section('content') + +@endsection diff --git a/resources/themes/sonardesk/views/legal/privacy.blade.php b/resources/themes/sonardesk/views/legal/privacy.blade.php new file mode 100755 index 0000000..a19a562 --- /dev/null +++ b/resources/themes/sonardesk/views/legal/privacy.blade.php @@ -0,0 +1,39 @@ +@extends('layouts.app', ['title' => 'Privacy Policy — SonarDesk']) + +@section('content') +@php + $legal = config('sonardesk.legal'); + $retention = config('sonardesk.privacy.support_retention_days', 730); +@endphp + +@endsection diff --git a/resources/themes/sonardesk/views/legal/refund.blade.php b/resources/themes/sonardesk/views/legal/refund.blade.php new file mode 100644 index 0000000..4410517 --- /dev/null +++ b/resources/themes/sonardesk/views/legal/refund.blade.php @@ -0,0 +1,102 @@ +@extends('layouts.app', ['title' => 'Refund Policy — SonarDesk']) + +@section('content') +@php($legal = config('sonardesk.legal')) + +@endsection diff --git a/resources/themes/sonardesk/views/legal/terms.blade.php b/resources/themes/sonardesk/views/legal/terms.blade.php new file mode 100755 index 0000000..45c57de --- /dev/null +++ b/resources/themes/sonardesk/views/legal/terms.blade.php @@ -0,0 +1,146 @@ +@extends('layouts.app', ['title' => 'Terms of Service — SonarDesk']) + +@section('content') +@php($legal = config('sonardesk.legal')) + +@endsection diff --git a/resources/themes/sonardesk/views/portal/index.blade.php b/resources/themes/sonardesk/views/portal/index.blade.php new file mode 100755 index 0000000..5424076 --- /dev/null +++ b/resources/themes/sonardesk/views/portal/index.blade.php @@ -0,0 +1,114 @@ +@extends('layouts.app') + +@section('content') +
Latest SonarDeskNeed the Mac app?Download the latest published, signed release from the SonarDesk distribution centre.
Download SonarDesk
+
+
+ Account +

My licences

+

Manage subscriptions, licence keys and activated Macs.

+
+ Buy another licence +
+ +@php + $activeLicences = $licenses->filter(fn ($license) => $license->is_usable); + $historyLicences = $licenses->reject(fn ($license) => $license->is_usable); +@endphp + +@if($activeLicences->isEmpty()) +
+

No active licences

+

No active SonarDesk licence is associated with {{ auth()->user()->email }}.

+ Choose a plan +
+@else +
+ @foreach($activeLicences as $license) + @php + $activeCount = $license->activations->whereNull('deactivated_at')->count(); + $isDuplicatePersonal = $hasProfessional && $license->edition === 'Personal'; + $billing = str_contains(strtolower((string) optional($license->product)->code), 'annual') ? 'Annual' : 'Monthly'; + @endphp +
+
+
+
+
+ Active + {{ $license->edition }} + {{ $billing }} +
+

SonarDesk {{ $license->edition }}

+

Licence ending {{ $license->license_key_last4 }}

+
+ Manage licence +
+ +
+
+ Macs activated + {{ $activeCount }} of {{ $license->activation_limit }} +
+
+ Subscription + {{ ucfirst($license->subscription_status ?: 'active') }} +
+
+ {{ $license->subscription_status === 'trialing' ? 'Trial ends' : 'Renews' }} + {{ optional($license->current_period_ends_at)->format('j M Y') ?: '—' }} +
+
+ +
+ +
+ + @if($isDuplicatePersonal) +
+
+ You already have an active Professional subscription. +

This Personal plan is a separate Paddle subscription and could be billed separately. Cancel it if it was only created while upgrading.

+
+
+ @csrf + @method('DELETE') + +
+
+ @elseif($license->edition === 'Personal') +
+
+ Need more Macs? + Upgrade this subscription to Professional for up to 3 Macs. +
+
+ @csrf + +
+
+ @endif +
+
+ @endforeach +
+@endif + +@if($historyLicences->isNotEmpty()) +
+ Licence history {{ $historyLicences->count() }} +
+ @foreach($historyLicences as $license) +
+
+ SonarDesk {{ $license->edition }} + Licence ending {{ $license->license_key_last4 }} +
+
{{ ucfirst($license->subscription_status ?: ($license->revoked_at ? 'revoked' : 'unavailable')) }}
+ Details +
+ @endforeach +
+
+@endif +@endsection diff --git a/resources/themes/sonardesk/views/portal/show.blade.php b/resources/themes/sonardesk/views/portal/show.blade.php new file mode 100755 index 0000000..cc75ebb --- /dev/null +++ b/resources/themes/sonardesk/views/portal/show.blade.php @@ -0,0 +1,81 @@ +@extends('layouts.app') + +@section('content') +
Latest SonarDeskNeed the Mac app?Download the latest published, signed release from the SonarDesk distribution centre.
Download SonarDesk
+@php + $activeActivations = $license->activations->whereNull('deactivated_at'); + $billing = str_contains(strtolower((string) optional($license->product)->code), 'annual') ? 'Annual' : 'Monthly'; +@endphp + +← My licences + +
+
+
+ {{ $license->is_usable ? 'Active' : 'Unavailable' }} + {{ $license->edition }} + {{ $billing }} +
+

SonarDesk {{ $license->edition }}

+

Licence ending {{ $license->license_key_last4 }}

+
+
+ @csrf + +
+
+ +
+
+
+
+

Activated Macs

+

{{ $activeActivations->count() }} of {{ $license->activation_limit }} activation slots in use.

+
+ {{ $activeActivations->count() }}/{{ $license->activation_limit }} +
+ + @forelse($activeActivations as $activation) +
+
⌘
+
+ {{ $activation->installation_name ?: 'Mac' }} + {{ $activation->platform ?: 'macOS' }}@if($activation->app_version) · SonarDesk {{ $activation->app_version }}@endif + Last seen {{ optional($activation->last_seen_at)->diffForHumans() ?: 'not yet recorded' }} +
+
+ @csrf + @method('DELETE') + +
+
+ @empty +
No Macs are currently activated with this licence.
+ @endforelse +
+ + +
+@endsection diff --git a/resources/themes/sonardesk/views/release.blade.php b/resources/themes/sonardesk/views/release.blade.php new file mode 100644 index 0000000..b43d39b --- /dev/null +++ b/resources/themes/sonardesk/views/release.blade.php @@ -0,0 +1,16 @@ +@extends('layouts.app', ['title' => 'SonarDesk 1.0 — Release', 'description' => 'SonarDesk 1.0 for macOS: a native desktop companion for SonarQube project health, quality gates and issues.']) +@section('content') +
Introducing SonarDesk 1.0

SonarQube monitoring, built for the Mac.

SonarDesk brings project health, quality gates, bugs, vulnerabilities, code smells and measures into a dedicated native macOS workspace.

+
+
+ Version 1.0

Why SonarDesk

+

SonarQube is an essential part of many development workflows, but checking it throughout the day often means returning to another browser tab, navigating back to a project and rebuilding context. SonarDesk is designed to make that recurring check faster and more focused on macOS.

+

It does not replace SonarQube. Your SonarQube server remains the source of truth. SonarDesk gives you a dedicated desktop view of the information you monitor most often.

+

What is included

+
  • Project dashboards and project health views
  • Quality gate status and important measures
  • Issue browsing for bugs, vulnerabilities and code smells
  • Detailed issue views and practical filtering
  • Server-side pagination for larger issue sets
  • Support for multiple SonarQube server configurations
  • SonarQube token storage using macOS Keychain
  • Direct licensing with a self-service customer portal
+

Who it is for

SonarDesk is for developers, technical leads and engineering teams who already use SonarQube and want a faster, dedicated way to keep project quality visible while working on a Mac.

+

Launch pricing

Personal is £24.99/year or £2.99/month for one active Mac. Professional is £44.99/year or £4.99/month for up to three active Macs. Both include a 7-day free trial and the complete SonarDesk feature set.

+
+ +
+@endsection diff --git a/resources/themes/sonardesk/views/seo/sitemap.blade.php b/resources/themes/sonardesk/views/seo/sitemap.blade.php new file mode 100644 index 0000000..517eb1c --- /dev/null +++ b/resources/themes/sonardesk/views/seo/sitemap.blade.php @@ -0,0 +1,18 @@ +{!! '' !!} + +@foreach($static as $item) + + {{ route($item['route']) }} + {{ $item['frequency'] }} + {{ $item['priority'] }} + +@endforeach +@foreach($pages as $page) + + {{ route('cms.show', $page->slug) }} + {{ $page->updated_at->toAtomString() }} + {{ $page->sitemap_change_frequency }} + {{ number_format((float) $page->sitemap_priority, 1, '.', '') }} + +@endforeach + diff --git a/resources/themes/sonardesk/views/support.blade.php b/resources/themes/sonardesk/views/support.blade.php new file mode 100755 index 0000000..6bdee43 --- /dev/null +++ b/resources/themes/sonardesk/views/support.blade.php @@ -0,0 +1,100 @@ +@extends('layouts.app', [ + 'title' => 'Support — SonarDesk', + 'description' => 'Contact SonarDesk support for technical, licence, billing and privacy enquiries.' +]) + +@section('content') +
+ Support +

How can we help?

+

Send us the details below. Your request is saved securely, assigned a reference and emailed to the support team.

+
+ +
+
+
+
+

Contact support

+

We will reply to the email address you provide.

+
+ Support ticket +
+ +
+ @csrf + + +
+
+ + + @error('name')
{{ $message }}
@enderror +
+
+ + + @error('email')
{{ $message }}
@enderror +
+
+ +
+
+ + + @error('category')
{{ $message }}
@enderror +
+
+ + + @error('subject')
{{ $message }}
@enderror +
+
+ +
+ + +
Do not include passwords, private SSH keys or your full licence token.
+ @error('message')
{{ $message }}
@enderror +
+ + + @error('privacy_notice')
{{ $message }}
@enderror + +
+ + @auth + @if(auth()->user()->hasVerifiedEmail())Open licence portal@endif + @endauth +
+
+
+ + +
+@endsection diff --git a/resources/themes/sonardesk/views/welcome.blade.php b/resources/themes/sonardesk/views/welcome.blade.php new file mode 100755 index 0000000..26e294a --- /dev/null +++ b/resources/themes/sonardesk/views/welcome.blade.php @@ -0,0 +1,223 @@ + + + + + + + {{ config('app.name', 'Laravel') }} + + @fonts + + + @if (file_exists(public_path('build/manifest.json')) || file_exists(public_path('hot'))) + @vite(['resources/css/app.css', 'resources/js/app.js']) + @else + + @endif + + +
+ @if (Route::has('login')) + + @endif +
+
+
+
+

Let's get started

+

With so many options available to you,
we suggest you start with the following:

+ + + +

+ v{{ app()->version() }} + + View changelog + + + + +

+
+
+ {{-- Laravel Logo --}} + + + + + + + + + + + {{-- 13 --}} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ + @if (Route::has('login')) + + @endif + +