Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
310 changes: 168 additions & 142 deletions index.html
Original file line number Diff line number Diff line change
@@ -1,104 +1,126 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Reform UK Exposed Tweets by Area & Person</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<script src="https://cdn.jsdelivr.net/npm/papaparse@5.4.1/papaparse.min.js"></script>
<style>
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
margin: 0;
padding: 0;
background: #f5f5f5;
color: #003b5c;
}
header {
background: #00aeef;
padding: 2rem 1rem 1rem;
text-align: center;
color: white;
position: relative;
}
header h1 {
margin: 0;
font-size: 2.5rem;
}
.subtext {
margin-top: 0.5rem;
font-size: 1rem;
color: white;
}
.subtext a {
color: white;
text-decoration: underline;
}
.hero-image {
width: 100%;
max-height: 300px;
object-fit: cover;
margin-top: 1rem;
border-bottom: 4px solid #003b5c;
}
.container {
max-width: 900px;
margin: 2rem auto;
padding: 0 1rem;
}
.filters {
margin-bottom: 1.5rem;
}
label {
font-weight: bold;
display: block;
margin-bottom: 0.5rem;
}
select, input[type="text"] {
width: 100%;
padding: 0.75rem;
border: 1px solid #ccc;
border-radius: 4px;
font-size: 1rem;
}
.tweet {
background: white;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.08);
padding: 1rem;
margin-bottom: 1rem;
line-height: 1.5;
}
.tweet a {
display: inline-block;
margin-top: 0.5rem;
color: #00aeef;
text-decoration: none;
}
footer {
text-align: center;
color: #888;
font-size: 0.9rem;
margin-top: 3rem;
padding-bottom: 2rem;
}
@media (max-width: 700px) {
<head>
<meta charset="UTF-8" />
<title>Reform UK Exposed Tweets by Area & Person</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />

<!-- Google Analytics -->
<script
async
src="https://www.googletagmanager.com/gtag/js?id=G-FQQ7TXGD96"
></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag() {
dataLayer.push(arguments);
}
gtag("js", new Date());
gtag("config", "G-G-FQQ7TXGD96");
</script>
<script src="https://cdn.jsdelivr.net/npm/papaparse@5.4.1/papaparse.min.js"></script>
<style>
body {
font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
margin: 0;
padding: 0;
background: #f5f5f5;
color: #003b5c;
}
header {
background: #00aeef;
padding: 2rem 1rem 1rem;
text-align: center;
color: white;
position: relative;
}
header h1 {
font-size: 2rem;
}
}
</style>
</head>
<body>

<header>
<h1>Reform UK Exposed Tweets</h1>
<div class="subtext">
Are you a local campaigner looking for information about your local Reform candidates? These are tweets from the brilliant <strong>Reform UK Exposed</strong> Twitter account, organised by geography and candidate.
<br />
Follow the original account <a href="https://twitter.com/ReformExposed" target="_blank">here</a>.
</div>
<img class="hero-image" src="https://i2-prod.mirror.co.uk/incoming/article5660503.ece/ALTERNATES/s1200/Election.jpg" alt="Satirical image of Nigel Farage crying">
</header>
margin: 0;
font-size: 2.5rem;
}
.subtext {
margin-top: 0.5rem;
font-size: 1rem;
color: white;
}
.subtext a {
color: white;
text-decoration: underline;
}
.hero-image {
width: 100%;
max-height: 300px;
object-fit: cover;
margin-top: 1rem;
border-bottom: 4px solid #003b5c;
}
.container {
max-width: 900px;
margin: 2rem auto;
padding: 0 1rem;
}
.filters {
margin-bottom: 1.5rem;
}
label {
font-weight: bold;
display: block;
margin-bottom: 0.5rem;
}
select,
input[type="text"] {
width: 100%;
padding: 0.75rem;
border: 1px solid #ccc;
border-radius: 4px;
font-size: 1rem;
}
.tweet {
background: white;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.08);
padding: 1rem;
margin-bottom: 1rem;
line-height: 1.5;
}
.tweet a {
display: inline-block;
margin-top: 0.5rem;
color: #00aeef;
text-decoration: none;
}
footer {
text-align: center;
color: #888;
font-size: 0.9rem;
margin-top: 3rem;
padding-bottom: 2rem;
}
@media (max-width: 700px) {
header h1 {
font-size: 2rem;
}
}
</style>
</head>
<body>
<header>
<h1>Reform UK Exposed Tweets</h1>
<div class="subtext">
Are you a local campaigner looking for information about your local
Reform candidates? These are tweets from the brilliant
<strong>Reform UK Exposed</strong> Twitter account, organised by
geography and candidate.
<br />
Follow the original account
<a href="https://twitter.com/ReformExposed" target="_blank">here</a>.
</div>
<img
class="hero-image"
src="https://i2-prod.mirror.co.uk/incoming/article5660503.ece/ALTERNATES/s1200/Election.jpg"
alt="Satirical image of Nigel Farage crying"
/>
</header>

