Refactor: Use new services and types

Update frontend components to use the new services and types for job management, including facilities, jobs, and transactions. Remove old type definitions and integrate the new ones.
This commit is contained in:
gpt-engineer-app[bot]
2025-07-04 13:28:35 +00:00
parent 7808907861
commit fb16824137
8 changed files with 272 additions and 173 deletions

View File

@@ -2,18 +2,27 @@ import React, { useState, useEffect } from 'react';
import { Button } from '@/components/ui/button';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Plus, Factory, TrendingUp, Briefcase } from 'lucide-react';
import { Job, Transaction, jobService } from '@/services/jobService';
import { IndJobResponse, IndTransactionResponse, IndJobRecord, IndTransactionRecord } from '@/lib/pbtypes';
import * as jobService from '@/services/jobService';
import { formatISK } from '@/utils/priceUtils';
import JobCard from '@/components/JobCard';
import JobForm from '@/components/JobForm';
import TransactionForm from '@/components/TransactionForm';
import TransactionTable from '@/components/TransactionTable';
// Extended job type for UI components
interface JobWithRelations extends IndJobResponse {
expenditures: IndTransactionResponse[];
income: IndTransactionResponse[];
billOfMaterials: any[];
consumedMaterials: { name: string; required: number }[];
}
const Index = () => {
const [jobs, setJobs] = useState<Job[]>([]);
const [jobs, setJobs] = useState<JobWithRelations[]>([]);
const [showJobForm, setShowJobForm] = useState(false);
const [editingJob, setEditingJob] = useState<Job | null>(null);
const [selectedJob, setSelectedJob] = useState<Job | null>(null);
const [editingJob, setEditingJob] = useState<JobWithRelations | null>(null);
const [selectedJob, setSelectedJob] = useState<JobWithRelations | null>(null);
useEffect(() => {
loadJobs();
@@ -22,38 +31,61 @@ const Index = () => {
const loadJobs = async () => {
try {
const fetchedJobs = await jobService.getJobs();
setJobs(fetchedJobs);
// Convert to JobWithRelations format
const jobsWithRelations: JobWithRelations[] = fetchedJobs.map(job => ({
...job,
expenditures: [],
income: [],
billOfMaterials: [],
consumedMaterials: []
}));
setJobs(jobsWithRelations);
} catch (error) {
console.error('Error loading jobs:', error);
}
};
const handleCreateJob = async (jobData: Omit<Job, 'id' | 'expenditures' | 'income'>) => {
const handleCreateJob = async (jobData: Omit<IndJobRecord, 'id' | 'created' | 'updated'>) => {
try {
const newJob = await jobService.createJob(jobData);
setJobs([...jobs, newJob]);
const jobWithRelations: JobWithRelations = {
...newJob,
expenditures: [],
income: [],
billOfMaterials: [],
consumedMaterials: []
};
setJobs([...jobs, jobWithRelations]);
setShowJobForm(false);
} catch (error) {
console.error('Error creating job:', error);
}
};
const handleEditJob = (job: Job) => {
const handleEditJob = (job: JobWithRelations) => {
setEditingJob(job);
setShowJobForm(true);
};
const handleUpdateJob = async (jobData: Omit<Job, 'id' | 'expenditures' | 'income'>) => {
const handleUpdateJob = async (jobData: Omit<IndJobRecord, 'id' | 'created' | 'updated'>) => {
if (!editingJob) return;
try {
const updatedJob = await jobService.updateJob(editingJob.id, jobData);
setJobs(jobs.map(job => job.id === editingJob.id ? updatedJob : job));
const updatedJobWithRelations: JobWithRelations = {
...updatedJob,
expenditures: editingJob.expenditures,
income: editingJob.income,
billOfMaterials: editingJob.billOfMaterials,
consumedMaterials: editingJob.consumedMaterials
};
setJobs(jobs.map(job => job.id === editingJob.id ? updatedJobWithRelations : job));
setShowJobForm(false);
setEditingJob(null);
// Update selectedJob if it's the same job being edited
if (selectedJob?.id === editingJob.id) {
setSelectedJob(updatedJob);
setSelectedJob(updatedJobWithRelations);
}
} catch (error) {
console.error('Error updating job:', error);
@@ -74,7 +106,7 @@ const Index = () => {
}
};
const handleTransactionsAdded = async (transactions: Transaction[], type: 'expenditure' | 'income') => {
const handleTransactionsAdded = async (transactions: IndTransactionRecord[], type: 'expenditure' | 'income') => {
if (!selectedJob) return;
try {
@@ -84,10 +116,12 @@ const Index = () => {
// Update local state
const updatedJob = { ...selectedJob };
const newTransactions = transactions as unknown as IndTransactionResponse[];
if (type === 'expenditure') {
updatedJob.expenditures = [...updatedJob.expenditures, ...transactions];
updatedJob.expenditures = [...updatedJob.expenditures, ...newTransactions];
} else {
updatedJob.income = [...updatedJob.income, ...transactions];
updatedJob.income = [...updatedJob.income, ...newTransactions];
}
setSelectedJob(updatedJob);
@@ -97,7 +131,7 @@ const Index = () => {
}
};
const handleUpdateTransaction = async (transactionId: string, updates: Partial<Transaction>) => {
const handleUpdateTransaction = async (transactionId: string, updates: Partial<IndTransactionResponse>) => {
if (!selectedJob) return;
try {
@@ -139,13 +173,13 @@ const Index = () => {
const totalJobs = jobs.length;
const totalProfit = jobs.reduce((sum, job) => {
const expenditure = job.expenditures.reduce((sum, tx) => sum + Math.abs(tx.totalAmount), 0);
const income = job.income.reduce((sum, tx) => sum + tx.totalAmount, 0);
const expenditure = job.expenditures.reduce((sum, tx) => sum + tx.totalPrice, 0);
const income = job.income.reduce((sum, tx) => sum + tx.totalPrice, 0);
return sum + (income - expenditure);
}, 0);
const totalRevenue = jobs.reduce((sum, job) =>
sum + job.income.reduce((sum, tx) => sum + tx.totalAmount, 0), 0
sum + job.income.reduce((sum, tx) => sum + tx.totalPrice, 0), 0
);
if (showJobForm) {
@@ -172,7 +206,7 @@ const Index = () => {
<div className="flex items-center justify-between">
<div>
<h1 className="text-3xl font-bold text-white">Job Details</h1>
<p className="text-gray-400">{selectedJob.outputItem.name}</p>
<p className="text-gray-400">{selectedJob.outputItem}</p>
</div>
<Button
variant="outline"