File size: 9,781 Bytes
896453f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
# Frontend Integration Guide

Complete guide for integrating the React Policy Accountability Dashboards with the Python backend.

## Quick Start

```bash
# 1. Generate data from Python analysis
cd /home/developer/projects/open-navigator
source .venv/bin/activate
python examples/tuscaloosa_accountability_report.py

# 2. Start frontend
cd frontend/policy-dashboards
npm install
npm start
```

## Architecture

```
Python Backend (Data Generation)
    ↓
    β”œβ”€β”€ Scrape meetings (agents/scraper.py)
    β”œβ”€β”€ Extract decisions (extraction/decision_analyzer.py)
    β”œβ”€β”€ Calculate accountability metrics (extraction/accountability_dashboards.py)
    β”œβ”€β”€ Generate dashboards (examples/tuscaloosa_accountability_report.py)
    ↓
Output Files
    β”œβ”€β”€ output/tuscaloosa_accountability_dashboards.json (Python format)
    └── frontend/policy-dashboards/src/data/dashboardData.js (React format)
    ↓
React Frontend (Visualization)
    β”œβ”€β”€ Load dashboardData.js
    β”œβ”€β”€ Render 4 dashboards + summary
    └── Display at http://localhost:3000
```

## Data Flow

### 1. Python Analysis

```python
# examples/tuscaloosa_accountability_report.py

# Generate all accountability dashboards
dashboards = generate_all_accountability_dashboards(
    jurisdiction="Tuscaloosa, AL",
    meeting_documents=documents,
    decisions=all_decisions,
    budget_items=all_budget_items
)

# Export for frontend (automatically called)
export_for_frontend(dashboards)
```

### 2. JavaScript Data Format

The export function converts Python dataclasses to JavaScript modules:

**Python:**
```python
@dataclass
class RhetoricGapMetrics:
    sentiment_density: float = 92.0
    budget_change_dollars: float = -120000
```

**JavaScript:**
```javascript
export const rhetoricGapData = {
  sentimentScore: 92,
  budgetDelta: -120000,
  // ... more fields
};
```

### 3. React Components

```jsx
// src/components/WordsVsDollars.jsx
import { rhetoricGapData as d } from '../data/dashboardData';

export default function WordsVsDollars() {
  return (
    <MetricCard 
      value={`${d.sentimentScore}%`}
      label="Positive sentiment" 
    />
  );
}
```

## Component Structure

```
frontend/policy-dashboards/src/
β”œβ”€β”€ components/
β”‚   β”œβ”€β”€ shared/                    # Reusable UI components
β”‚   β”‚   β”œβ”€β”€ BarMeter.jsx          # Horizontal bar charts
β”‚   β”‚   β”œβ”€β”€ MetricCard.jsx        # Key metric display
β”‚   β”‚   β”œβ”€β”€ Compare.jsx           # 4-column benchmark comparison
β”‚   β”‚   └── InsightBox.jsx        # Summary/logic boxes
β”‚   β”œβ”€β”€ Summary.jsx               # Summary dashboard (tab 0)
β”‚   β”œβ”€β”€ WordsVsDollars.jsx        # Dashboard 1: Rhetoric Gap
β”‚   β”œβ”€β”€ EndlessStudyLoop.jsx      # Dashboard 2: Deferral Pattern
β”‚   β”œβ”€β”€ WhereMoneyWent.jsx        # Dashboard 3: Displacement Matrix
β”‚   └── WhoIsInCharge.jsx         # Dashboard 4: Influence Radar
β”œβ”€β”€ data/
β”‚   └── dashboardData.js          # ⚠️ AUTO-GENERATED FROM PYTHON
β”œβ”€β”€ App.jsx                        # Main app shell with tabs
└── index.js                       # React entry point
```

## Customization

### Change Dashboard Titles

Edit `src/App.jsx`:

```jsx
const tabs = [
  { id: 0, label: 'Summary', component: Summary },
  { id: 1, label: 'Your Custom Title', component: WordsVsDollars },
  // ...
];
```

### Update Benchmark Data

Currently benchmarks use **placeholder values**. To add real data:

**Option 1: Update Python Export**

```python
# In examples/tuscaloosa_accountability_report.py

def calculate_real_benchmarks(jurisdiction):
    """Query NCES data for real benchmarks."""
    # Query NCES Common Core of Data
    republican_districts = nces_api.query(party="R")
    democratic_districts = nces_api.query(party="D")
    
    return {
        "republicanAvg": np.mean([d.per_student for d in republican_districts]),
        "democraticAvg": np.mean([d.per_student for d in democratic_districts]),
        # ...
    }

# In export_for_frontend()
benchmarks = calculate_real_benchmarks(jurisdiction)
```

**Option 2: Update JavaScript Directly**

```javascript
// src/data/dashboardData.js
benchmarks: {
  thisDistrict: { perStudent: 41, label: "This District" },
  republicanAvg: { perStudent: 74, label: "Republican Districts" },
  // Update these values ↑
}
```

### Add New Metrics

**1. Python Analysis**

```python
# extraction/accountability_dashboards.py

@dataclass
class RhetoricGapMetrics:
    new_metric: float  # Add field
```

**2. Python Export**

```python
# examples/tuscaloosa_accountability_report.py

js_content += f"""
  newMetric: {gap.new_metric},
"""
```

**3. React Component**