<div class="container">
<div class="filters">
Expand All @@ -113,30 +135,31 @@ <h1>Reform UK Exposed Tweets</h1>
</select>
</div>

<div style="margin-bottom: 1.5rem;">
<label for="searchInput">Search tweets:</label>
<input type="text" id="searchInput" placeholder="Enter keyword..." />
<div style="margin-bottom: 1.5rem">
<label for="searchInput">Search tweets:</label>
<input type="text" id="searchInput" placeholder="Enter keyword..." />
</div>

<div id="tweets"></div>
</div>

<div id="tweets"></div>
</div>
<footer>
Built by volunteers at Campaign Lab to uncover the truth behind Reform UK
</footer>

<footer>
Built by volunteers at Campaign Lab to uncover the truth behind Reform UK
</footer>
<script>
const sheetURL =
"https://docs.google.com/spreadsheets/d/e/2PACX-1vQyOqn4w0KNNgwXjXBam72jKvAmFwr3RUQEHjYEFhUq8gTwZqwuNSStbT-4SELNDNoT7taAgIXC66E2/pub?gid=0&single=true&output=csv";
let allData = [];

<script>
const sheetURL = 'https://docs.google.com/spreadsheets/d/e/2PACX-1vQyOqn4w0KNNgwXjXBam72jKvAmFwr3RUQEHjYEFhUq8gTwZqwuNSStbT-4SELNDNoT7taAgIXC66E2/pub?gid=0&single=true&output=csv';
let allData = [];
async function loadCSV(url) {
const res = await fetch(url);
const text = await res.text();

async function loadCSV(url) {
const res = await fetch(url);
const text = await res.text();

const parsed = Papa.parse(text, {
header: true,
skipEmptyLines: true
});
const parsed = Papa.parse(text, {
header: true,
skipEmptyLines: true,
});

const cleaned = parsed.data.map(row => ({
area: row["Area"]?.trim(),
Expand All @@ -145,18 +168,18 @@ <h1>Reform UK Exposed Tweets</h1>
url: row["URL"]?.trim()
})).filter(d => d.area && d.tweet);

return cleaned;
}
return cleaned;
}

function populateDropdown(id, items) {
const select = document.getElementById(id);
items.sort().forEach(value => {
const option = document.createElement("option");
option.value = value;
option.textContent = value;
select.appendChild(option);
});
}
function populateDropdown(id, items) {
const select = document.getElementById(id);
items.sort().forEach((value) => {
const option = document.createElement("option");
option.value = value;
option.textContent = value;
select.appendChild(option);
});
}

function applyFilters() {
const area = document.getElementById('areaSelect').value;
Expand All @@ -172,22 +195,26 @@ <h1>Reform UK Exposed Tweets</h1>
return matchesArea && matchesPerson && matchesSearch;
});

if (filtered.length === 0) {
tweetsDiv.innerHTML = "<p>No tweets match your filters.</p>";
return;
}
if (filtered.length === 0) {
tweetsDiv.innerHTML = "<p>No tweets match your filters.</p>";
return;
}

filtered.forEach(d => {
const div = document.createElement("div");
div.className = "tweet";
div.innerHTML = `
<strong>${d.person}</strong><br>
${d.tweet}
${d.url ? `<br><a href="${d.url}" target="_blank">View on Twitter</a>` : ''}
${
d.url
? `<br><a href="${d.url}" target="_blank">View on Twitter</a>`
: ""
}
`;
tweetsDiv.appendChild(div);
});
}
tweetsDiv.appendChild(div);
});
}

async function init() {
allData = await loadCSV(sheetURL);
Expand All @@ -202,11 +229,10 @@ <h1>Reform UK Exposed Tweets</h1>
document.getElementById('personSelect').addEventListener('change', applyFilters);
document.getElementById('searchInput').addEventListener('input', applyFilters);

applyFilters(); // initial render
}

init();
</script>
applyFilters(); // initial render
}

</body>
init();
</script>
</body>
</html>