You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
5.1 KiB
5.1 KiB
Contributing to OpenHamClock
Thank you for your interest in contributing! This document explains how to work with the modular codebase.
📐 Architecture Overview
OpenHamClock uses a clean separation of concerns:
src/
├── components/ # React UI components
├── hooks/ # Data fetching & state management
├── utils/ # Pure utility functions
└── styles/ # CSS with theme variables
🔧 Working on Components
Each component is self-contained in its own file. To modify a component:
- Open the component file in
src/components/ - Make your changes
- Test with
npm run dev - Ensure all three themes still work
Component Guidelines
// Good component structure
export const MyComponent = ({ prop1, prop2, onAction }) => {
// Hooks at the top
const [state, setState] = useState(initial);
// Event handlers
const handleClick = () => {
onAction?.(state);
};
// Early returns for loading/empty states
if (!prop1) return null;
// Main render
return (
<div className="panel">
{/* Use CSS variables for colors */}
<div style={{ color: 'var(--accent-cyan)' }}>
{prop1}
</div>
</div>
);
};
🪝 Working on Hooks
Hooks handle data fetching and state. Each hook:
- Fetches from a specific API endpoint
- Manages loading state
- Handles errors gracefully
- Returns consistent shape:
{ data, loading, error? }
Hook Guidelines
// Good hook structure
export const useMyData = (param) => {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
if (!param) {
setLoading(false);
return;
}
const fetchData = async () => {
try {
const response = await fetch(`/api/endpoint/${param}`);
if (response.ok) {
const result = await response.json();
setData(result);
}
} catch (err) {
console.error('MyData error:', err);
} finally {
setLoading(false);
}
};
fetchData();
const interval = setInterval(fetchData, 30000); // 30 sec refresh
return () => clearInterval(interval);
}, [param]);
return { data, loading };
};
🛠️ Working on Utilities
Utilities are pure functions with no side effects:
// Good utility
export const calculateSomething = (input1, input2) => {
// Pure calculation, no API calls or DOM access
return result;
};
🎨 CSS & Theming
Use CSS variables for all colors:
/* ✅ Good - uses theme variable */
.my-element {
color: var(--accent-cyan);
background: var(--bg-panel);
border: 1px solid var(--border-color);
}
/* ❌ Bad - hardcoded color */
.my-element {
color: #00ddff;
}
Available theme variables:
--bg-primary,--bg-secondary,--bg-tertiary,--bg-panel--border-color--text-primary,--text-secondary,--text-muted--accent-amber,--accent-green,--accent-red,--accent-blue,--accent-cyan,--accent-purple
📝 Adding a New Feature
New Component
- Create
src/components/MyComponent.jsx - Export from
src/components/index.js - Import and use in
App.jsx
New Hook
- Create
src/hooks/useMyHook.js - Export from
src/hooks/index.js - Import and use in component
New Utility
- Add function to appropriate file in
src/utils/ - Export from
src/utils/index.js - Import where needed
🧪 Testing Your Changes
# Start dev servers
node server.js # Terminal 1
npm run dev # Terminal 2
# Test checklist:
# [ ] Component renders correctly
# [ ] Works in Dark theme
# [ ] Works in Light theme
# [ ] Works in Legacy theme
# [ ] Responsive on smaller screens
# [ ] No console errors
# [ ] Data fetches correctly
📋 Pull Request Checklist
- Code follows existing patterns
- All themes work correctly
- No console errors/warnings
- Component is exported from index.js
- Added JSDoc comments if needed
- Tested on different screen sizes
🐛 Reporting Bugs
- Check existing issues first
- Include browser and screen size
- Include console errors if any
- Include steps to reproduce
💡 Feature Requests
- Describe the feature
- Explain the use case
- Show how it would work (mockups welcome)
🏗️ Reference Implementation
The original monolithic version is preserved at public/index-monolithic.html (5714 lines). Use it as reference for:
- Line numbers for each feature section
- Complete implementation details
- Original styling decisions
Key Sections in Monolithic Version
| Lines | Section |
|---|---|
| 30-335 | CSS styles & themes |
| 340-640 | Config & map providers |
| 438-636 | Utility functions (geo) |
| 641-691 | useSpaceWeather |
| 721-810 | useBandConditions |
| 812-837 | usePOTASpots |
| 839-1067 | DX cluster filters & helpers |
| 1069-1696 | useDXCluster with filtering |
| 2290-3022 | WorldMap component |
| 3024-3190 | Header component |
| 3195-3800 | DXFilterManager |
| 3800-4200 | SettingsPanel |
| 5019-5714 | Main App & rendering |
📜 License
By contributing, you agree that your contributions will be licensed under the MIT License.