home.html
html
<!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>
No comments yet.