Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .claude/settings.local.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
"Bash(mkdir:*)",
"Bash(npm run build:*)",
"Bash(npx tsc:*)",
"Bash(npm run test:run:*)"
"Bash(npm run test:run:*)",
"Bash(npm run typecheck:*)"
],
"deny": [],
"ask": []
Expand Down
8 changes: 8 additions & 0 deletions .vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"recommendations": [
"ms-vscode.vscode-typescript-next",
"bradlc.vscode-tailwindcss",
"esbenp.prettier-vscode",
"ms-vscode.vscode-json"
]
}
24 changes: 24 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"typescript.preferences.includePackageJsonAutoImports": "on",
"typescript.suggest.autoImports": true,
"typescript.preferences.importModuleSpecifier": "non-relative",
"typescript.format.enable": true,
"typescript.validate.enable": true,
"typescript.surveys.enabled": false,
"typescript.tsdk": "node_modules/typescript/lib",
"typescript.suggest.includeCompletionsForModuleExports": true,
"typescript.suggest.includeCompletionsForImportStatements": true,
"typescript.preferences.includeCompletionsForImportStatements": true,
"typescript.workspaceSymbols.scope": "allOpenProjects",
"typescript.references.enabled": true,
"path-intellisense.mappings": {
"@": "${workspaceFolder}/src",
"@features": "${workspaceFolder}/src/features",
"@components": "${workspaceFolder}/src/components",
"@hooks": "${workspaceFolder}/src/hooks",
"@services": "${workspaceFolder}/src/services",
"@stores": "${workspaceFolder}/src/stores",
"@utils": "${workspaceFolder}/src/utils",
"@context": "${workspaceFolder}/src/context"
}
}
100 changes: 98 additions & 2 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ src/
├── types/ # TypeScript type definitions (country, coordinates, ISSStats)
├── utils/ # Utility functions (countries, iss, logger, numberFormatter)
├── features/ # Feature-specific code
│ └── iss-tracker/ # ISS tracking feature with map visualization
│ └── iss-tracker/ # ISS tracking feature with map visualisation
├── styles/ # Global CSS files (vars.css, grid.css)
└── apis/ # API endpoint configurations
```
Expand All @@ -70,7 +70,7 @@ src/
### Important Notes
- React Strict Mode causes double API calls during development - abort signals are critical for preventing blocked endpoints
- Polling automatically suspends when the browser tab is inactive to conserve resources
- Application uses Leaflet maps via react-leaflet for geographic visualization
- Application uses Leaflet maps via react-leaflet for geographic visualisation
- The architecture now supports adding multiple features alongside the ISS tracker in the `features/` directory

## Development Approaches
Expand Down Expand Up @@ -168,6 +168,102 @@ import { ErrorBoundary } from 'react-error-boundary';
- **Best Practices**: Use `interface` for object shapes, `type` for unions/aliases, prefer `unknown` over `any`
- **Import Style**: Use `import type { ... }` for type-only imports to improve build performance

## Orbital Visualisation System

### Features
The ISS tracker includes advanced orbital visualisation capabilities:

- **Historical Tracking**: View ISS orbital path for the past 24 hours
- **Future Predictions**: Display predicted ISS positions for up to 6 hours
- **Ground Track Visualization**: Show ISS ground track patterns
- **Real-time Control Panel**: Toggle features and adjust settings
- **Customizable Appearance**: Control path colors, opacity, and update intervals

### State Management (Zustand)
Orbital visualisation uses Zustand for state management:

```typescript
import { useOrbitalStore } from '../stores/orbitalStore';

// Access store state and actions
const {
settings,
isHistoricalTrackingEnabled,
toggleHistoricalTracking,
updateSettings,
} = useOrbitalStore();
```

### Key Components

#### OrbitalControlPanel
- **Location**: `src/components/OrbitalControlPanel/`
- **Purpose**: Floating control panel for managing orbital visualisation
- **Features**: Toggle switches, sliders for duration/opacity, color picker
- **Position**: Fixed top-right with responsive design

#### OrbitalVisualization
- **Location**: `src/components/OrbitalPath/`
- **Purpose**: Renders orbital paths on Leaflet map
- **Layers**: Historical path, future predictions, ground track
- **Integration**: Embedded within MapContainer component

#### OrbitalDataService
- **Location**: `src/services/OrbitalDataService.ts`
- **Purpose**: Fetches historical and predicted ISS positions
- **API**: Uses wheretheiss.at API with rate limiting (1 req/sec)
- **Features**: Chunk requests, abort signal support, retry logic with exponential backoff, error handling

#### useOrbitalData Hook
- **Location**: `src/hooks/useOrbitalData.ts`
- **Purpose**: Manages orbital data fetching and updates
- **Features**: Automatic polling, cleanup on unmount, settings synchronization

### Usage Examples

#### Enable Historical Tracking
```typescript
import { useOrbitalStore } from '../stores/orbitalStore';

function MyComponent() {
const { toggleHistoricalTracking } = useOrbitalStore();

return (
<button onClick={toggleHistoricalTracking}>
Enable Orbital Tracking
</button>
);
}
```

#### Customize Orbital Settings
```typescript
const { updateSettings } = useOrbitalStore();

// Update path duration to 4 hours
updateSettings({ pathDuration: 4 });

// Change path color and opacity
updateSettings({
pathColor: '#ff6600',
pathOpacity: 0.8
});
```

### API Integration
- **Historical Data**: `/satellites/25544/positions?timestamps=...`
- **Rate Limiting**: 1 request per second with automatic delays
- **Data Chunks**: Max 10 timestamps per request
- **Retry Logic**: Exponential backoff (1s, 2s, 4s) for failed requests
- **Error Handling**: Network errors, abort signals, API failures with proper propagation
- **Caching**: No caching - always fresh data for real-time tracking

### Performance Considerations
- **Efficient Updates**: Only fetch data when tracking is enabled
- **Abort Controllers**: Cancel requests on component unmount
- **Minimal Re-renders**: Zustand state management reduces unnecessary updates
- **Chunked Requests**: Large time ranges split into manageable API calls

### CSS and Styling
- **Global styles**: Place in `src/styles/` (vars.css, grid.css)
- **Feature styles**: Co-locate with feature components
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ The application follows a modular architecture with clear separation of concerns

## 📱 Live Demo

Visit the live application: [ISS Tracker](https://your-github-username.github.io/iss-track-react/)
Visit the live application: [ISS Tracker](https://jamesmanuel.github.io/iss-track-react/)

## 🤝 Contributing

Expand Down
36 changes: 33 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
"react-dom": "^19.0.0",
"react-error-boundary": "^5.0.0",
"react-leaflet": "^5.0.0",
"web-vitals": "^2.1.4"
"web-vitals": "^2.1.4",
"zustand": "^5.0.8"
},
"scripts": {
"start": "vite",
Expand Down
6 changes: 5 additions & 1 deletion src/components/Loader/Loader.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import { memo } from 'react';
import './loader.css';
export default function Loader(){

function Loader(){
return (
<span className="loader"></span>
)
}

export default memo(Loader);
Loading