tailwind prettier (#1646)

* tailwind prettier

* Minor fixes

* Sorts components and pages

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
Co-authored-by: zomars <zomars@me.com>
pull/1764/head
Peer Richelsen 2022-02-09 00:05:13 +00:00 committed by GitHub
parent 1e9234ea67
commit 51d553559f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
125 changed files with 977 additions and 945 deletions

View File

@ -9,4 +9,5 @@ module.exports = {
arrowParens: "always",
importOrder: ["^@ee/(.*)$", "^@lib/(.*)$", "^@components/(.*)$", "^@(server|trpc)/(.*)$", "^[./]"],
importOrderSeparation: true,
plugins: [require("prettier-plugin-tailwindcss")],
};

View File

@ -5,7 +5,6 @@
"esbenp.prettier-vscode", // prettier plugin
"dbaeumer.vscode-eslint", // eslint plugin
"bradlc.vscode-tailwindcss", // hinting / autocompletion for tailwind
"heybourn.headwind", // automatically sort tailwind classes in predictable order, kinda like "prettier for tailwind",
"ban.spellright", // Spell check for docs
"stripe.vscode-stripe" // stripe VSCode extension
]

View File

@ -0,0 +1,15 @@
declare module "@wojtekmaj/react-daterange-picker/dist/entry.nostyle" {
import { CalendarProps } from "react-calendar";
export type DateRangePickerCalendarProps = Omit<
CalendarProps,
"calendarClassName" | "onChange" | "value"
> & {
calendarClassName?: string;
onChange: (value: [Date, Date]) => void;
value: [Date, Date];
clearIcon: JSX.Element | null;
calendarIcon: JSX.Element | null;
rangeDivider: JSX.Element | null;
};
export default function DateRangePicker(props: DateRangePickerCalendarProps): JSX.Element;
}

View File

