mirror of
https://github.com/wanderer-industries/wanderer
synced 2025-12-12 02:35:42 +00:00
feat: add structure widget with timer and associated api
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
// File: TimerCell.tsx
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { StructureStatus } from '../helpers/structureTypes';
|
||||
import { statusesRequiringTimer } from '../helpers';
|
||||
|
||||
interface TimerCellProps {
|
||||
endTime?: string;
|
||||
status: StructureStatus;
|
||||
}
|
||||
|
||||
function TimerCellImpl({ endTime, status }: TimerCellProps) {
|
||||
const [now, setNow] = useState(() => Date.now());
|
||||
|
||||
useEffect(() => {
|
||||
if (!endTime || !statusesRequiringTimer.includes(status)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const intervalId = setInterval(() => {
|
||||
setNow(Date.now());
|
||||
}, 1000);
|
||||
|
||||
return () => clearInterval(intervalId);
|
||||
}, [endTime, status]);
|
||||
|
||||
if (!statusesRequiringTimer.includes(status)) {
|
||||
return <span className="text-stone-400"></span>;
|
||||
}
|
||||
if (!endTime) {
|
||||
return <span className="text-sky-400">Set Timer</span>;
|
||||
}
|
||||
|
||||
const msLeft = new Date(endTime).getTime() - now;
|
||||
if (msLeft <= 0) {
|
||||
return <span className="text-red-500">00:00:00</span>;
|
||||
}
|
||||
|
||||
const sec = Math.floor(msLeft / 1000) % 60;
|
||||
const min = Math.floor(msLeft / (1000 * 60)) % 60;
|
||||
const hr = Math.floor(msLeft / (1000 * 3600));
|
||||
|
||||
const pad = (n: number) => n.toString().padStart(2, '0');
|
||||
return (
|
||||
<span className="text-sky-400">
|
||||
{pad(hr)}:{pad(min)}:{pad(sec)}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
export const TimerCell = React.memo(TimerCellImpl);
|
||||
@@ -0,0 +1,36 @@
|
||||
import { StructureItem } from '../helpers';
|
||||
import { TimerCell } from './TimerCell';
|
||||
|
||||
export function renderTimerCell(row: StructureItem) {
|
||||
return <TimerCell endTime={row.endTime} status={row.status} />;
|
||||
}
|
||||
|
||||
export function renderOwnerCell(row: StructureItem) {
|
||||
return (
|
||||
<div className="flex items-center gap-2">
|
||||
{row.ownerId && (
|
||||
<img
|
||||
src={`https://images.evetech.net/corporations/${row.ownerId}/logo?size=32`}
|
||||
alt="corp icon"
|
||||
className="w-5 h-5 object-contain"
|
||||
/>
|
||||
)}
|
||||
<span>{row.ownerTicker || row.ownerName}</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export function renderTypeCell(row: StructureItem) {
|
||||
return (
|
||||
<div className="flex items-center gap-1">
|
||||
{row.structureTypeId && (
|
||||
<img
|
||||
src={`https://images.evetech.net/types/${row.structureTypeId}/icon`}
|
||||
alt="icon"
|
||||
className="w-5 h-5 object-contain"
|
||||
/>
|
||||
)}
|
||||
<span>{row.structureType ?? ''}</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user