moved og:image outside of isReady scope so it renders on the server

This commit is contained in:
Peer Richelsen 2021-08-12 19:05:46 +02:00
parent d682804c5f
commit 99e003153e
3 changed files with 200 additions and 147 deletions

View file

@ -166,9 +166,9 @@ const DatePicker = ({
return selectedMonth ? ( return selectedMonth ? (
<div <div
className={ className={
"mt-8 sm:mt-0 sm:min-w-[480px] " + "mt-8 sm:mt-0 sm:min-w-[455px] " +
(selectedDate (selectedDate
? "w-full sm:min-w-[465px] sm:w-1/2 md:w-1/3 sm:border-r sm:dark:border-gray-800 sm:pl-4 sm:pr-6 " ? "w-full sm:w-1/2 md:w-1/3 sm:border-r sm:dark:border-gray-800 sm:pl-4 sm:pr-6 "
: "sm:w-1/2 sm:pl-4") : "sm:w-1/2 sm:pl-4")
}> }>
<div className="flex text-gray-600 font-light text-xl mb-4"> <div className="flex text-gray-600 font-light text-xl mb-4">

View file

@ -47,33 +47,83 @@ export default function User(props): User {
</div> </div>
)); ));
return ( return (
isReady && ( <>
<div className="bg-neutral-50 dark:bg-black h-screen"> <Head>
<Head> <title>{props.user.name || props.user.username} | Calendso</title>
<title>{props.user.name || props.user.username} | Calendso</title> <link rel="icon" href="/favicon.ico" />
<link rel="icon" href="/favicon.ico" />
</Head>
<main className="max-w-3xl mx-auto py-24 px-4"> <meta name="title" content={"Meet " + (props.user.name || props.user.username) + " via Calendso"} />
<div className="mb-8 text-center"> <meta name="description" content={"Book a time with " + (props.user.name || props.user.username)} />
<Avatar user={props.user} className="mx-auto w-24 h-24 rounded-full mb-4" />
<h1 className="text-3xl font-bold text-neutral-900 dark:text-white mb-1"> <meta property="og:type" content="website" />
{props.user.name || props.user.username} <meta property="og:url" content="https://calendso/" />
</h1> <meta
<p className="text-neutral-500 dark:text-white">{props.user.bio}</p> property="og:title"
</div> content={"Meet " + (props.user.name || props.user.username) + " via Calendso"}
<div className="space-y-6">{eventTypes}</div> />
{eventTypes.length == 0 && ( <meta
<div className="shadow overflow-hidden rounded-sm"> property="og:description"
<div className="p-8 text-center text-gray-400 dark:text-white"> content={"Book a time with " + (props.user.name || props.user.username)}
<h2 className="font-semibold text-3xl text-gray-600">Uh oh!</h2> />
<p className="max-w-md mx-auto">This user hasn&apos;t set up any event types yet.</p> <meta
</div> property="og:image"
content={
"https://og-image-one-pi.vercel.app/" +
encodeURIComponent("Meet **" + (props.user.name || props.user.username) + "** <br>").replace(
/'/g,
"%27"
) +
".png?md=1&images=https%3A%2F%2Fcalendso.com%2Fcalendso-logo-white.svg&images=" +
encodeURIComponent(props.user.avatar)
}
/>
<meta property="twitter:card" content="summary_large_image" />
<meta property="twitter:url" content="https://calendso/" />
<meta
property="twitter:title"
content={"Meet " + (props.user.name || props.user.username) + " via Calendso"}
/>
<meta
property="twitter:description"
content={"Book a time with " + (props.user.name || props.user.username)}
/>
<meta
property="twitter:image"
content={
"https://og-image-one-pi.vercel.app/" +
encodeURIComponent("Meet **" + (props.user.name || props.user.username) + "** <br>").replace(
/'/g,
"%27"
) +
".png?md=1&images=https%3A%2F%2Fcalendso.com%2Fcalendso-logo-white.svg&images=" +
encodeURIComponent(props.user.avatar)
}
/>
</Head>
{isReady && (
<div className="bg-neutral-50 dark:bg-black h-screen">
<main className="max-w-3xl mx-auto py-24 px-4">
<div className="mb-8 text-center">
<Avatar user={props.user} className="mx-auto w-24 h-24 rounded-full mb-4" />
<h1 className="text-3xl font-bold text-neutral-900 dark:text-white mb-1">
{props.user.name || props.user.username}
</h1>
<p className="text-neutral-500 dark:text-white">{props.user.bio}</p>
</div> </div>
)} <div className="space-y-6">{eventTypes}</div>
</main> {eventTypes.length == 0 && (
</div> <div className="shadow overflow-hidden rounded-sm">
) <div className="p-8 text-center text-gray-400 dark:text-white">
<h2 className="font-semibold text-3xl text-gray-600">Uh oh!</h2>
<p className="max-w-md mx-auto">This user hasn&apos;t set up any event types yet.</p>
</div>
</div>
)}
</main>
</div>
)}
</>
); );
} }

