import React, { useEffect, useState } from "react"; import { useAuth } from "@/shared/context/AuthContext"; import { usePositionConfigurationByPositionId } from "@/shared/hooks/usePositionConfigurations"; import { usePositions } from "@/user-management/hooks/usePosition"; import { useUnit } from "@/user-management/hooks/useUnit"; import { Card, CardContent } from "@/shared/common/ui/card"; import { Button } from "@/shared/common/ui/button"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/shared/common/ui/select"; import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage, } from "@/shared/common/ui/form"; import { Switch } from "@/shared/common/ui/switch"; import { Alert, AlertDescription } from "@/shared/common/ui/alert"; import { useForm } from "react-hook-form"; import { zodResolver } from "@hookform/resolvers/zod"; import * as z from "zod"; import { Settings, Mail, MessageSquare, Bell, Workflow, Loader2, AlertCircle, Save, } from "lucide-react"; import { PositionConfiguration, PositionConfigurationPayload, } from "@/shared/services/positionConfigurationService"; import { useLocalizedName } from "@/shared/common/localizedName"; import { t } from "i18next"; export enum PositionScopeToFetch { PARALLEL_WITH_IMMEDIATE_CHILD = "parallel_with_immediate_child", IMMEDIATE_CHILD = "immediate_child", ALL = "all", } export const positionScopeValues = [ PositionScopeToFetch.ALL, PositionScopeToFetch.IMMEDIATE_CHILD, PositionScopeToFetch.PARALLEL_WITH_IMMEDIATE_CHILD, ] as const; const configurationSchema = z.object({ positionId: z.string().min(1, "Position is required"), smsNotificationWhenRecordSubmitted: z.boolean(), emailNotificationWhenRecordSubmitted: z.boolean(), inboxNotificationWhenRecordSubmitted: z.boolean(), skipWorkflowIfNotAssigned: z.boolean(), positionScopeToFetch: z.enum(positionScopeValues), }); type ConfigurationFormData = z.infer; const defaultFormValues: ConfigurationFormData = { positionId: "", smsNotificationWhenRecordSubmitted: true, emailNotificationWhenRecordSubmitted: true, inboxNotificationWhenRecordSubmitted: true, skipWorkflowIfNotAssigned: false, positionScopeToFetch: PositionScopeToFetch.ALL, }; const parsePositionScope = ( config: PositionConfiguration | null, ): PositionScopeToFetch => { if ( config?.positionScopeToFetch && positionScopeValues.includes(config.positionScopeToFetch as PositionScopeToFetch) ) { return config.positionScopeToFetch as PositionScopeToFetch; } if (!config?.items?.data) return PositionScopeToFetch.ALL; try { const parsed = JSON.parse(config.items.data) as { positionScopeToFetch?: PositionScopeToFetch; }; if ( parsed.positionScopeToFetch && positionScopeValues.includes(parsed.positionScopeToFetch) ) { return parsed.positionScopeToFetch; } } catch { return PositionScopeToFetch.ALL; } return PositionScopeToFetch.ALL; }; const buildPayload = ( data: ConfigurationFormData, ): PositionConfigurationPayload => ({ positionId: data.positionId, smsNotificationWhenRecordSubmitted: data.smsNotificationWhenRecordSubmitted, emailNotificationWhenRecordSubmitted: data.emailNotificationWhenRecordSubmitted, inboxNotificationWhenRecordSubmitted: data.inboxNotificationWhenRecordSubmitted, skipWorkflowIfNotAssigned: data.skipWorkflowIfNotAssigned, positionScopeToFetch: data.positionScopeToFetch, }); const PositionConfigurationPage = () => { const { user } = useAuth(); const defaultUnitId = user?.employee?.[0]?.unitId || ""; const organizationId = user?.employee?.[0]?.organizationId || ""; const localizedName = useLocalizedName(); const [selectedUnitId, setSelectedUnitId] = useState(defaultUnitId); const [selectedPositionId, setSelectedPositionId] = useState(""); const { configuration, isLoading: isLoadingConfig, isError: isConfigError, error: configError, saveConfiguration, isSaving, refetch, } = usePositionConfigurationByPositionId(selectedPositionId); const { getList: getUnitList } = useUnit(); const { data: units, isLoading: isLoadingUnits } = getUnitList( organizationId, { take: 1000 }, ); const { usePositionListByUnitId } = usePositions(); const { data: positions, isLoading: isLoadingPositions } = usePositionListByUnitId(selectedUnitId, { take: 1000 }); const form = useForm({ resolver: zodResolver(configurationSchema), defaultValues: defaultFormValues, }); useEffect(() => { if (defaultUnitId && !selectedUnitId) { setSelectedUnitId(defaultUnitId); } }, [defaultUnitId, selectedUnitId]); useEffect(() => { setSelectedPositionId(""); }, [selectedUnitId]); useEffect(() => { if (!selectedPositionId) { form.reset(defaultFormValues); return; } if (isLoadingConfig) return; if (configuration) { form.reset({ positionId: selectedPositionId, smsNotificationWhenRecordSubmitted: configuration.smsNotificationWhenRecordSubmitted, emailNotificationWhenRecordSubmitted: configuration.emailNotificationWhenRecordSubmitted, inboxNotificationWhenRecordSubmitted: configuration.inboxNotificationWhenRecordSubmitted, skipWorkflowIfNotAssigned: configuration.skipWorkflowIfNotAssigned, positionScopeToFetch: parsePositionScope(configuration), }); return; } form.reset({ ...defaultFormValues, positionId: selectedPositionId, }); }, [selectedPositionId, configuration, isLoadingConfig, form]); const handleSave = (data: ConfigurationFormData) => { saveConfiguration(buildPayload(data), { onSuccess: () => { refetch(); }, }); }; if (!organizationId) { return (
{t("setting.msg1")}
); } return (

{t("setting.positionConfig")}

{t("setting.positionConfigMsg")}

{!selectedPositionId ? (

{t( "setting.selectPositionToConfigure", "Select a unit and position to load configuration.", )}

) : isLoadingConfig ? (

{t("setting.msg2")}

) : ( <> {isConfigError && ( {t("setting.error")}{" "} {configError instanceof Error ? configError.message : "Unknown error"} )}
( {t("setting.positionScope")} )} />

{t("setting.notification")}

(
{t("setting.sms")}
{t("setting.smsMsg")}
)} /> (
{t("setting.email")}
{t("setting.emailMsg")}
)} /> (
{t("setting.inbox")}
{t("setting.inboxMsg")}
)} />

{t("setting.workflow")}

(
{t("setting.workflowMsg")}
{t("setting.workflowMsg1")}
)} />
)}
); }; export default PositionConfigurationPage;