moved og:image outside of isReady scope so it renders on the server
This commit is contained in:
parent
d682804c5f
commit
99e003153e
3 changed files with 200 additions and 147 deletions
|
@ -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">
|
||||||
|
|
100
pages/[user].tsx
100
pages/[user].tsx
|
@ -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'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't set up any event types yet.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</main>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
Loading…
Reference in a new issue