feat: Implement runtime parsing and reduce button alpha

Adds runtime parsing from job imports and adds a runtime field to the job creation dialogue. Reduces the alpha on status buttons.
This commit is contained in:
gpt-engineer-app[bot]
2025-07-09 22:56:36 +00:00
committed by PhatPhuckDave
parent c5b4a41b19
commit f697f38e4f
2 changed files with 33 additions and 13 deletions

View File

@@ -1,3 +1,4 @@
import React, { useState } from 'react'; import React, { useState } from 'react';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Button } from '@/components/ui/button'; import { Button } from '@/components/ui/button';
@@ -21,7 +22,8 @@ const JobForm: React.FC<JobFormProps> = ({ job, onSubmit, onCancel }) => {
outputQuantity: job?.outputQuantity || 0, outputQuantity: job?.outputQuantity || 0,
status: job?.status || IndJobStatusOptions.Planned, status: job?.status || IndJobStatusOptions.Planned,
projectedCost: job?.projectedCost || 0, projectedCost: job?.projectedCost || 0,
projectedRevenue: job?.projectedRevenue || 0 projectedRevenue: job?.projectedRevenue || 0,
runtime: job?.runtime || 0
}); });
const [jobDump, setJobDump] = useState(''); const [jobDump, setJobDump] = useState('');
@@ -35,7 +37,7 @@ const JobForm: React.FC<JobFormProps> = ({ job, onSubmit, onCancel }) => {
const lines = dumpText.trim().split('\n').filter(line => line.trim()); const lines = dumpText.trim().split('\n').filter(line => line.trim());
if (lines.length >= 3) { if (lines.length >= 4) {
// Parse first line: "Item Name Quantity" // Parse first line: "Item Name Quantity"
const firstLine = lines[0].trim(); const firstLine = lines[0].trim();
const lastSpaceIndex = firstLine.lastIndexOf(' '); const lastSpaceIndex = firstLine.lastIndexOf(' ');
@@ -44,22 +46,26 @@ const JobForm: React.FC<JobFormProps> = ({ job, onSubmit, onCancel }) => {
const itemName = firstLine.substring(0, lastSpaceIndex).trim(); const itemName = firstLine.substring(0, lastSpaceIndex).trim();
const quantity = parseInt(firstLine.substring(lastSpaceIndex + 1).trim()) || 0; const quantity = parseInt(firstLine.substring(lastSpaceIndex + 1).trim()) || 0;
// Parse cost (second line) // Parse runtime (second line)
const cost = parseISKAmount(lines[1].replace(/,/g, '')); const runtime = parseInt(lines[1].replace(/,/g, '')) || 0;
// Parse revenue (third line) // Parse cost (third line)
const revenue = parseISKAmount(lines[2].replace(/,/g, '')); const cost = parseISKAmount(lines[2].replace(/,/g, ''));
// Parse revenue (fourth line)
const revenue = parseISKAmount(lines[3].replace(/,/g, ''));
setFormData(prev => ({ setFormData(prev => ({
...prev, ...prev,
outputItem: itemName, outputItem: itemName,
outputQuantity: quantity, outputQuantity: quantity,
runtime: runtime,
projectedCost: cost, projectedCost: cost,
projectedRevenue: revenue projectedRevenue: revenue
})); }));
// Parse BOM - everything after the first 3 lines is BOM // Parse BOM - everything after the first 4 lines is BOM
const bomLines = lines.slice(3); // Start from line 4 (index 3) const bomLines = lines.slice(4); // Start from line 5 (index 4)
const billOfMaterials: { name: string; quantity: number }[] = []; const billOfMaterials: { name: string; quantity: number }[] = [];
for (const line of bomLines) { for (const line of bomLines) {
@@ -95,7 +101,8 @@ const JobForm: React.FC<JobFormProps> = ({ job, onSubmit, onCancel }) => {
outputQuantity: formData.outputQuantity, outputQuantity: formData.outputQuantity,
status: formData.status, status: formData.status,
projectedCost: formData.projectedCost, projectedCost: formData.projectedCost,
projectedRevenue: formData.projectedRevenue projectedRevenue: formData.projectedRevenue,
runtime: formData.runtime
}, parsedBillOfMaterials.length > 0 ? parsedBillOfMaterials : undefined); }, parsedBillOfMaterials.length > 0 ? parsedBillOfMaterials : undefined);
}; };
@@ -159,7 +166,20 @@ const JobForm: React.FC<JobFormProps> = ({ job, onSubmit, onCancel }) => {
</Select> </Select>
</div> </div>
<div className="grid grid-cols-2 gap-4"> <div className="grid grid-cols-3 gap-4">
<div className="space-y-2">
<Label htmlFor="runtime" className="text-gray-300">Runtime (seconds)</Label>
<Input
id="runtime"
type="number"
value={formData.runtime}
onChange={(e) => setFormData({
...formData,
runtime: parseInt(e.target.value) || 0
})}
className="bg-gray-800 border-gray-600 text-white"
/>
</div>
<div className="space-y-2"> <div className="space-y-2">
<Label htmlFor="projectedCost" className="text-gray-300">Projected Cost</Label> <Label htmlFor="projectedCost" className="text-gray-300">Projected Cost</Label>
<Input <Input
@@ -194,7 +214,7 @@ const JobForm: React.FC<JobFormProps> = ({ job, onSubmit, onCancel }) => {
id="jobDump" id="jobDump"
value={jobDump} value={jobDump}
onChange={handleJobDumpChange} onChange={handleJobDumpChange}
placeholder="Paste job dump here:&#10;&#10;Standup Light Guided Bomb 100&#10;285,224,182&#10;771,342,930&#10;&#10;Megacyte 37&#10;Zydrine 84&#10;..." placeholder="Paste job dump here:&#10;&#10;Discovery Survey Probe I 800&#10;468000&#10;158,670,288&#10;237,484,800&#10;&#10;Tritanium 8888800&#10;Pyerite 711200&#10;..."
className="bg-gray-800 border-gray-600 text-white min-h-[120px]" className="bg-gray-800 border-gray-600 text-white min-h-[120px]"
rows={6} rows={6}
/> />

View File

@@ -74,7 +74,7 @@ const JobStatusNavigation: React.FC<JobStatusNavigationProps> = ({ job }) => {
e.stopPropagation(); e.stopPropagation();
handleStatusChange(previousStatus); handleStatusChange(previousStatus);
}} }}
className={`${getStatusColor(previousStatus)} text-white px-4 py-2 rounded flex items-center justify-center gap-1 hover:opacity-80 transition-opacity w-32`} className={`${getStatusColor(previousStatus)}/60 text-white px-4 py-2 rounded flex items-center justify-center gap-1 hover:opacity-80 transition-opacity w-32`}
data-no-navigate data-no-navigate
title={`Move to ${previousStatus}`} title={`Move to ${previousStatus}`}
> >
@@ -88,7 +88,7 @@ const JobStatusNavigation: React.FC<JobStatusNavigationProps> = ({ job }) => {
e.stopPropagation(); e.stopPropagation();
handleStatusChange(nextStatus); handleStatusChange(nextStatus);
}} }}
className={`${getStatusColor(nextStatus)} text-white px-4 py-2 rounded flex items-center justify-center gap-1 hover:opacity-80 transition-opacity w-32`} className={`${getStatusColor(nextStatus)}/60 text-white px-4 py-2 rounded flex items-center justify-center gap-1 hover:opacity-80 transition-opacity w-32`}
data-no-navigate data-no-navigate
title={`Move to ${nextStatus}`} title={`Move to ${nextStatus}`}
> >