import { Button, Flex, Form, Input, Modal } from "antd"; import HeaderBar from "core/components/Header"; import MyBanner from "shared/components/MyBanner"; import { SaveOutlined } from "@ant-design/icons"; import MyUpload from "shared/components/MyUpload"; import { Constants } from "core/utils/utils"; import ColorPicker from "antd/es/color-picker"; import { useGetOrganizationSettingsQuery, useIsSubdomainAvailableMutation, useUpdateOrganizationSettingsMutation, useUpdateSubdomainMutation, } from "core/services/organization"; import MyErrorResult from "shared/components/MyResult"; import { useForm } from "antd/es/form/Form"; import { useEffect, useRef, useState } from "react"; import { AggregationColor } from "antd/es/color-picker/color"; import { useDispatch, useSelector } from "react-redux"; import { bannerUrl, logoUrl, setBannerUrl, setLogoUrl, setPrimaryColor, } from "core/reducers/appSlice"; import MyMiddleCard from "shared/components/MyMiddleCard"; import { OrganizationSettings } from "core/types/organization"; import { useMessage } from "core/context/MessageContext"; import { addWebSocketReconnectListener, removeWebSocketReconnectListener, } from "core/services/websocketService"; import { useTranslation } from "react-i18next"; type GeneralFieldType = { primaryColor: string | AggregationColor; companyName: string; }; export default function Settings() { const { t } = useTranslation(); const { data, error, isLoading, refetch } = useGetOrganizationSettingsQuery( undefined, { refetchOnMountOrArgChange: true, } ); useEffect(() => { addWebSocketReconnectListener(refetch); return () => removeWebSocketReconnectListener(refetch); }, []); if (error) return ; return ( <> } /> ); } function GeneralCard({ data, isLoading, }: { data?: OrganizationSettings; isLoading?: boolean } = {}) { const { t } = useTranslation(); const [form] = useForm(); const { success, error: errorMessage } = useMessage(); const dispatch = useDispatch(); const debounceRef = useRef(null); const currentPrimaryColor = useRef(); const [updateOrganizationSettings, { isLoading: isUpdateSettingsLoading }] = useUpdateOrganizationSettingsMutation(); const handleSave = async (values: GeneralFieldType) => { const hexColor = typeof values.primaryColor === "string" ? values.primaryColor : values.primaryColor.toHexString().split("#")[1]; try { await updateOrganizationSettings({ primaryColor: hexColor, companyName: values.companyName, }).unwrap(); currentPrimaryColor.current = hexColor; success( t("organizationSettings.generalCard.messageSettingsSuccessfullyUpdated") ); } catch (error) { console.error(error); errorMessage(t("common.messageRequestFailed")); } }; useEffect(() => { if (data) { form.setFieldsValue({ primaryColor: data.PrimaryColor, companyName: data.CompanyName, }); currentPrimaryColor.current = data.PrimaryColor; } }, [data]); useEffect(() => { return () => { dispatch(setPrimaryColor(currentPrimaryColor.current)); if (debounceRef.current) { clearTimeout(debounceRef.current); } }; }, []); return (
} type="text" shape="circle" size="large" htmlType="submit" loading={isUpdateSettingsLoading} /> } > name="primaryColor" label={t("organizationSettings.generalCard.primaryColor")} > { if (debounceRef.current) { clearTimeout(debounceRef.current); } debounceRef.current = setTimeout(() => { dispatch(setPrimaryColor(color.toHexString().split("#")[1])); }, 600); }} /> name="companyName" label={t("organizationSettings.generalCard.companyName")} >
); } function MediaCard({ isLoading, }: { data?: OrganizationSettings; isLoading?: boolean } = {}) { const { t } = useTranslation(); const { success } = useMessage(); const dispatch = useDispatch(); const appLogoUrl = useSelector(logoUrl); const appBannerUrl = useSelector(bannerUrl); return (
{ if (info.file.status === "done" && info.file.response.Data) { dispatch(setLogoUrl(info.file.response.Data)); success( t( "organizationSettings.mediaCard.messageLogoSuccessfullyUpdated" ) ); } }} imgCropProps={{ aspect: 1 / 1, children: <>, }} > {t("organizationSettings.mediaCard.logo")} { if (info.file.status === "done" && info.file.response.Data) { dispatch(setBannerUrl(info.file.response.Data)); success( t( "organizationSettings.mediaCard.messageBannerSuccessfullyUpdated" ) ); } }} imgCropProps={{ aspect: 22 / 9, children: <>, }} > {t("organizationSettings.mediaCard.banner")}
); } const subdomainPattern = /^[a-zA-Z0-9-]+$/; function SubdomainCard({ data, isLoading, }: { data?: OrganizationSettings; isLoading?: boolean } = {}) { const { t } = useTranslation(); const [form] = useForm(); const { success, info } = useMessage(); const [isModalOpen, setIsModalOpen] = useState(false); const [reqIsSubdomainAvailable] = useIsSubdomainAvailableMutation(); const [reqUpdateSubdomain] = useUpdateSubdomainMutation(); const validateSubdomain = async (rule: any, value: string) => { if (value) { if ( value.length < Constants.GLOBALS.MIN_SUBDOMAIN_LENGTH || value.length > Constants.GLOBALS.MAX_SUBDOMAIN_LENGTH || !subdomainPattern.test(value) ) { return Promise.reject(); } // Check if subdomain is current subdomain if (value === window.location.hostname.split(".")[0]) { return Promise.resolve(); } try { const { data } = await reqIsSubdomainAvailable(value); if (!data.Available) { return Promise.reject( t("organizationSettings.subdomainCard.subdomainAlreadyTaken") ); } return Promise.resolve(); } catch (error) { return Promise.reject( t("organizationSettings.subdomainCard.subdomainAlreadyTaken") ); } } return Promise.resolve(); }; useEffect(() => { if (data) { form.setFieldsValue({ subdomain: data.Subdomain, }); } }, [data]); return ( <> setIsModalOpen(false)} okText={t("common.change")} onOk={async () => { try { await reqUpdateSubdomain(form.getFieldValue("subdomain")); success( t( "organizationSettings.subdomainCard.modalChangeSubdomain.messageSubdomainSuccessfullyUpdated" ) ); info( t( "organizationSettings.subdomainCard.modalChangeSubdomain.messageRedirect" ) ); /* window.location.href = `https://${form.getFieldValue( "subdomain" )}.${window.location.hostname.split(".").slice(1).join(".")}`; */ } catch (error) { console.error(error); } }} >

{t("organizationSettings.subdomainCard.modalChangeSubdomain.message")}

} type="text" shape="circle" size="large" onClick={() => { form .validateFields() .then(() => setIsModalOpen(true)) .catch(() => {}); }} /> } >
); }