diff --git a/apps/web/src/features/auth/Login.tsx b/apps/web/src/features/auth/Login.tsx index a432a5a0..c22005f5 100644 --- a/apps/web/src/features/auth/Login.tsx +++ b/apps/web/src/features/auth/Login.tsx @@ -125,7 +125,6 @@ const Login: React.FC = () => { // Dispatch Redux action to handle login dispatch(loginUser({ email, password })); }; - console.log(user); return (
{/* Left Side: Hero Image (Hidden on Mobile) */} diff --git a/apps/web/src/features/dashboard/AdminDashboard.tsx b/apps/web/src/features/dashboard/AdminDashboard.tsx index 157ea9e1..4f61639c 100644 --- a/apps/web/src/features/dashboard/AdminDashboard.tsx +++ b/apps/web/src/features/dashboard/AdminDashboard.tsx @@ -1,7 +1,7 @@ const AdminDashboard = () => { return ( -
Dashboard
+
Admin Dashboard
) } diff --git a/apps/web/src/features/workforce/directory/AddStaff.tsx b/apps/web/src/features/workforce/directory/AddStaff.tsx index a01e166c..c108389f 100644 --- a/apps/web/src/features/workforce/directory/AddStaff.tsx +++ b/apps/web/src/features/workforce/directory/AddStaff.tsx @@ -1,14 +1,15 @@ -import { useState, useEffect } from "react"; +import { useState } from "react"; import { useNavigate } from "react-router-dom"; import { Button } from "@/common/components/ui/button"; import { Input } from "@/common/components/ui/input"; import { Label } from "@/common/components/ui/label"; -import { ArrowLeft, Loader2, Save, Mail, Phone, User, Award, ShieldAlert } from "lucide-react"; +import { ArrowLeft, Loader2, Save, Mail, Phone, User, Award } from "lucide-react"; import DashboardLayout from "@/features/layouts/DashboardLayout"; -import { useCreateStaff, useGetUserById } from "@/dataconnect-generated/react"; -import { dataConnect, auth } from "@/features/auth/firebase"; +import { useCreateStaff } from "@/dataconnect-generated/react"; +import { dataConnect } from "@/features/auth/firebase"; import { useForm, Controller } from "react-hook-form"; import { Checkbox } from "@/common/components/ui/checkbox"; +import { BackgroundCheckStatus } from "@/dataconnect-generated"; const COMMON_SKILLS = [ "Barista", @@ -30,15 +31,6 @@ interface AddStaffFormData { export default function AddStaff() { const navigate = useNavigate(); const [isSubmitting, setIsSubmitting] = useState(false); - - // Get current user and their role from DataConnect - const currentUser = auth.currentUser; - const { data: userData, isLoading: isUserLoading } = useGetUserById( - dataConnect, - { id: currentUser?.uid || "" }, - { enabled: !!currentUser } - ); - const { mutateAsync: createStaff } = useCreateStaff(dataConnect); const { register, handleSubmit, control, formState: { errors } } = useForm({ @@ -51,22 +43,7 @@ export default function AddStaff() { } }); - // Check for admin role - const isAdmin = userData?.user?.userRole?.toLowerCase() === 'admin'; - - useEffect(() => { - if (!isUserLoading && !isAdmin && currentUser) { - // Small delay to allow user to see why they are being redirected if needed, - // but usually immediate is better for security - const timer = setTimeout(() => { - navigate("/staff"); - }, 2000); - return () => clearTimeout(timer); - } - }, [isAdmin, isUserLoading, navigate, currentUser]); - const onSubmit = async (data: AddStaffFormData) => { - if (!isAdmin) return; setIsSubmitting(true); try { await createStaff({ @@ -75,7 +52,7 @@ export default function AddStaff() { email: data.email, phone: data.phone, skills: data.skills, - backgroundCheckStatus: "PENDING", + backgroundCheckStatus: BackgroundCheckStatus.PENDING, initial: `${data.firstName.charAt(0)}${data.lastName.charAt(0)}`.toUpperCase(), }); navigate("/staff"); @@ -86,39 +63,6 @@ export default function AddStaff() { } }; - if (isUserLoading) { - return ( -
- -

VERIFYING PERMISSIONS...

-
- ); - } - - if (!isAdmin) { - return ( -
-
- -
-
-

Access Denied

-

- Only administrators can manually onboard new staff members. - You are being redirected to the staff directory. -

-
- -
- ); - } - return ( { - const checked = e.target.checked; + onCheckedChange={(checked) => { const updatedSkills = checked ? [...(field.value || []), skill] : field.value?.filter((s: string) => s !== skill); @@ -262,7 +205,6 @@ export default function AddStaff() {
- - + = ); } diff --git a/apps/web/src/features/workforce/directory/EditStaff.tsx b/apps/web/src/features/workforce/directory/EditStaff.tsx index 3a7ec507..2c4ff852 100644 --- a/apps/web/src/features/workforce/directory/EditStaff.tsx +++ b/apps/web/src/features/workforce/directory/EditStaff.tsx @@ -1,23 +1,30 @@ import { useState, useMemo } from "react"; import { useParams, useNavigate } from "react-router-dom"; +import { useSelector } from "react-redux"; +import type { RootState } from "@/store/store"; import { Button } from "@/common/components/ui/button"; -import { ArrowLeft, Loader2, Edit, Save, X, User, FileText, Briefcase, Shield } from "lucide-react"; +import { ArrowLeft, Loader2, Edit, Save, X, AlertCircle } from "lucide-react"; import StaffForm from "./components/StaffForm"; import DashboardLayout from "@/features/layouts/DashboardLayout"; -import { useGetStaffById, useUpdateStaff } from "@/dataconnect-generated/react"; +import { useGetStaffById, useUpdateStaff, useCreateActivityLog } from "@/dataconnect-generated/react"; import { dataConnect } from "@/features/auth/firebase"; import type { Staff } from "../type"; import { Badge } from "@/common/components/ui/badge"; +import { ActivityIconType, ActivityType } from "@/dataconnect-generated"; export default function EditStaff() { const { id } = useParams<{ id: string }>(); const navigate = useNavigate(); const [isEditing, setIsEditing] = useState(false); + const { user } = useSelector((state: RootState) => state.auth); const { data: staffData, isLoading, refetch } = useGetStaffById(dataConnect, { id: id || "" }); const { mutateAsync: updateStaff } = useUpdateStaff(dataConnect); + const { mutateAsync: createActivityLog } = useCreateActivityLog(dataConnect); const [isSubmitting, setIsSubmitting] = useState(false); + const isAdmin = user?.userRole === 'admin' || user?.userRole === 'ADMIN'; + const staff = useMemo(() => { if (!staffData?.staff) return null; const s = staffData.staff; @@ -48,7 +55,7 @@ export default function EditStaff() { }, [staffData]); const handleSubmit = async (staffData: Staff) => { - if (!id) return; + if (!id || !isAdmin) return; setIsSubmitting(true); try { await updateStaff({ @@ -69,6 +76,18 @@ export default function EditStaff() { city: staffData.city, addres: staffData.address, }); + + // Audit Log + await createActivityLog({ + userId: user?.uid || "system", + date: new Date().toISOString(), + title: "Staff Profile Updated", + description: `Administrator ${user?.displayName || user?.email} updated professional records for ${staffData.employee_name}`, + activityType: ActivityType.SYSTEM_UPDATE, + iconType: ActivityIconType.CHECK, + iconColor: "emerald", + }); + await refetch(); setIsEditing(false); } catch (error) { @@ -91,6 +110,27 @@ export default function EditStaff() { ); } + if (!isAdmin) { + return ( + +
+
+ +
+
+

Restricted Access

+

+ Only administrators are authorized to modify staff professional records. Please contact your system administrator if you believe this is an error. +

+
+ +
+
+ ); + } + return (