<!DOCTYPE html>
<html lang="en" data-theme="dark">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Skylinks</title>
<!-- HTMX -->
<script src="https://cdn.jsdelivr.net/npm/htmx.org@2.0.8/dist/htmx.min.js"
integrity="sha384-/TgkGk7p307TH7EXJDuUlgG3Ce1UVolAOFopFekQkkXihi5u/6OCvVKyz1W+idaz"
crossorigin="anonymous"></script>
<script src="https://unpkg.com/hyperscript.org@0.9.12"></script>
<!-- Tailwind CSS & Daisy UI -->
<link href="https://cdn.jsdelivr.net/npm/daisyui@5" rel="stylesheet" type="text/css" />
<link href="https://cdn.jsdelivr.net/npm/daisyui@5/themes.css" rel="stylesheet" type="text/css" />
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>
<!-- Sortable (kept for parity with Hacknight setup) -->
<script src="https://cdn.jsdelivr.net/npm/sortablejs@latest/Sortable.min.js"></script>
</head>
<body class="min-h-screen bg-base-200 text-base-content">
<div class="mx-auto w-full max-w-4xl px-4 sm:px-6 py-8 space-y-6">
<header class="text-center space-y-3">
<h1 class="text-3xl sm:text-4xl font-bold">Skylinks</h1>
<p class="text-base sm:text-lg text-base-content/70">Link anywhere on The Skyscape and beyond!</p>
</header>
<section class="card bg-base-100 shadow-xl">
{{with CurrentUser}}
<form method="post" action="/links" class="card-body space-y-5" hx-post="/links" hx-swap="none">
<div class="flex items-center gap-4 justify-between">
<a href="https://theskyscape.com/user/{{ .Handle }}"
class="btn btn-ghost btn-lg gap-3 items-center justify-start min-w-0" target="_blank"
rel="noopener noreferrer">
<div class="avatar">
<div class="w-9 h-9 p-1 rounded-full border border-white/20 bg-base-100 shadow">
<img src="{{ .Avatar }}" alt="{{ .Handle }} avatar" class="rounded-full">
</div>
</div>
<div class="min-w-0 text-left">
<p class="text-xs uppercase tracking-[0.16em] text-base-content/60">Signed in</p>
<p class="text-base font-semibold truncate">@{{ .Handle }}</p>
</div>
</a>
<a href="/auth/logout" class="btn btn-soft btn-error btn-sm sm:btn-md">Sign out</a>
</div>
<div class="space-y-2">
<label class="label">
<span class="label-text font-semibold">Target URL</span>
<span class="label-text-alt text-error">*</span>
</label>
<input type="url" name="target_url" placeholder="https://example.com/articles/123"
class="input input-bordered w-full text-sm sm:text-base" required>
</div>
<div class="flex flex-col gap-4 md:flex-row md:items-end">
<div class="flex-1 space-y-2">
<label class="label">
<span class="label-text font-semibold">Custom short code</span>
<span class="label-text-alt">optional</span>
</label>
<input type="text" name="short_code" placeholder="cool-link"
class="input input-bordered w-full text-sm sm:text-base">
<p class="text-xs text-base-content/60">Leave blank to auto-generate; letters, numbers, dash, underscore.
</p>
</div>
<button type="submit" class="btn btn-primary w-full md:w-auto md:self-center">
Create Link
</button>
</div>
</form>
{{else}}
<div class="card-body space-y-5">
<div class="space-y-2">
<p class="text-xs uppercase tracking-[0.18em] text-primary font-semibold">Sign in required</p>
<h2 class="text-xl sm:text-2xl font-semibold">
Use The Skyscape OAuth to create links
</h2>
<p class="text-sm sm:text-base text-base-content/70">
Connect your Skyscape Profile through the secure OAuth flow
to start making short codes and keep them tied to your profile.
</p>
</div>
<div class="grid gap-3 sm:grid-cols-2">
<div class="flex items-center gap-2 text-sm text-base-content/70">
<span class="badge badge-outline badge-primary">Secure</span>
Sign-in is handled entirely by The Skyscape
</div>
<div class="flex items-center gap-2 text-sm text-base-content/70">
<span class="badge badge-outline">Fast</span>
Use your Skyscape profile in Skylinks
</div>
</div>
<div class="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-end sm:gap-4">
<a href="/auth/signin" class="btn btn-primary w-full sm:w-auto sm:ml-auto">Sign In with The Skyscape</a>
</div>
</div>
{{end}}
</section>
<section class="space-y-3">
<div class="flex items-center justify-between">
<h2 class="text-2xl font-semibold">Recently created</h2>
<span class="text-sm text-base-content/70">Newest first</span>
</div>
{{with $recent := links.RecentLinks}}
<div class="grid gap-4 sm:grid-cols-2">
{{range $recent}}
<div class="card bg-base-100 shadow-md border border-base-200 overflow-hidden">
<div class="card-body space-y-3">
{{ $link := . }}
{{ $owner := $link.User }}
<div class="flex items-center justify-between gap-3">
<a href="https://theskyscape.com/user/{{ $owner.Handle }}"
class="btn btn-ghost btn-sm px-2 sm:px-3 gap-2 items-center justify-start min-w-0"
target="_blank" rel="noopener noreferrer">
<div class="avatar">
<div class="w-8 h-8 rounded-full border border-white/20 p-0.5">
<img src="{{ $owner.Avatar }}" alt="{{ $owner.Handle }} avatar" class="rounded-full">
</div>
</div>
<p class="text-xs font-semibold truncate">@{{ $owner.Handle }}</p>
</a>
{{if $link.CanDelete CurrentUser}}
<div class="dropdown dropdown-end">
<div tabindex="0" role="button" class="btn btn-ghost btn-sm btn-circle">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-5 h-5">
<path
d="M6.75 12a1.25 1.25 0 1 1-2.5 0 1.25 1.25 0 0 1 2.5 0Zm6 0a1.25 1.25 0 1 1-2.5 0 1.25 1.25 0 0 1 2.5 0Zm6 0a1.25 1.25 0 1 1-2.5 0 1.25 1.25 0 0 1 2.5 0Z" />
</svg>
</div>
<ul tabindex="0" class="dropdown-content menu p-2 shadow bg-base-100 rounded-box w-32">
<li>
<button type="button" class="text-error w-full text-left" hx-delete="/links/{{ .ID }}"
hx-swap="none" hx-confirm="Delete this link?">
Delete
</button>
</li>
</ul>
</div>
{{end}}
</div>
<div class="flex flex-col gap-1">
<h3 class="text-sm uppercase tracking-wider font-bold text-base-content/70">{{ .ShortCode }}</h3>
<a href="/{{ .ShortCode }}" class="mt-2 text-sm text-base-content/90 truncate underline" target="_blank">
{{ .DisplayURL }}
</a>
</div>
<div class="card-actions flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between mt-2">
<code class="text-xs text-base-content/60 text-center sm:text-right">
{{ .CreatedAtPST }}
</code>
<div class="flex flex-col w-full sm:w-auto sm:flex-row sm:gap-3 gap-2">
<button class="btn btn-outline btn-sm w-full sm:w-auto" aria-label="Copy short link" _="on click call navigator.clipboard.writeText(window.location.origin + '/{{ .ShortCode }}')
then put 'Copied!' into me.innerText
then add .btn-success to me
then wait 1s
then put 'Copy' into me.innerText
then remove .btn-success from me">
Copy
</button>
<a class="btn btn-primary btn-sm w-full sm:w-auto" href="/{{ .ShortCode }}" target="_blank"
rel="noopener noreferrer">
Open
</a>
</div>
</div>
</div>
</div>
{{end}}
</div>
{{else}}
<div class="p-8 text-center text-base-content/70 border border-dashed border-base-300 rounded-xl">
No links yet — submit your first target URL above.
</div>
{{end}}
</section>
</div>
</body>
</html>