diff --git a/apps/web/next.config.js b/apps/web/next.config.js index 02ebea1769..65de64f75d 100644 --- a/apps/web/next.config.js +++ b/apps/web/next.config.js @@ -80,6 +80,10 @@ const nextConfig = { source: "/:user/avatar.png", destination: "/api/user/avatar?username=:user", }, + { + source: "/team/:teamname/avatar.png", + destination: "/api/user/avatar?teamname=:teamname", + }, ]; }, async redirects() { diff --git a/apps/web/pages/api/user/avatar.ts b/apps/web/pages/api/user/avatar.ts index 7a85a1af50..8bd856d8f5 100644 --- a/apps/web/pages/api/user/avatar.ts +++ b/apps/web/pages/api/user/avatar.ts @@ -1,31 +1,60 @@ import crypto from "crypto"; import type { NextApiRequest, NextApiResponse } from "next"; +import { getPlaceholderAvatar } from "@lib/getPlaceholderAvatar"; import prisma from "@lib/prisma"; import { defaultAvatarSrc } from "@lib/profile"; export default async function handler(req: NextApiRequest, res: NextApiResponse) { // const username = req.url?.substring(1, req.url.lastIndexOf("/")); const username = req.query.username as string; - const user = await prisma.user.findUnique({ - where: { - username: username, - }, - select: { - avatar: true, - email: true, - }, - }); + const teamname = req.query.teamname as string; + let identity; + if (username) { + const user = await prisma.user.findUnique({ + where: { + username: username, + }, + select: { + avatar: true, + email: true, + }, + }); + identity = { + name: username, + email: user?.email, + avatar: user?.avatar, + }; + } else if (teamname) { + const team = await prisma.team.findUnique({ + where: { + slug: teamname, + }, + select: { + logo: true, + }, + }); + identity = { + name: teamname, + shouldDefaultBeNameBased: true, + avatar: team?.logo, + }; + } const emailMd5 = crypto .createHash("md5") - .update((user?.email as string) || "guest@example.com") + .update((identity?.email as string) || "guest@example.com") .digest("hex"); - const img = user?.avatar; + const img = identity?.avatar; if (!img) { + let defaultSrc = defaultAvatarSrc({ md5: emailMd5 }); + if (identity?.shouldDefaultBeNameBased) { + defaultSrc = getPlaceholderAvatar(null, identity.name); + } res.writeHead(302, { - Location: defaultAvatarSrc({ md5: emailMd5 }), + Location: defaultSrc, }); + res.end(); } else if (!img.includes("data:image")) { res.writeHead(302, { diff --git a/apps/web/pages/event-types/index.tsx b/apps/web/pages/event-types/index.tsx index 75c366f570..ba010aee22 100644 --- a/apps/web/pages/event-types/index.tsx +++ b/apps/web/pages/event-types/index.tsx @@ -18,6 +18,7 @@ import Link from "next/link"; import { useRouter } from "next/router"; import React, { Fragment, useEffect, useState } from "react"; +import { WEBAPP_URL } from "@calcom/lib/constants"; import { useLocale } from "@calcom/lib/hooks/useLocale"; import showToast from "@calcom/lib/notification"; import { Button } from "@calcom/ui"; @@ -452,45 +453,48 @@ export const EventTypeList = ({ group, groupIndex, readOnly, types }: EventTypeL ); }; -const EventTypeListHeading = ({ profile, membershipCount }: EventTypeListHeadingProps): JSX.Element => ( -