Skip to content
Open
Show file tree
Hide file tree
Changes from 3 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
Binary file added .DS_Store
Binary file not shown.
4 changes: 4 additions & 0 deletions gs/backend/api/backend_setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
from gs.backend.api.v1.mcc.endpoints.aro_requests import aro_requests_router
from gs.backend.api.v1.mcc.endpoints.commands import commands_router
from gs.backend.api.v1.mcc.endpoints.main_commands import main_commands_router
from gs.backend.api.v1.mcc.endpoints.mcc_logs import logs_router
from gs.backend.api.v1.mcc.endpoints.mission_commands import mission_commands_router
from gs.backend.api.v1.mcc.endpoints.telemetry import telemetry_router


Expand All @@ -26,6 +28,8 @@ def setup_routes(app: FastAPI) -> None:
app.include_router(telemetry_router, prefix=f"{mcc_prefix}/telemetry")
app.include_router(aro_requests_router, prefix=f"{mcc_prefix}/requests")
app.include_router(main_commands_router, prefix=f"{mcc_prefix}/main-commands")
app.include_router(mission_commands_router, prefix=f"{mcc_prefix}/mission-commands")
app.include_router(logs_router, prefix=f"{mcc_prefix}/logs")


def setup_middlewares(app: FastAPI) -> None:
Expand Down
5 changes: 4 additions & 1 deletion gs/backend/api/middleware/cors_middleware.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@ def add_cors_middleware(app: FastAPI) -> None:
"""
app.add_middleware(
CORSMiddleware,
allow_origins=["http://localhost:5173"],
allow_origins=[
"http://localhost:5173",
"http://localhost:5174",
],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
Expand Down
36 changes: 36 additions & 0 deletions gs/backend/api/v1/mcc/endpoints/aro_requests.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,39 @@
from fastapi import APIRouter
from pydantic import BaseModel

aro_requests_router = APIRouter(tags=["MCC", "ARO Requests"])


class AROItem(BaseModel):
"""
Represents an ARO request item with location and status.

Attributes:
id (int): Unique identifier of the ARO request.
latitude (float): Latitude of the request location.
longitude (float): Longitude of the request location.
status (str): Status of the request.
"""

id: int
latitude: float
longitude: float
status: str


hardcoded_aro_requests = [
{"id": 1, "latitude": 43.468, "longitude": -80.540, "status": "pending"},
{"id": 2, "latitude": 43.471, "longitude": -80.544, "status": "complete"},
{"id": 3, "latitude": 43.473, "longitude": -80.539, "status": "in-progress"},
]


@aro_requests_router.get("/", response_model=list[AROItem])
async def get_aro_requests() -> list[AROItem]:
"""
Retrieve the hardcoded ARO requests for MCC frontend testing.

Returns:
List[AROItem]: A list of all hardcoded ARO requests.
"""
return hardcoded_aro_requests
36 changes: 36 additions & 0 deletions gs/backend/api/v1/mcc/endpoints/mcc_logs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
from datetime import datetime

from fastapi import APIRouter
from pydantic import BaseModel

logs_router = APIRouter(tags=["Logs"])


class LogItem(BaseModel):
"""
Represents a log item with date and message.

Attributes:
date (datetime): Time that the messaged was logged.
log (str): Information that was logged
"""

date: datetime
log: str


# Example hardcoded logs
hardcoded_logs = [
{"date": "2025-09-28 10:05:00", "log": "ARO request received."},
{"date": "2025-09-28 10:10:00", "log": "Mission Command request received"},
]


@logs_router.get("/", response_model=list[LogItem])
async def get_recent_logs() -> list[LogItem]:
"""
Gets the hardcoded test logs for MCC frontend testing

:return: list of logs
"""
return hardcoded_logs
36 changes: 36 additions & 0 deletions gs/backend/api/v1/mcc/endpoints/mission_commands.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
from fastapi import APIRouter
from pydantic import BaseModel

mission_commands_router = APIRouter(tags=["Mission Control"])


class MissionCommandRequest(BaseModel):
"""
Represents a body for a mission command request

Attributes:
command (str): Title of the command request.
"""

command: str


class MissionCommandResponse(BaseModel):
"""
Represents a body for a mission command response

Attributes:
response (str): Response message.
"""

response: str


@mission_commands_router.post("/", response_model=MissionCommandResponse)
async def execute_mission_command(cmd: MissionCommandRequest) -> MissionCommandResponse:
"""
Gets the hardcoded mission command response for MCC frontend testing

