<!doctype html>

<html lang="en">

<head>

  <meta charset="utf-8" />

  <meta name="viewport" content="width=device-width,initial-scale=1" />

  <title>DJ Requests</title>

  <style>

    :root{--bg:#0b1020;--bg2:#070b12;--card:rgba(255,255,255,.07);--line:rgba(255,255,255,.12);--txt:rgba(255,255,255,.92);--mut:rgba(255,255,255,.65)}

    *{box-sizing:border-box;font-family:system-ui,-apple-system,Segoe UI,Roboto,Arial}

    body{margin:0;min-height:100vh;color:var(--txt);

      background: radial-gradient(900px 500px at 15% 10%, rgba(124,58,237,.35), transparent 60%),

                  radial-gradient(900px 500px at 85% 20%, rgba(34,197,94,.22), transparent 55%),

                  linear-gradient(180deg,var(--bg),var(--bg2))}

    .wrap{width:min(1100px,92vw);margin:26px auto 50px}

    header{display:flex;justify-content:space-between;gap:14px;align-items:flex-end}

    h1{margin:0;font-size:34px}

    p{margin:6px 0 0;color:var(--mut)}

    .card{margin-top:14px;background:linear-gradient(180deg,var(--card),rgba(255,255,255,.04));

      border:1px solid var(--line);border-radius:18px;padding:16px;backdrop-filter:blur(10px)}

    .pill{display:inline-flex;gap:10px;align-items:center;padding:10px 14px;border-radius:999px;

      border:1px solid var(--line);background:rgba(255,255,255,.06);color:var(--txt);text-decoration:none;cursor:pointer}

    .grid{display:grid;grid-template-columns:1fr 1fr;gap:12px}

    label span{display:block;color:var(--mut);font-size:12px;margin:2px 0 7px}

    input,select,textarea{width:100%;border-radius:14px;border:1px solid var(--line);

      background:rgba(0,0,0,.22);color:var(--txt);padding:12px;outline:none}

    textarea{min-height:90px;resize:vertical}

    .span2{grid-column:1/-1}

    .btn{margin-top:12px;width:100%;border:none;border-radius:16px;padding:14px 16px;

      background:linear-gradient(90deg, rgba(124,58,237,.85), rgba(34,197,94,.70));

      color:white;font-weight:800;cursor:pointer;display:flex;justify-content:space-between}

    .tiny{margin:10px 2px 0;color:var(--mut);font-size:12px}

    .row{display:flex;gap:10px;flex-wrap:wrap}

    .chips button{border-radius:999px;border:1px solid var(--line);background:rgba(255,255,255,.05);

      color:var(--txt);padding:9px 12px;cursor:pointer}

    .chips button.active{border-color:rgba(124,58,237,.65);background:rgba(124,58,237,.18)}

    .list{display:grid;gap:12px;margin-top:12px}

    .item{border-radius:18px;border:1px solid var(--line);background:rgba(255,255,255,.06);padding:14px;display:flex;justify-content:space-between;gap:14px}

    .badge{font-size:12px;border:1px solid var(--line);border-radius:999px;padding:6px 10px;color:var(--mut);background:rgba(0,0,0,.2);display:inline-block;margin-right:8px}

    .title{margin:8px 0 6px;font-size:18px;line-height:1.2}

    .note{margin:10px 0 0;color:rgba(255,255,255,.78)}

    .actions button{border-radius:14px;border:1px solid var(--line);background:rgba(255,255,255,.06);color:var(--txt);padding:10px 12px;cursor:pointer}

  </style>

</head>

<body>

  <div class="wrap">

    <header>

      <div>

        <h1>DJ Requests</h1>

        <p>Works on any network. Guests submit. DJ view updates live.</p>

      </div>

      <div class="row">

        <a class="pill" href="#guest">Guest</a>

        <a class="pill" href="#dj">DJ View</a>

      </div>

    </header>


    <section id="guest" class="card">

      <h2 style="margin:0 0 6px;font-size:16px">Guest page</h2>

      <form id="form">

        <div class="grid">

          <label><span>Your name</span><input name="name" maxlength="40" placeholder="Mike / Sarah / Table 7"/></label>

          <label><span>Type</span>

            <select name="type">

              <option value="song">Song request</option>

              <option value="karaoke">Karaoke request</option>

              <option value="message">Message</option>

            </select>

          </label>

          <label class="span2" data-show="song karaoke"><span>Artist</span><input name="artist" maxlength="60" placeholder="Queen"/></label>

          <label class="span2" data-show="song karaoke"><span>Song</span><input name="title" maxlength="60" placeholder="Don’t Stop Me Now"/></label>

          <label class="span2" data-show="message song karaoke"><span>Note (optional)</span><textarea name="note" maxlength="180" placeholder="Dedication, vibe, karaoke chaos..."></textarea></label>

        </div>

        <button class="btn" type="submit"><span>Send request</span><span>↯</span></button>

        <div class="tiny" id="status"></div>

      </form>

    </section>


    <section id="dj" class="card">

      <div class="row" style="justify-content:space-between;align-items:flex-end">

        <div>

          <h2 style="margin:0 0 6px;font-size:16px">DJ view (screen-share this)</h2>

          <div class="tiny" id="count"></div>

        </div>

        <div class="chips" id="chips">

          <button class="active" data-f="all">All</button>

          <button data-f="song">Songs</button>

          <button data-f="karaoke">Karaoke</button>

          <button data-f="message">Messages</button>

          <button data-f="new">Unplayed</button>

          <button data-f="played">Played</button>

        </div>

      </div>

      <div class="list" id="list"></div>

    </section>

  </div>


  <script type="module">

    import { createClient } from "https://cdn.jsdelivr.net/npm/@supabase/supabase-js@2/+esm";


    const SUPABASE_URL = "PASTE_SUPABASE_URL";

    const SUPABASE_ANON_KEY = "PASTE_SUPABASE_ANON_KEY";


    const supabase = createClient(SUPABASE_URL, SUPABASE_ANON_KEY);


    const $ = (s)=>document.querySelector(s);

    const $$ = (s)=>Array.from(document.querySelectorAll(s));

    const esc = (s)=>String(s??"").replaceAll("&","&amp;").replaceAll("<","&lt;").replaceAll(">","&gt;");


    let all = [];

    let filter = "all";


    function applyTypeVisibility(){

      const form = $("#form");

      const type = form.type.value;

      $$("[data-show]").forEach(el=>{

        const allowed = el.getAttribute("data-show").split(" ");

        el.style.display = allowed.includes(type) ? "" : "none";

      });

    }


    async function load(){

      const { data, error } = await supabase

        .from("requests")

        .select("*")

        .order("created_at", { ascending: false })

        .limit(300);

      if (!error) all = data || [];

      render();

    }


    function render(){

      let items = [...all];

      if (["song","karaoke","message"].includes(filter)) items = items.filter(r=>r.type===filter);

      if (["new","played"].includes(filter)) items = items.filter(r=>r.status===filter);


      $("#count").textContent = `${items.length} showing · ${all.length} total`;


      $("#list").innerHTML = items.map(r=>{

        const label = r.type === "song" ? "Song" : r.type === "karaoke" ? "Karaoke" : "Message";

        const who = esc(r.name || "Anonymous");

        const time = new Date(r.created_at).toLocaleTimeString([], {hour:"2-digit", minute:"2-digit"});

        const mainTitle = r.type === "message"

          ? esc(r.note || "(no message)")

          : `${esc(r.artist || "Unknown artist")} · ${esc(r.title || "Unknown song")}`;


        return `

          <div class="item" data-id="${r.id}">

            <div>

              <div>

                <span class="badge">${label}</span>

                <span class="badge">${who}</span>

                <span class="badge">${time}</span>

                ${r.status === "played" ? `<span class="badge">Played</span>` : ``}

              </div>

              <div class="title">${mainTitle}</div>

              ${r.type !== "message" && r.note ? `<div class="note">Note: ${esc(r.note)}</div>` : ``}

            </div>

            <div class="actions">

              <button data-a="toggle">${r.status==="played" ? "Unplay" : "Played"}</button>

            </div>

          </div>

        `;

      }).join("");


      $$("#list .item").forEach(el=>{

        el.addEventListener("click", async (e)=>{

          const btn = e.target.closest("button");

          if (!btn) return;

          const id = el.getAttribute("data-id");

          const rec = all.find(x=>x.id===id);

          const next = rec.status === "played" ? "new" : "played";

          await supabase.from("requests").update({ status: next }).eq("id", id);

        });

      });

    }


    $("#chips").addEventListener("click",(e)=>{

      const b = e.target.closest("button");

      if(!b) return;

      filter = b.getAttribute("data-f");

      $$("#chips button").forEach(x=>x.classList.toggle("active", x===b));

      render();

    });


    const form = $("#form");

    applyTypeVisibility();

    form.type.addEventListener("change", applyTypeVisibility);


    form.addEventListener("submit", async (e)=>{

      e.preventDefault();

      const payload = {

        name: form.name.value?.trim() || "Anonymous",

        type: form.type.value,

        artist: form.artist?.value?.trim() || null,

        title: form.title?.value?.trim() || null,

        note: form.note?.value?.trim() || null

      };


      if ((payload.type==="song"||payload.type==="karaoke") && (!payload.artist || !payload.title)){

        $("#status").textContent = "Add artist + song title so the DJ isn’t forced to guess.";

        return;

      }

      if (payload.type==="message" && !payload.note){

        $("#status").textContent = "Type a message.";

        return;

      }


      const { error } = await supabase.from("requests").insert(payload);

      $("#status").textContent = error ? "Didn’t send. Try again." : "Sent ↯";

      if (!error){ form.artist.value=""; form.title.value=""; form.note.value=""; }

    });


    supabase.channel("requests-live")

      .on("postgres_changes", { event: "*", schema: "public", table: "requests" }, () => load())

      .subscribe();


    load();

  </script>

</body>

</html>