Skip to content

Commit 521fc92

Browse files
authored
Merge pull request #24 from ProspektStudio/Ace-Edits
Refactor CurrentlyViewing component to use CustomDropdown for group a…
2 parents 71fed18 + f7408bf commit 521fc92

4 files changed

Lines changed: 424 additions & 93 deletions

File tree

components/CurrentlyViewing.tsx

Lines changed: 41 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
import useClientStore from '@/services/clientStore';
2+
import CustomDropdown from './CustomDropdown';
23

34
const CurrentlyViewing: React.FC = () => {
45
const { selectedGroup, satellites, selectedSatellite, setSelectedGroup, setSelectedSatellite } = useClientStore();
56

67
const groups = [
7-
{ name: 'Space Stations', value: 'stations' },
8-
{ name: 'Globalstar', value: 'globalstar' },
9-
{ name: 'Intelsat', value: 'intelsat' }
8+
{ value: 'stations', label: 'Space Stations' },
9+
{ value: 'globalstar', label: 'Globalstar' },
10+
{ value: 'intelsat', label: 'Intelsat' }
1011
];
1112

1213
// Only show if a group is selected
@@ -16,77 +17,45 @@ const CurrentlyViewing: React.FC = () => {
1617
setSelectedSatellite(satellites.find(satellite => satellite.noradId === noradId) || null);
1718
};
1819

19-
const selectStyle = {
20-
background: 'rgba(0, 0, 0, 0.2)',
21-
border: '1px solid rgba(255, 255, 255, 0.1)',
22-
color: '#FFFFFF',
23-
padding: '4px 8px',
24-
borderRadius: '4px',
25-
fontSize: '16px',
26-
fontFamily: 'Shentox, sans-serif',
27-
cursor: 'pointer',
28-
width: '200px'
29-
};
30-
31-
const labelStyle = {
32-
color: '#969696',
33-
paddingRight: '16px',
34-
whiteSpace: 'nowrap'
35-
};
36-
37-
const cellStyle = {
38-
padding: '8px 8px'
39-
};
20+
const satelliteOptions = satellites.map(sat => ({
21+
value: sat.noradId.toString(),
22+
label: sat.name
23+
}));
4024

4125
return (
42-
<div>
43-
<div
44-
style={{
45-
background: 'rgba(0, 0, 0, 0.3)',
46-
backdropFilter: 'blur(10px)',
47-
fontSize: '16px',
48-
fontFamily: 'Shentox, sans-serif',
49-
color: '#FFFFFF',
50-
}}
51-
>
52-
<table>
53-
<tbody>
54-
<tr>
55-
<td style={{ ...labelStyle, ...cellStyle }}>Current Group:</td>
56-
<td style={cellStyle}>
57-
<select
58-
value={selectedGroup}
59-
onChange={(e) => setSelectedGroup(e.target.value)}
60-
style={selectStyle}
61-
>
62-
{groups.map((group) => (
63-
<option key={group.value} value={group.value}>
64-
{group.name}
65-
</option>
66-
))}
67-
</select>
68-
</td>
69-
</tr>
70-
<tr>
71-
<td style={{ ...labelStyle, ...cellStyle }}>Selected Satellite:</td>
72-
<td style={cellStyle}>
73-
<select
74-
value={selectedSatellite?.noradId}
75-
onChange={(e) => onSatelliteSelect(Number(e.target.value))}
76-
style={selectStyle}
77-
>
78-
<option value=""></option>
79-
{satellites.map((satellite) => (
80-
<option key={satellite.noradId} value={satellite.noradId}>
81-
{satellite.name}
82-
</option>
83-
))}
84-
</select>
85-
</td>
86-
</tr>
87-
</tbody>
88-
</table>
89-
</div>
26+
<div className="currently-viewing">
27+
<h3 className="title">Find Satellite</h3>
28+
29+
<CustomDropdown
30+
options={groups}
31+
value={selectedGroup}
32+
onChange={setSelectedGroup}
33+
placeholder="Groups"
34+
/>
35+
36+
<CustomDropdown
37+
options={satelliteOptions}
38+
value={selectedSatellite?.noradId.toString() || ''}
39+
onChange={(value) => onSatelliteSelect(Number(value))}
40+
placeholder="Satellites"
41+
/>
42+
43+
<style jsx>{`
44+
.currently-viewing {
45+
display: flex;
46+
flex-direction: column;
47+
gap: 8px;
48+
padding: 16px 8px;
49+
}
50+
51+
.title {
52+
font-family: 'Inter', sans-serif;
53+
font-size: 14px;
54+
font-weight: 400;
55+
color: rgba(183, 183, 183, 0.7);
56+
margin: 0 0 8px 0;
57+
}
58+
`}</style>
9059
</div>
9160
);
9261
};

