Adds ship cards with navigation, create ship modal with initial stats, inline delete confirmation, and supporting CSS for modals and cards. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
44 lines
1.2 KiB
TypeScript
44 lines
1.2 KiB
TypeScript
import { useNavigate } from 'react-router-dom';
|
|
import type { ShipListItem } from '../../types/ship';
|
|
|
|
interface Props {
|
|
ship: ShipListItem;
|
|
onDelete: (id: string) => void;
|
|
}
|
|
|
|
export default function ShipCard({ ship, onDelete }: Props) {
|
|
const navigate = useNavigate();
|
|
|
|
const timeAgo = formatTimeAgo(ship.updated_at);
|
|
|
|
return (
|
|
<div className="ship-card" onClick={() => navigate(`/ship/${ship.id}`)}>
|
|
<div className="ship-card-info">
|
|
<span className="ship-card-name">{ship.name}</span>
|
|
<span className="ship-card-updated">{timeAgo}</span>
|
|
</div>
|
|
<button
|
|
className="btn-icon ship-card-delete"
|
|
onClick={(e) => {
|
|
e.stopPropagation();
|
|
onDelete(ship.id);
|
|
}}
|
|
title="Delete ship"
|
|
>
|
|
🗑
|
|
</button>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
function formatTimeAgo(timestamp: number): string {
|
|
const seconds = Math.floor((Date.now() - timestamp) / 1000);
|
|
if (seconds < 60) return 'just now';
|
|
const minutes = Math.floor(seconds / 60);
|
|
if (minutes < 60) return `${minutes}m ago`;
|
|
const hours = Math.floor(minutes / 60);
|
|
if (hours < 24) return `${hours}h ago`;
|
|
const days = Math.floor(hours / 24);
|
|
return `${days}d ago`;
|
|
}
|