import React, { type JSX, useCallback, useState } from 'react'; import { useAtomValue, useSetAtom } from 'jotai'; import { useTranslation } from 'react-i18next'; import ImageCropModal from '~/client/components/Common/ImageCropModal'; import { apiv3Delete, apiv3PostForm, apiv3Put, } from '~/client/util/apiv3-client'; import { toastError, toastSuccess } from '~/client/util/toastr'; import { useIsDefaultLogo } from '~/states/global'; import { isCustomizedLogoUploadedAtom } from '~/states/server-configurations'; import AdminUpdateButtonRow from '../Common/AdminUpdateButtonRow'; const DEFAULT_LOGO = '/images/logo.svg'; const CUSTOMIZED_LOGO = '/attachment/brand-logo'; const CustomizeLogoSetting = (): JSX.Element => { const { t } = useTranslation(); const isDefaultLogo = useIsDefaultLogo(); const isCustomizedLogoUploaded = useAtomValue(isCustomizedLogoUploadedAtom); const setIsCustomizedLogoUploaded = useSetAtom(isCustomizedLogoUploadedAtom); const [uploadLogoSrc, setUploadLogoSrc] = useState< ArrayBuffer | string | null >(null); const [isImageCropModalShow, setIsImageCropModalShow] = useState(false); const [isDefaultLogoSelected, setIsDefaultLogoSelected] = useState( isDefaultLogo ?? true, ); const [retrieveError, setRetrieveError] = useState(); const onSelectFile = useCallback((e: React.ChangeEvent) => { if (e.target.files != null && e.target.files.length > 0) { const reader = new FileReader(); reader.addEventListener('load', () => setUploadLogoSrc(reader.result)); reader.readAsDataURL(e.target.files[0]); setIsImageCropModalShow(true); } }, []); const onClickSubmit = useCallback(async () => { try { await apiv3Put('/customize-setting/customize-logo', { isDefaultLogo: isDefaultLogoSelected, }); toastSuccess( t('toaster.update_successed', { target: t('admin:customize_settings.custom_logo'), ns: 'commons', }), ); } catch (err) { toastError(err); } }, [t, isDefaultLogoSelected]); const onClickDeleteBtn = useCallback(async () => { try { await apiv3Delete('/customize-setting/delete-brand-logo'); setIsCustomizedLogoUploaded(false); toastSuccess( t('toaster.update_successed', { target: t('admin:customize_settings.current_logo'), ns: 'commons', }), ); } catch (err) { toastError(err); setRetrieveError(err); throw new Error('Failed to delete logo'); } }, [setIsCustomizedLogoUploaded, t]); const processImageCompletedHandler = useCallback( async (croppedImage) => { try { const formData = new FormData(); formData.append('file', croppedImage); await apiv3PostForm('/customize-setting/upload-brand-logo', formData); setIsCustomizedLogoUploaded(true); toastSuccess( t('toaster.update_successed', { target: t('admin:customize_settings.current_logo'), ns: 'commons', }), ); } catch (err) { toastError(err); setRetrieveError(err); throw new Error('Failed to upload brand logo'); } }, [setIsCustomizedLogoUploaded, t], ); return (

{t('admin:customize_settings.custom_logo')}

{ setIsDefaultLogoSelected(true); }} />

{ setIsDefaultLogoSelected(false); }} />

{isCustomizedLogoUploaded && ( <>

)}
setIsImageCropModalShow(false)} onImageProcessCompleted={processImageCompletedHandler} isCircular={false} showCropOption={false} />
); }; export default CustomizeLogoSetting;