1+ <!DOCTYPE html>
2+ < html lang ="en ">
3+ < head >
4+ < meta charset ="UTF-8 ">
5+ < meta name ="viewport " content ="width=device-width, initial-scale=1.0 ">
6+ < title > Digital Humanities Dashboard: C.A.R. Literature</ title >
7+
8+ <!-- Tailwind CSS -->
9+ < script src ="https://cdn.tailwindcss.com "> </ script >
10+
11+ <!-- FontAwesome for Icons -->
12+ < link rel ="stylesheet " href ="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css ">
13+
14+ <!-- React and ReactDOM (Using Production builds for better UMD stability) -->
15+ < script crossorigin src ="https://unpkg.com/react@18.2.0/umd/react.production.min.js "> </ script >
16+ < script crossorigin src ="https://unpkg.com/react-dom@18.2.0/umd/react-dom.production.min.js "> </ script >
17+
18+ <!-- PropTypes (CRITICAL FIX: Required by Recharts UMD build to prevent 'oneOfType' undefined error) -->
19+ < script src ="https://unpkg.com/prop-types@15.8.1/prop-types.min.js "> </ script >
20+
21+ <!-- Babel for JSX -->
22+ < script src ="https://unpkg.com/@babel/standalone/babel.min.js "> </ script >
23+
24+ <!-- Recharts -->
25+ < script src ="https://unpkg.com/recharts@2.12.7/umd/Recharts.js "> </ script >
26+
27+ < style >
28+ body { background-color : # f8fafc ; }
29+ .animate-fade-in { animation : fadeIn 0.5s ease-in; }
30+ @keyframes fadeIn { from { opacity : 0 ; transform : translateY (10px ); } to { opacity : 1 ; transform : translateY (0 ); } }
31+ </ style >
32+ </ head >
33+ < body >
34+ < div id ="root "> </ div >
35+
36+ < script type ="text/babel ">
37+ const { useState } = React ;
38+
39+ // Safe destructuring of Recharts components
40+ const {
41+ BarChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip, Legend, ResponsiveContainer,
42+ LineChart, Line, AreaChart, Area
43+ } = window . Recharts ;
44+
45+ // --- DATASETS ---
46+
47+ const genderData = [
48+ { year : '1989' , source : 'Notre Librairie' , total : 1 , women : 0 , label : 'Indigenous Women' , notes : 'Only Huguette Kreif (French) mentioned' } ,
49+ { year : '1990' , source : 'Anthologie (Pénel)' , total : 60 , women : 7 , percentage : 11.6 , label : 'Women Contributors' } ,
50+ { year : '2023' , source : 'Anthologie (Kotagbia)' , total : 27 , women : 5 , percentage : 18.5 , label : 'Women Contributors' } ,
51+ { year : '2025' , source : 'Les Murmures' , total : 12 , women : 12 , percentage : 100 , label : 'Women Featured' } ,
52+ ] ;
53+
54+ const timelineData = [
55+ { year : 1970 , event : 'Bokassa Regime' , severity : 9 , type : 'Repression' , detail : 'Censorship, persecution of intellectuals (Bamboté exile).' } ,
56+ { year : 1980 , event : 'Post-Bokassa Frenzy' , severity : 4 , type : 'Resurgence' , detail : 'Short "frenzy" of reading/writing. Small journals appear.' } ,
57+ { year : 1983 , event : 'The Institutional Void' , severity : 10 , type : 'Collapse' , detail : 'UNESCO Report: No library, no newspapers since 1981.' } ,
58+ { year : 1990 , event : 'Economic Barrier' , severity : 8 , type : 'Economic' , detail : 'Book prices become prohibitive vs purchasing power.' } ,
59+ { year : 2017 , event : 'Éditions Oubangui' , severity : 3 , type : 'Sovereignty' , detail : 'Local publishing ecosystem established by L.O. Delombaut.' } ,
60+ { year : 2024 , event : 'Diaspora Initiative' , severity : 2 , type : 'Promotion' , detail : 'Arc-En-Ciel du Livre (Paris) organizes promotion.' } ,
61+ ] ;
62+
63+ const newVoices = [
64+ "Aliya Djabara" , "Adrianna Djangha Yasse" , "Gladys Nambele" ,
65+ "Providence Patassé" , "Emmanuella Ngoko Yassi" , "Esthanou Niko" ,
66+ "Inès Laure N’Gopot" , "Marie Allayam Mboro" , "Myriam Sakama Ondjibou" ,
67+ "Olivia Zoko Kassani" , "Winnie Deba" , "Phonsia Guere-Mbenzi"
68+ ] ;
69+
70+ // --- MAIN COMPONENT ---
71+
72+ const Dashboard = ( ) => {
73+ const [ activeTab , setActiveTab ] = useState ( 'gender' ) ;
74+
75+ return (
76+ < div className = "min-h-screen bg-slate-50 font-sans text-slate-800 p-6 max-w-7xl mx-auto" >
77+
78+ { /* HEADER */ }
79+ < header className = "mb-8 border-b border-slate-200 pb-6" >
80+ < div className = "flex items-center gap-3 mb-2" >
81+ < i className = "fa-solid fa-database text-indigo-600 text-3xl" > </ i >
82+ < h1 className = "text-3xl font-bold text-slate-900" > Digital Humanities Analysis</ h1 >
83+ </ div >
84+ < h2 className = "text-xl text-slate-500" > The Literary Landscape of C.A.R. (1980s–2025)</ h2 >
85+ < p className = "text-sm text-slate-400 mt-2" > Data extracted from historical archives, UNESCO reports, and contemporary anthologies.</ p >
86+ </ header >
87+
88+ { /* NAVIGATION */ }
89+ < div className = "flex flex-wrap gap-4 mb-8" >
90+ < button
91+ onClick = { ( ) => setActiveTab ( 'gender' ) }
92+ className = { `px-4 py-2 rounded-lg flex items-center gap-2 font-medium transition-colors ${ activeTab === 'gender' ? 'bg-indigo-600 text-white' : 'bg-white border border-slate-200 hover:bg-slate-50' } ` }
93+ >
94+ < i className = "fa-solid fa-users" > </ i >
95+ Gender Representation
96+ </ button >
97+ < button
98+ onClick = { ( ) => setActiveTab ( 'timeline' ) }
99+ className = { `px-4 py-2 rounded-lg flex items-center gap-2 font-medium transition-colors ${ activeTab === 'timeline' ? 'bg-indigo-600 text-white' : 'bg-white border border-slate-200 hover:bg-slate-50' } ` }
100+ >
101+ < i className = "fa-solid fa-arrow-trend-up" > </ i >
102+ Chronology of Flux
103+ </ button >
104+ < button
105+ onClick = { ( ) => setActiveTab ( 'barriers' ) }
106+ className = { `px-4 py-2 rounded-lg flex items-center gap-2 font-medium transition-colors ${ activeTab === 'barriers' ? 'bg-indigo-600 text-white' : 'bg-white border border-slate-200 hover:bg-slate-50' } ` }
107+ >
108+ < i className = "fa-solid fa-triangle-exclamation" > </ i >
109+ Structural Barriers
110+ </ button >
111+ </ div >
112+
113+ { /* CONTENT AREA */ }
114+ < div className = "bg-white rounded-xl shadow-sm border border-slate-200 p-6 min-h-[500px]" >
115+
116+ { /* TAB 1: GENDER ANALYSIS */ }
117+ { activeTab === 'gender' && (
118+ < div className = "animate-fade-in" >
119+ < h3 className = "text-xl font-bold mb-4 flex items-center gap-2" >
120+ < i className = "fa-solid fa-venus text-pink-500" > </ i >
121+ The Rise of Female Voices (1989–2025)
122+ </ h3 >
123+ < div className = "grid md:grid-cols-3 gap-6" >
124+ < div className = "md:col-span-2 h-80" >
125+ < ResponsiveContainer width = "100%" height = "100%" >
126+ < BarChart data = { genderData } margin = { { top : 20 , right : 30 , left : 20 , bottom : 5 } } >
127+ < CartesianGrid strokeDasharray = "3 3" vertical = { false } />
128+ < XAxis dataKey = "year" />
129+ < YAxis label = { { value : 'Number of Women' , angle : - 90 , position : 'insideLeft' } } />
130+ < Tooltip
131+ contentStyle = { { borderRadius : '8px' , border : 'none' , boxShadow : '0 4px 6px -1px rgba(0,0,0,0.1)' } }
132+ />
133+ < Legend />
134+ < Bar dataKey = "women" name = "Women Writers Identified" fill = "#db2777" radius = { [ 4 , 4 , 0 , 0 ] } barSize = { 50 } />
135+ </ BarChart >
136+ </ ResponsiveContainer >
137+ </ div >
138+
139+ < div className = "bg-pink-50 p-6 rounded-xl border border-pink-100" >
140+ < h4 className = "font-bold text-pink-900 mb-3" > The 2025 Cohort</ h4 >
141+ < p className = "text-xs text-pink-600 mb-3" > Featured in < em > Les murmures d’espoir pour mon pays</ em > </ p >
142+ < ul className = "text-sm space-y-1 text-slate-700 h-60 overflow-y-auto pr-2" >
143+ { newVoices . map ( ( name , i ) => (
144+ < li key = { i } className = "flex items-center gap-2 border-b border-pink-100 py-1" >
145+ < span className = "w-2 h-2 rounded-full bg-pink-400" > </ span >
146+ { name }
147+ </ li >
148+ ) ) }
149+ </ ul >
150+ </ div >
151+ </ div >
152+ < div className = "mt-6 text-sm text-slate-500 bg-slate-50 p-4 rounded-lg" >
153+ < strong > Data Insight:</ strong > In 1989, < em > Notre Librairie</ em > listed zero indigenous women. By 2025, a specific anthology highlights 12 distinct female poets, shifting from "historical absence" to specific, named recognition.
154+ </ div >
155+ </ div >
156+ ) }
157+
158+ { /* TAB 2: TIMELINE ANALYSIS */ }
159+ { activeTab === 'timeline' && (
160+ < div className = "animate-fade-in" >
161+ < h3 className = "text-xl font-bold mb-4 flex items-center gap-2" >
162+ < i className = "fa-regular fa-calendar text-blue-500" > </ i >
163+ Institutional Flux: From Void to Sovereignty
164+ </ h3 >
165+ < div className = "h-80 w-full mb-6" >
166+ < ResponsiveContainer width = "100%" height = "100%" >
167+ < AreaChart data = { timelineData } margin = { { top : 10 , right : 30 , left : 0 , bottom : 0 } } >
168+ < defs >
169+ < linearGradient id = "colorSeverity" x1 = "0" y1 = "0" x2 = "0" y2 = "1" >
170+ < stop offset = "5%" stopColor = "#ef4444" stopOpacity = { 0.8 } />
171+ < stop offset = "95%" stopColor = "#ef4444" stopOpacity = { 0.1 } />
172+ </ linearGradient >
173+ </ defs >
174+ < XAxis dataKey = "year" />
175+ < YAxis label = { { value : 'Institutional Difficulty Index (0-10)' , angle : - 90 , position : 'insideLeft' } } domain = { [ 0 , 10 ] } />
176+ < CartesianGrid strokeDasharray = "3 3" />
177+ < Tooltip />
178+ < Area type = "monotone" dataKey = "severity" stroke = "#ef4444" fillOpacity = { 1 } fill = "url(#colorSeverity)" name = "Institutional Difficulty" />
179+ </ AreaChart >
180+ </ ResponsiveContainer >
181+ </ div >
182+
183+ < div className = "grid md:grid-cols-3 gap-4" >
184+ { timelineData . map ( ( item , idx ) => (
185+ < div key = { idx } className = "bg-slate-50 p-4 rounded-lg border border-slate-200 hover:shadow-md transition-shadow" >
186+ < div className = "flex justify-between items-center mb-1" >
187+ < span className = "font-bold text-blue-600" > { item . year } </ span >
188+ < span className = { `text-xs font-bold px-2 py-1 rounded ${
189+ item . severity > 7 ? 'bg-red-100 text-red-700' :
190+ item . severity < 4 ? 'bg-green-100 text-green-700' : 'bg-amber-100 text-amber-700'
191+ } `} > { item . type } </ span >
192+ </ div >
193+ < h4 className = "font-bold text-slate-800 text-sm" > { item . event } </ h4 >
194+ < p className = "text-xs text-slate-500 mt-1" > { item . detail } </ p >
195+ </ div >
196+ ) ) }
197+ </ div >
198+ </ div >
199+ ) }
200+
201+ { /* TAB 3: BARRIERS ANALYSIS */ }
202+ { activeTab === 'barriers' && (
203+ < div className = "animate-fade-in" >
204+ < h3 className = "text-xl font-bold mb-6 flex items-center gap-2" >
205+ < i className = "fa-solid fa-triangle-exclamation text-amber-500" > </ i >
206+ The "Institutional Void" (1983–1985)
207+ </ h3 >
208+
209+ < div className = "grid md:grid-cols-2 gap-8" >
210+ < div className = "space-y-4" >
211+ < div className = "bg-amber-50 p-5 rounded-xl border border-amber-100" >
212+ < h4 className = "font-bold text-amber-800 mb-2 flex items-center gap-2" >
213+ < i className = "fa-solid fa-building-columns" > </ i > Infrastructure
214+ </ h4 >
215+ < ul className = "list-disc pl-5 text-sm text-amber-900 space-y-2" >
216+ < li > < strong > No National Library:</ strong > A total lack of archival memory (Dubreuil 12).</ li >
217+ < li > < strong > Print Media Blackout:</ strong > No newspaper published in the country between 1981 and 1983.</ li >
218+ </ ul >
219+ </ div >
220+
221+ < div className = "bg-slate-50 p-5 rounded-xl border border-slate-200" >
222+ < h4 className = "font-bold text-slate-800 mb-2 flex items-center gap-2" >
223+ < i className = "fa-solid fa-file-lines" > </ i > Economic & Literacy
224+ </ h4 >
225+ < ul className = "list-disc pl-5 text-sm text-slate-700 space-y-2" >
226+ < li > < strong > Prohibitive Cost:</ strong > Books too expensive for local purchasing power (Saulnier 192).</ li >
227+ < li > < strong > Regression Risk:</ strong > Scarcity of material created a risk of "return to illiteracy" for neo-literates (Dubreuil 15).</ li >
228+ </ ul >
229+ </ div >
230+ </ div >
231+
232+ < div className = "bg-green-50 p-6 rounded-xl border border-green-100" >
233+ < h4 className = "font-bold text-green-800 mb-4 text-lg" > The Solution: Cultural Sovereignty</ h4 >
234+ < p className = "text-sm text-green-900 mb-4 italic" >
235+ "Create an internal francophone area... small local publications." — Pierre Sammy-Mackfoy
236+ </ p >
237+
238+ < div className = "relative pl-4 border-l-2 border-green-300 space-y-6" >
239+ < div >
240+ < span className = "text-xs font-bold text-green-600 block" > 2017: The Turning Point</ span >
241+ < strong className = "text-slate-800" > Éditions Oubangui Established</ strong >
242+ < p className = "text-xs text-slate-600 mt-1" > Founder: Landry Ouoko Delombaut. < br /> Output: 84+ Titles.</ p >
243+ </ div >
244+ < div >
245+ < span className = "text-xs font-bold text-green-600 block" > Impact</ span >
246+ < strong className = "text-slate-800" > Internal Ecosystem</ strong >
247+ < p className = "text-xs text-slate-600 mt-1" > Replaces external intermediaries, allowing for the emergence of female voices (e.g., Yabouza).</ p >
248+ </ div >
249+ </ div >
250+ </ div >
251+ </ div >
252+ </ div >
253+ ) }
254+
255+ </ div >
256+ </ div >
257+ ) ;
258+ } ;
259+
260+ const root = ReactDOM . createRoot ( document . getElementById ( 'root' ) ) ;
261+ root . render ( < Dashboard /> ) ;
262+ </ script >
263+ </ body >
264+ </ html >
0 commit comments