```jsx
// src/components/WordsVsDollars.jsx

<MetricCard 
  value={d.newMetric} 
  label="New Metric Description" 
/>
```

### Change Colors

```jsx
// In any component
const colors = {
  positive: "#1D9E75",   // Green - change this
  negative: "#D85A30",   // Red/orange - change this
  neutral: "#222"        // Dark gray
};
```

## Deployment

### Option 1: Static Site

```bash
cd frontend/policy-dashboards

# Build for production
npm run build

# Serve the build folder
# Upload build/* to your web server
```

### Option 2: GitHub Pages

```bash
# Install gh-pages
npm install --save-dev gh-pages

# Add to package.json:
{
  "homepage": "https://yourusername.github.io/open-navigator",
  "scripts": {
    "predeploy": "npm run build",
    "deploy": "gh-pages -d build"
  }
}

# Deploy
npm run deploy
```

### Option 3: Netlify/Vercel

1. Connect repository
2. Set build command: `npm run build`
3. Set publish directory: `build`
4. Deploy

### Option 4: Integrate with Python API

```python
# api/app.py (FastAPI example)
from fastapi.staticfiles import StaticFiles

app.mount(
    "/dashboards", 
    StaticFiles(directory="frontend/policy-dashboards/build", html=True),
    name="dashboards"
)
```

Access at: `http://localhost:8000/dashboards`

## Workflow

### Regular Updates

```bash
# 1. Scrape new data
python main.py scrape --state AL --municipality Tuscaloosa \
  --url https://tuscaloosaal.suiteonemedia.com \
  --platform suiteonemedia --max-events 0

# 2. Run accountability analysis (auto-exports to frontend)
python examples/tuscaloosa_accountability_report.py

# 3. Frontend auto-refreshes if dev server is running
# OR rebuild for production:
cd frontend/policy-dashboards && npm run build
```

### Data Update Frequency

- **Monthly**: Run analysis after each board meeting
- **Quarterly**: Full benchmark recalculation
- **Annual**: Major methodology updates

## Advanced Features

### PDF Export

```bash
npm install html2canvas jspdf
```

```jsx
// src/App.jsx
import html2canvas from 'html2canvas';
import jsPDF from 'jspdf';

function downloadPDF() {
  const element = document.getElementById('dashboard-container');
  html2canvas(element).then(canvas => {
    const pdf = new jsPDF();
    pdf.addImage(canvas.toDataURL('image/png'), 'PNG', 0, 0);
    pdf.save('tuscaloosa-accountability.pdf');
  });
}

// Add button:
<button onClick={downloadPDF}>Download PDF</button>
```

### Presentation Mode

Stack all dashboards for scrollable handout:

```jsx
// src/App.jsx
const searchParams = new URLSearchParams(window.location.search);
const presentMode = searchParams.get('mode') === 'present';

// Render differently based on mode
```

Visit: `http://localhost:3000?mode=present`

### Real-Time API Integration

```jsx
// src/App.jsx
import { useState, useEffect } from 'react';

function App() {
  const [data, setData] = useState(null);
  
  useEffect(() => {
    fetch('/api/accountability/latest')
      .then(res => res.json())
      .then(data => setData(data));
  }, []);
  
  // ...
}
```

## Troubleshooting

### Issue: Data Not Updating

**Solution:**
```bash
# Verify Python export ran
ls -la frontend/policy-dashboards/src/data/dashboardData.js

# Check file timestamp
stat frontend/policy-dashboards/src/data/dashboardData.js

# Restart dev server
cd frontend/policy-dashboards
npm start
```

### Issue: Build Errors

**Solution:**
```bash
# Clear cache
rm -rf node_modules package-lock.json

# Reinstall
npm install

# Try again
npm start
```

### Issue: Wrong Data Showing

**Solution:**
```bash
# Check which data file React is loading
grep -r "dashboardData" frontend/policy-dashboards/src/

# Verify export path in Python
grep "export_for_frontend" examples/tuscaloosa_accountability_report.py
```

### Issue: Benchmarks Are Placeholders

**Expected** - Benchmark data currently uses illustrative values.

**To Fix:**
1. Add NCES data query to Python analysis
2. Calculate per-student averages by party affiliation
3. Update `export_for_frontend()` function

See: "Update Benchmark Data" section above

## Testing

### Manual Testing Checklist

- [ ] Python analysis runs without errors
- [ ] `dashboardData.js` file is generated
- [ ] File timestamp is recent
- [ ] React dev server starts
- [ ] All 5 tabs load correctly
- [ ] Data matches Python output
- [ ] Benchmarks display (even if placeholder)
- [ ] "Ask them" boxes show correct questions

### Automated Testing

```bash
cd frontend/policy-dashboards

# Run tests
npm test

# Coverage report
npm test -- --coverage
```

## Resources

- **React Docs**: https://react.dev/
- **Create React App**: https://create-react-app.dev/
- **Python Backend**: `extraction/accountability_dashboards.py`
- **Strategy Guide**: `docs/ACCOUNTABILITY_DASHBOARD_STRATEGY.md`
- **NCES Data**: https://nces.ed.gov/ccd/

## Support

For issues:
1. Check this guide
2. Review `frontend/policy-dashboards/README.md`
3. Check Python logs: `logs/`
4. Open GitHub issue

---

**Integration Complete** βœ… Python analysis β†’ JavaScript export β†’ React visualization