Skip to content
Closed
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
11 changes: 10 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,13 @@ icons/sprite.svg
# Bun server
/binaries/

.wrangler
.wrangler

.devcontainer/
.claude/
*.code-workspace

CLAUDE.md
server.log
package-lock.json

2 changes: 2 additions & 0 deletions app/components/Station/StationLayout.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { q, clientId } from "@thorium/context/AppContext";
import { SVGImageLoader } from "@thorium/ui/SVGImageLoader";
import { FlightPauseIndicator } from "@thorium/ui/FlightPauseIndicator";
import { useThoriumAccount } from "@thorium/context/ThoriumAccountContext";
import { CardArea } from "./CardArea";
import { CardSwitcher } from "./CardSwitcher";
Expand Down Expand Up @@ -97,6 +98,7 @@ const StationLayout = () => {
<div className="widgets flex items-center gap-2 absolute bottom-8 right-[calc(2rem+50px)]">
<Widgets />
</div>
<FlightPauseIndicator />
</div>
</div>
);
Expand Down
63 changes: 63 additions & 0 deletions app/components/ui/FlightPauseIndicator.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { Icon } from "@thorium/ui/Icon";
import { useFlightStatus } from "@thorium/hooks/useFlightStatus";

/**
* Flight pause indicator component that displays when a flight is paused.
*
* @description
* Shows a prominent warning banner at the top of the screen when the
* current flight is paused. The indicator automatically appears and
* disappears based on the flight's pause state.
*
* Features:
* - Appears only when flight is paused
* - Fixed position overlay that doesn't interfere with card functionality
* - Warning styling with icon and text for clear visibility
* - Responsive design that works across different screen sizes
*
* @component
* @example
* ```tsx
* <FlightPauseIndicator />
* ```
*
* @see {@link useFlightStatus} - Hook for flight state data
* @since 1.0.0
*/
export function FlightPauseIndicator() {
const { isPaused } = useFlightStatus();

// Only render when flight is paused
if (!isPaused) {
return null;
}

return (
<>
{/* Black background overlay to prevent interaction */}
<div
className="fixed inset-0 bg-black bg-opacity-75 z-40"
aria-hidden="true"
/>

{/* Large pause indicator */}
<div
className="fixed inset-0 flex items-center justify-center z-50"
role="alert"
aria-live="polite"
>
<div className="panel panel-warning px-12 py-8 flex flex-col items-center gap-6 shadow-2xl max-w-md mx-4">
<Icon name="ban" size="2xl" aria-hidden="true" className="text-warning" />
<span className="font-bold text-4xl select-none text-center">
FLIGHT PAUSED
</span>
<span className="text-lg text-center opacity-80 select-none">
Please wait for the flight director to resume the simulation
</span>
</div>
</div>
</>
);
}

export default FlightPauseIndicator;
21 changes: 14 additions & 7 deletions app/components/ui/icons/sprite.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
103 changes: 103 additions & 0 deletions app/hooks/useFlightStatus.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import { q } from "@thorium/context/AppContext";

/**
* Custom hook for accessing flight status information.
*
* @description
* Provides a convenient interface for accessing flight state including
* whether a flight is active, paused, and basic flight information.
*
* @returns {FlightStatusReturn} Flight status data and helper flags
*
* @example
* ```typescript
* const { isActive, isPaused, flightName } = useFlightStatus();
*
* if (isPaused) {
* console.log("Flight is paused");
* }
* ```
*
* @see {@link q.flight.active} - Server procedure for flight data
* @since 1.0.0
*/
export function useFlightStatus() {
const [flight] = q.flight.active.useNetRequest();

return {
/**
* Whether a flight is currently active (loaded).
*/
isActive: !!flight,

/**
* Whether the active flight is currently paused.
* Returns false if no flight is active.
*/
isPaused: flight?.paused || false,

/**
* Name of the current flight.
* Returns null if no flight is active.
*/
flightName: flight?.name || null,

/**
* Date the flight was created.
* Returns null if no flight is active.
*/
flightDate: flight?.date || null,

/**
* Whether the flight has a flight director assigned.
* Returns false if no flight is active.
*/
hasFlightDirector: flight?.hasFlightDirector || false,

/**
* Raw flight data from the server.
* Returns null if no flight is active.
*/
flight: flight || null
};
}

/**
* Return type for the useFlightStatus hook.
*/
export interface FlightStatusReturn {
/**
* Whether a flight is currently active (loaded).
*/
isActive: boolean;

/**
* Whether the active flight is currently paused.
*/
isPaused: boolean;

/**
* Name of the current flight.
*/
flightName: string | null;

/**
* Date the flight was created.
*/
flightDate: Date | null;

/**
* Whether the flight has a flight director assigned.
*/
hasFlightDirector: boolean;

/**
* Raw flight data from the server.
*/
flight: {
name: string;
date: Date;
paused: boolean;
hasFlightDirector: boolean;
} | null;
}
Loading