refactor: add next-seo (#531)
* refactor: add next-seo * refactor: change naming of seo component
This commit is contained in:
		
							parent
							
								
									fc50821282
								
							
						
					
					
						commit
						a37411b8af
					
				
					 33 changed files with 290 additions and 298 deletions
				
			
		|  | @ -3,7 +3,7 @@ import React, { Fragment, useEffect, useState } from "react"; | |||
| import { useRouter } from "next/router"; | ||||
| import { signOut, useSession } from "next-auth/client"; | ||||
| import { Menu, Transition } from "@headlessui/react"; | ||||
| import { collectPageParameters, telemetryEventTypes, useTelemetry } from "../lib/telemetry"; | ||||
| import { collectPageParameters, telemetryEventTypes, useTelemetry } from "@lib/telemetry"; | ||||
| import { SelectorIcon } from "@heroicons/react/outline"; | ||||
| import { | ||||
|   CalendarIcon, | ||||
|  | @ -20,6 +20,7 @@ import classNames from "@lib/classNames"; | |||
| import { Toaster } from "react-hot-toast"; | ||||
| import Avatar from "@components/Avatar"; | ||||
| import { User } from "@prisma/client"; | ||||
| import { HeadSeo } from "@components/seo/head-seo"; | ||||
| 
 | ||||
| export default function Shell(props) { | ||||
|   const router = useRouter(); | ||||
|  | @ -70,8 +71,18 @@ export default function Shell(props) { | |||
|     router.replace("/auth/login"); | ||||
|   } | ||||
| 
 | ||||
|   const pageTitle = typeof props.heading === "string" ? props.heading : props.title; | ||||
| 
 | ||||
|   return session ? ( | ||||
|     <> | ||||
|       <HeadSeo | ||||
|         title={pageTitle} | ||||
|         description={props.subtitle} | ||||
|         nextSeoProps={{ | ||||
|           nofollow: true, | ||||
|           noindex: true, | ||||
|         }} | ||||
|       /> | ||||
|       <div> | ||||
|         <Toaster position="bottom-right" /> | ||||
|       </div> | ||||
|  |  | |||
							
								
								
									
										101
									
								
								components/seo/head-seo.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										101
									
								
								components/seo/head-seo.tsx
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,101 @@ | |||
| import { NextSeo, NextSeoProps } from "next-seo"; | ||||
| import React from "react"; | ||||
| import { getBrowserInfo } from "@lib/core/browser/browser.utils"; | ||||
| import { getSeoImage, seoConfig } from "@lib/config/next-seo.config"; | ||||
| import merge from "lodash.merge"; | ||||
| 
 | ||||
| export type HeadSeoProps = { | ||||
|   title: string; | ||||
|   description: string; | ||||
|   siteName?: string; | ||||
|   name?: string; | ||||
|   avatar?: string; | ||||
|   url?: string; | ||||
|   canonical?: string; | ||||
|   nextSeoProps?: NextSeoProps; | ||||
| }; | ||||
| 
 | ||||
| /** | ||||
|  * Build full seo tags from title, desc, canonical and url | ||||
|  */ | ||||
| const buildSeoMeta = (pageProps: { | ||||
|   title: string; | ||||
|   description: string; | ||||
|   image: string; | ||||
|   siteName?: string; | ||||
|   url?: string; | ||||
|   canonical?: string; | ||||
| }): NextSeoProps => { | ||||
|   const { title, description, image, canonical, siteName = seoConfig.headSeo.siteName } = pageProps; | ||||
|   return { | ||||
|     title: title, | ||||
|     canonical: canonical, | ||||
|     openGraph: { | ||||
|       site_name: siteName, | ||||
|       type: "website", | ||||
|       title: title, | ||||
|       description: description, | ||||
|       images: [ | ||||
|         { | ||||
|           url: image, | ||||
|           //width: 1077,
 | ||||
|           //height: 565,
 | ||||
|           //alt: "Alt image"
 | ||||
|         }, | ||||
|       ], | ||||
|     }, | ||||
|     additionalMetaTags: [ | ||||
|       { | ||||
|         property: "name", | ||||
|         content: title, | ||||
|       }, | ||||
|       { | ||||
|         property: "description", | ||||
|         content: description, | ||||
|       }, | ||||
|       { | ||||
|         name: "description", | ||||
|         content: description, | ||||
|       }, | ||||
|       { | ||||
|         property: "image", | ||||
|         content: image, | ||||
|       }, | ||||
|     ], | ||||
|   }; | ||||
| }; | ||||
| 
 | ||||
| const constructImage = (name: string, avatar: string, description: string): string => { | ||||
|   return ( | ||||
|     encodeURIComponent("Meet **" + name + "** <br>" + description).replace(/'/g, "%27") + | ||||
|     ".png?md=1&images=https%3A%2F%2Fcalendso.com%2Fcalendso-logo-white.svg&images=" + | ||||
|     encodeURIComponent(avatar) | ||||
|   ); | ||||
| }; | ||||
| 
 | ||||
| export const HeadSeo: React.FC<HeadSeoProps & { children?: never }> = (props) => { | ||||
|   const defaultUrl = getBrowserInfo()?.url; | ||||
|   const image = getSeoImage("default"); | ||||
| 
 | ||||
|   const { | ||||
|     title, | ||||
|     description, | ||||
|     name = null, | ||||
|     avatar = null, | ||||
|     siteName, | ||||
|     canonical = defaultUrl, | ||||
|     nextSeoProps = {}, | ||||
|   } = props; | ||||
| 
 | ||||
|   const pageTitle = title + " | Calendso"; | ||||
|   let seoObject = buildSeoMeta({ title: pageTitle, image, description, canonical, siteName }); | ||||
| 
 | ||||
|   if (name && avatar) { | ||||
|     const pageImage = getSeoImage("ogImage") + constructImage(name, avatar, description); | ||||
|     seoObject = buildSeoMeta({ title: pageTitle, description, image: pageImage, canonical, siteName }); | ||||
|   } | ||||
| 
 | ||||
|   const seoProps: NextSeoProps = merge(nextSeoProps, seoObject); | ||||
| 
 | ||||
|   return <NextSeo {...seoProps} />; | ||||
| }; | ||||
							
								
								
									
										27
									
								
								lib/config/next-seo.config.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								lib/config/next-seo.config.ts
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,27 @@ | |||
| import { DefaultSeoProps } from "next-seo"; | ||||
| import { HeadSeoProps } from "@components/seo/head-seo"; | ||||
| 
 | ||||
| const seoImages = { | ||||
|   default: "https://calendso.com/og-image.png", | ||||
|   ogImage: "https://og-image-one-pi.vercel.app/", | ||||
| }; | ||||
| 
 | ||||
| export const getSeoImage = (key: keyof typeof seoImages): string => { | ||||
|   return seoImages[key]; | ||||
| }; | ||||
| 
 | ||||
| export const seoConfig: { | ||||
|   headSeo: Required<Pick<HeadSeoProps, "siteName">>; | ||||
|   defaultNextSeo: DefaultSeoProps; | ||||
| } = { | ||||
|   headSeo: { | ||||
|     siteName: "Calendso", | ||||
|   }, | ||||
|   defaultNextSeo: { | ||||
|     twitter: { | ||||
|       handle: "@calendso", | ||||
|       site: "@Calendso", | ||||
|       cardType: "summary_large_image", | ||||
|     }, | ||||
|   }, | ||||
| } as const; | ||||
							
								
								
									
										22
									
								
								lib/core/browser/browser.utils.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								lib/core/browser/browser.utils.ts
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,22 @@ | |||
| export const isBrowser = () => typeof window !== "undefined"; | ||||
| 
 | ||||
| type BrowserInfo = { | ||||
|   url: string; | ||||
|   path: string; | ||||
|   referrer: string; | ||||
|   title: string; | ||||
|   query: string; | ||||
| }; | ||||
| 
 | ||||
| export const getBrowserInfo = (): Partial<BrowserInfo> => { | ||||
|   if (!isBrowser()) { | ||||
|     return {}; | ||||
|   } | ||||
|   return { | ||||
|     url: window.document.location?.href ?? undefined, | ||||
|     path: window.document.location?.pathname ?? undefined, | ||||
|     referrer: window.document?.referrer ?? undefined, | ||||
|     title: window.document.title ?? undefined, | ||||
|     query: window.document.location?.search, | ||||
|   }; | ||||
| }; | ||||
|  | @ -42,6 +42,7 @@ | |||
|     "lodash.throttle": "^4.1.1", | ||||
|     "next": "^10.2.3", | ||||
|     "next-auth": "^3.28.0", | ||||
|     "next-seo": "^4.26.0", | ||||
|     "next-transpile-modules": "^8.0.0", | ||||
|     "nodemailer": "^6.6.3", | ||||
|     "react": "17.0.2", | ||||
|  |  | |||
|  | @ -3,7 +3,7 @@ import { BookOpenIcon, CheckIcon, CodeIcon, DocumentTextIcon } from "@heroicons/ | |||
| import { useRouter } from "next/router"; | ||||
| import React from "react"; | ||||
| import Link from "next/link"; | ||||
| import Head from "next/head"; | ||||
| import { HeadSeo } from "@components/seo/head-seo"; | ||||
| 
 | ||||
| const links = [ | ||||
|   { | ||||
|  | @ -32,9 +32,14 @@ export default function Custom404() { | |||
| 
 | ||||
|   return ( | ||||
|     <> | ||||
|       <Head> | ||||
|         <title>404: This page could not be found.</title> | ||||
|       </Head> | ||||
|       <HeadSeo | ||||
|         title="404: This page could not be found." | ||||
|         description="404: This page could not be found." | ||||
|         nextSeoProps={{ | ||||
|           nofollow: true, | ||||
|           noindex: true, | ||||
|         }} | ||||
|       /> | ||||
|       <div className="bg-white min-h-screen px-4"> | ||||
|         <main className="max-w-xl mx-auto pb-6 pt-16 sm:pt-24"> | ||||
|           <div className="text-center"> | ||||
|  |  | |||
|  | @ -1,5 +1,5 @@ | |||
| import { GetServerSideProps } from "next"; | ||||
| import Head from "next/head"; | ||||
| import { HeadSeo } from "@components/seo/head-seo"; | ||||
| import Link from "next/link"; | ||||
| import prisma, { whereAndSelect } from "@lib/prisma"; | ||||
| import Avatar from "@components/Avatar"; | ||||
|  | @ -48,59 +48,12 @@ export default function User(props): User { | |||
|   )); | ||||
|   return ( | ||||
|     <> | ||||
|       <Head> | ||||
|         <title>{props.user.name || props.user.username} | Calendso</title> | ||||
|         <link rel="icon" href="/favicon.ico" /> | ||||
| 
 | ||||
|         <meta name="title" content={"Meet " + (props.user.name || props.user.username) + " via Calendso"} /> | ||||
|         <meta name="description" content={"Book a time with " + (props.user.name || props.user.username)} /> | ||||
| 
 | ||||
|         <meta property="og:type" content="website" /> | ||||
|         <meta property="og:url" content="https://calendso/" /> | ||||
|         <meta | ||||
|           property="og:title" | ||||
|           content={"Meet " + (props.user.name || props.user.username) + " via Calendso"} | ||||
|       <HeadSeo | ||||
|         title={props.user.name || props.user.username} | ||||
|         description={props.user.name || props.user.username} | ||||
|         name={props.user.name || props.user.username} | ||||
|         avatar={props.user.avatar} | ||||
|       /> | ||||
|         <meta | ||||
|           property="og:description" | ||||
|           content={"Book a time with " + (props.user.name || props.user.username)} | ||||
|         /> | ||||
|         <meta | ||||
|           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"> | ||||
|  |  | |||
|  | @ -6,16 +6,16 @@ import prisma from "@lib/prisma"; | |||
| import * as Collapsible from "@radix-ui/react-collapsible"; | ||||
| import dayjs, { Dayjs } from "dayjs"; | ||||
| import { GetServerSidePropsContext, InferGetServerSidePropsType } from "next"; | ||||
| import Head from "next/head"; | ||||
| import { HeadSeo } from "@components/seo/head-seo"; | ||||
| import { useRouter } from "next/router"; | ||||
| import { useEffect, useState } from "react"; | ||||
| import Avatar from "@components/Avatar"; | ||||
| import AvailableTimes from "../../components/booking/AvailableTimes"; | ||||
| import DatePicker from "../../components/booking/DatePicker"; | ||||
| import TimeOptions from "../../components/booking/TimeOptions"; | ||||
| import PoweredByCalendso from "../../components/ui/PoweredByCalendso"; | ||||
| import { timeZone } from "../../lib/clock"; | ||||
| import { collectPageParameters, telemetryEventTypes, useTelemetry } from "../../lib/telemetry"; | ||||
| import AvailableTimes from "@components/booking/AvailableTimes"; | ||||
| import DatePicker from "@components/booking/DatePicker"; | ||||
| import TimeOptions from "@components/booking/TimeOptions"; | ||||
| import PoweredByCalendso from "@components/ui/PoweredByCalendso"; | ||||
| import { timeZone } from "@lib/clock"; | ||||
| import { collectPageParameters, telemetryEventTypes, useTelemetry } from "@lib/telemetry"; | ||||
| import { asStringOrNull } from "@lib/asStringOrNull"; | ||||
| 
 | ||||
| export default function Type(props: InferGetServerSidePropsType<typeof getServerSideProps>) { | ||||
|  | @ -82,53 +82,14 @@ export default function Type(props: InferGetServerSidePropsType<typeof getServer | |||
| 
 | ||||
|   return ( | ||||
|     <> | ||||
|       <Head> | ||||
|         <title> | ||||
|           {rescheduleUid && "Reschedule"} {props.eventType.title} | {props.user.name || props.user.username} | | ||||
|           Calendso | ||||
|         </title> | ||||
|         <meta name="title" content={"Meet " + (props.user.name || props.user.username) + " via Calendso"} /> | ||||
|         <meta name="description" content={props.eventType.description} /> | ||||
| 
 | ||||
|         <meta property="og:type" content="website" /> | ||||
|         <meta property="og:url" content="https://calendso/" /> | ||||
|         <meta | ||||
|           property="og:title" | ||||
|           content={"Meet " + (props.user.name || props.user.username) + " via Calendso"} | ||||
|       <HeadSeo | ||||
|         title={`${rescheduleUid ? "Reschedule" : ""} ${props.eventType.title} | ${ | ||||
|           props.user.name || props.user.username | ||||
|         }`}
 | ||||
|         description={`${rescheduleUid ? "Reschedule" : ""} ${props.eventType.title}`} | ||||
|         name={props.user.name || props.user.username} | ||||
|         avatar={props.user.avatar} | ||||
|       /> | ||||
|         <meta property="og:description" content={props.eventType.description} /> | ||||
|         <meta | ||||
|           property="og:image" | ||||
|           content={ | ||||
|             "https://og-image-one-pi.vercel.app/" + | ||||
|             encodeURIComponent( | ||||
|               "Meet **" + (props.user.name || props.user.username) + "** <br>" + props.eventType.description | ||||
|             ).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={props.eventType.description} /> | ||||
|         <meta | ||||
|           property="twitter:image" | ||||
|           content={ | ||||
|             "https://og-image-one-pi.vercel.app/" + | ||||
|             encodeURIComponent( | ||||
|               "Meet **" + (props.user.name || props.user.username) + "** <br>" + props.eventType.description | ||||
|             ).replace(/'/g, "%27") + | ||||
|             ".png?md=1&images=https%3A%2F%2Fcalendso.com%2Fcalendso-logo-white.svg&images=" + | ||||
|             encodeURIComponent(props.user.avatar) | ||||
|           } | ||||
|         /> | ||||
|       </Head> | ||||
| 
 | ||||
|       {isReady && ( | ||||
|         <div> | ||||
|           <main | ||||
|  |  | |||
|  | @ -1,16 +1,16 @@ | |||
| import Head from "next/head"; | ||||
| import { HeadSeo } from "@components/seo/head-seo"; | ||||
| import Link from "next/link"; | ||||
| import { useRouter } from "next/router"; | ||||
| import { CalendarIcon, ClockIcon, ExclamationIcon, LocationMarkerIcon } from "@heroicons/react/solid"; | ||||
| import prisma, { whereAndSelect } from "../../lib/prisma"; | ||||
| import prisma, { whereAndSelect } from "@lib/prisma"; | ||||
| import { EventTypeCustomInputType } from "@prisma/client"; | ||||
| import { collectPageParameters, telemetryEventTypes, useTelemetry } from "../../lib/telemetry"; | ||||
| import { collectPageParameters, telemetryEventTypes, useTelemetry } from "@lib/telemetry"; | ||||
| import { useEffect, useState } from "react"; | ||||
| import dayjs from "dayjs"; | ||||
| import utc from "dayjs/plugin/utc"; | ||||
| import timezone from "dayjs/plugin/timezone"; | ||||
| import PhoneInput from "@components/ui/form/PhoneInput"; | ||||
| import { LocationType } from "../../lib/location"; | ||||
| import { LocationType } from "@lib/location"; | ||||
| import Avatar from "@components/Avatar"; | ||||
| import { Button } from "@components/ui/Button"; | ||||
| import Theme from "@components/Theme"; | ||||
|  | @ -150,13 +150,14 @@ export default function Book(props: any): JSX.Element { | |||
|   return ( | ||||
|     isReady && ( | ||||
|       <div> | ||||
|         <Head> | ||||
|           <title> | ||||
|             {rescheduleUid ? "Reschedule" : "Confirm"} your {props.eventType.title} with{" "} | ||||
|             {props.user.name || props.user.username} | Calendso | ||||
|           </title> | ||||
|           <link rel="icon" href="/favicon.ico" /> | ||||
|         </Head> | ||||
|         <HeadSeo | ||||
|           title={`${rescheduleUid ? "Reschedule" : "Confirm"} your ${props.eventType.title} with ${ | ||||
|             props.user.name || props.user.username | ||||
|           }`}
 | ||||
|           description={`${rescheduleUid ? "Reschedule" : "Confirm"} your ${props.eventType.title} with ${ | ||||
|             props.user.name || props.user.username | ||||
|           }`}
 | ||||
|         /> | ||||
| 
 | ||||
|         <main className="max-w-3xl mx-auto my-0 sm:my-24"> | ||||
|           <div className="dark:bg-neutral-900 bg-white overflow-hidden border border-gray-200 dark:border-0 sm:rounded-sm"> | ||||
|  |  | |||
|  | @ -1,7 +1,8 @@ | |||
| import "../styles/globals.css"; | ||||
| import AppProviders from "@lib/app-providers"; | ||||
| import type { AppProps as NextAppProps } from "next/app"; | ||||
| import Head from "next/head"; | ||||
| import { DefaultSeo } from "next-seo"; | ||||
| import { seoConfig } from "@lib/config/next-seo.config"; | ||||
| 
 | ||||
| // Workaround for https://github.com/zeit/next.js/issues/8592
 | ||||
| export type AppProps = NextAppProps & { | ||||
|  | @ -12,9 +13,7 @@ export type AppProps = NextAppProps & { | |||
| function MyApp({ Component, pageProps, err }: AppProps) { | ||||
|   return ( | ||||
|     <AppProviders> | ||||
|       <Head> | ||||
|         <meta name="viewport" content="width=device-width, initial-scale=1.0" /> | ||||
|       </Head> | ||||
|       <DefaultSeo {...seoConfig.defaultNextSeo} /> | ||||
|       <Component {...pageProps} err={err} /> | ||||
|     </AppProviders> | ||||
|   ); | ||||
|  |  | |||
|  | @ -1,6 +1,6 @@ | |||
| import { useRouter } from "next/router"; | ||||
| import { XIcon } from "@heroicons/react/outline"; | ||||
| import Head from "next/head"; | ||||
| import { HeadSeo } from "@components/seo/head-seo"; | ||||
| import Link from "next/link"; | ||||
| 
 | ||||
| export default function Error() { | ||||
|  | @ -13,10 +13,7 @@ export default function Error() { | |||
|       aria-labelledby="modal-title" | ||||
|       role="dialog" | ||||
|       aria-modal="true"> | ||||
|       <Head> | ||||
|         <title>{error} - Calendso</title> | ||||
|         <link rel="icon" href="/favicon.ico" /> | ||||
|       </Head> | ||||
|       <HeadSeo title="Error" description="Error" /> | ||||
|       <div className="flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0"> | ||||
|         <span className="hidden sm:inline-block sm:align-middle sm:h-screen" aria-hidden="true"> | ||||
|           ​ | ||||
|  |  | |||
|  | @ -1,7 +1,6 @@ | |||
| import { getCsrfToken } from "next-auth/client"; | ||||
| import prisma from "../../../lib/prisma"; | ||||
| 
 | ||||
| import Head from "next/head"; | ||||
| import prisma from "@lib/prisma"; | ||||
| import { HeadSeo } from "@components/seo/head-seo"; | ||||
| import React, { useMemo } from "react"; | ||||
| import debounce from "lodash.debounce"; | ||||
| import dayjs from "dayjs"; | ||||
|  | @ -122,10 +121,7 @@ export default function Page({ resetPasswordRequest, csrfToken }: Props) { | |||
| 
 | ||||
|   return ( | ||||
|     <div className="min-h-screen bg-gray-50 flex flex-col justify-center py-12 sm:px-6 lg:px-8"> | ||||
|       <Head> | ||||
|         <title>Reset Password</title> | ||||
|         <link rel="icon" href="/favicon.ico" /> | ||||
|       </Head> | ||||
|       <HeadSeo title="Reset Password" description="Change your password" /> | ||||
|       <div className="mt-8 sm:mx-auto sm:w-full sm:max-w-md"> | ||||
|         <div className="bg-white py-8 px-4 mx-2 shadow rounded-lg sm:px-10 space-y-6"> | ||||
|           {isRequestExpired && <Expired />} | ||||
|  |  | |||
|  | @ -1,4 +1,4 @@ | |||
| import Head from "next/head"; | ||||
| import { HeadSeo } from "@components/seo/head-seo"; | ||||
| import Link from "next/link"; | ||||
| import React from "react"; | ||||
| import { getCsrfToken, getSession } from "next-auth/client"; | ||||
|  | @ -71,11 +71,7 @@ export default function ForgotPassword({ csrfToken }) { | |||
| 
 | ||||
|   return ( | ||||
|     <div className="min-h-screen bg-gray-50 flex flex-col justify-center py-12 sm:px-6 lg:px-8"> | ||||
|       <Head> | ||||
|         <title>Forgot Password</title> | ||||
|         <link rel="icon" href="/favicon.ico" /> | ||||
|       </Head> | ||||
| 
 | ||||
|       <HeadSeo title="Forgot Password" description="Forgot Password" /> | ||||
|       <div className="mt-8 sm:mx-auto sm:w-full sm:max-w-md"> | ||||
|         <div className="bg-white py-8 px-4 mx-2 shadow rounded-lg sm:px-10 space-y-6"> | ||||
|           {success && <Success />} | ||||
|  |  | |||
|  | @ -1,14 +1,11 @@ | |||
| import Head from "next/head"; | ||||
| import { HeadSeo } from "@components/seo/head-seo"; | ||||
| import Link from "next/link"; | ||||
| import { getCsrfToken, getSession } from "next-auth/client"; | ||||
| 
 | ||||
| export default function Login({ csrfToken }) { | ||||
|   return ( | ||||
|     <div className="min-h-screen bg-neutral-50 flex flex-col justify-center py-12 sm:px-6 lg:px-8"> | ||||
|       <Head> | ||||
|         <title>Login</title> | ||||
|         <link rel="icon" href="/favicon.ico" /> | ||||
|       </Head> | ||||
|       <HeadSeo title="Login" description="Login" /> | ||||
|       <div className="sm:mx-auto sm:w-full sm:max-w-md"> | ||||
|         <img className="h-6 mx-auto" src="/calendso-logo-white-word.svg" alt="Calendso Logo" /> | ||||
|         <h2 className="mt-6 text-center text-3xl font-bold text-neutral-900">Sign in to your account</h2> | ||||
|  |  | |||
|  | @ -1,4 +1,4 @@ | |||
| import Head from "next/head"; | ||||
| import { HeadSeo } from "@components/seo/head-seo"; | ||||
| import Link from "next/link"; | ||||
| import { CheckIcon } from "@heroicons/react/outline"; | ||||
| 
 | ||||
|  | @ -9,10 +9,7 @@ export default function Logout() { | |||
|       aria-labelledby="modal-title" | ||||
|       role="dialog" | ||||
|       aria-modal="true"> | ||||
|       <Head> | ||||
|         <title>Logged out - Calendso</title> | ||||
|         <link rel="icon" href="/favicon.ico" /> | ||||
|       </Head> | ||||
|       <HeadSeo title="Logged out" description="Logged out" /> | ||||
|       <div className="flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0"> | ||||
|         <span className="hidden sm:inline-block sm:align-middle sm:h-screen" aria-hidden="true"> | ||||
|           ​ | ||||
|  |  | |||
|  | @ -1,10 +1,10 @@ | |||
| import Head from "next/head"; | ||||
| import { HeadSeo } from "@components/seo/head-seo"; | ||||
| import { useRouter } from "next/router"; | ||||
| import { signIn } from "next-auth/client"; | ||||
| import ErrorAlert from "../../components/ui/alerts/Error"; | ||||
| import ErrorAlert from "@components/ui/alerts/Error"; | ||||
| import { useState } from "react"; | ||||
| import { UsernameInput } from "../../components/ui/UsernameInput"; | ||||
| import prisma from "../../lib/prisma"; | ||||
| import { UsernameInput } from "@components/ui/UsernameInput"; | ||||
| import prisma from "@lib/prisma"; | ||||
| 
 | ||||
| export default function Signup(props) { | ||||
|   const router = useRouter(); | ||||
|  | @ -54,10 +54,7 @@ export default function Signup(props) { | |||
|       aria-labelledby="modal-title" | ||||
|       role="dialog" | ||||
|       aria-modal="true"> | ||||
|       <Head> | ||||
|         <title>Sign up</title> | ||||
|         <link rel="icon" href="/favicon.ico" /> | ||||
|       </Head> | ||||
|       <HeadSeo title="Sign up" description="Sign up" /> | ||||
|       <div className="sm:mx-auto sm:w-full sm:max-w-md"> | ||||
|         <h2 className="text-center text-3xl font-extrabold text-gray-900">Create your account</h2> | ||||
|       </div> | ||||
|  |  | |||
|  | @ -1,8 +1,7 @@ | |||
| import Head from "next/head"; | ||||
| import Link from "next/link"; | ||||
| import prisma from "../../lib/prisma"; | ||||
| import Modal from "../../components/Modal"; | ||||
| import Shell from "../../components/Shell"; | ||||
| import prisma from "@lib/prisma"; | ||||
| import Modal from "@components/Modal"; | ||||
| import Shell from "@components/Shell"; | ||||
| import { useRouter } from "next/router"; | ||||
| import { useRef, useState } from "react"; | ||||
| import { getSession, useSession } from "next-auth/client"; | ||||
|  | @ -115,15 +114,7 @@ export default function Availability(props) { | |||
| 
 | ||||
|   return ( | ||||
|     <div> | ||||
|       <Head> | ||||
|         <title>Availability | Calendso</title> | ||||
|         <link rel="icon" href="/favicon.ico" /> | ||||
|       </Head> | ||||
|       <Shell | ||||
|         heading="Availability" | ||||
|         subtitle="Configure times when you are available for bookings. | ||||
| 
 | ||||
| "> | ||||
|       <Shell heading="Availability" subtitle="Configure times when you are available for bookings."> | ||||
|         <div className="flex"> | ||||
|           <div className="w-1/2 mr-2 bg-white border border-gray-200 rounded-sm"> | ||||
|             <div className="px-4 py-5 sm:p-6"> | ||||
|  |  | |||
|  | @ -4,9 +4,8 @@ import dayjs from "dayjs"; | |||
| import utc from "dayjs/plugin/utc"; | ||||
| import { GetServerSideProps } from "next"; | ||||
| import { getSession } from "next-auth/client"; | ||||
| import Head from "next/head"; | ||||
| import { useEffect, useState } from "react"; | ||||
| import Shell from "../../components/Shell"; | ||||
| import Shell from "@components/Shell"; | ||||
| 
 | ||||
| dayjs.extend(utc); | ||||
| 
 | ||||
|  | @ -52,10 +51,6 @@ export default function Troubleshoot({ user }) { | |||
| 
 | ||||
|   return ( | ||||
|     <div> | ||||
|       <Head> | ||||
|         <title>Troubleshoot | Calendso</title> | ||||
|         <link rel="icon" href="/favicon.ico" /> | ||||
|       </Head> | ||||
|       <Shell | ||||
|         heading="Troubleshoot" | ||||
|         subtitle="Understand why certain times are available and others are blocked."> | ||||
|  |  | |||
|  | @ -1,7 +1,6 @@ | |||
| import Head from "next/head"; | ||||
| import prisma from "../../lib/prisma"; | ||||
| import prisma from "@lib/prisma"; | ||||
| import { getSession, useSession } from "next-auth/client"; | ||||
| import Shell from "../../components/Shell"; | ||||
| import Shell from "@components/Shell"; | ||||
| import { useRouter } from "next/router"; | ||||
| import dayjs from "dayjs"; | ||||
| import { Fragment } from "react"; | ||||
|  | @ -36,10 +35,6 @@ export default function Bookings({ bookings }) { | |||
| 
 | ||||
|   return ( | ||||
|     <div> | ||||
|       <Head> | ||||
|         <title>Bookings | Calendso</title> | ||||
|         <link rel="icon" href="/favicon.ico" /> | ||||
|       </Head> | ||||
|       <Shell heading="Bookings" subtitle="See upcoming and past events booked through your event type links."> | ||||
|         <div className="-mx-4 sm:mx-auto flex flex-col"> | ||||
|           <div className="-my-2 overflow-x-auto sm:-mx-6 lg:-mx-8"> | ||||
|  |  | |||
|  | @ -4,11 +4,11 @@ import isBetween from "dayjs/plugin/isBetween"; | |||
| import isSameOrBefore from "dayjs/plugin/isSameOrBefore"; | ||||
| import timezone from "dayjs/plugin/timezone"; | ||||
| import utc from "dayjs/plugin/utc"; | ||||
| import Head from "next/head"; | ||||
| import { HeadSeo } from "@components/seo/head-seo"; | ||||
| import { useRouter } from "next/router"; | ||||
| import { useState } from "react"; | ||||
| import prisma from "../../lib/prisma"; | ||||
| import { collectPageParameters, telemetryEventTypes, useTelemetry } from "../../lib/telemetry"; | ||||
| import prisma from "@lib/prisma"; | ||||
| import { collectPageParameters, telemetryEventTypes, useTelemetry } from "@lib/telemetry"; | ||||
| 
 | ||||
| dayjs.extend(isSameOrBefore); | ||||
| dayjs.extend(isBetween); | ||||
|  | @ -55,13 +55,12 @@ export default function Type(props) { | |||
| 
 | ||||
|   return ( | ||||
|     <div> | ||||
|       <Head> | ||||
|         <title> | ||||
|           Cancel {props.booking && `${props.booking.title} | ${props.user.name || props.user.username} `}| | ||||
|           Calendso | ||||
|         </title> | ||||
|         <link rel="icon" href="/favicon.ico" /> | ||||
|       </Head> | ||||
|       <HeadSeo | ||||
|         title={`Cancel ${props.booking && props.booking.title} | ${props.user.name || props.user.username}`} | ||||
|         description={`Cancel ${props.booking && props.booking.title} | ${ | ||||
|           props.user.name || props.user.username | ||||
|         }`}
 | ||||
|       /> | ||||
|       <main className="max-w-3xl mx-auto my-24"> | ||||
|         <div className="fixed z-50 inset-0 overflow-y-auto"> | ||||
|           <div className="flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0"> | ||||
|  |  | |||
|  | @ -1,4 +1,4 @@ | |||
| import Head from "next/head"; | ||||
| import { HeadSeo } from "@components/seo/head-seo"; | ||||
| import prisma from "../../lib/prisma"; | ||||
| import { useRouter } from "next/router"; | ||||
| import dayjs from "dayjs"; | ||||
|  | @ -19,12 +19,10 @@ export default function Type(props) { | |||
| 
 | ||||
|   return ( | ||||
|     <div> | ||||
|       <Head> | ||||
|         <title> | ||||
|           Cancelled {props.title} | {props.user.name || props.user.username} | Calendso | ||||
|         </title> | ||||
|         <link rel="icon" href="/favicon.ico" /> | ||||
|       </Head> | ||||
|       <HeadSeo | ||||
|         title={`Cancelled ${props.title} | ${props.user.name || props.user.username}`} | ||||
|         description={`Cancelled ${props.title} | ${props.user.name || props.user.username}`} | ||||
|       /> | ||||
|       <main className="max-w-3xl mx-auto my-24"> | ||||
|         <div className="fixed z-50 inset-0 overflow-y-auto"> | ||||
|           <div className="flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0"> | ||||
|  |  | |||
|  | @ -1,7 +1,6 @@ | |||
| import Head from "next/head"; | ||||
| import Link from "next/link"; | ||||
| import { useRouter } from "next/router"; | ||||
| import Modal from "../../components/Modal"; | ||||
| import Modal from "@components/Modal"; | ||||
| import React, { useEffect, useRef, useState } from "react"; | ||||
| import Select, { OptionBase } from "react-select"; | ||||
| import prisma from "@lib/prisma"; | ||||
|  | @ -331,11 +330,8 @@ const EventTypePage = (props: InferGetServerSidePropsType<typeof getServerSidePr | |||
| 
 | ||||
|   return ( | ||||
|     <div> | ||||
|       <Head> | ||||
|         <title>{eventType.title} | Event Type | Calendso</title> | ||||
|         <link rel="icon" href="/favicon.ico" /> | ||||
|       </Head> | ||||
|       <Shell | ||||
|         title={`${eventType.title} | Event Type`} | ||||
|         heading={ | ||||
|           <input | ||||
|             ref={titleRef} | ||||
|  |  | |||
|  | @ -15,7 +15,6 @@ import { | |||
| import classNames from "@lib/classNames"; | ||||
| import showToast from "@lib/notification"; | ||||
| import { getSession, useSession } from "next-auth/client"; | ||||
| import Head from "next/head"; | ||||
| import Link from "next/link"; | ||||
| import { useRouter } from "next/router"; | ||||
| import React, { Fragment, useRef } from "react"; | ||||
|  | @ -193,10 +192,6 @@ const EventTypesPage = (props: InferGetServerSidePropsType<typeof getServerSideP | |||
| 
 | ||||
|   return ( | ||||
|     <div> | ||||
|       <Head> | ||||
|         <title>Event Types | Calendso</title> | ||||
|         <link rel="icon" href="/favicon.ico" /> | ||||
|       </Head> | ||||
|       <Shell | ||||
|         heading="Event Types" | ||||
|         subtitle="Create events to share for people to book on your calendar." | ||||
|  |  | |||
|  | @ -1,7 +1,6 @@ | |||
| import Head from "next/head"; | ||||
| import prisma from "../../lib/prisma"; | ||||
| import { getIntegrationName, getIntegrationType } from "../../lib/integrations"; | ||||
| import Shell from "../../components/Shell"; | ||||
| import prisma from "@lib/prisma"; | ||||
| import { getIntegrationName, getIntegrationType } from "@lib/integrations"; | ||||
| import Shell from "@components/Shell"; | ||||
| import { useState } from "react"; | ||||
| import { useRouter } from "next/router"; | ||||
| import { getSession, useSession } from "next-auth/client"; | ||||
|  | @ -40,12 +39,9 @@ export default function Integration(props) { | |||
| 
 | ||||
|   return ( | ||||
|     <div> | ||||
|       <Head> | ||||
|         <title>{getIntegrationName(props.integration.type)} App | Calendso</title> | ||||
|         <link rel="icon" href="/favicon.ico" /> | ||||
|       </Head> | ||||
| 
 | ||||
|       <Shell heading={getIntegrationName(props.integration.type)} subtitle="Manage and delete this app."> | ||||
|       <Shell | ||||
|         heading={`${getIntegrationName(props.integration.type)} App`} | ||||
|         subtitle="Manage and delete this app."> | ||||
|         <div className="block sm:grid grid-cols-3 gap-4"> | ||||
|           <div className="col-span-2 bg-white border border-gray-200 mb-6 overflow-hidden rounded-sm"> | ||||
|             <div className="px-4 py-5 sm:px-6"> | ||||
|  |  | |||
|  | @ -1,7 +1,6 @@ | |||
| import Head from "next/head"; | ||||
| import Link from "next/link"; | ||||
| import prisma from "../../lib/prisma"; | ||||
| import Shell from "../../components/Shell"; | ||||
| import prisma from "@lib/prisma"; | ||||
| import Shell from "@components/Shell"; | ||||
| import { useEffect, useState, useRef, useCallback } from "react"; | ||||
| import { getSession, useSession } from "next-auth/client"; | ||||
| import { CheckCircleIcon, ChevronRightIcon, PlusIcon, XCircleIcon } from "@heroicons/react/solid"; | ||||
|  | @ -270,11 +269,6 @@ export default function Home({ integrations }: Props) { | |||
| 
 | ||||
|   return ( | ||||
|     <div> | ||||
|       <Head> | ||||
|         <title>App Store | Calendso</title> | ||||
|         <link rel="icon" href="/favicon.ico" /> | ||||
|       </Head> | ||||
| 
 | ||||
|       <Shell heading="App Store" subtitle="Connect your favourite apps." CTA={<ConnectNewAppDialog />}> | ||||
|         <div className="bg-white border border-gray-200 overflow-hidden rounded-sm mb-8"> | ||||
|           {integrations.filter((ig) => ig.credential).length !== 0 ? ( | ||||
|  |  | |||
|  | @ -1,15 +1,11 @@ | |||
| import Head from "next/head"; | ||||
| import Shell from "../../components/Shell"; | ||||
| import SettingsShell from "../../components/Settings"; | ||||
| import prisma from "../../lib/prisma"; | ||||
| import Shell from "@components/Shell"; | ||||
| import SettingsShell from "@components/Settings"; | ||||
| import prisma from "@lib/prisma"; | ||||
| import { getSession } from "next-auth/client"; | ||||
| 
 | ||||
| export default function Billing() { | ||||
|   return ( | ||||
|     <Shell heading="Billing" subtitle="Manage your billing information and cancel your subscription."> | ||||
|       <Head> | ||||
|         <title>Billing | Calendso</title> | ||||
|       </Head> | ||||
|       <SettingsShell> | ||||
|         <div className="py-6 lg:pb-8 lg:col-span-9"> | ||||
|           <div className="my-6"> | ||||
|  |  | |||
|  | @ -1,7 +1,6 @@ | |||
| import Head from "next/head"; | ||||
| import prisma from "../../lib/prisma"; | ||||
| import Shell from "../../components/Shell"; | ||||
| import SettingsShell from "../../components/Settings"; | ||||
| import prisma from "@lib/prisma"; | ||||
| import Shell from "@components/Shell"; | ||||
| import SettingsShell from "@components/Settings"; | ||||
| import { getSession, useSession } from "next-auth/client"; | ||||
| import Loader from "@components/Loader"; | ||||
| 
 | ||||
|  | @ -15,10 +14,6 @@ export default function Embed(props) { | |||
| 
 | ||||
|   return ( | ||||
|     <Shell heading="Embed" subtitle="Integrate with your website using our embed options."> | ||||
|       <Head> | ||||
|         <title>Embed | Calendso</title> | ||||
|         <link rel="icon" href="/favicon.ico" /> | ||||
|       </Head> | ||||
|       <SettingsShell> | ||||
|         <div className="py-6 lg:pb-8 lg:col-span-9"> | ||||
|           <div className="mb-6"> | ||||
|  |  | |||
|  | @ -1,9 +1,8 @@ | |||
| import Head from "next/head"; | ||||
| import { useRef, useState } from "react"; | ||||
| import prisma from "../../lib/prisma"; | ||||
| import Modal from "../../components/Modal"; | ||||
| import Shell from "../../components/Shell"; | ||||
| import SettingsShell from "../../components/Settings"; | ||||
| import prisma from "@lib/prisma"; | ||||
| import Modal from "@components/Modal"; | ||||
| import Shell from "@components/Shell"; | ||||
| import SettingsShell from "@components/Settings"; | ||||
| import { getSession, useSession } from "next-auth/client"; | ||||
| import Loader from "@components/Loader"; | ||||
| 
 | ||||
|  | @ -45,11 +44,7 @@ export default function Settings() { | |||
|   } | ||||
| 
 | ||||
|   return ( | ||||
|     <Shell heading="Password" subtitle="Change the password that you use to sign in to your account."> | ||||
|       <Head> | ||||
|         <title>Change Password | Calendso</title> | ||||
|         <link rel="icon" href="/favicon.ico" /> | ||||
|       </Head> | ||||
|     <Shell heading="Change Password" subtitle="Change the password that you use to sign in to your account."> | ||||
|       <SettingsShell> | ||||
|         <form className="divide-y divide-gray-200 lg:col-span-9" onSubmit={changePasswordHandler}> | ||||
|           <div className="py-6 lg:pb-8"> | ||||
|  |  | |||
|  | @ -1,17 +1,16 @@ | |||
| import { GetServerSideProps } from "next"; | ||||
| import Head from "next/head"; | ||||
| import { useEffect, useRef, useState } from "react"; | ||||
| import prisma from "@lib/prisma"; | ||||
| import Modal from "../../components/Modal"; | ||||
| import Shell from "../../components/Shell"; | ||||
| import SettingsShell from "../../components/Settings"; | ||||
| import Modal from "@components/Modal"; | ||||
| import Shell from "@components/Shell"; | ||||
| import SettingsShell from "@components/Settings"; | ||||
| import Avatar from "@components/Avatar"; | ||||
| import { getSession } from "next-auth/client"; | ||||
| import Select from "react-select"; | ||||
| import TimezoneSelect from "react-timezone-select"; | ||||
| import { UsernameInput } from "../../components/ui/UsernameInput"; | ||||
| import ErrorAlert from "../../components/ui/alerts/Error"; | ||||
| import ImageUploader from "../../components/ImageUploader"; | ||||
| import { UsernameInput } from "@components/ui/UsernameInput"; | ||||
| import ErrorAlert from "@components/ui/alerts/Error"; | ||||
| import ImageUploader from "@components/ImageUploader"; | ||||
| import crypto from "crypto"; | ||||
| 
 | ||||
| const themeOptions = [ | ||||
|  | @ -107,10 +106,6 @@ export default function Settings(props) { | |||
| 
 | ||||
|   return ( | ||||
|     <Shell heading="Profile" subtitle="Edit your profile information, which shows on your scheduling link."> | ||||
|       <Head> | ||||
|         <title>Profile | Calendso</title> | ||||
|         <link rel="icon" href="/favicon.ico" /> | ||||
|       </Head> | ||||
|       <SettingsShell> | ||||
|         <form className="divide-y divide-gray-200 lg:col-span-9" onSubmit={updateProfileHandler}> | ||||
|           {hasErrors && <ErrorAlert message={errorMessage} />} | ||||
|  |  | |||
|  | @ -1,13 +1,12 @@ | |||
| import { GetServerSideProps } from "next"; | ||||
| import Head from "next/head"; | ||||
| import Shell from "../../components/Shell"; | ||||
| import SettingsShell from "../../components/Settings"; | ||||
| import Shell from "@components/Shell"; | ||||
| import SettingsShell from "@components/Settings"; | ||||
| import { useEffect, useState } from "react"; | ||||
| import type { Session } from "next-auth"; | ||||
| import { getSession, useSession } from "next-auth/client"; | ||||
| import { UsersIcon } from "@heroicons/react/outline"; | ||||
| import TeamList from "../../components/team/TeamList"; | ||||
| import TeamListItem from "../../components/team/TeamListItem"; | ||||
| import TeamList from "@components/team/TeamList"; | ||||
| import TeamListItem from "@components/team/TeamListItem"; | ||||
| import Loader from "@components/Loader"; | ||||
| 
 | ||||
| export default function Teams() { | ||||
|  | @ -59,10 +58,6 @@ export default function Teams() { | |||
| 
 | ||||
|   return ( | ||||
|     <Shell heading="Teams" subtitle="Create and manage teams to use collaborative features."> | ||||
|       <Head> | ||||
|         <title>Teams | Calendso</title> | ||||
|         <link rel="icon" href="/favicon.ico" /> | ||||
|       </Head> | ||||
|       <SettingsShell> | ||||
|         <div className="divide-y divide-gray-200 lg:col-span-9"> | ||||
|           <div className="py-6 lg:pb-8"> | ||||
|  |  | |||
|  | @ -1,6 +1,6 @@ | |||
| import Head from "next/head"; | ||||
| import { HeadSeo } from "@components/seo/head-seo"; | ||||
| import Link from "next/link"; | ||||
| import prisma, { whereAndSelect } from "../lib/prisma"; | ||||
| import prisma, { whereAndSelect } from "@lib/prisma"; | ||||
| import { useEffect, useState } from "react"; | ||||
| import { useRouter } from "next/router"; | ||||
| import { CheckIcon } from "@heroicons/react/outline"; | ||||
|  | @ -10,7 +10,7 @@ import utc from "dayjs/plugin/utc"; | |||
| import toArray from "dayjs/plugin/toArray"; | ||||
| import timezone from "dayjs/plugin/timezone"; | ||||
| import { createEvent } from "ics"; | ||||
| import { getEventName } from "../lib/event"; | ||||
| import { getEventName } from "@lib/event"; | ||||
| import Theme from "@components/Theme"; | ||||
| 
 | ||||
| dayjs.extend(utc); | ||||
|  | @ -61,13 +61,10 @@ export default function Success(props) { | |||
|   return ( | ||||
|     isReady && ( | ||||
|       <div className="bg-neutral-50 dark:bg-neutral-900 h-screen"> | ||||
|         <Head> | ||||
|           <title> | ||||
|             Booking {props.eventType.requiresConfirmation ? "Submitted" : "Confirmed"} | {eventName} | | ||||
|             Calendso | ||||
|           </title> | ||||
|           <link rel="icon" href="/favicon.ico" /> | ||||
|         </Head> | ||||
|         <HeadSeo | ||||
|           title={`Booking ${props.eventType.requiresConfirmation ? "Submitted" : "Confirmed"}`} | ||||
|           description={`Booking ${props.eventType.requiresConfirmation ? "Submitted" : "Confirmed"}`} | ||||
|         /> | ||||
|         <main className="max-w-3xl mx-auto py-24"> | ||||
|           <div className="fixed z-50 inset-0 overflow-y-auto"> | ||||
|             <div className="flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0"> | ||||
|  |  | |||
|  | @ -1,6 +1,5 @@ | |||
| import { GetServerSideProps } from "next"; | ||||
| import Head from "next/head"; | ||||
| 
 | ||||
| import { HeadSeo } from "@components/seo/head-seo"; | ||||
| import Theme from "@components/Theme"; | ||||
| import { getTeam } from "@lib/teams/getTeam"; | ||||
| import Team from "@components/team/screens/Team"; | ||||
|  | @ -11,11 +10,7 @@ export default function Page(props) { | |||
|   return ( | ||||
|     isReady && ( | ||||
|       <div> | ||||
|         <Head> | ||||
|           <title>{props.team.name} | Calendso</title> | ||||
|           <link rel="icon" href="/favicon.ico" /> | ||||
|         </Head> | ||||
| 
 | ||||
|         <HeadSeo title={props.team.name} description={props.team.name} /> | ||||
|         <main className="mx-auto py-24 px-4"> | ||||
|           <Team team={props.team} /> | ||||
|         </main> | ||||
|  |  | |||
|  | @ -4216,6 +4216,10 @@ next-auth@^3.28.0: | |||
|     preact-render-to-string "^5.1.14" | ||||
|     querystring "^0.2.0" | ||||
| 
 | ||||
| next-seo@^4.26.0: | ||||
|   version "4.26.0" | ||||
|   resolved "https://registry.yarnpkg.com/next-seo/-/next-seo-4.26.0.tgz#4218cfae5651fdc2e330dcdf1cc1b34ce199d41c" | ||||
| 
 | ||||
| next-transpile-modules@^8.0.0: | ||||
|   version "8.0.0" | ||||
|   resolved "https://registry.npmjs.org/next-transpile-modules/-/next-transpile-modules-8.0.0.tgz#56375cdc25ae5d23a834195f277fc2737b26cb97" | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Mihai C
						Mihai C