date-fns#formatISO TypeScript Examples
The following examples show how to use
date-fns#formatISO.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: date-picker-accepter.tsx From platyplus with MIT License | 6 votes |
DatePickerAccepter: React.ElementType<
DatePickerProps &
FormControlAccepterProps & { date?: boolean; time?: boolean }
> = ({
value,
defaultValue,
onChange,
date = true,
time = false,
...props
}) => {
const formatter = useCallback(
(v) => {
if (v == null) return null
return formatISO(v, {
representation: !time ? 'date' : !date ? 'time' : 'complete'
})
},
[date, time]
)
const internalValue = value == null ? null : parseISO(value)
return (
<DatePicker
oneTap
value={internalValue}
onChange={(dateValue, event) => onChange(formatter(dateValue), event)}
{...props}
/>
)
}
Example #2
Source File: Date.tsx From nextjs-netlify-blog-template with MIT License | 6 votes |
export default function Date({ date }: Props) {
return (
<time dateTime={formatISO(date)}>
<span>{format(date, "LLLL d, yyyy")}</span>
<style jsx>
{`
span {
color: #9b9b9b;
}
`}
</style>
</time>
);
}
Example #3
Source File: JsonLdMeta.tsx From nextjs-netlify-blog-template with MIT License | 6 votes |
export default function JsonLdMeta({
url,
title,
keywords,
date,
author,
image,
description,
}: Props) {
return (
<Head>
<script
{...jsonLdScriptProps<BlogPosting>({
"@context": "https://schema.org",
"@type": "BlogPosting",
mainEntityOfPage: config.base_url + url,
headline: title,
keywords: keywords ? undefined : keywords.join(","),
datePublished: formatISO(date),
author: author,
image: image,
description: description,
})}
/>
</Head>
);
}
Example #4
Source File: VideoForm.hooks.ts From atlas with GNU General Public License v3.0 | 5 votes |
useVideoFormDraft = (
watch: UseFormWatch<VideoWorkspaceVideoFormFields>,
dirtyFields: FieldNamesMarkedBoolean<VideoWorkspaceVideoFormFields>
) => {
const { activeChannelId } = useAuthorizedUser()
const { editedVideoInfo, setEditedVideo } = useVideoWorkspace()
const { updateDraft, addDraft } = useDraftStore((state) => state.actions)
// we pass the functions explicitly so the debounced function doesn't need to change when those functions change
const debouncedDraftSave = useRef(
debounce(
(
channelId: string,
tab: VideoWorkspace,
data: VideoWorkspaceVideoFormFields,
addDraftFn: typeof addDraft,
updateDraftFn: typeof updateDraft,
updateSelectedTabFn: typeof setEditedVideo
) => {
const draftData: RawDraft = {
...data,
channelId: activeChannelId,
type: 'video',
publishedBeforeJoystream: isDateValid(data.publishedBeforeJoystream)
? formatISO(data.publishedBeforeJoystream as Date)
: null,
}
if (tab.isNew) {
addDraftFn(draftData, tab.id)
updateSelectedTabFn({ ...tab, isNew: false })
} else {
updateDraftFn(tab.id, draftData)
}
},
700
)
)
// save draft on form fields update
useEffect(() => {
if (!editedVideoInfo?.isDraft) {
return
}
const subscription = watch((data) => {
if (!Object.keys(dirtyFields).length) {
return
}
debouncedDraftSave.current(activeChannelId, editedVideoInfo, data, addDraft, updateDraft, setEditedVideo)
})
return () => {
subscription.unsubscribe()
}
}, [addDraft, dirtyFields, editedVideoInfo, updateDraft, setEditedVideo, watch, activeChannelId])
const flushDraftSave = useCallback(() => {
debouncedDraftSave.current.flush()
}, [])
return { flushDraftSave }
}
Example #5
Source File: index.ts From integration-services with Apache License 2.0 | 5 votes |
getDateStringFromDate = (date: Date): string | null | undefined => {
return date && formatISO(date);
}
Example #6
Source File: CommentItem.test.tsx From knboard with MIT License | 5 votes |
comment: TaskComment = {
id: 1,
author: 1,
created: formatISO(new Date(2012, 8, 18, 19, 0, 52)),
modified: formatISO(new Date(2015, 9, 15, 20, 2, 53)),
task: 1,
text: "foobar",
}
Example #7
Source File: VideoForm.tsx From atlas with GNU General Public License v3.0 | 4 votes |
VideoForm: React.FC<VideoFormProps> = React.memo(({ onSubmit, setFormStatus }) => {
const [moreSettingsVisible, setMoreSettingsVisible] = useState(false)
const [cachedEditedVideoId, setCachedEditedVideoId] = useState('')
const [royaltiesFieldEnabled, setRoyaltiesFieldEnabled] = useState(false)
const mintNftFormFieldRef = useRef<HTMLDivElement>(null)
const { editedVideoInfo } = useVideoWorkspace()
const { tabData, loading: tabDataLoading, error: tabDataError } = useVideoWorkspaceData()
const {
chainState: { nftMaxCreatorRoyaltyPercentage, nftMinCreatorRoyaltyPercentage },
} = useJoystream()
const resolveAsset = useRawAssetResolver()
const deleteVideo = useDeleteVideo()
const isEdit = !editedVideoInfo?.isDraft
const isNew = !isEdit
const mintNft = editedVideoInfo?.mintNft
const { categories, error: categoriesError } = useCategories(undefined, {
onError: (error) => SentryLogger.error('Failed to fetch categories', 'VideoWorkspace', error),
})
const {
register,
control,
handleSubmit: createSubmitHandler,
getValues,
setValue,
watch,
trigger,
reset,
formState: { errors, dirtyFields, isDirty, touchedFields, isValid },
} = useForm<VideoWorkspaceVideoFormFields>({
shouldFocusError: true,
mode: 'onChange',
})
const videoFieldsLocked = tabData?.mintNft && isEdit
// manage assets used by the form
const {
handleVideoFileChange,
handleThumbnailFileChange,
videoHashPromise,
thumbnailHashPromise,
files,
mediaAsset,
thumbnailAsset,
hasUnsavedAssets,
} = useVideoFormAssets(watch, getValues, setValue, dirtyFields)
// manage draft saving
const { flushDraftSave } = useVideoFormDraft(watch, dirtyFields)
// reset form whenever edited video gets updated
useEffect(() => {
if (editedVideoInfo.id === cachedEditedVideoId || !tabData || tabDataLoading) {
return
}
setCachedEditedVideoId(editedVideoInfo.id)
reset(tabData)
}, [tabData, tabDataLoading, reset, mintNft, editedVideoInfo.id, cachedEditedVideoId, setValue])
// animate scroll to Mint an NFT switch and toggle it, if user selected it from video tile context menu
useEffect(() => {
if (!mintNft || !mintNftFormFieldRef.current || !tabData || getValues('mintNft') || touchedFields.mintNft) {
return
}
const scrollTimeout = setTimeout(
() => mintNftFormFieldRef.current?.scrollIntoView({ behavior: 'smooth', block: 'center' }),
SCROLL_TIMEOUT
)
const setMintNftTimeout = setTimeout(
() => setValue('mintNft', tabData.mintNft || mintNft, { shouldTouch: true }),
MINT_NFT_TIMEOUT
)
return () => {
clearTimeout(scrollTimeout)
clearTimeout(setMintNftTimeout)
}
}, [touchedFields, mintNft, setValue, tabData, getValues])
const handleSubmit = useCallback(() => {
flushDraftSave()
const handler = createSubmitHandler(async (data) => {
if (!editedVideoInfo) {
return
}
const { video: videoInputFile, thumbnail: thumbnailInputFile } = data.assets
const videoAsset = resolveAsset(videoInputFile.id)
const thumbnailAsset = resolveAsset(thumbnailInputFile.cropId)
if (isNew && (!videoAsset || !videoHashPromise)) {
ConsoleLogger.error('Video file cannot be empty')
return
}
if (isNew && (!thumbnailAsset || !thumbnailHashPromise)) {
ConsoleLogger.error('Thumbnail cannot be empty')
return
}
const license = {
code: data.licenseCode ?? undefined,
attribution: data.licenseAttribution ?? undefined,
customText: data.licenseCustomText ?? undefined,
}
const anyLicenseFieldsDirty =
dirtyFields.licenseCode || dirtyFields.licenseAttribution || dirtyFields.licenseCustomText
const metadata: VideoInputMetadata = {
...(isNew || dirtyFields.title ? { title: data.title } : {}),
...(isNew || dirtyFields.description ? { description: data.description } : {}),
...(isNew || dirtyFields.category ? { category: Number(data.category) } : {}),
...(isNew || dirtyFields.isPublic ? { isPublic: data.isPublic } : {}),
...((isNew || dirtyFields.hasMarketing) && data.hasMarketing != null
? { hasMarketing: data.hasMarketing }
: {}),
...((isNew || dirtyFields.isExplicit) && data.isExplicit != null ? { isExplicit: data.isExplicit } : {}),
...((isNew || dirtyFields.language) && data.language != null ? { language: data.language } : {}),
...(isNew || anyLicenseFieldsDirty ? { license } : {}),
...((isNew || dirtyFields.publishedBeforeJoystream) && data.publishedBeforeJoystream != null
? {
publishedBeforeJoystream: formatISO(data.publishedBeforeJoystream),
}
: {}),
...(isNew || dirtyFields.assets?.video
? {
mimeMediaType: videoInputFile?.mimeType,
}
: {}),
...(isNew || dirtyFields.assets?.video ? { duration: Math.round(videoInputFile?.duration || 0) } : {}),
...(isNew || dirtyFields.assets?.video ? { mediaPixelHeight: videoInputFile?.mediaPixelHeight } : {}),
...(isNew || dirtyFields.assets?.video ? { mediaPixelWidth: videoInputFile?.mediaPixelWidth } : {}),
}
const videoWidth = videoInputFile?.mediaPixelWidth
const videoHeight = videoInputFile?.mediaPixelHeight
const assets: VideoFormAssets = {
...(videoAsset?.blob && videoInputFile.id && videoHashPromise
? {
media: {
id: videoInputFile.id,
blob: videoAsset.blob,
url: videoAsset.url || undefined,
hashPromise: videoHashPromise,
dimensions: videoWidth && videoHeight ? { height: videoHeight, width: videoWidth } : undefined,
},
}
: {}),
...(thumbnailAsset?.blob && thumbnailInputFile.cropId && thumbnailInputFile.originalId && thumbnailHashPromise
? {
thumbnailPhoto: {
id: thumbnailInputFile.cropId,
originalId: thumbnailInputFile.originalId,
blob: thumbnailAsset.blob,
url: thumbnailAsset.url || undefined,
hashPromise: thumbnailHashPromise,
dimensions: thumbnailInputFile?.assetDimensions,
cropData: thumbnailInputFile?.imageCropData,
},
}
: {}),
}
const nftMetadata: NftIssuanceInputMetadata | undefined = data.mintNft
? {
royalty: data.nftRoyaltiesPercent || undefined,
}
: undefined
onSubmit({
metadata,
assets,
nftMetadata,
})
})
return handler()
}, [
createSubmitHandler,
dirtyFields,
editedVideoInfo,
flushDraftSave,
isNew,
onSubmit,
resolveAsset,
thumbnailHashPromise,
videoHashPromise,
])
const actionBarPrimaryText = watch('mintNft') ? 'Publish & mint' : !isEdit ? 'Publish & upload' : 'Publish changes'
const isFormValid = (isEdit || !!mediaAsset) && !!thumbnailAsset && isValid
const formStatus: VideoWorkspaceFormStatus = useMemo(
() => ({
hasUnsavedAssets,
isDirty,
isDisabled: isEdit ? isDirty || !!mintNft : isFormValid,
actionBarPrimaryText,
isValid: isFormValid,
triggerFormSubmit: handleSubmit,
triggerReset: reset,
}),
[actionBarPrimaryText, handleSubmit, hasUnsavedAssets, isDirty, isEdit, isFormValid, mintNft, reset]
)
// sent updates on form status to VideoWorkspace
useEffect(() => {
setFormStatus(formStatus)
}, [formStatus, setFormStatus])
const handleDeleteVideo = () => {
editedVideoInfo && deleteVideo(editedVideoInfo.id)
}
const categoriesSelectItems: SelectItem[] =
categories?.map((c) => ({
name: c.name || 'Unknown category',
value: c.id,
})) || []
const getHiddenSectionLabel = () => {
if (videoFieldsLocked) {
return `${moreSettingsVisible ? 'Hide' : 'Show'} non-editable fields`
}
return `Show ${moreSettingsVisible ? 'less' : 'more'} settings`
}
if (tabDataError || categoriesError) {
return <ViewErrorFallback />
}
const videoEditFields = (
<>
<DescriptionTextArea
{...register('description', textFieldValidation({ name: 'Description', maxLength: 5000 }))}
maxLength={5000}
placeholder="Description of the video to share with your audience"
error={!!errors.description}
helperText={errors.description?.message}
disabled={videoFieldsLocked}
/>
<FormField title="Video category">
<Controller
name="category"
control={control}
rules={requiredValidation('Video category')}
render={({ field: { value, onChange, ref } }) => (
<Select
containerRef={ref}
value={value}
items={categoriesSelectItems}
onChange={onChange}
error={!!errors.category && !value}
helperText={errors.category?.message}
disabled={videoFieldsLocked}
/>
)}
/>
</FormField>
<FormField title="Video language">
<Controller
name="language"
control={control}
rules={requiredValidation('Video language')}
render={({ field: { value, onChange } }) => (
<Select
value={value}
items={languages}
onChange={onChange}
error={!!errors.language && !value}
helperText={errors.language?.message}
disabled={videoFieldsLocked}
/>
)}
/>
</FormField>
<ExtendedMarginFormField title="Video visibility">
<Controller
name="isPublic"
control={control}
defaultValue={true}
rules={{
validate: (value) => value !== null,
}}
render={({ field: { value, onChange } }) => (
<RadioCardButtonsContainer>
<OptionCardRadio
value="true"
label="Public"
onChange={() => onChange(true)}
selectedValue={value?.toString()}
helperText="Visible to all"
disabled={videoFieldsLocked}
/>
<OptionCardRadio
value="false"
label="Unlisted"
onChange={() => onChange(false)}
selectedValue={value?.toString()}
helperText="Visible with link only"
disabled={videoFieldsLocked}
/>
</RadioCardButtonsContainer>
)}
/>
</ExtendedMarginFormField>
</>
)
return (
<FormWrapper as="form" onSubmit={handleSubmit}>
<Controller
name="assets"
control={control}
render={() => (
// don't remove this div
// without this element position sticky won't work
<div>
<StyledMultiFileSelect
files={files}
onVideoChange={handleVideoFileChange}
onThumbnailChange={handleThumbnailFileChange}
editMode={isEdit}
disabled={videoFieldsLocked}
maxVideoSize={10 * 1024 * 1024 * 1024}
/>
</div>
)}
/>
<InputsContainer>
<Controller
name="title"
control={control}
rules={textFieldValidation({ name: 'Video Title', minLength: 3, maxLength: 60, required: true })}
render={({ field: { value, onChange } }) => (
<StyledTitleArea
onChange={onChange}
value={value}
min={3}
max={60}
placeholder="Video title"
disabled={videoFieldsLocked}
/>
)}
/>
{!videoFieldsLocked && videoEditFields}
<SwitchFormField title="Mint NFT" ref={mintNftFormFieldRef}>
<SwitchNftWrapper>
<Controller
name="mintNft"
control={control}
defaultValue={false}
render={({ field: { value, onChange } }) => (
<Switch
label="Mint NFT for this video"
value={value}
onChange={(e) => {
if (!e?.currentTarget.checked) {
trigger()
setRoyaltiesFieldEnabled(false)
setValue('nftRoyaltiesPercent', undefined)
}
onChange(e)
}}
disabled={videoFieldsLocked}
/>
)}
/>
<Information
placement="top"
arrowDisabled
text="Minting an NFT creates a record of ownership on the blockchain that can be put on sale. This will not impact your intellectual rights of the video."
/>
</SwitchNftWrapper>
{watch('mintNft') && (
<>
<Banner
id="issuing-nft"
dismissable={false}
icon={<StyledSvgWarning width={24} height={24} />}
description={
!videoFieldsLocked ? (
<Text variant="t200">
You <YellowText>won’t be able to edit this video</YellowText> once you mint an NFT for it.
</Text>
) : (
<Text variant="t200">
Many fields are disabled after minting an NFT for this video -
<VideoLink to={absoluteRoutes.viewer.video(editedVideoInfo.id)}>
go to it's video page.
</VideoLink>
</Text>
)
}
/>
<FormField
switchProps={{
value: videoFieldsLocked ? !!watch('nftRoyaltiesPercent') : royaltiesFieldEnabled,
onChange: (e) => {
if (e?.currentTarget.checked) {
setValue('nftRoyaltiesPercent', 1)
} else {
setValue('nftRoyaltiesPercent', undefined, { shouldValidate: true })
trigger()
}
setRoyaltiesFieldEnabled(!!e?.currentTarget.checked)
},
disabled: videoFieldsLocked,
}}
title="Set creator's royalties"
infoTooltip={{ text: 'Setting royalties lets you earn commission from every sale of this NFT.' }}
>
<TextField
type="number"
{...register('nftRoyaltiesPercent', {
valueAsNumber: true,
min: {
value: nftMinCreatorRoyaltyPercentage,
message: `Creator royalties cannot be lower than ${nftMinCreatorRoyaltyPercentage}%`,
},
max: {
value: nftMaxCreatorRoyaltyPercentage,
message: `Creator royalties cannot be higher than ${nftMaxCreatorRoyaltyPercentage}%`,
},
})}
error={!!errors.nftRoyaltiesPercent}
placeholder="—"
helperText={errors.nftRoyaltiesPercent?.message}
nodeEnd={<Pill variant="default" label="%" />}
disabled={videoFieldsLocked || !royaltiesFieldEnabled}
/>
</FormField>
</>
)}
</SwitchFormField>
<MoreSettingsHeader>
<Button
size="large"
iconPlacement="right"
textOnly
icon={moreSettingsVisible ? <SvgActionChevronT /> : <SvgActionChevronB />}
onClick={() => setMoreSettingsVisible(!moreSettingsVisible)}
>
{getHiddenSectionLabel()}
</Button>
<MoreSettingsDescription as="p" variant="t200" secondary visible={!moreSettingsVisible}>
{!videoFieldsLocked
? `License, content rating, published before, marketing${isEdit ? ', delete video' : ''}`
: 'Description, video category, video language, video visibility, licence, content rating, published before, marketing'}
</MoreSettingsDescription>
</MoreSettingsHeader>
<MoreSettingsSection expanded={moreSettingsVisible}>
{videoFieldsLocked && videoEditFields}
<FormField title="License">
<Controller
name="licenseCode"
control={control}
rules={requiredValidation('License')}
render={({ field: { value, onChange, ref } }) => (
<Select
containerRef={ref}
value={value}
items={knownLicensesOptions}
placeholder="Choose license type"
onChange={onChange}
error={!!errors.licenseCode && !value}
helperText={errors.licenseCode?.message}
disabled={videoFieldsLocked}
/>
)}
/>
</FormField>
{knownLicenses.find((license) => license.code === watch('licenseCode'))?.attributionRequired && (
<FormField title="License attribution" optional>
<TextField
{...register(
'licenseAttribution',
textFieldValidation({ name: 'License attribution', maxLength: 5000 })
)}
placeholder="Type your attribution here"
error={!!errors.licenseAttribution}
helperText={errors.licenseAttribution?.message}
disabled={videoFieldsLocked}
/>
</FormField>
)}
{watch('licenseCode') === CUSTOM_LICENSE_CODE && (
<FormField title="Custom license">
<TextArea
{...register(
'licenseCustomText',
textFieldValidation({ name: 'License', maxLength: 5000, required: false })
)}
maxLength={5000}
placeholder="Type your license content here"
error={!!errors.licenseCustomText}
helperText={errors.licenseCustomText?.message}
/>
</FormField>
)}
<ExtendedMarginFormField
title="Content rating"
description="If the content you are publishing contains explicit material (sex, violence, etc.), please mark it as mature."
>
<Controller
name="isExplicit"
control={control}
defaultValue={false}
rules={{
validate: (value) => value !== null,
}}
render={({ field: { value, onChange, ref } }) => (
<RadioButtonsContainer>
<RadioButton
ref={ref}
value="false"
label="All audiences"
onChange={() => onChange(false)}
selectedValue={value?.toString()}
error={!!errors.isExplicit}
helperText={errors.isExplicit ? 'Content rating must be selected' : ''}
disabled={videoFieldsLocked}
/>
<RadioButton
value="true"
label="Mature"
onChange={() => onChange(true)}
selectedValue={value?.toString()}
error={!!errors.isExplicit}
helperText={errors.isExplicit ? 'Content rating must be selected' : ''}
disabled={videoFieldsLocked}
/>
</RadioButtonsContainer>
)}
/>
</ExtendedMarginFormField>
<ExtendedMarginFormField
title="Prior publication"
optional
description="If the content you are publishing was originally published outside of Joystream, please provide the original publication date."
>
<Controller
name="publishedBeforeJoystream"
control={control}
rules={{
validate: (value) => pastDateValidation(value),
}}
render={({ field: { value, onChange } }) => (
<Datepicker
value={value}
onChange={onChange}
error={!!errors.publishedBeforeJoystream}
helperText={errors.publishedBeforeJoystream ? 'Please provide a valid date.' : ''}
disabled={videoFieldsLocked}
/>
)}
/>
</ExtendedMarginFormField>
<FormField title="Marketing" optional>
<Controller
name="hasMarketing"
control={control}
render={({ field: { value, onChange } }) => (
<Checkbox
value={value ?? false}
label="My video features a paid promotion material"
onChange={onChange}
disabled={videoFieldsLocked}
/>
)}
/>
</FormField>
{isEdit && !videoFieldsLocked && (
<DeleteVideoButton fullWidth size="large" variant="destructive-secondary" onClick={handleDeleteVideo}>
Delete video
</DeleteVideoButton>
)}
</MoreSettingsSection>
</InputsContainer>
</FormWrapper>
)
})