import { FC, useState } from 'react'; import { InputType } from 'reactstrap/lib/Input'; import { Button, FormGroup, Input, Row } from 'reactstrap'; import { isEmpty } from 'ramda'; import * as m from 'moment'; import DateInput, { DateInputProps } from '../utils/DateInput'; import { supportsListingDomains, supportsSettingShortCodeLength, supportsShortUrlTitle, } from '../utils/helpers/features'; import { SimpleCard } from '../utils/SimpleCard'; import { handleEventPreventingDefault, hasValue } from '../utils/utils'; import Checkbox from '../utils/Checkbox'; import { SelectedServer } from '../servers/data'; import { TagsSelectorProps } from '../tags/helpers/TagsSelector'; import { Versions } from '../utils/helpers/version'; import { DomainSelectorProps } from '../domains/DomainSelector'; import { formatIsoDate } from '../utils/helpers/date'; import UseExistingIfFoundInfoIcon from './UseExistingIfFoundInfoIcon'; import { normalizeTag } from './CreateShortUrl'; import { ShortUrlData } from './data'; import './ShortUrlForm.scss'; type Mode = 'create' | 'create-basic' | 'edit'; type DateFields = 'validSince' | 'validUntil'; type NonDateFields = 'longUrl' | 'customSlug' | 'shortCodeLength' | 'domain' | 'maxVisits' | 'title'; export interface ShortUrlFormProps { mode: Mode; saving: boolean; initialState: ShortUrlData; onSave: (shortUrlData: ShortUrlData) => Promise; selectedServer: SelectedServer; } export const ShortUrlForm = ( TagsSelector: FC, ForServerVersion: FC, DomainSelector: FC, ): FC => ({ mode, saving, onSave, initialState, selectedServer, children }) => { // eslint-disable-line complexity const [ shortUrlData, setShortUrlData ] = useState(initialState); const changeTags = (tags: string[]) => setShortUrlData({ ...shortUrlData, tags: tags.map(normalizeTag) }); const reset = () => setShortUrlData(initialState); const submit = handleEventPreventingDefault(async () => onSave({ ...shortUrlData, validSince: formatIsoDate(shortUrlData.validSince) ?? undefined, validUntil: formatIsoDate(shortUrlData.validUntil) ?? undefined, }).then(reset).catch(() => {})); const renderOptionalInput = (id: NonDateFields, placeholder: string, type: InputType = 'text', props = {}) => ( setShortUrlData({ ...shortUrlData, [id]: e.target.value })} {...props} /> ); const renderDateInput = (id: DateFields, placeholder: string, props: Partial = {}) => (
setShortUrlData({ ...shortUrlData, [id]: date })} {...props} />
); const basicComponents = ( <> setShortUrlData({ ...shortUrlData, longUrl: e.target.value })} /> ); const showDomainSelector = supportsListingDomains(selectedServer); const disableShortCodeLength = !supportsSettingShortCodeLength(selectedServer); const supportsTitle = supportsShortUrlTitle(selectedServer); const isEdit = mode === 'edit'; return (
{mode === 'create-basic' && basicComponents} {mode !== 'create-basic' && ( <> {basicComponents}
{supportsTitle && renderOptionalInput('title', 'Title')} {!isEdit && ( <>
{renderOptionalInput('customSlug', 'Custom slug', 'text', { disabled: hasValue(shortUrlData.shortCodeLength), })}
{renderOptionalInput('shortCodeLength', 'Short code length', 'number', { min: 4, disabled: disableShortCodeLength || hasValue(shortUrlData.customSlug), ...disableShortCodeLength && { title: 'Shlink 2.1.0 or higher is required to be able to provide the short code length', }, })}
{!showDomainSelector && renderOptionalInput('domain', 'Domain', 'text')} {showDomainSelector && ( setShortUrlData({ ...shortUrlData, domain })} /> )} )}
{renderOptionalInput('maxVisits', 'Maximum number of visits allowed', 'number', { min: 1 })} {renderDateInput('validSince', 'Enabled since...', { maxDate: shortUrlData.validUntil as m.Moment | undefined })} {renderDateInput('validUntil', 'Enabled until...', { minDate: shortUrlData.validSince as m.Moment | undefined })}
{!isEdit && (

Make sure the long URL is valid, or ensure an existing short URL is returned if it matches all provided data.

)}

setShortUrlData({ ...shortUrlData, validateUrl })} > Validate URL

{!isEdit && (

setShortUrlData({ ...shortUrlData, findIfExists })} > Use existing URL if found

)}
)}
{children}
); };