import React, { useEffect, useState } from "react"; import { Activity as ActivityIcon, Layers, Plus, RefreshCw, Trash2, } from "lucide-react"; import { Card, CardContent, CardHeader } from "../components/ui/Card.tsx"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from "../components/ui/Table.tsx"; import { Button } from "../components/ui/Button.tsx"; import { Input, Select } from "../components/ui/Input.tsx"; import { useDepartments, useSubDepartments } from "../hooks/useDepartments.ts"; import { useActivitiesByDepartment } from "../hooks/useActivities.ts"; import { useAuth } from "../contexts/authContext.ts"; import { api } from "../services/api.ts"; import { Activity, SubDepartment } from "../types.ts"; export const ActivitiesPage: React.FC = () => { const [activeTab, setActiveTab] = useState<"subDepartments" | "activities">( "subDepartments", ); const { user } = useAuth(); const { departments } = useDepartments(); // Role-based access const isSupervisor = user?.role === "Supervisor"; const isSuperAdmin = user?.role === "SuperAdmin"; const canAccess = isSupervisor || isSuperAdmin; // Department selection - supervisors are locked to their department const [selectedDeptId, setSelectedDeptId] = useState(""); // Get sub-departments and activities for selected department const { subDepartments, refresh: refreshSubDepts } = useSubDepartments( selectedDeptId, ); const { activities, refresh: refreshActivities } = useActivitiesByDepartment( selectedDeptId, ); // Form states const [subDeptForm, setSubDeptForm] = useState({ name: "" }); const [activityForm, setActivityForm] = useState({ subDepartmentId: "", name: "", unitOfMeasurement: "Per Bag" as "Per Bag" | "Fixed Rate-Per Person", }); const [loading, setLoading] = useState(false); const [error, setError] = useState(""); const [success, setSuccess] = useState(""); // Auto-select department for supervisors useEffect(() => { if (isSupervisor && user?.department_id) { setSelectedDeptId(String(user.department_id)); } }, [isSupervisor, user?.department_id]); // Clear messages after 3 seconds useEffect(() => { if (success || error) { const timer = setTimeout(() => { setSuccess(""); setError(""); }, 3000); return () => clearTimeout(timer); } }, [success, error]); const handleCreateSubDepartment = async () => { if (!subDeptForm.name.trim()) { setError("Sub-department name is required"); return; } if (!selectedDeptId) { setError("Please select a department first"); return; } setLoading(true); setError(""); try { await api.createSubDepartment({ department_id: parseInt(selectedDeptId), name: subDeptForm.name.trim(), }); setSuccess("Sub-department created successfully"); setSubDeptForm({ name: "" }); refreshSubDepts(); } catch (err) { setError( err instanceof Error ? err.message : "Failed to create sub-department", ); } finally { setLoading(false); } }; const handleDeleteSubDepartment = async (id: number) => { if ( !confirm( "Are you sure you want to delete this sub-department? This will also delete all associated activities.", ) ) { return; } setLoading(true); try { await api.deleteSubDepartment(id); setSuccess("Sub-department deleted successfully"); refreshSubDepts(); refreshActivities(); } catch (err) { setError( err instanceof Error ? err.message : "Failed to delete sub-department", ); } finally { setLoading(false); } }; const handleCreateActivity = async () => { if (!activityForm.name.trim()) { setError("Activity name is required"); return; } if (!activityForm.subDepartmentId) { setError("Please select a sub-department"); return; } setLoading(true); setError(""); try { await api.createActivity({ sub_department_id: parseInt(activityForm.subDepartmentId), name: activityForm.name.trim(), unit_of_measurement: activityForm.unitOfMeasurement, }); setSuccess("Activity created successfully"); setActivityForm({ subDepartmentId: "", name: "", unitOfMeasurement: "Per Bag", }); refreshActivities(); } catch (err) { setError( err instanceof Error ? err.message : "Failed to create activity", ); } finally { setLoading(false); } }; const handleDeleteActivity = async (id: number) => { if (!confirm("Are you sure you want to delete this activity?")) { return; } setLoading(true); try { await api.deleteActivity(id); setSuccess("Activity deleted successfully"); refreshActivities(); } catch (err) { setError( err instanceof Error ? err.message : "Failed to delete activity", ); } finally { setLoading(false); } }; if (!canAccess) { return (

You do not have permission to access this page.

); } const selectedDeptName = departments.find((d) => d.id === parseInt(selectedDeptId))?.name || ""; return (

Manage Activities & Sub-Departments

{/* Department Selection */}
{isSupervisor ? (

As a supervisor, you can only manage your department's activities.

) : ( setSubDeptForm({ name: e.target.value })} placeholder="e.g., Loading/Unloading, Destoner, Tank" />
{/* Sub-Departments List */} Sub-Department Name Activities Count Created At Actions {subDepartments.length === 0 ? ( No sub-departments found. Create one above. ) : ( subDepartments.map((subDept: SubDepartment) => { const activityCount = activities.filter((a) => a.sub_department_id === subDept.id ).length; return ( {subDept.name} {activityCount} {new Date(subDept.created_at) .toLocaleDateString()} ); }) )}
)} {/* Activities Tab */} {activeTab === "activities" && (
{/* Create Activity Form */}

Add New Activity

setActivityForm((prev) => ({ ...prev, name: e.target.value, }))} placeholder="e.g., Mufali Aavak Katai" />