feat: Implement user tracking in projects
- Added user tracking features to the projects module, including: - Database schema updates to track project creator and assignee. - API enhancements for user management and project filtering by user. - UI components for user assignment in project forms and listings. - New query functions for retrieving users and filtering projects. - Security integration with role-based access and authentication requirements. chore: Create utility scripts for database checks and project testing - Added scripts to check the structure of the projects table. - Created tests for project creation and user tracking functionality. - Implemented API tests to verify project retrieval and user assignment. fix: Update project creation and update functions to include user tracking - Modified createProject and updateProject functions to handle user IDs for creator and assignee. - Ensured that project updates reflect the correct user assignments and timestamps.
This commit is contained in:
@@ -22,22 +22,59 @@ export default function ProjectForm({ initialData = null }) {
|
||||
contact: "",
|
||||
notes: "",
|
||||
coordinates: "",
|
||||
project_type: initialData?.project_type || "design",
|
||||
// project_status is not included in the form for creation or editing
|
||||
...initialData,
|
||||
project_type: "design",
|
||||
assigned_to: "",
|
||||
});
|
||||
|
||||
const [contracts, setContracts] = useState([]);
|
||||
const [users, setUsers] = useState([]);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const router = useRouter();
|
||||
const isEdit = !!initialData;
|
||||
|
||||
useEffect(() => {
|
||||
// Fetch contracts
|
||||
fetch("/api/contracts")
|
||||
.then((res) => res.json())
|
||||
.then(setContracts);
|
||||
|
||||
// Fetch users for assignment
|
||||
fetch("/api/projects/users")
|
||||
.then((res) => res.json())
|
||||
.then(setUsers);
|
||||
}, []);
|
||||
|
||||
// Update form state when initialData changes (for edit mode)
|
||||
useEffect(() => {
|
||||
if (initialData) {
|
||||
setForm({
|
||||
contract_id: "",
|
||||
project_name: "",
|
||||
address: "",
|
||||
plot: "",
|
||||
district: "",
|
||||
unit: "",
|
||||
city: "",
|
||||
investment_number: "",
|
||||
finish_date: "",
|
||||
wp: "",
|
||||
contact: "",
|
||||
notes: "",
|
||||
coordinates: "",
|
||||
project_type: "design",
|
||||
assigned_to: "",
|
||||
...initialData,
|
||||
// Ensure these defaults are preserved if not in initialData
|
||||
project_type: initialData.project_type || "design",
|
||||
assigned_to: initialData.assigned_to || "",
|
||||
// Format finish_date for input if it exists
|
||||
finish_date: initialData.finish_date
|
||||
? formatDateForInput(initialData.finish_date)
|
||||
: "",
|
||||
});
|
||||
}
|
||||
}, [initialData]);
|
||||
|
||||
function handleChange(e) {
|
||||
setForm({ ...form, [e.target.name]: e.target.value });
|
||||
}
|
||||
@@ -83,7 +120,7 @@ export default function ProjectForm({ initialData = null }) {
|
||||
<CardContent>
|
||||
<form onSubmit={handleSubmit} className="space-y-6">
|
||||
{/* Contract and Project Type Section */}
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-gray-700 mb-2">
|
||||
Contract <span className="text-red-500">*</span>
|
||||
@@ -125,6 +162,25 @@ export default function ProjectForm({ initialData = null }) {
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-gray-700 mb-2">
|
||||
Assigned To
|
||||
</label>
|
||||
<select
|
||||
name="assigned_to"
|
||||
value={form.assigned_to || ""}
|
||||
onChange={handleChange}
|
||||
className="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500"
|
||||
>
|
||||
<option value="">Unassigned</option>
|
||||
{users.map((user) => (
|
||||
<option key={user.id} value={user.id}>
|
||||
{user.name} ({user.email})
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Basic Information Section */}
|
||||
|
||||
Reference in New Issue
Block a user