Skip to content

Commit bc03d65

Browse files
authored
Merge pull request #1332 from recodehive/copilot/dynamic-mapping-for-discussions
feat: wire DOCUSAURUS_GIT_TOKEN to GitHub service for live discussions
2 parents 935e0ca + e097655 commit bc03d65

6 files changed

Lines changed: 99 additions & 44 deletions

File tree

.env.example

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@
44
# No special permissions needed for public repositories
55
GITHUB_TOKEN=your_github_token_here
66

7+
# GitHub token used by Docusaurus for dynamic features (discussions, stats, leaderboard)
8+
# This must be set for the discussions section to fetch live data from GitHub
9+
# Create a Classic PAT with read:discussion scope at https://github.com/settings/tokens
10+
DOCUSAURUS_GIT_TOKEN=your_github_token_here
11+
712
# Shopify Configuration (for Merch Store)
813
# Get these from: Shopify Admin > Settings > Apps and sales channels > Develop apps
914
# Required scopes: unauthenticated_read_product_listings, unauthenticated_write_checkouts

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,4 @@ yarn-error.log*
2424

2525
# Temporary files
2626
/tmp/
27+
tsconfig.tsbuildinfo

package-lock.json

Lines changed: 2 additions & 40 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/components/discussions/discussions.css

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,44 @@
270270
box-shadow: 0 6px 20px rgba(16, 185, 129, 0.4);
271271
}
272272

273+
.refresh-discussions-btn {
274+
background: var(--ifm-card-background-color);
275+
color: var(--ifm-color-emphasis-700);
276+
border: 1px solid var(--ifm-color-emphasis-300);
277+
padding: 0.75rem;
278+
border-radius: 12px;
279+
cursor: pointer;
280+
transition: all 0.2s ease;
281+
display: flex;
282+
align-items: center;
283+
justify-content: center;
284+
flex-shrink: 0;
285+
}
286+
287+
.refresh-discussions-btn:hover:not(:disabled) {
288+
border-color: var(--ifm-color-primary);
289+
color: var(--ifm-color-primary);
290+
transform: translateY(-1px);
291+
}
292+
293+
.refresh-discussions-btn:disabled {
294+
opacity: 0.6;
295+
cursor: not-allowed;
296+
}
297+
298+
@keyframes spin {
299+
from {
300+
transform: rotate(0deg);
301+
}
302+
to {
303+
transform: rotate(360deg);
304+
}
305+
}
306+
307+
.spinning {
308+
animation: spin 1s linear infinite;
309+
}
310+
273311
.tab-btn {
274312
background: var(--ifm-card-background-color);
275313
border: 2px solid var(--ifm-color-emphasis-200);

src/pages/dashboard/index.tsx

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
} from "@site/src/lib/statsProvider";
1010
import SlotCounter from "react-slot-counter";
1111
import { useLocation, useHistory } from "@docusaurus/router";
12+
import useDocusaurusContext from "@docusaurus/useDocusaurusContext";
1213
import {
1314
githubService,
1415
GitHubDiscussion,
@@ -30,6 +31,7 @@ import {
3031
BarChart3,
3132
ArrowLeft,
3233
GitFork,
34+
RefreshCw,
3335
} from "lucide-react";
3436
import NavbarIcon from "@site/src/components/navbar/NavbarIcon";
3537
import "@site/src/components/discussions/discussions.css";
@@ -65,6 +67,9 @@ const categories: Category[] = [
6567
const DashboardContent: React.FC = () => {
6668
const location = useLocation();
6769
const history = useHistory();
70+
const {
71+
siteConfig: { customFields },
72+
} = useDocusaurusContext();
6873
const [activeTab, setActiveTab] = useState<
6974
"home" | "discuss" | "giveaway" | "contributors"
7075
>("home");
@@ -80,6 +85,14 @@ const DashboardContent: React.FC = () => {
8085
const [discussionsError, setDiscussionsError] = useState<string | null>(null);
8186
const [showDashboardMenu, setShowDashboardMenu] = useState(false);
8287

88+
// Initialize GitHub service with token from Docusaurus config
89+
useEffect(() => {
90+
const token = customFields?.gitToken as string;
91+
if (token) {
92+
githubService.setToken(token);
93+
}
94+
}, [customFields?.gitToken]);
95+
8396
// Close dashboard menu when clicking outside
8497
useEffect(() => {
8598
const handleClickOutside = (event: MouseEvent) => {
@@ -138,6 +151,10 @@ const DashboardContent: React.FC = () => {
138151
}
139152
};
140153

154+
const handleRefreshDiscussions = () => {
155+
fetchDiscussions();
156+
};
157+
141158
// Discussion handlers
142159
const handleDiscussionTabChange = (tab: DiscussionTab) => {
143160
setActiveDiscussionTab(tab);
@@ -597,6 +614,17 @@ const DashboardContent: React.FC = () => {
597614
<option value="latest">Latest</option>
598615
<option value="oldest">Oldest</option>
599616
</select>
617+
<button
618+
className="refresh-discussions-btn"
619+
onClick={handleRefreshDiscussions}
620+
disabled={discussionsLoading}
621+
title="Refresh discussions"
622+
>
623+
<RefreshCw
624+
size={16}
625+
className={discussionsLoading ? "spinning" : ""}
626+
/>
627+
</button>
600628
<button
601629
className="new-discussion-btn"
602630
onClick={handleNewDiscussion}
@@ -629,6 +657,15 @@ const DashboardContent: React.FC = () => {
629657
{discussionsError && (
630658
<div className="discussions-error-message">
631659
<p>{discussionsError}</p>
660+
<p>
661+
<a
662+
href="https://github.com/recodehive/recode-website/discussions"
663+
target="_blank"
664+
rel="noopener noreferrer"
665+
>
666+
View discussions on GitHub →
667+
</a>
668+
</p>
632669
</div>
633670
)}
634671
{!discussionsLoading &&

src/services/githubService.ts

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,17 +68,29 @@ class GitHubService {
6868
// === ADDED: include anonymous contributors configurable (default false)
6969
private includeAnonymousContributors = false;
7070

71+
// === ADDED: stored token for authenticated API calls
72+
private token: string = "";
73+
74+
// === ADDED: set the GitHub token (e.g. from Docusaurus customFields.gitToken)
75+
setToken(token: string): void {
76+
if (token && token.trim()) {
77+
this.token = token.trim();
78+
}
79+
}
80+
7181
// Get headers for GitHub API requests
7282
private getHeaders(): Record<string, string> {
7383
const headers: Record<string, string> = {
7484
Accept: "application/vnd.github.v3+json",
7585
"Content-Type": "application/json",
7686
};
7787

78-
// Add GitHub token if available in environment
79-
// Note: In production, you might want to use a server-side proxy to avoid exposing tokens
80-
if (typeof window !== "undefined" && (window as any).GITHUB_TOKEN) {
81-
headers["Authorization"] = `token ${(window as any).GITHUB_TOKEN}`;
88+
// Use stored token first, then fall back to window.GITHUB_TOKEN
89+
const token =
90+
this.token ||
91+
(typeof window !== "undefined" ? (window as any).GITHUB_TOKEN : "");
92+
if (token) {
93+
headers["Authorization"] = `token ${token}`;
8294
}
8395

8496
return headers;

0 commit comments

Comments
 (0)