vidhimudaliar commited on
Commit
e964752
·
verified ·
1 Parent(s): f78b846

Upload homepage.js

Browse files
Files changed (1) hide show
  1. assets/js/homepage.js +145 -0
assets/js/homepage.js ADDED
@@ -0,0 +1,145 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // assets/js/homepage.js
2
+
3
+ const CSV_PATH = new URL("cleaned_data.csv", window.location.href).href;
4
+
5
+ const grid = document.getElementById("failureGrid");
6
+ const emptyState = document.getElementById("emptyState");
7
+ const searchInput = document.getElementById("searchFail");
8
+
9
+ const totalCountEl = document.getElementById("totalCount");
10
+ const videoCountEl = document.getElementById("videoCount");
11
+ const segmentCountEl = document.getElementById("segmentCount");
12
+
13
+ /* Categories we do NOT want displayed on the homepage */
14
+ const HIDDEN_CATEGORIES = new Set([
15
+ "time" // hide Time
16
+ ]);
17
+
18
+ function parseCSV(text) {
19
+ const lines = text.trim().split("\n");
20
+ const header = lines[0].split(",").map(s => s.trim());
21
+ const rows = [];
22
+
23
+ for (let i = 1; i < lines.length; i++) {
24
+ const cols = lines[i].split(",");
25
+ const obj = {};
26
+ for (let j = 0; j < header.length; j++) {
27
+ obj[header[j]] = (cols[j] ?? "").trim();
28
+ }
29
+ rows.push(obj);
30
+ }
31
+ return rows;
32
+ }
33
+
34
+ function normalizeLabel(x) {
35
+ return String(x || "").trim();
36
+ }
37
+
38
+ function buildStats(rows) {
39
+ const stats = new Map(); // label -> {segments, videos:Set, def}
40
+
41
+ for (const f of window.FAILURES) {
42
+ const lname = f.name.toLowerCase();
43
+ if (HIDDEN_CATEGORIES.has(lname)) continue;
44
+
45
+ stats.set(f.name, {
46
+ segments: 0,
47
+ videos: new Set(),
48
+ def: f.definition
49
+ });
50
+ }
51
+
52
+ for (const r of rows) {
53
+ const label = normalizeLabel(r.label);
54
+ if (!stats.has(label)) continue;
55
+
56
+ stats.get(label).segments += 1;
57
+ stats.get(label).videos.add(r.filename);
58
+ }
59
+
60
+ return stats;
61
+ }
62
+
63
+ function renderTiles(stats) {
64
+ grid.innerHTML = "";
65
+
66
+ const q = (searchInput.value || "").toLowerCase().trim();
67
+ let shown = 0;
68
+
69
+ let totalVideosImpacted = 0;
70
+ let totalSegments = 0;
71
+
72
+ for (const f of window.FAILURES) {
73
+ if (HIDDEN_CATEGORIES.has(f.name.toLowerCase())) continue;
74
+
75
+ const s = stats.get(f.name) || {
76
+ segments: 0,
77
+ videos: new Set(),
78
+ def: f.definition
79
+ };
80
+
81
+ const vids = s.videos.size;
82
+ const segs = s.segments;
83
+
84
+ totalVideosImpacted += vids;
85
+ totalSegments += segs;
86
+
87
+ const hay = `${f.name} ${f.family || ""} ${f.definition}`.toLowerCase();
88
+ if (q && !hay.includes(q)) continue;
89
+
90
+ shown++;
91
+
92
+ const card = document.createElement("div");
93
+ card.className = "failure-card";
94
+ card.tabIndex = 0;
95
+
96
+ card.innerHTML = `
97
+ <h3>${f.name}</h3>
98
+ <p>${f.definition}</p>
99
+ <div class="meta-row">
100
+ <span>${vids} videos</span>
101
+ <span>${segs} segments</span>
102
+ </div>
103
+ <div class="tooltip">
104
+ <strong style="display:block; margin-bottom:6px;">${f.name}</strong>
105
+ <div style="color: var(--text-muted); font-size: 13px; line-height: 1.5;">
106
+ ${f.definition}
107
+ </div>
108
+ <div style="margin-top:10px; color: var(--text-muted); font-size: 12px;">
109
+ Click to open details →
110
+ </div>
111
+ </div>
112
+ `;
113
+
114
+ card.addEventListener("click", () => {
115
+ const url = `category.html?cat=${encodeURIComponent(f.name)}`;
116
+ window.location.href = url;
117
+ });
118
+
119
+ card.addEventListener("keydown", (e) => {
120
+ if (e.key === "Enter" || e.key === " ") card.click();
121
+ });
122
+
123
+ grid.appendChild(card);
124
+ }
125
+
126
+ totalCountEl.textContent = `${stats.size} categories`;
127
+ videoCountEl.textContent = `${totalVideosImpacted} videos impacted`;
128
+ segmentCountEl.textContent = `${totalSegments} segments`;
129
+
130
+ emptyState.hidden = shown !== 0;
131
+ }
132
+
133
+ fetch(CSV_PATH)
134
+ .then(r => r.text())
135
+ .then(text => {
136
+ const rows = parseCSV(text);
137
+ const stats = buildStats(rows);
138
+
139
+ renderTiles(stats);
140
+ searchInput.addEventListener("input", () => renderTiles(stats));
141
+ })
142
+ .catch(err => {
143
+ console.error(err);
144
+ grid.innerHTML = `<div class="empty-state">Could not load cleaned_data.csv</div>`;
145
+ });