Files
2026-10-12 16:23:27 +01:00

13 lines
9.1 KiB
PHP

@extends('licensing::admin.layout')
@section('title','Downloads & releases')
@section('content')
<div class="sd-admin"><div class="sd-admin-head"><div><p class="sd-eyebrow">PRODUCT DISTRIBUTION</p><h1>Downloads &amp; releases</h1><p>Manage SonarDesk releases, SonarDisk and alternative installers from one place.</p></div><a href="{{ route('sonardesk.downloads') }}" target="_blank" rel="noopener" class="sd-link">View public downloads ↗</a></div>
@if(session('status'))<div class="sd-notice">{{ session('status') }}</div>@endif
@if($errors->any())<div class="sd-errors"><strong>Unable to save:</strong><ul>@foreach($errors->all() as $error)<li>{{ $error }}</li>@endforeach</ul></div>@endif
<div class="sd-two"><section class="sd-panel"><h2>Add SonarDesk release</h2><form method="POST" enctype="multipart/form-data" action="{{ route('administration.sonardesk.distribution.releases.store') }}">@csrf<div class="sd-grid"><label>Version<input name="version" required placeholder="1.2.0" value="{{ old('version') }}"></label><label>Build<input name="build_number" type="number" min="1" required value="{{ old('build_number') }}"></label><label>Channel<select name="channel"><option value="stable">Stable</option><option value="beta">Beta</option></select></label><label>Minimum macOS<input name="minimum_macos" placeholder="14.0"></label></div><label>Full release notes<textarea name="release_notes" rows="4"></textarea></label><label>Sparkle signature (optional)<input name="sparkle_signature"></label><label>Installer (.dmg, .zip, .pkg; up to 500 MB)<input type="file" name="file" required accept=".dmg,.zip,.pkg"></label><div class="sd-actions"><label class="sd-check"><input type="checkbox" name="is_published" value="1"> Publish now</label><button>Create release</button></div></form></section>
<section class="sd-panel"><h2>Add product / alternative download</h2><form method="POST" enctype="multipart/form-data" action="{{ route('administration.sonardesk.distribution.products.store') }}">@csrf<div class="sd-grid"><label>Product name<input name="name" required placeholder="SonarDisk"></label><label>Version<input name="version" placeholder="1.0"></label><label>Platform<input name="platform" placeholder="macOS · Apple Silicon"></label><label>Display order<input name="sort_order" type="number" value="0"></label></div><label>Short description<textarea name="description" rows="2"></textarea></label><label>Full release notes<textarea name="release_notes" rows="3"></textarea></label><label>System requirements<input name="minimum_system" placeholder="macOS 14 or later"></label><label>Download file (up to 500 MB)<input name="file" type="file" required></label><div class="sd-actions"><label class="sd-check"><input type="checkbox" name="is_published" value="1"> Publish now</label><button>Add download</button></div></form></section></div>
<section class="sd-panel"><h2>Manage products and alternative downloads <small>({{ $products->count() }})</small></h2><p class="sd-help">Add multiple files under the same product name to group them on the public page. Expand an entry to edit, replace its file or unpublish it.</p>@forelse($products as $p)<details class="sd-entry"><summary><strong>{{ $p->name }}</strong><span>{{ $p->version ?: 'Unversioned' }} · {{ $p->platform ?: 'Any platform' }}</span><span class="sd-status {{ $p->is_published ? 'live' : '' }}">{{ $p->is_published ? 'Published' : 'Draft' }}</span><span>{{ number_format($p->download_count) }} downloads</span></summary><form method="POST" enctype="multipart/form-data" action="{{ route('administration.sonardesk.distribution.products.update',$p) }}">@csrf @method('PATCH')<div class="sd-grid"><label>Name<input name="name" value="{{ $p->name }}" required></label><label>Version<input name="version" value="{{ $p->version }}"></label><label>Platform<input name="platform" value="{{ $p->platform }}"></label><label>Order<input type="number" name="sort_order" value="{{ $p->sort_order ?? 0 }}"></label></div><label>Description<textarea name="description" rows="2">{{ $p->description }}</textarea></label><label>Release notes<textarea name="release_notes" rows="4">{{ $p->release_notes }}</textarea></label><label>System requirements<input name="minimum_system" value="{{ $p->minimum_system }}"></label><label>Replace file (optional) — currently {{ $p->original_filename }}<input type="file" name="file"></label><div class="sd-actions"><label class="sd-check"><input type="checkbox" name="is_published" value="1" @checked($p->is_published)> Published</label><button>Save changes</button><a href="{{ route('sonardesk.products.show',$p) }}" target="_blank" rel="noopener">Public details ↗</a></div></form><form method="POST" action="{{ route('administration.sonardesk.distribution.products.delete',$p) }}" onsubmit="return confirm('Permanently delete this download and its file?')">@csrf @method('DELETE')<button class="sd-danger">Delete download</button></form></details>@empty<p>No additional downloads yet. Add SonarDisk or an alternative installer above.</p>@endforelse</section>
<section class="sd-panel"><h2>Manage SonarDesk releases</h2>@forelse($releases as $r)<details class="sd-entry"><summary><strong>SonarDesk {{ $r->version }}</strong><span>Build {{ $r->build_number }} · {{ ucfirst($r->channel) }}</span><span class="sd-status {{ $r->is_published ? 'live' : '' }}">{{ $r->is_published ? 'Published' : 'Draft' }}</span><span>{{ number_format($r->download_count) }} downloads</span></summary><form method="POST" enctype="multipart/form-data" action="{{ route('administration.sonardesk.distribution.releases.update',$r) }}">@csrf @method('PATCH')<div class="sd-grid"><label>Version<input name="version" required value="{{ $r->version }}"></label><label>Build<input type="number" min="1" name="build_number" required value="{{ $r->build_number }}"></label><label>Channel<select name="channel"><option value="stable" @selected($r->channel==='stable')>Stable</option><option value="beta" @selected($r->channel==='beta')>Beta</option></select></label><label>Minimum macOS<input name="minimum_macos" value="{{ $r->minimum_macos }}"></label></div><label>Release notes<textarea name="release_notes" rows="5">{{ $r->release_notes }}</textarea></label><label>Sparkle signature<input name="sparkle_signature" value="{{ $r->sparkle_signature }}"></label><label>Replace installer (optional) — {{ $r->original_filename }}<input type="file" name="file" accept=".dmg,.zip,.pkg"></label><div class="sd-actions"><label class="sd-check"><input type="checkbox" name="is_published" value="1" @checked($r->is_published)> Published</label><label class="sd-check"><input type="checkbox" name="is_featured" value="1" @checked($r->is_featured)> Featured</label><button>Save release</button></div></form><form method="POST" action="{{ route('administration.sonardesk.distribution.releases.delete',$r) }}" onsubmit="return confirm('Permanently delete this release and its installer?')">@csrf @method('DELETE')<button class="sd-danger">Delete release</button></form></details>@empty<p>No SonarDesk releases yet.</p>@endforelse<div class="sd-pager">{{ $releases->links() }}</div></section></div>
<style>.sd-admin{max-width:1480px;margin:auto}.sd-admin-head{display:flex;justify-content:space-between;gap:20px;align-items:center;margin-bottom:25px}.sd-admin-head h1{font-size:2rem;margin:4px 0}.sd-admin-head p{color:#71717a}.sd-eyebrow{font-size:11px;letter-spacing:.18em;color:#f97316!important;font-weight:800}.sd-two{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:20px}.sd-panel{border:1px solid #a1a1aa55;border-radius:16px;padding:25px;margin-bottom:20px;background:rgba(127,127,127,.035)}.sd-panel h2{font-size:1.25rem;margin:0 0 20px}.sd-panel label{display:block;font-size:13px;font-weight:650;margin-bottom:14px}.sd-panel input:not([type=checkbox]),.sd-panel select,.sd-panel textarea{display:block;width:100%;margin-top:6px;padding:10px 12px;border:1px solid #a1a1aa88;border-radius:8px;background:transparent;color:inherit}.sd-panel select option{color:#111}.sd-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:0 14px}.sd-actions{display:flex;gap:15px;align-items:center;flex-wrap:wrap}.sd-panel .sd-check{display:flex;align-items:center;gap:8px;margin:0}.sd-panel button:not(.sd-danger){background:#f97316;color:#fff;border:0;padding:10px 18px;border-radius:8px;font-weight:750;cursor:pointer}.sd-panel .sd-danger{background:transparent;border:1px solid #dc2626;color:#dc2626;padding:8px 12px;border-radius:8px;margin-top:12px;cursor:pointer}.sd-entry{border-top:1px solid #a1a1aa55;padding:15px 0}.sd-entry summary{cursor:pointer;display:flex;gap:20px;align-items:center;flex-wrap:wrap}.sd-entry summary strong{min-width:170px}.sd-entry summary span{font-size:13px;color:#71717a}.sd-entry[open] summary{margin-bottom:20px}.sd-status{padding:4px 9px;border-radius:30px;background:#a1a1aa33}.sd-status.live{background:#16a34a22!important;color:#16a34a!important}.sd-notice,.sd-errors{padding:14px;border-radius:8px;margin-bottom:18px;background:#16a34a22}.sd-errors{background:#dc262622}.sd-help{color:#71717a;margin-bottom:18px}.sd-link{white-space:nowrap}.sd-pager{margin-top:20px}@media(max-width:900px){.sd-two{grid-template-columns:1fr}}@media(max-width:540px){.sd-grid{grid-template-columns:1fr}.sd-admin-head{display:block}}</style>
@endsection