feat: Add project type and status fields to project forms and views, including database migrations
This commit is contained in:
@@ -12,8 +12,8 @@ import { differenceInCalendarDays, parseISO } from "date-fns";
|
||||
import PageContainer from "@/components/ui/PageContainer";
|
||||
import PageHeader from "@/components/ui/PageHeader";
|
||||
|
||||
export default async function ProjectViewPage({ params }) {
|
||||
const { id } = await params;
|
||||
export default function ProjectViewPage({ params }) {
|
||||
const { id } = params;
|
||||
const project = getProjectWithContract(id);
|
||||
const notes = getNotesForProject(id);
|
||||
const daysRemaining = differenceInCalendarDays(
|
||||
@@ -141,6 +141,36 @@ export default async function ProjectViewPage({ params }) {
|
||||
<p className="text-gray-900">{project.notes}</p>
|
||||
</div>
|
||||
)}
|
||||
<div>
|
||||
<span className="text-sm font-medium text-gray-500">
|
||||
Typ projektu
|
||||
</span>
|
||||
<p className="text-gray-900">
|
||||
{project.project_type === "design"
|
||||
? "Projektowanie"
|
||||
: project.project_type === "construction"
|
||||
? "Realizacja"
|
||||
: project.project_type === "design+construction"
|
||||
? "Projektowanie + Realizacja"
|
||||
: "-"}
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<span className="text-sm font-medium text-gray-500">
|
||||
Status projektu
|
||||
</span>
|
||||
<p className="text-gray-900">
|
||||
{project.project_status === "registered"
|
||||
? "Zarejestrowany"
|
||||
: project.project_status === "in_progress_design"
|
||||
? "W realizacji (projektowanie)"
|
||||
: project.project_status === "in_progress_construction"
|
||||
? "W realizacji (realizacja)"
|
||||
: project.project_status === "fulfilled"
|
||||
? "Zakończony"
|
||||
: "-"}
|
||||
</p>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
<Card>
|
||||
|
||||
@@ -192,6 +192,26 @@ export default function ProjectListPage() {
|
||||
<div className="col-span-1 text-sm text-gray-600 truncate">
|
||||
{project.finish_date || "N/A"}
|
||||
</div>
|
||||
<div className="col-span-1 text-sm text-gray-600 truncate">
|
||||
{project.project_type === "design"
|
||||
? "Projektowanie"
|
||||
: project.project_type === "construction"
|
||||
? "Realizacja"
|
||||
: project.project_type === "design+construction"
|
||||
? "Projektowanie + Realizacja"
|
||||
: "-"}
|
||||
</div>
|
||||
<div className="col-span-1 text-sm text-gray-600 truncate">
|
||||
{project.project_status === "registered"
|
||||
? "Zarejestrowany"
|
||||
: project.project_status === "in_progress_design"
|
||||
? "W realizacji (projektowanie)"
|
||||
: project.project_status === "in_progress_construction"
|
||||
? "W realizacji (realizacja)"
|
||||
: project.project_status === "fulfilled"
|
||||
? "Zakończony"
|
||||
: "-"}
|
||||
</div>
|
||||
<div className="col-span-1">
|
||||
<Link href={`/projects/${project.project_id}`}>
|
||||
<Button variant="outline" size="sm">
|
||||
|
||||
@@ -17,6 +17,8 @@ export default function ProjectForm({ initialData = null }) {
|
||||
wp: "",
|
||||
contact: "",
|
||||
notes: "",
|
||||
project_type: initialData?.project_type || "design",
|
||||
// project_status is not included in the form for creation or editing
|
||||
...initialData,
|
||||
});
|
||||
|
||||
@@ -74,6 +76,24 @@ export default function ProjectForm({ initialData = null }) {
|
||||
</select>
|
||||
</div>
|
||||
|
||||
{/* Project Type Dropdown */}
|
||||
<div>
|
||||
<label className="block font-medium">Typ projektu</label>
|
||||
<select
|
||||
name="project_type"
|
||||
value={form.project_type}
|
||||
onChange={handleChange}
|
||||
className="border p-2 w-full"
|
||||
required
|
||||
>
|
||||
<option value="design">Projektowanie</option>
|
||||
<option value="construction">Realizacja</option>
|
||||
<option value="design+construction">
|
||||
Projektowanie + Realizacja
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
{/* Other fields */}
|
||||
{[
|
||||
["project_name", "Nazwa projektu"],
|
||||
|
||||
38
src/components/ProjectStatusDropdown.js
Normal file
38
src/components/ProjectStatusDropdown.js
Normal file
@@ -0,0 +1,38 @@
|
||||
"use client";
|
||||
|
||||
import { useState } from "react";
|
||||
|
||||
export default function ProjectStatusDropdown({ project, onStatusChange }) {
|
||||
const [status, setStatus] = useState(project.project_status);
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
const handleChange = async (e) => {
|
||||
const newStatus = e.target.value;
|
||||
setStatus(newStatus);
|
||||
setLoading(true);
|
||||
await fetch(`/api/projects/${project.project_id}`, {
|
||||
method: "PUT",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ ...project, project_status: newStatus }),
|
||||
});
|
||||
setLoading(false);
|
||||
if (onStatusChange) onStatusChange(newStatus);
|
||||
};
|
||||
|
||||
return (
|
||||
<select
|
||||
name="project_status"
|
||||
value={status}
|
||||
onChange={handleChange}
|
||||
className="ml-2 border p-1 rounded"
|
||||
disabled={loading}
|
||||
>
|
||||
<option value="registered">Zarejestrowany</option>
|
||||
<option value="in_progress_design">W realizacji (projektowanie)</option>
|
||||
<option value="in_progress_construction">
|
||||
W realizacji (realizacja)
|
||||
</option>
|
||||
<option value="fulfilled">Zakończony</option>
|
||||
</select>
|
||||
);
|
||||
}
|
||||
@@ -30,6 +30,8 @@ export default function initializeDatabase() {
|
||||
wp TEXT,
|
||||
contact TEXT,
|
||||
notes TEXT,
|
||||
project_type TEXT CHECK(project_type IN ('design', 'construction', 'design+construction')) DEFAULT 'design',
|
||||
project_status TEXT CHECK(project_status IN ('registered', 'in_progress_design', 'in_progress_construction', 'fulfilled')) DEFAULT 'registered',
|
||||
FOREIGN KEY (contract_id) REFERENCES contracts(contract_id)
|
||||
);
|
||||
|
||||
@@ -98,4 +100,22 @@ export default function initializeDatabase() {
|
||||
} catch (e) {
|
||||
// Column already exists, ignore error
|
||||
}
|
||||
|
||||
// Migration: Add project_type column to projects table
|
||||
try {
|
||||
db.exec(`
|
||||
ALTER TABLE projects ADD COLUMN project_type TEXT CHECK(project_type IN ('design', 'construction', 'design+construction')) DEFAULT 'design';
|
||||
`);
|
||||
} catch (e) {
|
||||
// Column already exists, ignore error
|
||||
}
|
||||
|
||||
// Migration: Add project_status column to projects table
|
||||
try {
|
||||
db.exec(`
|
||||
ALTER TABLE projects ADD COLUMN project_status TEXT CHECK(project_status IN ('registered', 'in_progress_design', 'in_progress_construction', 'fulfilled')) DEFAULT 'registered';
|
||||
`);
|
||||
} catch (e) {
|
||||
// Column already exists, ignore error
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,8 +42,8 @@ export function createProject(data) {
|
||||
const stmt = db.prepare(`
|
||||
INSERT INTO projects (
|
||||
contract_id, project_name, project_number, address, plot, district, unit, city, investment_number, finish_date,
|
||||
wp, contact, notes
|
||||
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
wp, contact, notes, project_type, project_status
|
||||
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
`);
|
||||
stmt.run(
|
||||
data.contract_id,
|
||||
@@ -58,7 +58,9 @@ export function createProject(data) {
|
||||
data.finish_date,
|
||||
data.wp,
|
||||
data.contact,
|
||||
data.notes
|
||||
data.notes,
|
||||
data.project_type || "design",
|
||||
data.project_status || "registered"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -66,7 +68,7 @@ export function updateProject(id, data) {
|
||||
const stmt = db.prepare(`
|
||||
UPDATE projects SET
|
||||
contract_id = ?, project_name = ?, project_number = ?, address = ?, plot = ?, district = ?, unit = ?, city = ?,
|
||||
investment_number = ?, finish_date = ?, wp = ?, contact = ?, notes = ?
|
||||
investment_number = ?, finish_date = ?, wp = ?, contact = ?, notes = ?, project_type = ?, project_status = ?
|
||||
WHERE project_id = ?
|
||||
`);
|
||||
stmt.run(
|
||||
@@ -83,6 +85,8 @@ export function updateProject(id, data) {
|
||||
data.wp,
|
||||
data.contact,
|
||||
data.notes,
|
||||
data.project_type || "design",
|
||||
data.project_status || "registered",
|
||||
id
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user