lthn.io/app/Mod/Names/Views/show.blade.php
Claude 8f9c1f282e
feat: email notifications on claim approval + OG images for names
ClaimApproved mailable sent when admin approves a claim — dark
themed HTML email with name, next steps, and CTA links. Wrapped
in try/catch so email failure doesn't block approval.

Dynamic SVG OpenGraph images at /names/{name}/og.svg — shows name,
type badge (Registered/Reserved/Gateway/Available), and branding.
og:image meta tag added to name detail pages via @push('head').

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 12:20:43 +01:00

147 lines
7.2 KiB
PHP

@extends('lethean::layout')
@section('title', $name . '.lthn')
@section('meta_description', $name . '.lthn — blockchain domain name registered on the Lethean network. ' . ($alias['comment'] ?? ''))
@push('head')
<meta property="og:image" content="{{ url('/names/' . $name . '/og.svg') }}">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
@endpush
@section('content')
<div class="section" style="max-width: 900px; margin: 0 auto;">
<h2 style="margin-bottom: 0.25rem;"><span style="color: var(--accent);">{{ $name }}</span>.lthn</h2>
<p style="color: var(--muted); margin-bottom: 2rem;">Registered on the Lethean blockchain</p>
@php
$address = $alias['address'] ?? '';
$registrarWallets = [
'iTHNHN11yXMeBphpFSuHnDaSJ15QxiSEJXNY59VKbxKq4ype4xAH1PZHd1EKTknkPK9hHTu2G2tBBZzvrcRFaYMF8vWTzFZjGY' => '@LetheanRegistry',
'iTHNUNiuu3VP1yy8xH2y5iQaABKXurdjqZmzFiBiyR4dKG3j6534e9jMriY6SM7PH8NibVwVWW1DWJfQEWnSjS8n3Wgx86pQpY' => '@LetheanTestnet',
];
$isRegistryOwned = isset($registrarWallets[$address]);
$isCommunityMember = !$isRegistryOwned && !empty($address);
$displayAddress = $registrarWallets[$address] ?? (strlen($address) > 20 ? substr($address, 0, 12) . '...' . substr($address, -12) : $address);
$comment = $alias['comment'] ?? '';
$parsed = [];
foreach (explode(';', $comment) as $pair) {
$parts = explode('=', $pair, 2);
if (count($parts) === 2) $parsed[$parts[0]] = $parts[1];
}
$type = $parsed['type'] ?? 'user';
$reason = $parsed['reason'] ?? '';
@endphp
<div class="card-grid">
<div class="card">
<h3>Owner</h3>
<p>
<code title="{{ $address }}" style="font-size: 0.9rem; color: var(--accent);">{{ $displayAddress }}</code>
</p>
<p style="margin-top: 0.5rem;">
@if($isCommunityMember)
<span class="badge badge-amber" style="font-size: 0.75rem;">Community Member</span>
<span style="color: var(--muted); font-size: 0.75rem; display: block; margin-top: 0.25rem;">CIC governance participant</span>
@elseif($isRegistryOwned)
<span class="badge badge-green" style="font-size: 0.75rem;">Registry Managed</span>
@endif
</p>
</div>
<div class="card">
<h3>Type</h3>
<p>
@if($type === 'reserved')
<span class="badge badge-amber">Reserved</span>
@if($reason) <span style="color: var(--muted); font-size: 0.85rem;">&mdash; {{ $reason }}</span> @endif
@elseif($type === 'gateway')
<span class="badge badge-green">Gateway</span>
@elseif($type === 'service')
<span class="badge badge-green">Service</span>
@elseif($type === 'exit')
<span class="badge badge-green">Exit Node</span>
@else
<span class="badge badge-green">User</span>
@endif
</p>
@if(!empty($address) && !$isRegistryOwned)
<p style="margin-top: 0.75rem;">
<span style="color: var(--muted); font-size: 0.75rem;">Wallet</span><br>
<code style="font-size: 0.7rem; word-break: break-all; color: var(--muted);">{{ $address }}</code>
</p>
@endif
</div>
</div>
@if(!empty($parsed['cap']))
<div class="card" style="margin-top: 1rem;">
<h3>Capabilities</h3>
<p>
@foreach(explode(',', $parsed['cap']) as $cap)
<span class="badge badge-green" style="margin-right: 0.25rem;">{{ trim($cap) }}</span>
@endforeach
</p>
</div>
@endif
@if(!empty($records))
<div class="card" style="margin-top: 1rem;">
<h3>DNS Records</h3>
<table style="width: 100%; border-collapse: collapse; margin-top: 0.5rem;">
<tr style="border-bottom: 1px solid var(--border); text-align: left;">
<th style="padding: 0.4rem; color: var(--muted); font-size: 0.75rem; width: 60px;">TYPE</th>
<th style="padding: 0.4rem; color: var(--muted); font-size: 0.75rem;">HOST</th>
<th style="padding: 0.4rem; color: var(--muted); font-size: 0.75rem;">VALUE</th>
</tr>
@foreach($records as $record)
<tr style="border-bottom: 1px solid var(--border);">
<td style="padding: 0.4rem;"><span class="badge badge-green" style="font-size: 0.65rem;">{{ $record['type'] ?? '?' }}</span></td>
<td style="padding: 0.4rem; font-size: 0.85rem;"><code>{{ $record['host'] ?? '@' }}</code></td>
<td style="padding: 0.4rem; font-size: 0.85rem; color: var(--muted);">{{ $record['value'] ?? '' }}</td>
</tr>
@endforeach
</table>
</div>
@endif
@if(!empty($parsed['hns']))
<div class="card" style="margin-top: 1rem;">
<h3>ITNS Sidechain</h3>
<p style="color: var(--muted); font-size: 0.85rem;">
Registered on the ITNS sidechain as <code style="color: var(--accent);">{{ $parsed['hns'] }}</code>
</p>
</div>
@endif
@if($type === 'reserved')
<div class="card" style="margin-top: 1rem; border-left: 4px solid var(--amber); background: rgba(251,191,36,0.05);">
<h3>Sunrise Period</h3>
<p style="color: var(--muted); line-height: 1.6;">
<strong>{{ $name }}.lthn</strong> is reserved during the .lthn sunrise period. This name is protected to give the rightful brand owner the opportunity to claim their identity on the Lethean blockchain.
</p>
<p style="margin-top: 1rem; display: flex; gap: 0.75rem; flex-wrap: wrap;">
<a href="https://order.lthn.ai/order/forms/a/6" class="api-link">Fast Track $49 BTC &rarr;</a>
<a href="/sunrise" class="api-link" style="background: var(--surface); border: 1px solid var(--border);">About the Sunrise Period</a>
<a href="mailto:developers@lethean.io?subject=Sunrise%20Enquiry:%20{{ $name }}.lthn" class="api-link" style="background: var(--surface); border: 1px solid var(--border);">Enquire</a>
</p>
</div>
@elseif($type !== 'reserved')
<div class="card" style="margin-top: 1rem;">
<h3>Services</h3>
<div style="display: flex; gap: 1rem; flex-wrap: wrap; margin-top: 0.5rem;">
<a href="/services/dns-hosting" style="color: var(--link); font-size: 0.85rem;">DNS Hosting</a>
<a href="/services/ssl" style="color: var(--link); font-size: 0.85rem;">SSL Certificates</a>
@if($type === 'gateway' || !empty($parsed['cap']))
<a href="/services/residential-proxy" style="color: var(--link); font-size: 0.85rem;">Proxy Services</a>
@endif
</div>
</div>
@endif
<div style="margin-top: 2rem; display: flex; gap: 1.5rem;">
<a href="/names">&larr; Back to directory</a>
<a href="/v1/names/lookup/{{ $name }}">API lookup &rarr;</a>
<a href="/v1/names/records/{{ $name }}">DNS records API &rarr;</a>
</div>
</div>
@endsection