fix: ionspection add users and infractions

This commit is contained in:
2026-02-03 12:31:56 +03:30
parent 58ea683c1c
commit 67517e99c8
3 changed files with 113 additions and 32 deletions

View File

@@ -1,17 +1,103 @@
import Typography from "../../components/Typography/Typography";
import { Grid } from "../../components/Grid/Grid";
import { motion, AnimatePresence } from "framer-motion";
import {
ExclamationTriangleIcon,
DocumentTextIcon,
CheckCircleIcon,
} from "@heroicons/react/24/outline";
const containerVariants = {
hidden: { opacity: 0 },
visible: {
opacity: 1,
transition: { staggerChildren: 0.08, delayChildren: 0.05 },
},
exit: {
opacity: 0,
transition: { staggerChildren: 0.05, staggerDirection: -1 },
},
};
const itemVariants = {
hidden: { opacity: 0, y: 12 },
visible: { opacity: 1, y: 0 },
exit: { opacity: 0, y: -8 },
};
export const MainInfractions = ({
data,
handleUpdate,
handleUpdate: _handleUpdate,
}: {
data: any;
handleUpdate: () => void;
}) => {
console.log(data, handleUpdate);
const infractions = data?.infractions || [];
if (infractions.length === 0) {
return (
<Grid container column>
<Typography variant="body1">این بخش در دست توسعه است</Typography>
</Grid>
<motion.div
initial={{ opacity: 0, scale: 0.96 }}
animate={{ opacity: 1, scale: 1 }}
transition={{ duration: 0.3 }}
className="flex flex-col items-center justify-center py-12 px-6 rounded-xl bg-gray-50 dark:bg-gray-800/50 border border-gray-200 dark:border-gray-700"
>
<CheckCircleIcon className="w-14 h-14 text-emerald-500 dark:text-emerald-400 mb-4" />
<Typography
variant="body1"
className="text-gray-500 dark:text-gray-400 text-center"
>
تخلفی ثبت نشده است
</Typography>
</motion.div>
);
}
return (
<motion.div
variants={containerVariants}
initial="hidden"
animate="visible"
exit="exit"
className="flex flex-col gap-3"
>
<AnimatePresence mode="popLayout">
{infractions.map(
(
infraction: { _id: string; title: string; description?: string },
index: number,
) => (
<motion.div
key={infraction._id || index}
variants={itemVariants}
layout
className="group flex gap-4 p-4 rounded-xl border border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-800/80 hover:bg-gray-50 dark:hover:bg-gray-800 hover:border-red-200 dark:hover:border-red-900/50 shadow-sm hover:shadow-md transition-all duration-200"
>
<div className="flex-shrink-0 w-10 h-10 rounded-lg bg-red-100 dark:bg-red-900/30 flex items-center justify-center">
<ExclamationTriangleIcon className="w-5 h-5 text-red-600 dark:text-red-400" />
</div>
<div className="flex-1 min-w-0">
<Typography
variant="subtitle2"
className="font-semibold mb-1 text-gray-900 dark:text-gray-100"
>
{index + 1}. {infraction.title}
</Typography>
{infraction.description && (
<div className="flex items-start gap-2 mt-2">
<DocumentTextIcon className="w-4 h-4 text-gray-400 dark:text-gray-500 flex-shrink-0 mt-0.5" />
<Typography
variant="body2"
className="text-gray-600 dark:text-gray-400 leading-relaxed"
>
{infraction.description}
</Typography>
</div>
)}
</div>
</motion.div>
),
)}
</AnimatePresence>
</motion.div>
);
};

View File

@@ -119,7 +119,7 @@ const MainPlaceInfo: React.FC<MainPlaceInfoProps> = ({
const [personRegistryData, setPersonRegistryData] =
useState<PersonRegistryData | null>(null);
const [unitRegistryData, setUnitRegistryData] = useState<UnitRegistryData[]>(
[]
[],
);
const [isLoadingRegistry, setIsLoadingRegistry] = useState(false);
const { openDrawer } = useDrawerStore();
@@ -201,7 +201,7 @@ const MainPlaceInfo: React.FC<MainPlaceInfoProps> = ({
const unitsCandidate =
unitResult?.data ?? (Array.isArray(unitResult) ? unitResult : []);
setUnitRegistryData(
Array.isArray(unitsCandidate) ? unitsCandidate : []
Array.isArray(unitsCandidate) ? unitsCandidate : [],
);
} catch (error: any) {
console.error("Unit registry error:", error);
@@ -320,7 +320,6 @@ const MainPlaceInfo: React.FC<MainPlaceInfoProps> = ({
)}
</div>
{/* Submit Inspection Button */}
<div className="pt-2">
<Button
onClick={handleOpenInspection}

View File

@@ -93,30 +93,28 @@ const MainSubmitInspection: React.FC<MainSubmitInspectionProps> = ({
{ key: "عمده فروش", value: "عمده فروش" },
];
const usersList = Array.isArray(usersData)
? usersData
: ((usersData as any)?.data ?? []);
const inspectorOptions = useMemo(() => {
if (!usersData?.data) return [];
return usersData.data
.filter(
(user: any) =>
user.province === profile?.province &&
!user?.permissions?.includes("admin")
)
if (!usersList?.length) return [];
return usersList
.filter((user: any) => user.province === profile?.province)
.map((user: any) => ({
key: `${user.fullname} / ${user.mobile}`,
value: `${user.fullname} / ${user.mobile}`,
}));
}, [usersData, profile]);
}, [usersList, profile]);
const defaultInspectorKeys = useMemo(() => {
if (!isEdit || !item?.inspectors) return [];
return item.inspectors.map((insp: any) => {
if (typeof insp === "string") return insp;
const user = usersData?.data?.find(
(u: any) => u.fullname === insp.fullname
);
const user = usersList?.find((u: any) => u.fullname === insp.fullname);
return user ? `${insp.fullname} / ${user.mobile}` : insp.fullname;
});
}, [item, isEdit, usersData]);
}, [item, isEdit, usersList]);
const {
control,
@@ -150,17 +148,15 @@ const MainSubmitInspection: React.FC<MainSubmitInspectionProps> = ({
const watchedInfractions = watch("infractions");
useEffect(() => {
if (isEdit && item?.inspectors && usersData?.data) {
if (isEdit && item?.inspectors && usersList?.length) {
const inspectorStrings = item.inspectors.map((insp: any) => {
if (typeof insp === "string") return insp;
const user = usersData.data.find(
(u: any) => u.fullname === insp.fullname
);
const user = usersList.find((u: any) => u.fullname === insp.fullname);
return user ? `${insp.fullname} / ${user.mobile}` : insp.fullname;
});
setValue("inspectors", inspectorStrings);
}
}, [item, isEdit, usersData, setValue]);
}, [item, isEdit, usersList, setValue]);
const submitInspectionMutation = useApiMutation({
api: "inspections",