caddy-git-server

Caddy module that provides a git server.

<!DOCTYPE html>
<html class="h-full bg-gray-100">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="https://cdn.tailwindcss.com"></script>
    <!-- <script src="https://cdn.jsdelivr.net/npm/@tailwindplus/elements@1" type="module"></script> -->
    <!-- <link rel="stylesheet" href="/assets/style.css"> -->

    <title>{{.Name}}{{ if ne .Page "home" }} - {{.Page}}{{ end }} - {{ .Host }}</title>
</head>
<body class="h-full">
<div class="min-h-full">
  <nav class="bg-gray-800">
    <div class="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
      <div class="flex h-16 items-center justify-between">
        <div class="flex items-center">
          <div class="shrink-0">
            <a href="/{{ .Root }}">
              <img class="size-8" src="/assets/cgs-icon.png" alt="caddy-git-server" />
            </a>
          </div>
          <div class="hidden md:block">
            <div class="ml-10 flex items-baseline space-x-4">
              <!-- Current: "bg-gray-900 text-white", Default: "text-gray-300 hover:bg-gray-700 hover:text-white" -->
              <a href="/{{.Root}}{{with .Query}}?{{.}}{{end}}" class="rounded-md px-3 py-2 text-sm font-medium {{ if eq .Page "home" }}text-white bg-gray-900" aria-current="page"{{else}}text-gray-300 hover:bg-gray-700 hover:text-white"{{end}}>Home</a>
              <a href="/{{.Root}}/log{{with .Query}}?{{.}}{{end}}" class="rounded-md px-3 py-2 text-sm font-medium {{ if eq .Page "log" }}text-white bg-gray-900" aria-current="page"{{else}}text-gray-300 hover:bg-gray-700 hover:text-white"{{end}}>Log</a>
              <a href="/{{.Root}}/tree{{with .Query}}?{{.}}{{end}}" class="rounded-md px-3 py-2 text-sm font-medium {{ if eq .Page "tree" }}text-white bg-gray-900" aria-current="page"{{else}}text-gray-300 hover:bg-gray-700 hover:text-white"{{end}}>Tree</a>
            </div>
          </div>
        </div>

        <div class="hidden md:block">
          <div class="ml-4 flex items-center md:ml-6">
            <code class="rounded-md px-3 py-2 text-sm text-right text-white bg-gray-900">
              <span class="inline-block">git clone</span>
              <span class="inline-block select-all font-semibold">{{.CloneURL}}</span>
            </code>
          </div>
        </div>

        <div class="-mr-2 flex md:hidden">
          <!-- Mobile menu button -->
          <button type="button" id="mobile-menu-button" class="relative inline-flex items-center justify-center rounded-md bg-gray-800 p-2 text-gray-400 hover:bg-gray-700 hover:text-white focus:ring-2 focus:ring-white focus:ring-offset-2 focus:ring-offset-gray-800 focus:outline-hidden" aria-controls="mobile-menu" aria-expanded="false">
            <span class="absolute -inset-0.5"></span>
            <span class="sr-only">Open main menu</span>
            <!-- Menu open: "hidden", Menu closed: "block" -->
            <svg id="mobile-menu-open" class="block size-6" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" aria-hidden="true" data-slot="icon">
              <path stroke-linecap="round" stroke-linejoin="round" d="M3.75 6.75h16.5M3.75 12h16.5m-16.5 5.25h16.5" />
            </svg>
            <!-- Menu open: "block", Menu closed: "hidden" -->
            <svg id="mobile-menu-close" class="hidden size-6" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" aria-hidden="true" data-slot="icon">
              <path stroke-linecap="round" stroke-linejoin="round" d="M6 18 18 6M6 6l12 12" />
            </svg>
          </button>
        </div>
      </div>
    </div>

    <!-- Mobile menu, show/hide based on menu state. -->
    <div class="hidden" id="mobile-menu">
      <div class="space-y-1 px-2 pt-2 pb-3 sm:px-3">
        <!-- Current: "bg-gray-900 text-white", Default: "text-gray-300 hover:bg-gray-700 hover:text-white" -->
        <a href="/{{.Root}}{{with .Query}}?{{.}}{{end}}" class="block rounded-md px-3 py-2 text-base font-medium {{ if eq .Page "home" }}text-white bg-gray-900" aria-current="page"{{else}}text-gray-300 hover:bg-gray-700 hover:text-white"{{end}}>Home</a>
        <a href="/{{.Root}}/log{{with .Query}}?{{.}}{{end}}" class="block rounded-md px-3 py-2 text-base font-medium {{ if eq .Page "log" }}text-white bg-gray-900" aria-current="page"{{else}}text-gray-300 hover:bg-gray-700 hover:text-white"{{end}}>Log</a>
        <a href="/{{.Root}}/tree{{with .Query}}?{{.}}{{end}}" class="block rounded-md px-3 py-2 text-base font-medium {{ if eq .Page "tree" }}text-white bg-gray-900" aria-current="page"{{else}}text-gray-300 hover:bg-gray-700 hover:text-white"{{end}}>Tree</a>
      </div>
    </div>
    <script>
      document.addEventListener('DOMContentLoaded', function(){
        let menu = document.getElementById('mobile-menu');
        let menu_close = document.getElementById('mobile-menu-close');
        let menu_open = document.getElementById('mobile-menu-open');
  
        document.getElementById('mobile-menu-button').addEventListener('click', event => {
          menu.classList.toggle('hidden');
          menu_close.classList.toggle('hidden');
          menu_close.classList.toggle('block');
          menu_open.classList.toggle('hidden');
          menu_open.classList.toggle('block');
          menu.blur();
        });
      })
    </script>
  </nav>

  <main>
    <div class="mx-auto max-w-7xl px-8 sm:px-12 lg:px-16 pt-6 flow-root">
        <div class="-mx-4 -my-2 overflow-x-auto sm:-mx-6 lg:-mx-8">
          <div class="inline-block min-w-full py-2 align-middle sm:px-6 lg:px-8">
            <div class="overflow-hidden shadow-sm ring-1 ring-black/5 sm:rounded-lg divide-y divide-gray-300">
                <div class="py-3.5 px-4 sm:px-6 bg-white">
                  <p class="text-3xl font-bold inline-block">
                    {{.Name}}
                  </p>
                  <div class="inline-block float-right items-center">
                    <div class="mt-2 grid grid-cols-1">
                      <select id="location" name="location" onchange="location = this.value;" class="col-start-1 row-start-1 w-full appearance-none rounded-md bg-white pr-8 pl-3 text-sm text-gray-900 border border-gray-300 focus:border-grey-500 sm:text-sm/6">
                        {{ $ref := .RefString }}
                        {{ range .Branches }}
                          <option class="bg-black" value="?branch={{base .Name}}"{{if eq (print "refs/heads/" .Name) $ref}} selected{{end}}>{{.Name}}</option>
                        {{ end }}
                        {{ range .Tags }}
                          <option value="?tag={{base .Name}}"{{if eq (print "refs/tags/" .Name) $ref}} selected{{end}}>tags/{{.Name}}</option>
                        {{ end }}
                      </select>
                      <svg viewBox="0 0 16 16" fill="currentColor" data-slot="icon" aria-hidden="true" class="pointer-events-none col-start-1 row-start-1 mr-2 size-5 self-center justify-self-end text-gray-500 sm:size-4">
                        <path d="M4.22 6.22a.75.75 0 0 1 1.06 0L8 8.94l2.72-2.72a.75.75 0 1 1 1.06 1.06l-3.25 3.25a.75.75 0 0 1-1.06 0L4.22 7.28a.75.75 0 0 1 0-1.06Z" clip-rule="evenodd" fill-rule="evenodd" />
                      </svg>
                    </div>
                  </div>
                  <p class="inline-block pl-4 pt-2 text-gray-500">{{.Tagline}}</p>
                </div>
            </div>
          </div>
        </div>
    </div>
    <div class="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
      <!-- Your content -->
       {{ template "page" . }}
    </div>
  </main>

  <footer class="bg-gray-300 mt-6 sticky top-[100vh]">
    <div class="px-3 py-2 font-medium text-large text-gray-800 text-center">
      hosted with
      <a href="https://git.mckinnon.ninja/caddy-git-server" class="underline">
      caddy-git-server</a>
    </div>
  </footer>
</div>
</body>
</html>