import { useMutation, useQuery } from "@apollo/client"; import { useEffect, useState } from "react"; import { Alert, Button, Card, Checkbox, Divider, Form, Space, Switch, Table, Typography } from "antd"; import { useTranslation } from "react-i18next"; import { connect } from "react-redux"; import { createStructuredSelector } from "reselect"; import { selectBodyshop, selectCurrentUser } from "../../redux/user/user.selectors"; import AlertComponent from "../alert/alert.component"; import { QUERY_NOTIFICATION_SETTINGS, UPDATE_NOTIFICATION_SETTINGS, UPDATE_NOTIFICATIONS_AUTOADD } from "../../graphql/user.queries.js"; import { notificationScenarios } from "../../utils/jobNotificationScenarios.js"; import LoadingSpinner from "../loading-spinner/loading-spinner.component.jsx"; import PropTypes from "prop-types"; import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; import ColumnHeaderCheckbox from "../notification-settings/column-header-checkbox.component.jsx"; import { useIsEmployee } from "../../utils/useIsEmployee.js"; /** * Notifications Settings Form * @param currentUser * @param bodyshop * @returns {JSX.Element} * @constructor */ const NotificationSettingsForm = ({ currentUser, bodyshop }) => { const { t } = useTranslation(); const [form] = Form.useForm(); const [initialValues, setInitialValues] = useState({}); const [isDirty, setIsDirty] = useState(false); const [autoAddEnabled, setAutoAddEnabled] = useState(false); const [initialAutoAdd, setInitialAutoAdd] = useState(false); const notification = useNotification(); const isEmployee = useIsEmployee(bodyshop, currentUser); // Fetch notification settings and notifications_autoadd const { loading, error, data } = useQuery(QUERY_NOTIFICATION_SETTINGS, { fetchPolicy: "network-only", nextFetchPolicy: "network-only", variables: { email: currentUser.email }, skip: !currentUser }); const [updateNotificationSettings, { loading: savingSettings }] = useMutation(UPDATE_NOTIFICATION_SETTINGS); const [updateNotificationsAutoAdd, { loading: savingAutoAdd }] = useMutation(UPDATE_NOTIFICATIONS_AUTOADD); // Populate form with fetched data useEffect(() => { if (data?.associations?.length > 0) { const settings = data.associations[0].notification_settings || {}; const autoAdd = data.associations[0].notifications_autoadd ?? false; // Ensure each scenario has an object with { app, email, fcm } const formattedValues = notificationScenarios.reduce((acc, scenario) => { acc[scenario] = settings[scenario] ?? { app: false, email: false, fcm: false }; return acc; }, {}); setInitialValues(formattedValues); form.setFieldsValue(formattedValues); setAutoAddEnabled(autoAdd); setInitialAutoAdd(autoAdd); setIsDirty(false); // Reset dirty state when new data loads } }, [data, form]); // Handle toggle of notifications_autoadd const handleAutoAddToggle = async (checked) => { if (data?.associations?.length > 0) { const userId = data.associations[0].id; try { const result = await updateNotificationsAutoAdd({ variables: { id: userId, autoadd: checked } }); if (!result?.errors) { setAutoAddEnabled(checked); setInitialAutoAdd(checked); notification.success({ message: t("notifications.labels.auto-add-success") }); setIsDirty(false); // Reset dirty state if only auto-add was changed } else { throw new Error("Failed to update auto-add setting"); } } catch (err) { setAutoAddEnabled(!checked); // Revert on error notification.error({ message: t("notifications.labels.auto-add-failure") }); } } }; // Handle save of notification settings const handleSave = async (values) => { if (data?.associations?.length > 0) { const userId = data.associations[0].id; try { const result = await updateNotificationSettings({ variables: { id: userId, ns: values } }); if (!result?.errors) { notification.success({ message: t("notifications.labels.notification-settings-success") }); setInitialValues(values); setIsDirty(false); } else { throw new Error("Failed to update notification settings"); } } catch (err) { notification.error({ message: t("notifications.labels.notification-settings-failure") }); } } }; // Mark the form as dirty on any manual change const handleFormChange = () => { setIsDirty(true); }; // Check if auto-add has changed const isAutoAddDirty = autoAddEnabled !== initialAutoAdd; // Handle reset of form and auto-add const handleReset = () => { form.setFieldsValue(initialValues); setAutoAddEnabled(initialAutoAdd); setIsDirty(false); }; if (error) return ; if (loading) return ; const columns = [ { title: t("notifications.labels.scenario"), dataIndex: "scenarioLabel", key: "scenario", render: (_, record) => t(`notifications.scenarios.${record.key}`), width: "90%" }, { title: setIsDirty(true)} />, dataIndex: "app", key: "app", align: "center", render: (_, record) => ( ) }, { title: setIsDirty(true)} />, dataIndex: "email", key: "email", align: "center", render: (_, record) => ( ) } // TODO: Disabled for now until FCM is implemented. // { // title: setIsDirty(true)} />, // dataIndex: "fcm", // key: "fcm", // align: "center", // render: (_, record) => ( // // // // ) // } ]; const dataSource = notificationScenarios.map((scenario) => ({ key: scenario })); return (
{t("notifications.labels.auto-add")} } > {!isEmployee && (
)} ); }; NotificationSettingsForm.propTypes = { currentUser: PropTypes.shape({ email: PropTypes.string.isRequired }).isRequired, bodyshop: PropTypes.object.isRequired }; const mapStateToProps = createStructuredSelector({ currentUser: selectCurrentUser, bodyshop: selectBodyshop }); export default connect(mapStateToProps)(NotificationSettingsForm);