Skip to content
Merged
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
10 changes: 8 additions & 2 deletions src/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
'use client';

import Layout from '@/components/Layout';
import { direction } from 'html2canvas/dist/types/css/property-descriptors/direction';

const names = ["Default", "Arm Operation", "Debug", "Auxiliary", "Science"];
const colors = ['#0070f3', '#28a745', '#dc3545', '#ffc107', '#17a2b8'];
Expand Down Expand Up @@ -83,7 +84,12 @@ const layouts = [
second: {
direction: 'row',
first: 'webRTCClient:4',
second: 'nodeStatusPanel:5',
second: {
direction: 'column',
first: 'nodeStatusPanel:5',
second: 'rosMonitor:6',
splitPercentage: 70
},
splitPercentage: 70,
},
splitPercentage: 30,
Expand Down Expand Up @@ -219,4 +225,4 @@ const HomePage = () => {
);
};

export default HomePage;
export default HomePage;
2 changes: 2 additions & 0 deletions src/components/panels/MotorStatusPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ const MotorStatusPanel: React.FC = () => {
<div className="motor-panel">
<button
className="reset-button"
style={{ fontWeight: "600", border: "1px solid red", margin: "5px" }}
disabled={!ros}
onClick={handleResetAll}
>
Expand Down Expand Up @@ -263,6 +264,7 @@ const MotorStatusPanel: React.FC = () => {

.motor-table td {
border-bottom: 1px solid #333;
padding: 0px 3px;
}

.motor-table tbody tr:hover {
Expand Down
2 changes: 1 addition & 1 deletion src/components/panels/PDBRails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ const PDBRailsPanel: React.FC = () => {
</thead>
<tbody>
{LABELS.map((r, idx) => (
<tr className={failBorder(idx)}>
<tr className={failBorder(idx)} key={idx}>
<td>
{r}
</td>
Expand Down
6 changes: 6 additions & 0 deletions src/components/panels/SystemTelemetryPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ interface TelemetryData {
cpu_usage: number;
mem_usage: number;
gpu_usage: number;
core_temp: number;
case_temp: number;
}

const SystemTelemetryPanel: React.FC = () => {
Expand All @@ -39,6 +41,8 @@ const SystemTelemetryPanel: React.FC = () => {
cpu_usage: msg.cpu_usage,
mem_usage: msg.mem_usage,
gpu_usage: msg.gpu_usage,
core_temp: msg.core_temp,
case_temp: msg.case_temp,
};

// circular buffer, size 30
Expand Down Expand Up @@ -72,6 +76,8 @@ const SystemTelemetryPanel: React.FC = () => {
<Line type="monotone" dataKey="cpu_usage" stroke="#0070f3" name="CPU" dot={false} />
<Line type="monotone" dataKey="mem_usage" stroke="#28a745" name="Memory" dot={false} />
<Line type="monotone" dataKey="gpu_usage" stroke="#ff8800" name="GPU" dot={false} />
<Line type="monotone" dataKey="core_temp" stroke="#dc3545" name="Core Temp (C)" dot={false} />
<Line type="monotone" dataKey="case_temp" stroke="#17a2b8" name="Case Temp (C)" dot={false} />
</LineChart>
</ResponsiveContainer>
</div>
Expand Down
183 changes: 100 additions & 83 deletions src/components/panels/WaypointList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import React, { useState } from 'react';
import { useWaypoints, Waypoint } from '@/contexts/WaypointContext';

const WaypointList: React.FC = () => {
const { waypoints, removeWaypoint, updateWaypoint } = useWaypoints();
const { waypoints, removeWaypoint, clearWaypoints, updateWaypoint } = useWaypoints();
const [editingIndex, setEditingIndex] = useState<number | null>(null);
const [editedWaypoint, setEditedWaypoint] = useState<Waypoint | null>(null);

Expand Down Expand Up @@ -39,91 +39,108 @@ const WaypointList: React.FC = () => {
{waypoints.length === 0 ? (
<p>No waypoints added. Click on the map to add one👿</p>
) : (
< ul style={{ listStyle: 'none', padding: 0 }}>
{/*Ty chat gpt for styling this*/}
{waypoints.map((wp, index) => (
<li
key={index}
style={{
marginBottom: '0.5rem',
padding: '0.5rem',
border: '1px solid #444',
borderRadius: '4px',
}}
>
{editingIndex === index && editedWaypoint ? (
<div style={{ display: 'flex', flexDirection: 'column', gap: '0.5rem' }}>
<div>
<label style={{ marginRight: '0.5rem' }}>Name:</label>
<input
type="text"
value={editedWaypoint.name}
onChange={(e) => setEditedWaypoint({ ...editedWaypoint, name: e.target.value })}
style={{ padding: '0.25rem' }}
/>
<div>
<button
style={{
padding: "4px 8px",
marginBottom: "5px",
width: "100%",
fontWeight: "600",
border: "1px solid red",
borderRadius: "4px",
background: "#3b3b3b",
color: "f1f1f1"
}}
onClick={clearWaypoints}
>
Clear Waypoints
</button>
<ul style={{ listStyle: 'none', padding: 0 }}>
{/*Ty chat gpt for styling this*/}
{waypoints.map((wp, index) => (
<li
key={index}
style={{
marginBottom: '0.5rem',
padding: '0.5rem',
border: '1px solid #444',
borderRadius: '4px',
}}
>
{editingIndex === index && editedWaypoint ? (
<div style={{ display: 'flex', flexDirection: 'column', gap: '0.5rem' }}>
<div>
<label style={{ marginRight: '0.5rem' }}>Name:</label>
<input
type="text"
value={editedWaypoint.name}
onChange={(e) => setEditedWaypoint({ ...editedWaypoint, name: e.target.value })}
style={{ padding: '0.25rem' }}
/>
</div>
<div>
<label style={{ marginRight: '0.5rem' }}>Number:</label>
<input
type="number"
value={editedWaypoint.order}
onChange={(e) => setEditedWaypoint({ ...editedWaypoint, order: Number(e.target.value) })}
style={{ padding: '0.25rem', width: '60px' }}
/>
</div>
<div>
<label style={{ marginRight: '0.5rem' }}>Color:</label>
<input
type="color"
value={editedWaypoint.color}
onChange={(e) => setEditedWaypoint({ ...editedWaypoint, color: e.target.value })}
style={{ padding: '0.25rem' }}
/>
</div>
<div style={{ marginTop: '0.5rem' }}>
<button onClick={() => saveEditing(index)} style={{ marginRight: '0.5rem' }}>
Save
</button>
<button onClick={cancelEditing}>Cancel</button>
</div>
</div>
<div>
<label style={{ marginRight: '0.5rem' }}>Number:</label>
<input
type="number"
value={editedWaypoint.order}
onChange={(e) => setEditedWaypoint({ ...editedWaypoint, order: Number(e.target.value) })}
style={{ padding: '0.25rem', width: '60px' }}
/>
</div>
<div>
<label style={{ marginRight: '0.5rem' }}>Color:</label>
<input
type="color"
value={editedWaypoint.color}
onChange={(e) => setEditedWaypoint({ ...editedWaypoint, color: e.target.value })}
style={{ padding: '0.25rem' }}
/>
</div>
<div style={{ marginTop: '0.5rem' }}>
<button onClick={() => saveEditing(index)} style={{ marginRight: '0.5rem' }}>
Save
) : (
<div style={{ display: 'flex', alignItems: 'center', gap: '0.5rem' }}>
<div style={{ backgroundColor: wp.color, width: '12px', height: '12px', borderRadius: '50%' }} />
<span>{`Waypoint ${wp.order}: ${wp.name} [${wp.coordinate[0].toFixed(6)}, ${wp.coordinate[1].toFixed(6)}]`}</span>
<button
onClick={() => startEditing(index)}
style={{
marginLeft: 'auto',
padding: '0.25rem 0.5rem',
backgroundColor: '#444',
color: '#f1f1f1',
border: 'none',
borderRadius: '4px',
cursor: 'pointer',
}}
>
Edit
</button>
<button
onClick={() => removeWaypoint(index)}
style={{
marginLeft: '0.5rem',
padding: '0.25rem 0.5rem',
backgroundColor: '#444',
color: '#f1f1f1',
border: 'none',
borderRadius: '4px',
cursor: 'pointer',
}}
>
Remove
</button>
<button onClick={cancelEditing}>Cancel</button>
</div>
</div>
) : (
<div style={{ display: 'flex', alignItems: 'center', gap: '0.5rem' }}>
<div style={{ backgroundColor: wp.color, width: '12px', height: '12px', borderRadius: '50%' }} />
<span>{`Waypoint ${wp.order}: ${wp.name} [${wp.coordinate[0].toFixed(6)}, ${wp.coordinate[1].toFixed(6)}]`}</span>
<button
onClick={() => startEditing(index)}
style={{
marginLeft: 'auto',
padding: '0.25rem 0.5rem',
backgroundColor: '#444',
color: '#f1f1f1',
border: 'none',
borderRadius: '4px',
cursor: 'pointer',
}}
>
Edit
</button>
<button
onClick={() => removeWaypoint(index)}
style={{
marginLeft: '0.5rem',
padding: '0.25rem 0.5rem',
backgroundColor: '#444',
color: '#f1f1f1',
border: 'none',
borderRadius: '4px',
cursor: 'pointer',
}}
>
Remove
</button>
</div>
)}
</li>
))}
</ul>
)}
</li>
))}
</ul>
</div>
)
}
</div >
Expand Down
34 changes: 33 additions & 1 deletion src/contexts/WaypointContext.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use client';

import React, { createContext, useContext, useState, ReactNode } from 'react';
import React, { createContext, useContext, useState, useEffect, ReactNode } from 'react';

export type LatLngTuple = [number, number];

Expand All @@ -19,10 +19,42 @@ interface WaypointContextType {
updateWaypoint: (index: number, updated: Waypoint) => void;
}

const COOKIE_MAX_AGE_SECONDS = 60 * 60 * 24; // 1 day

const getCookie = (name: string, fallback: Waypoint[]) => {
const cookie = document.cookie
.split('; ')
.find((entry) => entry.startsWith(`${name}=`));

if (!cookie) return fallback;

const value = JSON.parse(decodeURIComponent(cookie.split('=')[1]));

return value;
};

const setCookie = (name: string, value: Waypoint[]) => {
document.cookie =
`${name}=${encodeURIComponent(JSON.stringify(value))}; ` +
`max-age=${COOKIE_MAX_AGE_SECONDS}; path=/; SameSite=Lax`;
};

const WaypointContext = createContext<WaypointContextType | undefined>(undefined);

export const WaypointProvider: React.FC<{ children: ReactNode }> = ({ children }) => {
const [waypoints, setWaypoints] = useState<Waypoint[]>([]);
const [cookiesLoaded, setCookiesLoaded] = useState(false);

useEffect(() => {
setWaypoints(getCookie("waypoints", []));
setCookiesLoaded(true);
}, [])

useEffect(() => {
if (!cookiesLoaded) return;

setCookie("waypoints", waypoints);
}, [waypoints, cookiesLoaded])

const addWaypoint = (coordinate: LatLngTuple) => {
setWaypoints((prev) => [
Expand Down
Loading