Skip to content

Commit efb10bf

Browse files
committed
swiping on profiles
1 parent d153f1c commit efb10bf

2 files changed

Lines changed: 93 additions & 38 deletions

File tree

src/components/OrbitSystem.tsx

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,26 @@ export default function OrbitSystem() {
6464
newSet.add(alien.id);
6565
return newSet;
6666
});
67-
setSelectedAlien(null);
67+
68+
// Find the next available alien in activeIds
69+
const currentIndex = activeIds.indexOf(alien.id);
70+
let nextId = null;
71+
if (currentIndex >= 0) {
72+
for(let i=1; i<5; i++) {
73+
const candidate = activeIds[(currentIndex + i) % 5];
74+
if (candidate && candidate !== alien.id) {
75+
nextId = candidate;
76+
break;
77+
}
78+
}
79+
}
80+
81+
if (nextId) {
82+
const nextAlien = mockAliens.find(a => a.id === nextId);
83+
setSelectedAlien(nextAlien || null);
84+
} else {
85+
setSelectedAlien(null);
86+
}
6887
};
6988

7089
const visibleAliens = mockAliens.filter(a => activeIds.includes(a.id));

src/components/ProfileModal.tsx

Lines changed: 73 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { useState, useEffect } from 'react';
12
import type { AlienProfile } from '../data/mockAliens';
23
import { X, Heart, Info, Globe, Wind } from 'lucide-react';
34

@@ -9,8 +10,38 @@ interface ProfileModalProps {
910
}
1011

1112
export default function ProfileModal({ alien, onClose, onMatch, onDismiss }: ProfileModalProps) {
13+
const [swipeDirection, setSwipeDirection] = useState<'left' | 'right' | null>(null);
14+
15+
useEffect(() => {
16+
setSwipeDirection(null);
17+
}, [alien.id]);
18+
19+
const handleMatch = () => {
20+
setSwipeDirection('right');
21+
setTimeout(() => onMatch(alien), 300);
22+
};
23+
24+
const handleDismiss = () => {
25+
setSwipeDirection('left');
26+
setTimeout(() => onDismiss(alien), 300);
27+
};
28+
1229
return (
13-
<div style={{
30+
<>
31+
<style>{`
32+
.swipe-card {
33+
transition: transform 0.3s ease-out, opacity 0.3s ease-out;
34+
}
35+
.swipe-card.left {
36+
transform: translateX(-150%) rotate(-15deg);
37+
opacity: 0;
38+
}
39+
.swipe-card.right {
40+
transform: translateX(150%) rotate(15deg);
41+
opacity: 0;
42+
}
43+
`}</style>
44+
<div style={{
1445
position: 'fixed',
1546
top: 0, left: 0, right: 0, bottom: 0,
1647
backgroundColor: 'rgba(15, 23, 42, 0.8)',
@@ -21,13 +52,30 @@ export default function ProfileModal({ alien, onClose, onMatch, onDismiss }: Pro
2152
zIndex: 1000,
2253
padding: '20px'
2354
}}>
24-
<div className="glass-panel" style={{
25-
maxWidth: '500px',
26-
width: '100%',
27-
maxHeight: '90vh',
28-
overflowY: 'auto',
29-
position: 'relative'
30-
}}>
55+
<div style={{ display: 'flex', alignItems: 'center', gap: '24px', width: '100%', maxWidth: '700px', justifyContent: 'center' }}>
56+
57+
{/* Reject Button */}
58+
<button
59+
onClick={handleDismiss}
60+
style={{
61+
width: '60px', height: '60px', borderRadius: '50%',
62+
background: 'rgba(46, 41, 78, 0.8)', border: '2px solid var(--color-white)',
63+
color: 'var(--color-white)', display: 'flex', alignItems: 'center', justifyContent: 'center',
64+
cursor: 'pointer', transition: 'all 0.2s ease', flexShrink: 0
65+
}}
66+
onMouseOver={e => e.currentTarget.style.transform = 'scale(1.1)'}
67+
onMouseOut={e => e.currentTarget.style.transform = 'scale(1)'}
68+
>
69+
<X size={28} />
70+
</button>
71+
72+
<div className={`glass-panel swipe-card ${swipeDirection || ''}`} style={{
73+
maxWidth: '500px',
74+
width: '100%',
75+
maxHeight: '90vh',
76+
overflowY: 'auto',
77+
position: 'relative'
78+
}}>
3179
<button
3280
onClick={onClose}
3381
style={{
@@ -118,38 +166,26 @@ export default function ProfileModal({ alien, onClose, onMatch, onDismiss }: Pro
118166
</div>
119167
</div>
120168

121-
<div style={{ display: 'flex', justifyContent: 'space-around', marginTop: '24px' }}>
122-
<button
123-
onClick={() => onDismiss(alien)}
124-
style={{
125-
width: '60px', height: '60px', borderRadius: '50%',
126-
background: 'rgba(46, 41, 78, 0.8)', border: '2px solid var(--color-white)',
127-
color: 'var(--color-white)', display: 'flex', alignItems: 'center', justifyContent: 'center',
128-
cursor: 'pointer', transition: 'all 0.2s ease'
129-
}}
130-
onMouseOver={e => e.currentTarget.style.transform = 'scale(1.1)'}
131-
onMouseOut={e => e.currentTarget.style.transform = 'scale(1)'}
132-
>
133-
<X size={28} />
134-
</button>
135-
136-
<button
137-
onClick={() => onMatch(alien)}
138-
style={{
139-
width: '60px', height: '60px', borderRadius: '50%',
140-
background: 'linear-gradient(135deg, var(--color-primary), var(--color-secondary))', border: 'none',
141-
color: 'white', display: 'flex', alignItems: 'center', justifyContent: 'center',
142-
boxShadow: '0 4px 15px rgba(217, 3, 104, 0.5)',
143-
cursor: 'pointer', transition: 'all 0.2s ease'
144-
}}
145-
onMouseOver={e => e.currentTarget.style.transform = 'scale(1.1)'}
146-
onMouseOut={e => e.currentTarget.style.transform = 'scale(1)'}
147-
>
148-
<Heart size={28} fill="white" />
149-
</button>
150169
</div>
151170
</div>
171+
172+
{/* Match Button */}
173+
<button
174+
onClick={handleMatch}
175+
style={{
176+
width: '60px', height: '60px', borderRadius: '50%',
177+
background: 'linear-gradient(135deg, var(--color-primary), var(--color-secondary))', border: 'none',
178+
color: 'white', display: 'flex', alignItems: 'center', justifyContent: 'center',
179+
boxShadow: '0 4px 15px rgba(217, 3, 104, 0.5)',
180+
cursor: 'pointer', transition: 'all 0.2s ease', flexShrink: 0
181+
}}
182+
onMouseOver={e => e.currentTarget.style.transform = 'scale(1.1)'}
183+
onMouseOut={e => e.currentTarget.style.transform = 'scale(1)'}
184+
>
185+
<Heart size={28} fill="white" />
186+
</button>
152187
</div>
153188
</div>
189+
</>
154190
);
155191
}

0 commit comments

Comments
 (0)