Performance improvements (lazy loading) for booking pages (#1762)
This commit is contained in:
		
							parent
							
								
									2e5deae7c0
								
							
						
					
					
						commit
						6fe824088a
					
				
					 4 changed files with 110 additions and 82 deletions
				
			
		
							
								
								
									
										28
									
								
								apps/web/components/ui/AvatarSSR.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								apps/web/components/ui/AvatarSSR.tsx
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,28 @@ | |||
| import { User } from "@prisma/client"; | ||||
| 
 | ||||
| import classNames from "@lib/classNames"; | ||||
| import { defaultAvatarSrc } from "@lib/profile"; | ||||
| 
 | ||||
| export type AvatarProps = { | ||||
|   user: Pick<User, "name" | "username" | "avatar"> & { emailMd5?: string }; | ||||
|   className?: string; | ||||
|   size?: number; | ||||
|   title?: string; | ||||
|   alt: string; | ||||
| }; | ||||
| 
 | ||||
| // An SSR Supported version of Avatar component.
 | ||||
| // FIXME: title support is missing
 | ||||
| export function AvatarSSR(props: AvatarProps) { | ||||
|   const { user, size } = props; | ||||
|   const nameOrUsername = user.name || user.username || ""; | ||||
|   const className = classNames("rounded-full", props.className, size && `h-${size} w-${size}`); | ||||
|   let imgSrc; | ||||
|   const alt = props.alt || nameOrUsername; | ||||
|   if (user.avatar) { | ||||
|     imgSrc = user.avatar; | ||||
|   } else if (user.emailMd5) { | ||||
|     imgSrc = defaultAvatarSrc({ md5: user.emailMd5 }); | ||||
|   } | ||||
|   return imgSrc ? <img alt={alt} className={className} src={imgSrc}></img> : null; | ||||
| } | ||||
|  | @ -1,6 +1,8 @@ | |||
| import { ArrowRightIcon } from "@heroicons/react/outline"; | ||||
| import { BadgeCheckIcon } from "@heroicons/react/solid"; | ||||
| import crypto from "crypto"; | ||||
| import { GetServerSidePropsContext } from "next"; | ||||
| import dynamic from "next/dynamic"; | ||||
| import Link from "next/link"; | ||||
| import { useRouter } from "next/router"; | ||||
| import React, { useState } from "react"; | ||||
|  | @ -9,24 +11,23 @@ import { JSONObject } from "superjson/dist/types"; | |||
| 
 | ||||
| import { useLocale } from "@lib/hooks/useLocale"; | ||||
| import useTheme from "@lib/hooks/useTheme"; | ||||
| import showToast from "@lib/notification"; | ||||
| import prisma from "@lib/prisma"; | ||||
| import { inferSSRProps } from "@lib/types/inferSSRProps"; | ||||
| 
 | ||||
| import EventTypeDescription from "@components/eventtype/EventTypeDescription"; | ||||
| import { HeadSeo } from "@components/seo/head-seo"; | ||||
| import Avatar from "@components/ui/Avatar"; | ||||
| import { AvatarSSR } from "@components/ui/AvatarSSR"; | ||||
| 
 | ||||
| import { ssrInit } from "@server/lib/ssr"; | ||||
| 
 | ||||
| import CryptoSection from "../ee/components/web3/CryptoSection"; | ||||
| const EventTypeDescription = dynamic(() => import("@components/eventtype/EventTypeDescription")); | ||||
| const HeadSeo = dynamic(() => import("@components/seo/head-seo").then((mod) => mod.HeadSeo)); | ||||
| const CryptoSection = dynamic(() => import("../ee/components/web3/CryptoSection")); | ||||
| 
 | ||||
| interface EvtsToVerify { | ||||
|   [evtId: string]: boolean; | ||||
| } | ||||
| 
 | ||||
| export default function User(props: inferSSRProps<typeof getServerSideProps>) { | ||||
|   const { isReady, Theme } = useTheme(props.user.theme); | ||||
|   const { Theme } = useTheme(props.user.theme); | ||||
|   const { user, eventTypes } = props; | ||||
|   const { t } = useLocale(); | ||||
|   const router = useRouter(); | ||||
|  | @ -35,7 +36,6 @@ export default function User(props: inferSSRProps<typeof getServerSideProps>) { | |||
| 
 | ||||
|   const nameOrUsername = user.name || user.username || ""; | ||||
|   const [evtsToVerify, setEvtsToVerify] = useState<EvtsToVerify>({}); | ||||
| 
 | ||||
|   return ( | ||||
|     <> | ||||
|       <Theme /> | ||||
|  | @ -46,19 +46,14 @@ export default function User(props: inferSSRProps<typeof getServerSideProps>) { | |||
|         username={(user.username as string) || ""} | ||||
|         // avatar={user.avatar || undefined}
 | ||||
|       /> | ||||
|       {isReady && ( | ||||
|       <div className="h-screen dark:bg-black"> | ||||
|         <main className="mx-auto max-w-3xl px-4 py-24"> | ||||
|           <div className="mb-8 text-center"> | ||||
|               <Avatar | ||||
|                 imageSrc={user.avatar} | ||||
|                 className="mx-auto mb-4 h-24 w-24 rounded-full" | ||||
|                 alt={nameOrUsername} | ||||
|               /> | ||||
|             <AvatarSSR user={user} className="mx-auto mb-4 h-24 w-24" alt={nameOrUsername}></AvatarSSR> | ||||
|             <h1 className="font-cal mb-1 text-3xl font-bold text-neutral-900 dark:text-white"> | ||||
|               {nameOrUsername} | ||||
|               {user.verified && ( | ||||
|                   <BadgeCheckIcon className="mx-1 -mt-1 inline h-6 w-6 text-blue-500 dark:text-white" /> | ||||
|                 <BadgeCheckIcon className="-mt-1 inline h-6 w-6 text-blue-500 dark:text-white" /> | ||||
|               )} | ||||
|             </h1> | ||||
|             <p className="text-neutral-500 dark:text-white">{user.bio}</p> | ||||
|  | @ -77,9 +72,10 @@ export default function User(props: inferSSRProps<typeof getServerSideProps>) { | |||
|                       query, | ||||
|                     }}> | ||||
|                     <a | ||||
|                         onClick={(e) => { | ||||
|                       onClick={async (e) => { | ||||
|                         // If a token is required for this event type, add a click listener that checks whether the user verified their wallet or not
 | ||||
|                         if (type.metadata.smartContractAddress && !evtsToVerify[type.id]) { | ||||
|                           const showToast = (await import("@lib/notification")).default; | ||||
|                           e.preventDefault(); | ||||
|                           showToast( | ||||
|                             "You must verify a wallet with a token belonging to the specified smart contract first", | ||||
|  | @ -119,7 +115,6 @@ export default function User(props: inferSSRProps<typeof getServerSideProps>) { | |||
|         </main> | ||||
|         <Toaster position="bottom-right" /> | ||||
|       </div> | ||||
|       )} | ||||
|     </> | ||||
|   ); | ||||
| } | ||||
|  | @ -224,7 +219,10 @@ export const getServerSideProps = async (context: GetServerSidePropsContext) => | |||
| 
 | ||||
|   return { | ||||
|     props: { | ||||
|       user, | ||||
|       user: { | ||||
|         ...user, | ||||
|         emailMd5: crypto.createHash("md5").update(user.email).digest("hex"), | ||||
|       }, | ||||
|       eventTypes, | ||||
|       trpcState: ssr.dehydrate(), | ||||
|     }, | ||||
|  |  | |||
|  | @ -27,7 +27,9 @@ | |||
|     "husky": "^7.0.1", | ||||
|     "lint-staged": "^11.1.2", | ||||
|     "prettier": "^2.5.1", | ||||
|     "prettier-plugin-tailwindcss": "^0.1.6", | ||||
|     "prettier-plugin-tailwindcss": "^0.1.6" | ||||
|   }, | ||||
|   "dependencies": { | ||||
|     "turbo": "latest" | ||||
|   }, | ||||
|   "lint-staged": { | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 hariombalhara
						hariombalhara