:return: mission command respone
"""
return MissionCommandResponse(response=f"Executed command: {cmd.command}")
3 changes: 2 additions & 1 deletion gs/backend/config/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@

load_dotenv()


print(environ.get("GS_DATABASE_LOCATION"))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you should remove these print statements since they seem to be for debugging

print(environ.get("GS_DATABASE_PORT"))
# TODO: Make these throw an exception if they are None
GS_DATABASE_USER = environ.get("GS_DATABASE_USER")
GS_DATABASE_PASSWORD = environ.get("GS_DATABASE_PASSWORD")
Expand Down
27 changes: 27 additions & 0 deletions gs/frontend/mcc/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions gs/frontend/mcc/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
},
"dependencies": {
"@tailwindcss/vite": "^4.1.13",
"@tanstack/react-query": "^5.90.2",
"bootstrap": "^5.3.8",
"react": "^19.1.1",
"react-bootstrap": "^2.10.10",
Expand Down
28 changes: 13 additions & 15 deletions gs/frontend/mcc/src/aro-requests/aro-requests.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import Table from "react-bootstrap/Table";
import { useEffect, useState } from "react";
import { useQuery } from '@tanstack/react-query';

type AROItemProps = {
id: number;
latitude: number;
longitude: number;
status: string;
};

function AROItem({ id, latitude, longitude, status }: AROItemProps) {
return (
<>
Expand All @@ -21,17 +22,14 @@ function AROItem({ id, latitude, longitude, status }: AROItemProps) {
}

function ARORequests() {
const [loading, setLoading] = useState(true);
const [aroRequests, setARORequests] = useState<AROItemProps[]>([]);

useEffect(() => {
fetch("http://localhost:5000/aro-request")
.then((response) => response.json())
.then((data) => {
setARORequests(data);
setLoading(false);
});
}, []);
const { data, isLoading} = useQuery<AROItemProps[]>({
queryKey: ["aro-requests"],
queryFn: async () => {
const response = await fetch("http://localhost:8000/api/v1/mcc/requests/");
if(!response.ok) throw new Error("Network response was not ok");
return response.json();
},
});

return (
<div className="arorequests layout">
Expand All @@ -45,14 +43,14 @@ function ARORequests() {
</tr>
</thead>
<tbody>
{loading
{isLoading || !data
? (
<tr>
<td colSpan={4}>Loading...</td>
</tr>
)
: (
aroRequests.map((item) => {
:(
data.map((item) => {
return (
<AROItem
key={item.id}
Expand Down
49 changes: 20 additions & 29 deletions gs/frontend/mcc/src/common/logs.tsx
Original file line number Diff line number Diff line change
@@ -1,40 +1,27 @@
import Table from "react-bootstrap/Table";
import { useEffect, useState } from "react";

function LogItem() {
const [date, setDate] = useState(Date.now());
const [log, setLog] = useState("");
const [loading, setLoading] = useState(true);

const fetchLogData = async () => {
const response = await fetch(`http://localhost:5000/recent-logs/`);
const data = await response.json();
setDate(data.date);
setLog(data.log);
setLoading(false);
};

useEffect(() => {
fetchLogData();
const interval = setInterval(fetchLogData, 10000);
return () => clearInterval(interval);
}, []);
import { useQuery } from '@tanstack/react-query';

function LogItem({ log }: { log: any }) {
return (
<tr>
{loading ? <td>Loading...</td> : (
<>
<td>{date}</td>
<td>{log}</td>
{" "}
</>
)}
<td>{log.date}</td>
<td>{log.log}</td>
</tr>
);
}

function Logs() {
const count = 5;
const { data, isLoading} = useQuery({
queryKey: ["logData"],
queryFn: async () => {
const response = await fetch("http://localhost:8000/api/v1/mcc/logs/");
if (!response.ok) {
throw new Error("Network response was not ok");
}
return response.json();
},
});

return (
<div className="logs layout">
<Table responsive="sm">
Expand All @@ -45,7 +32,11 @@ function Logs() {
</tr>
</thead>
<tbody>
{[...Array(count).keys()].map((key) => <LogItem key={key} />)}
{isLoading ? (
<tr><td colSpan={2}>Loading...</td></tr>
) : (
data?.map((log: any, idx: number) => <LogItem key={idx} log={log} />)
)}
</tbody>
</Table>
</div>
Expand Down
5 changes: 5 additions & 0 deletions gs/frontend/mcc/src/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,14 @@ import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App.tsx";
import "./index.css";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";

const queryClient = new QueryClient();

ReactDOM.createRoot(document.getElementById("root")!).render(
<React.StrictMode>
<QueryClientProvider client={queryClient}>
<App />
</QueryClientProvider>
</React.StrictMode>
);
Loading
Loading