@@ -6,16 +6,18 @@ import { useAppContext } from '../context/AppContext';
66import ProfileModal from './ProfileModal' ;
77import { getCompatibility } from '../utils/compatibility' ;
88import { useRocketNav } from '../context/TransitionContext' ;
9+ import ScientificWarningModal from './ScientificWarningModal' ;
10+ import { getScientificWarnings } from '../utils/scienceWarnings' ;
911
1012export default function OrbitSystem ( ) {
1113
1214 const { preferences, addMatch, matches } = useAppContext ( ) ;
1315 const triggerRocketNav = useRocketNav ( ) ;
1416 const [ selectedAlien , setSelectedAlien ] = useState < AlienProfile | null > ( null ) ;
1517 const [ dismissedIds , setDismissedIds ] = useState < Set < string > > ( new Set ( ) ) ;
16-
1718 const [ animStage , setAnimStage ] = useState < 'none' | 'heart' | 'break' | 'final' > ( 'none' ) ;
18-
19+ const [ pendingMatchAlien , setPendingMatchAlien ] = useState < AlienProfile | null > ( null ) ;
20+
1921 // Keep exactly 5 slots for the 5 orbit tracks
2022 const [ activeIds , setActiveIds ] = useState < ( string | null ) [ ] > ( [ null , null , null , null , null ] ) ;
2123
@@ -71,8 +73,22 @@ export default function OrbitSystem() {
7173 if ( ! preferences ) return null ;
7274
7375 const handleMatch = ( alien : AlienProfile ) => {
76+ const warnings = getScientificWarnings ( alien ) ;
77+ if ( warnings . length > 0 ) {
78+ // Hazards detected — close modal and show warning first
79+ setSelectedAlien ( null ) ;
80+ setPendingMatchAlien ( alien ) ;
81+ } else {
82+ // No hazards — proceed directly
83+ addMatch ( alien ) ;
84+ setSelectedAlien ( null ) ;
85+ triggerRocketNav ( `/chat/${ alien . id } ` , { alienImg : alien . profilePic } ) ;
86+ }
87+ } ;
88+
89+ const confirmMatch = ( alien : AlienProfile ) => {
7490 addMatch ( alien ) ;
75- setSelectedAlien ( null ) ;
91+ setPendingMatchAlien ( null ) ;
7692 triggerRocketNav ( `/chat/${ alien . id } ` , { alienImg : alien . profilePic } ) ;
7793 } ;
7894
@@ -108,10 +124,26 @@ export default function OrbitSystem() {
108124 return (
109125 < >
110126 < style > { `
111- @keyframes orbit {
127+ @keyframes orbit-0 {
112128 from { offset-distance: 0%; }
113129 to { offset-distance: 100%; }
114130 }
131+ @keyframes orbit-1 {
132+ from { offset-distance: 20%; }
133+ to { offset-distance: 120%; }
134+ }
135+ @keyframes orbit-2 {
136+ from { offset-distance: 40%; }
137+ to { offset-distance: 140%; }
138+ }
139+ @keyframes orbit-3 {
140+ from { offset-distance: 60%; }
141+ to { offset-distance: 160%; }
142+ }
143+ @keyframes orbit-4 {
144+ from { offset-distance: 80%; }
145+ to { offset-distance: 180%; }
146+ }
115147 .orbit-ring {
116148 position: absolute;
117149 top: 50%;
@@ -131,7 +163,9 @@ export default function OrbitSystem() {
131163 cursor: pointer;
132164 offset-path: ellipse(var(--rx) var(--ry) at 50% 50%);
133165 offset-rotate: 0deg;
134- animation: orbit var(--duration) linear infinite;
166+ animation-duration: var(--duration);
167+ animation-timing-function: linear;
168+ animation-iteration-count: infinite;
135169 }
136170 .orbit-avatar {
137171 width: 100%;
@@ -173,26 +207,27 @@ export default function OrbitSystem() {
173207 < div style = { { position : 'relative' , width : '100%' , flex : 1 , display : 'flex' , alignItems : 'center' , justifyContent : 'center' , overflow : 'hidden' } } >
174208
175209 { /* User Center */ }
176- { ! activeIds . every ( id => id === null ) && (
177- < div style = { {
178- width : '12vmin' ,
179- height : '12vmin' ,
180- minWidth : '60px' ,
181- minHeight : '60px' ,
182- borderRadius : '50%' ,
183- background : 'linear-gradient(135deg, var(--color-primary), var(--color-secondary))' ,
184- boxShadow : '0 0 30px var(--color-secondary)' ,
185- display : 'flex' ,
186- alignItems : 'center' ,
187- justifyContent : 'center' ,
188- fontWeight : 'bold' ,
189- zIndex : 10 ,
190- fontSize : 'clamp(1rem, 2.5vmin, 1.5rem)' ,
191- color : 'white'
192- } } >
193- { preferences . name . substring ( 0 , 2 ) . toUpperCase ( ) || 'YOU' }
194- </ div >
195- ) }
210+ < div style = { {
211+ width : '12vmin' ,
212+ height : '12vmin' ,
213+ minWidth : '60px' ,
214+ minHeight : '60px' ,
215+ borderRadius : '50%' ,
216+ background : preferences . profilePic
217+ ? `url(${ preferences . profilePic } ) center/cover`
218+ : 'linear-gradient(135deg, var(--color-primary), var(--color-secondary))' ,
219+ boxShadow : '0 0 30px var(--color-secondary)' ,
220+ display : 'flex' ,
221+ alignItems : 'center' ,
222+ justifyContent : 'center' ,
223+ fontWeight : 'bold' ,
224+ zIndex : 10 ,
225+ fontSize : 'clamp(1rem, 2.5vmin, 1.5rem)' ,
226+ color : 'white' ,
227+ border : '2px solid var(--color-secondary)' ,
228+ } } >
229+ { ! preferences . profilePic && ( preferences . name . substring ( 0 , 2 ) . toUpperCase ( ) || 'YOU' ) }
230+ </ div >
196231
197232 { /* Orbit Rings and Aliens */ }
198233 { activeIds
@@ -224,7 +259,7 @@ export default function OrbitSystem() {
224259 '--rx' : `${ rx } px` ,
225260 '--ry' : `${ ry } px` ,
226261 '--duration' : `${ duration } s` ,
227- animationDelay : `${ delay } s `
262+ animationName : `orbit- ${ i } `
228263 } }
229264 title = { `${ alien . name } (${ alien . distanceLY } Light years)` }
230265 >
@@ -314,6 +349,14 @@ export default function OrbitSystem() {
314349 />
315350 ) }
316351
352+ { pendingMatchAlien && (
353+ < ScientificWarningModal
354+ alien = { pendingMatchAlien }
355+ onProceed = { ( ) => confirmMatch ( pendingMatchAlien ) }
356+ onCancel = { ( ) => setPendingMatchAlien ( null ) }
357+ />
358+ ) }
359+
317360 </ >
318361 ) ;
319362}
0 commit comments