1+ import {
2+ format ,
3+ formatDuration ,
4+ intervalToDuration ,
5+ isSameDay ,
6+ type FormatDistanceToken ,
7+ } from 'date-fns' ;
18import { and , eq } from 'drizzle-orm' ;
29import { ImageResponse } from 'next/og' ;
310import { UTDClubsLogoStandalone } from '@src/icons/UTDClubsLogo' ;
@@ -9,48 +16,62 @@ export const alt = 'Event Details';
916export const size = { width : 1200 , height : 630 } ;
1017export const contentType = 'image/png' ;
1118
12- function formatEventDate ( startTime : Date , endTime : Date ) : string {
13- const dateOptions : Intl . DateTimeFormatOptions = {
14- weekday : 'short' ,
15- month : 'short' ,
16- day : 'numeric' ,
17- } ;
18- const timeOptions : Intl . DateTimeFormatOptions = {
19- hour : 'numeric' ,
20- minute : '2-digit' ,
21- hour12 : true ,
22- } ;
19+ const distanceTokenUnits : Partial < Record < FormatDistanceToken , string > > = {
20+ xSeconds : 's' ,
21+ xMinutes : 'm' ,
22+ xHours : 'h' ,
23+ xDays : 'd' ,
24+ xMonths : 'mo' ,
25+ xYears : 'y' ,
26+ } ;
2327
24- const startDate = startTime . toLocaleDateString ( 'en-US' , dateOptions ) ;
25- const startTimeStr = startTime . toLocaleTimeString ( 'en-US' , timeOptions ) ;
26- const endTimeStr = endTime . toLocaleTimeString ( 'en-US' , timeOptions ) ;
28+ function formatEventDate ( startTime : Date , endTime : Date ) : string {
29+ const dateStr = format ( startTime , 'EEE, LLLL d, yyyy @ h:mm a' ) ;
2730
28- const sameDay = startTime . toDateString ( ) === endTime . toDateString ( ) ;
29- if ( sameDay ) {
30- return `${ startDate } , ${ startTimeStr } - ${ endTimeStr } ` ;
31+ if ( startTime . getTime ( ) === endTime . getTime ( ) ) {
32+ return dateStr ;
3133 }
32- const endDate = endTime . toLocaleDateString ( 'en-US' , dateOptions ) ;
33- return `${ startDate } , ${ startTimeStr } - ${ endDate } , ${ endTimeStr } ` ;
34- }
3534
36- export default async function Image ( { params } : { params : { id : string } } ) {
37- const id = ( await params ) . id ;
38-
39- const eventData = await db . query . events . findFirst ( {
40- where : ( events ) => and ( eq ( events . id , id ) , eq ( events . status , 'approved' ) ) ,
41- with : {
42- club : {
43- columns : { name : true , profileImage : true , updatedAt : true } ,
35+ const duration = formatDuration (
36+ intervalToDuration ( { start : startTime , end : endTime } ) ,
37+ {
38+ locale : {
39+ formatDistance : ( token , count ) =>
40+ `${ count } ${ distanceTokenUnits [ token ] ?? '' } ` ,
4441 } ,
4542 } ,
46- } ) ;
43+ ) ;
44+
45+ const endStr = isSameDay ( startTime , endTime )
46+ ? format ( endTime , 'h:mm a' )
47+ : format ( endTime , 'EEE, LLLL d, yyyy @ h:mm a' ) ;
48+
49+ return `${ dateStr } · ${ duration } (till ${ endStr } )` ;
50+ }
4751
48- const gradientBuffer = await fetch (
49- new URL ( '../../../../public/images/landingGradient.png' , import . meta. url ) ,
50- ) . then ( ( res ) => res . arrayBuffer ( ) ) ;
52+ export default async function Image ( { params } : { params : { id : string } } ) {
53+ const { id } = await params ;
5154
52- const baiJamjureeBuffer = await loadGoogleFont ( 'Bai Jamjuree' , 700 ) ;
53- const interBuffer = await loadGoogleFont ( 'Inter' , 600 ) ;
55+ const [ eventData , gradientBuffer , baiJamjureeBuffer , interBuffer ] =
56+ await Promise . all ( [
57+ db . query . events . findFirst ( {
58+ where : ( events ) =>
59+ and ( eq ( events . id , id ) , eq ( events . status , 'approved' ) ) ,
60+ with : {
61+ club : {
62+ columns : { name : true , profileImage : true , updatedAt : true } ,
63+ } ,
64+ } ,
65+ } ) ,
66+ fetch (
67+ new URL (
68+ '../../../../public/images/landingGradient.png' ,
69+ import . meta. url ,
70+ ) ,
71+ ) . then ( ( res ) => res . arrayBuffer ( ) ) ,
72+ loadGoogleFont ( 'Bai Jamjuree' , 700 ) ,
73+ loadGoogleFont ( 'Inter' , 600 ) ,
74+ ] ) ;
5475
5576 const background = (
5677 < img
@@ -194,7 +215,6 @@ export default async function Image({ params }: { params: { id: string } }) {
194215 fontSize : '22px' ,
195216 margin : '0 0 16px 0' ,
196217 textShadow : '0 0 4px rgba(0,0,0,0.4)' ,
197- opacity : 0.9 ,
198218 maxWidth : hasImage ? '55%' : '90%' ,
199219 textAlign : hasImage ? 'left' : 'center' ,
200220 } }
@@ -271,8 +291,8 @@ export default async function Image({ params }: { params: { id: string } }) {
271291 display : 'flex' ,
272292 alignItems : 'center' ,
273293 justifyContent : 'center' ,
274- width : 36 ,
275- height : 36 ,
294+ width : 40 ,
295+ height : 40 ,
276296 } }
277297 >
278298 < UTDClubsLogoStandalone
0 commit comments