252 lines
6.2 KiB
Markdown
252 lines
6.2 KiB
Markdown
# RFCP Fixes - Iteration 1
|
||
|
||
## Issues to Fix:
|
||
|
||
### 1. Heatmap Colors - More Obvious Gradient
|
||
|
||
**Current problem:** Green→Yellow→Red gradient not obvious enough
|
||
|
||
**Fix:** Update `src/components/map/Heatmap.tsx`
|
||
|
||
Change the gradient to use more distinct colors with better visibility:
|
||
|
||
```typescript
|
||
// In Heatmap.tsx, update the gradient prop:
|
||
|
||
<HeatmapLayer
|
||
points={heatmapPoints}
|
||
longitudeExtractor={(p: any) => p[1]}
|
||
latitudeExtractor={(p: any) => p[0]}
|
||
intensityExtractor={(p: any) => p[2]}
|
||
gradient={{
|
||
0.0: '#0000ff', // Blue (very weak, -120 dBm)
|
||
0.2: '#00ffff', // Cyan (weak, -110 dBm)
|
||
0.4: '#00ff00', // Green (fair, -100 dBm)
|
||
0.6: '#ffff00', // Yellow (good, -85 dBm)
|
||
0.8: '#ff7f00', // Orange (strong, -70 dBm)
|
||
1.0: '#ff0000', // Red (excellent, > -70 dBm)
|
||
}}
|
||
radius={25}
|
||
blur={15}
|
||
max={1.0}
|
||
/>
|
||
```
|
||
|
||
**Reasoning:**
|
||
- Blue/Cyan for weak signals (more intuitive - "cold" = weak)
|
||
- Green for acceptable
|
||
- Yellow/Orange for good
|
||
- Red for excellent (hot = strong)
|
||
|
||
This is actually inverted from typical "green=good", but in RF planning, RED = STRONG SIGNAL = GOOD!
|
||
|
||
---
|
||
|
||
### 2. Coverage Radius - Increase to 100km
|
||
|
||
**Current problem:** Max radius only 20km, not enough for tactical planning
|
||
|
||
**Fix:** Update `src/components/panels/SiteForm.tsx` (or wherever Coverage Settings are)
|
||
|
||
Find the radius slider and change:
|
||
|
||
```typescript
|
||
// Old:
|
||
<Slider
|
||
label="Radius (km)"
|
||
min={1}
|
||
max={20} // ← Change this
|
||
step={1}
|
||
value={coverageSettings.radius}
|
||
onChange={(value) => updateCoverageSettings({ radius: value })}
|
||
/>
|
||
|
||
// New:
|
||
<Slider
|
||
label="Radius (km)"
|
||
min={1}
|
||
max={100} // ← Increased to 100km
|
||
step={5} // ← Larger step for easier control
|
||
value={coverageSettings.radius}
|
||
onChange={(value) => updateCoverageSettings({ radius: value })}
|
||
help="Calculation area around each site"
|
||
/>
|
||
```
|
||
|
||
**Also update default value in store:**
|
||
|
||
```typescript
|
||
// In src/store/coverage.ts or wherever coverage settings are initialized:
|
||
const initialSettings = {
|
||
radius: 10, // Default 10km (reasonable starting point)
|
||
resolution: 200, // 200m resolution
|
||
rsrpThreshold: -120
|
||
};
|
||
```
|
||
|
||
---
|
||
|
||
### 3. Save & Calculate Button
|
||
|
||
**Current problem:** Two separate buttons, extra click needed
|
||
|
||
**Fix:** Update `src/components/panels/SiteForm.tsx`
|
||
|
||
Replace the button section:
|
||
|
||
```typescript
|
||
// Old:
|
||
<div className="flex gap-2">
|
||
<Button onClick={handleSave}>Save</Button>
|
||
<Button onClick={handleDelete} variant="danger">Delete</Button>
|
||
</div>
|
||
|
||
// New:
|
||
<div className="flex gap-2">
|
||
<Button
|
||
onClick={handleSaveAndCalculate}
|
||
variant="primary"
|
||
className="flex-1"
|
||
>
|
||
💾 Save & Calculate Coverage
|
||
</Button>
|
||
<Button
|
||
onClick={handleSave}
|
||
variant="secondary"
|
||
className="flex-1"
|
||
>
|
||
💾 Save Only
|
||
</Button>
|
||
<Button
|
||
onClick={handleDelete}
|
||
variant="danger"
|
||
>
|
||
🗑️ Delete
|
||
</Button>
|
||
</div>
|
||
|
||
// Add the handler:
|
||
const handleSaveAndCalculate = async () => {
|
||
// Save the site first
|
||
await handleSave();
|
||
|
||
// Then trigger coverage calculation
|
||
const sites = useSitesStore.getState().sites;
|
||
const coverage = useCoverageStore.getState();
|
||
|
||
// Calculate coverage for all sites
|
||
await coverage.calculateCoverage(sites);
|
||
|
||
// Show success toast
|
||
toast.success('Site saved and coverage calculated!');
|
||
};
|
||
```
|
||
|
||
**Alternative (simpler):** Just make the main button do both:
|
||
|
||
```typescript
|
||
<div className="flex gap-2">
|
||
<Button
|
||
onClick={async () => {
|
||
await handleSave();
|
||
// Auto-trigger calculate after save
|
||
const sites = useSitesStore.getState().sites;
|
||
await useCoverageStore.getState().calculateCoverage(sites);
|
||
}}
|
||
variant="primary"
|
||
className="flex-1"
|
||
>
|
||
💾 Save & Calculate
|
||
</Button>
|
||
<Button
|
||
onClick={handleDelete}
|
||
variant="danger"
|
||
>
|
||
🗑️ Delete
|
||
</Button>
|
||
</div>
|
||
```
|
||
|
||
---
|
||
|
||
### 4. Legend Colors Update
|
||
|
||
**Fix:** Update `src/components/map/Legend.tsx` to match new gradient:
|
||
|
||
```typescript
|
||
const signalRanges = [
|
||
{ label: 'Excellent', range: '> -70 dBm', color: '#ff0000' }, // Red
|
||
{ label: 'Good', range: '-70 to -85 dBm', color: '#ff7f00' }, // Orange
|
||
{ label: 'Fair', range: '-85 to -100 dBm', color: '#ffff00' }, // Yellow
|
||
{ label: 'Poor', range: '-100 to -110 dBm', color: '#00ff00' }, // Green
|
||
{ label: 'Weak', range: '-110 to -120 dBm', color: '#00ffff' }, // Cyan
|
||
{ label: 'Very Weak', range: '< -120 dBm', color: '#0000ff' }, // Blue
|
||
];
|
||
```
|
||
|
||
---
|
||
|
||
### 5. Resolution Adjustment for Large Radius
|
||
|
||
**Problem:** 200m resolution + 100km radius = MANY points = slow calculation
|
||
|
||
**Fix:** Auto-adjust resolution based on radius:
|
||
|
||
```typescript
|
||
// In src/store/coverage.ts or coverage calculator:
|
||
|
||
const getOptimalResolution = (radius: number): number => {
|
||
if (radius <= 10) return 100; // 100m for small areas
|
||
if (radius <= 30) return 200; // 200m for medium areas
|
||
if (radius <= 60) return 300; // 300m for large areas
|
||
return 500; // 500m for very large areas (100km)
|
||
};
|
||
|
||
// Use in calculation:
|
||
const resolution = settings.resolution || getOptimalResolution(settings.radius);
|
||
```
|
||
|
||
Or add a notice in UI:
|
||
|
||
```typescript
|
||
<p className="text-sm text-gray-500">
|
||
💡 Larger radius = longer calculation time.
|
||
Consider increasing resolution (200m → 500m) for faster results.
|
||
</p>
|
||
```
|
||
|
||
---
|
||
|
||
## Summary of Changes:
|
||
|
||
1. ✅ **Heatmap gradient:** Blue → Cyan → Green → Yellow → Orange → Red
|
||
2. ✅ **Max radius:** 20km → 100km (step: 5km)
|
||
3. ✅ **Button:** "Save & Calculate" as primary action
|
||
4. ✅ **Legend:** Updated colors to match new gradient
|
||
5. ✅ **Performance:** Auto-adjust resolution or show warning
|
||
|
||
---
|
||
|
||
## Implementation Order:
|
||
|
||
1. **Start with colors** (easiest, biggest visual impact)
|
||
2. **Then radius** (simple slider change)
|
||
3. **Then button** (requires store integration)
|
||
4. **Test everything**
|
||
|
||
---
|
||
|
||
## Files to Edit:
|
||
|
||
```
|
||
frontend/src/components/map/Heatmap.tsx - gradient colors
|
||
frontend/src/components/map/Legend.tsx - legend colors
|
||
frontend/src/components/panels/SiteForm.tsx - radius slider + button
|
||
frontend/src/store/coverage.ts - default settings
|
||
```
|
||
|
||
---
|
||
|
||
Would you like me to create the exact code patches for Claude Code to apply?
|
||
Or should I create complete replacement files?
|