components/CustomDropdown.tsx

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
import React, { useState, useRef, useEffect } from 'react';
2+
3+
interface Option {
4+
value: string;
5+
label: string;
6+
}
7+
8+
interface CustomDropdownProps {
9+
options: Option[];
10+
value: string;
11+
onChange: (value: string) => void;
12+
placeholder: string;
13+
disabled?: boolean;
14+
}
15+
16+
const CustomDropdown: React.FC<CustomDropdownProps> = ({
17+
options,
18+
value,
19+
onChange,
20+
placeholder,
21+
disabled = false
22+
}) => {
23+
const [isOpen, setIsOpen] = useState(false);
24+
const dropdownRef = useRef<HTMLDivElement>(null);
25+
26+
const selectedOption = options.find(opt => opt.value === value);
27+
28+
useEffect(() => {
29+
const handleClickOutside = (event: MouseEvent) => {
30+
if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node)) {
31+
setIsOpen(false);
32+
}
33+
};
34+
35+
document.addEventListener('mousedown', handleClickOutside);
36+
return () => document.removeEventListener('mousedown', handleClickOutside);
37+
}, []);
38+
39+
return (
40+
<div className="custom-dropdown" ref={dropdownRef}>
41+
<div
42+
className={`dropdown-header ${isOpen ? 'open' : ''}`}
43+
onClick={() => !disabled && setIsOpen(!isOpen)}
44+
>
45+
<span>{selectedOption ? selectedOption.label : placeholder}</span>
46+
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
47+
<path d="M6 9l6 6 6-6" />
48+
</svg>
49+
</div>
50+
51+
{isOpen && (
52+
<div className="dropdown-list">
53+
<div className="dropdown-title">{placeholder}</div>
54+
{options.map((option) => (
55+
<div
56+
key={option.value}
57+
className={`dropdown-item ${option.value === value ? 'selected' : ''}`}
58+
onClick={() => {
59+
onChange(option.value);
60+
setIsOpen(false);
61+
}}
62+
>
63+
{option.label}
64+
</div>
65+
))}
66+
</div>
67+
)}
68+
69+
<style jsx>{`
70+
.custom-dropdown {
71+
position: relative;
72+
width: 100%;
73+
font-family: 'Inter', sans-serif;
74+
}
75+
76+
.dropdown-header {
77+
display: flex;
78+
align-items: center;
79+
justify-content: space-between;
80+
padding: 8px 12px;
81+
background: transparent;
82+
border: 0.4px solid #D8D8D8;
83+
border-radius: 4px;
84+
color: #D8D8D8;
85+
cursor: pointer;
86+
height: 36px;
87+
font-size: 14px;
88+
}
89+
90+
.dropdown-header.open {
91+
border-color: #808080;
92+
}
93+
94+
.dropdown-list {
95+
position: absolute;
96+
top: 100%;
97+
left: 0;
98+
right: 0;
99+
background: #000000;
100+
border: 0.5px solid #434343;
101+
border-radius: 4px;
102+
margin-top: 4px;
103+
max-height: 200px;
104+
overflow-y: auto;
105+
z-index: 1000;
106+
padding: 8px;
107+
}
108+
109+
.dropdown-title {
110+
color: rgba(255, 255, 255, 0.5);
111+
font-size: 12px;
112+
font-weight: 500;
113+
padding: 8px 4px;
114+
cursor: default;
115+
}
116+
117+
.dropdown-item {
118+
padding: 8px 12px;
119+
cursor: pointer;
120+
color: #D8D8D8;
121+
font-size: 14px;
122+
height: 33px;
123+
display: flex;
124+
align-items: center;
125+
margin: 0 4px;
126+
}
127+
128+
.dropdown-item:hover {
129+
background: rgba(128, 128, 128, 0.2);
130+
}
131+
132+
.dropdown-item.selected {
133+
background: transparent;
134+
}
135+
136+
/* Scrollbar styling */
137+
.dropdown-list::-webkit-scrollbar {
138+
width: 8px;
139+
}
140+
141+
.dropdown-list::-webkit-scrollbar-track {
142+
background: #000000;
143+
}
144+
145+
.dropdown-list::-webkit-scrollbar-thumb {
146+
background: #434343;
147+
border-radius: 4px;
148+
}
149+
`}</style>
150+
</div>
151+
);
152+
};
153+
154+
export default CustomDropdown;

components/Globe.tsx

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,9 +94,16 @@ const Globe: React.FC = () => {
9494
1000
9595
);
9696

97+
// Ensure container is mounted and has dimensions
98+
if (!containerRef.current || containerRef.current.clientWidth === 0 || containerRef.current.clientHeight === 0) {
99+
console.warn('Container not ready for WebGLRenderer initialization');
100+
return;
101+
}
102+
97103
const newRenderer = new THREE.WebGLRenderer({
98104
antialias: true,
99-
alpha: true
105+
alpha: true,
106+
powerPreference: 'high-performance'
100107
});
101108

102109
// Set initial size

0 commit comments

Comments
 (0)