Snapshot of main at 9f39a6e1e (2026-11-02)

This commit is contained in:
Ronald Huynen committed 2026-11-02 10:41:47 +01:00
commit 6ccf1792d7
2580 files changed
+1040202

No files matched your search

@@ -0,0 +1,53 @@
{{-- Shared b/w call card partial — used by both pdf-a4-bw and pdf-bulk-bw --}}
{{-- Expects all variables from buildCallPdfData() plus CSS classes from parent view --}}
<div class="logo-area">
@if($logoBase64)
<img src="{{ $logoBase64 }}" alt="{{ config('app.name') }}">
@else
<div class="app-name">{{ config('app.name') }}</div>
@endif
</div>
<div class="categories">
@foreach($tagCategories as $cat)
<div class="badge-row"><span class="category-badge">{{ $cat['name'] }}</span></div>
@endforeach
@if($callLocation)
<div class="badge-row"><span class="location-badge">{{ $callLocation }}</span></div>
@endif
@if($expiryBadgeText)
<div class="badge-row"><span class="location-badge">{{ $expiryBadgeText }}</span></div>
@endif
</div>
<div class="title">
@if($isDeleted)<span class="status-label">{{ $statusLabelDeleted }}: </span>
@elseif($call->is_suppressed)<span class="status-label">{{ $statusLabelBlocked }}: </span>
@elseif($call->is_paused)<span class="status-label">{{ $statusLabelPaused }}: </span>
@elseif($isExpired)<span class="status-label">{{ $statusLabelExpired }}: </span>
@endif{{ $call->tag?->translation?->name ?? $call->tag?->name }}
</div>
@if($callContent)
<div class="call-content">{{ $callContent }}</div>
@endif
<div class="footer-panel">
<table class="footer-table">
<tr>
@if($qrSvgBw)
<td class="footer-qr-cell">
<img src="{{ $qrSvgBw }}" alt="QR">
</td>
@endif
<td class="footer-callable-cell">
<div class="callable-name">{{ $call->callable?->name }}</div>
@if($callableLocation)
<div class="callable-location">{{ $callableLocation }}</div>
@endif
</td>
</tr>
</table>
<div class="footer-tagline">{{ config('app.name') }} &mdash; {{ timebank_config('footer.tagline') }}</div>
</div>
@@ -0,0 +1,54 @@
{{-- Shared colour call card partial — used by pdf-a4 and pdf-bulk --}}
<div class="logo-area">
@if($logoBase64)
<img src="{{ $logoBase64 }}" alt="{{ config('app.name') }}">
@else
<div class="app-name">{{ config('app.name') }}</div>
@endif
</div>
<div class="categories">
@foreach($tagCategories as $cat)
<div class="badge-row">
<span class="category-badge" style="background-color: #{{ $cat['colorHex'] ?? $tagColorHex }};">{{ $cat['name'] }}</span>
</div>
@endforeach
@if($callLocation)
<div class="badge-row"><span class="location-badge">{{ $callLocation }}</span></div>
@endif
@if($expiryBadgeText)
<div class="badge-row"><span class="location-badge">{{ $expiryBadgeText }}</span></div>
@endif
</div>
<div class="title">
@if($isDeleted)<span class="status-label">{{ $statusLabelDeleted }}: </span>
@elseif($call->is_suppressed)<span class="status-label">{{ $statusLabelBlocked }}: </span>
@elseif($call->is_paused)<span class="status-label">{{ $statusLabelPaused }}: </span>
@elseif($isExpired)<span class="status-label">{{ $statusLabelExpired }}: </span>
@endif{{ $call->tag?->translation?->name ?? $call->tag?->name }}
</div>
@if($callContent)
<div class="call-content">{{ $callContent }}</div>
@endif
<div class="footer-panel">
<table class="footer-table">
<tr>
@if($qrSvg)
<td class="footer-qr-cell">
<img src="{{ $qrSvg }}" alt="QR">
</td>
@endif
<td class="footer-callable-cell">
<div class="callable-name">{{ $call->callable?->name }}</div>
@if($callableLocation)
<div class="callable-location">{{ $callableLocation }}</div>
@endif
</td>
</tr>
</table>
<div class="footer-tagline">{{ config('app.name') }} &mdash; {{ timebank_config('footer.tagline') }}</div>
</div>
+29
View File
@@ -0,0 +1,29 @@
<x-app-layout>
<x-slot name="header">
{{ trans_with_platform('@PLATFORM_NAME@ calls') }}
</x-slot>
<div class="py-6">
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
<div class="bg-theme-background overflow-x-visible shadow-xl sm:rounded-lg">
<div class="p-12 px-6 sm:px-20 bg-theme-background">
@php
$sidePostType = session('activeProfileType') === \App\Models\Admin::class
? 'SiteContents\\Manage\\CallsAdmin'
: 'SiteContents\\Manage\\Calls';
$sidePostFallback = session('activeProfileType') === \App\Models\Admin::class
? __('Manage calls (admin)')
: __('Manage calls');
@endphp
@livewire('side-post', [
'type' => $sidePostType,
'latest' => true,
'fallbackTitle' => $sidePostFallback,
'fallbackDescription' => ''])
@livewire('calls.manage')
</div>
</div>
</div>
</div>
</x-app-layout>
+242
View File
@@ -0,0 +1,242 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta charset="utf-8">
<title>{{ $call->tag?->translation?->name ?? $call->tag?->name }}</title>
<style>
* { box-sizing: border-box; margin: 0; padding: 0; }
@font-face {
font-family: 'OswaldRegular';
src: url('/fonts/static/oswald/Oswald-Regular.ttf') format('truetype');
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: 'Oswald';
src: url('/fonts/static/oswald/Oswald-SemiBold.ttf') format('truetype');
font-weight: 600;
font-style: normal;
}
@font-face {
font-family: 'Poppins';
src: url('/fonts/static/poppins/Poppins-Regular.otf') format('opentype');
font-weight: normal;
font-style: normal;
}
html, body {
width: 210mm;
height: 297mm;
background-color: #ffffff;
font-family: DejaVu Sans, Arial, sans-serif;
color: #000000;
}
.page {
position: absolute;
top: 0;
left: 0;
width: 210mm;
height: 297mm;
background-color: #ffffff;
}
/* ── Logo: top-right ── */
.logo-area {
position: absolute;
top: 13mm;
right: 15mm;
text-align: right;
}
.logo-area img {
max-height: 44mm;
max-width: 61mm;
}
.app-name {
font-size: 15pt;
color: #333333;
}
/* ── Categories: top-left, constrained so they never reach logo ── */
.categories {
position: absolute;
top: 20mm;
left: 20mm;
right: 100mm;
font-size: 13pt;
}
.badge-row {
display: block;
margin-bottom: 2.6mm;
}
.category-badge {
display: inline-block;
background-color: #555555;
color: #ffffff;
padding: 4px 13px;
border-radius: 8px;
font-size: 13pt;
font-weight: normal;
line-height: 1;
}
.location-badge {
display: inline-block;
font-family: 'OswaldRegular', sans-serif;
color: #666666;
font-size: 13pt;
text-transform: uppercase;
}
.expiry {
display: block;
margin-top: 2.6mm;
font-size: 13pt;
color: #666666;
}
/* ── Title ── */
.title {
position: absolute;
top: 55mm;
left: 20mm;
right: 20mm;
font-family: 'Oswald', sans-serif;
font-size: 37pt;
font-weight: 600;
line-height: 0.95;
text-transform: uppercase;
color: #000000;
padding-top: 17mm;
padding-bottom: 7mm;
}
.status-label { color: #333333; }
/* ── Content ── */
.call-content {
position: absolute;
top: 122mm;
left: 20mm;
right: 20mm;
font-size: 20pt;
font-weight: bold;
line-height: 1.35;
color: #000000;
max-height: 48mm;
overflow: hidden;
}
/* ── Footer row: QR left + callable right ── */
.footer-panel {
position: absolute;
bottom: 20mm;
left: 20mm;
right: 20mm;
}
.footer-table {
width: 100%;
border-collapse: collapse;
}
.footer-qr-cell {
width: 32mm;
padding-right: 7mm;
vertical-align: bottom;
}
.footer-qr-cell img {
display: block;
width: 23mm;
height: 23mm;
}
.footer-callable-cell {
vertical-align: bottom;
text-align: right;
}
.callable-name {
font-family: 'Oswald', sans-serif;
font-weight: 600;
font-size: 22pt;
line-height: 0.95;
text-transform: uppercase;
color: #000000;
}
.callable-location {
font-family: 'OswaldRegular', sans-serif;
font-weight: normal;
font-size: 17pt;
line-height: 0.95;
text-transform: uppercase;
color: #555555;
margin-top: 2mm;
}
.footer-tagline {
margin-top: 4mm;
font-family: 'Poppins', sans-serif;
font-size: 11pt;
color: #aaaaaa;
text-align: left;
}
</style>
</head>
<body>
<div class="page">
{{-- Logo: top-right ── --}}
<div class="logo-area">
@if($logoBase64)
<img src="{{ $logoBase64 }}" alt="{{ config('app.name') }}">
@else
<div class="app-name">{{ config('app.name') }}</div>
@endif
</div>
{{-- Categories: top-left, never overlap logo ── --}}
<div class="categories">
@foreach($tagCategories as $cat)
<div class="badge-row"><span class="category-badge">{{ $cat['name'] }}</span></div>
@endforeach
@if($callLocation)
<div class="badge-row"><span class="location-badge">{{ $callLocation }}</span></div>
@endif
@if($expiryBadgeText)
<div class="badge-row"><span class="location-badge">{{ $expiryBadgeText }}</span></div>
@endif
</div>
{{-- Title ── --}}
<div class="title">
@if($isDeleted)<span class="status-label">{{ $statusLabelDeleted }}: </span>
@elseif($call->is_suppressed)<span class="status-label">{{ $statusLabelBlocked }}: </span>
@elseif($call->is_paused)<span class="status-label">{{ $statusLabelPaused }}: </span>
@elseif($isExpired)<span class="status-label">{{ $statusLabelExpired }}: </span>
@endif{{ $call->tag?->translation?->name ?? $call->tag?->name }}
</div>
{{-- Content ── --}}
@if($callContent)
<div class="call-content">{{ $callContent }}</div>
@endif
{{-- Footer: QR left + callable right ── --}}
<div class="footer-panel">
<table class="footer-table">
<tr>
@if($qrSvgBw)
<td class="footer-qr-cell">
<img src="{{ $qrSvgBw }}" alt="QR">
</td>
@endif
<td class="footer-callable-cell">
<div class="callable-name">{{ $call->callable?->name }}</div>
@if($callableLocation)
<div class="callable-location">{{ $callableLocation }}</div>
@endif
</td>
</tr>
</table>
<div class="footer-tagline">{{ config('app.name') }} &mdash; {{ timebank_config('footer.tagline') }}</div>
</div>
</div>
</body>
</html>
+242
View File
@@ -0,0 +1,242 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta charset="utf-8">
<title>{{ $call->tag?->translation?->name ?? $call->tag?->name }}</title>
<style>
* { box-sizing: border-box; margin: 0; padding: 0; }
@font-face {
font-family: 'OswaldRegular';
src: url('/fonts/static/oswald/Oswald-Regular.ttf') format('truetype');
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: 'Oswald';
src: url('/fonts/static/oswald/Oswald-SemiBold.ttf') format('truetype');
font-weight: 600;
font-style: normal;
}
@font-face {
font-family: 'Poppins';
src: url('/fonts/static/poppins/Poppins-Regular.otf') format('opentype');
font-weight: normal;
font-style: normal;
}
html, body {
width: 210mm;
height: 297mm;
background-color: #ffffff;
font-family: DejaVu Sans, Arial, sans-serif;
color: #ffffff;
}
.page {
position: absolute;
top: 0;
left: 0;
width: 210mm;
height: 297mm;
background-color: #{{ $bgDarkHex }};
}
/* ── Logo: top-right ── */
.logo-area {
position: absolute;
top: 13mm;
right: 15mm;
text-align: right;
}
.logo-area img {
max-height: 44mm;
max-width: 61mm;
}
.app-name {
font-size: 15pt;
color: #aaaaaa;
}
/* ── Categories: top-left, constrained so they never reach logo ── */
.categories {
position: absolute;
top: 20mm;
left: 20mm;
right: 100mm;
font-size: 13pt;
}
.badge-row {
display: block;
margin-bottom: 2.6mm;
}
.category-badge {
display: inline-block;
background-color: #{{ $tagColorHex }};
color: #000000;
padding: 4px 13px;
border-radius: 8px;
font-size: 13pt;
font-weight: normal;
line-height: 1;
}
.location-badge {
display: inline-block;
font-family: 'OswaldRegular', sans-serif;
color: #cccccc;
font-size: 13pt;
text-transform: uppercase;
}
.expiry {
display: block;
margin-top: 2.6mm;
font-size: 13pt;
color: #cccccc;
}
/* ── Title ── */
.title {
position: absolute;
top: 55mm;
left: 20mm;
right: 20mm;
font-family: 'Oswald', sans-serif;
font-size: 37pt;
font-weight: 600;
line-height: 0.95;
text-transform: uppercase;
color: #ffffff;
padding-top: 17mm;
padding-bottom: 7mm;
}
.status-label { color: #fc8181; }
/* ── Content ── */
.call-content {
position: absolute;
top: 122mm;
left: 20mm;
right: 20mm;
font-size: 20pt;
font-weight: bold;
line-height: 1.35;
color: #ffffff;
max-height: 48mm;
overflow: hidden;
}
/* ── Footer row: QR left + callable right ── */
.footer-panel {
position: absolute;
bottom: 20mm;
left: 20mm;
right: 20mm;
}
.footer-table {
width: 100%;
border-collapse: collapse;
}
.footer-qr-cell {
width: 32mm;
padding-right: 7mm;
vertical-align: bottom;
}
.footer-qr-cell img {
display: block;
width: 23mm;
height: 23mm;
}
.footer-callable-cell {
vertical-align: bottom;
text-align: right;
}
.callable-name {
font-family: 'Oswald', sans-serif;
font-weight: 600;
font-size: 22pt;
line-height: 0.95;
text-transform: uppercase;
color: #ffffff;
}
.callable-location {
font-family: 'OswaldRegular', sans-serif;
font-weight: normal;
font-size: 17pt;
line-height: 0.95;
text-transform: uppercase;
color: #cccccc;
margin-top: 2mm;
}
.footer-tagline {
margin-top: 4mm;
font-family: 'Poppins', sans-serif;
font-size: 11pt;
color: #aaaaaa;
text-align: left;
}
</style>
</head>
<body>
<div class="page">
{{-- Logo: top-right ── --}}
<div class="logo-area">
@if($logoBase64)
<img src="{{ $logoBase64 }}" alt="{{ config('app.name') }}">
@else
<div class="app-name">{{ config('app.name') }}</div>
@endif
</div>
{{-- Categories: top-left, never overlap logo ── --}}
<div class="categories">
@foreach($tagCategories as $cat)
<div class="badge-row"><span class="category-badge" style="background-color: #{{ $cat['colorHex'] ?? $tagColorHex }};">{{ $cat['name'] }}</span></div>
@endforeach
@if($callLocation)
<div class="badge-row"><span class="location-badge">{{ $callLocation }}</span></div>
@endif
@if($expiryBadgeText)
<div class="badge-row"><span class="location-badge">{{ $expiryBadgeText }}</span></div>
@endif
</div>
{{-- Title ── --}}
<div class="title">
@if($isDeleted)<span class="status-label">{{ $statusLabelDeleted }}: </span>
@elseif($call->is_suppressed)<span class="status-label">{{ $statusLabelBlocked }}: </span>
@elseif($call->is_paused)<span class="status-label">{{ $statusLabelPaused }}: </span>
@elseif($isExpired)<span class="status-label">{{ $statusLabelExpired }}: </span>
@endif{{ $call->tag?->translation?->name ?? $call->tag?->name }}
</div>
{{-- Content ── --}}
@if($callContent)
<div class="call-content">{{ $callContent }}</div>
@endif
{{-- Footer: QR left + callable right ── --}}
<div class="footer-panel">
<table class="footer-table">
<tr>
@if($qrSvg)
<td class="footer-qr-cell">
<img src="{{ $qrSvg }}" alt="QR">
</td>
@endif
<td class="footer-callable-cell">
<div class="callable-name">{{ $call->callable?->name }}</div>
@if($callableLocation)
<div class="callable-location">{{ $callableLocation }}</div>
@endif
</td>
</tr>
</table>
<div class="footer-tagline">{{ config('app.name') }} &mdash; {{ timebank_config('footer.tagline') }}</div>
</div>
</div>
</body>
</html>
+247
View File
@@ -0,0 +1,247 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta charset="utf-8">
<title>{{ __('Calls') }}</title>
<style>
@font-face {
font-family: 'OswaldRegular';
src: url('/fonts/static/oswald/Oswald-Regular.ttf') format('truetype');
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: 'Oswald';
src: url('/fonts/static/oswald/Oswald-SemiBold.ttf') format('truetype');
font-weight: 600;
font-style: normal;
}
@font-face {
font-family: 'Poppins';
src: url('/fonts/static/poppins/Poppins-Regular.otf') format('opentype');
font-weight: normal;
font-style: normal;
}
@page { margin: 0; }
* { box-sizing: border-box; margin: 0; padding: 0; }
html, body {
width: 210mm;
height: 297mm;
background-color: #ffffff;
font-family: DejaVu Sans, Arial, sans-serif;
color: #000000;
}
@php
// Layout per mode:
// 1-up: portrait A4, 1 col × 1 row, card 210×297mm, scale 1.0
// 2-up: landscape A4, 2 cols × 1 row, each card 148×210mm (A5 portrait), scale ≈ 0.705
// 4-up: portrait A4, 2 cols × 2 rows, each card 105×148mm, scale 0.498
$cols = $perPage >= 2 ? 2 : 1;
$rows = $perPage === 4 ? 2 : 1;
$cardW = $perPage === 4 ? 105 : ($perPage === 2 ? 148 : 210);
$cardH = $perPage === 4 ? 148 : ($perPage === 2 ? 210 : 297);
// Scale relative to A4 single baseline (210×297)
$scale = match($perPage) {
2 => 148/210, // A5 portrait ≈ 0.705
4 => 0.498,
default => 1.0,
};
$margin = round(20 * $scale, 1) . 'mm';
$logoTop = round(13 * $scale, 1) . 'mm';
$logoRight = round(15 * $scale, 1) . 'mm';
$logoMaxH = round(44 * $scale, 1) . 'mm';
$logoMaxW = round(61 * $scale, 1) . 'mm';
$catTop = round(20 * $scale, 1) . 'mm';
$catRight = round(100 * $scale, 1) . 'mm';
$catFont = round(13 * $scale, 1) . 'pt';
$badgePadV = round(4 * $scale, 1) . 'px';
$badgePadH = round(13 * $scale, 1) . 'px';
$badgeRadius = round(8 * $scale, 1) . 'px';
$badgeGap = round(2.6 * $scale, 1) . 'mm';
$titleTop = round(55 * $scale, 1) . 'mm';
$titleFont = round(37 * $scale, 1) . 'pt';
$titlePadT = round(17 * $scale, 1) . 'mm';
$titlePadB = round(7 * $scale, 1) . 'mm';
$contentTop = round(122 * $scale, 1) . 'mm';
$contentFont = round(20 * $scale, 1) . 'pt';
$contentMaxH = round(48 * $scale, 1) . 'mm';
$footerBottom= round(20 * $scale, 1) . 'mm';
$qrSize = round(23 * $scale, 1) . 'mm';
$qrCellW = round(32 * $scale, 1) . 'mm';
$qrCellPad = round(7 * $scale, 1) . 'mm';
$callNameFont= round(22 * $scale, 1) . 'pt';
$callLocFont = round(17 * $scale, 1) . 'pt';
$callLocMT = round(2 * $scale, 1) . 'mm';
$taglineFont = round(11 * $scale, 1) . 'pt';
$taglineMT = round(4 * $scale, 1) . 'mm';
@endphp
/* Page table: groups cards into pages */
@if($perPage === 2)
@page { size: A4 landscape; margin: 0; }
html, body { width: 297mm; height: 210mm; }
@endif
.page-table {
width: {{ $perPage === 2 ? '297mm' : '210mm' }};
border-collapse: collapse;
}
.page-table-break { page-break-after: always; }
.page-table tr { height: {{ $cardH }}mm; }
.card-cell {
width: {{ $cardW }}mm;
height: {{ $cardH }}mm;
overflow: hidden;
position: relative;
vertical-align: top;
background-color: #ffffff;
}
.logo-area {
position: absolute;
top: {{ $logoTop }};
right: {{ $logoRight }};
text-align: right;
}
.logo-area img { max-height: {{ $logoMaxH }}; max-width: {{ $logoMaxW }}; }
.app-name { font-size: {{ $catFont }}; color: #333333; }
.categories {
position: absolute;
top: {{ $catTop }};
left: {{ $margin }};
right: {{ $catRight }};
font-size: {{ $catFont }};
}
.badge-row { display: block; margin-bottom: {{ $badgeGap }}; }
.category-badge {
display: inline-block;
background-color: #555555;
color: #ffffff;
padding: {{ $badgePadV }} {{ $badgePadH }};
border-radius: {{ $badgeRadius }};
font-size: {{ $catFont }};
font-weight: normal;
line-height: 1;
}
.location-badge {
display: inline-block;
font-family: 'OswaldRegular', sans-serif;
color: #666666;
font-size: {{ $catFont }};
text-transform: uppercase;
}
.expiry {
display: block;
margin-top: {{ $badgeGap }};
font-size: {{ $catFont }};
color: #666666;
}
.title {
position: absolute;
top: {{ $titleTop }};
left: {{ $margin }};
right: {{ $margin }};
font-family: 'Oswald', sans-serif;
font-size: {{ $titleFont }};
font-weight: 600;
line-height: 0.95;
text-transform: uppercase;
color: #000000;
padding-top: {{ $titlePadT }};
padding-bottom: {{ $titlePadB }};
}
.status-label { color: #333333; }
.call-content {
position: absolute;
top: {{ $contentTop }};
left: {{ $margin }};
right: {{ $margin }};
font-size: {{ $contentFont }};
font-weight: bold;
line-height: 1.35;
color: #000000;
max-height: {{ $contentMaxH }};
overflow: hidden;
}
.footer-panel {
position: absolute;
bottom: {{ $footerBottom }};
left: {{ $margin }};
right: {{ $margin }};
}
.footer-table { width: 100%; border-collapse: collapse; }
.footer-qr-cell {
width: {{ $qrCellW }};
padding-right: {{ $qrCellPad }};
vertical-align: bottom;
}
.footer-qr-cell img { display: block; width: {{ $qrSize }}; height: {{ $qrSize }}; }
.footer-callable-cell { vertical-align: bottom; text-align: right; }
.callable-name {
font-family: 'Oswald', sans-serif;
font-weight: 600;
font-size: {{ $callNameFont }};
line-height: 0.95;
text-transform: uppercase;
color: #000000;
}
.callable-location {
font-family: 'OswaldRegular', sans-serif;
font-weight: normal;
font-size: {{ $callLocFont }};
line-height: 0.95;
text-transform: uppercase;
color: #555555;
margin-top: {{ $callLocMT }};
}
.footer-tagline {
margin-top: {{ $taglineMT }};
font-family: 'Poppins', sans-serif;
font-size: {{ $taglineFont }};
color: #aaaaaa;
text-align: left;
}
</style>
</head>
<body>
@php
// Chunk calls into pages (each page holds $rows × $cols cards)
$cardsPerPage = $rows * $cols;
$pages = array_chunk($calls, $cardsPerPage);
@endphp
@foreach($pages as $pageIndex => $pageCalls)
@php
$padded = array_pad($pageCalls, $cardsPerPage, null);
$isLast = $pageIndex === count($pages) - 1;
@endphp
<table class="page-table {{ $isLast ? '' : 'page-table-break' }}">
@for($row = 0; $row < $rows; $row++)
<tr>
@for($col = 0; $col < $cols; $col++)
@php $idx = $row * $cols + $col; $data = $padded[$idx] ?? null; @endphp
<td class="card-cell">
@if($data)
@include('calls._pdf-card-bw', $data)
@endif
</td>
@endfor
</tr>
@endfor
</table>
@endforeach
</body>
</html>
+241
View File
@@ -0,0 +1,241 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta charset="utf-8">
<title>{{ __('Calls') }}</title>
<style>
@font-face {
font-family: 'OswaldRegular';
src: url('/fonts/static/oswald/Oswald-Regular.ttf') format('truetype');
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: 'Oswald';
src: url('/fonts/static/oswald/Oswald-SemiBold.ttf') format('truetype');
font-weight: 600;
font-style: normal;
}
@font-face {
font-family: 'Poppins';
src: url('/fonts/static/poppins/Poppins-Regular.otf') format('opentype');
font-weight: normal;
font-style: normal;
}
@page { margin: 0; }
* { box-sizing: border-box; margin: 0; padding: 0; }
html, body {
width: 210mm;
height: 297mm;
background-color: #ffffff;
font-family: DejaVu Sans, Arial, sans-serif;
color: #ffffff;
}
@php
// 1-up: portrait A4, 1 col × 1 row, card 210×297mm, scale 1.0
// 2-up: landscape A4, 2 cols × 1 row, each card 148×210mm (A5 portrait), scale ≈ 0.705
// 4-up: portrait A4, 2 cols × 2 rows, each card 105×148mm, scale 0.498
$cols = $perPage >= 2 ? 2 : 1;
$rows = $perPage === 4 ? 2 : 1;
$cardW = $perPage === 4 ? 105 : ($perPage === 2 ? 148 : 210);
$cardH = $perPage === 4 ? 148 : ($perPage === 2 ? 210 : 297);
$scale = match($perPage) {
2 => 148/210, // A5 portrait ≈ 0.705
4 => 0.498,
default => 1.0,
};
$margin = round(20 * $scale, 1) . 'mm';
$logoTop = round(13 * $scale, 1) . 'mm';
$logoRight = round(15 * $scale, 1) . 'mm';
$logoMaxH = round(44 * $scale, 1) . 'mm';
$logoMaxW = round(61 * $scale, 1) . 'mm';
$catTop = round(20 * $scale, 1) . 'mm';
$catRight = round(100 * $scale, 1) . 'mm';
$catFont = round(13 * $scale, 1) . 'pt';
$badgePadV = round(4 * $scale, 1) . 'px';
$badgePadH = round(13 * $scale, 1) . 'px';
$badgeRadius = round(8 * $scale, 1) . 'px';
$badgeGap = round(2.6 * $scale, 1) . 'mm';
$titleTop = round(55 * $scale, 1) . 'mm';
$titleFont = round(37 * $scale, 1) . 'pt';
$titlePadT = round(17 * $scale, 1) . 'mm';
$titlePadB = round(7 * $scale, 1) . 'mm';
$contentTop = round(122 * $scale, 1) . 'mm';
$contentFont = round(20 * $scale, 1) . 'pt';
$contentMaxH = round(48 * $scale, 1) . 'mm';
$footerBottom= round(20 * $scale, 1) . 'mm';
$qrSize = round(23 * $scale, 1) . 'mm';
$qrCellW = round(32 * $scale, 1) . 'mm';
$qrCellPad = round(7 * $scale, 1) . 'mm';
$callNameFont= round(22 * $scale, 1) . 'pt';
$callLocFont = round(17 * $scale, 1) . 'pt';
$callLocMT = round(2 * $scale, 1) . 'mm';
$taglineFont = round(11 * $scale, 1) . 'pt';
$taglineMT = round(4 * $scale, 1) . 'mm';
@endphp
@if($perPage === 2)
@page { size: A4 landscape; margin: 0; }
html, body { width: 297mm; height: 210mm; }
@endif
.page-table {
width: {{ $perPage === 2 ? '297mm' : '210mm' }};
border-collapse: collapse;
}
.page-table-break { page-break-after: always; }
.page-table tr { height: {{ $cardH }}mm; }
.card-cell {
width: {{ $cardW }}mm;
height: {{ $cardH }}mm;
overflow: hidden;
position: relative;
vertical-align: top;
}
.logo-area {
position: absolute;
top: {{ $logoTop }};
right: {{ $logoRight }};
text-align: right;
}
.logo-area img { max-height: {{ $logoMaxH }}; max-width: {{ $logoMaxW }}; }
.app-name { font-size: {{ $catFont }}; color: #aaaaaa; }
.categories {
position: absolute;
top: {{ $catTop }};
left: {{ $margin }};
right: {{ $catRight }};
font-size: {{ $catFont }};
}
.badge-row { display: block; margin-bottom: {{ $badgeGap }}; }
.category-badge {
display: inline-block;
color: #000000;
padding: {{ $badgePadV }} {{ $badgePadH }};
border-radius: {{ $badgeRadius }};
font-size: {{ $catFont }};
font-weight: normal;
line-height: 1;
}
.location-badge {
display: inline-block;
font-family: 'OswaldRegular', sans-serif;
color: #cccccc;
font-size: {{ $catFont }};
text-transform: uppercase;
}
.expiry {
display: block;
margin-top: {{ $badgeGap }};
font-size: {{ $catFont }};
color: #cccccc;
}
.title {
position: absolute;
top: {{ $titleTop }};
left: {{ $margin }};
right: {{ $margin }};
font-family: 'Oswald', sans-serif;
font-size: {{ $titleFont }};
font-weight: 600;
line-height: 0.95;
text-transform: uppercase;
color: #ffffff;
padding-top: {{ $titlePadT }};
padding-bottom: {{ $titlePadB }};
}
.status-label { color: #fc8181; }
.call-content {
position: absolute;
top: {{ $contentTop }};
left: {{ $margin }};
right: {{ $margin }};
font-size: {{ $contentFont }};
font-weight: bold;
line-height: 1.35;
color: #ffffff;
max-height: {{ $contentMaxH }};
overflow: hidden;
}
.footer-panel {
position: absolute;
bottom: {{ $footerBottom }};
left: {{ $margin }};
right: {{ $margin }};
}
.footer-table { width: 100%; border-collapse: collapse; }
.footer-qr-cell {
width: {{ $qrCellW }};
padding-right: {{ $qrCellPad }};
vertical-align: bottom;
}
.footer-qr-cell img { display: block; width: {{ $qrSize }}; height: {{ $qrSize }}; }
.footer-callable-cell { vertical-align: bottom; text-align: right; }
.callable-name {
font-family: 'Oswald', sans-serif;
font-weight: 600;
font-size: {{ $callNameFont }};
line-height: 0.95;
text-transform: uppercase;
color: #ffffff;
}
.callable-location {
font-family: 'OswaldRegular', sans-serif;
font-weight: normal;
font-size: {{ $callLocFont }};
line-height: 0.95;
text-transform: uppercase;
color: #cccccc;
margin-top: {{ $callLocMT }};
}
.footer-tagline {
margin-top: {{ $taglineMT }};
font-family: 'Poppins', sans-serif;
font-size: {{ $taglineFont }};
color: #aaaaaa;
text-align: left;
}
</style>
</head>
<body>
@php
$cardsPerPage = $rows * $cols;
$pages = array_chunk($calls, $cardsPerPage);
@endphp
@foreach($pages as $pageIndex => $pageCalls)
@php
$padded = array_pad($pageCalls, $cardsPerPage, null);
$isLast = $pageIndex === count($pages) - 1;
@endphp
<table class="page-table {{ $isLast ? '' : 'page-table-break' }}">
@for($row = 0; $row < $rows; $row++)
<tr>
@for($col = 0; $col < $cols; $col++)
@php $idx = $row * $cols + $col; $data = $padded[$idx] ?? null; @endphp
<td class="card-cell" @if($data) style="background-color: #{{ $data['bgDarkHex'] }};" @endif>
@if($data)
@include('calls._pdf-card-color', $data)
@endif
</td>
@endfor
</tr>
@endfor
</table>
@endforeach
</body>
</html>
+243
View File
@@ -0,0 +1,243 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta charset="utf-8">
<title>{{ $call->tag?->translation?->name ?? $call->tag?->name }}</title>
<style>
* { box-sizing: border-box; margin: 0; padding: 0; }
@font-face {
font-family: 'OswaldRegular';
src: url('/fonts/static/oswald/Oswald-Regular.ttf') format('truetype');
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: 'Oswald';
src: url('/fonts/static/oswald/Oswald-SemiBold.ttf') format('truetype');
font-weight: 600;
font-style: normal;
}
@font-face {
font-family: 'Poppins';
src: url('/fonts/static/poppins/Poppins-Regular.otf') format('opentype');
font-weight: normal;
font-style: normal;
}
html, body {
width: 105mm;
height: 148mm;
background-color: #ffffff;
font-family: DejaVu Sans, Arial, sans-serif;
color: #000000;
}
.page {
position: absolute;
top: 5mm;
left: 5mm;
width: 95mm;
height: 138mm;
background-color: #ffffff;
border-radius: 6px;
}
/* ── Logo: top-right, same proportional position as post PDF ── */
.logo-area {
position: absolute;
top: 6mm;
right: 7mm;
text-align: right;
}
.logo-area img {
max-height: 20mm;
max-width: 28mm;
}
.app-name {
font-size: 7pt;
color: #333333;
}
/* ── Categories: top-left, constrained so they never reach logo ── */
.categories {
position: absolute;
top: 9mm;
left: 9mm;
right: 46mm;
font-size: 6pt;
}
.badge-row {
display: block;
margin-bottom: 1.2mm;
}
.category-badge {
display: inline-block;
background-color: #555555;
color: #ffffff;
padding: 2px 6px;
border-radius: 4px;
font-size: 6pt;
font-weight: normal;
line-height: 1;
}
.location-badge {
display: inline-block;
font-family: 'OswaldRegular', sans-serif;
color: #666666;
font-size: 6pt;
text-transform: uppercase;
}
.expiry {
display: block;
margin-top: 1.2mm;
font-size: 6pt;
color: #666666;
}
/* ── Title: large margin-top/bottom for breathing room, tight line-height within ── */
.title {
position: absolute;
top: 25mm;
left: 9mm;
right: 9mm;
font-family: 'Oswald', sans-serif;
font-size: 17pt;
font-weight: 600;
line-height: 0.95;
text-transform: uppercase;
color: #000000;
padding-top: 8mm;
padding-bottom: 3mm;
}
.status-label { color: #333333; }
/* ── Content: below title (25mm + 8mm + ~20mm text + 3mm = 56mm) ── */
.call-content {
position: absolute;
top: 56mm;
left: 9mm;
right: 9mm;
font-size: 9pt;
font-weight: bold;
line-height: 1.35;
color: #000000;
max-height: 22mm;
overflow: hidden;
}
/* ── Footer row: QR left + callable right, pinned to bottom ── */
.footer-panel {
position: absolute;
bottom: 9mm;
left: 9mm;
right: 9mm;
}
.footer-table {
width: 100%;
border-collapse: collapse;
}
.footer-qr-cell {
width: 14.5mm;
padding-right: 3mm;
vertical-align: bottom;
}
.footer-qr-cell img {
display: block;
width: 10.5mm;
height: 10.5mm;
}
.footer-callable-cell {
vertical-align: bottom;
text-align: right;
}
.callable-name {
font-family: 'Oswald', sans-serif;
font-weight: 600;
font-size: 10pt;
line-height: 0.95;
text-transform: uppercase;
color: #000000;
}
.callable-location {
font-family: 'OswaldRegular', sans-serif;
font-weight: normal;
font-size: 8pt;
line-height: 0.95;
text-transform: uppercase;
color: #555555;
margin-top: 1mm;
}
.footer-tagline {
margin-top: 2mm;
font-family: 'Poppins', sans-serif;
font-size: 5pt;
color: #aaaaaa;
text-align: left;
}
</style>
</head>
<body>
<div class="page">
{{-- Logo: top-right ── --}}
<div class="logo-area">
@if($logoBase64)
<img src="{{ $logoBase64 }}" alt="{{ config('app.name') }}">
@else
<div class="app-name">{{ config('app.name') }}</div>
@endif
</div>
{{-- Categories: top-left, never overlap logo ── --}}
<div class="categories">
@foreach($tagCategories as $cat)
<div class="badge-row"><span class="category-badge">{{ $cat['name'] }}</span></div>
@endforeach
@if($callLocation)
<div class="badge-row"><span class="location-badge">{{ $callLocation }}</span></div>
@endif
@if($expiryBadgeText)
<div class="badge-row"><span class="location-badge">{{ $expiryBadgeText }}</span></div>
@endif
</div>
{{-- Title: below logo ── --}}
<div class="title">
@if($isDeleted)<span class="status-label">{{ $statusLabelDeleted }}: </span>
@elseif($call->is_suppressed)<span class="status-label">{{ $statusLabelBlocked }}: </span>
@elseif($call->is_paused)<span class="status-label">{{ $statusLabelPaused }}: </span>
@elseif($isExpired)<span class="status-label">{{ $statusLabelExpired }}: </span>
@endif{{ $call->tag?->translation?->name ?? $call->tag?->name }}
</div>
{{-- Content: below title ── --}}
@if($callContent)
<div class="call-content">{{ $callContent }}</div>
@endif
{{-- Footer: QR left + callable right, matching post PDF event footer ── --}}
<div class="footer-panel">
<table class="footer-table">
<tr>
@if($qrSvgBw)
<td class="footer-qr-cell">
<img src="{{ $qrSvgBw }}" alt="QR">
</td>
@endif
<td class="footer-callable-cell">
<div class="callable-name">{{ $call->callable?->name }}</div>
@if($callableLocation)
<div class="callable-location">{{ $callableLocation }}</div>
@endif
</td>
</tr>
</table>
<div class="footer-tagline">{{ config('app.name') }} &mdash; {{ timebank_config('footer.tagline') }}</div>
</div>
</div>
</body>
</html>
+243
View File
@@ -0,0 +1,243 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta charset="utf-8">
<title>{{ $call->tag?->translation?->name ?? $call->tag?->name }}</title>
<style>
* { box-sizing: border-box; margin: 0; padding: 0; }
@font-face {
font-family: 'OswaldRegular';
src: url('/fonts/static/oswald/Oswald-Regular.ttf') format('truetype');
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: 'Oswald';
src: url('/fonts/static/oswald/Oswald-SemiBold.ttf') format('truetype');
font-weight: 600;
font-style: normal;
}
@font-face {
font-family: 'Poppins';
src: url('/fonts/static/poppins/Poppins-Regular.otf') format('opentype');
font-weight: normal;
font-style: normal;
}
html, body {
width: 105mm;
height: 148mm;
background-color: #ffffff;
font-family: DejaVu Sans, Arial, sans-serif;
color: #ffffff;
}
.page {
position: absolute;
top: 5mm;
left: 5mm;
width: 95mm;
height: 138mm;
background-color: #{{ $bgDarkHex }};
border-radius: 6px;
}
/* ── Logo: top-right, same proportional position as post PDF ── */
.logo-area {
position: absolute;
top: 6mm;
right: 7mm;
text-align: right;
}
.logo-area img {
max-height: 20mm;
max-width: 28mm;
}
.app-name {
font-size: 7pt;
color: #aaaaaa;
}
/* ── Categories: top-left, constrained so they never reach logo ── */
.categories {
position: absolute;
top: 9mm;
left: 9mm;
right: 46mm;
font-size: 6pt;
}
.badge-row {
display: block;
margin-bottom: 1.2mm;
}
.category-badge {
display: inline-block;
background-color: #{{ $tagColorHex }};
color: #000000;
padding: 2px 6px;
border-radius: 4px;
font-size: 6pt;
font-weight: normal;
line-height: 1;
}
.location-badge {
display: inline-block;
font-family: 'OswaldRegular', sans-serif;
color: #cccccc;
font-size: 6pt;
text-transform: uppercase;
}
.expiry {
display: block;
margin-top: 1.2mm;
font-size: 6pt;
color: #cccccc;
}
/* ── Title: large margin-top/bottom for breathing room, tight line-height within ── */
.title {
position: absolute;
top: 25mm;
left: 9mm;
right: 9mm;
font-family: 'Oswald', sans-serif;
font-size: 17pt;
font-weight: 600;
line-height: 0.95;
text-transform: uppercase;
color: #ffffff;
padding-top: 8mm;
padding-bottom: 3mm;
}
.status-label { color: #fc8181; }
/* ── Content: below title (25mm + 8mm + ~20mm text + 3mm = 56mm) ── */
.call-content {
position: absolute;
top: 56mm;
left: 9mm;
right: 9mm;
font-size: 9pt;
font-weight: bold;
line-height: 1.35;
color: #ffffff;
max-height: 22mm;
overflow: hidden;
}
/* ── Footer row: QR left + callable right, pinned to bottom ── */
.footer-panel {
position: absolute;
bottom: 9mm;
left: 9mm;
right: 9mm;
}
.footer-table {
width: 100%;
border-collapse: collapse;
}
.footer-qr-cell {
width: 14.5mm;
padding-right: 3mm;
vertical-align: bottom;
}
.footer-qr-cell img {
display: block;
width: 10.5mm;
height: 10.5mm;
}
.footer-callable-cell {
vertical-align: bottom;
text-align: right;
}
.callable-name {
font-family: 'Oswald', sans-serif;
font-weight: 600;
font-size: 10pt;
line-height: 0.95;
text-transform: uppercase;
color: #ffffff;
}
.callable-location {
font-family: 'OswaldRegular', sans-serif;
font-weight: normal;
font-size: 8pt;
line-height: 0.95;
text-transform: uppercase;
color: #cccccc;
margin-top: 1mm;
}
.footer-tagline {
margin-top: 2mm;
font-family: 'Poppins', sans-serif;
font-size: 5pt;
color: #aaaaaa;
text-align: left;
}
</style>
</head>
<body>
<div class="page">
{{-- Logo: top-right ── --}}
<div class="logo-area">
@if($logoBase64)
<img src="{{ $logoBase64 }}" alt="{{ config('app.name') }}">
@else
<div class="app-name">{{ config('app.name') }}</div>
@endif
</div>
{{-- Categories: top-left, never overlap logo ── --}}
<div class="categories">
@foreach($tagCategories as $cat)
<div class="badge-row"><span class="category-badge" style="background-color: #{{ $cat['colorHex'] ?? $tagColorHex }};">{{ $cat['name'] }}</span></div>
@endforeach
@if($callLocation)
<div class="badge-row"><span class="location-badge">{{ $callLocation }}</span></div>
@endif
@if($expiryBadgeText)
<div class="badge-row"><span class="location-badge">{{ $expiryBadgeText }}</span></div>
@endif
</div>
{{-- Title: below logo ── --}}
<div class="title">
@if($isDeleted)<span class="status-label">{{ $statusLabelDeleted }}: </span>
@elseif($call->is_suppressed)<span class="status-label">{{ $statusLabelBlocked }}: </span>
@elseif($call->is_paused)<span class="status-label">{{ $statusLabelPaused }}: </span>
@elseif($isExpired)<span class="status-label">{{ $statusLabelExpired }}: </span>
@endif{{ $call->tag?->translation?->name ?? $call->tag?->name }}
</div>
{{-- Content: below title ── --}}
@if($callContent)
<div class="call-content">{{ $callContent }}</div>
@endif
{{-- Footer: QR left + callable right, matching post PDF event footer ── --}}
<div class="footer-panel">
<table class="footer-table">
<tr>
@if($qrSvg)
<td class="footer-qr-cell">
<img src="{{ $qrSvg }}" alt="QR">
</td>
@endif
<td class="footer-callable-cell">
<div class="callable-name">{{ $call->callable?->name }}</div>
@if($callableLocation)
<div class="callable-location">{{ $callableLocation }}</div>
@endif
</td>
</tr>
</table>
<div class="footer-tagline">{{ config('app.name') }} &mdash; {{ timebank_config('footer.tagline') }}</div>
</div>
</div>
</body>
</html>
+138
View File
@@ -0,0 +1,138 @@
<x-guest-layout>
<x-slot name="header">
{{ trans_with_platform('@PLATFORM_NAME@ call') }}
</x-slot>
<div class="py-0 md:py-12" id="custom-timebank-style">
<div class="mx-auto max-w-7xl sm:px-6 lg:px-8">
<div class="overflow-hidden shadow-xl sm:rounded-lg relative bg-{{ $tagColor ?? 'gray' }}-400">
<div class="absolute inset-0 bg-black/50"></div>
{{-- Like button absolutely positioned top-right, matching event card full view --}}
<div class="absolute top-14 right-4 md:right-10 lg:right-14 z-30">
@livewire('reaction-button', [
'typeName' => 'like',
'showCounter' => true,
'reactionCounter' => $call->loveReactant?->reactionCounters->firstWhere('reaction_type_id', 3)?->count ?? 0,
'modelClass' => \App\Models\Call::class,
'modelId' => $call->id,
'size' => 'w-10 h-10',
'inverseColors' => true,
'redirectUrl' => url()->current(),
], key('like-call-' . $call->id))
</div>
<div class="relative p-6 sm:px-20 lg:px-32 lg:py-18">
{{-- Tag category badges + expiry --}}
<div class="mb-2 mt-0 md:mt-6 lg:mt-12">
<div class="flex flex-wrap items-center gap-2">
@foreach ($tagCategories as $cat)
<span class="bg-{{ $cat['color'] ?? 'gray' }}-400 inline-flex items-center rounded-md px-2 py-1 text-sm font-normal text-black">
{{ $cat['name'] }}
</span>
@endforeach
</div>
@if ($call->till)
<div class="mt-2 text-xs text-white/70">
{{ __('Expires') }}: {{ $call->till->translatedFormat('l d F Y') }}
</div>
@endif
@if ($call->is_suppressed)
<div class="mt-0.5 text-xs text-red-400">
{{ __('Publication blocked due to policy violation') }}
</div>
@endif
</div>
{{-- Title (tag name) --}}
<h2 class="mt-4 lg:mt-8 text-3xl lg:text-5xl font-semibold leading-tight text-white">
@if ($isDeleted)<span class="text-red-400">{{ __('DELETED') }}: </span>@elseif ($call->is_suppressed)<span class="text-red-400">{{ __('BLOCKED') }}: </span>@elseif ($call->is_paused)<span class="text-red-400">{{ __('PAUSED') }}: </span>@elseif ($isExpired)<span class="text-red-400">{{ __('EXPIRED') }}: </span>@endif{{ $call->tag?->translation?->name ?? $call->tag?->name }}
</h2>
{{-- Location + expiry badges --}}
@if ($callLocation || $expiryBadgeText)
<div class="mt-3 flex flex-wrap items-center gap-2">
@if ($callLocation)
<h4 class="inline-block items-center rounded-sm bg-black px-2 pb-1 pt-0.5 text-sm lg:text-base font-normal uppercase text-white">
{{ $callLocation }}
</h4>
@endif
@if ($expiryBadgeText)
<h4 class="inline-block items-center rounded-sm bg-black px-2 pb-1 pt-0.5 text-sm lg:text-base font-normal uppercase text-white">
{{ $expiryBadgeText }}
</h4>
@endif
</div>
@endif
{{-- Content --}}
@if ($callDescription)
<div class="mt-6">
<div class="px-0 py-2 text-xl lg:text-2xl leading-normal lg:leading-loose font-bold text-white">
{{ $callDescription }}
</div>
</div>
@endif
{{-- Callable profile block — hidden for private calls --}}
@if ($call->is_public && ($call->callable?->name || $callableLocation))
<div class="my-8 lg:my-12">
<div class="flex items-center gap-4">
@if ($call->callable?->profile_photo_url)
<div class="h-16 w-16 flex-shrink-0 rounded-full outline outline-1 outline-offset-1 outline-white/60 overflow-hidden">
<img src="{{ $call->callable->profile_photo_url }}"
alt=""
class="h-full w-full object-cover">
</div>
@endif
<div>
<div class="font-semibold text-lg text-white">{{ $call->callable?->name }}</div>
@if ($callableLocation)
<div class="text-sm text-white/70 mt-1">{{ $callableLocation }}</div>
@endif
</div>
</div>
</div>
@endif
</div>
{{-- Social share + respond button --}}
<div class="relative flex items-end justify-between gap-8 pl-6 sm:pl-20 lg:pl-32 pr-4 md:pr-10 lg:pr-14 mb-12">
{{-- Social share buttons (left, only when public and available) --}}
@if (!$isDeleted && !$isExpired && !$call->is_suppressed && !$call->is_paused && !$call->callable?->isRemoved())
<div class="flex flex-wrap gap-2">
@if ($call->is_public)
{!! Share::mastodon()
->bluesky()
->linkedin()
->instagram()
->facebook()
->whatsapp()
->text($call->tag?->translation?->name ?? $call->tag?->name ?? '')
->render() !!}
@endif
@if($call->is_public)
<a href="{{ route('call.pdf-a4-bw', ['id' => $call->id]) }}"
target="_blank"
title="{{ __('Print as PDF') }}"
class="inline-flex items-center justify-center rounded-md border border-theme-border bg-theme-surface p-2 transition-all duration-200 hover:opacity-80 focus:outline-none focus:ring-2 focus:ring-theme-surface focus:ring-offset-2">
<span class="inline-flex h-6 w-6 items-center justify-center">
<x-icon name="printer" class="h-5 w-5" solid />
</span>
</a>
@endif
</div>
@endif
{{-- Respond button (right) --}}
<a href="{{ route('login') }}">
<x-jetstream.button>
{{ __('Respond') }}
</x-jetstream.button>
</a>
</div>
</div>
</div>
</div>
</x-guest-layout>
+134
View File
@@ -0,0 +1,134 @@
<x-app-layout>
<x-slot name="header">
{{ trans_with_platform('@PLATFORM_NAME@ call') }}
</x-slot>
<div class="py-0 md:py-12" id="custom-timebank-style">
<div class="mx-auto max-w-7xl sm:px-6 lg:px-8">
<div class="overflow-hidden shadow-xl sm:rounded-lg relative bg-{{ $tagColor ?? 'gray' }}-400">
<div class="absolute inset-0 bg-black/50"></div>
{{-- Like button absolutely positioned top-right, matching event card full view --}}
<div class="absolute top-14 right-4 md:right-10 lg:right-14 z-30">
@livewire('reaction-button', [
'typeName' => 'like',
'showCounter' => true,
'reactionCounter' => $call->loveReactant?->reactionCounters->firstWhere('reaction_type_id', 3)?->count ?? 0,
'modelClass' => \App\Models\Call::class,
'modelId' => $call->id,
'size' => 'w-10 h-10',
'inverseColors' => true,
], key('like-call-' . $call->id))
</div>
<div class="relative p-6 sm:px-20 lg:px-32 lg:py-18">
{{-- Tag category badges + expiry --}}
<div class="mb-2 mt-0 md:mt-6 lg:mt-12">
<div class="flex flex-wrap items-center gap-2">
@foreach ($tagCategories as $cat)
<a href="{{ route('search.show') }}?category={{ $cat['id'] }}"
class="bg-{{ $cat['color'] ?? 'gray' }}-400 inline-flex items-center rounded-md px-2 py-1 text-sm font-normal text-black hover:opacity-80">
{{ $cat['name'] }}
</a>
@endforeach
</div>
@if ($call->till)
<div class="mt-2 text-xs text-white/70">
{{ __('Expires') }}: {{ $call->till->translatedFormat('l d F Y') }}
</div>
@endif
@if ($call->is_suppressed)
<div class="mt-0.5 text-xs text-red-400">
{{ __('Publication blocked due to policy violation') }}
</div>
@else
<div class="mt-0.5 text-xs text-white/70">
<a href="{{ route('static-report-issue', [], false) . '?' . http_build_query(['subject' => __('Call reported for policy review'), 'message' => trans_with_platform('Please review this call for @PLATFORM_NAME@ policy compliance.') . "\n\n" . url()->current()]) }}"
class="underline underline-offset-2 hover:text-white/90">{{ __('Report') }}</a>{{ __(' this call for policy review') }}
</div>
@endif
</div>
{{-- Title (tag name) --}}
<h2 class="mt-4 lg:mt-8 text-3xl lg:text-5xl font-semibold leading-tight text-white">
@if ($isDeleted)<span class="text-red-400">{{ __('DELETED') }}: </span>@elseif ($call->is_suppressed)<span class="text-red-400">{{ __('BLOCKED') }}: </span>@elseif ($call->is_paused)<span class="text-red-400">{{ __('PAUSED') }}: </span>@elseif ($isExpired)<span class="text-red-400">{{ __('EXPIRED') }}: </span>@endif{{ $call->tag?->translation?->name ?? $call->tag?->name }}
</h2>
{{-- Location + expiry badges --}}
@if ($callLocation || $expiryBadgeText)
<div class="mt-3 flex flex-wrap items-center gap-2">
@if ($callLocation)
<h4 class="inline-block items-center rounded-sm bg-black px-2 pb-1 pt-0.5 text-sm lg:text-base font-normal uppercase text-white">
{{ $callLocation }}
</h4>
@endif
@if ($expiryBadgeText)
<h4 class="inline-block items-center rounded-sm bg-black px-2 pb-1 pt-0.5 text-sm lg:text-base font-normal uppercase text-white">
{{ $expiryBadgeText }}
</h4>
@endif
</div>
@endif
{{-- Content --}}
@if ($callDescription)
<div class="mt-6">
<div class="px-0 py-2 text-xl lg:text-2xl leading-normal lg:leading-loose font-bold text-white">
{{ $callDescription }}
</div>
</div>
@endif
{{-- Callable profile block --}}
<div class="my-8 lg:my-12">
<a href="{{ $call->callable?->profile_url }}"
class="flex items-center gap-4 hover:opacity-80 cursor-pointer">
@if ($call->callable?->profile_photo_url)
<img src="{{ $call->callable->profile_photo_url }}"
alt="{{ $call->callable->name }}"
class="h-16 w-16 flex-shrink-0 rounded-full object-cover outline outline-1 outline-offset-1 outline-white/60">
@endif
<div>
<div class="font-semibold text-lg text-white">{{ $call->callable?->name }}</div>
@if ($callableLocation)
<div class="text-sm text-white/70 mt-1">{{ $callableLocation }}</div>
@endif
</div>
</a>
</div>
</div>
{{-- Social share + action buttons --}}
<div class="relative flex items-end justify-between gap-8 pl-6 sm:pl-20 lg:pl-32 pr-4 md:pr-10 lg:pr-14 mb-12">
{{-- Social share buttons (left, only when public and available) --}}
@if (!$isDeleted && !$isExpired && !$call->is_suppressed && !$call->is_paused && !$call->callable?->isRemoved())
<div class="flex flex-wrap gap-2">
@if ($call->is_public)
{!! Share::mastodon()
->bluesky()
->linkedin()
->instagram()
->facebook()
->whatsapp()
->text($call->tag?->translation?->name ?? $call->tag?->name ?? '')
->render() !!}
@endif
<a href="{{ route('call.pdf-a4-bw', ['id' => $call->id]) }}"
target="_blank"
title="{{ __('Print as PDF') }}"
class="inline-flex items-center justify-center rounded-md border border-theme-border bg-theme-surface p-2 transition-all duration-200 hover:opacity-80 focus:outline-none focus:ring-2 focus:ring-theme-surface focus:ring-offset-2">
<span class="inline-flex h-6 w-6 items-center justify-center">
<x-icon name="printer" class="h-5 w-5" solid />
</span>
</a>
</div>
@endif
{{-- Send message button (right) --}}
@livewire('calls.send-message-button', ['callable' => $call->callable, 'call' => $call], key('send-message-' . $call->id))
</div>
</div>
</div>
</div>
</x-app-layout>
@@ -0,0 +1,27 @@
<x-app-layout>
<x-slot name="header">
{{ __('Calls') }}
</x-slot>
<div class="py-6">
<div class="mx-auto max-w-7xl sm:px-6 lg:px-8">
<div class="overflow-hidden bg-white shadow-xl sm:rounded-lg">
<div class="border-b border-gray-200 bg-white p-6 sm:px-20">
<div class="mt-12">
<div class="text-5xl font-bold text-gray-900">
{{ __('This call is not available') }}
</div>
</div>
<div class="mb-12 mt-6">
<span class="text-xl text-gray-700">
{{ __('This call has expired or is currently not available.') }}
</span>
</div>
</div>
</div>
</div>
</div>
</x-app-layout>