diff --git a/src/mission-control-client/src/components/MissionsTable/MissionsTable.tsx b/src/mission-control-client/src/components/MissionsTable/MissionsTable.tsx
new file mode 100644
index 0000000..4e2bb93
--- /dev/null
+++ b/src/mission-control-client/src/components/MissionsTable/MissionsTable.tsx
@@ -0,0 +1,192 @@
+import { Loader, Alert, Table, ActionIcon, Popover, Button, Text, Group, Paper, Select, Stack } from "@mantine/core";
+import { IconChevronDown, IconChevronRight } from "@tabler/icons-react";
+import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
+import { useState } from "react";
+import { listMissions, type Mission } from "../../api/missions";
+import { toReadableDateTime } from "../../utils/dateUtils";
+import { MissionLaunchStatusBadge } from "../MissionLaunchStatusBadge";
+import { MissionStatusBadge } from "../MissionStatusBadge";
+import { DateTimePicker } from "@mantine/dates";
+import { useForm } from "@mantine/form";
+import { notifications } from "@mantine/notifications";
+import { createMissionLaunch, type MissionLaunchStatus, MissionLaunchStatuses } from "../../api/missionLaunches";
+
+export function MissionsTable() {
+ const missionsQuery = useQuery({
+ queryKey: ['missions'],
+ queryFn: listMissions,
+ });
+
+ if (missionsQuery.isPending) {
+ return ;
+ }
+
+ if (missionsQuery.isError) {
+ return (
+
+ Is the API running?
+
+ );
+ }
+
+ return (
+
+
+
+
+ Name
+ Description
+ Status
+
+
+
+ {missionsQuery.data.map((mission) => (
+
+ ))}
+
+
+ );
+}
+
+function MissionsTableRow({ mission }: { mission: Mission }) {
+ const [expanded, setExpanded] = useState(false);
+
+ return (
+ <>
+
+
+ setExpanded((expanded) => !expanded)}>
+ {expanded ? : }
+
+
+ {mission.name}
+
+
+ {mission.description}
+
+
+
+
+
+
+ {expanded === true ? (
+ <>
+
+
+
+ Launches
+
+
+
+
+ Scheduled For
+ Status
+
+
+
+ {mission.missionLaunches.map((missionLaunch) => (
+
+ {toReadableDateTime(missionLaunch.scheduledFor)}
+
+
+
+
+ ))}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ >
+ ) : null}
+ >
+ );
+}
+
+function CreateMissionLaunchForm({ missionId }: { missionId: string }) {
+ const queryClient = useQueryClient();
+
+ const form = useForm({
+ mode: 'uncontrolled',
+ initialValues: { scheduledFor: '', status: '' },
+ validate: {
+ scheduledFor: (value) =>
+ value.length === 0 ? 'Scheduled For is required' : null,
+ status: (value) =>
+ value.trim().length === 0 ? 'Status is required' : null,
+ },
+ });
+
+ const createMissionLaunchMutation = useMutation({
+ mutationFn: createMissionLaunch,
+ onSuccess: () => {
+ notifications.show({
+ title: 'Mission launch created',
+ message: `Mission Launch created!`,
+ color: 'green',
+ });
+ form.reset();
+ return queryClient.invalidateQueries({ queryKey: ['missions'] });
+ },
+ onError: () =>
+ notifications.show({
+ title: 'Something went wrong',
+ message: 'The mission launch could not be created.',
+ color: 'red',
+ }),
+ });
+
+ return (
+
+
+
+ );
+}
diff --git a/src/mission-control-client/src/routes/missions.tsx b/src/mission-control-client/src/routes/missions.tsx
index 9c7325b..8e9b995 100644
--- a/src/mission-control-client/src/routes/missions.tsx
+++ b/src/mission-control-client/src/routes/missions.tsx
@@ -1,35 +1,18 @@
import {
- ActionIcon,
- Alert,
Button,
Group,
- Loader,
Paper,
- Popover,
- Select,
Stack,
- Table,
- Text,
Textarea,
TextInput,
Title,
} from '@mantine/core';
-import { DateTimePicker } from '@mantine/dates';
import { useForm } from '@mantine/form';
import { notifications } from '@mantine/notifications';
-import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
+import { useMutation, useQueryClient } from '@tanstack/react-query';
import { createFileRoute } from '@tanstack/react-router';
-import { useState } from 'react';
-import {
- createMissionLaunch,
- MissionLaunchStatuses,
- type MissionLaunchStatus,
-} from '../api/missionLaunches';
-import { createMission, listMissions, type Mission } from '../api/missions';
-import { MissionLaunchStatusBadge } from '../components/MissionLaunchStatusBadge';
-import { MissionStatusBadge } from '../components/MissionStatusBadge';
-import { IconChevronDown, IconChevronRight } from '@tabler/icons-react';
-import { toReadableDateTime } from '../utils/dateUtils';
+import { createMission } from '../api/missions';
+import { MissionsTable } from '../components/MissionsTable/MissionsTable';
export const Route = createFileRoute('/missions')({
component: MissionsPage,
@@ -108,184 +91,4 @@ function CreateMissionForm() {
);
-}
-
-function CreateMissionLaunchForm({ missionId }: { missionId: string }) {
- const queryClient = useQueryClient();
-
- const form = useForm({
- mode: 'uncontrolled',
- initialValues: { scheduledFor: '', status: '' },
- validate: {
- scheduledFor: (value) =>
- value.length === 0 ? 'Scheduled For is required' : null,
- status: (value) =>
- value.trim().length === 0 ? 'Status is required' : null,
- },
- });
-
- const createMissionLaunchMutation = useMutation({
- mutationFn: createMissionLaunch,
- onSuccess: () => {
- notifications.show({
- title: 'Mission launch created',
- message: `Mission Launch created!`,
- color: 'green',
- });
- form.reset();
- return queryClient.invalidateQueries({ queryKey: ['missions'] });
- },
- onError: () =>
- notifications.show({
- title: 'Something went wrong',
- message: 'The mission launch could not be created.',
- color: 'red',
- }),
- });
-
- return (
-
-
-
- );
-}
-
-function MissionsTable() {
- const missionsQuery = useQuery({
- queryKey: ['missions'],
- queryFn: listMissions,
- });
-
- if (missionsQuery.isPending) {
- return ;
- }
-
- if (missionsQuery.isError) {
- return (
-
- Is the API running?
-
- );
- }
-
- return (
-
-
-
-
- Name
- Description
- Status
-
-
-
- {missionsQuery.data.map((mission) => (
-
- ))}
-
-
- );
-}
-
-function MissionsTableRow({ mission }: { mission: Mission }) {
- const [expanded, setExpanded] = useState(false);
-
- return (
- <>
-
-
- setExpanded((expanded) => !expanded)}>
- {expanded ? : }
-
-
- {mission.name}
-
-
- {mission.description}
-
-
-
-
-
-
- {expanded === true ? (
- <>
-
-
-
- Launches
-
-
-
-
- Scheduled For
- Status
-
-
-
- {mission.missionLaunches.map((missionLaunch) => (
-
- {toReadableDateTime(missionLaunch.scheduledFor)}
-
-
-
-
- ))}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- >
- ) : null}
- >
- );
-}
+}
\ No newline at end of file