Tweak date/time positioning in photo details
This commit is contained in:
parent
ec1985d311
commit
3c367f68b9
@ -1,20 +1,30 @@
|
||||
import { formatDate } from '@/utility/date';
|
||||
import { clsx } from 'clsx/lite';
|
||||
|
||||
export default function ResponsiveDate({
|
||||
date,
|
||||
className,
|
||||
}: {
|
||||
date: Date
|
||||
className?: string
|
||||
}) {
|
||||
return (
|
||||
<>
|
||||
{/* Mobile */}
|
||||
<span className="inline-block sm:hidden">
|
||||
{formatDate(date, true)}
|
||||
<span
|
||||
title={formatDate(date).toLocaleUpperCase()}
|
||||
className={clsx(className, 'uppercase')}
|
||||
>
|
||||
{/* Small */}
|
||||
<span className="xs:hidden">
|
||||
{formatDate(date, 'short')}
|
||||
</span>
|
||||
{/* Desktop */}
|
||||
{/* Medium */}
|
||||
<span className="hidden xs:inline-block sm:hidden">
|
||||
{formatDate(date, 'medium')}
|
||||
</span>
|
||||
{/* Large */}
|
||||
<span className="hidden sm:inline-block">
|
||||
{formatDate(date)}
|
||||
</span>
|
||||
</>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
@ -21,6 +21,8 @@ export default function ShareButton({
|
||||
className={clsx(
|
||||
className,
|
||||
dim ? 'text-dim' : 'text-medium',
|
||||
'-mx-0.5 translate-x-0.5',
|
||||
'sm:mx-0 sm:translate-x-0',
|
||||
)}
|
||||
icon={<TbPhotoShare size={17} />}
|
||||
spinnerColor="dim"
|
||||
|
||||
@ -4,14 +4,16 @@ import { useMemo } from 'react';
|
||||
|
||||
export default function PhotoDate({
|
||||
photo: { takenAtNaive },
|
||||
className,
|
||||
}: {
|
||||
photo: Photo
|
||||
className?: string
|
||||
}) {
|
||||
const date = useMemo(() => {
|
||||
const date = new Date(takenAtNaive);
|
||||
return isNaN(date.getTime()) ? new Date() : date;
|
||||
}, [takenAtNaive]);
|
||||
return (
|
||||
<ResponsiveDate {...{ date }} />
|
||||
<ResponsiveDate {...{ date, className }} />
|
||||
);
|
||||
}
|
||||
|
||||
@ -25,6 +25,7 @@ import AdminPhotoMenuClient from '@/admin/AdminPhotoMenuClient';
|
||||
import { RevalidatePhoto } from './InfinitePhotoScroll';
|
||||
import { useRef } from 'react';
|
||||
import useOnVisible from '@/utility/useOnVisible';
|
||||
import PhotoDate from './PhotoDate';
|
||||
|
||||
export default function PhotoLarge({
|
||||
photo,
|
||||
@ -161,14 +162,13 @@ export default function PhotoLarge({
|
||||
/>}
|
||||
</>}
|
||||
<div className={clsx(
|
||||
'flex gap-x-1.5 gap-y-baseline',
|
||||
'flex gap-x-2 gap-y-baseline',
|
||||
'md:flex-col md:justify-normal',
|
||||
)}>
|
||||
<div className={clsx(
|
||||
'text-medium uppercase pr-1',
|
||||
)}>
|
||||
{photo.takenAtNaiveFormatted}
|
||||
</div>
|
||||
<PhotoDate
|
||||
photo={photo}
|
||||
className="text-medium"
|
||||
/>
|
||||
<ShareButton
|
||||
className={clsx(
|
||||
'md:translate-x-[-2.5px]',
|
||||
|
||||
@ -235,11 +235,11 @@ export const dateRangeForPhotos = (
|
||||
const photosSorted = sortPhotosByDate(photos);
|
||||
start = formatDateFromPostgresString(
|
||||
explicitDateRange?.start ?? photosSorted[photos.length - 1].takenAtNaive,
|
||||
true,
|
||||
'short',
|
||||
);
|
||||
end = formatDateFromPostgresString(
|
||||
explicitDateRange?.end ?? photosSorted[0].takenAtNaive,
|
||||
true
|
||||
'short',
|
||||
);
|
||||
description = start === end
|
||||
? start
|
||||
|
||||
@ -1,16 +1,27 @@
|
||||
import { format, parseISO, parse } from 'date-fns';
|
||||
|
||||
const DATE_STRING_FORMAT_SHORT = 'dd MMM yyyy';
|
||||
const DATE_STRING_FORMAT_MEDIUM = 'dd MMM yy h:mma';
|
||||
const DATE_STRING_FORMAT = 'dd MMM yyyy h:mma';
|
||||
const DATE_STRING_FORMAT_POSTGRES = 'yyyy-MM-dd HH:mm:ss';
|
||||
|
||||
type AmbiguousTimestamp = number | string;
|
||||
|
||||
export const formatDate = (date: Date, short?: boolean) =>
|
||||
format(date, short ? DATE_STRING_FORMAT_SHORT : DATE_STRING_FORMAT);
|
||||
type Length = 'short' | 'medium' | 'long';
|
||||
|
||||
export const formatDateFromPostgresString = (date: string, short?: boolean) =>
|
||||
formatDate(parse(date, DATE_STRING_FORMAT_POSTGRES, new Date()), short);
|
||||
export const formatDate = (date: Date, length: Length = 'long') => {
|
||||
switch (length) {
|
||||
case 'short':
|
||||
return format(date, DATE_STRING_FORMAT_SHORT);
|
||||
case 'medium':
|
||||
return format(date, DATE_STRING_FORMAT_MEDIUM);
|
||||
default:
|
||||
return format(date, DATE_STRING_FORMAT);
|
||||
}
|
||||
};
|
||||
|
||||
export const formatDateFromPostgresString = (date: string, length?: Length) =>
|
||||
formatDate(parse(date, DATE_STRING_FORMAT_POSTGRES, new Date()), length);
|
||||
|
||||
export const formatDateForPostgres = (date: Date) =>
|
||||
date.toISOString().replace(
|
||||
|
||||
Loading…
Reference in New Issue
Block a user