Compare commits

..

No commits in common. "92806d5257043ecc43e319e26bd498c520ffc66b" and "9825754b3237a2fa9a9b5a279fc0cf0a59aadec4" have entirely different histories.

20 changed files with 104 additions and 1454 deletions

View file

@ -84,7 +84,7 @@ export default function App({
}, []); }, []);
return ( return (
<> <>
<Shell large isPublic> <Shell large>
<div className="-mx-4 md:-mx-8"> <div className="-mx-4 md:-mx-8">
<div className="bg-gray-50 px-4"> <div className="bg-gray-50 px-4">
<Link href="/apps"> <Link href="/apps">

View file

@ -2,6 +2,8 @@ import React from "react";
import { SkeletonText } from "@calcom/ui"; import { SkeletonText } from "@calcom/ui";
import BookingsShell from "@components/BookingsShell";
function SkeletonLoader() { function SkeletonLoader() {
return ( return (
<ul className="mt-6 animate-pulse divide-y divide-neutral-200 border border-gray-200 bg-white sm:mx-0 sm:overflow-hidden"> <ul className="mt-6 animate-pulse divide-y divide-neutral-200 border border-gray-200 bg-white sm:mx-0 sm:overflow-hidden">
@ -20,9 +22,10 @@ function SkeletonItem() {
<div className="flex-grow truncate text-sm"> <div className="flex-grow truncate text-sm">
<div className="flex"> <div className="flex">
<div className="flex flex-col space-y-2"> <div className="flex flex-col space-y-2">
<SkeletonText width="16" height="5" /> <SkeletonText width="32" height="5" />
<SkeletonText width="32" height="4" /> <SkeletonText width="16" height="4" />
</div> </div>
<SkeletonText width="24" height="5" className="ml-4" />
</div> </div>
</div> </div>
<div className="mt-4 hidden flex-shrink-0 sm:mt-0 sm:ml-5 lg:flex"> <div className="mt-4 hidden flex-shrink-0 sm:mt-0 sm:ml-5 lg:flex">

View file

@ -24,11 +24,18 @@ import { Frequency as RRuleFrequency } from "rrule";
import { v4 as uuidv4 } from "uuid"; import { v4 as uuidv4 } from "uuid";
import { z } from "zod"; import { z } from "zod";
import { useEmbedNonStylesConfig, useIsBackgroundTransparent, useIsEmbed } from "@calcom/embed-core"; import {
useIsEmbed,
useEmbedStyles,
useIsBackgroundTransparent,
useEmbedType,
useEmbedNonStylesConfig,
} from "@calcom/embed-core";
import classNames from "@calcom/lib/classNames"; import classNames from "@calcom/lib/classNames";
import { useLocale } from "@calcom/lib/hooks/useLocale"; import { useLocale } from "@calcom/lib/hooks/useLocale";
import { HttpError } from "@calcom/lib/http-error"; import { HttpError } from "@calcom/lib/http-error";
import { createPaymentLink } from "@calcom/stripe/client"; import { createPaymentLink } from "@calcom/stripe/client";
import { RecurringEvent } from "@calcom/types/Calendar";
import { Button } from "@calcom/ui/Button"; import { Button } from "@calcom/ui/Button";
import { Tooltip } from "@calcom/ui/Tooltip"; import { Tooltip } from "@calcom/ui/Tooltip";
import { EmailInput, Form } from "@calcom/ui/form/fields"; import { EmailInput, Form } from "@calcom/ui/form/fields";
@ -43,6 +50,7 @@ import createRecurringBooking from "@lib/mutations/bookings/create-recurring-boo
import { parseDate, parseRecurringDates } from "@lib/parseDate"; import { parseDate, parseRecurringDates } from "@lib/parseDate";
import slugify from "@lib/slugify"; import slugify from "@lib/slugify";
import { collectPageParameters, telemetryEventTypes, useTelemetry } from "@lib/telemetry"; import { collectPageParameters, telemetryEventTypes, useTelemetry } from "@lib/telemetry";
import { BookingCreateBody } from "@lib/types/booking";
import CustomBranding from "@components/CustomBranding"; import CustomBranding from "@components/CustomBranding";
import AvatarGroup from "@components/ui/AvatarGroup"; import AvatarGroup from "@components/ui/AvatarGroup";

View file

@ -4,7 +4,6 @@ import { MembershipRole } from "@prisma/client";
import Link from "next/link"; import Link from "next/link";
import { useState } from "react"; import { useState } from "react";
import { WEBSITE_URL } from "@calcom/lib/constants";
import { useLocale } from "@calcom/lib/hooks/useLocale"; import { useLocale } from "@calcom/lib/hooks/useLocale";
import showToast from "@calcom/lib/notification"; import showToast from "@calcom/lib/notification";
import Button from "@calcom/ui/Button"; import Button from "@calcom/ui/Button";
@ -18,6 +17,7 @@ import Dropdown, {
import { Tooltip } from "@calcom/ui/Tooltip"; import { Tooltip } from "@calcom/ui/Tooltip";
import TeamAvailabilityModal from "@ee/components/team/availability/TeamAvailabilityModal"; import TeamAvailabilityModal from "@ee/components/team/availability/TeamAvailabilityModal";
import { getPlaceholderAvatar } from "@lib/getPlaceholderAvatar";
import useCurrentUserId from "@lib/hooks/useCurrentUserId"; import useCurrentUserId from "@lib/hooks/useCurrentUserId";
import { inferQueryOutput, trpc } from "@lib/trpc"; import { inferQueryOutput, trpc } from "@lib/trpc";
@ -74,7 +74,7 @@ export default function MemberListItem(props: Props) {
<div className="flex w-full flex-col justify-between sm:flex-row"> <div className="flex w-full flex-col justify-between sm:flex-row">
<div className="flex"> <div className="flex">
<Avatar <Avatar
imageSrc={WEBSITE_URL + "/" + props.member.username + "/avatar.png"} imageSrc={getPlaceholderAvatar(props.member?.avatar, name)}
alt={name || ""} alt={name || ""}
className="h-9 w-9 rounded-full" className="h-9 w-9 rounded-full"
/> />

View file

@ -5,9 +5,9 @@ import Link from "next/link";
import { TeamPageProps } from "pages/team/[slug]"; import { TeamPageProps } from "pages/team/[slug]";
import React from "react"; import React from "react";
import { WEBSITE_URL } from "@calcom/lib/constants";
import Button from "@calcom/ui/Button"; import Button from "@calcom/ui/Button";
import { getPlaceholderAvatar } from "@lib/getPlaceholderAvatar";
import { useLocale } from "@lib/hooks/useLocale"; import { useLocale } from "@lib/hooks/useLocale";
import Avatar from "@components/ui/Avatar"; import Avatar from "@components/ui/Avatar";
@ -52,7 +52,7 @@ const Team = ({ team }: TeamPageProps) => {
<div> <div>
<Avatar <Avatar
alt={member.name || ""} alt={member.name || ""}
imageSrc={WEBSITE_URL + "/" + member.username + "/avatar.png"} imageSrc={getPlaceholderAvatar(member.avatar, member.username)}
className="-mt-4 h-12 w-12" className="-mt-4 h-12 w-12"
/> />
<section className="mt-2 w-full space-y-1"> <section className="mt-2 w-full space-y-1">

View file

@ -24,7 +24,7 @@ export default function ApiKeyListContainer() {
query={query} query={query}
success={({ data }) => ( success={({ data }) => (
<> <>
<div className="flex flex-col justify-between truncate pl-2 pr-1 sm:flex-row"> <div className=" flex flex-col justify-between truncate pl-2 pr-1 sm:flex-row">
<div className="mt-9"> <div className="mt-9">
<h2 className="font-cal text-lg font-medium leading-6 text-gray-900">{t("api_keys")}</h2> <h2 className="font-cal text-lg font-medium leading-6 text-gray-900">{t("api_keys")}</h2>
<p className="mt-1 mb-5 text-sm text-gray-500">{t("api_keys_subtitle")}</p> <p className="mt-1 mb-5 text-sm text-gray-500">{t("api_keys_subtitle")}</p>

View file

@ -3,8 +3,7 @@ import utc from "dayjs/plugin/utc";
import React, { useState, useEffect } from "react"; import React, { useState, useEffect } from "react";
import TimezoneSelect, { ITimezone } from "react-timezone-select"; import TimezoneSelect, { ITimezone } from "react-timezone-select";
import { WEBSITE_URL } from "@calcom/lib/constants"; import { getPlaceholderAvatar } from "@lib/getPlaceholderAvatar";
import { trpc, inferQueryOutput } from "@lib/trpc"; import { trpc, inferQueryOutput } from "@lib/trpc";
import Avatar from "@components/ui/Avatar"; import Avatar from "@components/ui/Avatar";
@ -37,7 +36,7 @@ export default function TeamAvailabilityModal(props: Props) {
<div className="min-w-64 w-64 space-y-5 p-5 pr-0"> <div className="min-w-64 w-64 space-y-5 p-5 pr-0">
<div className="flex"> <div className="flex">
<Avatar <Avatar
imageSrc={WEBSITE_URL + "/" + props.member?.username + "/avatar.png"} imageSrc={getPlaceholderAvatar(props.member?.avatar, props.member?.name as string)}
alt={props.member?.name || ""} alt={props.member?.name || ""}
className="h-14 w-14 rounded-full" className="h-14 w-14 rounded-full"
/> />

View file

@ -4,8 +4,7 @@ import TimezoneSelect, { ITimezone } from "react-timezone-select";
import AutoSizer from "react-virtualized-auto-sizer"; import AutoSizer from "react-virtualized-auto-sizer";
import { FixedSizeList as List } from "react-window"; import { FixedSizeList as List } from "react-window";
import { WEBSITE_URL } from "@calcom/lib/constants"; import { getPlaceholderAvatar } from "@lib/getPlaceholderAvatar";
import { trpc, inferQueryOutput } from "@lib/trpc"; import { trpc, inferQueryOutput } from "@lib/trpc";
import Avatar from "@components/ui/Avatar"; import Avatar from "@components/ui/Avatar";
@ -46,7 +45,7 @@ export default function TeamAvailabilityScreen(props: Props) {
HeaderComponent={ HeaderComponent={
<div className="mb-6 flex items-center"> <div className="mb-6 flex items-center">
<Avatar <Avatar
imageSrc={WEBSITE_URL + "/" + member.username + "/avatar.png"} imageSrc={getPlaceholderAvatar(member?.avatar, member?.name as string)}
alt={member?.name || ""} alt={member?.name || ""}
className="min-w-10 min-h-10 mt-1 h-10 w-10 rounded-full" className="min-w-10 min-h-10 mt-1 h-10 w-10 rounded-full"
/> />

View file

@ -11,6 +11,7 @@ export type TeamWithMembers = AsyncReturnType<typeof getTeamWithMembers>;
export async function getTeamWithMembers(id?: number, slug?: string) { export async function getTeamWithMembers(id?: number, slug?: string) {
const userSelect = Prisma.validator<Prisma.UserSelect>()({ const userSelect = Prisma.validator<Prisma.UserSelect>()({
username: true, username: true,
avatar: true,
email: true, email: true,
name: true, name: true,
id: true, id: true,

View file

@ -1,6 +1,6 @@
{ {
"name": "@calcom/web", "name": "@calcom/web",
"version": "1.5.4", "version": "1.5.3",
"private": true, "private": true,
"scripts": { "scripts": {
"analyze": "ANALYZE=true next build", "analyze": "ANALYZE=true next build",

View file

@ -60,7 +60,10 @@ export default function Bookings() {
}; };
return ( return (
<Shell heading={t("bookings")} subtitle={t("bookings_description")} customLoader={<SkeletonLoader />}> <Shell
heading={t("bookings")}
subtitle={t("bookings_description")}
customLoader={<SkeletonLoader></SkeletonLoader>}>
<WipeMyCalActionButton trpc={trpc} bookingStatus={status} bookingsEmpty={isEmpty} /> <WipeMyCalActionButton trpc={trpc} bookingStatus={status} bookingsEmpty={isEmpty} />
<BookingsShell> <BookingsShell>
<div className="-mx-4 flex flex-col sm:mx-auto"> <div className="-mx-4 flex flex-col sm:mx-auto">

View file

@ -13,7 +13,7 @@ import { useSession } from "next-auth/react";
import Link from "next/link"; import Link from "next/link";
import { useRouter } from "next/router"; import { useRouter } from "next/router";
import { useEffect, useRef, useState } from "react"; import { useEffect, useRef, useState } from "react";
import RRule from "rrule"; import rrule from "rrule";
import { SpaceBookingSuccessPage } from "@calcom/app-store/spacebooking/components"; import { SpaceBookingSuccessPage } from "@calcom/app-store/spacebooking/components";
import { import {
@ -379,7 +379,7 @@ export default function Success(props: SuccessProps) {
: "") + : "") +
(props.eventType.recurringEvent (props.eventType.recurringEvent
? "&recur=" + ? "&recur=" +
encodeURIComponent(new RRule(props.eventType.recurringEvent).toString()) encodeURIComponent(new rrule(props.eventType.recurringEvent).toString())
: "") : "")
}> }>
<a className="mx-2 h-10 w-10 rounded-sm border border-neutral-200 px-3 py-2 dark:border-neutral-700 dark:text-white"> <a className="mx-2 h-10 w-10 rounded-sm border border-neutral-200 px-3 py-2 dark:border-neutral-700 dark:text-white">

View file

@ -6,7 +6,6 @@ import Link from "next/link";
import React, { useEffect } from "react"; import React, { useEffect } from "react";
import { useIsEmbed } from "@calcom/embed-core"; import { useIsEmbed } from "@calcom/embed-core";
import { WEBSITE_URL } from "@calcom/lib/constants";
import Button from "@calcom/ui/Button"; import Button from "@calcom/ui/Button";
import { getPlaceholderAvatar } from "@lib/getPlaceholderAvatar"; import { getPlaceholderAvatar } from "@lib/getPlaceholderAvatar";
@ -14,6 +13,7 @@ import { useExposePlanGlobally } from "@lib/hooks/useExposePlanGlobally";
import { useLocale } from "@lib/hooks/useLocale"; import { useLocale } from "@lib/hooks/useLocale";
import useTheme from "@lib/hooks/useTheme"; import useTheme from "@lib/hooks/useTheme";
import { useToggleQuery } from "@lib/hooks/useToggleQuery"; import { useToggleQuery } from "@lib/hooks/useToggleQuery";
import { defaultAvatarSrc } from "@lib/profile";
import { getTeamWithMembers } from "@lib/queries/teams"; import { getTeamWithMembers } from "@lib/queries/teams";
import { collectPageParameters, telemetryEventTypes, useTelemetry } from "@lib/telemetry"; import { collectPageParameters, telemetryEventTypes, useTelemetry } from "@lib/telemetry";
import { inferSSRProps } from "@lib/types/inferSSRProps"; import { inferSSRProps } from "@lib/types/inferSSRProps";
@ -68,7 +68,7 @@ function TeamPage({ team }: TeamPageProps) {
size={10} size={10}
items={type.users.map((user) => ({ items={type.users.map((user) => ({
alt: user.name || "", alt: user.name || "",
image: WEBSITE_URL + "/" + user.username + "/avatar.png" || "", image: user.avatar || "",
}))} }))}
/> />
</div> </div>
@ -147,7 +147,7 @@ export const getServerSideProps = async (context: GetServerSidePropsContext) =>
...type, ...type,
users: type.users.map((user) => ({ users: type.users.map((user) => ({
...user, ...user,
avatar: WEBSITE_URL + "/" + user.username + "/avatar.png", avatar: user.avatar || defaultAvatarSrc({ email: user.email || "" }),
})), })),
})); }));

View file

@ -820,6 +820,5 @@
"zapier_setup_instructions": "<0>Log into your Zapier account and create a new Zap.</0><1>Select Cal.com as your Trigger app. Also choose a Trigger event.</1><2>Choose your account and then enter your Unique API Key.</2><3>Test your Trigger.</3><4>You're set!</4>", "zapier_setup_instructions": "<0>Log into your Zapier account and create a new Zap.</0><1>Select Cal.com as your Trigger app. Also choose a Trigger event.</1><2>Choose your account and then enter your Unique API Key.</2><3>Test your Trigger.</3><4>You're set!</4>",
"install_zapier_app": "Please first install the Zapier App in the app store.", "install_zapier_app": "Please first install the Zapier App in the app store.",
"go_to_app_store": "Go to App Store", "go_to_app_store": "Go to App Store",
"calendar_error": "Something went wrong, try reconnecting your calendar with all necessary permissions", "calendar_error": "Something went wrong, try reconnecting your calendar with all necessary permissions"
"calendar_no_busy_slots": "There are no busy slots"
} }

View file

@ -28,7 +28,7 @@
"heroku-postbuild": "turbo run @calcom/web#build", "heroku-postbuild": "turbo run @calcom/web#build",
"lint": "turbo run lint", "lint": "turbo run lint",
"lint:report": "turbo run lint:report", "lint:report": "turbo run lint:report",
"postinstall": "turbo run post-install", "postinstall": "turbo run postinstall",
"pre-commit": "lint-staged", "pre-commit": "lint-staged",
"env-check:common": "dotenv-checker --schema .env.example --env .env", "env-check:common": "dotenv-checker --schema .env.example --env .env",
"env-check:app-store": "dotenv-checker --schema .env.appStore.example --env .env.appStore", "env-check:app-store": "dotenv-checker --schema .env.appStore.example --env .env.appStore",

View file

@ -1,4 +1,3 @@
export * as api from "./api"; export * as api from "./api";
export * as components from "./components";
export * as lib from "./lib"; export * as lib from "./lib";
export { metadata } from "./_metadata"; export { metadata } from "./_metadata";

View file

@ -3,7 +3,7 @@
"version": "0.0.0", "version": "0.0.0",
"private": true, "private": true,
"scripts": { "scripts": {
"build": "yarn prisma migrate deploy && yarn seed-app-store", "build": "yarn generate-schemas",
"clean": "rm -rf .turbo && rm -rf node_modules", "clean": "rm -rf .turbo && rm -rf node_modules",
"db-deploy": "yarn prisma migrate deploy", "db-deploy": "yarn prisma migrate deploy",
"db-migrate": "yarn prisma migrate dev", "db-migrate": "yarn prisma migrate dev",
@ -13,9 +13,10 @@
"db-setup": "run-s db-up db-deploy db-seed", "db-setup": "run-s db-up db-deploy db-seed",
"db-studio": "yarn prisma studio", "db-studio": "yarn prisma studio",
"db-up": "docker-compose up -d", "db-up": "docker-compose up -d",
"deploy": "yarn prisma migrate deploy && yarn seed-app-store",
"dx": "yarn db-setup", "dx": "yarn db-setup",
"generate-schemas": "prisma generate && prisma format", "generate-schemas": "prisma generate && prisma format",
"post-install": "yarn generate-schemas", "postinstall": "yarn generate-schemas",
"seed-app-store": "ts-node --transpile-only ./seed-app-store.ts" "seed-app-store": "ts-node --transpile-only ./seed-app-store.ts"
}, },
"devDependencies": { "devDependencies": {

View file

@ -3,6 +3,10 @@
"baseBranch": "origin/main", "baseBranch": "origin/main",
"globalDependencies": [".env", "packages/prisma/.env"], "globalDependencies": [".env", "packages/prisma/.env"],
"pipeline": { "pipeline": {
"@calcom/prisma#build": {
"dependsOn": ["$DATABASE_URL"],
"outputs": ["zod/**"]
},
"@calcom/prisma#db-deploy": { "@calcom/prisma#db-deploy": {
"cache": false, "cache": false,
"dependsOn": ["$DATABASE_URL"] "dependsOn": ["$DATABASE_URL"]
@ -99,7 +103,7 @@
"db-seed": {}, "db-seed": {},
"deploy": { "deploy": {
"cache": false, "cache": false,
"dependsOn": ["@calcom/web#build"], "dependsOn": ["@calcom/web#build", "@calcom/embed-core#build"],
"outputs": [] "outputs": []
}, },
"clean": { "clean": {
@ -119,7 +123,7 @@
"cache": false, "cache": false,
"outputs": ["lint-results"] "outputs": ["lint-results"]
}, },
"post-install": {}, "postinstall": {},
"start": {}, "start": {},
"embed-tests": { "embed-tests": {
"cache": false "cache": false

1480
yarn.lock

File diff suppressed because it is too large Load diff