import React, { FC, useState, useCallback } from 'react'; import { isInteger } from 'core-js/fn/number'; import { format, parse, addDays, set, } from 'date-fns'; import { useTranslation } from 'next-i18next'; import { apiv3Post } from '~/client/util/apiv3-client'; import { toastSuccess, toastError } from '~/client/util/toastr'; import { useCurrentPageId } from '~/stores/page'; const ExpirationType = { UNLIMITED: 'unlimited', CUSTOM: 'custom', NUMBER_OF_DAYS: 'numberOfDays', } as const; type ExpirationType = typeof ExpirationType[keyof typeof ExpirationType]; type Props = { onCloseForm: () => void, } export const ShareLinkForm: FC = (props: Props) => { const { t } = useTranslation(); const { onCloseForm } = props; const [expirationType, setExpirationType] = useState(ExpirationType.UNLIMITED); const [numberOfDays, setNumberOfDays] = useState(7); const [description, setDescription] = useState(''); const [customExpirationDate, setCustomExpirationDate] = useState(new Date()); const [customExpirationTime, setCustomExpirationTime] = useState(new Date()); const { data: currentPageId } = useCurrentPageId(); const handleChangeExpirationType = useCallback((expirationType: ExpirationType) => { setExpirationType(expirationType); }, []); const handleChangeNumberOfDays = useCallback((numberOfDays: number) => { setNumberOfDays(numberOfDays); }, []); const handleChangeDescription = useCallback((description: string) => { setDescription(description); }, []); const handleChangeCustomExpirationDate = useCallback((customExpirationDate: string) => { const parsedDate = parse(customExpirationDate, 'yyyy-MM-dd', new Date()); setCustomExpirationDate(parsedDate); }, []); const handleChangeCustomExpirationTime = useCallback((customExpirationTime: string) => { const parsedTime = parse(customExpirationTime, 'HH:mm', new Date()); setCustomExpirationTime(parsedTime); }, []); const generateExpired = useCallback(() => { if (expirationType === ExpirationType.UNLIMITED) { return null; } if (expirationType === ExpirationType.NUMBER_OF_DAYS) { if (!isInteger(Number(numberOfDays))) { throw new Error(t('share_links.Invalid_Number_of_Date')); } return addDays(new Date(), numberOfDays); } if (expirationType === ExpirationType.CUSTOM) { return set(customExpirationDate, { hours: customExpirationTime.getHours(), minutes: customExpirationTime.getMinutes() }); } }, [t, customExpirationTime, customExpirationDate, expirationType, numberOfDays]); const closeForm = useCallback(() => { if (onCloseForm == null) { return; } onCloseForm(); }, [onCloseForm]); const handleIssueShareLink = useCallback(async() => { let expiredAt; try { expiredAt = generateExpired(); } catch (err) { return toastError(err); } try { await apiv3Post('/share-links/', { relatedPage: currentPageId, expiredAt, description }); closeForm(); toastSuccess(t('toaster.issue_share_link')); } catch (err) { toastError(err); } }, [t, currentPageId, description, closeForm, generateExpired]); return (

{ t('share_links.share_settings') }

{/* ExpirationTypeOptions */}
{ handleChangeExpirationType(ExpirationType.UNLIMITED) }} />
{ handleChangeExpirationType(ExpirationType.NUMBER_OF_DAYS) }} name="expirationType" />
{ handleChangeExpirationType(ExpirationType.CUSTOM) }} />
{ handleChangeExpirationType(ExpirationType.CUSTOM) }} onChange={e => handleChangeCustomExpirationDate(e.target.value)} /> { handleChangeExpirationType(ExpirationType.CUSTOM) }} onChange={e => handleChangeCustomExpirationTime(e.target.value)} />
{/* DescriptionForm */}
handleChangeDescription(e.target.value)} />
); };