@ -14,13 +14,13 @@ export default function AddToHomescreen() {
}
return !closeBanner ? (
<div className="fixed inset-x-0 bottom-0 pb-2 sm:hidden sm:pb-5">
<div className="px-2 mx-auto max-w-7xl sm:px-6 lg:px-8">
<div className="p-2 rounded-lg shadow-lg sm:p-3" style={{ background: "#2F333D" }}>
<div className="mx-auto max-w-7xl px-2 sm:px-6 lg:px-8">
<div className="rounded-lg p-2 shadow-lg sm:p-3" style={{ background: "#2F333D" }}>
<div className="flex flex-wrap items-center justify-between">
<div className="flex items-center flex-1 w-0">
<span className="flex p-2 rounded-lg bg-opacity-30 bg-brand text-brandcontrast">
<div className="flex w-0 flex-1 items-center">
<span className="flex rounded-lg bg-brand bg-opacity-30 p-2 text-brandcontrast">
<svg
className="text-indigo-500 fill-current h-7 w-7"
className="h-7 w-7 fill-current text-indigo-500"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 50 50"
enableBackground="new 0 0 50 50">
@ -34,13 +34,13 @@ export default function AddToHomescreen() {
</p>
</div>
<div className="flex-shrink-0 order-2 sm:order-3">
<div className="order-2 flex-shrink-0 sm:order-3">
<button
onClick={() => setCloseBanner(true)}
type="button"
className="flex p-2 -mr-1 rounded-md hover:bg-gray-800 focus:outline-none focus:ring-2 focus:ring-white">
className="-mr-1 flex rounded-md p-2 hover:bg-gray-800 focus:outline-none focus:ring-2 focus:ring-white">
<span className="sr-only">{t("dismiss")}</span>
<XIcon className="w-6 h-6 text-white" aria-hidden="true" />
<XIcon className="h-6 w-6 text-white" aria-hidden="true" />
</button>
</div>
</div>

View File

@ -56,8 +56,8 @@ const DestinationCalendarSelector = ({
<div className="relative">
{/* There's no easy way to customize the displayed value for a Select, so we fake it. */}
{!hidePlaceholder && (
<div className="absolute z-10 pointer-events-none">
<Button size="sm" color="secondary" className="border-transparent m-[1px] rounded-sm">
<div className="pointer-events-none absolute z-10">
<Button size="sm" color="secondary" className="m-[1px] rounded-sm border-transparent">
{t("select_destination_calendar")}: {selectedOption?.label || ""}
</Button>
</div>
@ -67,7 +67,7 @@ const DestinationCalendarSelector = ({
placeholder={!hidePlaceholder ? `${t("select_destination_calendar")}:` : undefined}
options={options}
isSearchable={false}
className="flex-1 block w-full min-w-0 mt-1 mb-2 border-gray-300 rounded-none focus:ring-primary-500 focus:border-primary-500 rounded-r-md sm:text-sm"
className="mt-1 mb-2 block w-full min-w-0 flex-1 rounded-none rounded-r-md border-gray-300 focus:border-primary-500 focus:ring-primary-500 sm:text-sm"
onChange={(option) => {
setSelectedOption(option);
if (!option) {

View File

@ -6,7 +6,7 @@ export function Dialog(props: DialogProps) {
const { children, ...other } = props;
return (
<DialogPrimitive.Root {...other}>
<DialogPrimitive.Overlay className="fixed inset-0 transition-opacity bg-gray-500 bg-opacity-75" />
<DialogPrimitive.Overlay className="fixed inset-0 bg-gray-500 bg-opacity-75 transition-opacity" />
{children}
</DialogPrimitive.Root>
);
@ -17,7 +17,7 @@ export const DialogContent = React.forwardRef<HTMLDivElement, DialogContentProps
({ children, ...props }, forwardedRef) => (
<DialogPrimitive.Content
{...props}
className="min-w-[360px] fixed left-1/2 top-1/2 p-6 text-left bg-white rounded shadow-xl -translate-x-1/2 -translate-y-1/2 sm:align-middle sm:w-full sm:max-w-lg"
className="fixed left-1/2 top-1/2 min-w-[360px] -translate-x-1/2 -translate-y-1/2 rounded bg-white p-6 text-left shadow-xl sm:w-full sm:max-w-lg sm:align-middle"
ref={forwardedRef}>
{children}
</DialogPrimitive.Content>
@ -32,7 +32,7 @@ type DialogHeaderProps = {
export function DialogHeader(props: DialogHeaderProps) {
return (
<div className="mb-8">
<h3 className="text-xl text-gray-900 leading-16 font-cal" id="modal-title">
<h3 className="leading-16 font-cal text-xl text-gray-900" id="modal-title">
{props.title}
</h3>
{props.subtitle && <div className="text-sm text-gray-400">{props.subtitle}</div>}
@ -43,7 +43,7 @@ export function DialogHeader(props: DialogHeaderProps) {
export function DialogFooter(props: { children: ReactNode }) {
return (
<div>
<div className="flex justify-end mt-5 rtl:space-x-reverse space-x-2">{props.children}</div>
<div className="mt-5 flex justify-end space-x-2 rtl:space-x-reverse">{props.children}</div>
</div>
);
}

View File

@ -13,12 +13,12 @@ export default function EmptyScreen({
}) {
return (
<>
<div className="min-h-80 border border-dashed rounded-sm flex justify-center items-center flex-col my-6">
<div className="bg-white w-[72px] h-[72px] flex justify-center items-center rounded-full">
<Icon className="inline-block w-10 h-10 bg-white" />
<div className="my-6 flex min-h-80 flex-col items-center justify-center rounded-sm border border-dashed">
<div className="flex h-[72px] w-[72px] items-center justify-center rounded-full bg-white">
<Icon className="inline-block h-10 w-10 bg-white" />
</div>
<div className="max-w-[420px] text-center">
<h2 className="text-lg font-medium mt-6 mb-1">{headline}</h2>
<h2 className="mt-6 mb-1 text-lg font-medium">{headline}</h2>
<p className="text-sm leading-6 text-gray-600">{description}</p>
</div>
</div>

View File

@ -38,8 +38,8 @@ function CropContainer({
};
return (
<div className="w-40 h-40 rounded-full crop-container max-h-40">
<div className="relative w-40 h-40 rounded-full">
<div className="crop-container h-40 max-h-40 w-40 rounded-full">
<div className="relative h-40 w-40 rounded-full">
<Cropper
image={imageSrc}
crop={crop}
@ -119,38 +119,38 @@ export default function ImageUploader({
<DialogContent>
<div className="mb-4 sm:flex sm:items-start">
<div className="mt-3 text-center sm:mt-0 sm:text-left">
<h3 className="text-lg font-bold leading-6 text-gray-900 font-cal" id="modal-title">
<h3 className="font-cal text-lg font-bold leading-6 text-gray-900" id="modal-title">
{t("upload_target", { target })}
</h3>
</div>
</div>
<div className="mb-4">
<div className="flex flex-col items-center justify-center p-8 mt-6 cropper">
<div className="cropper mt-6 flex flex-col items-center justify-center p-8">
{!result && (
<div className="flex items-center justify-start w-20 h-20 bg-gray-50 rounded-full max-h-20">
<div className="flex h-20 max-h-20 w-20 items-center justify-start rounded-full bg-gray-50">
{!imageSrc && (
<p className="w-full text-sm text-center text-white sm:text-xs">
<p className="w-full text-center text-sm text-white sm:text-xs">
{t("no_target", { target })}
</p>
)}
{imageSrc && <img className="w-20 h-20 rounded-full" src={imageSrc} alt={target} />}
{imageSrc && <img className="h-20 w-20 rounded-full" src={imageSrc} alt={target} />}
</div>
)}
{result && <CropContainer imageSrc={result as string} onCropComplete={setCroppedAreaPixels} />}
<label className="px-3 py-1 mt-8 text-xs font-medium leading-4 text-gray-700 bg-white border border-gray-300 rounded-sm hover:bg-gray-50 hover:text-gray-900 hover:shadow-sm focus:outline-none focus:ring-2 focus:ring-offset-1 focus:ring-neutral-900 dark:bg-transparent dark:text-white dark:border-gray-800 dark:hover:bg-gray-900">
<label className="mt-8 rounded-sm border border-gray-300 bg-white px-3 py-1 text-xs font-medium leading-4 text-gray-700 hover:bg-gray-50 hover:text-gray-900 hover:shadow-sm focus:outline-none focus:ring-2 focus:ring-neutral-900 focus:ring-offset-1 dark:border-gray-800 dark:bg-transparent dark:text-white dark:hover:bg-gray-900">
<input
onInput={onInputFile}
type="file"
name={id}
placeholder={t("upload_image")}
className="absolute mt-4 opacity-0 pointer-events-none"
className="pointer-events-none absolute mt-4 opacity-0"
accept="image/*"
/>
{t("choose_a_file")}
</label>
</div>
</div>
<div className="mt-5 sm:mt-4 sm:flex sm:flex-row-reverse gap-x-2">
<div className="mt-5 gap-x-2 sm:mt-4 sm:flex sm:flex-row-reverse">
<DialogClose asChild>
<Button onClick={() => showCroppedImage(croppedAreaPixels)}>{t("save")}</Button>
</DialogClose>

View File

@ -5,7 +5,7 @@ import classNames from "@lib/classNames";
export function List(props: JSX.IntrinsicElements["ul"]) {
return (
<ul {...props} className={classNames("sm:overflow-hidden rounded-sm sm:mx-0 -mx-4", props.className)}>
<ul {...props} className={classNames("-mx-4 rounded-sm sm:mx-0 sm:overflow-hidden", props.className)}>
{props.children}
</ul>
);

View File

@ -3,7 +3,7 @@ export default function Logo({ small, icon }: { small?: boolean; icon?: boolean
<h1 className="inline">
<strong>
{icon ? (
<img className="w-9 mx-auto" alt="Cal" title="Cal" src="/cal-com-icon-white.svg" />
<img className="mx-auto w-9" alt="Cal" title="Cal" src="/cal-com-icon-white.svg" />
) : (
<img
className={small ? "h-4 w-auto" : "h-5 w-auto"}

View File

@ -18,7 +18,7 @@ const NavTabs: FC<Props> = ({ tabs, linkProps }) => {
return (
<>
<nav
className="flex -mb-px space-x-2 space-x-5 rtl:space-x-reverse sm:rtl:space-x-reverse"
className="-mb-px flex space-x-2 space-x-5 rtl:space-x-reverse sm:rtl:space-x-reverse"
aria-label="Tabs">
{tabs.map((tab) => {
const isCurrent = router.asPath === tab.href;
@ -28,15 +28,15 @@ const NavTabs: FC<Props> = ({ tabs, linkProps }) => {
className={classNames(
isCurrent
? "border-neutral-900 text-neutral-900"
: "border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300",
"group inline-flex items-center py-4 px-1 border-b-2 font-medium text-sm"
: "border-transparent text-gray-500 hover:border-gray-300 hover:text-gray-700",
"group inline-flex items-center border-b-2 py-4 px-1 text-sm font-medium"
)}
aria-current={isCurrent ? "page" : undefined}>
{tab.icon && (
<tab.icon
className={classNames(
isCurrent ? "text-neutral-900" : "text-gray-400 group-hover:text-gray-500",
"-ml-0.5 ltr:mr-2 rtl:ml-2 h-5 w-5 hidden sm:inline-block"
"-ml-0.5 hidden h-5 w-5 ltr:mr-2 rtl:ml-2 sm:inline-block"
)}
aria-hidden="true"
/>

View File

@ -104,12 +104,12 @@ export function ShellSubHeading(props: {
className?: string;
}) {
return (
<div className={classNames("block sm:flex justify-between mb-3", props.className)}>
<div className={classNames("mb-3 block justify-between sm:flex", props.className)}>
<div>
<h2 className="flex items-center content-center space-x-2 text-base font-bold leading-6 text-gray-900 rtl:space-x-reverse">
<h2 className="flex content-center items-center space-x-2 text-base font-bold leading-6 text-gray-900 rtl:space-x-reverse">
{props.title}
</h2>
{props.subtitle && <p className="text-sm ltr:mr-4 text-neutral-500">{props.subtitle}</p>}
{props.subtitle && <p className="text-sm text-neutral-500 ltr:mr-4">{props.subtitle}</p>}
</div>
{props.actions && <div className="flex-shrink-0">{props.actions}</div>}
</div>
@ -184,7 +184,7 @@ export default function Shell(props: {
if (i18n.status === "loading" || isRedirectingToOnboarding || loading) {
// show spinner whilst i18n is loading to avoid language flicker
return (
<div className="absolute z-50 flex items-center w-full h-screen bg-gray-50">
<div className="absolute z-50 flex h-screen w-full items-center bg-gray-50">
<Loader />
</div>
);
@ -206,9 +206,9 @@ export default function Shell(props: {
<div className="flex h-screen overflow-hidden bg-gray-100" data-testid="dashboard-shell">
<div className="hidden md:flex lg:flex-shrink-0">
<div className="flex flex-col w-14 lg:w-56">
<div className="flex flex-col flex-1 h-0 bg-white border-r border-gray-200">
<div className="flex flex-col flex-1 pt-3 pb-4 overflow-y-auto lg:pt-5">
<div className="flex w-14 flex-col lg:w-56">
<div className="flex h-0 flex-1 flex-col border-r border-gray-200 bg-white">
<div className="flex flex-1 flex-col overflow-y-auto pt-3 pb-4 lg:pt-5">
<Link href="/event-types">
<a className="px-4 md:hidden lg:inline">
<Logo small />
@ -220,7 +220,7 @@ export default function Shell(props: {
<Logo small icon />
</a>
</Link>
<nav className="flex-1 px-2 mt-2 space-y-1 bg-white lg:mt-5">
<nav className="mt-2 flex-1 space-y-1 bg-white px-2 lg:mt-5">
{navigation.map((item) => (
<Link key={item.name} href={item.href}>
<a
@ -228,14 +228,14 @@ export default function Shell(props: {
item.current
? "bg-neutral-100 text-neutral-900"
: "text-neutral-500 hover:bg-gray-50 hover:text-neutral-900",
"group flex items-center px-2 py-2 text-sm font-medium rounded-sm"
"group flex items-center rounded-sm px-2 py-2 text-sm font-medium"
)}>
<item.icon
className={classNames(
item.current
? "text-neutral-500"
: "text-neutral-400 group-hover:text-neutral-500",
"ltr:mr-3 rtl:ml-3 flex-shrink-0 h-5 w-5"
"h-5 w-5 flex-shrink-0 ltr:mr-3 rtl:ml-3"
)}
aria-hidden="true"
/>
@ -246,7 +246,7 @@ export default function Shell(props: {
</nav>
</div>
<TrialBanner />
<div className="p-2 pt-2 pr-2 m-2 rounded-sm hover:bg-gray-100">
<div className="m-2 rounded-sm p-2 pt-2 pr-2 hover:bg-gray-100">
<span className="hidden lg:inline">
<UserDropdown />
</span>
@ -258,25 +258,25 @@ export default function Shell(props: {
</div>
</div>
<div className="flex flex-col flex-1 w-0 overflow-hidden">
<div className="flex w-0 flex-1 flex-col overflow-hidden">
<main
className={classNames(
"flex-1 relative z-0 overflow-y-auto focus:outline-none max-w-[1700px]",
"relative z-0 max-w-[1700px] flex-1 overflow-y-auto focus:outline-none",
props.flexChildrenContainer && "flex flex-col"
)}>
{/* show top navigation for md and smaller (tablet and phones) */}
<nav className="flex items-center justify-between p-4 bg-white border-b border-gray-200 md:hidden">
<nav className="flex items-center justify-between border-b border-gray-200 bg-white p-4 md:hidden">
<Link href="/event-types">
<a>
<Logo />
</a>
</Link>
<div className="flex items-center self-center gap-3">
<button className="p-2 text-gray-400 bg-white rounded-full hover:text-gray-500 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-black">
<div className="flex items-center gap-3 self-center">
<button className="rounded-full bg-white p-2 text-gray-400 hover:bg-gray-50 hover:text-gray-500 focus:outline-none focus:ring-2 focus:ring-black focus:ring-offset-2">
<span className="sr-only">{t("view_notifications")}</span>
<Link href="/settings/profile">
<a>
<CogIcon className="w-6 h-6" aria-hidden="true" />
<CogIcon className="h-6 w-6" aria-hidden="true" />
</a>
</Link>
</button>
@ -285,8 +285,8 @@ export default function Shell(props: {
</nav>
<div
className={classNames(
props.centered && "md:max-w-5xl mx-auto",
props.flexChildrenContainer && "flex flex-col flex-1",
props.centered && "mx-auto md:max-w-5xl",
props.flexChildrenContainer && "flex flex-1 flex-col",
"py-8"
)}>
{!!props.backPath && (
@ -299,25 +299,25 @@ export default function Shell(props: {
</Button>
</div>
)}
<div className="block sm:flex justify-between px-4 sm:px-6 md:px-8 min-h-[80px]">
<div className="block min-h-[80px] justify-between px-4 sm:flex sm:px-6 md:px-8">
{props.HeadingLeftIcon && <div className="ltr:mr-4">{props.HeadingLeftIcon}</div>}
<div className="w-full mb-8">
<h1 className="mb-1 text-xl font-bold tracking-wide text-gray-900 font-cal">
<div className="mb-8 w-full">
<h1 className="mb-1 font-cal text-xl font-bold tracking-wide text-gray-900">
{props.heading}
</h1>
<p className="text-sm ltr:mr-4 rtl:ml-4 text-neutral-500">{props.subtitle}</p>
<p className="text-sm text-neutral-500 ltr:mr-4 rtl:ml-4">{props.subtitle}</p>
</div>
<div className="flex-shrink-0 mb-4">{props.CTA}</div>
<div className="mb-4 flex-shrink-0">{props.CTA}</div>
</div>
<div
className={classNames(
"px-4 sm:px-6 md:px-8",
props.flexChildrenContainer && "flex flex-col flex-1"
props.flexChildrenContainer && "flex flex-1 flex-col"
)}>
{props.children}
</div>
{/* show bottom navigation for md and smaller (tablet and phones) */}
<nav className="fixed bottom-0 z-40 flex w-full bg-white shadow bottom-nav md:hidden">
<nav className="bottom-nav fixed bottom-0 z-40 flex w-full bg-white shadow md:hidden">
{/* note(PeerRich): using flatMap instead of map to remove settings from bottom nav */}
{navigation.flatMap((item, itemIdx) =>
item.href === "/settings/profile" ? (
@ -329,13 +329,13 @@ export default function Shell(props: {
item.current ? "text-gray-900" : "text-neutral-400 hover:text-gray-700",
itemIdx === 0 ? "rounded-l-lg" : "",
itemIdx === navigation.length - 1 ? "rounded-r-lg" : "",
"group relative min-w-0 flex-1 overflow-hidden bg-white py-2 px-2 text-xs sm:text-sm font-medium text-center hover:bg-gray-50 focus:z-10"
"group relative min-w-0 flex-1 overflow-hidden bg-white py-2 px-2 text-center text-xs font-medium hover:bg-gray-50 focus:z-10 sm:text-sm"
)}
aria-current={item.current ? "page" : undefined}>
<item.icon
className={classNames(
item.current ? "text-gray-900" : "text-gray-400 group-hover:text-gray-500",
"block mx-auto flex-shrink-0 h-5 w-5 mb-1 text-center"
"mx-auto mb-1 block h-5 w-5 flex-shrink-0 text-center"
)}
aria-hidden="true"
/>
@ -370,11 +370,11 @@ function UserDropdown({ small }: { small?: boolean }) {
return (
<Dropdown>
<DropdownMenuTrigger asChild>
<div className="flex items-center w-full appearance-none cursor-pointer group">
<div className="group flex w-full cursor-pointer appearance-none items-center">
<span
className={classNames(
small ? "w-8 h-8" : "w-10 h-10",
"bg-gray-300 rounded-full flex-shrink-0 relative ltr:mr-3 rtl:ml-3"
small ? "h-8 w-8" : "h-10 w-10",
"relative flex-shrink-0 rounded-full bg-gray-300 ltr:mr-3 rtl:ml-3"
)}>
<img
className="rounded-full"
@ -387,24 +387,24 @@ function UserDropdown({ small }: { small?: boolean }) {
alt={user?.username || "Nameless User"}
/>
{!user?.away && (
<div className="absolute bottom-0 right-0 w-3 h-3 bg-green-500 border-2 border-white rounded-full"></div>
<div className="absolute bottom-0 right-0 h-3 w-3 rounded-full border-2 border-white bg-green-500"></div>
)}
{user?.away && (
<div className="absolute bottom-0 right-0 w-3 h-3 bg-yellow-500 border-2 border-white rounded-full"></div>
<div className="absolute bottom-0 right-0 h-3 w-3 rounded-full border-2 border-white bg-yellow-500"></div>
)}
</span>
{!small && (
<span className="flex items-center flex-grow truncate">
<span className="flex-grow text-sm truncate">
<span className="block font-medium text-gray-900 truncate">
<span className="flex flex-grow items-center truncate">
<span className="flex-grow truncate text-sm">
<span className="block truncate font-medium text-gray-900">
{user?.username || "Nameless User"}
</span>
<span className="block font-normal truncate text-neutral-500">
<span className="block truncate font-normal text-neutral-500">
{user?.username ? `cal.com/${user.username}` : "No public page"}
</span>
</span>
<SelectorIcon
className="flex-shrink-0 w-5 h-5 text-gray-400 group-hover:text-gray-500"
className="h-5 w-5 flex-shrink-0 text-gray-400 group-hover:text-gray-500"
aria-hidden="true"
/>
</span>
@ -418,13 +418,13 @@ function UserDropdown({ small }: { small?: boolean }) {
mutation.mutate({ away: !user?.away });
utils.invalidateQueries("viewer.me");
}}
className="flex px-4 py-2 text-sm cursor-pointer hover:bg-gray-100 hover:text-gray-900">
className="flex cursor-pointer px-4 py-2 text-sm hover:bg-gray-100 hover:text-gray-900">
<MoonIcon
className={classNames(
user?.away
? "text-purple-500 group-hover:text-purple-700"
: "text-gray-500 group-hover:text-gray-700",
"ltr:mr-3 rtl:ml-3 flex-shrink-0 h-5 w-5"
"h-5 w-5 flex-shrink-0 ltr:mr-3 rtl:ml-3"
)}
aria-hidden="true"
/>
@ -439,7 +439,7 @@ function UserDropdown({ small }: { small?: boolean }) {
rel="noopener noreferrer"
href={`${process.env.NEXT_PUBLIC_APP_URL}/${user.username}`}
className="flex items-center px-4 py-2 text-sm text-gray-700">
<ExternalLinkIcon className="w-5 h-5 text-gray-500 ltr:mr-3 rtl:ml-3" /> {t("view_public_page")}
<ExternalLinkIcon className="h-5 w-5 text-gray-500 ltr:mr-3 rtl:ml-3" /> {t("view_public_page")}
</a>
</DropdownMenuItem>
)}
@ -454,7 +454,7 @@ function UserDropdown({ small }: { small?: boolean }) {
viewBox="0 0 2447.6 2452.5"
className={classNames(
"text-gray-500 group-hover:text-gray-700",
"mt-0.5 ltr:mr-2 rtl:ml-2 flex-shrink-0 h-4 w-4"
"mt-0.5 h-4 w-4 flex-shrink-0 ltr:mr-2 rtl:ml-2"
)}
xmlns="http://www.w3.org/2000/svg">
<g clipRule="evenodd" fillRule="evenodd">
@ -481,7 +481,7 @@ function UserDropdown({ small }: { small?: boolean }) {
rel="noopener noreferrer"
href="https://cal.com/roadmap"
className="flex items-center px-4 py-2 text-sm text-gray-700">
<MapIcon className="w-5 h-5 text-gray-500 ltr:mr-3 rtl:ml-3" /> {t("visit_roadmap")}
<MapIcon className="h-5 w-5 text-gray-500 ltr:mr-3 rtl:ml-3" /> {t("visit_roadmap")}
</a>
</DropdownMenuItem>
<HelpMenuItemDynamic />
@ -489,11 +489,11 @@ function UserDropdown({ small }: { small?: boolean }) {
<DropdownMenuItem>
<a
onClick={() => signOut({ callbackUrl: "/auth/logout" })}
className="flex px-4 py-2 text-sm cursor-pointer hover:bg-gray-100 hover:text-gray-900">
className="flex cursor-pointer px-4 py-2 text-sm hover:bg-gray-100 hover:text-gray-900">
<LogoutIcon
className={classNames(
"text-gray-500 group-hover:text-gray-700",
"ltr:mr-3 rtl:ml-3 flex-shrink-0 h-5 w-5"
"h-5 w-5 flex-shrink-0 ltr:mr-3 rtl:ml-3"
)}
aria-hidden="true"
/>

View File

@ -12,7 +12,7 @@ const Slider = ({
changeHandler: (value: number) => void;
}) => (
<SliderPrimitive.Root
className="mt-2 slider"
className="slider mt-2"
value={[value]}
aria-label={label}
onValueChange={(value: number[]) => changeHandler(value[0] ?? value)}

View File

@ -9,15 +9,15 @@ export type SwatchProps = {
const Swatch = (props: SwatchProps) => {
const { size, backgroundColor, onClick } = props;
return (
<div className="p-1 border-2 border-gray-200 shadow-sm">
<div className="border-2 border-gray-200 p-1 shadow-sm">
<div
onClick={onClick}
style={{ backgroundColor }}
className={classNames(
"cursor-pointer",
size === "sm" && "w-6 h-6 rounded-sm",
size === "base" && "w-16 h-16 rounded-sm",
size === "lg" && "w-24 h-24 rounded-sm"
size === "sm" && "h-6 w-6 rounded-sm",
size === "base" && "h-16 w-16 rounded-sm",
size === "lg" && "h-24 w-24 rounded-sm"
)}></div>
</div>
);

View File

@ -23,7 +23,7 @@ export function Tooltip({
onOpenChange={onOpenChange}>
<TooltipPrimitive.Trigger asChild>{children}</TooltipPrimitive.Trigger>
<TooltipPrimitive.Content
className="bg-black text-xs -mt-2 text-white px-1 py-0.5 shadow-lg rounded-sm"
className="-mt-2 rounded-sm bg-black px-1 py-0.5 text-xs text-white shadow-lg"
side="top"
align="center"
{...props}>

View File

@ -35,7 +35,7 @@ export default function SAMLLogin(props: Props) {
<Button
color="secondary"
data-testid={"saml"}
className="flex justify-center w-full"
className="flex w-full justify-center"
onClick={async (event) => {
event.preventDefault();

View File

@ -26,7 +26,7 @@ export default function TwoFactor() {
const className = "h-12 w-12 !text-xl text-center";
return (
<div className="max-w-sm mx-auto !mt-0">
<div className="mx-auto !mt-0 max-w-sm">
<p className="mb-4 text-sm text-gray-500">{t("2fa_enabled_instructions")}</p>
<input hidden type="hidden" value={value} {...methods.register("totpCode")} />
<div className="flex flex-row space-x-1">

View File

@ -55,8 +55,8 @@ const AvailableTimes: FC<AvailableTimesProps> = ({
}, []);
return (
<div className="flex flex-col mt-8 text-center sm:pl-4 sm:mt-0 sm:w-1/3 md:-mb-5">
<div className="mb-4 text-lg font-light text-left text-gray-600">
<div className="mt-8 flex flex-col text-center sm:mt-0 sm:w-1/3 sm:pl-4 md:-mb-5">
<div className="mb-4 text-left text-lg font-light text-gray-600">
<span className="w-1/2 text-gray-600 dark:text-white">
<strong>{date.toDate().toLocaleString(i18n.language, { weekday: "long" })}</strong>
<span className="text-gray-500">
@ -65,7 +65,7 @@ const AvailableTimes: FC<AvailableTimesProps> = ({
</span>
</span>
</div>
<div className="flex-grow md:h-[364px] overflow-y-auto">
<div className="flex-grow overflow-y-auto md:h-[364px]">
{!loading &&
slots?.length > 0 &&
slots.map((slot) => {
@ -95,7 +95,7 @@ const AvailableTimes: FC<AvailableTimesProps> = ({
<Link href={bookingUrl}>
<a
className={classNames(
"block py-4 mb-2 font-medium bg-white border rounded-sm dark:bg-gray-600 text-primary-500 dark:text-neutral-200 dark:border-transparent hover:text-white hover:bg-brand hover:text-brandcontrast dark:hover:border-black dark:hover:bg-brand dark:hover:text-brandcontrast",
"mb-2 block rounded-sm border bg-white py-4 font-medium text-primary-500 hover:bg-brand hover:text-white hover:text-brandcontrast dark:border-transparent dark:bg-gray-600 dark:text-neutral-200 dark:hover:border-black dark:hover:bg-brand dark:hover:text-brandcontrast",
brand === "#fff" || brand === "#ffffff" ? "border-brandcontrast" : "border-brand"
)}
data-testid="time">
@ -106,7 +106,7 @@ const AvailableTimes: FC<AvailableTimesProps> = ({
);
})}
{!loading && !error && !slots.length && (
<div className="flex flex-col items-center content-center justify-center w-full h-full -mt-4">
<div className="-mt-4 flex h-full w-full flex-col content-center items-center justify-center">
<h1 className="my-6 text-xl text-black dark:text-white">{t("all_booked_today")}</h1>
</div>
)}
@ -114,10 +114,10 @@ const AvailableTimes: FC<AvailableTimesProps> = ({
{loading && <Loader />}
{error && (
<div className="p-4 border-l-4 border-yellow-400 bg-yellow-50">
<div className="border-l-4 border-yellow-400 bg-yellow-50 p-4">
<div className="flex">
<div className="flex-shrink-0">
<ExclamationIcon className="w-5 h-5 text-yellow-400" aria-hidden="true" />
<ExclamationIcon className="h-5 w-5 text-yellow-400" aria-hidden="true" />
</div>
<div className="ltr:ml-3 rtl:mr-3">
<p className="text-sm text-yellow-700">{t("slots_load_fail")}</p>

View File

@ -74,13 +74,13 @@ function BookingListItem(booking: BookingItem) {
return (
<tr className="flex">
<td className="hidden py-4 align-top ltr:pl-6 rtl:pr-6 sm:table-cell whitespace-nowrap">
<td className="hidden whitespace-nowrap py-4 align-top ltr:pl-6 rtl:pr-6 sm:table-cell">
<div className="text-sm leading-6 text-gray-900">{startTime}</div>
<div className="text-sm text-gray-500">
{dayjs(booking.startTime).format("HH:mm")} - {dayjs(booking.endTime).format("HH:mm")}
</div>
</td>
<td className={"ltr:pl-4 rtl:pr-4 py-4 flex-1" + (booking.rejected ? " line-through" : "")}>
<td className={"flex-1 py-4 ltr:pl-4 rtl:pr-4" + (booking.rejected ? " line-through" : "")}>
<div className="sm:hidden">
{!booking.confirmed && !booking.rejected && (
<Tag className="mb-2 ltr:mr-2 rtl:ml-2">{t("unconfirmed")}</Tag>
@ -97,7 +97,7 @@ function BookingListItem(booking: BookingItem) {
</div>
<div
title={booking.title}
className="text-sm font-medium leading-6 truncate text-neutral-900 max-w-56 md:max-w-max">
className="max-w-56 truncate text-sm font-medium leading-6 text-neutral-900 md:max-w-max">
{booking.eventType?.team && <strong>{booking.eventType.team.name}: </strong>}
{booking.title}
{!!booking?.eventType?.price && !booking.paid && (
@ -108,7 +108,7 @@ function BookingListItem(booking: BookingItem) {
)}
</div>
{booking.description && (
<div className="text-sm text-gray-500 truncate max-w-52 md:max-w-96" title={booking.description}>
<div className="max-w-52 truncate text-sm text-gray-500 md:max-w-96" title={booking.description}>
&quot;{booking.description}&quot;
</div>
)}
@ -119,7 +119,7 @@ function BookingListItem(booking: BookingItem) {
)}
</td>
<td className="py-4 text-sm font-medium text-right ltr:pr-4 rtl:pl-4 whitespace-nowrap">
<td className="whitespace-nowrap py-4 text-right text-sm font-medium ltr:pr-4 rtl:pl-4">
{isUpcoming && !isCancelled ? (
<>
{!booking.confirmed && !booking.rejected && <TableActions actions={pendingActions} />}
@ -137,7 +137,7 @@ function BookingListItem(booking: BookingItem) {
const Tag = ({ children, className = "" }: React.PropsWithChildren<{ className?: string }>) => {
return (
<span
className={`inline-flex items-center px-1.5 py-0.5 rounded-sm text-xs font-medium bg-yellow-100 text-yellow-800 ${className}`}>
className={`inline-flex items-center rounded-sm bg-yellow-100 px-1.5 py-0.5 text-xs font-medium text-yellow-800 ${className}`}>
{children}
</span>
);

View File

@ -163,10 +163,10 @@ function DatePicker({
className={
"mt-8 sm:mt-0 sm:min-w-[455px] " +
(date
? "w-full 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 sm:border-r sm:pl-4 sm:pr-6 sm:dark:border-gray-800 md:w-1/3 "
: "w-full sm:pl-4")
}>
<div className="flex mb-4 text-xl font-light text-gray-600">
<div className="mb-4 flex text-xl font-light text-gray-600">
<span className="w-1/2 text-gray-600 dark:text-white">
<strong className="text-gray-900 dark:text-white">{month}</strong>{" "}
<span className="text-gray-500">{year}</span>
@ -175,21 +175,21 @@ function DatePicker({
<button
onClick={decrementMonth}
className={classNames(
"group ltr:mr-2 rtl:ml-2 p-1",
"group p-1 ltr:mr-2 rtl:ml-2",
isFirstMonth && "text-gray-400 dark:text-gray-600"
)}
disabled={isFirstMonth}
data-testid="decrementMonth">
<ChevronLeftIcon className="w-5 h-5 group-hover:text-black dark:group-hover:text-white" />
<ChevronLeftIcon className="h-5 w-5 group-hover:text-black dark:group-hover:text-white" />
</button>
<button className="p-1 group" onClick={incrementMonth} data-testid="incrementMonth">
<ChevronRightIcon className="w-5 h-5 group-hover:text-black dark:group-hover:text-white" />
<button className="group p-1" onClick={incrementMonth} data-testid="incrementMonth">
<ChevronRightIcon className="h-5 w-5 group-hover:text-black dark:group-hover:text-white" />
</button>
</div>
</div>
<div className="grid grid-cols-7 gap-4 text-center border-t border-b dark:border-gray-800 sm:border-0">
<div className="grid grid-cols-7 gap-4 border-t border-b text-center dark:border-gray-800 sm:border-0">
{weekdayNames(i18n.language, weekStart === "Sunday" ? 0 : 1, "short").map((weekDay) => (
<div key={weekDay} className="my-4 text-xs tracking-widest text-gray-500 uppercase">
<div key={weekDay} className="my-4 text-xs uppercase tracking-widest text-gray-500">
{weekDay}
</div>
))}
@ -209,9 +209,9 @@ function DatePicker({
onClick={() => onDatePicked(browsingDate.date(day.date))}
disabled={day.disabled}
className={classNames(
"absolute w-full top-0 left-0 right-0 bottom-0 rounded-sm text-center mx-auto",
"absolute top-0 left-0 right-0 bottom-0 mx-auto w-full rounded-sm text-center",
"hover:border hover:border-brand dark:hover:border-white",
day.disabled ? "text-gray-400 font-light hover:border-0 cursor-default" : "font-medium",
day.disabled ? "cursor-default font-light text-gray-400 hover:border-0" : "font-medium",
date && date.isSame(browsingDate.date(day.date), "day")
? "bg-brand text-brandcontrast"
: !day.disabled

View File

@ -35,8 +35,8 @@ const TimeOptions: FC<Props> = (props) => {
};
return selectedTimeZone !== "" ? (
<div className="absolute z-10 w-full px-4 py-2 bg-white border border-gray-200 rounded-sm max-w-80 dark:bg-gray-700 dark:border-0">
<div className="flex mb-4">
<div className="absolute z-10 w-full max-w-80 rounded-sm border border-gray-200 bg-white px-4 py-2 dark:border-0 dark:bg-gray-700">
<div className="mb-4 flex">
<div className="w-1/2 font-medium text-gray-600 dark:text-white">{t("time_options")}</div>
<div className="w-1/2">
<Switch.Group as="div" className="flex items-center justify-end">
@ -47,15 +47,15 @@ const TimeOptions: FC<Props> = (props) => {
checked={is24hClock}
onChange={handle24hClockToggle}
className={classNames(
is24hClock ? "bg-brand text-brandcontrast" : "dark:bg-gray-600 bg-gray-200",
"relative inline-flex flex-shrink-0 h-5 w-8 border-2 border-transparent rounded-full cursor-pointer transition-colors ease-in-out duration-200 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-black"
is24hClock ? "bg-brand text-brandcontrast" : "bg-gray-200 dark:bg-gray-600",
"relative inline-flex h-5 w-8 flex-shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors duration-200 ease-in-out focus:outline-none focus:ring-2 focus:ring-black focus:ring-offset-2"
)}>
<span className="sr-only">{t("use_setting")}</span>
<span
aria-hidden="true"
className={classNames(
is24hClock ? "translate-x-3" : "translate-x-0",
"pointer-events-none inline-block h-4 w-4 rounded-full bg-white shadow transform ring-0 transition ease-in-out duration-200"
"pointer-events-none inline-block h-4 w-4 transform rounded-full bg-white shadow ring-0 transition duration-200 ease-in-out"
)}
/>
</Switch>
@ -69,7 +69,7 @@ const TimeOptions: FC<Props> = (props) => {
id="timeZone"
value={selectedTimeZone}
onChange={(tz: ITimezoneOption) => setSelectedTimeZone(tz.value)}
className="block w-full mt-1 mb-2 border-gray-300 rounded-md shadow-sm focus:ring-black focus:border-brand sm:text-sm"
className="mt-1 mb-2 block w-full rounded-md border-gray-300 shadow-sm focus:border-brand focus:ring-black sm:text-sm"
/>
</div>
) : null;

View File

@ -110,11 +110,11 @@ const AvailabilityPage = ({ profile, eventType, workingHours }: Props) => {
<div>
<main
className={
"mx-auto my-0 md:my-24 transition-max-width ease-in-out duration-500 " +
"transition-max-width mx-auto my-0 duration-500 ease-in-out md:my-24 " +
(selectedDate ? "max-w-5xl" : "max-w-3xl")
}>
{isReady && (
<div className="bg-white border-gray-200 rounded-sm sm:dark:border-gray-600 dark:bg-gray-900 md:border">
<div className="rounded-sm border-gray-200 bg-white dark:bg-gray-900 sm:dark:border-gray-600 md:border">
{/* mobile: details */}
<div className="block p-4 sm:p-8 md:hidden">
<div className="flex items-center">
@ -139,12 +139,12 @@ const AvailabilityPage = ({ profile, eventType, workingHours }: Props) => {
<div className="flex gap-2 text-xs font-medium text-gray-600">
{eventType.title}
<div>
<ClockIcon className="inline-block w-4 h-4 mr-1 -mt-1" />
<ClockIcon className="mr-1 -mt-1 inline-block h-4 w-4" />
{eventType.length} {t("minutes")}
</div>
{eventType.price > 0 && (
<div>
<CreditCardIcon className="inline-block w-4 h-4 mr-1 -mt-1" />
<CreditCardIcon className="mr-1 -mt-1 inline-block h-4 w-4" />
<IntlProvider locale="en">
<FormattedNumber
value={eventType.price / 100.0}
@ -160,10 +160,10 @@ const AvailabilityPage = ({ profile, eventType, workingHours }: Props) => {
<p className="mt-3 text-gray-600 dark:text-gray-200">{eventType.description}</p>
</div>
<div className="px-4 sm:flex sm:py-5 sm:p-4">
<div className="px-4 sm:flex sm:p-4 sm:py-5">
<div
className={
"hidden md:block pr-8 sm:border-r sm:dark:border-gray-800 " +
"hidden pr-8 sm:border-r sm:dark:border-gray-800 md:block " +
(selectedDate ? "sm:w-1/3" : "sm:w-1/2")
}>
<AvatarGroup
@ -183,16 +183,16 @@ const AvailabilityPage = ({ profile, eventType, workingHours }: Props) => {
truncateAfter={3}
/>
<h2 className="mt-3 font-medium text-gray-500 dark:text-gray-300">{profile.name}</h2>
<h1 className="mb-4 text-3xl font-semibold text-gray-800 font-cal dark:text-white">
<h1 className="mb-4 font-cal text-3xl font-semibold text-gray-800 dark:text-white">
{eventType.title}
</h1>
<p className="px-2 py-1 mb-1 -ml-2 text-gray-500">
<ClockIcon className="inline-block w-4 h-4 mr-1 -mt-1" />
<p className="mb-1 -ml-2 px-2 py-1 text-gray-500">
<ClockIcon className="mr-1 -mt-1 inline-block h-4 w-4" />
{eventType.length} {t("minutes")}
</p>
{eventType.price > 0 && (
<p className="px-2 py-1 mb-1 -ml-2 text-gray-500">
<CreditCardIcon className="inline-block w-4 h-4 mr-1 -mt-1" />
<p className="mb-1 -ml-2 px-2 py-1 text-gray-500">
<CreditCardIcon className="mr-1 -mt-1 inline-block h-4 w-4" />
<IntlProvider locale="en">
<FormattedNumber
value={eventType.price / 100.0}
@ -221,7 +221,7 @@ const AvailabilityPage = ({ profile, eventType, workingHours }: Props) => {
minimumBookingNotice={eventType.minimumBookingNotice}
/>
<div className="block mt-4 ml-1 sm:hidden">
<div className="mt-4 ml-1 block sm:hidden">
<TimezoneDropdown />
</div>
@ -249,13 +249,13 @@ const AvailabilityPage = ({ profile, eventType, workingHours }: Props) => {
function TimezoneDropdown() {
return (
<Collapsible.Root open={isTimeOptionsOpen} onOpenChange={setIsTimeOptionsOpen}>
<Collapsible.Trigger className="px-2 py-1 mb-1 -ml-2 text-left text-gray-500 min-w-32">
<GlobeIcon className="inline-block w-4 h-4 mr-1 -mt-1" />
<Collapsible.Trigger className="mb-1 -ml-2 min-w-32 px-2 py-1 text-left text-gray-500">
<GlobeIcon className="mr-1 -mt-1 inline-block h-4 w-4" />
{timeZone()}
{isTimeOptionsOpen ? (
<ChevronUpIcon className="inline-block w-4 h-4 ml-1 -mt-1" />
<ChevronUpIcon className="ml-1 -mt-1 inline-block h-4 w-4" />
) : (
<ChevronDownIcon className="inline-block w-4 h-4 ml-1 -mt-1" />
<ChevronDownIcon className="ml-1 -mt-1 inline-block h-4 w-4" />
)}
</Collapsible.Trigger>
<Collapsible.Content>

View File

@ -291,9 +291,9 @@ const BookingPage = (props: BookingPageProps) => {
<link rel="icon" href="/favicon.ico" />
</Head>
<CustomBranding val={props.profile.brandColor} />
<main className="max-w-3xl mx-auto my-0 rounded-sm sm:my-24 sm:border sm:dark:border-gray-600">
<main className=" mx-auto my-0 max-w-3xl rounded-sm sm:my-24 sm:border sm:dark:border-gray-600">
{isReady && (
<div className="overflow-hidden bg-white border border-gray-200 dark:bg-neutral-900 dark:border-0 sm:rounded-sm">
<div className="overflow-hidden border border-gray-200 bg-white dark:border-0 dark:bg-neutral-900 sm:rounded-sm">
<div className="px-4 py-5 sm:flex sm:p-4">
<div className="sm:w-1/2 sm:border-r sm:dark:border-gray-800">
<AvatarGroup
@ -307,19 +307,19 @@ const BookingPage = (props: BookingPageProps) => {
}))
)}
/>
<h2 className="mt-2 font-medium text-gray-500 font-cal dark:text-gray-300">
<h2 className="mt-2 font-cal font-medium text-gray-500 dark:text-gray-300">
{props.profile.name}
</h2>
<h1 className="mb-4 text-3xl font-semibold text-gray-800 dark:text-white">
{props.eventType.title}
</h1>
<p className="mb-2 text-gray-500">
<ClockIcon className="inline-block w-4 h-4 mr-1 -mt-1" />
<ClockIcon className="mr-1 -mt-1 inline-block h-4 w-4" />
{props.eventType.length} {t("minutes")}
</p>
{props.eventType.price > 0 && (
<p className="px-2 py-1 mb-1 -ml-2 text-gray-500">
<CreditCardIcon className="inline-block w-4 h-4 mr-1 -mt-1" />
<p className="mb-1 -ml-2 px-2 py-1 text-gray-500">
<CreditCardIcon className="mr-1 -mt-1 inline-block h-4 w-4" />
<IntlProvider locale="en">
<FormattedNumber
value={props.eventType.price / 100.0}
@ -331,22 +331,22 @@ const BookingPage = (props: BookingPageProps) => {
)}
{selectedLocation === LocationType.InPerson && (
<p className="mb-2 text-gray-500">
<LocationMarkerIcon className="inline-block w-4 h-4 mr-1 -mt-1" />
<LocationMarkerIcon className="mr-1 -mt-1 inline-block h-4 w-4" />
{getLocationValue({ locationType: selectedLocation })}
</p>
)}
{selectedLocation === LocationType.Jitsi && (
<p className="mb-2 text-gray-500">
<LocationMarkerIcon className="inline-block w-4 h-4 mr-1 -mt-1" />
<LocationMarkerIcon className="mr-1 -mt-1 inline-block h-4 w-4" />
Jitsi Meet
</p>
)}
<p className="mb-4 text-green-500">
<CalendarIcon className="inline-block w-4 h-4 mr-1 -mt-1" />
<CalendarIcon className="mr-1 -mt-1 inline-block h-4 w-4" />
{parseDate(date)}
</p>
{eventTypeDetail.isWeb3Active && eventType.metadata.smartContractAddress && (
<p className="px-2 py-1 mb-1 -ml-2 text-gray-500">
<p className="mb-1 -ml-2 px-2 py-1 text-gray-500">
Requires ownership of a token belonging to the following address:{" "}
{eventType.metadata.smartContractAddress}
</p>
@ -366,7 +366,7 @@ const BookingPage = (props: BookingPageProps) => {
name="name"
id="name"
required
className="block w-full border-gray-300 rounded-sm shadow-sm dark:bg-black dark:text-white dark:border-gray-900 focus:ring-black focus:border-brand sm:text-sm"
className="block w-full rounded-sm border-gray-300 shadow-sm focus:border-brand focus:ring-black dark:border-gray-900 dark:bg-black dark:text-white sm:text-sm"
placeholder="John Doe"
/>
</div>
@ -381,7 +381,7 @@ const BookingPage = (props: BookingPageProps) => {
<EmailInput
{...bookingForm.register("email")}
required
className="block w-full border-gray-300 rounded-sm shadow-sm dark:bg-black dark:text-white dark:border-gray-900 focus:ring-black focus:border-brand sm:text-sm"
className="block w-full rounded-sm border-gray-300 shadow-sm focus:border-brand focus:ring-black dark:border-gray-900 dark:bg-black dark:text-white sm:text-sm"
placeholder="you@example.com"
/>
</div>
@ -395,12 +395,12 @@ const BookingPage = (props: BookingPageProps) => {
<label key={i} className="block">
<input
type="radio"
className="w-4 h-4 text-black border-gray-300 ltr:mr-2 rtl:ml-2 location focus:ring-black"
className="location h-4 w-4 border-gray-300 text-black focus:ring-black ltr:mr-2 rtl:ml-2"
{...bookingForm.register("locationType", { required: true })}
value={location.type}
defaultChecked={selectedLocation === location.type}
/>
<span className="ltr:ml-2 rtl:mr-2text-sm dark:text-gray-500">
<span className="rtl:mr-2text-sm ltr:ml-2 dark:text-gray-500">
{locationLabels[location.type]}
</span>
</label>
@ -428,7 +428,7 @@ const BookingPage = (props: BookingPageProps) => {
{input.type !== EventTypeCustomInputType.BOOL && (
<label
htmlFor={"custom_" + input.id}
className="block mb-1 text-sm font-medium text-gray-700 dark:text-white">
className="mb-1 block text-sm font-medium text-gray-700 dark:text-white">
{input.label}
</label>
)}
@ -439,7 +439,7 @@ const BookingPage = (props: BookingPageProps) => {
})}
id={"custom_" + input.id}
rows={3}
className="block w-full border-gray-300 rounded-sm shadow-sm dark:bg-black dark:text-white dark:border-gray-900 focus:ring-black focus:border-brand sm:text-sm"
className="block w-full rounded-sm border-gray-300 shadow-sm focus:border-brand focus:ring-black dark:border-gray-900 dark:bg-black dark:text-white sm:text-sm"
placeholder={input.placeholder}
/>
)}
@ -450,7 +450,7 @@ const BookingPage = (props: BookingPageProps) => {
required: input.required,
})}
id={"custom_" + input.id}
className="block w-full border-gray-300 rounded-sm shadow-sm dark:bg-black dark:text-white dark:border-gray-900 focus:ring-black focus:border-brand sm:text-sm"
className="block w-full rounded-sm border-gray-300 shadow-sm focus:border-brand focus:ring-black dark:border-gray-900 dark:bg-black dark:text-white sm:text-sm"
placeholder={input.placeholder}
/>
)}
@ -461,24 +461,24 @@ const BookingPage = (props: BookingPageProps) => {
required: input.required,
})}
id={"custom_" + input.id}
className="block w-full border-gray-300 rounded-sm shadow-sm dark:bg-black dark:text-white dark:border-gray-900 focus:ring-black focus:border-brand sm:text-sm"
className="block w-full rounded-sm border-gray-300 shadow-sm focus:border-brand focus:ring-black dark:border-gray-900 dark:bg-black dark:text-white sm:text-sm"
placeholder=""
/>
)}
{input.type === EventTypeCustomInputType.BOOL && (
<div className="flex items-center h-5">
<div className="flex h-5 items-center">
<input
type="checkbox"
{...bookingForm.register(`customInputs.${input.id}`, {
required: input.required,
})}
id={"custom_" + input.id}
className="w-4 h-4 text-black border-gray-300 rounded ltr:mr-2 rtl:ml-2 focus:ring-black"
className="h-4 w-4 rounded border-gray-300 text-black focus:ring-black ltr:mr-2 rtl:ml-2"
placeholder=""
/>
<label
htmlFor={"custom_" + input.id}
className="block mb-1 text-sm font-medium text-gray-700 dark:text-white">
className="mb-1 block text-sm font-medium text-gray-700 dark:text-white">
{input.label}
</label>
</div>
@ -491,7 +491,7 @@ const BookingPage = (props: BookingPageProps) => {
<label
onClick={() => setGuestToggle(!guestToggle)}
htmlFor="guests"
className="block mb-1 text-sm font-medium dark:text-white hover:cursor-pointer">
className="mb-1 block text-sm font-medium hover:cursor-pointer dark:text-white">
{/*<UserAddIcon className="inline-block w-5 h-5 mr-1 -mt-1" />*/}
{t("additional_guests")}
</label>
@ -500,7 +500,7 @@ const BookingPage = (props: BookingPageProps) => {
<div>
<label
htmlFor="guests"
className="block mb-1 text-sm font-medium text-gray-700 dark:text-white">
className="mb-1 block text-sm font-medium text-gray-700 dark:text-white">
{t("guests")}
</label>
<Controller
@ -536,14 +536,14 @@ const BookingPage = (props: BookingPageProps) => {
<div className="mb-4">
<label
htmlFor="notes"
className="block mb-1 text-sm font-medium text-gray-700 dark:text-white">
className="mb-1 block text-sm font-medium text-gray-700 dark:text-white">
{t("additional_notes")}
</label>
<textarea
{...bookingForm.register("notes")}
id="notes"
rows={3}
className="block w-full border-gray-300 rounded-sm shadow-sm dark:bg-black dark:text-white dark:border-gray-900 focus:ring-black focus:border-brand sm:text-sm"
className="block w-full rounded-sm border-gray-300 shadow-sm focus:border-brand focus:ring-black dark:border-gray-900 dark:bg-black dark:text-white sm:text-sm"
placeholder={t("share_additional_notes")}
/>
</div>
@ -557,10 +557,10 @@ const BookingPage = (props: BookingPageProps) => {
</div>
</Form>
{mutation.isError && (
<div className="p-4 mt-2 border-l-4 border-yellow-400 bg-yellow-50">
<div className="mt-2 border-l-4 border-yellow-400 bg-yellow-50 p-4">
<div className="flex">
<div className="flex-shrink-0">
<ExclamationIcon className="w-5 h-5 text-yellow-400" aria-hidden="true" />
<ExclamationIcon className="h-5 w-5 text-yellow-400" aria-hidden="true" />
</div>
<div className="ltr:ml-3 rtl:mr-3">
<p className="text-sm text-yellow-700">

View File

@ -33,26 +33,26 @@ export default function ConfirmationDialogContent(props: PropsWithChildren<Confi
<DialogContent>
<div className="flex">
{variety && (
<div className="ltr:mr-3 mt-0.5">
<div className="mt-0.5 ltr:mr-3">
{variety === "danger" && (
<div className="p-2 mx-auto text-center bg-red-100 rounded-full">
<ExclamationIcon className="w-5 h-5 text-red-600" />
<div className="mx-auto rounded-full bg-red-100 p-2 text-center">
<ExclamationIcon className="h-5 w-5 text-red-600" />
</div>
)}
{variety === "warning" && (
<div className="p-2 mx-auto text-center bg-orange-100 rounded-full">
<ExclamationIcon className="w-5 h-5 text-orange-600" />
<div className="mx-auto rounded-full bg-orange-100 p-2 text-center">
<ExclamationIcon className="h-5 w-5 text-orange-600" />
</div>
)}
{variety === "success" && (
<div className="p-2 mx-auto text-center bg-green-100 rounded-full">
<CheckIcon className="w-5 h-5 text-green-600" />
<div className="mx-auto rounded-full bg-green-100 p-2 text-center">
<CheckIcon className="h-5 w-5 text-green-600" />
</div>
)}
</div>
)}
<div>
<DialogPrimitive.Title className="text-xl font-bold text-gray-900 font-cal">
<DialogPrimitive.Title className="font-cal text-xl font-bold text-gray-900">
{title}
</DialogPrimitive.Title>
<DialogPrimitive.Description className="text-sm text-neutral-500">
@ -60,7 +60,7 @@ export default function ConfirmationDialogContent(props: PropsWithChildren<Confi
</DialogPrimitive.Description>
</div>
</div>
<div className="mt-5 sm:mt-8 sm:flex sm:flex-row-reverse gap-x-2">
<div className="mt-5 gap-x-2 sm:mt-8 sm:flex sm:flex-row-reverse">
<DialogClose onClick={onConfirm} asChild>
{confirmBtn || <Button color="primary">{confirmBtnText}</Button>}
</DialogClose>

View File

@ -29,15 +29,15 @@ const ErrorDebugPanel: React.FC<{ error: Props["error"]; children?: never }> = (
];
return (
<div className="bg-white shadow overflow-hidden sm:rounded-lg">
<div className="overflow-hidden bg-white shadow sm:rounded-lg">
<div className="border-t border-gray-200 px-4 py-5 sm:p-0">
<dl className="sm:divide-y sm:divide-gray-200">
{debugMap.map(([key, value]) => {
if (value !== undefined) {
return (
<div key={key} className="py-4 sm:py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
<div key={key} className="py-4 sm:grid sm:grid-cols-3 sm:gap-4 sm:py-5 sm:px-6">
<dt className="text-sm font-bold text-black">{key}</dt>
<dd className="mt-1 text-sm text-black sm:mt-0 sm:col-span-2">{value}</dd>
<dd className="mt-1 text-sm text-black sm:col-span-2 sm:mt-0">{value}</dd>
</div>
);
}
@ -53,11 +53,11 @@ export const ErrorPage: React.FC<Props> = (props) => {
return (
<>
<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="min-h-screen bg-white px-4">
<main className="mx-auto max-w-xl pb-6 pt-16 sm:pt-24">
<div className="text-center">
<p className="text-sm font-semibold text-black uppercase tracking-wide">{statusCode}</p>
<h1 className="mt-2 text-4xl font-extrabold text-gray-900 tracking-tight sm:text-5xl">
<p className="text-sm font-semibold uppercase tracking-wide text-black">{statusCode}</p>
<h1 className="mt-2 text-4xl font-extrabold tracking-tight text-gray-900 sm:text-5xl">
{message}
</h1>
</div>

View File

@ -139,7 +139,7 @@ export default function CreateEventTypeButton(props: Props) {
{props.options.map((option) => (
<DropdownMenuItem
key={option.slug}
className="px-3 py-2 cursor-pointer hover:bg-neutral-100 focus:outline-none"
className="cursor-pointer px-3 py-2 hover:bg-neutral-100 focus:outline-none"
onSelect={() => openModal(option)}>
<Avatar
alt={option.name || ""}
@ -207,7 +207,7 @@ export default function CreateEventTypeButton(props: Props) {
className="pr-20"
{...register("length", { valueAsNumber: true })}
/>
<div className="absolute inset-y-0 right-0 flex items-center pt-4 mt-1.5 pr-3 text-sm text-gray-400">
<div className="absolute inset-y-0 right-0 mt-1.5 flex items-center pt-4 pr-3 text-sm text-gray-400">
{t("minutes")}
</div>
</div>
@ -227,20 +227,20 @@ export default function CreateEventTypeButton(props: Props) {
<RadioArea.Group
{...register("schedulingType")}
onChange={(val) => form.setValue("schedulingType", val as SchedulingType)}
className="relative flex mt-1 rtl:space-x-reverse space-x-6 rounded-sm shadow-sm">
className="relative mt-1 flex space-x-6 rounded-sm shadow-sm rtl:space-x-reverse">
<RadioArea.Item value={SchedulingType.COLLECTIVE} className="w-1/2 text-sm">
<strong className="block mb-1">{t("collective")}</strong>
<strong className="mb-1 block">{t("collective")}</strong>
<p>{t("collective_description")}</p>
</RadioArea.Item>
<RadioArea.Item value={SchedulingType.ROUND_ROBIN} className="w-1/2 text-sm">
<strong className="block mb-1">{t("round_robin")}</strong>
<strong className="mb-1 block">{t("round_robin")}</strong>
<p>{t("round_robin_description")}</p>
</RadioArea.Item>
</RadioArea.Group>
</div>
)}
</div>
<div className="flex flex-row-reverse mt-8 gap-x-2">
<div className="mt-8 flex flex-row-reverse gap-x-2">
<Button type="submit" loading={createMutation.isLoading}>
{t("continue")}
</Button>

View File

@ -32,31 +32,31 @@ export const EventTypeDescription = ({ eventType, className }: EventTypeDescript
<>
<div className={classNames("text-neutral-500 dark:text-white", className)}>
{eventType.description && (
<h2 className="opacity-60 text-ellipsis overflow-hidden max-w-[280px] sm:max-w-[500px]">
<h2 className="max-w-[280px] overflow-hidden text-ellipsis opacity-60 sm:max-w-[500px]">
{eventType.description.substring(0, 100)}
{eventType.description.length > 100 && "..."}
</h2>
)}
<ul className="flex mt-2 space-x-4 rtl:space-x-reverse ">
<ul className="mt-2 flex space-x-4 rtl:space-x-reverse ">
<li className="flex whitespace-nowrap">
<ClockIcon className="inline mt-0.5 mr-1.5 h-4 w-4 text-neutral-400" aria-hidden="true" />
<ClockIcon className="mt-0.5 mr-1.5 inline h-4 w-4 text-neutral-400" aria-hidden="true" />
{eventType.length}m
</li>
{eventType.schedulingType ? (
<li className="flex whitespace-nowrap">
<UsersIcon className="inline mt-0.5 mr-1.5 h-4 w-4 text-neutral-400" aria-hidden="true" />
<UsersIcon className="mt-0.5 mr-1.5 inline h-4 w-4 text-neutral-400" aria-hidden="true" />
{eventType.schedulingType === SchedulingType.ROUND_ROBIN && t("round_robin")}
{eventType.schedulingType === SchedulingType.COLLECTIVE && t("collective")}
</li>
) : (
<li className="flex whitespace-nowrap">
<UserIcon className="inline mt-0.5 mr-1.5 h-4 w-4 text-neutral-400" aria-hidden="true" />
<UserIcon className="mt-0.5 mr-1.5 inline h-4 w-4 text-neutral-400" aria-hidden="true" />
{t("1_on_1")}
</li>
)}
{eventType.price > 0 && (
<li className="flex whitespace-nowrap">
<CreditCardIcon className="inline mt-0.5 mr-1.5 h-4 w-4 text-neutral-400" aria-hidden="true" />
<CreditCardIcon className="mt-0.5 mr-1.5 inline h-4 w-4 text-neutral-400" aria-hidden="true" />
<IntlProvider locale="en">
<FormattedNumber
value={eventType.price / 100.0}

View File

@ -17,7 +17,7 @@ export const Input = forwardRef<HTMLInputElement, InputProps>(function Input(pro
{...props}
ref={ref}
className={classNames(
"mt-1 block w-full border border-gray-300 rounded-sm shadow-sm py-2 px-3 focus:outline-none focus:ring-1 focus:ring-neutral-800 focus:border-neutral-800 sm:text-sm",
"mt-1 block w-full rounded-sm border border-gray-300 py-2 px-3 shadow-sm focus:border-neutral-800 focus:outline-none focus:ring-1 focus:ring-neutral-800 sm:text-sm",
props.className
)}
/>
@ -34,7 +34,7 @@ export function Label(props: JSX.IntrinsicElements["label"]) {
export function InputLeading(props: JSX.IntrinsicElements["div"]) {
return (
<span className="inline-flex items-center flex-shrink-0 px-3 text-gray-500 border border-r-0 border-gray-300 rounded-l-sm bg-gray-50 sm:text-sm">
<span className="inline-flex flex-shrink-0 items-center rounded-l-sm border border-r-0 border-gray-300 bg-gray-50 px-3 text-gray-500 sm:text-sm">
{props.children}
</span>
);
@ -69,7 +69,7 @@ const InputField = forwardRef<HTMLInputElement, InputFieldProps>(function InputF
</Label>
)}
{addOnLeading ? (
<div className="flex mt-1 rounded-md shadow-sm">
<div className="mt-1 flex rounded-md shadow-sm">
{addOnLeading}
<Input
id={id}
@ -136,7 +136,7 @@ export const TextArea = forwardRef<HTMLTextAreaElement, TextAreaProps>(function
ref={ref}
{...props}
className={classNames(
"block w-full font-mono border-gray-300 rounded-sm shadow-sm focus:ring-neutral-900 focus:border-neutral-900 sm:text-sm",
"font-mono block w-full rounded-sm border-gray-300 shadow-sm focus:border-neutral-900 focus:ring-neutral-900 sm:text-sm",
props.className
)}
/>
@ -221,7 +221,7 @@ export function InputGroupBox(props: JSX.IntrinsicElements["div"]) {
return (
<div
{...props}
className={classNames("p-2 bg-white border border-gray-300 rounded-sm space-y-2", props.className)}>
className={classNames("space-y-2 rounded-sm border border-gray-300 bg-white p-2", props.className)}>
{props.children}
</div>
);

View File

@ -122,7 +122,7 @@ function ConnectedCalendarsList(props: Props) {
onOpenChange={props.onChanged}
/>
}>
<ul className="p-4 space-y-2">
<ul className="space-y-2 p-4">
{item.calendars.map((cal) => (
<CalendarSwitch
key={cal.externalId}

View File

@ -14,9 +14,9 @@ function IntegrationListItem(props: {
}): JSX.Element {
return (
<ListItem expanded={!!props.children} className={classNames("flex-col")}>
<div className={classNames("flex flex-1 rtl:space-x-reverse space-x-2 w-full p-3 items-center")}>
<div className={classNames("flex w-full flex-1 items-center space-x-2 p-3 rtl:space-x-reverse")}>
<Image width={40} height={40} src={`/${props.imageSrc}`} alt={props.title} />
<div className="flex-grow pl-2 truncate">
<div className="flex-grow truncate pl-2">
<ListItemTitle component="h3">{props.title}</ListItemTitle>
<ListItemText component="p">{props.description}</ListItemText>
</div>

View File

@ -1,12 +1,17 @@
import { EventTypeCustomInput, EventTypeCustomInputType } from "@prisma/client";
import React, { FC } from "react";
import { Controller, SubmitHandler, useForm, useWatch } from "react-hook-form";
import Select, { OptionTypeBase } from "react-select";
import Select from "react-select";
import { useLocale } from "@lib/hooks/useLocale";
import Button from "@components/ui/Button";
interface OptionTypeBase {
label: string;
value: EventTypeCustomInputType;
}
interface Props {
onSubmit: SubmitHandler<IFormInput>;
onCancel: () => void;
@ -50,8 +55,8 @@ const CustomInputTypeForm: FC<Props> = (props) => {
defaultValue={selectedInputOption}
options={inputOptions}
isSearchable={false}
className="flex-1 block w-full min-w-0 mt-1 mb-2 border-gray-300 rounded-none focus:ring-primary-500 focus:border-primary-500 rounded-r-md sm:text-sm"
onChange={(option) => field.onChange(option.value)}
className="mt-1 mb-2 block w-full min-w-0 flex-1 rounded-none rounded-r-md border-gray-300 focus:border-primary-500 focus:ring-primary-500 sm:text-sm"
onChange={(option) => option && field.onChange(option.value)}
value={selectedInputOption}
onBlur={field.onBlur}
name={field.name}
@ -68,7 +73,7 @@ const CustomInputTypeForm: FC<Props> = (props) => {
type="text"
id="label"
required
className="block w-full border-gray-300 rounded-sm shadow-sm focus:ring-primary-500 focus:border-primary-500 sm:text-sm"
className="block w-full rounded-sm border-gray-300 shadow-sm focus:border-primary-500 focus:ring-primary-500 sm:text-sm"
defaultValue={selectedCustomInput?.label}
{...register("label", { required: true })}
/>
@ -84,18 +89,18 @@ const CustomInputTypeForm: FC<Props> = (props) => {
<input
type="text"
id="placeholder"
className="block w-full border-gray-300 rounded-sm shadow-sm focus:ring-primary-500 focus:border-primary-500 sm:text-sm"
className="block w-full rounded-sm border-gray-300 shadow-sm focus:border-primary-500 focus:ring-primary-500 sm:text-sm"
defaultValue={selectedCustomInput?.placeholder}
{...register("placeholder")}
/>
</div>
</div>
)}
<div className="flex items-center h-5">
<div className="flex h-5 items-center">
<input
id="required"
type="checkbox"
className="w-4 h-4 ltr:mr-2 rtl:ml-2 border-gray-300 rounded focus:ring-primary-500 text-primary-600"
className="h-4 w-4 rounded border-gray-300 text-primary-600 focus:ring-primary-500 ltr:mr-2 rtl:ml-2"
defaultChecked={selectedCustomInput?.required ?? true}
{...register("required")}
/>

View File

@ -57,7 +57,7 @@ const ChangePasswordSection = () => {
return (
<>
<div className="mt-6">
<h2 className="text-lg font-medium leading-6 text-gray-900 font-cal">{t("change_password")}</h2>
<h2 className="font-cal text-lg font-medium leading-6 text-gray-900">{t("change_password")}</h2>
</div>
<form className="divide-y divide-gray-200 lg:col-span-9" onSubmit={changePasswordHandler}>
<div className="py-6 lg:pb-8">
@ -74,12 +74,12 @@ const ChangePasswordSection = () => {
name="current_password"
id="current_password"
required
className="block w-full border-gray-300 rounded-sm shadow-sm focus:ring-black focus:border-brand sm:text-sm"
className="block w-full rounded-sm border-gray-300 shadow-sm focus:border-brand focus:ring-black sm:text-sm"
placeholder={t("your_old_password")}
/>
</div>
</div>
<div className="w-1/2 ml-2">
<div className="ml-2 w-1/2">
<label htmlFor="new_password" className="block text-sm font-medium text-gray-700">
{t("new_password")}
</label>
@ -91,7 +91,7 @@ const ChangePasswordSection = () => {
value={newPassword}
required
onInput={(e) => setNewPassword(e.currentTarget.value)}
className="block w-full border-gray-300 rounded-sm shadow-sm focus:ring-black focus:border-brand sm:text-sm"
className="block w-full rounded-sm border-gray-300 shadow-sm focus:border-brand focus:ring-black sm:text-sm"
placeholder={t("super_secure_new_password")}
/>
</div>

View File

@ -70,7 +70,7 @@ const DisableTwoFactorAuthModal = ({ onDisable, onCancel }: DisableTwoFactorAuth
required
value={password}
onInput={(e) => setPassword(e.currentTarget.value)}
className="block w-full border-gray-300 rounded-sm shadow-sm focus:ring-neutral-900 focus:border-neutral-900 sm:text-sm"
className="block w-full rounded-sm border-gray-300 shadow-sm focus:border-neutral-900 focus:ring-neutral-900 sm:text-sm"
/>
</div>

View File

@ -139,7 +139,7 @@ const EnableTwoFactorModal = ({ onEnable, onCancel }: EnableTwoFactorModalProps)
required
value={password}
onInput={(e) => setPassword(e.currentTarget.value)}
className="block w-full border-gray-300 rounded-sm shadow-sm focus:ring-neutral-900 focus:border-neutral-900 sm:text-sm"
className="block w-full rounded-sm border-gray-300 shadow-sm focus:border-neutral-900 focus:ring-neutral-900 sm:text-sm"
/>
</div>
@ -152,7 +152,7 @@ const EnableTwoFactorModal = ({ onEnable, onCancel }: EnableTwoFactorModalProps)
<div className="flex justify-center">
<img src={dataUri} />
</div>
<p className="text-center text-xs font-mono">{secret}</p>
<p className="font-mono text-center text-xs">{secret}</p>
</>
</WithStep>
<WithStep step={SetupStep.EnterTotpCode} current={step}>
@ -172,7 +172,7 @@ const EnableTwoFactorModal = ({ onEnable, onCancel }: EnableTwoFactorModalProps)
minLength={6}
inputMode="numeric"
onInput={(e) => setTotpCode(e.currentTarget.value)}
className="block w-full border-gray-300 rounded-sm shadow-sm focus:ring-neutral-900 focus:border-neutral-900 sm:text-sm"
className="block w-full rounded-sm border-gray-300 shadow-sm focus:border-neutral-900 focus:ring-neutral-900 sm:text-sm"
/>
</div>

View File

@ -17,8 +17,8 @@ const TwoFactorAuthSection = ({ twoFactorEnabled }: { twoFactorEnabled: boolean
return (
<>
<div className="flex flex-row items-center">
<h2 className="font-cal text-lg leading-6 font-medium text-gray-900">{t("2fa")}</h2>
<Badge className="text-xs ml-2" variant={enabled ? "success" : "gray"}>
<h2 className="font-cal text-lg font-medium leading-6 text-gray-900">{t("2fa")}</h2>
<Badge className="ml-2 text-xs" variant={enabled ? "success" : "gray"}>
{enabled ? t("enabled") : t("disabled")}
</Badge>
</div>

View File

@ -4,11 +4,11 @@ import React from "react";
const TwoFactorModalHeader = ({ title, description }: { title: string; description: string }) => {
return (
<div className="mb-4 sm:flex sm:items-start">
<div className="flex items-center justify-center flex-shrink-0 w-12 h-12 mx-auto rounded-full bg-brand text-brandcontrast bg-opacity-5 sm:mx-0 sm:h-10 sm:w-10">
<ShieldCheckIcon className="w-6 h-6 text-black" />
<div className="mx-auto flex h-12 w-12 flex-shrink-0 items-center justify-center rounded-full bg-brand bg-opacity-5 text-brandcontrast sm:mx-0 sm:h-10 sm:w-10">
<ShieldCheckIcon className="h-6 w-6 text-black" />
</div>
<div className="mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left">
<h3 className="text-lg font-medium leading-6 text-gray-900 font-cal" id="modal-title">
<h3 className="font-cal text-lg font-medium leading-6 text-gray-900" id="modal-title">
{title}
</h3>
<p className="text-sm text-gray-400">{description}</p>

View File

@ -51,14 +51,14 @@ export default function MemberChangeRoleModal(props: {
</div>
<form onSubmit={changeRole}>
<div className="mb-4">
<label className="block mb-2 text-sm font-medium tracking-wide text-gray-700" htmlFor="role">
<label className="mb-2 block text-sm font-medium tracking-wide text-gray-700" htmlFor="role">
{t("role")}
</label>
<select
value={role}
onChange={(e) => setRole(e.target.value as MembershipRole)}
id="role"
className="block w-full mt-1 border-gray-300 rounded-md shadow-sm focus:ring-black focus:border-brand sm:text-sm">
className="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-brand focus:ring-black sm:text-sm">
<option value="MEMBER">{t("member")}</option>
<option value="ADMIN">{t("admin")}</option>
{/*<option value="OWNER">{t("owner")}</option> - needs dialog to confirm change of ownership */}

View File

@ -53,19 +53,19 @@ export default function MemberInvitationModal(props: { team: TeamWithMembers | n
aria-labelledby="modal-title"
role="dialog"
aria-modal="true">
<div className="flex items-end justify-center min-h-screen px-4 pt-4 pb-20 text-center sm:block sm:p-0">
<div className="flex min-h-screen items-end justify-center px-4 pt-4 pb-20 text-center sm:block sm:p-0">
<div
className="fixed inset-0 z-0 transition-opacity bg-gray-500 bg-opacity-75"
className="fixed inset-0 z-0 bg-gray-500 bg-opacity-75 transition-opacity"
aria-hidden="true"></div>
<span className="hidden sm:inline-block sm:align-middle sm:h-screen" aria-hidden="true">
<span className="hidden sm:inline-block sm:h-screen sm:align-middle" aria-hidden="true">
&#8203;
</span>
<div className="inline-block px-4 pt-5 pb-4 text-left align-bottom transition-all transform bg-white rounded-lg shadow-xl sm:my-8 sm:align-middle sm:max-w-lg sm:w-full sm:p-6">
<div className="inline-block transform rounded-lg bg-white px-4 pt-5 pb-4 text-left align-bottom shadow-xl transition-all sm:my-8 sm:w-full sm:max-w-lg sm:p-6 sm:align-middle">
<div className="mb-4 sm:flex sm:items-start">
<div className="flex items-center justify-center flex-shrink-0 w-12 h-12 mx-auto rounded-full bg-brand text-brandcontrast bg-opacity-5 sm:mx-0 sm:h-10 sm:w-10">
<UserIcon className="w-6 h-6 text-brandcontrast" />
<div className="mx-auto flex h-12 w-12 flex-shrink-0 items-center justify-center rounded-full bg-brand bg-opacity-5 text-brandcontrast sm:mx-0 sm:h-10 sm:w-10">
<UserIcon className="h-6 w-6 text-brandcontrast" />
</div>
<div className="mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left">
<h3 className="text-lg font-medium leading-6 text-gray-900" id="modal-title">
@ -86,34 +86,34 @@ export default function MemberInvitationModal(props: { team: TeamWithMembers | n
required
/>
<div>
<label className="block mb-1 text-sm font-medium tracking-wide text-gray-700" htmlFor="role">
<label className="mb-1 block text-sm font-medium tracking-wide text-gray-700" htmlFor="role">
{t("role")}
</label>
<select
id="role"
className="block w-full mt-1 border-gray-300 rounded-sm shadow-sm focus:ring-black focus:border-brand sm:text-sm">
className="mt-1 block w-full rounded-sm border-gray-300 shadow-sm focus:border-brand focus:ring-black sm:text-sm">
<option value="MEMBER">{t("member")}</option>
<option value="ADMIN">{t("admin")}</option>
</select>
</div>
<div className="relative flex items-start">
<div className="flex items-center h-5">
<div className="flex h-5 items-center">
<input
type="checkbox"
name="sendInviteEmail"
defaultChecked
id="sendInviteEmail"
className="text-black border-gray-300 rounded-sm shadow-sm focus:ring-black focus:border-brand sm:text-sm"
className="rounded-sm border-gray-300 text-black shadow-sm focus:border-brand focus:ring-black sm:text-sm"
/>
</div>
<div className="ltr:ml-2 rtl:mr-2text-sm">
<div className="rtl:mr-2text-sm ltr:ml-2">
<label htmlFor="sendInviteEmail" className="font-medium text-gray-700">
{t("send_invite_email")}
</label>
</div>
</div>
<div className="flex flex-row px-3 py-2 rounded-sm bg-gray-50">
<InformationCircleIcon className="flex-shrink-0 w-5 h-5 fill-gray-400" aria-hidden="true" />
<div className="flex flex-row rounded-sm bg-gray-50 px-3 py-2">
<InformationCircleIcon className="h-5 w-5 flex-shrink-0 fill-gray-400" aria-hidden="true" />
<span className="ml-2 text-sm leading-tight text-gray-500">
Note: This will cost an extra seat ($12/m) on your subscription if this invitee does not
have a pro account.{" "}

View File

@ -12,7 +12,7 @@ export default function MemberList(props: Props) {
return (
<div>
<ul className="px-4 mb-2 -mx-4 bg-white border divide-y divide-gray-200 rounded sm:px-4 sm:mx-0">
<ul className="-mx-4 mb-2 divide-y divide-gray-200 rounded border bg-white px-4 sm:mx-0 sm:px-4">
{props.members?.map((member) => (
<MemberListItem key={member.id} member={member} team={props.team} />
))}

View File

@ -61,25 +61,25 @@ export default function MemberListItem(props: Props) {
return (
<li className="divide-y">
<div className="flex justify-between my-4">
<div className="flex flex-col justify-between w-full sm:flex-row">
<div className="my-4 flex justify-between">
<div className="flex w-full flex-col justify-between sm:flex-row">
<div className="flex">
<Avatar
imageSrc={getPlaceholderAvatar(props.member?.avatar, name)}
alt={name || ""}
className="rounded-full w-9 h-9"
className="h-9 w-9 rounded-full"
/>
<div className="inline-block ml-3">
<div className="ml-3 inline-block">
<span className="text-sm font-bold text-neutral-700">{name}</span>
<span
className="block -mt-1 text-xs text-gray-400"
className="-mt-1 block text-xs text-gray-400"
data-testid="member-email"
data-email={props.member.email}>
{props.member.email}
</span>
</div>
</div>
<div className="flex mt-2 ltr:mr-2 rtl:ml-2 sm:mt-0 sm:justify-center">
<div className="mt-2 flex ltr:mr-2 rtl:ml-2 sm:mt-0 sm:justify-center">
{/* Tooltip doesn't show... WHY????? */}
{props.member.isMissingSeat && (
<Tooltip content={t("hidden_team_member_message")}>
@ -102,13 +102,13 @@ export default function MemberListItem(props: Props) {
disabled={!props.member.accepted}
onClick={() => (props.member.accepted ? setShowTeamAvailabilityModal(true) : null)}
color="minimal"
className="items-center justify-center hidden w-10 h-10 px-0 py-0 border border-transparent group text-neutral-400 hover:border-gray-200 hover:bg-white sm:flex">
<ClockIcon className="w-5 h-5 group-hover:text-gray-800" />
className="group hidden h-10 w-10 items-center justify-center border border-transparent px-0 py-0 text-neutral-400 hover:border-gray-200 hover:bg-white sm:flex">
<ClockIcon className="h-5 w-5 group-hover:text-gray-800" />
</Button>
</Tooltip>
<Dropdown>
<DropdownMenuTrigger className="w-10 h-10 p-0 border border-transparent group text-neutral-400 hover:border-gray-200 hover:bg-white">
<DotsHorizontalIcon className="w-5 h-5 group-hover:text-gray-800" />
<DropdownMenuTrigger className="group h-10 w-10 border border-transparent p-0 text-neutral-400 hover:border-gray-200 hover:bg-white">
<DotsHorizontalIcon className="h-5 w-5 group-hover:text-gray-800" />
</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuItem>
@ -129,7 +129,7 @@ export default function MemberListItem(props: Props) {
onClick={() => setShowChangeMemberRoleModal(true)}
color="minimal"
StartIcon={PencilIcon}
className="flex-shrink-0 w-full font-normal">
className="w-full flex-shrink-0 font-normal">
{t("edit_role")}
</Button>
</DropdownMenuItem>
@ -173,7 +173,7 @@ export default function MemberListItem(props: Props) {
{showTeamAvailabilityModal && (
<ModalContainer wide noPadding>
<TeamAvailabilityModal team={props.team} member={props.member} />
<div className="p-5 space-x-2 border-t rtl:space-x-reverse">
<div className="space-x-2 border-t p-5 rtl:space-x-reverse">
<Button onClick={() => setShowTeamAvailabilityModal(false)}>{t("done")}</Button>
{props.team.membership.role !== MembershipRole.MEMBER && (
<Link href={`/settings/teams/${props.team.id}/availability`}>

View File

@ -37,19 +37,19 @@ export default function TeamCreate(props: Props) {
aria-labelledby="modal-title"
role="dialog"
aria-modal="true">
<div className="flex items-end justify-center min-h-screen px-4 pt-4 pb-20 text-center sm:block sm:p-0">
<div className="flex min-h-screen items-end justify-center px-4 pt-4 pb-20 text-center sm:block sm:p-0">
<div
className="fixed inset-0 z-0 transition-opacity bg-gray-500 bg-opacity-75"
className="fixed inset-0 z-0 bg-gray-500 bg-opacity-75 transition-opacity"
aria-hidden="true"></div>
<span className="hidden sm:inline-block sm:align-middle sm:h-screen" aria-hidden="true">
<span className="hidden sm:inline-block sm:h-screen sm:align-middle" aria-hidden="true">
&#8203;
</span>
<div className="inline-block px-4 pt-5 pb-4 text-left align-bottom transition-all transform bg-white rounded-sm shadow-xl sm:my-8 sm:align-middle sm:max-w-lg sm:w-full sm:p-6">
<div className="inline-block transform rounded-sm bg-white px-4 pt-5 pb-4 text-left align-bottom shadow-xl transition-all sm:my-8 sm:w-full sm:max-w-lg sm:p-6 sm:align-middle">
<div className="mb-4 sm:flex sm:items-start">
<div className="flex items-center justify-center flex-shrink-0 w-12 h-12 mx-auto rounded-full bg-neutral-100 sm:mx-0 sm:h-10 sm:w-10">
<UsersIcon className="w-6 h-6 text-neutral-900" />
<div className="mx-auto flex h-12 w-12 flex-shrink-0 items-center justify-center rounded-full bg-neutral-100 sm:mx-0 sm:h-10 sm:w-10">
<UsersIcon className="h-6 w-6 text-neutral-900" />
</div>
<div className="mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left">
<h3 className="text-lg font-medium leading-6 text-gray-900" id="modal-title">
@ -72,7 +72,7 @@ export default function TeamCreate(props: Props) {
id="name"
placeholder="Acme Inc."
required
className="block w-full px-3 py-2 mt-1 border border-gray-300 rounded-sm shadow-sm focus:outline-none focus:ring-neutral-500 focus:border-neutral-500 sm:text-sm"
className="mt-1 block w-full rounded-sm border border-gray-300 px-3 py-2 shadow-sm focus:border-neutral-500 focus:outline-none focus:ring-neutral-500 sm:text-sm"
/>
</div>
{errorMessage && <Alert severity="error" title={errorMessage} />}
@ -80,7 +80,7 @@ export default function TeamCreate(props: Props) {
<button type="submit" className="btn btn-primary">
{t("create_team")}
</button>
<button onClick={props.onClose} type="button" className="ltr:mr-2 btn btn-white">
<button onClick={props.onClose} type="button" className="btn btn-white ltr:mr-2">
{t("cancel")}
</button>
</div>

View File

@ -33,7 +33,7 @@ export default function TeamList(props: Props) {
return (
<div>
<ul className="mb-2 bg-white border divide-y rounded divide-neutral-200">
<ul className="mb-2 divide-y divide-neutral-200 rounded border bg-white">
{props.teams.map((team) => (
<TeamListItem
key={team?.id as number}

View File

@ -60,9 +60,9 @@ export default function TeamListItem(props: Props) {
size={9}
imageSrc={getPlaceholderAvatar(team?.logo, team?.name as string)}
alt="Team Logo"
className="rounded-full w-9 h-9 min-w-9 min-h-9"
className="h-9 min-h-9 w-9 min-w-9 rounded-full"
/>
<div className="inline-block ml-3">
<div className="ml-3 inline-block">
<span className="text-sm font-bold text-neutral-700">{team.name}</span>
<span className="block text-xs text-gray-400">
{process.env.NEXT_PUBLIC_APP_URL}/team/{team.slug}
@ -75,12 +75,12 @@ export default function TeamListItem(props: Props) {
<li className="divide-y">
<div
className={classNames(
"flex justify-between items-center",
"flex items-center justify-between",
!isInvitee && "group hover:bg-neutral-50"
)}>
{!isInvitee ? (
<Link href={"/settings/teams/" + team.id}>
<a className="flex-grow text-sm truncate cursor-pointer" title={`${team.name}`}>
<a className="flex-grow cursor-pointer truncate text-sm" title={`${team.name}`}>
{teamInfo}
</a>
</Link>
@ -108,16 +108,16 @@ export default function TeamListItem(props: Props) {
navigator.clipboard.writeText(process.env.NEXT_PUBLIC_APP_URL + "/team/" + team.slug);
showToast(t("link_copied"), "success");
}}
className="w-10 h-10 transition-none"
className="h-10 w-10 transition-none"
size="icon"
color="minimal"
type="button">
<LinkIcon className="w-5 h-5 group-hover:text-gray-600" />
<LinkIcon className="h-5 w-5 group-hover:text-gray-600" />
</Button>
</Tooltip>
<Dropdown>
<DropdownMenuTrigger className="w-10 h-10 p-0 border border-transparent group text-neutral-400 hover:border-gray-200 ">
<DotsHorizontalIcon className="w-5 h-5 group-hover:text-gray-800" />
<DropdownMenuTrigger className="group h-10 w-10 border border-transparent p-0 text-neutral-400 hover:border-gray-200 ">
<DotsHorizontalIcon className="h-5 w-5 group-hover:text-gray-800" />
</DropdownMenuTrigger>
<DropdownMenuContent>
{isAdmin && (

View File

@ -13,12 +13,12 @@ interface Props {
export default function TeamPill(props: Props) {
return (
<div
className={classNames("self-center px-3 py-1 ltr:mr-2 rtl:ml-2 text-xs capitalize border rounded-md", {
"bg-gray-50 border-gray-200 text-gray-700": !props.color,
"bg-blue-50 border-blue-200 text-blue-700": props.color === "blue",
"bg-red-50 border-red-200 text-red-700": props.color === "red",
"bg-yellow-50 border-yellow-200 text-yellow-700": props.color === "yellow",
"bg-green-50 border-green-200 text-green-600": props.color === "green",
className={classNames("self-center rounded-md border px-3 py-1 text-xs capitalize ltr:mr-2 rtl:ml-2", {
"border-gray-200 bg-gray-50 text-gray-700": !props.color,
"border-blue-200 bg-blue-50 text-blue-700": props.color === "blue",
"border-red-200 bg-red-50 text-red-700": props.color === "red",
"border-yellow-200 bg-yellow-50 text-yellow-700": props.color === "yellow",
"border-green-200 bg-green-50 text-green-600": props.color === "green",
})}>
{props.text}
</div>

View File

@ -90,7 +90,7 @@ export default function TeamSettings(props: Props) {
name="" // typescript requires name but we don't want component to render name label
id="team-url"
addOnLeading={
<span className="inline-flex items-center px-3 text-gray-500 border border-r-0 border-gray-300 rounded-l-sm bg-gray-50 sm:text-sm">
<span className="inline-flex items-center rounded-l-sm border border-r-0 border-gray-300 bg-gray-50 px-3 text-gray-500 sm:text-sm">
{process.env.NEXT_PUBLIC_APP_URL}/{"team/"}
</span>
}
@ -111,7 +111,7 @@ export default function TeamSettings(props: Props) {
id="name"
placeholder={t("your_team_name")}
required
className="block w-full px-3 py-2 mt-1 border border-gray-300 rounded-sm shadow-sm focus:outline-none focus:ring-neutral-800 focus:border-neutral-800 sm:text-sm"
className="mt-1 block w-full rounded-sm border border-gray-300 px-3 py-2 shadow-sm focus:border-neutral-800 focus:outline-none focus:ring-neutral-800 sm:text-sm"
defaultValue={team?.name as string}
/>
}
@ -130,7 +130,7 @@ export default function TeamSettings(props: Props) {
name="about"
rows={3}
defaultValue={team?.bio as string}
className="block w-full mt-1 border-gray-300 rounded-sm shadow-sm focus:ring-neutral-800 focus:border-neutral-800 sm:text-sm"></textarea>
className="mt-1 block w-full rounded-sm border-gray-300 shadow-sm focus:border-neutral-800 focus:ring-neutral-800 sm:text-sm"></textarea>
<p className="mt-2 text-sm text-gray-500">{t("team_description")}</p>
</>
}
@ -143,14 +143,14 @@ export default function TeamSettings(props: Props) {
htmlFor="avatar"
Input={
<>
<div className="flex mt-1">
<div className="mt-1 flex">
<input
ref={logoRef}
type="hidden"
name="avatar"
id="avatar"
placeholder="URL"
className="block w-full px-3 py-2 mt-1 border border-gray-300 rounded-sm shadow-sm focus:outline-none focus:ring-neutral-800 focus:border-neutral-800 sm:text-sm"
className="mt-1 block w-full rounded-sm border border-gray-300 px-3 py-2 shadow-sm focus:border-neutral-800 focus:outline-none focus:ring-neutral-800 sm:text-sm"
defaultValue={team?.logo ?? undefined}
/>
<ImageUploader
@ -165,7 +165,7 @@ export default function TeamSettings(props: Props) {
onClick={removeLogo}
color="secondary"
type="button"
className="py-1 ml-1 text-xs">
className="ml-1 py-1 text-xs">
{t("remove_logo")}
</Button>
)}
@ -178,14 +178,14 @@ export default function TeamSettings(props: Props) {
</div>
<div className="relative flex items-start">
<div className="flex items-center h-5">
<div className="flex h-5 items-center">
<input
id="hide-branding"
name="hide-branding"
type="checkbox"
ref={hideBrandingRef}
defaultChecked={team?.hideBranding}
className="w-4 h-4 border-gray-300 rounded-sm focus:ring-neutral-500 text-neutral-900"
className="h-4 w-4 rounded-sm border-gray-300 text-neutral-900 focus:ring-neutral-500"
/>
</div>
<div className="text-sm ltr:ml-3 rtl:mr-3">

View File

@ -48,7 +48,7 @@ export default function TeamSettingsRightSidebar(props: { team: TeamWithMembers;
}
return (
<div className="px-2 space-y-6">
<div className="space-y-6 px-2">
{(props.role === MembershipRole.OWNER || props.role === MembershipRole.ADMIN) && (
<CreateEventTypeButton
isIndividualTeam
@ -119,7 +119,7 @@ export default function TeamSettingsRightSidebar(props: { team: TeamWithMembers;
</div>
{props.team?.id && props.role !== MembershipRole.MEMBER && (
<Link href={`/settings/teams/${props.team.id}/availability`}>
<div className="hidden mt-5 space-y-1 sm:block">
<div className="mt-5 hidden space-y-1 sm:block">
<LinkIconButton Icon={ClockIcon}>{"View Availability"}</LinkIconButton>
<p className="mt-2 text-sm text-gray-500">See your team members availability at a glance.</p>
</div>

View File

@ -50,7 +50,7 @@ export function UpgradeToFlexibleProModal(props: Props) {
setErrorMessage(null);
}}>
<DialogTrigger asChild>
<a className="underline cursor-pointer">{"Upgrade Now"}</a>
<a className="cursor-pointer underline">{"Upgrade Now"}</a>
</DialogTrigger>
<DialogContent>
<DialogHeader title={t("Purchase missing seats")} />

View File

@ -44,7 +44,7 @@ const Team = ({ team }: TeamPageProps) => {
"absolute top-4 right-4",
"h-4 w-4",
"transition-opacity",
"opacity-0 group-hover:opacity-100 group-hover:block"
"opacity-0 group-hover:block group-hover:opacity-100"
)}
/>
@ -52,9 +52,9 @@ const Team = ({ team }: TeamPageProps) => {
<Avatar
alt={member.name || ""}
imageSrc={getPlaceholderAvatar(member.avatar, member.username)}
className="w-12 h-12 -mt-4"
className="-mt-4 h-12 w-12"
/>
<section className="w-full mt-2 space-y-1">
<section className="mt-2 w-full space-y-1">
<Text variant="title">{member.name}</Text>
<Text variant="subtitle" className="">
{member.bio || t("user_from_team", { user: member.name, team: team.name })}
@ -72,7 +72,7 @@ const Team = ({ team }: TeamPageProps) => {
}
return (
<section className="flex flex-wrap justify-center max-w-5xl min-w-full mx-auto lg:min-w-lg gap-x-6 gap-y-6">
<section className="lg:min-w-lg mx-auto flex min-w-full max-w-5xl flex-wrap justify-center gap-x-6 gap-y-6">
{members.map((member) => {
return member.username !== null && <Member key={member.id} member={member} />;
})}

View File

@ -15,10 +15,10 @@ export function Alert(props: AlertProps) {
return (
<div
className={classNames(
"rounded-sm p-3 border border-opacity-20",
"rounded-sm border border-opacity-20 p-3",
props.className,
severity === "error" && "bg-red-50 text-red-800 border-red-900",
severity === "warning" && "bg-yellow-50 text-yellow-700 border-yellow-700",
severity === "error" && "border-red-900 bg-red-50 text-red-800",
severity === "warning" && "border-yellow-700 bg-yellow-50 text-yellow-700",
severity === "success" && "bg-gray-900 text-white"
)}>
<div className="flex">
@ -33,7 +33,7 @@ export function Alert(props: AlertProps) {
<CheckCircleIcon className={classNames("h-5 w-5 text-gray-400")} aria-hidden="true" />
)}
</div>
<div className="flex-grow ml-3">
<div className="ml-3 flex-grow">
<h3 className="text-sm font-medium">{props.title}</h3>
<div className="text-sm">{props.message}</div>
</div>

View File

@ -14,26 +14,26 @@ interface Props {
export default function AuthContainer(props: React.PropsWithChildren<Props>) {
return (
<div className="flex flex-col justify-center min-h-screen py-12 bg-neutral-50 sm:px-6 lg:px-8">
<div className="flex min-h-screen flex-col justify-center bg-neutral-50 py-12 sm:px-6 lg:px-8">
<HeadSeo title={props.title} description={props.description} />
<div className="sm:mx-auto sm:w-full sm:max-w-md">
{props.showLogo && (
<img className="h-6 mx-auto" src="/calendso-logo-white-word.svg" alt="Cal.com Logo" />
<img className="mx-auto h-6" src="/calendso-logo-white-word.svg" alt="Cal.com Logo" />
)}
{props.heading && (
<h2 className="mt-6 text-3xl font-bold text-center font-cal text-neutral-900">{props.heading}</h2>
<h2 className="mt-6 text-center font-cal text-3xl font-bold text-neutral-900">{props.heading}</h2>
)}
</div>
{props.loading && (
<div className="absolute z-50 flex items-center w-full h-screen bg-gray-50">
<div className="absolute z-50 flex h-screen w-full items-center bg-gray-50">
<Loader />
</div>
)}
<div className="mt-8 sm:mx-auto sm:w-full sm:max-w-md">
<div className="px-4 py-8 mx-2 bg-white border rounded-sm sm:px-10 border-neutral-200">
<div className="mx-2 rounded-sm border border-neutral-200 bg-white px-4 py-8 sm:px-10">
{props.children}
</div>
<div className="mt-4 text-sm text-center text-neutral-600">{props.footerText}</div>
<div className="mt-4 text-center text-sm text-neutral-600">{props.footerText}</div>
</div>
</div>
);

View File

@ -36,7 +36,7 @@ export default function Avatar(props: AvatarProps) {
return title ? (
<Tooltip.Tooltip delayDuration={300}>
<Tooltip.TooltipTrigger className="cursor-default">{avatar}</Tooltip.TooltipTrigger>
<Tooltip.Content className="p-2 text-sm rounded-sm shadow-sm bg-brand text-brandcontrast">
<Tooltip.Content className="rounded-sm bg-brand p-2 text-sm text-brandcontrast shadow-sm">
<Tooltip.Arrow />
{title}
</Tooltip.Content>

View File

@ -27,7 +27,7 @@ export const AvatarGroup = function AvatarGroup(props: AvatarGroupProps) {
: [];*/
return (
<ul className={classNames("flex -rtl:space-x-reverse space-x-2 overflow-hidden", props.className)}>
<ul className={classNames("-rtl:space-x-reverse flex space-x-2 overflow-hidden", props.className)}>
{props.items.slice(0, props.truncateAfter).map((item, idx) => {
if (item.image != null) {
return (

View File

@ -13,7 +13,7 @@ export const Badge = function Badge(props: BadgeProps) {
<span
{...passThroughProps}
className={classNames(
"font-bold px-2 py-0.5 inline-block rounded-sm text-xs",
"inline-block rounded-sm px-2 py-0.5 text-xs font-bold",
variant === "default" && "bg-yellow-100 text-yellow-800",
variant === "success" && "bg-green-100 text-green-800",
variant === "gray" && "bg-gray-200 text-gray-800",

View File

@ -93,17 +93,17 @@ export const Button = forwardRef<HTMLAnchorElement | HTMLButtonElement, ButtonPr
<StartIcon
className={classNames(
"inline",
size === "icon" ? "w-5 h-5 " : "w-5 h-5 ltr:mr-2 rtl:ml-2 rtl:ml-2 rtl:-mr-1 -ml-1"
size === "icon" ? "h-5 w-5 " : "-ml-1 h-5 w-5 ltr:mr-2 rtl:ml-2 rtl:ml-2 rtl:-mr-1"
)}
/>
)}
{props.children}
{loading && (
<div className="absolute transform -translate-x-1/2 -translate-y-1/2 top-1/2 left-1/2">
<div className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 transform">
<svg
className={classNames(
"w-5 h-5 mx-4 animate-spin",
color === "primary" ? "dark:text-black text-white" : "text-black"
"mx-4 h-5 w-5 animate-spin",
color === "primary" ? "text-white dark:text-black" : "text-black"
)}
xmlns="http://www.w3.org/2000/svg"
fill="none"
@ -122,7 +122,7 @@ export const Button = forwardRef<HTMLAnchorElement | HTMLButtonElement, ButtonPr
</svg>
</div>
)}
{EndIcon && <EndIcon className="inline w-5 h-5 ltr:ml-2 rtl:mr-2 -mr-1" />}
{EndIcon && <EndIcon className="-mr-1 inline h-5 w-5 ltr:ml-2 rtl:mr-2" />}
</>
);
return props.href ? (

View File

@ -12,7 +12,7 @@ export const DropdownMenuTrigger = forwardRef<HTMLButtonElement, DropdownMenuTri
className={
props.asChild
? className
: `relative inline-flex items-center px-3 py-2 ltr:ml-2 rtl:mr-2 text-sm font-medium text-gray-700 bg-transparent rounded-sm hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-1 focus:bg-gray-100 focus:ring-neutral-500 group-hover:text-black ${className}`
: `relative inline-flex items-center rounded-sm bg-transparent px-3 py-2 text-sm font-medium text-gray-700 hover:bg-gray-50 focus:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-neutral-500 focus:ring-offset-1 group-hover:text-black ltr:ml-2 rtl:mr-2 ${className}`
}
ref={forwardedRef}
/>
@ -26,7 +26,7 @@ export const DropdownMenuContent = forwardRef<HTMLDivElement, DropdownMenuConten
return (
<DropdownMenuPrimitive.Content
{...props}
className="z-10 w-48 mt-1 text-sm origin-top-right bg-white rounded-sm shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none"
className="z-10 mt-1 w-48 origin-top-right rounded-sm bg-white text-sm shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none"
ref={forwardedRef}>
{children}
</DropdownMenuPrimitive.Content>

View File

@ -7,7 +7,7 @@ export default function InfoBadge({ content }: { content: string }) {
<>
<Tooltip content={content}>
<span title={content}>
<InformationCircleIcon className="relative w-4 h-4 mt-px text-gray-500 top-px left-1 right-1" />
<InformationCircleIcon className="relative top-px left-1 right-1 mt-px h-4 w-4 text-gray-500" />
</span>
</Tooltip>
</>

View File

@ -12,8 +12,8 @@ export default function LinkIconButton(props: LinkIconButtonProps) {
<button
type="button"
{...props}
className="flex items-center px-2 py-1 text-sm font-medium text-gray-700 rounded-sm text-md hover:text-gray-900 hover:bg-gray-200">
<props.Icon className="w-4 h-4 ltr:mr-2 rtl:ml-2 text-neutral-500" />
className="text-md flex items-center rounded-sm px-2 py-1 text-sm font-medium text-gray-700 hover:bg-gray-200 hover:text-gray-900">
<props.Icon className="h-4 w-4 text-neutral-500 ltr:mr-2 rtl:ml-2" />
{props.children}
</button>
</div>

View File

@ -14,19 +14,19 @@ export default function ModalContainer(props: Props) {
aria-labelledby="modal-title"
role="dialog"
aria-modal="true">
<div className="flex items-end justify-center min-h-screen px-4 pt-4 pb-20 text-center sm:block sm:p-0">
<div className="flex min-h-screen items-end justify-center px-4 pt-4 pb-20 text-center sm:block sm:p-0">
<div
className="fixed inset-0 z-0 transition-opacity bg-gray-500 bg-opacity-75"
className="fixed inset-0 z-0 bg-gray-500 bg-opacity-75 transition-opacity"
aria-hidden="true"></div>
<span className="hidden sm:inline-block sm:align-middle sm:h-screen" aria-hidden="true">
<span className="hidden sm:inline-block sm:h-screen sm:align-middle" aria-hidden="true">
&#8203;
</span>
<div
className={classNames(
"inline-block min-w-96 px-4 pt-5 pb-4 text-left align-bottom transition-all transform bg-white rounded-lg shadow-xl sm:my-8 sm:align-middle sm:p-6",
"inline-block min-w-96 transform rounded-lg bg-white px-4 pt-5 pb-4 text-left align-bottom shadow-xl transition-all sm:my-8 sm:p-6 sm:align-middle",
{
"sm:max-w-lg sm:w-full ": !props.wide,
"sm:max-w-4xl sm:w-4xl": props.wide,
"sm:w-full sm:max-w-lg ": !props.wide,
"sm:w-4xl sm:max-w-4xl": props.wide,
"overflow-scroll": props.scroll,
"!p-0": props.noPadding,
}

View File

@ -5,17 +5,17 @@ import { useLocale } from "@lib/hooks/useLocale";
const PoweredByCal = () => {
const { t } = useLocale();
return (
<div className="text-xs text-center sm:text-right p-1">
<div className="p-1 text-center text-xs sm:text-right">
<Link href={`https://cal.com?utm_source=embed&utm_medium=powered-by-button`}>
<a target="_blank" className="dark:text-white text-gray-500 opacity-50 hover:opacity-100">
<a target="_blank" className="text-gray-500 opacity-50 hover:opacity-100 dark:text-white">
{t("powered_by")}{" "}
<img
className="dark:hidden w-auto inline h-[10px] relative -mt-px"
className="relative -mt-px inline h-[10px] w-auto dark:hidden"
src="https://cal.com/logo.svg"
alt="Cal.com Logo"
/>
<img
className="hidden dark:inline w-auto h-[10px] relativ -mt-px"
className="relativ -mt-px hidden h-[10px] w-auto dark:inline"
src="https://cal.com/logo-white.svg"
alt="Cal.com Logo"
/>

View File

@ -66,11 +66,11 @@ export const Scheduler = ({ availability, setAvailability, timeZone, setTimeZone
};
const OpeningHours = ({ idx, item }: { idx: number; item: Availability }) => (
<li className="flex justify-between py-2 border-b">
<li className="flex justify-between border-b py-2">
<div className="flex flex-col space-y-4 lg:inline-flex">
<WeekdaySelect defaultValue={item.days} onSelect={(selected: number[]) => (item.days = selected)} />
<button
className="px-3 py-2 text-sm rounded-sm bg-neutral-100"
className="rounded-sm bg-neutral-100 px-3 py-2 text-sm"
type="button"
onClick={() => setEditSchedule(idx)}>
{item.startTime.toLocaleTimeString(i18n.language, {
@ -89,8 +89,8 @@ export const Scheduler = ({ availability, setAvailability, timeZone, setTimeZone
<button
type="button"
onClick={() => removeScheduleAt(idx)}
className="px-2 py-1 ml-1 bg-transparent btn-sm">
<TrashIcon className="inline w-5 h-5 -mt-1 text-gray-400" />
className="btn-sm ml-1 bg-transparent px-2 py-1">
<TrashIcon className="-mt-1 inline h-5 w-5 text-gray-400" />
</button>
</li>
);
@ -108,7 +108,7 @@ export const Scheduler = ({ availability, setAvailability, timeZone, setTimeZone
id="timeZone"
value={timeZone}
onChange={(tz: ITimezoneOption) => setTimeZone(tz.value)}
className="block w-full mt-1 border-gray-300 rounded-md shadow-sm focus:ring-black focus:border-brand sm:text-sm"
className="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-brand focus:ring-black sm:text-sm"
/>
</div>
</div>

View File

@ -13,12 +13,12 @@ export default function SettingInputContainer({
<div className="space-y-3">
<div className="block sm:flex">
<div className="mb-4 min-w-48 sm:mb-0">
<label htmlFor={htmlFor} className="flex mt-1 text-sm font-medium text-neutral-700">
<Icon className="w-4 h-4 ltr:mr-2 rtl:ml-2 mt-0.5 text-neutral-500" />
<label htmlFor={htmlFor} className="mt-1 flex text-sm font-medium text-neutral-700">
<Icon className="mt-0.5 h-4 w-4 text-neutral-500 ltr:mr-2 rtl:ml-2" />
{label}
</label>
</div>
<div className="flex-grow w-full">{Input}</div>
<div className="w-full flex-grow">{Input}</div>
</div>
</div>
);

View File

@ -20,16 +20,16 @@ export default function Switch(props: SwitchProps) {
};
const id = useId();
return (
<div className="flex items-center h-[20px]">
<div className="flex h-[20px] items-center">
<PrimitiveSwitch.Root
className={classNames(checked ? "bg-gray-900" : "bg-gray-400", "rounded-sm w-[36px] p-0.5 h-[20px]")}
className={classNames(checked ? "bg-gray-900" : "bg-gray-400", "h-[20px] w-[36px] rounded-sm p-0.5")}
checked={checked}
onCheckedChange={onPrimitiveCheckedChange}
{...primitiveProps}>
<PrimitiveSwitch.Thumb
id={id}
className={classNames(
"bg-white w-[16px] h-[16px] block transition-transform",
"block h-[16px] w-[16px] bg-white transition-transform",
checked ? "translate-x-[16px]" : "translate-x-0"
)}
/>
@ -37,7 +37,7 @@ export default function Switch(props: SwitchProps) {
{label && (
<Label.Root
htmlFor={id}
className="text-sm font-medium align-text-top cursor-pointer text-neutral-700 ltr:ml-3 rtl:mr-3">
className="cursor-pointer align-text-top text-sm font-medium text-neutral-700 ltr:ml-3 rtl:mr-3">
{label}
</Label.Root>
)}

View File

@ -24,7 +24,7 @@ const TableActions: FC<Props> = ({ actions }) => {
const { t } = useLocale();
return (
<>
<div className="rtl:space-x-reverse space-x-2 hidden lg:block">
<div className="hidden space-x-2 rtl:space-x-reverse lg:block">
{actions.map((action) => (
<Button
key={action.id}
@ -38,11 +38,11 @@ const TableActions: FC<Props> = ({ actions }) => {
</Button>
))}
</div>
<Menu as="div" className="inline-block lg:hidden text-left ">
<Menu as="div" className="inline-block text-left lg:hidden ">
{({ open }) => (
<>
<div>
<Menu.Button className="text-neutral-400 mt-1 p-2 border border-transparent hover:border-gray-200">
<Menu.Button className="mt-1 border border-transparent p-2 text-neutral-400 hover:border-gray-200">
<span className="sr-only">{t("open_options")}</span>
<DotsHorizontalIcon className="h-5 w-5" aria-hidden="true" />
</Menu.Button>
@ -59,7 +59,7 @@ const TableActions: FC<Props> = ({ actions }) => {
leaveTo="transform opacity-0 scale-95">
<Menu.Items
static
className="origin-top-right absolute right-0 mt-2 w-56 rounded-sm shadow-lg bg-white ring-1 ring-black ring-opacity-5 focus:outline-none divide-y divide-neutral-100">
className="absolute right-0 mt-2 w-56 origin-top-right divide-y divide-neutral-100 rounded-sm bg-white shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none">
<div className="py-1">
{actions.map((action) => {
const Element = typeof action.onClick === "function" ? "span" : "a";
@ -74,7 +74,7 @@ const TableActions: FC<Props> = ({ actions }) => {
"group flex items-center px-4 py-2 text-sm font-medium"
)}>
<action.icon
className="ltr:mr-3 h-5 w-5 text-neutral-400 group-hover:text-neutral-500"
className="h-5 w-5 text-neutral-400 group-hover:text-neutral-500 ltr:mr-3"
aria-hidden="true"
/>
{action.label}

View File

@ -33,8 +33,8 @@ export const WeekdaySelect = (props: WeekdaySelectProps) => {
toggleDay(idx);
}}
className={`
w-10 h-10
bg-brand text-brandcontrast focus:outline-none px-3 py-1 rounded
h-10 w-10
rounded bg-brand px-3 py-1 text-brandcontrast focus:outline-none
${activeDays[idx + 1] ? "rounded-r-none" : ""}
${activeDays[idx - 1] ? "rounded-l-none" : ""}
${idx === 0 ? "rounded-l" : ""}
@ -50,7 +50,7 @@ export const WeekdaySelect = (props: WeekdaySelectProps) => {
toggleDay(idx);
}}
style={{ marginTop: "1px", marginBottom: "1px" }}
className={`w-10 h-10 bg-gray-50 focus:outline-none px-3 py-1 rounded-none ${
className={`h-10 w-10 rounded-none bg-gray-50 px-3 py-1 focus:outline-none ${
idx === 0 ? "rounded-l" : "border-l-0"
} ${idx === days.length - 1 ? "rounded-r" : ""}`}>
{day}

View File

@ -69,13 +69,13 @@ const ColorPicker = (props: ColorPickerProps) => {
const close = useCallback(() => toggle(false), []);
useOnClickOutside(popover, close);
return (
<div className="relative flex items-center justify-center mt-1">
<div className="relative mt-1 flex items-center justify-center">
<Swatch size="sm" backgroundColor={color} onClick={() => toggle(!isOpen)} />
{isOpen && (
<div className="popover" ref={popover}>
<HexColorPicker
className="!w-32 !h-32 !absolute !top-10 !left-0 !z-10"
className="!absolute !top-10 !left-0 !z-10 !h-32 !w-32"
color={color}
onChange={(val) => {
setColor(val);
@ -85,7 +85,7 @@ const ColorPicker = (props: ColorPickerProps) => {
</div>
)}
<HexColorInput
className="block w-full px-3 py-2 ml-1 border border-gray-300 rounded-sm shadow-sm focus:outline-none focus:ring-neutral-800 focus:border-neutral-800 sm:text-sm"
className="ml-1 block w-full rounded-sm border border-gray-300 px-3 py-2 shadow-sm focus:border-neutral-800 focus:outline-none focus:ring-neutral-800 sm:text-sm"
color={color}
onChange={(val) => {
setColor(val);

View File

@ -7,7 +7,7 @@ type Props = InputHTMLAttributes<HTMLInputElement> & {
const CheckboxField = forwardRef<HTMLInputElement, Props>(({ label, description, ...rest }, ref) => {
return (
<div className="items-center block sm:flex">
<div className="block items-center sm:flex">
<div className="mb-4 min-w-48 sm:mb-0">
<label htmlFor={rest.id} className="flex text-sm font-medium text-neutral-700">
{label}
@ -15,15 +15,15 @@ const CheckboxField = forwardRef<HTMLInputElement, Props>(({ label, description,
</div>
<div className="w-full">
<div className="relative flex items-start">
<div className="flex items-center h-5">
<div className="flex h-5 items-center">
<input
{...rest}
ref={ref}
type="checkbox"
className="w-4 h-4 border-gray-300 rounded focus:ring-primary-500 text-primary-600"
className="h-4 w-4 rounded border-gray-300 text-primary-600 focus:ring-primary-500"
/>
</div>
<div className="ltr:ml-3 rtl:mr-3 text-sm">
<div className="text-sm ltr:ml-3 rtl:mr-3">
<p className="text-neutral-900">{description}</p>
</div>
</div>

View File

@ -1,15 +1,15 @@
import { CheckIcon, XIcon } from "@heroicons/react/outline";
import React, { ForwardedRef, useEffect, useState } from "react";
import { useLocale } from "@lib/hooks/useLocale";
import Avatar from "@components/ui/Avatar";
import Select from "@components/ui/form/Select";
import { CheckIcon, XIcon } from "@heroicons/react/outline";
import { useLocale } from "@lib/hooks/useLocale";
import React, { useEffect, useState } from "react";
import { MultiValue } from "react-select";
type CheckedSelectValue = {
avatar: string;
label: string;
value: string;
disabled?: boolean;
}[];
export type CheckedSelectProps = {
@ -21,7 +21,7 @@ export type CheckedSelectProps = {
disabled: boolean;
};
export const CheckedSelect = React.forwardRef((props: CheckedSelectProps, ref: ForwardedRef<unknown>) => {
export const CheckedSelect = (props: CheckedSelectProps) => {
const [selectedOptions, setSelectedOptions] = useState<CheckedSelectValue>(props.defaultValue || []);
const { t } = useLocale();
@ -29,18 +29,6 @@ export const CheckedSelect = React.forwardRef((props: CheckedSelectProps, ref: F
props.onChange(selectedOptions);
}, [selectedOptions]);
const formatOptionLabel = ({ label, avatar, disabled }) => (
<div className="flex">
<Avatar className="h-6 w-6 rounded-full mr-3" displayName={label} imageSrc={avatar} />
{label}
{disabled && (
<div className="flex-grow">
<CheckIcon className="text-neutral-500 w-6 h-6 float-right" />
</div>
)}
</div>
);
const options = props.options.map((option) => ({
...option,
disabled: !!selectedOptions.find((selectedOption) => selectedOption.value === option.value),
@ -49,7 +37,7 @@ export const CheckedSelect = React.forwardRef((props: CheckedSelectProps, ref: F
const removeOption = (value: string) =>
setSelectedOptions(selectedOptions.filter((option) => option.value !== value));
const changeHandler = (selections) =>
const changeHandler = (selections: MultiValue<CheckedSelectValue[number]>) =>
selections.forEach((selected) => {
if (selectedOptions.find((option) => option.value === selected.value)) {
removeOption(selected.value);
@ -60,8 +48,7 @@ export const CheckedSelect = React.forwardRef((props: CheckedSelectProps, ref: F
return (
<>
<Select
ref={ref}
<Select<CheckedSelectValue[number], true>
styles={{
option: (styles, { isDisabled }) => ({
...styles,
@ -71,29 +58,39 @@ export const CheckedSelect = React.forwardRef((props: CheckedSelectProps, ref: F
name={props.name}
placeholder={props.placeholder || t("select")}
isSearchable={false}
formatOptionLabel={formatOptionLabel}
formatOptionLabel={({ label, avatar, disabled }) => (
<div className="flex">
<Avatar className="mr-3 h-6 w-6 rounded-full" alt={label} imageSrc={avatar} />
{label}
{disabled && (
<div className="flex-grow">
<CheckIcon className="float-right h-6 w-6 text-neutral-500" />
</div>
)}
</div>
)}
options={options}
isMulti
value={props.placeholder || t("select")}
// value={props.placeholder || t("select")}
onChange={changeHandler}
/>
{selectedOptions.map((option) => (
<div key={option.value} className="border border-1 p-2 font-medium">
<div key={option.value} className="border-1 border p-2 font-medium">
<Avatar
className="w-6 h-6 rounded-full inline ltr:mr-2 rtl:ml-2"
className="inline h-6 w-6 rounded-full ltr:mr-2 rtl:ml-2"
imageSrc={option.avatar}
displayName={option.label}
alt={option.label}
/>
{option.label}
<XIcon
onClick={() => changeHandler([option])}
className="cursor-pointer h-5 w-5 mt-0.5 text-neutral-500 float-right"
className="float-right mt-0.5 h-5 w-5 cursor-pointer text-neutral-500"
/>
</div>
))}
</>
);
});
};
CheckedSelect.displayName = "CheckedSelect";

View File

@ -16,11 +16,11 @@ export const DatePicker = ({ date, onDatesChange, className }: Props) => {
return (
<PrimitiveDatePicker
className={classNames(
"p-1 pl-2 border border-gray-300 rounded-sm shadow-sm focus:ring-primary-500 focus:border-primary-500 sm:text-sm",
"rounded-sm border border-gray-300 p-1 pl-2 shadow-sm focus:border-primary-500 focus:ring-primary-500 sm:text-sm",
className
)}
clearIcon={null}
calendarIcon={<CalendarIcon className="w-5 h-5 text-gray-500" />}
calendarIcon={<CalendarIcon className="h-5 w-5 text-gray-500" />}
value={date}
onChange={onDatesChange}
/>

View File

@ -14,13 +14,13 @@ type Props = {
export const DateRangePicker = ({ startDate, endDate, onDatesChange }: Props) => {
return (
<PrimitiveDateRangePicker
className="border-gray-300 rounded-sm focus:ring-primary-500 focus:border-primary-500 sm:text-sm"
className="rounded-sm border-gray-300 focus:border-primary-500 focus:ring-primary-500 sm:text-sm"
clearIcon={null}
calendarIcon={<CalendarIcon className="h-5 w-5 text-gray-500" />}
rangeDivider={<ArrowRightIcon className="h-4 w-4 text-gray-400 ltr:mr-2 rtl:ml-2" />}
value={[startDate, endDate]}
onChange={([startDate, endDate]) => {
onDatesChange({ startDate, endDate });
if (typeof onDatesChange === "function") onDatesChange({ startDate, endDate });
}}
/>
);

View File

@ -10,7 +10,7 @@ const MinutesField = forwardRef<HTMLInputElement, Props>(({ label, ...rest }, re
<div className="block sm:flex">
{!!label && (
<div className="mb-4 min-w-48 sm:mb-0">
<label htmlFor={rest.id} className="flex items-center h-full text-sm font-medium text-neutral-700">
<label htmlFor={rest.id} className="flex h-full items-center text-sm font-medium text-neutral-700">
{label}
</label>
</div>
@ -22,11 +22,11 @@ const MinutesField = forwardRef<HTMLInputElement, Props>(({ label, ...rest }, re
ref={ref}
type="number"
className={classNames(
"block w-full pl-2 pr-12 border-gray-300 rounded-sm focus:ring-primary-500 focus:border-primary-500 sm:text-sm",
"block w-full rounded-sm border-gray-300 pl-2 pr-12 focus:border-primary-500 focus:ring-primary-500 sm:text-sm",
rest.className
)}
/>
<div className="absolute inset-y-0 right-0 flex items-center pr-3 pointer-events-none">
<div className="pointer-events-none absolute inset-y-0 right-0 flex items-center pr-3">
<span className="text-gray-500 sm:text-sm" id="duration">
mins
</span>

View File

@ -9,7 +9,7 @@ export const PhoneInput = (props: Optional<PhoneInputProps, "onChange">) => (
<BasePhoneInput
{...props}
className={classNames(
"shadow-sm rounded-sm block w-full py-px px-3 border border-1 border-gray-300 ring-black focus-within:ring-1 focus-within:border-brand dark:border-black dark:text-white dark:bg-black",
"border-1 block w-full rounded-sm border border-gray-300 py-px px-3 shadow-sm ring-black focus-within:border-brand focus-within:ring-1 dark:border-black dark:bg-black dark:text-white",
props.className
)}
onChange={() => {

View File

@ -139,21 +139,21 @@ const ScheduleBlock = ({ name, day, weekday }: ScheduleBlockProps) => {
};
return (
<fieldset className="flex flex-col space-y-2 sm:space-y-0 sm:flex-row justify-between py-5 min-h-[86px]">
<fieldset className="flex min-h-[86px] flex-col justify-between space-y-2 py-5 sm:flex-row sm:space-y-0">
<div className="w-1/3">
<label className="flex items-center space-x-2 rtl:space-x-reverse">
<input
type="checkbox"
checked={fields.length > 0}
onChange={(e) => (e.target.checked ? replace([defaultDayRange]) : replace([]))}
className="inline-block border-gray-300 rounded-sm focus:ring-neutral-500 text-neutral-900"
className="inline-block rounded-sm border-gray-300 text-neutral-900 focus:ring-neutral-500"
/>
<span className="inline-block text-sm capitalize">{weekday}</span>
</label>
</div>
<div className="flex-grow">
{fields.map((field, index) => (
<div key={field.id} className="flex justify-between mb-1">
<div key={field.id} className="mb-1 flex justify-between">
<div className="flex items-center space-x-2 rtl:space-x-reverse">
<TimeRangeField name={`${name}.${day}.${index}`} />
</div>

View File

@ -11,7 +11,7 @@ const RadioArea = (props: RadioAreaProps) => {
return (
<label
className={classNames(
"block border border-1 p-4 focus:outline-none focus:ring focus:ring-neutral-500",
"border-1 block border p-4 focus:outline-none focus:ring focus:ring-neutral-500",
props.checked && "border-brand",
props.className
)}>

View File

@ -7,13 +7,15 @@ import { useLocale } from "@lib/hooks/useLocale";
import { RadioArea, RadioAreaGroup } from "@components/ui/form/radio-area/RadioAreaGroup";
type OptionProps = React.OptionHTMLAttributes<HTMLOptionElement> & {
interface OptionProps
extends Pick<React.OptionHTMLAttributes<HTMLOptionElement>, "value" | "label" | "className"> {
description?: string;
};
}
type RadioAreaSelectProps = React.SelectHTMLAttributes<HTMLSelectElement> & {
interface RadioAreaSelectProps extends Omit<React.SelectHTMLAttributes<HTMLSelectElement>, "onChange"> {
options: OptionProps[]; // allow options to be passed programmatically, like options={}
};
onChange?: (value: string) => void;
}
export const Select = function RadioAreaSelect(props: RadioAreaSelectProps) {
const { t } = useLocale();
@ -23,7 +25,7 @@ export const Select = function RadioAreaSelect(props: RadioAreaSelectProps) {
placeholder = t("select"),
} = props;
const getLabel = (value: string | ReadonlyArray<string> | number) =>
const getLabel = (value: string | ReadonlyArray<string> | number | undefined) =>
options.find((option: OptionProps) => option.value === value)?.label;
return (
@ -32,8 +34,8 @@ export const Select = function RadioAreaSelect(props: RadioAreaSelectProps) {
type="button"
disabled={disabled}
className={classNames(
"mb-1 cursor-pointer focus:ring-primary-500 text-left border border-1 bg-white p-2 shadow-sm block w-full sm:text-sm border-gray-300 rounded-sm",
disabled && "focus:ring-0 cursor-default bg-gray-200 "
"border-1 mb-1 block w-full cursor-pointer rounded-sm border border-gray-300 bg-white p-2 text-left shadow-sm focus:ring-primary-500 sm:text-sm",
disabled && "cursor-default bg-gray-200 focus:ring-0 "
)}>
{getLabel(props.value) ?? placeholder}
<ChevronDownIcon className="float-right h-5 w-5 text-neutral-500" />
@ -41,8 +43,11 @@ export const Select = function RadioAreaSelect(props: RadioAreaSelectProps) {
<CollapsibleContent>
<RadioAreaGroup className="space-y-2 text-sm" name={props.name} onChange={props.onChange}>
{options.map((option) => (
<RadioArea {...option} key={option.value} defaultChecked={props.value === option.value}>
<strong className="block mb-1">{option.label}</strong>
<RadioArea
{...option}
key={Array.isArray(option.value) ? option.value.join(",") : `${option.value}`}
defaultChecked={props.value === option.value}>
<strong className="mb-1 block">{option.label}</strong>
<p>{option.description}</p>
</RadioArea>
))}

View File

@ -5,31 +5,21 @@ import { useLocale } from "@lib/hooks/useLocale";
import Button from "@components/ui/Button";
export default function SetTimesModal(props) {
interface SetTimesModalProps {
startTime: number;
endTime: number;
onChange: (times: { startTime: number; endTime: number }) => void;
onExit: (...p: unknown[]) => void;
}
export default function SetTimesModal(props: SetTimesModalProps) {
const { t } = useLocale();
const [startHours, startMinutes] = [Math.floor(props.startTime / 60), props.startTime % 60];
const [endHours, endMinutes] = [Math.floor(props.endTime / 60), props.endTime % 60];
const startHoursRef = useRef<HTMLInputElement>();
const startMinsRef = useRef<HTMLInputElement>();
const endHoursRef = useRef<HTMLInputElement>();
const endMinsRef = useRef<HTMLInputElement>();
function updateStartEndTimesHandler(event) {
event.preventDefault();
const enteredStartHours = parseInt(startHoursRef.current.value);
const enteredStartMins = parseInt(startMinsRef.current.value);
const enteredEndHours = parseInt(endHoursRef.current.value);
const enteredEndMins = parseInt(endMinsRef.current.value);
props.onChange({
startTime: enteredStartHours * 60 + enteredStartMins,
endTime: enteredEndHours * 60 + enteredEndMins,
});
props.onExit(0);
}
const startHoursRef = useRef<HTMLInputElement>(null!);
const startMinsRef = useRef<HTMLInputElement>(null!);
const endHoursRef = useRef<HTMLInputElement>(null!);
const endMinsRef = useRef<HTMLInputElement>(null!);
return (
<div
@ -37,19 +27,19 @@ export default function SetTimesModal(props) {
aria-labelledby="modal-title"
role="dialog"
aria-modal="true">
<div className="flex items-end justify-center min-h-screen px-4 pt-4 pb-20 text-center sm:block sm:p-0">
<div className="flex min-h-screen items-end justify-center px-4 pt-4 pb-20 text-center sm:block sm:p-0">
<div
className="fixed inset-0 z-0 transition-opacity bg-gray-500 bg-opacity-75"
className="fixed inset-0 z-0 bg-gray-500 bg-opacity-75 transition-opacity"
aria-hidden="true"></div>
<span className="hidden sm:inline-block sm:align-middle sm:h-screen" aria-hidden="true">
<span className="hidden sm:inline-block sm:h-screen sm:align-middle" aria-hidden="true">
&#8203;
</span>
<div className="inline-block px-4 pt-5 pb-4 overflow-hidden text-left align-bottom transition-all transform bg-white rounded-lg shadow-xl sm:my-8 sm:align-middle sm:max-w-lg sm:w-full sm:p-6">
<div className="inline-block transform overflow-hidden rounded-lg bg-white px-4 pt-5 pb-4 text-left align-bottom shadow-xl transition-all sm:my-8 sm:w-full sm:max-w-lg sm:p-6 sm:align-middle">
<div className="mb-4 sm:flex sm:items-start">
<div className="flex items-center justify-center flex-shrink-0 w-12 h-12 mx-auto bg-blue-100 rounded-full sm:mx-0 sm:h-10 sm:w-10">
<ClockIcon className="w-6 h-6 text-black" />
<div className="mx-auto flex h-12 w-12 flex-shrink-0 items-center justify-center rounded-full bg-blue-100 sm:mx-0 sm:h-10 sm:w-10">
<ClockIcon className="h-6 w-6 text-black" />
</div>
<div className="mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left">
<h3 className="text-lg font-medium leading-6 text-gray-900" id="modal-title">
@ -60,7 +50,7 @@ export default function SetTimesModal(props) {
</div>
</div>
</div>
<div className="flex mb-4">
<div className="mb-4 flex">
<label className="block w-1/4 pt-2 text-sm font-medium text-gray-700">{t("start_time")}</label>
<div>
<label htmlFor="startHours" className="sr-only">
@ -71,15 +61,15 @@ export default function SetTimesModal(props) {
type="number"
min="0"
max="23"
maxLength="2"
maxLength={2}
name="hours"
id="startHours"
className="block w-full border-gray-300 rounded-md shadow-sm focus:ring-black focus:border-brand sm:text-sm"
className="block w-full rounded-md border-gray-300 shadow-sm focus:border-brand focus:ring-black sm:text-sm"
placeholder="9"
defaultValue={startHours}
/>
</div>
<span className="pt-1 mx-2">:</span>
<span className="mx-2 pt-1">:</span>
<div>
<label htmlFor="startMinutes" className="sr-only">
{t("minutes")}
@ -90,10 +80,10 @@ export default function SetTimesModal(props) {
min="0"
max="59"
step="15"
maxLength="2"
maxLength={2}
name="minutes"
id="startMinutes"
className="block w-full border-gray-300 rounded-md shadow-sm focus:ring-black focus:border-brand sm:text-sm"
className="block w-full rounded-md border-gray-300 shadow-sm focus:border-brand focus:ring-black sm:text-sm"
placeholder="30"
defaultValue={startMinutes}
/>
@ -110,15 +100,15 @@ export default function SetTimesModal(props) {
type="number"
min="0"
max="24"
maxLength="2"
maxLength={2}
name="hours"
id="endHours"
className="block w-full border-gray-300 rounded-md shadow-sm focus:ring-black focus:border-brand sm:text-sm"
className="block w-full rounded-md border-gray-300 shadow-sm focus:border-brand focus:ring-black sm:text-sm"
placeholder="17"
defaultValue={endHours}
/>
</div>
<span className="pt-1 mx-2">:</span>
<span className="mx-2 pt-1">:</span>
<div>
<label htmlFor="endMinutes" className="sr-only">
{t("minutes")}
@ -128,18 +118,34 @@ export default function SetTimesModal(props) {
type="number"
min="0"
max="59"
maxLength="2"
maxLength={2}
step="15"
name="minutes"
id="endMinutes"
className="block w-full border-gray-300 rounded-md shadow-sm focus:ring-black focus:border-brand sm:text-sm"
className="block w-full rounded-md border-gray-300 shadow-sm focus:border-brand focus:ring-black sm:text-sm"
placeholder="30"
defaultValue={endMinutes}
/>
</div>
</div>
<div className="mt-5 sm:mt-4 sm:flex sm:flex-row-reverse">
<Button onClick={updateStartEndTimesHandler} type="submit">
<Button
onClick={(event) => {
event.preventDefault();
const enteredStartHours = parseInt(startHoursRef.current.value);
const enteredStartMins = parseInt(startMinsRef.current.value);
const enteredEndHours = parseInt(endHoursRef.current.value);
const enteredEndMins = parseInt(endMinsRef.current.value);
props.onChange({
startTime: enteredStartHours * 60 + enteredStartMins,
endTime: enteredEndHours * 60 + enteredEndMins,
});
props.onExit(0);
}}
type="submit">
{t("save")}
</Button>
<Button onClick={props.onExit} type="button" color="secondary" className="ltr:mr-2">

View File

@ -3,7 +3,7 @@ import React from "react";
function UserCalendarIllustration() {
return (
<svg
className="w-1/2 md:w-32 mx-auto block mb-4"
className="mx-auto mb-4 block w-1/2 md:w-32"
viewBox="0 0 132 132"
fill="none"
xmlns="http://www.w3.org/2000/svg">

View File

@ -24,40 +24,40 @@ export default function LicenseBanner() {
}
return (
<div className="fixed inset-x-0 bottom-0 left-0 pb-2 md:left-56 sm:pb-5">
<div className="px-2 mx-auto max-w-7xl sm:px-8">
<div className="p-2 bg-green-600 rounded-sm shadow-lg sm:p-3">
<div className="fixed inset-x-0 bottom-0 left-0 pb-2 sm:pb-5 md:left-56">
<div className="mx-auto max-w-7xl px-2 sm:px-8">
<div className="rounded-sm bg-green-600 p-2 shadow-lg sm:p-3">
<div className="flex flex-wrap items-center justify-between">
<div className="flex items-center flex-1 w-0">
<span className="flex p-2 bg-green-800 rounded-sm">
<BadgeCheckIcon className="w-6 h-6 text-white" aria-hidden="true" />
<div className="flex w-0 flex-1 items-center">
<span className="flex rounded-sm bg-green-800 p-2">
<BadgeCheckIcon className="h-6 w-6 text-white" aria-hidden="true" />
</span>
<p className="ml-3 font-medium text-white truncate">
<p className="ml-3 truncate font-medium text-white">
<span className="inline">
<Trans i18nKey="accept_our_license" values={{ agree: "agree" }}>
Accept our license by changing the .env variable
<span className="px-1 bg-gray-50 bg-opacity-20">NEXT_PUBLIC_LICENSE_CONSENT</span> to
<span className="bg-gray-50 bg-opacity-20 px-1">NEXT_PUBLIC_LICENSE_CONSENT</span> to
&apos;agree&apos;.
</Trans>
</span>
</p>
</div>
<div className="flex-shrink-0 order-3 w-full mt-2 sm:order-2 sm:mt-0 sm:w-auto">
<div className="order-3 mt-2 w-full flex-shrink-0 sm:order-2 sm:mt-0 sm:w-auto">
<Dialog>
<DialogTrigger asChild>
<button className="flex items-center justify-center w-full px-4 py-2 text-sm font-medium text-green-600 bg-white border border-transparent rounded-sm shadow-sm hover:bg-green-50">
<button className="flex w-full items-center justify-center rounded-sm border border-transparent bg-white px-4 py-2 text-sm font-medium text-green-600 shadow-sm hover:bg-green-50">
{t("accept_license")}
</button>
</DialogTrigger>
<DialogContent />
</Dialog>
</div>
<div className="flex-shrink-0 order-2 sm:order-3 sm:ml-2">
<div className="order-2 flex-shrink-0 sm:order-3 sm:ml-2">
<Dialog>
<DialogTrigger asChild>
<button className="flex p-2 -mr-1 rounded-sm hover:bg-green-500 focus:outline-none focus:ring-2 focus:ring-white">
<button className="-mr-1 flex rounded-sm p-2 hover:bg-green-500 focus:outline-none focus:ring-2 focus:ring-white">
<span className="sr-only">{t("dismiss")}</span>
<XIcon className="w-6 h-6 text-white" aria-hidden="true" />
<XIcon className="h-6 w-6 text-white" aria-hidden="true" />
</button>
</DialogTrigger>
<DialogContent />
@ -78,12 +78,12 @@ export default function LicenseBanner() {
cancelBtnText={t("cancel")}>
<Trans i18nKey="remove_banner_instructions" values={{ agree: "agree" }}>
To remove this banner, please open your .env file and change the
<span className="bg-green-400 text-green-500 bg-opacity-20 p-[2px]">
<span className="bg-green-400 bg-opacity-20 p-[2px] text-green-500">
NEXT_PUBLIC_LICENSE_CONSENT
</span>{" "}
</span>
variable to &apos;agreeapos;.
</Trans>
<h2 className="mt-8 mb-2 text-black font-cal">{t("terms_summary")}:</h2>
<h2 className="mt-8 mb-2 font-cal text-black">{t("terms_summary")}:</h2>
<ul className="ml-5 list-disc">
<li>{t("codebase_has_to_stay_opensource")}</li>
<li>{t("cannot_repackage_codebase")}</li>

View File

@ -19,13 +19,13 @@ const TrialBanner = () => {
return (
<div
className="hidden p-4 m-4 text-sm font-medium text-center text-gray-600 bg-yellow-200 rounded-md sm:block"
className="m-4 hidden rounded-md bg-yellow-200 p-4 text-center text-sm font-medium text-gray-600 sm:block"
data-testid="trial-banner">
<div className="mb-2 text-left">{t("trial_days_left", { days: trialDaysLeft })}</div>
<Button
href="/api/upgrade"
color="minimal"
className="justify-center w-full border-2 border-gray-600 hover:bg-yellow-100">
className="w-full justify-center border-2 border-gray-600 hover:bg-yellow-100">
{t("upgrade_now")}
</Button>
</div>

View File

@ -94,7 +94,7 @@ export default function SAMLConfiguration({
<>
<hr className="mt-8" />
<div className="mt-6">
<h2 className="text-lg font-medium leading-6 text-gray-900 font-cal">
<h2 className="font-cal text-lg font-medium leading-6 text-gray-900">
{t("saml_configuration")}
<Badge className="ml-2 text-xs" variant={samlConfig ? "success" : "gray"}>
{samlConfig ? t("enabled") : t("disabled")}
@ -110,7 +110,7 @@ export default function SAMLConfiguration({
</div>
{samlConfig ? (
<div className="flex mt-2">
<div className="mt-2 flex">
<Dialog>
<DialogTrigger asChild>
<Button

View File

@ -106,7 +106,7 @@ export default function PaymentComponent(props: Props) {
return (
<form id="payment-form" className="mt-4" onSubmit={handleSubmit}>
<CardElement id="card-element" options={CARD_OPTIONS} onChange={handleChange} />
<div className="flex justify-center mt-2">
<div className="mt-2 flex justify-center">
<Button
type="submit"
disabled={["processing", "error"].includes(state.status)}

View File

@ -40,25 +40,25 @@ const PaymentPage: FC<PaymentPageProps> = (props) => {
</title>
<link rel="icon" href="/favicon.ico" />
</Head>
<main className="max-w-3xl py-24 mx-auto">
<main className="mx-auto max-w-3xl py-24">
<div className="fixed inset-0 z-50 overflow-y-auto">
<div className="flex items-end justify-center min-h-screen px-4 pt-4 pb-20 text-center sm:block sm:p-0">
<div className="flex min-h-screen items-end justify-center px-4 pt-4 pb-20 text-center sm:block sm:p-0">
<div className="fixed inset-0 my-4 transition-opacity sm:my-0" aria-hidden="true">
<span className="hidden sm:inline-block sm:align-middle sm:h-screen" aria-hidden="true">
<span className="hidden sm:inline-block sm:h-screen sm:align-middle" aria-hidden="true">
&#8203;
</span>
<div
className="inline-block px-8 pt-5 pb-4 overflow-hidden text-left align-bottom transition-all transform bg-white border rounded-sm dark:bg-gray-800 border-neutral-200 dark:border-neutral-700 sm:my-8 sm:align-middle sm:max-w-lg sm:w-full sm:py-6"
className="inline-block transform overflow-hidden rounded-sm border border-neutral-200 bg-white px-8 pt-5 pb-4 text-left align-bottom transition-all dark:border-neutral-700 dark:bg-gray-800 sm:my-8 sm:w-full sm:max-w-lg sm:py-6 sm:align-middle"
role="dialog"
aria-modal="true"
aria-labelledby="modal-headline">
<div>
<div className="flex items-center justify-center w-12 h-12 mx-auto bg-green-100 rounded-full">
<CreditCardIcon className="w-8 h-8 text-green-600" />
<div className="mx-auto flex h-12 w-12 items-center justify-center rounded-full bg-green-100">
<CreditCardIcon className="h-8 w-8 text-green-600" />
</div>
<div className="mt-3 text-center sm:mt-5">
<h3
className="text-2xl font-semibold leading-6 dark:text-white text-neutral-900"
className="text-2xl font-semibold leading-6 text-neutral-900 dark:text-white"
id="modal-headline">
{t("payment")}
</h3>
@ -67,7 +67,7 @@ const PaymentPage: FC<PaymentPageProps> = (props) => {
{t("pay_later_instructions")}
</p>
</div>
<div className="grid grid-cols-3 py-4 mt-4 text-left text-gray-700 border-t border-b dark:text-gray-300 dark:border-gray-900">
<div className="mt-4 grid grid-cols-3 border-t border-b py-4 text-left text-gray-700 dark:border-gray-900 dark:text-gray-300">
<div className="font-medium">{t("what")}</div>
<div className="col-span-2 mb-6">{eventName}</div>
<div className="font-medium">{t("when")}</div>
@ -117,7 +117,7 @@ const PaymentPage: FC<PaymentPageProps> = (props) => {
)}
</div>
{!props.profile.hideBranding && (
<div className="pt-4 mt-4 text-xs text-center text-gray-400 border-t dark:border-gray-900 dark:text-white">
<div className="mt-4 border-t pt-4 text-center text-xs text-gray-400 dark:border-gray-900 dark:text-white">
<a href="https://cal.com/signup">{t("create_booking_link_with_calcom")}</a>
</div>
)}

View File

@ -32,17 +32,17 @@ export default function TeamAvailabilityModal(props: Props) {
}, [utils, selectedTimeZone, selectedDate]);
return (
<div className="flex flex-row max-h-[500px] min-h-[500px] rtl:space-x-reverse space-x-8">
<div className="w-64 p-5 pr-0 space-y-5 min-w-64">
<div className="flex max-h-[500px] min-h-[500px] flex-row space-x-8 rtl:space-x-reverse">
<div className="w-64 min-w-64 space-y-5 p-5 pr-0">
<div className="flex">
<Avatar
imageSrc={getPlaceholderAvatar(props.member?.avatar, props.member?.name as string)}
alt={props.member?.name || ""}
className="rounded-full w-14 h-14"
className="h-14 w-14 rounded-full"
/>
<div className="inline-block pt-1 ml-3">
<div className="ml-3 inline-block pt-1">
<span className="text-lg font-bold text-neutral-700">{props.member?.name}</span>
<span className="block -mt-1 text-sm text-gray-400">{props.member?.email}</span>
<span className="-mt-1 block text-sm text-gray-400">{props.member?.email}</span>
</div>
</div>
<div className="flex flex-col">
@ -61,7 +61,7 @@ export default function TeamAvailabilityModal(props: Props) {
value={selectedTimeZone}
onChange={(timezone) => setSelectedTimeZone(timezone.value)}
classNamePrefix="react-select"
className="block w-full mt-1 border border-gray-300 rounded-sm shadow-sm react-select-container focus:ring-neutral-800 focus:border-neutral-800 sm:text-sm"
className="react-select-container mt-1 block w-full rounded-sm border border-gray-300 shadow-sm focus:border-neutral-800 focus:ring-neutral-800 sm:text-sm"
/>
</div>
<div>
@ -74,7 +74,7 @@ export default function TeamAvailabilityModal(props: Props) {
]}
isSearchable={false}
classNamePrefix="react-select"
className="flex-1 block w-full min-w-0 border border-gray-300 rounded-sm react-select-container focus:ring-primary-500 focus:border-primary-500 sm:text-sm"
className="react-select-container block w-full min-w-0 flex-1 rounded-sm border border-gray-300 focus:border-primary-500 focus:ring-primary-500 sm:text-sm"
value={{ value: frequency, label: `${frequency} minutes` }}
onChange={(newFrequency) => setFrequency(newFrequency?.value ?? 30)}
/>

View File

@ -35,7 +35,7 @@ export default function TeamAvailabilityScreen(props: Props) {
if (!member) return <></>;
return (
<div key={member.id} style={style} className="flex pl-4 border-r border-gray-200 ">
<div key={member.id} style={style} className="flex border-r border-gray-200 pl-4 ">
<TeamAvailabilityTimes
teamId={props.team?.id as number}
memberId={member.id}
@ -43,15 +43,15 @@ export default function TeamAvailabilityScreen(props: Props) {
selectedDate={selectedDate}
selectedTimeZone={selectedTimeZone}
HeaderComponent={
<div className="flex items-center mb-6">
<div className="mb-6 flex items-center">
<Avatar
imageSrc={getPlaceholderAvatar(member?.avatar, member?.name as string)}
alt={member?.name || ""}
className="w-10 h-10 mt-1 rounded-full min-w-10 min-h-10"
className="mt-1 h-10 min-h-10 w-10 min-w-10 rounded-full"
/>
<div className="inline-block pt-1 ml-3 overflow-hidden">
<span className="text-lg font-bold truncate text-neutral-700">{member?.name}</span>
<span className="block -mt-1 text-sm text-gray-400 truncate">{member?.email}</span>
<div className="ml-3 inline-block overflow-hidden pt-1">
<span className="truncate text-lg font-bold text-neutral-700">{member?.name}</span>
<span className="-mt-1 block truncate text-sm text-gray-400">{member?.email}</span>
</div>
</div>
}
@ -61,8 +61,8 @@ export default function TeamAvailabilityScreen(props: Props) {
};
return (
<div className="flex flex-col flex-1 bg-white border rounded-sm border-neutral-200">
<div className="flex w-full p-4 rtl:space-x-reverse space-x-5 border-b border-gray-200">
<div className="flex flex-1 flex-col rounded-sm border border-neutral-200 bg-white">
<div className="flex w-full space-x-5 border-b border-gray-200 p-4 rtl:space-x-reverse">
<div className="flex flex-col">
<span className="text-sm font-medium text-neutral-700">Date</span>
<DatePicker
@ -80,7 +80,7 @@ export default function TeamAvailabilityScreen(props: Props) {
value={selectedTimeZone}
onChange={(timezone) => setSelectedTimeZone(timezone.value)}
classNamePrefix="react-select"
className="w-full border border-gray-300 rounded-sm shadow-sm react-select-container focus:ring-neutral-800 focus:border-neutral-800 sm:text-sm"
className="react-select-container w-full rounded-sm border border-gray-300 shadow-sm focus:border-neutral-800 focus:ring-neutral-800 sm:text-sm"
/>
</div>
<div className="hidden sm:block">
@ -93,13 +93,13 @@ export default function TeamAvailabilityScreen(props: Props) {
]}
isSearchable={false}
classNamePrefix="react-select"
className="flex-1 block w-full min-w-0 border border-gray-300 rounded-sm react-select-container focus:ring-primary-500 focus:border-primary-500 sm:text-sm"
className="react-select-container block w-full min-w-0 flex-1 rounded-sm border border-gray-300 focus:border-primary-500 focus:ring-primary-500 sm:text-sm"
value={{ value: frequency, label: `${frequency} minutes` }}
onChange={(newFrequency) => setFrequency(newFrequency?.value ?? 30)}
/>
</div>
</div>
<div className="flex flex-1 h-full">
<div className="flex h-full flex-1">
<AutoSizer>
{({ height, width }) => (
<List

View File

@ -48,7 +48,7 @@ export default function TeamAvailabilityTimes(props: Props) {
: [];
return (
<div className={classNames("flex-grow p-5 pl-0 min-w-60", props.className)}>
<div className={classNames("min-w-60 flex-grow p-5 pl-0", props.className)}>
{props.HeaderComponent}
{isLoading && times.length === 0 && <Loader />}
{!isLoading && times.length === 0 && (
@ -59,7 +59,7 @@ export default function TeamAvailabilityTimes(props: Props) {
{times.map((time) => (
<div key={time.format()} className="flex flex-row items-center">
<a
className="flex-grow block py-2 mb-2 mr-3 font-medium text-center bg-white border rounded-sm min-w-48 dark:bg-gray-600 text-primary-500 dark:text-neutral-200 border-brand dark:border-transparent hover:bg-brand hover:text-brandcontrast dark:hover:border-black dark:hover:text-white dark:hover:bg-black"
className="mb-2 mr-3 block min-w-48 flex-grow rounded-sm border border-brand bg-white py-2 text-center font-medium text-primary-500 hover:bg-brand hover:text-brandcontrast dark:border-transparent dark:bg-gray-600 dark:text-neutral-200 dark:hover:border-black dark:hover:bg-black dark:hover:text-white"
data-testid="time">
{time.format("HH:mm")}
</a>

View File

@ -96,7 +96,7 @@ const CryptoSection = (props: CryptoSectionProps) => {
const verifyButton = useMemo(() => {
return (
<Button color="secondary" onClick={verifyWallet} type="button" id="hasToken" name="hasToken">
<img className="h-5 mr-1" src="/integrations/metamask.svg" />
<img className="mr-1 h-5" src="/integrations/metamask.svg" />
{t("verify_wallet")}
</Button>
);
@ -105,7 +105,7 @@ const CryptoSection = (props: CryptoSectionProps) => {
const connectButton = useMemo(() => {
return (
<Button color="secondary" onClick={connectMetamask} type="button">
<img className="h-5 mr-1" src="/integrations/metamask.svg" />
<img className="mr-1 h-5" src="/integrations/metamask.svg" />
{t("connect_metamask")}
</Button>
);
@ -120,7 +120,7 @@ const CryptoSection = (props: CryptoSectionProps) => {
await connectMetamask();
await verifyWallet();
}}>
<img className="h-5 mr-1" src="/integrations/metamask.svg" />
<img className="mr-1 h-5" src="/integrations/metamask.svg" />
{t("verify_wallet")}
</Button>
);
@ -141,7 +141,7 @@ const CryptoSection = (props: CryptoSectionProps) => {
return (
<div
className="absolute transition-opacity transform -translate-x-1/2 -translate-y-1/2 opacity-0 dark:bg-gray-900 top-1/2 left-1/2 group-hover:opacity-100"
className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 transform opacity-0 transition-opacity group-hover:opacity-100 dark:bg-gray-900"
id={`crypto-${props.id}`}>
{determineButton()}
</div>

View File

@ -20,7 +20,7 @@ const HelpMenuItem = () => {
<ChatAltIcon
className={classNames(
"text-neutral-400 group-hover:text-neutral-500",
"ltr:mr-2 flex-shrink-0 h-5 w-5"
"h-5 w-5 flex-shrink-0 ltr:mr-2"
)}
aria-hidden="true"
/>

View File

@ -1,11 +1,11 @@
export class HttpError<TCode extends number = number> extends Error {
public readonly cause: unknown;
public readonly cause?: Error;
public readonly statusCode: TCode;
public readonly message: string;
public readonly url: string | undefined;
public readonly method: string | undefined;
constructor(opts: { url?: string; method?: string; message?: string; statusCode: TCode; cause?: unknown }) {
constructor(opts: { url?: string; method?: string; message?: string; statusCode: TCode; cause?: Error }) {
super(opts.message ?? `HTTP Error ${opts.statusCode} `);
Object.setPrototypeOf(this, HttpError.prototype);

View File

@ -123,14 +123,14 @@ const AddCalDavIntegration = React.forwardRef<HTMLFormElement, Props>((props, re
<label htmlFor="url" className="block text-sm font-medium text-gray-700">
Calendar URL
</label>
<div className="flex mt-1 rounded-md shadow-sm">
<div className="mt-1 flex rounded-md shadow-sm">
<input
required
type="text"
name="url"
id="url"
placeholder="https://example.com/calendar"
className="flex-grow block w-full min-w-0 lowercase border-gray-300 rounded-none rounded-r-sm focus:ring-black focus:border-brand sm:text-sm"
className="block w-full min-w-0 flex-grow rounded-none rounded-r-sm border-gray-300 lowercase focus:border-brand focus:ring-black sm:text-sm"
/>
</div>
</div>
@ -144,7 +144,7 @@ const AddCalDavIntegration = React.forwardRef<HTMLFormElement, Props>((props, re
name="username"
id="username"
placeholder="rickroll"
className="block w-full px-3 py-2 mt-1 border border-gray-300 rounded-sm shadow-sm focus:outline-none focus:ring-neutral-500 focus:border-neutral-500 sm:text-sm"
className="mt-1 block w-full rounded-sm border border-gray-300 px-3 py-2 shadow-sm focus:border-neutral-500 focus:outline-none focus:ring-neutral-500 sm:text-sm"
/>
</div>
<div className="mb-2">
@ -157,7 +157,7 @@ const AddCalDavIntegration = React.forwardRef<HTMLFormElement, Props>((props, re
name="password"
id="password"
placeholder="•••••••••••••"
className="block w-full px-3 py-2 mt-1 border border-gray-300 rounded-sm shadow-sm focus:outline-none focus:ring-neutral-500 focus:border-neutral-500 sm:text-sm"
className="mt-1 block w-full rounded-sm border border-gray-300 px-3 py-2 shadow-sm focus:border-neutral-500 focus:outline-none focus:ring-neutral-500 sm:text-sm"
/>
</div>
</form>

View File

@ -152,6 +152,7 @@
"npm-run-all": "^4.1.5",
"postcss": "^8.4.4",
"prettier": "^2.3.2",
"prettier-plugin-tailwindcss": "^0.1.6",
"prisma": "3.0.2",
"tailwindcss": "^3.0.0",
"ts-jest": "^26.0.0",

View File

@ -43,36 +43,36 @@ export default function Custom404() {
noindex: true,
}}
/>
<div className="min-h-screen px-4 bg-white">
<main className="max-w-xl pt-16 pb-6 mx-auto sm:pt-24">
<div className="min-h-screen bg-white px-4">
<main className="mx-auto max-w-xl pt-16 pb-6 sm:pt-24">
{isSignup && process.env.NEXT_PUBLIC_BASE_URL !== "https://app.cal.com" ? (
<div>
<div>
<p className="text-sm font-semibold tracking-wide text-black uppercase">
<p className="text-sm font-semibold uppercase tracking-wide text-black">
{t("missing_license")}
</p>
<h1 className="mt-2 text-3xl font-extrabold text-gray-900 font-cal">
<h1 className="mt-2 font-cal text-3xl font-extrabold text-gray-900">
{t("signup_requires")}
</h1>
<p className="mt-4">{t("signup_requires_description")}</p>
</div>
<div className="mt-12">
<h2 className="text-sm font-semibold tracking-wide text-gray-500 uppercase">
<h2 className="text-sm font-semibold uppercase tracking-wide text-gray-500">
{t("next_steps")}
</h2>
<ul role="list" className="mt-4">
<li className="px-4 py-2 border-2 border-green-500">
<li className="border-2 border-green-500 px-4 py-2">
<a
href="https://cal.com/pricing?infra"
className="relative flex items-start py-6 space-x-4 rtl:space-x-reverse">
className="relative flex items-start space-x-4 py-6 rtl:space-x-reverse">
<div className="flex-shrink-0">
<span className="flex items-center justify-center w-12 h-12 rounded-lg bg-green-50">
<CheckIcon className="w-6 h-6 text-green-500" aria-hidden="true" />
<span className="flex h-12 w-12 items-center justify-center rounded-lg bg-green-50">
<CheckIcon className="h-6 w-6 text-green-500" aria-hidden="true" />
</span>
</div>
<div className="flex-1 min-w-0">
<div className="min-w-0 flex-1">
<h3 className="text-base font-medium text-gray-900">
<span className="rounded-sm focus-within:ring-2 focus-within:ring-offset-2 focus-within:ring-gray-500">
<span className="rounded-sm focus-within:ring-2 focus-within:ring-gray-500 focus-within:ring-offset-2">
<span className="focus:outline-none">
<span className="absolute inset-0" aria-hidden="true" />
{t("acquire_commercial_license")}
@ -81,33 +81,33 @@ export default function Custom404() {
</h3>
<p className="text-base text-gray-500">{t("the_infrastructure_plan")}</p>
</div>
<div className="self-center flex-shrink-0">
<ChevronRightIcon className="w-5 h-5 text-gray-400" aria-hidden="true" />
<div className="flex-shrink-0 self-center">
<ChevronRightIcon className="h-5 w-5 text-gray-400" aria-hidden="true" />
</div>
</a>
</li>
</ul>
<ul role="list" className="border-gray-200 divide-y divide-gray-200">
<ul role="list" className="divide-y divide-gray-200 border-gray-200">
<li className="px-4 py-2">
<Link href="https://docs.cal.com/self-hosting/install#setting-up-your-first-user">
<a className="relative flex items-start py-6 space-x-4 rtl:space-x-reverse">
<a className="relative flex items-start space-x-4 py-6 rtl:space-x-reverse">
<div className="flex-shrink-0">
<span className="flex items-center justify-center w-12 h-12 rounded-lg bg-gray-50">
<DocumentTextIcon className="w-6 h-6 text-gray-700" aria-hidden="true" />
<span className="flex h-12 w-12 items-center justify-center rounded-lg bg-gray-50">
<DocumentTextIcon className="h-6 w-6 text-gray-700" aria-hidden="true" />
</span>
</div>
<div className="flex-1 min-w-0">
<div className="min-w-0 flex-1">
<h3 className="text-base font-medium text-gray-900">
<span className="rounded-sm focus-within:ring-2 focus-within:ring-offset-2 focus-within:ring-gray-500">
<span className="rounded-sm focus-within:ring-2 focus-within:ring-gray-500 focus-within:ring-offset-2">
<span className="absolute inset-0" aria-hidden="true" />
{t("prisma_studio_tip")}
</span>
</h3>
<p className="text-base text-gray-500">{t("prisma_studio_tip_description")}</p>
</div>
<div className="self-center flex-shrink-0">
<ChevronRightIcon className="w-5 h-5 text-gray-400" aria-hidden="true" />
<div className="flex-shrink-0 self-center">
<ChevronRightIcon className="h-5 w-5 text-gray-400" aria-hidden="true" />
</div>
</a>
</Link>
@ -115,12 +115,12 @@ export default function Custom404() {
<li className="px-4 py-2">
<a
href="https://cal.com/slack"
className="relative flex items-start py-6 space-x-4 rtl:space-x-reverse">
className="relative flex items-start space-x-4 py-6 rtl:space-x-reverse">
<div className="flex-shrink-0">
<span className="flex items-center justify-center w-12 h-12 rounded-lg bg-gray-50">
<span className="flex h-12 w-12 items-center justify-center rounded-lg bg-gray-50">
<svg
viewBox="0 0 2447.6 2452.5"
className="w-6 h-6"
className="h-6 w-6"
xmlns="http://www.w3.org/2000/svg">
<g clipRule="evenodd" fillRule="evenodd">
<path
@ -139,17 +139,17 @@ export default function Custom404() {
</svg>
</span>
</div>
<div className="flex-1 min-w-0">
<div className="min-w-0 flex-1">
<h3 className="text-base font-medium text-gray-900">
<span className="rounded-sm focus-within:ring-2 focus-within:ring-offset-2 focus-within:ring-gray-500">
<span className="rounded-sm focus-within:ring-2 focus-within:ring-gray-500 focus-within:ring-offset-2">
<span className="absolute inset-0" aria-hidden="true" />
Slack
</span>
</h3>
<p className="text-base text-gray-500">{t("join_our_community")}</p>
</div>
<div className="self-center flex-shrink-0">
<ChevronRightIcon className="w-5 h-5 text-gray-400" aria-hidden="true" />
<div className="flex-shrink-0 self-center">
<ChevronRightIcon className="h-5 w-5 text-gray-400" aria-hidden="true" />
</div>
</a>
</li>
@ -167,18 +167,18 @@ export default function Custom404() {
) : (
<>
<div className="text-center">
<p className="text-sm font-semibold tracking-wide text-black uppercase">{t("error_404")}</p>
<h1 className="mt-2 text-4xl font-extrabold text-gray-900 font-cal sm:text-5xl">
<p className="text-sm font-semibold uppercase tracking-wide text-black">{t("error_404")}</p>
<h1 className="mt-2 font-cal text-4xl font-extrabold text-gray-900 sm:text-5xl">
{t("page_doesnt_exist")}
</h1>
{isSubpage ? (
<span className="inline-block mt-2 text-lg ">
<span className="mt-2 inline-block text-lg ">
{t("check_spelling_mistakes_or_go_back")}
</span>
) : process.env.NEXT_PUBLIC_BASE_URL === "https://app.cal.com" ? (
<a
href={"https://cal.com/signup?username=" + username.replace("/", "")}
className="inline-block mt-2 text-lg ">
className="mt-2 inline-block text-lg ">
{t("the_username")} <strong className="text-blue-500">cal.com{username}</strong>{" "}
{t("is_still_available")} <span className="text-blue-500">{t("register_now")}</span>.
</a>
@ -194,23 +194,23 @@ export default function Custom404() {
)}
</div>
<div className="mt-12">
<h2 className="text-sm font-semibold tracking-wide text-gray-500 uppercase">
<h2 className="text-sm font-semibold uppercase tracking-wide text-gray-500">
{t("popular_pages")}
</h2>
{!isSubpage && process.env.NEXT_PUBLIC_BASE_URL === "https://app.cal.com" && (
<ul role="list" className="mt-4">
<li className="px-4 py-2 border-2 border-green-500">
<li className="border-2 border-green-500 px-4 py-2">
<a
href={"https://cal.com/signup?username=" + username.replace("/", "")}
className="relative flex items-start py-6 space-x-4 rtl:space-x-reverse">
className="relative flex items-start space-x-4 py-6 rtl:space-x-reverse">
<div className="flex-shrink-0">
<span className="flex items-center justify-center w-12 h-12 rounded-lg bg-green-50">
<CheckIcon className="w-6 h-6 text-green-500" aria-hidden="true" />
<span className="flex h-12 w-12 items-center justify-center rounded-lg bg-green-50">
<CheckIcon className="h-6 w-6 text-green-500" aria-hidden="true" />
</span>
</div>
<div className="flex-1 min-w-0">
<div className="min-w-0 flex-1">
<h3 className="text-base font-medium text-gray-900">
<span className="rounded-sm focus-within:ring-2 focus-within:ring-offset-2 focus-within:ring-gray-500">
<span className="rounded-sm focus-within:ring-2 focus-within:ring-gray-500 focus-within:ring-offset-2">
<span className="focus:outline-none">
<span className="absolute inset-0" aria-hidden="true" />
{t("register")} <strong className="text-green-500">{username}</strong>
@ -219,35 +219,35 @@ export default function Custom404() {
</h3>
<p className="text-base text-gray-500">{t("claim_username_and_schedule_events")}</p>
</div>
<div className="self-center flex-shrink-0">
<ChevronRightIcon className="w-5 h-5 text-gray-400" aria-hidden="true" />
<div className="flex-shrink-0 self-center">
<ChevronRightIcon className="h-5 w-5 text-gray-400" aria-hidden="true" />
</div>
</a>
</li>
</ul>
)}
<ul role="list" className="mt-4 border-gray-200 divide-y divide-gray-200">
<ul role="list" className="mt-4 divide-y divide-gray-200 border-gray-200">
{links.map((link, linkIdx) => (
<li key={linkIdx} className="px-4 py-2">
<Link href={link.href}>
<a className="relative flex items-start py-6 space-x-4 rtl:space-x-reverse">
<a className="relative flex items-start space-x-4 py-6 rtl:space-x-reverse">
<div className="flex-shrink-0">
<span className="flex items-center justify-center w-12 h-12 rounded-lg bg-gray-50">
<link.icon className="w-6 h-6 text-gray-700" aria-hidden="true" />
<span className="flex h-12 w-12 items-center justify-center rounded-lg bg-gray-50">
<link.icon className="h-6 w-6 text-gray-700" aria-hidden="true" />
</span>
</div>
<div className="flex-1 min-w-0">
<div className="min-w-0 flex-1">
<h3 className="text-base font-medium text-gray-900">
<span className="rounded-sm focus-within:ring-2 focus-within:ring-offset-2 focus-within:ring-gray-500">
<span className="rounded-sm focus-within:ring-2 focus-within:ring-gray-500 focus-within:ring-offset-2">
<span className="absolute inset-0" aria-hidden="true" />
{link.title}
</span>
</h3>
<p className="text-base text-gray-500">{link.description}</p>
</div>
<div className="self-center flex-shrink-0">
<ChevronRightIcon className="w-5 h-5 text-gray-400" aria-hidden="true" />
<div className="flex-shrink-0 self-center">
<ChevronRightIcon className="h-5 w-5 text-gray-400" aria-hidden="true" />
</div>
</a>
</Link>
@ -256,12 +256,12 @@ export default function Custom404() {
<li className="px-4 py-2">
<a
href="https://cal.com/slack"
className="relative flex items-start py-6 space-x-4 rtl:space-x-reverse">
className="relative flex items-start space-x-4 py-6 rtl:space-x-reverse">
<div className="flex-shrink-0">
<span className="flex items-center justify-center w-12 h-12 rounded-lg bg-gray-50">
<span className="flex h-12 w-12 items-center justify-center rounded-lg bg-gray-50">
<svg
viewBox="0 0 2447.6 2452.5"
className="w-6 h-6"
className="h-6 w-6"
xmlns="http://www.w3.org/2000/svg">
<g clipRule="evenodd" fillRule="evenodd">
<path
@ -280,17 +280,17 @@ export default function Custom404() {
</svg>
</span>
</div>
<div className="flex-1 min-w-0">
<div className="min-w-0 flex-1">
<h3 className="text-base font-medium text-gray-900">
<span className="rounded-sm focus-within:ring-2 focus-within:ring-offset-2 focus-within:ring-gray-500">
<span className="rounded-sm focus-within:ring-2 focus-within:ring-gray-500 focus-within:ring-offset-2">
<span className="absolute inset-0" aria-hidden="true" />
Slack
</span>
</h3>
<p className="text-base text-gray-500">{t("join_our_community")}</p>
</div>
<div className="self-center flex-shrink-0">
<ChevronRightIcon className="w-5 h-5 text-gray-400" aria-hidden="true" />
<div className="flex-shrink-0 self-center">
<ChevronRightIcon className="h-5 w-5 text-gray-400" aria-hidden="true" />
</div>
</a>
</li>

View File

@ -47,17 +47,17 @@ export default function User(props: inferSSRProps<typeof getServerSideProps>) {
/>
{isReady && (
<div className="h-screen dark:bg-black">
<main className="max-w-3xl px-4 py-24 mx-auto">
<main className="mx-auto max-w-3xl px-4 py-24">
<div className="mb-8 text-center">
<Avatar
imageSrc={user.avatar}
className="w-24 h-24 mx-auto mb-4 rounded-full"
className="mx-auto mb-4 h-24 w-24 rounded-full"
alt={nameOrUsername}
/>
<h1 className="mb-1 text-3xl font-bold font-cal text-neutral-900 dark:text-white">
<h1 className="mb-1 font-cal text-3xl font-bold text-neutral-900 dark:text-white">
{nameOrUsername}
{user.verified && (
<BadgeCheckIcon className="inline w-6 h-6 -mt-1 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>
@ -68,8 +68,8 @@ export default function User(props: inferSSRProps<typeof getServerSideProps>) {
<div
key={type.id}
style={{ display: "flex" }}
className="relative bg-white border rounded-sm group dark:bg-neutral-900 dark:border-0 dark:hover:border-neutral-600 hover:bg-gray-50 border-neutral-200 hover:border-brand">
<ArrowRightIcon className="absolute w-4 h-4 text-black transition-opacity opacity-0 right-3 top-3 dark:text-white group-hover:opacity-100" />
className="group relative rounded-sm border border-neutral-200 bg-white hover:border-brand hover:bg-gray-50 dark:border-0 dark:bg-neutral-900 dark:hover:border-neutral-600">
<ArrowRightIcon className="absolute right-3 top-3 h-4 w-4 text-black opacity-0 transition-opacity group-hover:opacity-100 dark:text-white" />
<Link
href={{
pathname: `/${user.username}/${type.slug}`,
@ -88,7 +88,7 @@ export default function User(props: inferSSRProps<typeof getServerSideProps>) {
}}
className="block w-full px-6 py-4"
data-testid="event-type-link">
<h2 className="font-semibold grow text-neutral-900 dark:text-white">{type.title}</h2>
<h2 className="grow font-semibold text-neutral-900 dark:text-white">{type.title}</h2>
<EventTypeDescription eventType={type} />
</a>
</Link>
@ -108,10 +108,10 @@ export default function User(props: inferSSRProps<typeof getServerSideProps>) {
{eventTypes.length === 0 && (
<div className="overflow-hidden rounded-sm shadow">
<div className="p-8 text-center text-gray-400 dark:text-white">
<h2 className="text-3xl font-semibold text-gray-600 font-cal dark:text-white">
<h2 className="font-cal text-3xl font-semibold text-gray-600 dark:text-white">
{t("uh_oh")}
</h2>
<p className="max-w-md mx-auto">{t("no_event_types_have_been_setup")}</p>
<p className="mx-auto max-w-md">{t("no_event_types_have_been_setup")}</p>
</div>
</div>
)}

View File

@ -18,11 +18,11 @@ export default function Error() {
return (
<AuthContainer title="" description="">
<div>
<div className="mx-auto flex items-center justify-center h-12 w-12 rounded-full bg-red-100">
<div className="mx-auto flex h-12 w-12 items-center justify-center rounded-full bg-red-100">
<XIcon className="h-6 w-6 text-red-600" />
</div>
<div className="mt-3 text-center sm:mt-5">
<h3 className="text-lg leading-6 font-medium text-gray-900" id="modal-title">
<h3 className="text-lg font-medium leading-6 text-gray-900" id="modal-title">
{error}
</h3>
<div className="mt-2">
@ -32,7 +32,7 @@ export default function Error() {
</div>
<div className="mt-5 sm:mt-6">
<Link href="/auth/login">
<Button className="w-full flex justify-center">{t("go_back_login")}</Button>
<Button className="flex w-full justify-center">{t("go_back_login")}</Button>
</Link>
</div>
</AuthContainer>

View File

@ -58,7 +58,7 @@ export default function Page({ resetPasswordRequest, csrfToken }: Props) {
<>
<div className="space-y-6">
<div>
<h2 className="mt-6 text-3xl font-extrabold text-center text-gray-900 font-cal">
<h2 className="mt-6 text-center font-cal text-3xl font-extrabold text-gray-900">
{t("success")}
</h2>
</div>
@ -66,7 +66,7 @@ export default function Page({ resetPasswordRequest, csrfToken }: Props) {
<Link href="/auth/login">
<button
type="button"
className="flex justify-center w-full px-4 py-2 text-sm font-medium text-blue-600 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-black">
className="flex w-full justify-center px-4 py-2 text-sm font-medium text-blue-600 focus:outline-none focus:ring-2 focus:ring-black focus:ring-offset-2">
{t("login")}
</button>
</Link>
@ -80,14 +80,14 @@ export default function Page({ resetPasswordRequest, csrfToken }: Props) {
<>
<div className="space-y-6">
<div>
<h2 className="mt-6 text-3xl font-extrabold text-center text-gray-900 font-cal">{t("whoops")}</h2>
<h2 className="text-3xl font-extrabold text-center text-gray-900">{t("request_is_expired")}</h2>
<h2 className="mt-6 text-center font-cal text-3xl font-extrabold text-gray-900">{t("whoops")}</h2>
<h2 className="text-center text-3xl font-extrabold text-gray-900">{t("request_is_expired")}</h2>
</div>
<p>{t("request_is_expired_instructions")}</p>
<Link href="/auth/forgot-password">
<button
type="button"
className="flex justify-center w-full px-4 py-2 text-sm font-medium text-blue-600 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-black">
className="flex w-full justify-center px-4 py-2 text-sm font-medium text-blue-600 focus:outline-none focus:ring-2 focus:ring-black focus:ring-offset-2">
{t("try_again")}
</button>
</Link>
@ -102,15 +102,15 @@ export default function Page({ resetPasswordRequest, csrfToken }: Props) {
}, [resetPasswordRequest]);
return (
<div className="flex flex-col justify-center min-h-screen py-12 bg-gray-50 sm:px-6 lg:px-8">
<div className="flex min-h-screen flex-col justify-center bg-gray-50 py-12 sm:px-6 lg:px-8">
<HeadSeo title={t("reset_password")} description={t("change_your_password")} />
<div className="mt-8 sm:mx-auto sm:w-full sm:max-w-md">
<div className="px-4 py-8 mx-2 space-y-6 bg-white rounded-lg shadow sm:px-10">
<div className="mx-2 space-y-6 rounded-lg bg-white px-4 py-8 shadow sm:px-10">
{isRequestExpired && <Expired />}
{!isRequestExpired && !success && (
<>
<div className="space-y-6">
<h2 className="mt-6 text-3xl font-extrabold text-center text-gray-900 font-cal">
<h2 className="mt-6 text-center font-cal text-3xl font-extrabold text-gray-900">
{t("reset_password")}
</h2>
<p>{t("enter_new_password")}</p>
@ -151,7 +151,7 @@ export default function Page({ resetPasswordRequest, csrfToken }: Props) {
type="password"
autoComplete="password"
required
className="block w-full px-3 py-2 placeholder-gray-400 border border-gray-300 rounded-md shadow-sm appearance-none focus:outline-none focus:ring-black focus:border-brand sm:text-sm"
className="block w-full appearance-none rounded-md border border-gray-300 px-3 py-2 placeholder-gray-400 shadow-sm focus:border-brand focus:outline-none focus:ring-black sm:text-sm"
/>
</div>
</div>
@ -160,12 +160,12 @@ export default function Page({ resetPasswordRequest, csrfToken }: Props) {
<button
type="submit"
disabled={loading}
className={`w-full flex justify-center py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-black ${
className={`flex w-full justify-center rounded-md border border-transparent bg-blue-600 py-2 px-4 text-sm font-medium text-white shadow-sm hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-black focus:ring-offset-2 ${
loading ? "cursor-not-allowed" : ""
}`}>
{loading && (
<svg
className="w-5 h-5 mr-3 -ml-1 text-white animate-spin"
className="mr-3 -ml-1 h-5 w-5 animate-spin text-white"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24">

View File

@ -111,7 +111,7 @@ export default function ForgotPassword({ csrfToken }: { csrfToken: string }) {
/>
<div className="space-y-2">
<Button
className="justify-center w-full"
className="w-full justify-center"
type="submit"
disabled={loading}
aria-label={t("request_password_reset")}

View File

@ -139,7 +139,7 @@ export default function Login({
{errorMessage && <Alert severity="error" title={errorMessage} />}
<div className="flex space-y-2">
<Button
className="flex justify-center w-full"
className="flex w-full justify-center"
type="submit"
disabled={form.formState.isSubmitting}>
{twoFactorRequired ? t("submit") : t("sign_in")}
@ -153,7 +153,7 @@ export default function Login({
<div className="mt-5">
<Button
color="secondary"
className="flex justify-center w-full"
className="flex w-full justify-center"
data-testid={"google"}
onClick={async (e) => {
e.preventDefault();

View File

@ -26,8 +26,8 @@ export default function Logout(props: Props) {
return (
<AuthContainer title={t("logged_out")} description={t("youve_been_logged_out")}>
<div className="mb-4">
<div className="flex items-center justify-center w-12 h-12 mx-auto bg-green-100 rounded-full">
<CheckIcon className="w-6 h-6 text-green-600" />
<div className="mx-auto flex h-12 w-12 items-center justify-center rounded-full bg-green-100">
<CheckIcon className="h-6 w-6 text-green-600" />
</div>
<div className="mt-3 text-center sm:mt-5">
<h3 className="text-lg font-medium leading-6 text-gray-900" id="modal-title">
@ -39,7 +39,7 @@ export default function Logout(props: Props) {
</div>
</div>
<Link href="/auth/login">
<Button className="flex justify-center w-full"> {t("go_back_login")}</Button>
<Button className="flex w-full justify-center"> {t("go_back_login")}</Button>
</Link>
</AuthContainer>
);

View File

@ -64,18 +64,18 @@ export default function Signup({ email }: Props) {
return (
<div
className="flex flex-col justify-center min-h-screen py-12 bg-gray-50 sm:px-6 lg:px-8"
className="flex min-h-screen flex-col justify-center bg-gray-50 py-12 sm:px-6 lg:px-8"
aria-labelledby="modal-title"
role="dialog"
aria-modal="true">
<HeadSeo title={t("sign_up")} description={t("sign_up")} />
<div className="sm:mx-auto sm:w-full sm:max-w-md">
<h2 className="text-3xl font-extrabold text-center text-gray-900 font-cal">
<h2 className="text-center font-cal text-3xl font-extrabold text-gray-900">
{t("create_your_account")}
</h2>
</div>
<div className="mt-8 sm:mx-auto sm:w-full sm:max-w-md">
<div className="px-4 py-8 mx-2 bg-white shadow sm:rounded-lg sm:px-10">
<div className="mx-2 bg-white px-4 py-8 shadow sm:rounded-lg sm:px-10">
{/* TODO: Refactor as soon as /availability is live */}
<FormProvider {...methods}>
<form onSubmit={methods.handleSubmit(signUp)} className="space-y-6 bg-white">
@ -83,25 +83,25 @@ export default function Signup({ email }: Props) {
<div className="space-y-2">
<TextField
addOnLeading={
<span className="inline-flex items-center px-3 text-gray-500 border border-r-0 border-gray-300 rounded-l-sm bg-gray-50 sm:text-sm">
<span className="inline-flex items-center rounded-l-sm border border-r-0 border-gray-300 bg-gray-50 px-3 text-gray-500 sm:text-sm">
{process.env.NEXT_PUBLIC_APP_URL}/
</span>
}
labelProps={{ className: "block text-sm font-medium text-gray-700" }}
className="flex-grow block w-full min-w-0 lowercase border-gray-300 rounded-none rounded-r-sm focus:ring-black focus:border-black sm:text-sm"
className="block w-full min-w-0 flex-grow rounded-none rounded-r-sm border-gray-300 lowercase focus:border-black focus:ring-black sm:text-sm"
{...register("username")}
required
/>
<EmailField
{...register("email")}
className="block w-full px-3 py-2 mt-1 bg-gray-100 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-black focus:border-black sm:text-sm"
className="mt-1 block w-full rounded-md border border-gray-300 bg-gray-100 px-3 py-2 shadow-sm focus:border-black focus:outline-none focus:ring-black sm:text-sm"
/>
<PasswordField
labelProps={{
className: "block text-sm font-medium text-gray-700",
}}
{...register("password")}
className="block w-full px-3 py-2 mt-1 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-black focus:border-black sm:text-sm"
className="mt-1 block w-full rounded-md border border-gray-300 px-3 py-2 shadow-sm focus:border-black focus:outline-none focus:ring-black sm:text-sm"
/>
<PasswordField
label={t("confirm_password")}
@ -112,16 +112,16 @@ export default function Signup({ email }: Props) {
validate: (value) =>
value === methods.watch("password") || (t("error_password_mismatch") as string),
})}
className="block w-full px-3 py-2 mt-1 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-black focus:border-black sm:text-sm"
className="mt-1 block w-full rounded-md border border-gray-300 px-3 py-2 shadow-sm focus:border-black focus:outline-none focus:ring-black sm:text-sm"
/>
</div>
<div className="flex rtl:space-x-reverse space-x-2">
<Button loading={isSubmitting} className="justify-center w-7/12">
<div className="flex space-x-2 rtl:space-x-reverse">
<Button loading={isSubmitting} className="w-7/12 justify-center">
{t("create_account")}
</Button>
<Button
color="secondary"
className="justify-center w-5/12"
className="w-5/12 justify-center"
onClick={() =>
signIn("Cal.com", { callbackUrl: (router.query.callbackUrl || "") as string })
}>

View File

@ -90,7 +90,7 @@ export function AvailabilityForm(props: inferQueryOutput<"viewer.availability">)
await createSchedule(values);
}}
className="col-span-3 space-y-2 lg:col-span-2">
<div className="px-4 py-5 bg-white border border-gray-200 divide-y rounded-sm sm:p-6">
<div className="divide-y rounded-sm border border-gray-200 bg-white px-4 py-5 sm:p-6">
<h3 className="mb-5 text-base font-medium leading-6 text-gray-900">{t("change_start_end")}</h3>
<Schedule name="schedule" />
</div>
@ -107,12 +107,12 @@ export function AvailabilityForm(props: inferQueryOutput<"viewer.availability">)
<Button>{t("save")}</Button>
</div>
</Form>
<div className="col-span-3 ltr:ml-2 rtl:mr-2 lg:col-span-1 min-w-40">
<div className="px-4 py-5 border border-gray-200 rounded-sm sm:p-6 ">
<div className="col-span-3 min-w-40 ltr:ml-2 rtl:mr-2 lg:col-span-1">
<div className="rounded-sm border border-gray-200 px-4 py-5 sm:p-6 ">
<h3 className="text-base font-medium leading-6 text-gray-900">
{t("something_doesnt_look_right")}
</h3>
<div className="max-w-xl mt-2 text-sm text-gray-500">
<div className="mt-2 max-w-xl text-sm text-gray-500">
<p>{t("troubleshoot_availability")}</p>
</div>
<div className="mt-5">

View File

@ -16,14 +16,14 @@ type User = inferQueryOutput<"viewer.me">;
const AvailabilityView = ({ user }: { user: User }) => {
const { t } = useLocale();
const [loading, setLoading] = useState(true);
const [availability, setAvailability] = useState([]);
const [availability, setAvailability] = useState<{ end: string; start: string }[]>([]);
const [selectedDate, setSelectedDate] = useState(dayjs());
function convertMinsToHrsMins(mins: number) {
let h = Math.floor(mins / 60);
let m = mins % 60;
h = h < 10 ? "0" + h : h;
m = m < 10 ? "0" + m : m;
h = h < 10 ? 0 + h : h;
m = m < 10 ? 0 + m : m;
return `${h}:${m}`;
}
@ -51,12 +51,12 @@ const AvailabilityView = ({ user }: { user: User }) => {
}, [selectedDate]);
return (
<div className="max-w-xl overflow-hidden bg-white rounded-sm shadow">
<div className="max-w-xl overflow-hidden rounded-sm bg-white shadow">
<div className="px-4 py-5 sm:p-6">
{t("overview_of_day")}{" "}
<input
type="date"
className="inline h-8 p-0 border-none"
className="inline h-8 border-none p-0"
defaultValue={selectedDate.format("YYYY-MM-DD")}
onChange={(e) => {
setSelectedDate(dayjs(e.target.value));
@ -65,7 +65,7 @@ const AvailabilityView = ({ user }: { user: User }) => {
<small className="block text-neutral-400">{t("hover_over_bold_times_tip")}</small>
<div className="mt-4 space-y-4">
<div className="overflow-hidden rounded-sm bg-brand">
<div className="px-4 py-2 sm:px-6 text-brandcontrast">
<div className="px-4 py-2 text-brandcontrast sm:px-6">
{t("your_day_starts_at")} {convertMinsToHrsMins(user.startTime)}
</div>
</div>
@ -95,7 +95,7 @@ const AvailabilityView = ({ user }: { user: User }) => {
)}
<div className="overflow-hidden rounded-sm bg-brand">
<div className="px-4 py-2 sm:px-6 text-brandcontrast">
<div className="px-4 py-2 text-brandcontrast sm:px-6">
{t("your_day_ends_at")} {convertMinsToHrsMins(user.endTime)}
</div>
</div>

View File

@ -45,7 +45,7 @@ export default function Bookings() {
return (
<Shell heading={t("bookings")} subtitle={t("bookings_description")}>
<BookingsShell>
<div className="flex flex-col -mx-4 sm:mx-auto">
<div className="-mx-4 flex flex-col sm:mx-auto">
<div className="-my-2 overflow-x-auto sm:-mx-6 lg:-mx-8">
<div className="inline-block min-w-full py-2 align-middle sm:px-6 lg:px-8">
{query.status === "error" && (
@ -54,9 +54,9 @@ export default function Bookings() {
{(query.status === "loading" || query.status === "idle") && <Loader />}
{query.status === "success" && !isEmpty && (
<>
<div className="mt-6 overflow-hidden border border-b border-gray-200 rounded-sm">
<div className="mt-6 overflow-hidden rounded-sm border border-b border-gray-200">
<table className="min-w-full divide-y divide-gray-200">
<tbody className="bg-white divide-y divide-gray-200" data-testid="bookings">
<tbody className="divide-y divide-gray-200 bg-white" data-testid="bookings">
{query.data.pages.map((page, index) => (
<Fragment key={index}>
{page.bookings.map((booking) => (
@ -67,7 +67,7 @@ export default function Bookings() {
</tbody>
</table>
</div>
<div className="text-center p-4" ref={buttonInView.ref}>
<div className="p-4 text-center" ref={buttonInView.ref}>
<Button
loading={query.isFetchingNextPage}
disabled={!query.hasNextPage}

Some files were not shown because too many files have changed in this diff Show More