@@ -8,42 +8,46 @@ The Global Anti-CCP Resistance Hub is a **static React single-page application (
88
99```
1010src/data/*.json ─────┐
11- src/pages/*.jsx ─────┤ npm run build dist/
12- src/components/*.jsx ─┼─ ────────────── → ├── index.html
11+ src/pages/*.tsx ─────┤ npm run build dist/
12+ src/components/*.tsx ─┼─ ────────────── → ├── index.html
1313src/locales/*.json ──┤ (Vite + Rollup) ├── assets/
14- src/index.css ───────┘ │ ├── index-*.js (305KB / 97KB gzip)
14+ src/index.css ───────┘ │ ├── index-*.js (310KB / 99KB gzip)
1515 │ ├── index-*.css (86KB / 15KB gzip)
1616 │ ├── vendor-react-* (11KB)
1717 │ ├── vendor-router-* (35KB)
18- │ ├── vendor-motion-* (116KB)
1918 │ └── [81 lazy chunks]
2019 └── (static assets)
2120```
2221
2322### Key Build Features
24- - ** Manual chunks** : React, React Router, and Framer Motion split into cacheable vendor bundles
23+ - ** 100% TypeScript** : Entire codebase is TypeScript — 0 JavaScript/JSX files remain (360+ .ts/.tsx files)
24+ - ** Manual chunks** : React and React Router split into cacheable vendor bundles
2525- ** Lazy loading** : 81 sub-components loaded on demand (all page bundles under 50KB)
2626- ** Base path** : Configurable via ` VITE_BASE_PATH ` env var — defaults to ` / ` for Cloudflare, set to ` /global-anti-ccp-resistance-hub/ ` for GitHub Pages
2727
2828---
2929
3030## Routing
3131
32- React Router v7 handles all client-side navigation. Routes are defined in ` src/App.jsx ` .
32+ React Router v7 handles all client-side navigation. Routes are defined in ` src/App.tsx ` .
3333
3434```
3535/ → Dashboard
36- /intelligence-feeds → IntelligenceFeeds (3 tabs: Live Feeds, Regional, CCP Ops)
37- /political- prisoners → PoliticalPrisoners
38- /security-center → SecurityCenter (5 tabs, includes ChinaExitBan )
39- /educational-resources → EducationalResources (7 tabs, includes ConfuciusInstitutes )
36+ /intelligence → IntelligenceFeeds (3 tabs: Live Feeds, Regional, CCP Ops)
37+ /prisoners → PoliticalPrisoners
38+ /security → SecurityCenter (tabs: Overview, Tools, Guides, Quiz, Report )
39+ /education → EducationCenter ( tabs: Resources, Media, Guides, Tactics )
4040/take-action → TakeAction
41- /community-support → CommunitySupport
42- /resistance- resources → ResistanceResources
43- /resistance- directory → ResistanceDirectory
41+ /community → CommunitySupport
42+ /resources → ResistanceResources
43+ /directory → ResistanceDirectory
4444/data-sources → DataSources
4545/profiles → ProfilesIndex (links to all 15 profiles)
4646/profiles/:slug → Individual profile pages (15 total)
47+ /campaigns → Redirect → /take-action
48+ /communications → Redirect → /security
49+ /tactics → Redirect → /education
50+ /threats → Redirect → /intelligence
4751```
4852
4953SPA routing on Cloudflare is handled by ` wrangler.jsonc ` (` not_found_handling: "single-page-application" ` ). On GitHub Pages, a ` 404.html ` redirect handles deep links.
@@ -56,28 +60,31 @@ All structured content lives in `src/data/` as JSON files. Components import the
5660
5761```
5862src/data/
59- ├── political_prisoners_research.json # 62 prisoners with status, dates, sources
60- ├── sanctions_tracker.json # 35 sanctions across US/EU/UK/CA/AU
63+ ├── political_prisoners_research.json # 64 prisoners with status, dates, sources
64+ ├── sanctions_tracker.json # 47 sanctions across US/EU/UK/CA/AU
65+ ├── sanctioned_officials_research.json # 34 CCP officials under international sanctions
66+ ├── forced_labor_companies_research.json # 30 companies linked to forced labor
6167├── detention_facilities_research.json # 11 facilities with coordinates, capacity
62- ├── sanctioned_officials_research.json # CCP officials under international sanctions
63- ├── forced_labor_companies_research.json # Companies linked to forced labor
64- ├── confucius_institutes_research.json # Confucius Institutes worldwide
65- ├── timeline_events.json # 31 events from 1989–2026
68+ ├── timeline_events.json # 40 events from 1989–2026
6669├── security_center_data.json # Security tools and recommendations
6770├── data_sources.json # RSS sources and source categories
6871├── academic_experts_research.json # Expert researchers
6972├── human_rights_orgs_research.json # Organizations directory
7073├── international_responses_research.json # Government responses
7174├── police_stations_research.json # CCP overseas police stations
7275├── recent_news_research.json # Recent developments
73- ├── ccpTactics.js # CCP tactics documentation
74- ├── researchData.js # General research data
75- └── liveDataSources.js # Live data source configurations
76+ ├── recent_updates.json # Platform changelog entries
77+ ├── emergency_alerts.json # Active emergency alerts
78+ ├── live_data_feeds.json # Live data source configurations
79+ ├── live_statistics.json # Live statistics data
80+ ├── educational_modules.json # Educational content modules
81+ ├── legal_cases_research.json # Legal cases data
82+ └── take_action_steps.json # Action step guides
7683```
7784
7885### Why JSON?
7986- ** Verifiable** : Every entry has source URLs that can be checked
80- - ** Testable** : 631 automated tests validate data integrity (required fields, valid URLs, no CCP sources)
87+ - ** Testable** : 3,602 automated tests validate data integrity (required fields, valid URLs, no CCP sources)
8188- ** No runtime dependency** : Data is bundled into JavaScript — the site works offline after initial load
8289- ** Git-auditable** : All changes go through PR review
8390
@@ -87,9 +94,9 @@ src/data/
8794
8895### Page Layout
8996```
90- App.jsx
97+ App.tsx
9198├── Header (navigation, language selector, mobile menu)
92- ├── Sidebar (desktop navigation)
99+ ├── Sidebar (desktop navigation — 7 items )
93100├── <Routes>
94101│ ├── Dashboard
95102│ ├── IntelligenceFeeds
@@ -99,7 +106,7 @@ App.jsx
99106│ ├── SecurityCenter
100107│ │ ├── Tab: Overview
101108│ │ ├── Tab: Tools
102- │ │ ├── Tab: Exit Ban Guide (ChinaExitBan)
109+ │ │ ├── Tab: Guides (ChinaExitBan, WhistleblowerGuide )
103110│ │ ├── Tab: Quiz
104111│ │ └── Tab: Report (IncidentReportForm)
105112│ ├── profiles/:slug → Profile pages (5-tab layout each)
@@ -109,7 +116,7 @@ App.jsx
109116
110117### Lazy Loading
111118All page-level components and heavy sub-components use ` React.lazy() ` + ` <Suspense> ` :
112- ``` jsx
119+ ``` tsx
113120const Dashboard = lazy (() => import (' ./pages/Dashboard' ));
114121```
115122
@@ -123,8 +130,8 @@ const Dashboard = lazy(() => import('./pages/Dashboard'));
123130## Supabase Integration (Optional)
124131
125132When ` VITE_SUPABASE_URL ` and ` VITE_SUPABASE_ANON_KEY ` are configured:
126- - ` src/services/supabaseClient.js ` creates a Supabase client
127- - ` src/services/supabaseService.js ` provides helpers for 4 form types:
133+ - ` src/services/supabaseClient.ts ` creates a Supabase client
134+ - ` src/services/supabaseService.ts ` provides helpers for 4 form types:
128135 - ` submitIncidentReport() ` → ` incident_reports ` table
129136 - ` submitVolunteerSignup() ` → ` volunteer_signups ` table
130137 - ` submitNewsletterSubscription() ` → ` newsletter_subscribers ` table
@@ -136,30 +143,33 @@ When not configured, the client is `null` and forms display "Coming Soon" notice
136143
137144## CCP Influence Detection
138145
139- ` src/services /sourceLinks.js ` contains a centralized system for detecting CCP state media:
146+ Centralized system in ` src/utils /sourceLinks.ts ` for detecting CCP state media:
140147- 21 state media outlet names (e.g., Xinhua, CGTN, People's Daily, Global Times)
141148- 13 blocked domains (e.g., xinhuanet.com, cgtn.com, globaltimes.cn)
142149- 15 elevated-risk entries requiring extra scrutiny
143150- 4 utility functions: ` isCCPSource() ` , ` isElevatedRisk() ` , ` getSourceRiskLevel() ` , ` validateSources() `
144- - 37 dedicated tests in ` src/test/ccp-influence-detection.test.js `
151+ - 37 dedicated tests in ` src/test/ccp-influence-detection.test.ts `
145152
146153---
147154
148155## Testing Strategy
149156
150- 631 tests across 34 files using Vitest + jsdom + React Testing Library.
157+ 3,602 tests across 192 files using Vitest + jsdom + React Testing Library.
151158
152159| Category | Files | What it tests |
153160| ----------| -------| ---------------|
154- | Data integrity | 8 files | JSON fields, valid URLs, no CCP sources, chronological order |
155- | Component tests | 10 files | React components render, user interactions, form submissions |
156- | Accessibility | 1 file | ARIA labels, keyboard nav, contrast ratios |
157- | Design system | 1 file | Scans all JSX for prohibited CSS patterns |
158- | URL health | 1 file | No CCP domains, no insecure HTTP URLs in data |
161+ | Data integrity | 15+ files | JSON fields, valid URLs, no CCP sources, chronological order, cross-dataset consistency |
162+ | Component tests | 60+ files | React components render, user interactions, form submissions |
163+ | Accessibility | 3 files | ARIA labels, keyboard nav, contrast ratios, heading hierarchy |
164+ | Design system | 1 file | Scans all TSX for prohibited CSS patterns (8 automated checks) |
165+ | URL health | 2 files | No CCP domains, no insecure HTTP URLs in data, HTTPS validation |
159166| i18n | 1 file | All 8 locales have identical key sets |
160- | Security | 2 files | CSP headers, WebRTC leak detection |
161- | Services | 2 files | Supabase service, live data service |
162- | Other | 8 files | Sitemap, manifest/PWA, routes, utilities |
167+ | Security | 3 files | CSP headers, WebRTC leak detection, supabase key validation |
168+ | Performance | 3 files | Bundle size budget, performance resilience, responsive layout |
169+ | TypeScript purity | 1 file | Enforces 0 JS/JSX files, no @ts-nocheck , strict mode |
170+ | Services | 4 files | Supabase service, live data service, data API, source links |
171+ | Profile pages | 15 files | All 15 profile pages render with correct data |
172+ | Other | 80+ files | Sitemap, manifest/PWA, routes, utilities, defensive coding, import hygiene |
163173
164174---
165175
0 commit comments