View file

@ -78,136 +78,139 @@ export default function Type(props): Type {
}; };
return ( return (
isReady && ( <>
<div> <Head>
<Head> <title>
<title> {rescheduleUid && "Reschedule"} {props.eventType.title} | {props.user.name || props.user.username} |
{rescheduleUid && "Reschedule"} {props.eventType.title} | {props.user.name || props.user.username}{" "} Calendso
| Calendso </title>
</title> <meta name="title" content={"Meet " + (props.user.name || props.user.username) + " via Calendso"} />
<meta name="title" content={"Meet " + (props.user.name || props.user.username) + " via Calendso"} /> <meta name="description" content={props.eventType.description} />
<meta name="description" content={props.eventType.description} />
<meta property="og:type" content="website" /> <meta property="og:type" content="website" />
<meta property="og:url" content="https://calendso/" /> <meta property="og:url" content="https://calendso/" />
<meta <meta
property="og:title" property="og:title"
content={"Meet " + (props.user.name || props.user.username) + " via Calendso"} content={"Meet " + (props.user.name || props.user.username) + " via Calendso"}
/> />
<meta property="og:description" content={props.eventType.description} /> <meta property="og:description" content={props.eventType.description} />
<meta <meta
property="og:image" property="og:image"
content={ content={
"https://og-image-one-pi.vercel.app/" + "https://og-image-one-pi.vercel.app/" +
encodeURIComponent( encodeURIComponent(
"Meet **" + (props.user.name || props.user.username) + "** <br>" + props.eventType.description "Meet **" + (props.user.name || props.user.username) + "** <br>" + props.eventType.description
).replace(/'/g, "%27") + ).replace(/'/g, "%27") +
".png?md=1&images=https%3A%2F%2Fcalendso.com%2Fcalendso-logo-white.svg&images=" + ".png?md=1&images=https%3A%2F%2Fcalendso.com%2Fcalendso-logo-white.svg&images=" +
encodeURIComponent(props.user.avatar) encodeURIComponent(props.user.avatar)
} }
/> />
<meta property="twitter:card" content="summary_large_image" /> <meta property="twitter:card" content="summary_large_image" />
<meta property="twitter:url" content="https://calendso/" /> <meta property="twitter:url" content="https://calendso/" />
<meta <meta
property="twitter:title" property="twitter:title"
content={"Meet " + (props.user.name || props.user.username) + " via Calendso"} content={"Meet " + (props.user.name || props.user.username) + " via Calendso"}
/> />
<meta property="twitter:description" content={props.eventType.description} /> <meta property="twitter:description" content={props.eventType.description} />
<meta <meta
property="twitter:image" property="twitter:image"
content={ content={
"https://og-image-one-pi.vercel.app/" + "https://og-image-one-pi.vercel.app/" +
encodeURIComponent( encodeURIComponent(
"Meet **" + (props.user.name || props.user.username) + "** <br>" + props.eventType.description "Meet **" + (props.user.name || props.user.username) + "** <br>" + props.eventType.description
).replace(/'/g, "%27") + ).replace(/'/g, "%27") +
".png?md=1&images=https%3A%2F%2Fcalendso.com%2Fcalendso-logo-white.svg&images=" + ".png?md=1&images=https%3A%2F%2Fcalendso.com%2Fcalendso-logo-white.svg&images=" +
encodeURIComponent(props.user.avatar) encodeURIComponent(props.user.avatar)
} }
/> />
</Head> </Head>
<main
className={ {isReady && (
"mx-auto my-0 md:my-24 transition-max-width ease-in-out duration-500 " + <div>
(selectedDate ? "max-w-5xl" : "max-w-3xl") <main
}> className={
<div className="sm:dark:border-gray-600 dark:bg-gray-900 bg-white md:border border-gray-200 rounded-sm"> "mx-auto my-0 md:my-24 transition-max-width ease-in-out duration-500 " +
{/* mobile: details */} (selectedDate ? "max-w-5xl" : "max-w-3xl")
<div className="p-4 sm:p-8 block md:hidden"> }>
<div className="flex items-center"> <div className="sm:dark:border-gray-600 dark:bg-gray-900 bg-white md:border border-gray-200 rounded-sm">
<Avatar user={props.user} className="inline-block h-9 w-9 rounded-full" /> {/* mobile: details */}
<div className="ml-3"> <div className="p-4 sm:p-8 block md:hidden">
<p className="text-sm font-medium dark:text-gray-300 text-black">{props.user.name}</p> <div className="flex items-center">
<div className="flex gap-2 text-xs font-medium text-gray-600"> <Avatar user={props.user} className="inline-block h-9 w-9 rounded-full" />
{props.eventType.title} <div className="ml-3">
<div> <p className="text-sm font-medium dark:text-gray-300 text-black">{props.user.name}</p>
<ClockIcon className="inline-block w-4 h-4 mr-1 -mt-1" /> <div className="flex gap-2 text-xs font-medium text-gray-600">
{props.eventType.length} minutes {props.eventType.title}
<div>
<ClockIcon className="inline-block w-4 h-4 mr-1 -mt-1" />
{props.eventType.length} minutes
</div>
</div> </div>
</div> </div>
</div> </div>
</div> <p className="dark:text-gray-200 text-gray-600 mt-3">{props.eventType.description}</p>
<p className="dark:text-gray-200 text-gray-600 mt-3">{props.eventType.description}</p>
</div>
<div className="sm:flex px-4 sm:py-5 sm:p-4">
<div
className={
"hidden md:block pr-8 sm:border-r sm:dark:border-gray-800 " +
(selectedDate ? "sm:w-1/3" : "sm:w-1/2")
}>
<Avatar user={props.user} className="w-16 h-16 rounded-full mb-4" />
<h2 className="font-medium dark:text-gray-300 text-gray-500">{props.user.name}</h2>
<h1 className="text-3xl font-semibold dark:text-white text-gray-800 mb-4">
{props.eventType.title}
</h1>
<p className="text-gray-500 mb-1 px-2 py-1 -ml-2">
<ClockIcon className="inline-block w-4 h-4 mr-1 -mt-1" />
{props.eventType.length} minutes
</p>
<TimezoneDropdown />
<p className="dark:text-gray-200 text-gray-600 mt-3 mb-8">{props.eventType.description}</p>
</div>
<DatePicker
date={selectedDate}
periodType={props.eventType?.periodType}
periodStartDate={props.eventType?.periodStartDate}
periodEndDate={props.eventType?.periodEndDate}
periodDays={props.eventType?.periodDays}
periodCountCalendarDays={props.eventType?.periodCountCalendarDays}
weekStart={props.user.weekStart}
onDatePicked={changeDate}
workingHours={props.workingHours}
organizerTimeZone={props.eventType.timeZone || props.user.timeZone}
inviteeTimeZone={timeZone()}
eventLength={props.eventType.length}
minimumBookingNotice={props.eventType.minimumBookingNotice}
/>
<div className="ml-1 mt-4 block sm:hidden">
<TimezoneDropdown />
</div> </div>
{selectedDate && ( <div className="sm:flex px-4 sm:py-5 sm:p-4">
<AvailableTimes <div
workingHours={props.workingHours} className={
timeFormat={timeFormat} "hidden md:block pr-8 sm:border-r sm:dark:border-gray-800 " +
organizerTimeZone={props.eventType.timeZone || props.user.timeZone} (selectedDate ? "sm:w-1/3" : "sm:w-1/2")
minimumBookingNotice={props.eventType.minimumBookingNotice} }>
eventTypeId={props.eventType.id} <Avatar user={props.user} className="w-16 h-16 rounded-full mb-4" />
eventLength={props.eventType.length} <h2 className="font-medium dark:text-gray-300 text-gray-500">{props.user.name}</h2>
<h1 className="text-3xl font-semibold dark:text-white text-gray-800 mb-4">
{props.eventType.title}
</h1>
<p className="text-gray-500 mb-1 px-2 py-1 -ml-2">
<ClockIcon className="inline-block w-4 h-4 mr-1 -mt-1" />
{props.eventType.length} minutes
</p>
<TimezoneDropdown />
<p className="dark:text-gray-200 text-gray-600 mt-3 mb-8">{props.eventType.description}</p>
</div>
<DatePicker
date={selectedDate} date={selectedDate}
user={props.user} periodType={props.eventType?.periodType}
periodStartDate={props.eventType?.periodStartDate}
periodEndDate={props.eventType?.periodEndDate}
periodDays={props.eventType?.periodDays}
periodCountCalendarDays={props.eventType?.periodCountCalendarDays}
weekStart={props.user.weekStart}
onDatePicked={changeDate}
workingHours={props.workingHours}
organizerTimeZone={props.eventType.timeZone || props.user.timeZone}
inviteeTimeZone={timeZone()}
eventLength={props.eventType.length}
minimumBookingNotice={props.eventType.minimumBookingNotice}
/> />
)}
<div className="ml-1 mt-4 block sm:hidden">
<TimezoneDropdown />
</div>
{selectedDate && (
<AvailableTimes
workingHours={props.workingHours}
timeFormat={timeFormat}
organizerTimeZone={props.eventType.timeZone || props.user.timeZone}
minimumBookingNotice={props.eventType.minimumBookingNotice}
eventTypeId={props.eventType.id}
eventLength={props.eventType.length}
date={selectedDate}
user={props.user}
/>
)}
</div>
</div> </div>
</div> {!props.user.hideBranding && <PoweredByCalendso />}
{!props.user.hideBranding && <PoweredByCalendso />} </main>
</main> </div>
</div> )}
) </>
); );
function TimezoneDropdown() { function TimezoneDropdown() {