128 lines
5.9 KiB
TypeScript
128 lines
5.9 KiB
TypeScript
import AuthenticatedLayout from '@/Layouts/AuthenticatedLayout';
|
|
import { Head, Link, useForm } from '@inertiajs/react';
|
|
import { Button } from '@/Components/ui/button';
|
|
import { Badge } from '@/Components/ui/badge';
|
|
import { CardHeader, CardTitle, CardDescription } from '@/Components/ui/card';
|
|
import { Sparkles, ChevronRight, Check } from 'lucide-react';
|
|
import { PageProps } from '@/types';
|
|
import { FormEvent } from 'react';
|
|
import { ProjectForm, ProjectFormData, ProjectClassificationItem } from '../../Components/ProjectForm';
|
|
|
|
interface Employee { id: number; ulid: string; name: string }
|
|
interface ParentProject { id: number; ulid: string; name: string; code: string }
|
|
|
|
interface Props extends PageProps {
|
|
employees: Employee[];
|
|
projects: ParentProject[];
|
|
classifications?: ProjectClassificationItem[];
|
|
}
|
|
|
|
export default function Create({ employees, projects, classifications = [] }: Props) {
|
|
const { data, setData, post, processing, errors } = useForm<ProjectFormData>({
|
|
name: '',
|
|
client_name: '',
|
|
location: '',
|
|
start_date: '',
|
|
target_end_date: '',
|
|
contract_duration: '',
|
|
description: '',
|
|
pm_id: '',
|
|
contract_value: '',
|
|
project_type: 'standard',
|
|
classifications: [],
|
|
parent_project_id: '',
|
|
is_unprofitable: false,
|
|
});
|
|
|
|
const handleSubmit = (e: FormEvent) => {
|
|
e.preventDefault();
|
|
post(route('projects.store'));
|
|
};
|
|
|
|
const stepsList = [
|
|
{ id: 1, label: 'Details' },
|
|
{ id: 2, label: 'Tasks' },
|
|
{ id: 3, label: 'Materials' },
|
|
{ id: 4, label: 'Manpower' },
|
|
{ id: 5, label: 'Equipment' },
|
|
{ id: 6, label: 'Estimation' },
|
|
{ id: 7, label: 'Submit' }
|
|
];
|
|
|
|
return (
|
|
<AuthenticatedLayout
|
|
header={
|
|
<div className="flex items-center justify-between">
|
|
<div>
|
|
<h2 className="text-xl font-bold leading-tight text-slate-800 flex items-center gap-2">
|
|
<Sparkles className="h-5 w-5 text-emerald-500" /> Project Wizard: {data.name || 'New Project'}
|
|
</h2>
|
|
<p className="text-xs text-slate-500 mt-0.5">Guided Project Estimation Setup</p>
|
|
</div>
|
|
<Badge className="bg-amber-50 text-amber-700 border-amber-100">
|
|
under bidding
|
|
</Badge>
|
|
</div>
|
|
}
|
|
>
|
|
<Head title="Project Setup Wizard" />
|
|
|
|
<div className="py-6 bg-slate-50/50 min-h-[calc(100vh-65px)]">
|
|
<div className="mx-auto max-w-5xl px-4 sm:px-6 lg:px-8 space-y-6">
|
|
|
|
{/* Stepper Header */}
|
|
<div className="bg-white p-4 rounded-xl border border-slate-200/80 shadow-sm">
|
|
<div className="flex flex-wrap justify-between items-center relative">
|
|
<div className="absolute left-6 right-6 top-1/2 -translate-y-1/2 h-[2px] bg-slate-100 z-0 hidden md:block" />
|
|
|
|
{stepsList.map((s) => {
|
|
const isActive = s.id === 1;
|
|
return (
|
|
<div key={s.id} className="flex flex-col items-center z-10 flex-1 relative min-w-[70px] md:min-w-0">
|
|
<div className={`h-8 w-8 rounded-full flex items-center justify-center font-semibold text-xs border transition-all duration-300 ${
|
|
isActive
|
|
? 'bg-emerald-600 border-emerald-600 text-white shadow-md shadow-emerald-200 scale-110'
|
|
: 'bg-white border-slate-200 text-slate-400'
|
|
}`}>
|
|
{s.id}
|
|
</div>
|
|
<span className={`text-[10px] md:text-xs mt-1.5 font-medium transition-all ${
|
|
isActive ? 'text-emerald-700 font-bold' : 'text-slate-400'
|
|
}`}>{s.label}</span>
|
|
</div>
|
|
);
|
|
})}
|
|
</div>
|
|
</div>
|
|
|
|
{/* Step 1 Form Container */}
|
|
<div className="bg-white rounded-xl border border-slate-200/80 shadow-sm overflow-hidden p-6 space-y-6">
|
|
<CardHeader className="p-0 pb-4 border-b border-slate-100">
|
|
<CardTitle className="text-md font-semibold text-slate-800">Step 1: Project Information</CardTitle>
|
|
<CardDescription className="text-xs">Review and update project information parameters.</CardDescription>
|
|
</CardHeader>
|
|
|
|
<form onSubmit={handleSubmit} className="space-y-6">
|
|
<ProjectForm
|
|
data={data}
|
|
setData={setData}
|
|
errors={errors}
|
|
employees={employees}
|
|
projects={projects}
|
|
classifications={classifications}
|
|
/>
|
|
|
|
<div className="flex justify-between pt-6 border-t border-slate-100">
|
|
<div></div>
|
|
<Button type="submit" disabled={processing} className="bg-emerald-600 hover:bg-emerald-700 text-white font-medium">
|
|
Save & Next <ChevronRight className="ml-2 h-4 w-4" />
|
|
</Button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</AuthenticatedLayout>
|
|
);
|
|
}
|