PageSourceSearch

https://watchpartyradar.com/submit/

html watchpartyradar.com collected 2026-10-06 18:51:13 UTC 10,794 bytes, 191 lines download raw bytes

1<!doctype html>
2<html lang="en">
3<head>
4  <meta charset="utf-8" />
5  
5<script>(function(){try{var h=location.hostname;if(h==="worldcup.dashmote.com"||h==="wc26party.com"||h==="www.wc26party.com"||h==="dashmote-worldcup.web.app"){location.replace("https://watchpartyradar.com"+location.pathname+location.search+location.hash);}}catch(e){}})();</script>
5
6  <meta name="viewport" content="width=device-width, initial-scale=1" />
7  <title>Submit a Watch Party | World Cup Watch Party Radar</title>
8  <meta name="description" content="Know a bar, pub or fan zone showing the 2026 World Cup? Submit it to the World Cup Watch Party Radar and help fans find it." />
9  <meta name="robots" content="noindex, follow" />
10  <link rel="canonical" href="https://watchpartyradar.com/submit/" />
11  <link rel="icon" type="image/png" href="/icon.png" sizes="any" />
12  <link rel="apple-touch-icon" href="/apple-touch-icon.png" />
13  <link rel="preconnect" href="https://fonts.googleapis.com" />
14  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
15  <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&family=Space+Grotesk:wght@600;700&display=swap" rel="stylesheet" />
16  <style>
17    :root { --navy:#040433; --blue:#0e49b5; --muted:#747488; --border:#e8e8f0; --bg:#ffffff; --bg-soft:#f7f7fb; }
18    * { box-sizing:border-box; margin:0; padding:0; }
19    body { font-family:"Inter",system-ui,sans-serif; color:var(--navy); background:var(--bg); -webkit-font-smoothing:antialiased; }
20    .top { height:60px; display:flex; align-items:center; padding:0 1.1rem; border-bottom:1px solid var(--border); gap:.6rem; }
21    .wordmark { font-family:"Space Grotesk",sans-serif; font-weight:700; font-size:1.05rem; color:var(--navy); text-decoration:none; }
22    .wordmark span { color:var(--blue); }
23    .crumb { color:var(--muted); font-size:.85rem; }
24    main { max-width:640px; margin:0 auto; padding:1.6rem 1.1rem 4rem; }
25    h1 { font-family:"Space Grotesk",sans-serif; font-size:1.45rem; letter-spacing:-.02em; margin-bottom:.5rem; }
26    .lead { color:var(--muted); font-size:.95rem; line-height:1.55; margin-bottom:1.6rem; }
27    form { display:flex; flex-direction:column; gap:1rem; }
28    label { font-size:.8rem; font-weight:600; letter-spacing:.02em; display:block; margin-bottom:.3rem; }
29    label .req { color:var(--blue); }
30    input, textarea, select {
31      width:100%; font:inherit; font-size:.95rem; color:var(--navy);
32      padding:.65rem .8rem; border:1px solid var(--border); border-radius:10px; background:var(--bg);
33    }
34    input:focus, textarea:focus, select:focus { outline:2px solid var(--blue); outline-offset:1px; border-color:var(--blue); }
35    textarea { min-height:110px; resize:vertical; }
36    .hint { font-size:.76rem; color:var(--muted); margin-top:.3rem; line-height:1.4; }
37    .row2 { display:grid; grid-template-columns:1fr 1fr; gap:1rem; }
38    @media (max-width:520px){ .row2 { grid-template-columns:1fr; } }
39    button[type=submit] {
40      font-family:"Space Grotesk",sans-serif; font-weight:700; font-size:.95rem; color:#fff;
41      background:var(--blue); border:none; border-radius:10px; padding:.8rem 1.4rem; cursor:pointer; margin-top:.4rem;
42    }
43    button[type=submit]:hover { background:#0c3e9e; }
44    button[disabled] { opacity:.6; cursor:wait; }
45    .ok, .err { display:none; padding:1rem 1.1rem; border-radius:12px; font-size:.92rem; line-height:1.5; margin-top:1rem; }
46    .ok { background:#eef7f0; border:1px solid #bfe3c8; color:#11502a; }
47    .err { background:#fdf0ef; border:1px solid #f3c9c5; color:#7c2d26; }
48    .err a { color:var(--blue); }
49    .back { display:inline-block; margin-top:1.4rem; color:var(--blue); font-size:.88rem; text-decoration:none; }
50    .back:hover { text-decoration:underline; }
51  </style>
52</head>
53<body>
54  <header class="top">
55    <a class="wordmark" href="/">Dashmote<span>.</span></a>
56    <span class="crumb">World Cup Watch Party Radar / Submit a watch party</span>
57  </header>
58  <main>
59    <h1>Submit a watch party</h1>
60    <p class="lead">Know a bar, pub, brewery or fan zone showing the 2026 World Cup that is not on the radar yet?
61      Tell us about it. We verify every submission against its source before it goes live, venues with a public
62      post or website announcement get listed fastest.</p>
63
64    <form id="f" novalidate>
65      <div>
66        <label for="venue">Venue name <span class="req">*</span></label>
67        <input id="venue" name="venue" required maxlength="180" placeholder="e.g. Cafe De Zon" />
68      </div>
69      <div class="row2">
70        <div>
71          <label for="city">City <span class="req">*</span></label>
72          <input id="city" name="city" required maxlength="90" placeholder="e.g. Amsterdam" />
73        </div>
74        <div>
75          <label for="country">Country</label>
76          <input id="country" name="country" maxlength="60" placeholder="e.g. Netherlands" />
77        </div>
78      </div>
79      <div>
80        <label for="address">Address or Google Maps link</label>
81        <input id="address" name="address" maxlength="300" placeholder="Street + number, or a maps.google.com link" />
82      </div>
83      <div>
84        <label for="details">What is happening there?</label>
85        <textarea id="details" name="details" maxlength="1800"
86          placeholder="e.g. Shows every match on 4 big screens, beer garden, hosts an official fan zone for the group stage..."></textarea>
87      </div>
88      <div>
89        <label for="source_url">Source link <span class="req">*</span></label>
90        <input id="source_url" name="source_url" type="url" required maxlength="450" placeholder="An Instagram post, Facebook event or website page announcing it" />
91        <p class="hint">The public post or page that proves the venue is showing matches. This is what we verify.</p>
92      </div>
93      <div class="row2">
94        <div>
95          <label for="photo_url">Photo link</label>
96          <input id="photo_url" name="photo_url" type="url" maxlength="450" pattern="https://.*" title="Photo links must start with https://" placeholder="A photo of the venue (optional)" />
97        </div>
98        <div>
99          <label for="team">Team it supports</label>
100          <input id="team" name="team" maxlength="60" placeholder="e.g. Netherlands (optional)" />
101        </div>
102      </div>
103      <div>
104        <label for="email">Your email</label>
105        <input id="email" name="email" type="email" maxlength="120" placeholder="Optional, in case we have a question" />
106      </div>
107      <button type="submit" id="go">Submit watch party</button>
108      <p class="ok" id="busy" role="status" style="display:none">Submitting&hellip;</p>
109      <p class="ok" id="ok" role="status">Thank you! Your watch party was submitted. We verify every venue against its source,
110        if it checks out it will appear on the radar in the next refresh.</p>
111      <p class="err" id="err" role="alert">That did not go through. Please retry in a moment, or email it to
112        <a href="mailto:[email protected]?subject=World%20Cup%20watch%20party%20submission">[email protected]</a>.</p>
113    </form>
114    <a class="back" href="/">&larr; Back to the radar</a>
115  </main>
116
117  <!-- Firebase App Check (reCAPTCHA Enterprise): mints an attestation token so
118       only real browsers can write to the submissions collection. The token is
119       attached to the Firestore REST POST below; spam bots hitting the endpoint
120       directly have no valid token and are rejected once enforcement is on. -->
121  
121<script type="module">
122    import { initializeApp } from "https://www.gstatic.com/firebasejs/10.13.2/firebase-app.js";
123    import { initializeAppCheck, ReCaptchaEnterpriseProvider, getToken }
124      from "https://www.gstatic.com/firebasejs/10.13.2/firebase-app-check.js";
125    try {
126      const app = initializeApp({
127        apiKey: "AIzaSyBYtSoVor_xtodvsY8Cycpf8JpoVfksWcI",
128        projectId: "dashmote-worldcup",
129        appId: "1:414042519427:web:4329a82695908f405368b6"
130      });
131      const appCheck = initializeAppCheck(app, {
132        provider: new ReCaptchaEnterpriseProvider("6LeyWRItAAAAAB3QTCi73yefH6RtXxiGKj890GMy"),
133        isTokenAutoRefreshEnabled: true
134      });
135      window.__appCheckToken = async function () {
136        try { return (await getToken(appCheck, false)).token; } catch (e) { return null; }
137      };
138    } catch (e) { /* SDK/load failure: fall through, submit without a token */ }
139  </script>
139
140
141  
141<script>
142    (function () {
143      var ENDPOINT = "https://firestore.googleapis.com/v1/projects/dashmote-worldcup/databases/(default)/documents/submissions?key=AIzaSyBYtSoVor_xtodvsY8Cycpf8JpoVfksWcI";
144      var f = document.getElementById("f");
145      var ok = document.getElementById("ok");
146      var err = document.getElementById("err");
147      var go = document.getElementById("go");
148      var busy = document.getElementById("busy");
149      f.addEventListener("submit", function (e) {
150        e.preventDefault();
151        ok.style.display = "none"; err.style.display = "none";
152        if (!f.reportValidity()) return;
153        busy.style.display = "block";
154        var val = function (id) { return (document.getElementById(id).value || "").trim(); };
155        var fields = {
156          venue:      { stringValue: val("venue") },
157          city:       { stringValue: val("city") },
158          source_url: { stringValue: val("source_url") },
159          ts:         { stringValue: new Date().toISOString() },
160          page:       { stringValue: "submit-v1" }
161        };
162        var opt = { details: "details", country: "country", address: "address", photo_url: "photo_url", team: "team", email: "email" };
163        for (var k in opt) { var v = val(opt[k]); if (v) fields[k] = { stringValue: v }; }
164        go.disabled = true; go.setAttribute("aria-busy", "true"); f.setAttribute("aria-busy", "true");
165        var done = function () {
166          go.disabled = false; go.removeAttribute("aria-busy"); f.removeAttribute("aria-busy");
167          busy.style.display = "none";
168        };
169        // Get an App Check token first (best-effort), then POST with it attached.
170        var tokenP = window.__appCheckToken ? window.__appCheckToken() : Promise.resolve(null);
171        tokenP.then(function (token) {
172          var headers = { "Content-Type": "application/json" };
173          if (token) headers["X-Firebase-AppCheck"] = token;
174          return fetch(ENDPOINT, {
175            method: "POST",
176            headers: headers,
177            body: JSON.stringify({ fields: fields })
178          });
179        }).then(function (r) {
180          done();
181          if (r.ok) { ok.style.display = "block"; f.reset(); }
182          else { err.style.display = "block"; }
183        }).catch(function () {
184          done();
185          err.style.display = "block";
186        });
187      });
188    })();
189  </script>
189
190</body>
191</html>

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.