Skip to content

Commit 20c7bae

Browse files
committed
add phases ai
1 parent fd3e744 commit 20c7bae

File tree

3 files changed

+95
-2
lines changed

3 files changed

+95
-2
lines changed

server/db/logbook.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -922,13 +922,14 @@ export async function getActiveFlightData(flightId) {
922922

923923
return {
924924
...flight,
925-
925+
926926
current_altitude: activeData?.last_altitude || null,
927927
current_speed: activeData?.last_speed || null,
928928
current_heading: activeData?.last_heading || null,
929929
current_phase: activeData?.current_phase || null,
930930
last_update: activeData?.last_update || null,
931931
landing_detected: activeData?.landing_detected || false,
932+
stationary_notification_sent: activeData?.stationary_notification_sent || false,
932933

933934
duration_minutes: durationMinutes,
934935
max_altitude_ft: stats.max_altitude_ft || null,

server/services/flightTracker.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -568,7 +568,7 @@ class FlightTracker {
568568
} else {
569569
const stationaryDuration = (new Date() - new Date(activeFlight.stationary_since)) / 1000;
570570

571-
if (stationaryDuration >= 30 && !activeFlight.stationary_notification_sent) {
571+
if (stationaryDuration >= 60 && !activeFlight.stationary_notification_sent) {
572572
const userResult = await pool.query(`
573573
SELECT user_id FROM logbook_flights WHERE id = $1
574574
`, [activeFlight.flight_id]);

src/pages/FlightDetail.tsx

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ interface Flight {
7676
current_phase?: string | null;
7777
last_update?: string | null;
7878
landing_detected?: boolean;
79+
stationary_notification_sent?: boolean;
7980
telemetry_count?: number;
8081
}
8182

@@ -108,6 +109,10 @@ export default function FlightDetail() {
108109
const [debugData, setDebugData] = useState<{ type: string; data: unknown } | null>(null);
109110
const [debugLoading, setDebugLoading] = useState(false);
110111

112+
// Completion popup state
113+
const [showCompletionPopup, setShowCompletionPopup] = useState(false);
114+
const [completingFlight, setCompletingFlight] = useState(false);
115+
111116
const fetchFlightDetails = useCallback(async () => {
112117
try {
113118
const res = await fetch(
@@ -197,6 +202,13 @@ export default function FlightDetail() {
197202
return () => clearInterval(interval);
198203
}, [flight?.is_active, flight?.duration_minutes, lastFetchTime]);
199204

205+
// Show completion popup when flight is stationary
206+
useEffect(() => {
207+
if (flight?.stationary_notification_sent && !showCompletionPopup && !completingFlight) {
208+
setShowCompletionPopup(true);
209+
}
210+
}, [flight?.stationary_notification_sent, showCompletionPopup, completingFlight]);
211+
200212
const handleShare = async () => {
201213
setShareLoading(true);
202214
try {
@@ -226,6 +238,33 @@ export default function FlightDetail() {
226238
}
227239
};
228240

241+
const handleCompleteFlight = async () => {
242+
setCompletingFlight(true);
243+
try {
244+
const res = await fetch(
245+
`${import.meta.env.VITE_SERVER_URL}/api/logbook/flights/${flightId}/complete`,
246+
{
247+
method: 'POST',
248+
credentials: 'include'
249+
}
250+
);
251+
252+
if (res.ok) {
253+
setShowCompletionPopup(false);
254+
fetchFlightDetails();
255+
navigate('/logbook');
256+
} else {
257+
const data = await res.json();
258+
alert(data.error || 'Failed to complete flight');
259+
}
260+
} catch (err) {
261+
console.error('Failed to complete flight:', err);
262+
alert('Failed to complete flight');
263+
} finally {
264+
setCompletingFlight(false);
265+
}
266+
};
267+
229268
const formatDuration = (minutes: number | null, isLive: boolean = false) => {
230269
if (minutes === null || minutes === undefined) return 'N/A';
231270
if (minutes < 1 && !isLive) return 'N/A';
@@ -645,6 +684,59 @@ export default function FlightDetail() {
645684

646685
<div className="container mx-auto max-w-6xl px-4 py-8">
647686

687+
{/* Completion Popup Modal */}
688+
{showCompletionPopup && (
689+
<div className="fixed inset-0 bg-black/60 backdrop-blur-sm flex items-center justify-center z-50 px-4">
690+
<div className="bg-gradient-to-br from-gray-900 to-gray-800 border-2 border-green-600/50 rounded-2xl p-8 max-w-md w-full shadow-2xl shadow-green-500/20">
691+
<div className="flex items-center gap-4 mb-6">
692+
<div className="p-3 bg-green-500/20 rounded-xl">
693+
<Check className="h-8 w-8 text-green-400" />
694+
</div>
695+
<div>
696+
<h2 className="text-2xl font-bold text-white">Flight Ready to Complete</h2>
697+
<p className="text-gray-400 text-sm mt-1">You've arrived at the gate</p>
698+
</div>
699+
</div>
700+
701+
<p className="text-gray-300 mb-6">
702+
Your flight <span className="font-bold text-blue-300">{flight?.callsign}</span> has been stationary for over 1 minute.
703+
Would you like to complete your flight now?
704+
</p>
705+
706+
<div className="flex gap-3">
707+
<button
708+
onClick={() => setShowCompletionPopup(false)}
709+
disabled={completingFlight}
710+
className="flex-1 px-4 py-3 bg-gray-700 hover:bg-gray-600 text-white rounded-lg font-semibold transition-colors disabled:opacity-50 disabled:cursor-not-allowed"
711+
>
712+
Not Yet
713+
</button>
714+
<button
715+
onClick={handleCompleteFlight}
716+
disabled={completingFlight}
717+
className="flex-1 px-4 py-3 bg-green-600 hover:bg-green-500 text-white rounded-lg font-semibold transition-colors disabled:opacity-50 disabled:cursor-not-allowed flex items-center justify-center gap-2"
718+
>
719+
{completingFlight ? (
720+
<>
721+
<RefreshCw className="h-4 w-4 animate-spin" />
722+
Completing...
723+
</>
724+
) : (
725+
<>
726+
<Check className="h-4 w-4" />
727+
Complete Flight
728+
</>
729+
)}
730+
</button>
731+
</div>
732+
733+
<p className="text-xs text-gray-500 mt-4 text-center">
734+
Your flight will automatically complete if you leave the game
735+
</p>
736+
</div>
737+
</div>
738+
)}
739+
648740
{/* Real-Time Status - Only for active flights */}
649741
{isActive && (
650742
<div className="bg-gradient-to-br from-green-900/20 via-blue-900/20 to-purple-900/20 backdrop-blur-sm rounded-xl border-2 border-green-700/40 p-6 mb-6 shadow-lg shadow-green-500/5">

0 commit comments

Comments
 (0)