Optimize tag page layout

This commit is contained in:
Sam Becker 2023-09-14 20:43:53 -05:00
parent 9f01ddbff7
commit 4a7ea83e80
5 changed files with 35 additions and 9 deletions

View File

@ -8,6 +8,7 @@ import {
pageTitleForTag, pageTitleForTag,
} from '@/tag'; } from '@/tag';
import PhotoTag from '@/tag/PhotoTag'; import PhotoTag from '@/tag/PhotoTag';
import { cc } from '@/utility/css';
import { Metadata } from 'next'; import { Metadata } from 'next';
interface TagProps { interface TagProps {
@ -35,14 +36,32 @@ export async function generateMetadata({
export default async function TagPage({ params: { tag } }: TagProps) { export default async function TagPage({ params: { tag } }: TagProps) {
const photos = await getPhotos(undefined, undefined, undefined, tag); const photos = await getPhotos(undefined, undefined, undefined, tag);
const dateStart = photos[0].takenAtNaiveFormattedShort;
const dateEnd = photos[photos.length - 1].takenAtNaiveFormattedShort;
return ( return (
<SiteGrid <SiteGrid
contentMain={<div className="space-y-8 mt-4"> contentMain={<div className="space-y-8 mt-4">
<div className="flex items-center gap-2"> <div className={cc(
'flex gap-2 sm:gap-0',
'sm:grid sm:grid-cols-4 md:grid-cols-3 lg:grid-cols-4',
)}>
<PhotoTag tag={tag} /> <PhotoTag tag={tag} />
<span className="uppercase text-gray-400 dark:text-gray-500"> <span className={cc(
'uppercase text-gray-300 dark:text-gray-500',
'col-span-2 md:col-span-1 lg:col-span-2',
)}>
{descriptionForTaggedPhotos(photos)} {descriptionForTaggedPhotos(photos)}
</span> </span>
<span className={cc(
'hidden sm:inline-block',
'text-right uppercase',
'text-gray-400 dark:text-gray-500',
)}>
{dateStart === dateEnd
? dateStart
: <>{dateStart}<br /> {dateEnd}</>}
</span>
</div> </div>
<PhotoGrid photos={photos} /> <PhotoGrid photos={photos} />
</div>} </div>}

View File

@ -64,6 +64,7 @@ export interface Photo extends PhotoDb {
exposureTimeFormatted?: string exposureTimeFormatted?: string
exposureCompensationFormatted?: string exposureCompensationFormatted?: string
takenAtNaiveFormatted?: string takenAtNaiveFormatted?: string
takenAtNaiveFormattedShort?: string
} }
export const parsePhotoFromDb = (photoDbRaw: PhotoDb): Photo => { export const parsePhotoFromDb = (photoDbRaw: PhotoDb): Photo => {
@ -89,6 +90,8 @@ export const parsePhotoFromDb = (photoDbRaw: PhotoDb): Photo => {
formatExposureCompensation(photoDb.exposureCompensation), formatExposureCompensation(photoDb.exposureCompensation),
takenAtNaiveFormatted: takenAtNaiveFormatted:
formatDateFromPostgresString(photoDb.takenAtNaive), formatDateFromPostgresString(photoDb.takenAtNaive),
takenAtNaiveFormattedShort:
formatDateFromPostgresString(photoDb.takenAtNaive, true),
}; };
}; };

View File

@ -166,7 +166,7 @@ const sqlGetPhotosFromDbByTag = (
) => ) =>
sql<PhotoDb>` sql<PhotoDb>`
SELECT * FROM photos WHERE ${tag}=ANY(tags) SELECT * FROM photos WHERE ${tag}=ANY(tags)
ORDER BY taken_at DESC ORDER BY taken_at ASC
LIMIT ${limit} OFFSET ${offset} LIMIT ${limit} OFFSET ${offset}
` `
.then(({ rows }) => rows.map(parsePhotoFromDb)); .then(({ rows }) => rows.map(parsePhotoFromDb));

View File

@ -11,12 +11,15 @@ export default function PhotoTag({
<Link <Link
key={tag} key={tag}
href={pathForTag(tag)} href={pathForTag(tag)}
className="flex items-center gap-x-2" className="flex items-center gap-x-1.5 self-start"
> >
<FaTag
size={11}
className="text-gray-700 dark:text-gray-300 translate-y-[0.5px]"
/>
<span className="uppercase"> <span className="uppercase">
{tag.replaceAll('-', ' ')} {tag.replaceAll('-', ' ')}
</span> </span>
<FaTag size={11} />
</Link> </Link>
); );
} }

View File

@ -1,13 +1,14 @@
import { format, parseISO, parse } from 'date-fns'; import { format, parseISO, parse } from 'date-fns';
const DATE_STRING_FORMAT_SHORT = 'dd MMM yyyy';
const DATE_STRING_FORMAT = 'd MMM yyyy h:mma'; const DATE_STRING_FORMAT = 'd MMM yyyy h:mma';
const DATE_STRING_FORMAT_POSTGRES = 'yyyy-MM-dd HH:mm:ss'; const DATE_STRING_FORMAT_POSTGRES = 'yyyy-MM-dd HH:mm:ss';
export const formatDate = (date: Date) => export const formatDate = (date: Date, short?: boolean) =>
format(date, DATE_STRING_FORMAT); format(date, short? DATE_STRING_FORMAT_SHORT : DATE_STRING_FORMAT);
export const formatDateFromPostgresString = (date: string) => export const formatDateFromPostgresString = (date: string, short?: boolean) =>
formatDate(parse(date, DATE_STRING_FORMAT_POSTGRES, new Date())); formatDate(parse(date, DATE_STRING_FORMAT_POSTGRES, new Date()), short);
export const formatDateForPostgres = (date: Date) => export const formatDateForPostgres = (date: Date) =>
date.toISOString().replace( date.toISOString().replace(