Skip to content

Commit fd7d99a

Browse files
js fixes
1 parent 3d094b3 commit fd7d99a

File tree

2 files changed

+27
-18
lines changed

2 files changed

+27
-18
lines changed

site/js/config.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
1-
// Repository configuration update if the repo is renamed or transferred.
1+
// Repository configuration; update if the repo is renamed or transferred.
22
export const REPO_OWNER = 'pancakesaregood';
3-
export const REPO_NAME = 'potato';
3+
export const REPO_NAME = 'potato';
44

55
// Content paths within the repository.
6-
export const MANIFESTO_PATH = 'instances/canada/manifesto';
7-
export const PROPOSALS_PATH = 'instances/canada/proposals';
6+
export const MANIFESTO_PATH = 'instances/canada/manifesto';
7+
export const PROPOSALS_PATH = 'proposals';
88
export const EXPERIMENTS_PATH = 'docs/experiments';
99

1010
// GitHub REST API base.
1111
export const API_BASE = 'https://api.github.com';
1212

13-
// Proposal submission: redirects to GitHub Issues with template pre-filled.
13+
// Proposal submission: redirects to GitHub Issues with the template pre-filled.
1414
export const ISSUES_URL = `https://github.com/${REPO_OWNER}/${REPO_NAME}/issues/new?template=policy_proposal.yml`;
1515

1616
// Cache TTL in milliseconds (5 minutes).

site/js/github.js

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,18 @@ function cacheSet(url, data) {
3131
try {
3232
sessionStorage.setItem(cacheKey(url), JSON.stringify({ data, ts: Date.now() }));
3333
} catch {
34-
// sessionStorage quota exceeded — silently skip caching.
34+
// sessionStorage quota exceeded; silently skip caching.
35+
}
36+
}
37+
38+
function decodeBase64Utf8(content) {
39+
const binary = atob(content.replace(/\n/g, ''));
40+
const bytes = Uint8Array.from(binary, (char) => char.charCodeAt(0));
41+
42+
try {
43+
return new TextDecoder('utf-8').decode(bytes);
44+
} catch {
45+
return binary;
3546
}
3647
}
3748

@@ -67,7 +78,7 @@ export async function getManifestoFiles() {
6778
const url = `${API_BASE}/repos/${REPO_OWNER}/${REPO_NAME}/contents/${MANIFESTO_PATH}`;
6879
const files = await fetchJSON(url);
6980
return files
70-
.filter(f => f.type === 'file' && f.name.endsWith('.md') && f.name.toLowerCase() !== 'readme.md')
81+
.filter((file) => file.type === 'file' && file.name.endsWith('.md') && file.name.toLowerCase() !== 'readme.md')
7182
.sort((a, b) => a.name.localeCompare(b.name));
7283
}
7384

@@ -78,8 +89,7 @@ export async function getManifestoFiles() {
7889
export async function getFileContent(path) {
7990
const url = `${API_BASE}/repos/${REPO_OWNER}/${REPO_NAME}/contents/${path}`;
8091
const file = await fetchJSON(url);
81-
// GitHub API returns content as base64 with newlines.
82-
return atob(file.content.replace(/\n/g, ''));
92+
return decodeBase64Utf8(file.content);
8393
}
8494

8595
// --- Pulls API ---------------------------------------------------------------
@@ -130,33 +140,32 @@ export async function getPipelineStatus() {
130140

131141
/**
132142
* Extracts a human-readable title from a manifesto filename.
133-
* e.g. "article_05_housing_and_homelessness.md" "Article 05: Housing and Homelessness"
134-
* "why_the_potato.md" "Why the Potato?"
143+
* e.g. "article_05_housing_and_homelessness.md" -> "Article 05: Housing and Homelessness"
144+
* "why_the_potato.md" -> "Why the Potato?"
135145
*/
136146
export function filenameToTitle(filename) {
137147
const base = filename.replace(/\.md$/, '');
138148

139-
// Special case: why_the_potato
140149
if (base === 'why_the_potato') return 'Why the Potato?';
141150

142-
// article_NN_some_title pattern
143151
const match = base.match(/^article_(\d+)_(.+)$/);
144152
if (match) {
145153
const num = match[1];
146-
const words = match[2].split('_').map(w => w.charAt(0).toUpperCase() + w.slice(1));
154+
const words = match[2].split('_').map((word) => word.charAt(0).toUpperCase() + word.slice(1));
147155
return `Article ${num}: ${words.join(' ')}`;
148156
}
149157

150-
// Fallback: capitalise words
151-
return base.split('_').map(w => w.charAt(0).toUpperCase() + w.slice(1)).join(' ');
158+
return base.split('_').map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(' ');
152159
}
153160

154161
/**
155162
* Formats an ISO date string to a readable date.
156163
*/
157164
export function formatDate(iso) {
158-
if (!iso) return '';
165+
if (!iso) return '-';
159166
return new Date(iso).toLocaleDateString('en-CA', {
160-
year: 'numeric', month: 'long', day: 'numeric'
167+
year: 'numeric',
168+
month: 'long',
169+
day: 'numeric'
161170
});
162171
}

0 commit comments

Comments
 (0)