patch applied
|
@ -0,0 +1,229 @@
|
||||||
|
import {
|
||||||
|
BookOpenIcon,
|
||||||
|
DocumentTextIcon,
|
||||||
|
ExternalLinkIcon,
|
||||||
|
FlagIcon,
|
||||||
|
MailIcon,
|
||||||
|
ShieldCheckIcon,
|
||||||
|
} from "@heroicons/react/outline";
|
||||||
|
import { ChevronLeftIcon } from "@heroicons/react/solid";
|
||||||
|
import Link from "next/link";
|
||||||
|
import React from "react";
|
||||||
|
|
||||||
|
import { useLocale } from "@lib/hooks/useLocale";
|
||||||
|
|
||||||
|
//import NavTabs from "@components/NavTabs";
|
||||||
|
import Shell from "@components/Shell";
|
||||||
|
import Badge from "@components/ui/Badge";
|
||||||
|
import Button from "@components/ui/Button";
|
||||||
|
|
||||||
|
export default function App({
|
||||||
|
name,
|
||||||
|
logo,
|
||||||
|
body,
|
||||||
|
categories,
|
||||||
|
author,
|
||||||
|
price,
|
||||||
|
commission,
|
||||||
|
type,
|
||||||
|
docs,
|
||||||
|
website,
|
||||||
|
email,
|
||||||
|
tos,
|
||||||
|
privacy,
|
||||||
|
}: {
|
||||||
|
name: string;
|
||||||
|
logo: string;
|
||||||
|
body: React.ReactNode;
|
||||||
|
categories: string[];
|
||||||
|
author: string;
|
||||||
|
pro?: boolean;
|
||||||
|
price: number;
|
||||||
|
commission?: number;
|
||||||
|
type?: "monthly" | "usage-based" | "one-time" | "free";
|
||||||
|
docs?: string;
|
||||||
|
website?: string;
|
||||||
|
email: string; // required
|
||||||
|
tos?: string;
|
||||||
|
privacy?: string;
|
||||||
|
}) {
|
||||||
|
const { t } = useLocale();
|
||||||
|
|
||||||
|
/*const tabs = [
|
||||||
|
{
|
||||||
|
name: t("description"),
|
||||||
|
href: "?description",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: t("features"),
|
||||||
|
href: "?features",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: t("permissions"),
|
||||||
|
href: "?permissions",
|
||||||
|
},
|
||||||
|
];*/
|
||||||
|
|
||||||
|
const priceInDollar = Intl.NumberFormat("en-US", {
|
||||||
|
style: "currency",
|
||||||
|
currency: "USD",
|
||||||
|
useGrouping: false,
|
||||||
|
}).format(price);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Shell large>
|
||||||
|
<div className="-mx-8">
|
||||||
|
<div className="px-10 bg-gray-50">
|
||||||
|
<Link href="/apps">
|
||||||
|
<a className="inline-flex px-1 py-2 mt-2 text-sm text-gray-500 hover:bg-gray-100 hover:text-gray-800">
|
||||||
|
<ChevronLeftIcon className="w-5 h-5" /> {t("browse_apps")}
|
||||||
|
</a>
|
||||||
|
</Link>
|
||||||
|
<div className="flex items-center justify-between py-8">
|
||||||
|
<div className="flex">
|
||||||
|
<img className="w-16 h-16" src={logo} />
|
||||||
|
<header className="px-4 py-2">
|
||||||
|
<h1 className="text-xl text-gray-900 font-cal">{name}</h1>
|
||||||
|
<h2 className="text-sm text-gray-500">
|
||||||
|
<span className="capitalize">{categories[0]}</span> • {t("build_by", { author })}
|
||||||
|
</h2>
|
||||||
|
</header>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="text-right">
|
||||||
|
{type === "free" && (
|
||||||
|
<Button onClick={() => alert("TODO: installed free app")}>{t("install_app")}</Button>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{type === "usage-based" && (
|
||||||
|
<Button onClick={() => alert("TODO: installed usage based app")}>{t("install_app")}</Button>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{type === "monthly" && (
|
||||||
|
<Button onClick={() => alert("TODO: installed monthly billed app")}>
|
||||||
|
{t("subscribe")}
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{price !== 0 && (
|
||||||
|
<small className="block text-right">
|
||||||
|
{type === "usage-based"
|
||||||
|
? commission + "% + " + priceInDollar + "/booking"
|
||||||
|
: priceInDollar}
|
||||||
|
{type === "monthly" && "/" + t("month")}
|
||||||
|
</small>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/* reintroduce once we show permissions and features
|
||||||
|
<NavTabs tabs={tabs} linkProps={{ shallow: true }} /> */}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="flex justify-between px-10 py-10">
|
||||||
|
<div className="prose-sm prose">{body}</div>
|
||||||
|
<div className="flex-1 max-w-80">
|
||||||
|
<h4 className="font-medium text-gray-900 ">{t("categories")}</h4>
|
||||||
|
<div className="space-x-2">
|
||||||
|
{categories.map((category) => (
|
||||||
|
<Link href={"/apps/categories/" + category} key={category}>
|
||||||
|
<a>
|
||||||
|
<Badge variant="success">{category}</Badge>
|
||||||
|
</a>
|
||||||
|
</Link>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
<h4 className="mt-8 font-medium text-gray-900 ">{t("pricing")}</h4>
|
||||||
|
<small>
|
||||||
|
{price === 0 ? (
|
||||||
|
"Free"
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
{Intl.NumberFormat("en-US", {
|
||||||
|
style: "currency",
|
||||||
|
currency: "USD",
|
||||||
|
useGrouping: false,
|
||||||
|
}).format(price)}
|
||||||
|
{type === "monthly" && "/" + t("month")}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</small>
|
||||||
|
<h4 className="mt-8 mb-2 font-medium text-gray-900 ">{t("learn_more")}</h4>
|
||||||
|
<ul className="-ml-1 -mr-1 text-xs leading-5 prose">
|
||||||
|
{docs && (
|
||||||
|
<li>
|
||||||
|
<a
|
||||||
|
target="_blank"
|
||||||
|
rel="noreferrer"
|
||||||
|
className="text-blue-500 no-underline hover:underline"
|
||||||
|
href={docs}>
|
||||||
|
<BookOpenIcon className="inline w-4 h-4 mr-1 -mt-1" />
|
||||||
|
{t("documentation")}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
)}
|
||||||
|
{website && (
|
||||||
|
<li>
|
||||||
|
<a
|
||||||
|
target="_blank"
|
||||||
|
rel="noreferrer"
|
||||||
|
className="text-blue-500 no-underline hover:underline"
|
||||||
|
href={website}>
|
||||||
|
<ExternalLinkIcon className="inline w-4 h-4 mr-1 -mt-px" />
|
||||||
|
{website.replace("https://", "")}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
)}
|
||||||
|
{email && (
|
||||||
|
<li>
|
||||||
|
<a
|
||||||
|
target="_blank"
|
||||||
|
rel="noreferrer"
|
||||||
|
className="text-blue-500 no-underline hover:underline"
|
||||||
|
href={"mailto:" + email}>
|
||||||
|
<MailIcon className="inline w-4 h-4 mr-1 -mt-px" />
|
||||||
|
{email}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
)}
|
||||||
|
{tos && (
|
||||||
|
<li>
|
||||||
|
<a
|
||||||
|
target="_blank"
|
||||||
|
rel="noreferrer"
|
||||||
|
className="text-blue-500 no-underline hover:underline"
|
||||||
|
href={tos}>
|
||||||
|
<DocumentTextIcon className="inline w-4 h-4 mr-1 -mt-px" />
|
||||||
|
{t("terms_of_service")}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
)}
|
||||||
|
{privacy && (
|
||||||
|
<li>
|
||||||
|
<a
|
||||||
|
target="_blank"
|
||||||
|
rel="noreferrer"
|
||||||
|
className="text-blue-500 no-underline hover:underline"
|
||||||
|
href={privacy}>
|
||||||
|
<ShieldCheckIcon className="inline w-4 h-4 mr-1 -mt-px" />
|
||||||
|
{t("privacy_policy")}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
)}
|
||||||
|
</ul>
|
||||||
|
<hr className="my-6" />
|
||||||
|
<small className="block text-gray-500 leading-1">
|
||||||
|
Every app published on the Cal.com App Store is open source and thoroughly tested via peer
|
||||||
|
reviews. Nevertheless, Cal.com, Inc. does not endorse or certify these apps unless they are
|
||||||
|
published by Cal.com. If you encounter inappropriate content or behaviour please report it.
|
||||||
|
</small>
|
||||||
|
<a className="block mt-2 text-xs text-red-500" href="mailto:help@cal.com">
|
||||||
|
<FlagIcon className="inline w-3 h-3" /> Report App
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Shell>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
import { useSession } from "next-auth/react";
|
||||||
|
import React from "react";
|
||||||
|
|
||||||
|
import { useLocale } from "@lib/hooks/useLocale";
|
||||||
|
|
||||||
|
import NavTabs from "./NavTabs";
|
||||||
|
|
||||||
|
export default function AppsShell({ children }: { children: React.ReactNode }) {
|
||||||
|
const { t } = useLocale();
|
||||||
|
const { status } = useSession();
|
||||||
|
const tabs = [
|
||||||
|
{
|
||||||
|
name: t("app_store"),
|
||||||
|
href: "/apps",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: t("installed_apps"),
|
||||||
|
href: "/apps/installed",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div className="block mb-12 lg:hidden">
|
||||||
|
{status === "authenticated" && <NavTabs tabs={tabs} linkProps={{ shallow: true }} />}
|
||||||
|
</div>
|
||||||
|
<main>{children}</main>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
|
@ -1,20 +1,20 @@
|
||||||
import { SelectorIcon } from "@heroicons/react/outline";
|
import { SelectorIcon } from "@heroicons/react/outline";
|
||||||
import {
|
import {
|
||||||
CalendarIcon,
|
CalendarIcon,
|
||||||
ArrowLeftIcon,
|
|
||||||
ClockIcon,
|
ClockIcon,
|
||||||
CogIcon,
|
CogIcon,
|
||||||
ExternalLinkIcon,
|
ExternalLinkIcon,
|
||||||
LinkIcon,
|
LinkIcon,
|
||||||
LogoutIcon,
|
LogoutIcon,
|
||||||
PuzzleIcon,
|
ViewGridIcon,
|
||||||
MoonIcon,
|
MoonIcon,
|
||||||
MapIcon,
|
MapIcon,
|
||||||
|
ArrowLeftIcon,
|
||||||
} from "@heroicons/react/solid";
|
} from "@heroicons/react/solid";
|
||||||
import { signOut, useSession } from "next-auth/react";
|
import { signOut, useSession } from "next-auth/react";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
import React, { ReactNode, useEffect, useState } from "react";
|
import React, { Fragment, ReactNode, useEffect, useState } from "react";
|
||||||
import { Toaster } from "react-hot-toast";
|
import { Toaster } from "react-hot-toast";
|
||||||
|
|
||||||
import LicenseBanner from "@ee/components/LicenseBanner";
|
import LicenseBanner from "@ee/components/LicenseBanner";
|
||||||
|
@ -58,6 +58,10 @@ function useRedirectToLoginIfUnauthenticated() {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
if (router.pathname.startsWith("/apps")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!loading && !session) {
|
if (!loading && !session) {
|
||||||
router.replace({
|
router.replace({
|
||||||
pathname: "/auth/login",
|
pathname: "/auth/login",
|
||||||
|
@ -120,10 +124,11 @@ export function ShellSubHeading(props: {
|
||||||
export default function Shell(props: {
|
export default function Shell(props: {
|
||||||
centered?: boolean;
|
centered?: boolean;
|
||||||
title?: string;
|
title?: string;
|
||||||
heading: ReactNode;
|
heading?: ReactNode;
|
||||||
subtitle?: ReactNode;
|
subtitle?: ReactNode;
|
||||||
children: ReactNode;
|
children: ReactNode;
|
||||||
CTA?: ReactNode;
|
CTA?: ReactNode;
|
||||||
|
large?: boolean;
|
||||||
HeadingLeftIcon?: ReactNode;
|
HeadingLeftIcon?: ReactNode;
|
||||||
backPath?: string; // renders back button to specified path
|
backPath?: string; // renders back button to specified path
|
||||||
// use when content needs to expand with flex
|
// use when content needs to expand with flex
|
||||||
|
@ -156,10 +161,22 @@ export default function Shell(props: {
|
||||||
current: router.asPath.startsWith("/availability"),
|
current: router.asPath.startsWith("/availability"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: t("integrations"),
|
name: t("apps"),
|
||||||
href: "/integrations",
|
href: "/apps",
|
||||||
icon: PuzzleIcon,
|
icon: ViewGridIcon,
|
||||||
current: router.asPath.startsWith("/integrations"),
|
current: router.asPath.startsWith("/apps"),
|
||||||
|
child: [
|
||||||
|
{
|
||||||
|
name: t("app_store"),
|
||||||
|
href: "/apps",
|
||||||
|
current: router.asPath === "/apps",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: t("installed_apps"),
|
||||||
|
href: "/apps/installed",
|
||||||
|
current: router.asPath === "/apps/installed",
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: t("settings"),
|
name: t("settings"),
|
||||||
|
@ -181,6 +198,7 @@ export default function Shell(props: {
|
||||||
const user = query.data;
|
const user = query.data;
|
||||||
|
|
||||||
const i18n = useViewerI18n();
|
const i18n = useViewerI18n();
|
||||||
|
const { status } = useSession();
|
||||||
|
|
||||||
if (i18n.status === "loading" || isRedirectingToOnboarding || loading) {
|
if (i18n.status === "loading" || isRedirectingToOnboarding || loading) {
|
||||||
// show spinner whilst i18n is loading to avoid language flicker
|
// show spinner whilst i18n is loading to avoid language flicker
|
||||||
|
@ -205,59 +223,82 @@ export default function Shell(props: {
|
||||||
<Toaster position="bottom-right" />
|
<Toaster position="bottom-right" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex h-screen overflow-hidden bg-gray-100" data-testid="dashboard-shell">
|
<div
|
||||||
<div className="hidden md:flex lg:flex-shrink-0">
|
className={classNames("flex h-screen overflow-hidden", props.large ? "bg-white" : "bg-gray-100")}
|
||||||
<div className="flex w-14 flex-col lg:w-56">
|
data-testid="dashboard-shell">
|
||||||
<div className="flex h-0 flex-1 flex-col border-r border-gray-200 bg-white">
|
{status === "authenticated" && (
|
||||||
<div className="flex flex-1 flex-col overflow-y-auto pt-3 pb-4 lg:pt-5">
|
<div className="hidden md:flex lg:flex-shrink-0">
|
||||||
<Link href="/event-types">
|
<div className="flex w-14 flex-col lg:w-56">
|
||||||
<a className="px-4 md:hidden lg:inline">
|
<div className="flex h-0 flex-1 flex-col border-r border-gray-200 bg-white">
|
||||||
<Logo small />
|
<div className="flex flex-1 flex-col overflow-y-auto pt-3 pb-4 lg:pt-5">
|
||||||
</a>
|
<Link href="/event-types">
|
||||||
</Link>
|
<a className="px-4 md:hidden lg:inline">
|
||||||
{/* logo icon for tablet */}
|
<Logo small />
|
||||||
<Link href="/event-types">
|
</a>
|
||||||
<a className="md:inline lg:hidden">
|
</Link>
|
||||||
<Logo small icon />
|
{/* logo icon for tablet */}
|
||||||
</a>
|
<Link href="/event-types">
|
||||||
</Link>
|
<a className="md:inline lg:hidden">
|
||||||
<nav className="mt-2 flex-1 space-y-1 bg-white px-2 lg:mt-5">
|
<Logo small icon />
|
||||||
{navigation.map((item) => (
|
</a>
|
||||||
<Link key={item.name} href={item.href}>
|
</Link>
|
||||||
<a
|
<nav className="mt-2 flex-1 space-y-1 bg-white px-2 lg:mt-5">
|
||||||
className={classNames(
|
{navigation.map((item) => (
|
||||||
item.current
|
<Fragment key={item.name}>
|
||||||
? "bg-neutral-100 text-neutral-900"
|
<Link href={item.href}>
|
||||||
: "text-neutral-500 hover:bg-gray-50 hover:text-neutral-900",
|
<a
|
||||||
"group flex items-center rounded-sm px-2 py-2 text-sm font-medium"
|
className={classNames(
|
||||||
)}>
|
item.current
|
||||||
<item.icon
|
? "bg-neutral-100 text-neutral-900"
|
||||||
className={classNames(
|
: "text-neutral-500 hover:bg-gray-50 hover:text-neutral-900",
|
||||||
item.current
|
"group flex items-center rounded-sm px-2 py-2 text-sm font-medium"
|
||||||
? "text-neutral-500"
|
)}>
|
||||||
: "text-neutral-400 group-hover:text-neutral-500",
|
<item.icon
|
||||||
"h-5 w-5 flex-shrink-0 ltr:mr-3 rtl:ml-3"
|
className={classNames(
|
||||||
)}
|
item.current
|
||||||
aria-hidden="true"
|
? "text-neutral-500"
|
||||||
/>
|
: "text-neutral-400 group-hover:text-neutral-500",
|
||||||
<span className="hidden lg:inline">{item.name}</span>
|
"h-5 w-5 flex-shrink-0 ltr:mr-3 rtl:ml-3"
|
||||||
</a>
|
)}
|
||||||
</Link>
|
aria-hidden="true"
|
||||||
))}
|
/>
|
||||||
</nav>
|
<span className="hidden lg:inline">{item.name}</span>
|
||||||
</div>
|
</a>
|
||||||
<TrialBanner />
|
</Link>
|
||||||
<div className="m-2 rounded-sm p-2 pt-2 pr-2 hover:bg-gray-100">
|
{item.child &&
|
||||||
<span className="hidden lg:inline">
|
router.asPath.startsWith(item.href) &&
|
||||||
<UserDropdown />
|
item.child.map((item) => {
|
||||||
</span>
|
return (
|
||||||
<span className="hidden md:inline lg:hidden">
|
<Link key={item.name} href={item.href}>
|
||||||
<UserDropdown small />
|
<a
|
||||||
</span>
|
className={classNames(
|
||||||
|
item.current
|
||||||
|
? "text-neutral-900"
|
||||||
|
: "text-neutral-500 hover:text-neutral-900",
|
||||||
|
"group hidden items-center rounded-sm px-2 py-2 pl-10 text-sm font-medium lg:flex"
|
||||||
|
)}>
|
||||||
|
<span className="hidden lg:inline">{item.name}</span>
|
||||||
|
</a>
|
||||||
|
</Link>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</Fragment>
|
||||||
|
))}
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
<TrialBanner />
|
||||||
|
<div className="m-2 rounded-sm p-2 pt-2 pr-2 hover:bg-gray-100">
|
||||||
|
<span className="hidden lg:inline">
|
||||||
|
<UserDropdown />
|
||||||
|
</span>
|
||||||
|
<span className="hidden md:inline lg:hidden">
|
||||||
|
<UserDropdown small />
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
)}
|
||||||
|
|
||||||
<div className="flex w-0 flex-1 flex-col overflow-hidden">
|
<div className="flex w-0 flex-1 flex-col overflow-hidden">
|
||||||
<main
|
<main
|
||||||
|
@ -266,29 +307,31 @@ export default function Shell(props: {
|
||||||
props.flexChildrenContainer && "flex flex-col"
|
props.flexChildrenContainer && "flex flex-col"
|
||||||
)}>
|
)}>
|
||||||
{/* show top navigation for md and smaller (tablet and phones) */}
|
{/* show top navigation for md and smaller (tablet and phones) */}
|
||||||
<nav className="flex items-center justify-between border-b border-gray-200 bg-white p-4 md:hidden">
|
{status === "authenticated" && (
|
||||||
<Link href="/event-types">
|
<nav className="flex items-center justify-between border-b border-gray-200 bg-white p-4 md:hidden">
|
||||||
<a>
|
<Link href="/event-types">
|
||||||
<Logo />
|
<a>
|
||||||
</a>
|
<Logo />
|
||||||
</Link>
|
</a>
|
||||||
<div className="flex items-center gap-3 self-center">
|
</Link>
|
||||||
<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">
|
<div className="flex items-center gap-3 self-center">
|
||||||
<span className="sr-only">{t("view_notifications")}</span>
|
<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">
|
||||||
<Link href="/settings/profile">
|
<span className="sr-only">{t("view_notifications")}</span>
|
||||||
<a>
|
<Link href="/settings/profile">
|
||||||
<CogIcon className="h-6 w-6" aria-hidden="true" />
|
<a>
|
||||||
</a>
|
<CogIcon className="h-6 w-6" aria-hidden="true" />
|
||||||
</Link>
|
</a>
|
||||||
</button>
|
</Link>
|
||||||
<UserDropdown small />
|
</button>
|
||||||
</div>
|
<UserDropdown small />
|
||||||
</nav>
|
</div>
|
||||||
|
</nav>
|
||||||
|
)}
|
||||||
<div
|
<div
|
||||||
className={classNames(
|
className={classNames(
|
||||||
props.centered && "mx-auto md:max-w-5xl",
|
props.centered && "mx-auto md:max-w-5xl",
|
||||||
props.flexChildrenContainer && "flex flex-1 flex-col",
|
props.flexChildrenContainer && "flex flex-1 flex-col",
|
||||||
"py-8"
|
!props.large && "py-8"
|
||||||
)}>
|
)}>
|
||||||
{!!props.backPath && (
|
{!!props.backPath && (
|
||||||
<div className="mx-3 mb-8 sm:mx-8">
|
<div className="mx-3 mb-8 sm:mx-8">
|
||||||
|
@ -300,16 +343,22 @@ export default function Shell(props: {
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<div className="block min-h-[80px] justify-between px-4 sm:flex sm:px-6 md:px-8">
|
{props.heading && props.subtitle && (
|
||||||
{props.HeadingLeftIcon && <div className="ltr:mr-4">{props.HeadingLeftIcon}</div>}
|
<div
|
||||||
<div className="mb-8 w-full">
|
className={classNames(
|
||||||
<h1 className="font-cal mb-1 text-xl font-bold tracking-wide text-gray-900">
|
props.large && "bg-gray-100 py-8 lg:mb-8 lg:pt-16 lg:pb-7",
|
||||||
{props.heading}
|
"block min-h-[80px] justify-between px-4 sm:flex sm:px-6 md:px-8"
|
||||||
</h1>
|
)}>
|
||||||
<p className="text-sm text-neutral-500 ltr:mr-4 rtl:ml-4">{props.subtitle}</p>
|
{props.HeadingLeftIcon && <div className="ltr:mr-4">{props.HeadingLeftIcon}</div>}
|
||||||
|
<div className="mb-8 w-full">
|
||||||
|
<h1 className="font-cal mb-1 text-xl font-bold tracking-wide text-gray-900">
|
||||||
|
{props.heading}
|
||||||
|
</h1>
|
||||||
|
<p className="text-sm text-neutral-500 ltr:mr-4 rtl:ml-4">{props.subtitle}</p>
|
||||||
|
</div>
|
||||||
|
{props.CTA && <div className="mb-4 flex-shrink-0">{props.CTA}</div>}
|
||||||
</div>
|
</div>
|
||||||
<div className="mb-4 flex-shrink-0">{props.CTA}</div>
|
)}
|
||||||
</div>
|
|
||||||
<div
|
<div
|
||||||
className={classNames(
|
className={classNames(
|
||||||
"px-4 sm:px-6 md:px-8",
|
"px-4 sm:px-6 md:px-8",
|
||||||
|
@ -318,34 +367,36 @@ export default function Shell(props: {
|
||||||
{props.children}
|
{props.children}
|
||||||
</div>
|
</div>
|
||||||
{/* show bottom navigation for md and smaller (tablet and phones) */}
|
{/* show bottom navigation for md and smaller (tablet and phones) */}
|
||||||
<nav className="bottom-nav fixed bottom-0 z-30 flex w-full bg-white shadow md:hidden">
|
{status === "authenticated" && (
|
||||||
{/* note(PeerRich): using flatMap instead of map to remove settings from bottom nav */}
|
<nav className="bottom-nav fixed bottom-0 z-30 flex w-full bg-white shadow md:hidden">
|
||||||
{navigation.flatMap((item, itemIdx) =>
|
{/* note(PeerRich): using flatMap instead of map to remove settings from bottom nav */}
|
||||||
item.href === "/settings/profile" ? (
|
{navigation.flatMap((item, itemIdx) =>
|
||||||
[]
|
item.href === "/settings/profile" ? (
|
||||||
) : (
|
[]
|
||||||
<Link key={item.name} href={item.href}>
|
) : (
|
||||||
<a
|
<Link key={item.name} href={item.href}>
|
||||||
className={classNames(
|
<a
|
||||||
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-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(
|
className={classNames(
|
||||||
item.current ? "text-gray-900" : "text-gray-400 group-hover:text-gray-500",
|
item.current ? "text-gray-900" : "text-neutral-400 hover:text-gray-700",
|
||||||
"mx-auto mb-1 block h-5 w-5 flex-shrink-0 text-center"
|
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-center text-xs font-medium hover:bg-gray-50 focus:z-10 sm:text-sm"
|
||||||
)}
|
)}
|
||||||
aria-hidden="true"
|
aria-current={item.current ? "page" : undefined}>
|
||||||
/>
|
<item.icon
|
||||||
<span className="truncate">{item.name}</span>
|
className={classNames(
|
||||||
</a>
|
item.current ? "text-gray-900" : "text-gray-400 group-hover:text-gray-500",
|
||||||
</Link>
|
"mx-auto mb-1 block h-5 w-5 flex-shrink-0 text-center"
|
||||||
)
|
)}
|
||||||
)}
|
aria-hidden="true"
|
||||||
</nav>
|
/>
|
||||||
|
<span className="truncate">{item.name}</span>
|
||||||
|
</a>
|
||||||
|
</Link>
|
||||||
|
)
|
||||||
|
)}
|
||||||
|
</nav>
|
||||||
|
)}
|
||||||
{/* add padding to content for mobile navigation*/}
|
{/* add padding to content for mobile navigation*/}
|
||||||
<div className="block pt-12 md:hidden" />
|
<div className="block pt-12 md:hidden" />
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
import { appRegistry } from "pages/apps/appRegistry";
|
||||||
|
|
||||||
|
import { useLocale } from "@lib/hooks/useLocale";
|
||||||
|
|
||||||
|
import AppCard from "./AppCard";
|
||||||
|
|
||||||
|
export default function AllApps() {
|
||||||
|
const { t } = useLocale();
|
||||||
|
const apps = appRegistry();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="mb-16">
|
||||||
|
<h2 className="mb-2 text-lg font-semibold text-gray-900">{t("all_apps")}</h2>
|
||||||
|
<div className="grid gap-3 grid-col-1 md:grid-cols-3">
|
||||||
|
{apps.map((app) => (
|
||||||
|
<AppCard
|
||||||
|
key={app.name}
|
||||||
|
name={app.name}
|
||||||
|
slug={app.slug}
|
||||||
|
description={app.description}
|
||||||
|
logo={app.logo}
|
||||||
|
rating={app.rating}
|
||||||
|
reviews={app.reviews}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
import { StarIcon } from "@heroicons/react/solid";
|
||||||
|
import Link from "next/link";
|
||||||
|
|
||||||
|
import Button from "@components/ui/Button";
|
||||||
|
|
||||||
|
interface AppCardProps {
|
||||||
|
logo: string;
|
||||||
|
name: string;
|
||||||
|
slug?: string;
|
||||||
|
category?: string;
|
||||||
|
description: string;
|
||||||
|
rating: number;
|
||||||
|
reviews?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function AppCard(props: AppCardProps) {
|
||||||
|
return (
|
||||||
|
<Link href={"/apps/" + props.slug}>
|
||||||
|
<a className="block p-5 border border-gray-300 rounded-sm hover:bg-neutral-50">
|
||||||
|
<div className="flex">
|
||||||
|
<img src={props.logo} alt={props.name + " Logo"} className="w-12 h-12 mb-4 rounded-sm" />
|
||||||
|
<Button
|
||||||
|
color="secondary"
|
||||||
|
className="flex self-start ml-auto"
|
||||||
|
onClick={() => {
|
||||||
|
// TODO: Actually add the integration
|
||||||
|
console.log("The magic is supposed to happen here");
|
||||||
|
}}>
|
||||||
|
Add
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
<h3 className="font-medium">{props.name}</h3>
|
||||||
|
<div className="flex text-sm text-gray-800">
|
||||||
|
<span>{props.rating} stars</span> <StarIcon className="w-4 h-4 ml-1 text-yellow-600 mt-0.5" />
|
||||||
|
<span className="pl-1 text-gray-500">{props.reviews} reviews</span>
|
||||||
|
</div>
|
||||||
|
<p className="mt-2 text-sm text-gray-500">{props.description}</p>
|
||||||
|
</a>
|
||||||
|
</Link>
|
||||||
|
);
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
import { CreditCardIcon } from "@heroicons/react/outline";
|
||||||
|
import Link from "next/link";
|
||||||
|
|
||||||
|
import { useLocale } from "@lib/hooks/useLocale";
|
||||||
|
|
||||||
|
export default function AppStoreCategories(props: any) {
|
||||||
|
const { t } = useLocale();
|
||||||
|
return (
|
||||||
|
<div className="mb-16">
|
||||||
|
<h2 className="mb-2 text-lg font-semibold text-gray-900">{t("popular_categories")}</h2>
|
||||||
|
<div className="grid grid-cols-1 gap-3 md:grid-cols-3">
|
||||||
|
{props.categories.map((category: any) => (
|
||||||
|
<Link key={category.name} href={"/apps/categories/" + category.name}>
|
||||||
|
<a className="flex px-6 py-4 bg-gray-100 rounded-sm">
|
||||||
|
<div className="flex w-12 h-12 mr-4 bg-white rounded-sm">
|
||||||
|
<CreditCardIcon className="self-center w-6 h-6 mx-auto" />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h3 className="font-medium">{category.name}</h3>
|
||||||
|
<p className="text-sm text-gray-500">{category.count} apps</p>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</Link>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
|
@ -0,0 +1,72 @@
|
||||||
|
import Glide from "@glidejs/glide";
|
||||||
|
import { ArrowLeftIcon, ArrowRightIcon } from "@heroicons/react/solid";
|
||||||
|
import { appRegistry } from "pages/apps/appRegistry";
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
|
||||||
|
import { useLocale } from "@lib/hooks/useLocale";
|
||||||
|
import useMediaQuery from "@lib/hooks/useMediaQuery";
|
||||||
|
|
||||||
|
import AppCard from "./AppCard";
|
||||||
|
|
||||||
|
export default function Slider() {
|
||||||
|
const apps = appRegistry();
|
||||||
|
const { t } = useLocale();
|
||||||
|
const isMobile = useMediaQuery("(max-width: 767px)");
|
||||||
|
const [size, setSize] = useState(3);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (isMobile) {
|
||||||
|
setSize(1);
|
||||||
|
} else {
|
||||||
|
setSize(3);
|
||||||
|
}
|
||||||
|
}, [isMobile]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
new Glide(".glide", {
|
||||||
|
type: "carousel",
|
||||||
|
perView: size,
|
||||||
|
}).mount();
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="mb-16">
|
||||||
|
<div className="glide">
|
||||||
|
<div className="flex cursor-default">
|
||||||
|
<div>
|
||||||
|
<h2 className="mb-2 text-lg font-semibold text-gray-900">{t("trending_apps")}</h2>
|
||||||
|
</div>
|
||||||
|
<div className="ml-auto glide__arrows" data-glide-el="controls">
|
||||||
|
<button data-glide-dir="<" className="mr-4">
|
||||||
|
<ArrowLeftIcon className="w-5 h-5 text-gray-600 hover:text-black" />
|
||||||
|
</button>
|
||||||
|
<button data-glide-dir=">">
|
||||||
|
<ArrowRightIcon className="w-5 h-5 text-gray-600 hover:text-black" />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="glide__track" data-glide-el="track">
|
||||||
|
<ul className="glide__slides">
|
||||||
|
{apps.map((app) => {
|
||||||
|
return (
|
||||||
|
app.trending && (
|
||||||
|
<li key={app.name} className="glide__slide">
|
||||||
|
<AppCard
|
||||||
|
key={app.name}
|
||||||
|
name={app.name}
|
||||||
|
slug={app.slug}
|
||||||
|
description={app.description}
|
||||||
|
logo={app.logo}
|
||||||
|
rating={app.rating}
|
||||||
|
reviews={app.reviews}
|
||||||
|
/>
|
||||||
|
</li>
|
||||||
|
)
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
|
@ -94,7 +94,7 @@ const CryptoSection = (props: CryptoSectionProps) => {
|
||||||
const verifyButton = useMemo(() => {
|
const verifyButton = useMemo(() => {
|
||||||
return (
|
return (
|
||||||
<Button color="secondary" onClick={verifyWallet} type="button" id="hasToken" name="hasToken">
|
<Button color="secondary" onClick={verifyWallet} type="button" id="hasToken" name="hasToken">
|
||||||
<img className="mr-1 h-5" src="/integrations/metamask.svg" />
|
<img className="mr-1 h-5" src="/apps/metamask.svg" />
|
||||||
{t("verify_wallet")}
|
{t("verify_wallet")}
|
||||||
</Button>
|
</Button>
|
||||||
);
|
);
|
||||||
|
@ -103,7 +103,7 @@ const CryptoSection = (props: CryptoSectionProps) => {
|
||||||
const connectButton = useMemo(() => {
|
const connectButton = useMemo(() => {
|
||||||
return (
|
return (
|
||||||
<Button color="secondary" onClick={connectMetamask} type="button">
|
<Button color="secondary" onClick={connectMetamask} type="button">
|
||||||
<img className="mr-1 h-5" src="/integrations/metamask.svg" />
|
<img className="mr-1 h-5" src="/apps/metamask.svg" />
|
||||||
{t("connect_metamask")}
|
{t("connect_metamask")}
|
||||||
</Button>
|
</Button>
|
||||||
);
|
);
|
||||||
|
@ -118,7 +118,7 @@ const CryptoSection = (props: CryptoSectionProps) => {
|
||||||
await connectMetamask();
|
await connectMetamask();
|
||||||
await verifyWallet();
|
await verifyWallet();
|
||||||
}}>
|
}}>
|
||||||
<img className="mr-1 h-5" src="/integrations/metamask.svg" />
|
<img className="mr-1 h-5" src="/apps/metamask.svg" />
|
||||||
{t("verify_wallet")}
|
{t("verify_wallet")}
|
||||||
</Button>
|
</Button>
|
||||||
);
|
);
|
||||||
|
|
|
@ -2,9 +2,9 @@ import { PaymentType, Prisma } from "@prisma/client";
|
||||||
import Stripe from "stripe";
|
import Stripe from "stripe";
|
||||||
import { v4 as uuidv4 } from "uuid";
|
import { v4 as uuidv4 } from "uuid";
|
||||||
|
|
||||||
|
import { CalendarEvent } from "@lib/apps/calendar/interfaces/Calendar";
|
||||||
import { sendAwaitingPaymentEmail, sendOrganizerPaymentRefundFailedEmail } from "@lib/emails/email-manager";
|
import { sendAwaitingPaymentEmail, sendOrganizerPaymentRefundFailedEmail } from "@lib/emails/email-manager";
|
||||||
import { getErrorFromUnknown } from "@lib/errors";
|
import { getErrorFromUnknown } from "@lib/errors";
|
||||||
import { CalendarEvent } from "@lib/integrations/calendar/interfaces/Calendar";
|
|
||||||
import prisma from "@lib/prisma";
|
import prisma from "@lib/prisma";
|
||||||
|
|
||||||
import { createPaymentLink } from "./client";
|
import { createPaymentLink } from "./client";
|
||||||
|
|
|
@ -4,11 +4,11 @@ import Stripe from "stripe";
|
||||||
|
|
||||||
import stripe from "@ee/lib/stripe/server";
|
import stripe from "@ee/lib/stripe/server";
|
||||||
|
|
||||||
|
import { CalendarEvent } from "@lib/apps/calendar/interfaces/Calendar";
|
||||||
import { IS_PRODUCTION } from "@lib/config/constants";
|
import { IS_PRODUCTION } from "@lib/config/constants";
|
||||||
import { HttpError as HttpCode } from "@lib/core/http/error";
|
import { HttpError as HttpCode } from "@lib/core/http/error";
|
||||||
import { getErrorFromUnknown } from "@lib/errors";
|
import { getErrorFromUnknown } from "@lib/errors";
|
||||||
import EventManager from "@lib/events/EventManager";
|
import EventManager from "@lib/events/EventManager";
|
||||||
import { CalendarEvent } from "@lib/integrations/calendar/interfaces/Calendar";
|
|
||||||
import prisma from "@lib/prisma";
|
import prisma from "@lib/prisma";
|
||||||
|
|
||||||
import { getTranslation } from "@server/lib/i18n";
|
import { getTranslation } from "@server/lib/i18n";
|
||||||
|
|
|
@ -15,6 +15,7 @@ const config: Config.InitialOptions = {
|
||||||
"^@lib(.*)$": "<rootDir>/lib$1",
|
"^@lib(.*)$": "<rootDir>/lib$1",
|
||||||
"^@server(.*)$": "<rootDir>/server$1",
|
"^@server(.*)$": "<rootDir>/server$1",
|
||||||
"^@ee(.*)$": "<rootDir>/ee$1",
|
"^@ee(.*)$": "<rootDir>/ee$1",
|
||||||
|
"^@apps(.*)$": "<rootDir>/lib/apps$1",
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -2,10 +2,10 @@ import { Person } from "ics";
|
||||||
import short from "short-uuid";
|
import short from "short-uuid";
|
||||||
import { v5 as uuidv5 } from "uuid";
|
import { v5 as uuidv5 } from "uuid";
|
||||||
|
|
||||||
import { getIntegrationName } from "@lib/integrations";
|
import { getAppName } from "@lib/apps/utils/AppUtils";
|
||||||
|
|
||||||
|
import { CalendarEvent } from "./apps/calendar/interfaces/Calendar";
|
||||||
import { BASE_URL } from "./config/constants";
|
import { BASE_URL } from "./config/constants";
|
||||||
import { CalendarEvent } from "./integrations/calendar/interfaces/Calendar";
|
|
||||||
|
|
||||||
const translator = short();
|
const translator = short();
|
||||||
|
|
||||||
|
@ -54,7 +54,7 @@ ${calEvent.description}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getLocation = (calEvent: CalendarEvent) => {
|
export const getLocation = (calEvent: CalendarEvent) => {
|
||||||
let providerName = calEvent.location ? getIntegrationName(calEvent.location) : "";
|
let providerName = calEvent.location ? getAppName(calEvent.location) : "";
|
||||||
|
|
||||||
if (calEvent.location && calEvent.location.includes("integrations:")) {
|
if (calEvent.location && calEvent.location.includes("integrations:")) {
|
||||||
const location = calEvent.location.split(":")[1];
|
const location = calEvent.location.split(":")[1];
|
||||||
|
|
|
@ -13,9 +13,9 @@ import { Form, TextField } from "@components/form/fields";
|
||||||
import { Alert } from "@components/ui/Alert";
|
import { Alert } from "@components/ui/Alert";
|
||||||
import Button from "@components/ui/Button";
|
import Button from "@components/ui/Button";
|
||||||
|
|
||||||
export const ADD_APPLE_INTEGRATION_FORM_TITLE = "addAppleIntegration";
|
export const ADD_INTEGRATION_FORM_TITLE = "addAppleIntegration";
|
||||||
|
|
||||||
export function AddAppleIntegrationModal(props: DialogProps) {
|
export function AddIntegrationModal(props: DialogProps) {
|
||||||
const form = useForm({
|
const form = useForm({
|
||||||
defaultValues: {
|
defaultValues: {
|
||||||
username: "",
|
username: "",
|
|
@ -0,0 +1 @@
|
||||||
|
export const APPLE_CALENDAR_URL = "https://caldav.icloud.com";
|
|
@ -0,0 +1,11 @@
|
||||||
|
import { Credential } from "@prisma/client";
|
||||||
|
|
||||||
|
import { APPS_TYPES } from "../../calendar/constants/general";
|
||||||
|
import CalendarService from "../../calendar/services/CalendarService";
|
||||||
|
import { APPLE_CALENDAR_URL } from "../constants/general";
|
||||||
|
|
||||||
|
export default class AppleCalendarService extends CalendarService {
|
||||||
|
constructor(credential: Credential) {
|
||||||
|
super(credential, APPS_TYPES.apple, APPLE_CALENDAR_URL);
|
||||||
|
}
|
||||||
|
}
|
|
@ -17,14 +17,15 @@ type Props = {
|
||||||
onSubmit: () => void;
|
onSubmit: () => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const ADD_CALDAV_INTEGRATION_FORM_TITLE = "addCalDav";
|
export const ADD_INTEGRATION_FORM_TITLE = "addCalDav";
|
||||||
export type AddCalDavIntegrationRequest = {
|
|
||||||
|
export type AddIntegrationRequest = {
|
||||||
url: string;
|
url: string;
|
||||||
username: string;
|
username: string;
|
||||||
password: string;
|
password: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export function AddCalDavIntegrationModal(props: DialogProps) {
|
export function AddIntegrationModal(props: DialogProps) {
|
||||||
const form = useForm({
|
const form = useForm({
|
||||||
defaultValues: {
|
defaultValues: {
|
||||||
url: "",
|
url: "",
|
||||||
|
@ -118,7 +119,7 @@ const AddCalDavIntegration = React.forwardRef<HTMLFormElement, Props>((props, re
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<form id={ADD_CALDAV_INTEGRATION_FORM_TITLE} ref={ref} onSubmit={onSubmit}>
|
<form id={ADD_INTEGRATION_FORM_TITLE} ref={ref} onSubmit={onSubmit}>
|
||||||
<div className="mb-2">
|
<div className="mb-2">
|
||||||
<label htmlFor="url" className="block text-sm font-medium text-gray-700">
|
<label htmlFor="url" className="block text-sm font-medium text-gray-700">
|
||||||
Calendar URL
|
Calendar URL
|
|
@ -0,0 +1,10 @@
|
||||||
|
import { Credential } from "@prisma/client";
|
||||||
|
|
||||||
|
import { APPS_TYPES } from "../../calendar/constants/general";
|
||||||
|
import CalendarService from "../../calendar/services/CalendarService";
|
||||||
|
|
||||||
|
export default class CalDavCalendarService extends CalendarService {
|
||||||
|
constructor(credential: Credential) {
|
||||||
|
super(credential, APPS_TYPES.caldav);
|
||||||
|
}
|
||||||
|
}
|
|
@ -13,10 +13,10 @@ import { Alert } from "@components/ui/Alert";
|
||||||
import Button from "@components/ui/Button";
|
import Button from "@components/ui/Button";
|
||||||
import Switch from "@components/ui/Switch";
|
import Switch from "@components/ui/Switch";
|
||||||
|
|
||||||
import ConnectIntegration from "./ConnectIntegrations";
|
import ConnectIntegration from "../../../../components/integrations/ConnectIntegrations";
|
||||||
import DisconnectIntegration from "./DisconnectIntegration";
|
import DisconnectIntegration from "../../../../components/integrations/DisconnectIntegration";
|
||||||
import IntegrationListItem from "./IntegrationListItem";
|
import IntegrationListItem from "../../../../components/integrations/IntegrationListItem";
|
||||||
import SubHeadingTitleWithConnections from "./SubHeadingTitleWithConnections";
|
import SubHeadingTitleWithConnections from "../../../../components/integrations/SubHeadingTitleWithConnections";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
onChanged: () => unknown | Promise<unknown>;
|
onChanged: () => unknown | Promise<unknown>;
|
||||||
|
@ -105,7 +105,7 @@ function ConnectedCalendarsList(props: Props) {
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<List>
|
<List>
|
||||||
{data.connectedCalendars.map((item) => (
|
{data.connectedCalendars.map((item: any) => (
|
||||||
<Fragment key={item.credentialId}>
|
<Fragment key={item.credentialId}>
|
||||||
{item.calendars ? (
|
{item.calendars ? (
|
||||||
<IntegrationListItem
|
<IntegrationListItem
|
||||||
|
@ -170,7 +170,7 @@ function CalendarList(props: Props) {
|
||||||
query={query}
|
query={query}
|
||||||
success={({ data }) => (
|
success={({ data }) => (
|
||||||
<List>
|
<List>
|
||||||
{data.calendar.items.map((item) => (
|
{data.calendar.items.map((item: any) => (
|
||||||
<IntegrationListItem
|
<IntegrationListItem
|
||||||
key={item.title}
|
key={item.title}
|
||||||
{...item}
|
{...item}
|
|
@ -0,0 +1,41 @@
|
||||||
|
import { validJson } from "../../jsonUtils";
|
||||||
|
import { App } from "../interfaces/App";
|
||||||
|
|
||||||
|
export const APPS = {
|
||||||
|
google_calendar: {
|
||||||
|
installed: !!(process.env.GOOGLE_API_CREDENTIALS && validJson(process.env.GOOGLE_API_CREDENTIALS)),
|
||||||
|
type: "google_calendar",
|
||||||
|
title: "Google Calendar",
|
||||||
|
name: "Google Calendar",
|
||||||
|
description: "For personal and business calendars",
|
||||||
|
imageSrc: "apps/google-calendar.svg",
|
||||||
|
variant: "calendar",
|
||||||
|
},
|
||||||
|
office365_calendar: {
|
||||||
|
installed: !!(process.env.MS_GRAPH_CLIENT_ID && process.env.MS_GRAPH_CLIENT_SECRET),
|
||||||
|
type: "office365_calendar",
|
||||||
|
title: "Office 365 / Outlook.com Calendar",
|
||||||
|
name: "Office 365 Calendar",
|
||||||
|
description: "For personal and business calendars",
|
||||||
|
imageSrc: "apps/outlook.svg",
|
||||||
|
variant: "calendar",
|
||||||
|
},
|
||||||
|
caldav_calendar: {
|
||||||
|
installed: true,
|
||||||
|
type: "caldav_calendar",
|
||||||
|
title: "CalDav Server",
|
||||||
|
name: "CalDav Server",
|
||||||
|
imageSrc: "apps/caldav.svg",
|
||||||
|
description: "For personal and business calendars",
|
||||||
|
variant: "calendar",
|
||||||
|
},
|
||||||
|
apple_calendar: {
|
||||||
|
installed: true,
|
||||||
|
type: "apple_calendar",
|
||||||
|
title: "Apple Calendar",
|
||||||
|
name: "Apple Calendar",
|
||||||
|
description: "For personal and business calendars",
|
||||||
|
imageSrc: "apps/apple-calendar.svg",
|
||||||
|
variant: "calendar",
|
||||||
|
},
|
||||||
|
} as Record<string, App>;
|
|
@ -0,0 +1,8 @@
|
||||||
|
export const DEFAULT_CALENDAR_TYPE = "caldav";
|
||||||
|
|
||||||
|
export const APPS_TYPES = {
|
||||||
|
apple: "apple_calendar",
|
||||||
|
caldav: "caldav_calendar",
|
||||||
|
google: "google_calendar",
|
||||||
|
office365: "office365_calendar",
|
||||||
|
};
|
|
@ -7,20 +7,20 @@ import { EventResult } from "@lib/events/EventManager";
|
||||||
import logger from "@lib/logger";
|
import logger from "@lib/logger";
|
||||||
import notEmpty from "@lib/notEmpty";
|
import notEmpty from "@lib/notEmpty";
|
||||||
|
|
||||||
import { ALL_INTEGRATIONS } from "../getIntegrations";
|
import AppleCalendarService from "../../apple_calendar/services/CalendarService";
|
||||||
import { CALENDAR_INTEGRATIONS_TYPES } from "./constants/generals";
|
import CalDavCalendarService from "../../caldav_calendar/services/CalendarService";
|
||||||
import { CalendarServiceType, EventBusyDate } from "./constants/types";
|
import GoogleCalendarService from "../../google_calendar/services/CalendarService";
|
||||||
import { Calendar, CalendarEvent } from "./interfaces/Calendar";
|
import Office365CalendarService from "../../office365_calendar/services/CalendarService";
|
||||||
import AppleCalendarService from "./services/AppleCalendarService";
|
import { APPS } from "../config";
|
||||||
import CalDavCalendarService from "./services/CalDavCalendarService";
|
import { APPS_TYPES } from "../constants/general";
|
||||||
import GoogleCalendarService from "./services/GoogleCalendarService";
|
import { Calendar, CalendarEvent } from "../interfaces/Calendar";
|
||||||
import Office365CalendarService from "./services/Office365CalendarService";
|
import { CalendarServiceType, EventBusyDate } from "../types/CalendarTypes";
|
||||||
|
|
||||||
const CALENDARS: Record<string, CalendarServiceType> = {
|
const CALENDARS: Record<string, CalendarServiceType> = {
|
||||||
[CALENDAR_INTEGRATIONS_TYPES.apple]: AppleCalendarService,
|
[APPS_TYPES.apple]: AppleCalendarService,
|
||||||
[CALENDAR_INTEGRATIONS_TYPES.caldav]: CalDavCalendarService,
|
[APPS_TYPES.caldav]: CalDavCalendarService,
|
||||||
[CALENDAR_INTEGRATIONS_TYPES.google]: GoogleCalendarService,
|
[APPS_TYPES.google]: GoogleCalendarService,
|
||||||
[CALENDAR_INTEGRATIONS_TYPES.office365]: Office365CalendarService,
|
[APPS_TYPES.office365]: Office365CalendarService,
|
||||||
};
|
};
|
||||||
|
|
||||||
const log = logger.getChildLogger({ prefix: ["CalendarManager"] });
|
const log = logger.getChildLogger({ prefix: ["CalendarManager"] });
|
||||||
|
@ -41,7 +41,7 @@ export const getCalendarCredentials = (credentials: Array<Omit<Credential, "user
|
||||||
const calendarCredentials = credentials
|
const calendarCredentials = credentials
|
||||||
.filter((credential) => credential.type.endsWith("_calendar"))
|
.filter((credential) => credential.type.endsWith("_calendar"))
|
||||||
.flatMap((credential) => {
|
.flatMap((credential) => {
|
||||||
const integration = ALL_INTEGRATIONS.find((integration) => integration.type === credential.type);
|
const integration = APPS[credential.type];
|
||||||
|
|
||||||
const calendar = getCalendar({
|
const calendar = getCalendar({
|
||||||
...credential,
|
...credential,
|
|
@ -360,7 +360,7 @@ export default abstract class BaseCalendarService implements Calendar {
|
||||||
return createAccount({
|
return createAccount({
|
||||||
account: {
|
account: {
|
||||||
serverUrl: this.url,
|
serverUrl: this.url,
|
||||||
accountType: CALDAV_CALENDAR_TYPE,
|
accountType: DEFAULT_CALENDAR_TYPE,
|
||||||
credentials: this.credentials,
|
credentials: this.credentials,
|
||||||
},
|
},
|
||||||
headers: this.headers,
|
headers: this.headers,
|
|
@ -1,10 +1,18 @@
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
import ICAL from "ical.js";
|
import ICAL from "ical.js";
|
||||||
|
import { TFunction } from "next-i18next";
|
||||||
|
|
||||||
import AppleCalendarService from "../services/AppleCalendarService";
|
import AppleCalendarService from "../../apple_calendar/services/CalendarService";
|
||||||
import CalDavCalendarService from "../services/CalDavCalendarService";
|
import CalDavCalendarService from "../../apple_calendar/services/CalendarService";
|
||||||
import GoogleCalendarService from "../services/GoogleCalendarService";
|
import GoogleCalendarService from "../../google_calendar/services/CalendarService";
|
||||||
import Office365CalendarService from "../services/Office365CalendarService";
|
import Office365CalendarService from "../../office365_calendar/services/CalendarService";
|
||||||
|
|
||||||
|
export type Person = {
|
||||||
|
name: string;
|
||||||
|
email: string;
|
||||||
|
timeZone: string;
|
||||||
|
language: { translate: TFunction; locale: string };
|
||||||
|
};
|
||||||
|
|
||||||
export type EventBusyDate = Record<"start" | "end", Date | string>;
|
export type EventBusyDate = Record<"start" | "end", Date | string>;
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
import { App } from "../interfaces/App";
|
||||||
|
|
||||||
|
export const APPS = {
|
||||||
|
zoom_video: {
|
||||||
|
installed: !!(process.env.ZOOM_CLIENT_ID && process.env.ZOOM_CLIENT_SECRET),
|
||||||
|
type: "zoom_video",
|
||||||
|
title: "Zoom",
|
||||||
|
name: "Zoom",
|
||||||
|
description: "Video Conferencing",
|
||||||
|
imageSrc: "apps/zoom.svg",
|
||||||
|
variant: "conferencing",
|
||||||
|
},
|
||||||
|
daily_video: {
|
||||||
|
installed: !!process.env.DAILY_API_KEY,
|
||||||
|
type: "daily_video",
|
||||||
|
title: "Daily.co Video",
|
||||||
|
name: "Daily",
|
||||||
|
description: "Video Conferencing",
|
||||||
|
imageSrc: "apps/daily.svg",
|
||||||
|
variant: "conferencing",
|
||||||
|
},
|
||||||
|
} as Record<string, App>;
|
|
@ -3,13 +3,13 @@ import { GetTokenResponse } from "google-auth-library/build/src/auth/oauth2clien
|
||||||
import { Auth, calendar_v3, google } from "googleapis";
|
import { Auth, calendar_v3, google } from "googleapis";
|
||||||
|
|
||||||
import { getLocation, getRichDescription } from "@lib/CalEventParser";
|
import { getLocation, getRichDescription } from "@lib/CalEventParser";
|
||||||
import { CALENDAR_INTEGRATIONS_TYPES } from "@lib/integrations/calendar/constants/generals";
|
|
||||||
import logger from "@lib/logger";
|
import logger from "@lib/logger";
|
||||||
import prisma from "@lib/prisma";
|
import prisma from "@lib/prisma";
|
||||||
|
|
||||||
import { EventBusyDate, NewCalendarEventType } from "../constants/types";
|
import { APPS_TYPES } from "../../calendar/constants/general";
|
||||||
import { Calendar, CalendarEvent, IntegrationCalendar } from "../interfaces/Calendar";
|
import { Calendar, CalendarEvent, IntegrationCalendar } from "../../calendar/interfaces/Calendar";
|
||||||
import CalendarService from "./BaseCalendarService";
|
import CalendarService from "../../calendar/services/CalendarService";
|
||||||
|
import { EventBusyDate, NewCalendarEventType } from "../../calendar/types/CalendarTypes";
|
||||||
|
|
||||||
const GOOGLE_API_CREDENTIALS = process.env.GOOGLE_API_CREDENTIALS || "";
|
const GOOGLE_API_CREDENTIALS = process.env.GOOGLE_API_CREDENTIALS || "";
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ export default class GoogleCalendarService implements Calendar {
|
||||||
private log: typeof logger;
|
private log: typeof logger;
|
||||||
|
|
||||||
constructor(credential: Credential) {
|
constructor(credential: Credential) {
|
||||||
this.integrationName = CALENDAR_INTEGRATIONS_TYPES.google;
|
this.integrationName = APPS_TYPES.google;
|
||||||
|
|
||||||
this.auth = this.googleAuth(credential);
|
this.auth = this.googleAuth(credential);
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
/**
|
||||||
|
* Let define an App Integration.
|
||||||
|
*
|
||||||
|
* @type - App
|
||||||
|
* @member {boolean} installed is used to indicate if the app is installed or not.
|
||||||
|
* @member {string} type is used to indicate which type the app is.
|
||||||
|
* @member {string} title is used to add a distinctive name
|
||||||
|
* @member {string} name is the app's name.
|
||||||
|
* @member {string} description is to add information about the app.
|
||||||
|
* @member {string} imageSrc is to indicate where the app's logo is located.
|
||||||
|
* @member {string} variant is to indicate to which classification the app belongs. It can be a `calendar`, `payment` or `conferencing` integration.
|
||||||
|
*/
|
||||||
|
export type App = {
|
||||||
|
installed: boolean;
|
||||||
|
type: `${string}_calendar` | `${string}_payment` | `${string}_video`;
|
||||||
|
title: string;
|
||||||
|
name: string;
|
||||||
|
description: string;
|
||||||
|
imageSrc: string;
|
||||||
|
variant: "calendar" | "payment" | "conferencing";
|
||||||
|
};
|
|
@ -3,13 +3,13 @@ import { Credential } from "@prisma/client";
|
||||||
|
|
||||||
import { getLocation, getRichDescription } from "@lib/CalEventParser";
|
import { getLocation, getRichDescription } from "@lib/CalEventParser";
|
||||||
import { handleErrorsJson, handleErrorsRaw } from "@lib/errors";
|
import { handleErrorsJson, handleErrorsRaw } from "@lib/errors";
|
||||||
import { CALENDAR_INTEGRATIONS_TYPES } from "@lib/integrations/calendar/constants/generals";
|
|
||||||
import logger from "@lib/logger";
|
import logger from "@lib/logger";
|
||||||
import prisma from "@lib/prisma";
|
import prisma from "@lib/prisma";
|
||||||
|
|
||||||
import { BatchResponse, EventBusyDate, NewCalendarEventType } from "../constants/types";
|
import { APPS_TYPES } from "../../calendar/constants/general";
|
||||||
import { Calendar, CalendarEvent, IntegrationCalendar } from "../interfaces/Calendar";
|
import { Calendar, CalendarEvent, IntegrationCalendar } from "../../calendar/interfaces/Calendar";
|
||||||
import { BufferedBusyTime, O365AuthCredentials } from "../interfaces/Office365Calendar";
|
import { BatchResponse, EventBusyDate, NewCalendarEventType } from "../../calendar/types/CalendarTypes";
|
||||||
|
import { BufferedBusyTime, O365AuthCredentials } from "../types/Office365Calendar";
|
||||||
|
|
||||||
const MS_GRAPH_CLIENT_ID = process.env.MS_GRAPH_CLIENT_ID || "";
|
const MS_GRAPH_CLIENT_ID = process.env.MS_GRAPH_CLIENT_ID || "";
|
||||||
const MS_GRAPH_CLIENT_SECRET = process.env.MS_GRAPH_CLIENT_SECRET || "";
|
const MS_GRAPH_CLIENT_SECRET = process.env.MS_GRAPH_CLIENT_SECRET || "";
|
||||||
|
@ -21,7 +21,7 @@ export default class Office365CalendarService implements Calendar {
|
||||||
auth: { getToken: () => Promise<string> };
|
auth: { getToken: () => Promise<string> };
|
||||||
|
|
||||||
constructor(credential: Credential) {
|
constructor(credential: Credential) {
|
||||||
this.integrationName = CALENDAR_INTEGRATIONS_TYPES.office365;
|
this.integrationName = APPS_TYPES.office365;
|
||||||
this.auth = this.o365Auth(credential);
|
this.auth = this.o365Auth(credential);
|
||||||
|
|
||||||
this.log = logger.getChildLogger({ prefix: [`[[lib] ${this.integrationName}`] });
|
this.log = logger.getChildLogger({ prefix: [`[[lib] ${this.integrationName}`] });
|
|
@ -0,0 +1,17 @@
|
||||||
|
import { App } from "../interfaces/App";
|
||||||
|
|
||||||
|
export const APPS = {
|
||||||
|
stripe_payment: {
|
||||||
|
installed: !!(
|
||||||
|
process.env.STRIPE_CLIENT_ID &&
|
||||||
|
process.env.NEXT_PUBLIC_STRIPE_PUBLIC_KEY &&
|
||||||
|
process.env.STRIPE_PRIVATE_KEY
|
||||||
|
),
|
||||||
|
type: "stripe_payment",
|
||||||
|
title: "Stripe",
|
||||||
|
name: "Stripe",
|
||||||
|
imageSrc: "apps/stripe.svg",
|
||||||
|
description: "Collect payments",
|
||||||
|
variant: "payment",
|
||||||
|
},
|
||||||
|
} as Record<string, App>;
|
|
@ -0,0 +1,70 @@
|
||||||
|
import { Prisma } from "@prisma/client";
|
||||||
|
import _ from "lodash";
|
||||||
|
|
||||||
|
import { APPS as CalendarApps } from "@lib/apps/calendar/config";
|
||||||
|
import { APPS as ConferencingApps } from "@lib/apps/conferencing/config";
|
||||||
|
import { App } from "@lib/apps/interfaces/App";
|
||||||
|
import { APPS as PaymentApps } from "@lib/apps/payment/config";
|
||||||
|
|
||||||
|
const ALL_APPS_MAP = { ...CalendarApps, ...ConferencingApps, ...PaymentApps };
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We can't use aliases in playwright tests (yet)
|
||||||
|
* https://github.com/microsoft/playwright/issues/7121
|
||||||
|
*/
|
||||||
|
const credentialData = Prisma.validator<Prisma.CredentialArgs>()({
|
||||||
|
select: { id: true, type: true },
|
||||||
|
});
|
||||||
|
|
||||||
|
type CredentialData = Prisma.CredentialGetPayload<typeof credentialData>;
|
||||||
|
|
||||||
|
export const ALL_APPS = Object.entries(ALL_APPS_MAP).map((app) => app[1]);
|
||||||
|
|
||||||
|
function getApps(userCredentials: CredentialData[]) {
|
||||||
|
const apps = ALL_APPS.map((app) => {
|
||||||
|
const credentials = userCredentials
|
||||||
|
.filter((credential) => credential.type === app.type)
|
||||||
|
.map((credential) => _.pick(credential, ["id", "type"])); // ensure we don't leak `key` to frontend
|
||||||
|
|
||||||
|
const credential: typeof credentials[number] | null = credentials[0] || null;
|
||||||
|
return {
|
||||||
|
...app,
|
||||||
|
/**
|
||||||
|
* @deprecated use `credentials`
|
||||||
|
*/
|
||||||
|
credential,
|
||||||
|
credentials,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
return apps;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type AppMeta = ReturnType<typeof getApps>;
|
||||||
|
|
||||||
|
export function hasIntegration(apps: AppMeta, type: string): boolean {
|
||||||
|
return !!apps.find(
|
||||||
|
(app) => app.type === type && !!app.installed && (type === "daily_video" || app.credentials.length > 0)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
export function hasIntegrationInstalled(type: App["type"]): boolean {
|
||||||
|
return ALL_APPS.some((app) => app.type === type && !!app.installed);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getAppName(name: string) {
|
||||||
|
return ALL_APPS_MAP[name].name;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getAppType(name: string): string {
|
||||||
|
const type = ALL_APPS_MAP[name].type;
|
||||||
|
|
||||||
|
if (type.endsWith("_calendar")) {
|
||||||
|
return "Calendar";
|
||||||
|
}
|
||||||
|
if (type.endsWith("_payment")) {
|
||||||
|
return "Payment";
|
||||||
|
}
|
||||||
|
return "Unknown";
|
||||||
|
}
|
||||||
|
|
||||||
|
export default getApps;
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { CalendarEvent } from "@lib/calendar/interfaces/Calendar";
|
||||||
import AttendeeAwaitingPaymentEmail from "@lib/emails/templates/attendee-awaiting-payment-email";
|
import AttendeeAwaitingPaymentEmail from "@lib/emails/templates/attendee-awaiting-payment-email";
|
||||||
import AttendeeCancelledEmail from "@lib/emails/templates/attendee-cancelled-email";
|
import AttendeeCancelledEmail from "@lib/emails/templates/attendee-cancelled-email";
|
||||||
import AttendeeDeclinedEmail from "@lib/emails/templates/attendee-declined-email";
|
import AttendeeDeclinedEmail from "@lib/emails/templates/attendee-declined-email";
|
||||||
|
|
|
@ -308,7 +308,7 @@ ${getRichDescription(this.calEvent)}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected getLocation(): string {
|
protected getLocation(): string {
|
||||||
let providerName = this.calEvent.location ? getIntegrationName(this.calEvent.location) : "";
|
let providerName = this.calEvent.location ? getAppName(this.calEvent.location) : "";
|
||||||
|
|
||||||
if (this.calEvent.location && this.calEvent.location.includes("integrations:")) {
|
if (this.calEvent.location && this.calEvent.location.includes("integrations:")) {
|
||||||
const location = this.calEvent.location.split(":")[1];
|
const location = this.calEvent.location.split(":")[1];
|
||||||
|
|
|
@ -7,9 +7,9 @@ import { createEvent, DateArray, Person } from "ics";
|
||||||
import nodemailer from "nodemailer";
|
import nodemailer from "nodemailer";
|
||||||
|
|
||||||
import { getCancelLink, getRichDescription } from "@lib/CalEventParser";
|
import { getCancelLink, getRichDescription } from "@lib/CalEventParser";
|
||||||
|
import { CalendarEvent } from "@lib/apps/calendar/interfaces/Calendar";
|
||||||
|
import { getAppName } from "@lib/apps/utils/AppUtils";
|
||||||
import { getErrorFromUnknown } from "@lib/errors";
|
import { getErrorFromUnknown } from "@lib/errors";
|
||||||
import { getIntegrationName } from "@lib/integrations";
|
|
||||||
import { CalendarEvent } from "@lib/integrations/calendar/interfaces/Calendar";
|
|
||||||
import { serverConfig } from "@lib/serverConfig";
|
import { serverConfig } from "@lib/serverConfig";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
@ -299,7 +299,7 @@ ${getRichDescription(this.calEvent)}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected getLocation(): string {
|
protected getLocation(): string {
|
||||||
let providerName = this.calEvent.location ? getIntegrationName(this.calEvent.location) : "";
|
let providerName = this.calEvent.location ? getAppName(this.calEvent.location) : "";
|
||||||
|
|
||||||
if (this.calEvent.location && this.calEvent.location.includes("integrations:")) {
|
if (this.calEvent.location && this.calEvent.location.includes("integrations:")) {
|
||||||
const location = this.calEvent.location.split(":")[1];
|
const location = this.calEvent.location.split(":")[1];
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
import { useState, useEffect } from "react";
|
||||||
|
|
||||||
|
const useMediaQuery = (query: string) => {
|
||||||
|
const [matches, setMatches] = useState(false);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const media = window.matchMedia(query);
|
||||||
|
if (media.matches !== matches) {
|
||||||
|
setMatches(media.matches);
|
||||||
|
}
|
||||||
|
const listener = () => setMatches(media.matches);
|
||||||
|
window.addEventListener("resize", listener);
|
||||||
|
return () => window.removeEventListener("resize", listener);
|
||||||
|
}, [matches, query]);
|
||||||
|
|
||||||
|
return matches;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default useMediaQuery;
|
|
@ -1,10 +0,0 @@
|
||||||
export const CALDAV_CALENDAR_TYPE = "caldav";
|
|
||||||
|
|
||||||
export const APPLE_CALENDAR_URL = "https://caldav.icloud.com";
|
|
||||||
|
|
||||||
export const CALENDAR_INTEGRATIONS_TYPES = {
|
|
||||||
apple: "apple_calendar",
|
|
||||||
caldav: "caldav_calendar",
|
|
||||||
google: "google_calendar",
|
|
||||||
office365: "office365_calendar",
|
|
||||||
};
|
|
|
@ -1,10 +0,0 @@
|
||||||
import { Credential } from "@prisma/client";
|
|
||||||
|
|
||||||
import { APPLE_CALENDAR_URL, CALENDAR_INTEGRATIONS_TYPES } from "../constants/generals";
|
|
||||||
import CalendarService from "./BaseCalendarService";
|
|
||||||
|
|
||||||
export default class AppleCalendarService extends CalendarService {
|
|
||||||
constructor(credential: Credential) {
|
|
||||||
super(credential, CALENDAR_INTEGRATIONS_TYPES.apple, APPLE_CALENDAR_URL);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,10 +0,0 @@
|
||||||
import { Credential } from "@prisma/client";
|
|
||||||
|
|
||||||
import { CALENDAR_INTEGRATIONS_TYPES } from "../constants/generals";
|
|
||||||
import CalendarService from "./BaseCalendarService";
|
|
||||||
|
|
||||||
export default class CalDavCalendarService extends CalendarService {
|
|
||||||
constructor(credential: Credential) {
|
|
||||||
super(credential, CALENDAR_INTEGRATIONS_TYPES.caldav);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -2,9 +2,9 @@
|
||||||
import { Prisma } from "@prisma/client";
|
import { Prisma } from "@prisma/client";
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
|
|
||||||
|
import { getBusyCalendarTimes } from "@lib/apps/calendar/managers/CalendarManager";
|
||||||
import { asStringOrNull } from "@lib/asStringOrNull";
|
import { asStringOrNull } from "@lib/asStringOrNull";
|
||||||
import { getWorkingHours } from "@lib/availability";
|
import { getWorkingHours } from "@lib/availability";
|
||||||
import { getBusyCalendarTimes } from "@lib/integrations/calendar/CalendarManager";
|
|
||||||
import prisma from "@lib/prisma";
|
import prisma from "@lib/prisma";
|
||||||
|
|
||||||
export async function getUserAvailability(query: {
|
export async function getUserAvailability(query: {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { compile } from "handlebars";
|
import { compile } from "handlebars";
|
||||||
|
|
||||||
import { CalendarEvent } from "@lib/integrations/calendar/interfaces/Calendar";
|
import { CalendarEvent } from "@lib/apps/calendar/interfaces/Calendar";
|
||||||
|
|
||||||
type ContentType = "application/json" | "application/x-www-form-urlencoded";
|
type ContentType = "application/json" | "application/x-www-form-urlencoded";
|
||||||
|
|
||||||
|
|
|
@ -5,9 +5,9 @@ import timezone from "dayjs/plugin/timezone";
|
||||||
import utc from "dayjs/plugin/utc";
|
import utc from "dayjs/plugin/utc";
|
||||||
import type { NextApiRequest, NextApiResponse } from "next";
|
import type { NextApiRequest, NextApiResponse } from "next";
|
||||||
|
|
||||||
|
import { getBusyCalendarTimes } from "@lib/apps/calendar/managers/CalendarManager";
|
||||||
import { asStringOrNull } from "@lib/asStringOrNull";
|
import { asStringOrNull } from "@lib/asStringOrNull";
|
||||||
import { getWorkingHours } from "@lib/availability";
|
import { getWorkingHours } from "@lib/availability";
|
||||||
import { getBusyCalendarTimes } from "@lib/integrations/calendar/CalendarManager";
|
|
||||||
import prisma from "@lib/prisma";
|
import prisma from "@lib/prisma";
|
||||||
|
|
||||||
dayjs.extend(utc);
|
dayjs.extend(utc);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import type { NextApiRequest, NextApiResponse } from "next";
|
import type { NextApiRequest, NextApiResponse } from "next";
|
||||||
|
|
||||||
|
import { getCalendarCredentials, getConnectedCalendars } from "@lib/apps/calendar/managers/CalendarManager";
|
||||||
import { getSession } from "@lib/auth";
|
import { getSession } from "@lib/auth";
|
||||||
import { getCalendarCredentials, getConnectedCalendars } from "@lib/integrations/calendar/CalendarManager";
|
|
||||||
import notEmpty from "@lib/notEmpty";
|
import notEmpty from "@lib/notEmpty";
|
||||||
import prisma from "@lib/prisma";
|
import prisma from "@lib/prisma";
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,9 @@ import { v5 as uuidv5 } from "uuid";
|
||||||
|
|
||||||
import { handlePayment } from "@ee/lib/stripe/server";
|
import { handlePayment } from "@ee/lib/stripe/server";
|
||||||
|
|
||||||
|
import { CalendarEvent, AdditionInformation } from "@lib/apps/calendar/interfaces/Calendar";
|
||||||
|
import { getBusyCalendarTimes } from "@lib/apps/calendar/managers/CalendarManager";
|
||||||
|
import { BufferedBusyTime } from "@lib/apps/office365_calendar/types/Office365Calendar";
|
||||||
import {
|
import {
|
||||||
sendScheduledEmails,
|
sendScheduledEmails,
|
||||||
sendRescheduledEmails,
|
sendRescheduledEmails,
|
||||||
|
@ -20,9 +23,6 @@ import { ensureArray } from "@lib/ensureArray";
|
||||||
import { getErrorFromUnknown } from "@lib/errors";
|
import { getErrorFromUnknown } from "@lib/errors";
|
||||||
import { getEventName } from "@lib/event";
|
import { getEventName } from "@lib/event";
|
||||||
import EventManager, { EventResult, PartialReference } from "@lib/events/EventManager";
|
import EventManager, { EventResult, PartialReference } from "@lib/events/EventManager";
|
||||||
import { getBusyCalendarTimes } from "@lib/integrations/calendar/CalendarManager";
|
|
||||||
import { CalendarEvent, AdditionInformation } from "@lib/integrations/calendar/interfaces/Calendar";
|
|
||||||
import { BufferedBusyTime } from "@lib/integrations/calendar/interfaces/Office365Calendar";
|
|
||||||
import logger from "@lib/logger";
|
import logger from "@lib/logger";
|
||||||
import notEmpty from "@lib/notEmpty";
|
import notEmpty from "@lib/notEmpty";
|
||||||
import prisma from "@lib/prisma";
|
import prisma from "@lib/prisma";
|
||||||
|
|
|
@ -5,12 +5,12 @@ import { NextApiRequest, NextApiResponse } from "next";
|
||||||
|
|
||||||
import { refund } from "@ee/lib/stripe/server";
|
import { refund } from "@ee/lib/stripe/server";
|
||||||
|
|
||||||
|
import { CalendarEvent } from "@lib/apps/calendar/interfaces/Calendar";
|
||||||
|
import { getCalendar } from "@lib/apps/calendar/managers/CalendarManager";
|
||||||
import { asStringOrNull } from "@lib/asStringOrNull";
|
import { asStringOrNull } from "@lib/asStringOrNull";
|
||||||
import { getSession } from "@lib/auth";
|
import { getSession } from "@lib/auth";
|
||||||
import { sendCancelledEmails } from "@lib/emails/email-manager";
|
import { sendCancelledEmails } from "@lib/emails/email-manager";
|
||||||
import { FAKE_DAILY_CREDENTIAL } from "@lib/integrations/Daily/DailyVideoApiAdapter";
|
import { FAKE_DAILY_CREDENTIAL } from "@lib/integrations/Daily/DailyVideoApiAdapter";
|
||||||
import { getCalendar } from "@lib/integrations/calendar/CalendarManager";
|
|
||||||
import { CalendarEvent } from "@lib/integrations/calendar/interfaces/Calendar";
|
|
||||||
import prisma from "@lib/prisma";
|
import prisma from "@lib/prisma";
|
||||||
import { deleteMeeting } from "@lib/videoClient";
|
import { deleteMeeting } from "@lib/videoClient";
|
||||||
import sendPayload from "@lib/webhooks/sendPayload";
|
import sendPayload from "@lib/webhooks/sendPayload";
|
||||||
|
@ -158,7 +158,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
|
||||||
bookingToDelete.user.credentials.push(FAKE_DAILY_CREDENTIAL);
|
bookingToDelete.user.credentials.push(FAKE_DAILY_CREDENTIAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
const apiDeletes = async.mapLimit(bookingToDelete.user.credentials, 5, async (credential) => {
|
const apiDeletes = async.mapLimit(bookingToDelete.user.credentials, 5, async (credential: any) => {
|
||||||
const bookingRefUid = bookingToDelete.references.filter((ref) => ref.type === credential.type)[0]?.uid;
|
const bookingRefUid = bookingToDelete.references.filter((ref) => ref.type === credential.type)[0]?.uid;
|
||||||
if (bookingRefUid) {
|
if (bookingRefUid) {
|
||||||
if (credential.type.endsWith("_calendar")) {
|
if (credential.type.endsWith("_calendar")) {
|
||||||
|
|
|
@ -2,8 +2,8 @@ import { ReminderType } from "@prisma/client";
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
import type { NextApiRequest, NextApiResponse } from "next";
|
import type { NextApiRequest, NextApiResponse } from "next";
|
||||||
|
|
||||||
|
import { CalendarEvent } from "@lib/apps/calendar/interfaces/Calendar";
|
||||||
import { sendOrganizerRequestReminderEmail } from "@lib/emails/email-manager";
|
import { sendOrganizerRequestReminderEmail } from "@lib/emails/email-manager";
|
||||||
import { CalendarEvent } from "@lib/integrations/calendar/interfaces/Calendar";
|
|
||||||
import prisma from "@lib/prisma";
|
import prisma from "@lib/prisma";
|
||||||
|
|
||||||
import { getTranslation } from "@server/lib/i18n";
|
import { getTranslation } from "@server/lib/i18n";
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import type { NextApiRequest, NextApiResponse } from "next";
|
import type { NextApiRequest, NextApiResponse } from "next";
|
||||||
|
|
||||||
|
import { getCalendar } from "@lib/apps/calendar/managers/CalendarManager";
|
||||||
import { getSession } from "@lib/auth";
|
import { getSession } from "@lib/auth";
|
||||||
import { symmetricEncrypt } from "@lib/crypto";
|
import { symmetricEncrypt } from "@lib/crypto";
|
||||||
import { getCalendar } from "@lib/integrations/calendar/CalendarManager";
|
|
||||||
import logger from "@lib/logger";
|
import logger from "@lib/logger";
|
||||||
import prisma from "@lib/prisma";
|
import prisma from "@lib/prisma";
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import type { NextApiRequest, NextApiResponse } from "next";
|
import type { NextApiRequest, NextApiResponse } from "next";
|
||||||
|
|
||||||
|
import { getCalendar } from "@lib/apps/calendar/managers/CalendarManager";
|
||||||
import { getSession } from "@lib/auth";
|
import { getSession } from "@lib/auth";
|
||||||
import { symmetricEncrypt } from "@lib/crypto";
|
import { symmetricEncrypt } from "@lib/crypto";
|
||||||
import { getCalendar } from "@lib/integrations/calendar/CalendarManager";
|
|
||||||
import logger from "@lib/logger";
|
import logger from "@lib/logger";
|
||||||
import prisma from "@lib/prisma";
|
import prisma from "@lib/prisma";
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,92 @@
|
||||||
|
// TODO: maybe we wanna do this dynamically later based on folder structure
|
||||||
|
export function appRegistry() {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
name: "Zoom",
|
||||||
|
slug: "zoom", // needs to be the same as the folder name
|
||||||
|
category: "Video Conferencing",
|
||||||
|
description:
|
||||||
|
"Zoom is the most popular video conferencing platform, joinable on the web or via desktop/mobile apps.",
|
||||||
|
logo: "/apps/zoom.svg",
|
||||||
|
publisher: "Cal.com",
|
||||||
|
url: "https://zoom.us/",
|
||||||
|
verified: true,
|
||||||
|
rating: 4.3, // TODO: placeholder for now, pull this from TrustPilot or G2
|
||||||
|
reviews: 69, // TODO: placeholder for now, pull this from TrustPilot or G2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Cal Video",
|
||||||
|
slug: "cal-video",
|
||||||
|
category: "Video Conferencing",
|
||||||
|
description:
|
||||||
|
"Cal Video is the in-house web-based video conferencing platform powered by Daily.co, which is minimalistic and lightweight, but has most of the features you need.",
|
||||||
|
logo: "/apps/daily.svg",
|
||||||
|
publisher: "Cal.com",
|
||||||
|
url: "https://cal.com",
|
||||||
|
verified: true,
|
||||||
|
rating: 4.8,
|
||||||
|
trending: true,
|
||||||
|
reviews: 69,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Google Meet",
|
||||||
|
slug: "google-meet",
|
||||||
|
category: "Video Conferencing",
|
||||||
|
description:
|
||||||
|
"Google Meet is Google's web-based video conferencing platform, designed to compete with major conferencing platforms.",
|
||||||
|
logo: "https://cdn.iconscout.com/icon/free/png-256/google-meet-2923654-2416657.png",
|
||||||
|
rating: 4.4,
|
||||||
|
trending: true,
|
||||||
|
reviews: 69,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Stripe",
|
||||||
|
slug: "stripe",
|
||||||
|
category: "Payments",
|
||||||
|
description: "Stripe is the world's leading payment provider. Start charging for your bookings today.",
|
||||||
|
logo: "/apps/stripe.svg",
|
||||||
|
rating: 4.6,
|
||||||
|
trending: true,
|
||||||
|
reviews: 69,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Google Calendar",
|
||||||
|
slug: "google-calendar",
|
||||||
|
category: "Calendar",
|
||||||
|
description:
|
||||||
|
"Google Calendar is the most popular calendar platform for personal and business calendars.",
|
||||||
|
logo: "/apps/google-calendar.svg",
|
||||||
|
rating: 4.9,
|
||||||
|
reviews: 69,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Microsoft 365/Outlook Calendar",
|
||||||
|
slug: "microsoft-365",
|
||||||
|
category: "Calendar",
|
||||||
|
description:
|
||||||
|
"Microsoft 365 calendars for business users, and Outlook is a popular calendar platform for personal users.",
|
||||||
|
logo: "/apps/outlook.svg",
|
||||||
|
rating: 4.2,
|
||||||
|
reviews: 69,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "CalDAV",
|
||||||
|
slug: "caldav",
|
||||||
|
category: "Calendar",
|
||||||
|
description: "CalDAV is an open calendar standard which connects to virtually every calendar.",
|
||||||
|
logo: "/apps/caldav.svg",
|
||||||
|
rating: 3.6,
|
||||||
|
reviews: 69,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "iCloud Calendar",
|
||||||
|
slug: "icloud-calendar",
|
||||||
|
category: "Calendar",
|
||||||
|
description:
|
||||||
|
"iCloud Calendar is Apple's calendar platform for users of iCloud, and is used in the Apple Calendar app on iOS and macOS.",
|
||||||
|
logo: "/apps/apple-calendar.svg",
|
||||||
|
rating: 3.8,
|
||||||
|
reviews: 69,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
import { ChevronLeftIcon } from "@heroicons/react/solid";
|
||||||
|
import { useRouter } from "next/router";
|
||||||
|
|
||||||
|
import { useLocale } from "@lib/hooks/useLocale";
|
||||||
|
|
||||||
|
import Shell from "@components/Shell";
|
||||||
|
import AppCard from "@components/apps/AppCard";
|
||||||
|
import Button from "@components/ui/Button";
|
||||||
|
|
||||||
|
import { appRegistry } from "../appRegistry";
|
||||||
|
|
||||||
|
export default function Apps() {
|
||||||
|
const { t } = useLocale();
|
||||||
|
const router = useRouter();
|
||||||
|
const apps = appRegistry();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Shell
|
||||||
|
heading={router.query.category + " - " + t("app_store")}
|
||||||
|
subtitle={t("app_store_description")}
|
||||||
|
large>
|
||||||
|
<div className="mb-8">
|
||||||
|
<Button color="secondary" href="/apps">
|
||||||
|
<ChevronLeftIcon className="w-5 h-5" />
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
<div className="mb-16">
|
||||||
|
<h2 className="mb-2 text-lg font-semibold text-gray-900">All {router.query.category} apps</h2>
|
||||||
|
<div className="grid grid-cols-3 gap-3">
|
||||||
|
{apps.map((app) => {
|
||||||
|
return (
|
||||||
|
app.category === router.query.category && (
|
||||||
|
<AppCard
|
||||||
|
key={app.name}
|
||||||
|
slug={app.slug}
|
||||||
|
name={app.name}
|
||||||
|
description={app.description}
|
||||||
|
logo={app.logo}
|
||||||
|
rating={app.rating}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Shell>
|
||||||
|
);
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
import { useLocale } from "@lib/hooks/useLocale";
|
||||||
|
|
||||||
|
import AppsShell from "@components/AppsShell";
|
||||||
|
import Shell from "@components/Shell";
|
||||||
|
import AllApps from "@components/apps/AllApps";
|
||||||
|
import AppStoreCategories from "@components/apps/Categories";
|
||||||
|
import Slider from "@components/apps/Slider";
|
||||||
|
|
||||||
|
export default function Apps() {
|
||||||
|
const { t } = useLocale();
|
||||||
|
|
||||||
|
const popularCategories = [
|
||||||
|
{
|
||||||
|
name: "Payments",
|
||||||
|
count: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Video",
|
||||||
|
count: 3,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Calendar",
|
||||||
|
count: 4,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Shell heading={t("app_store")} subtitle={t("app_store_description")} large>
|
||||||
|
<AppsShell>
|
||||||
|
<AppStoreCategories categories={popularCategories} />
|
||||||
|
<Slider />
|
||||||
|
<AllApps />
|
||||||
|
</AppsShell>
|
||||||
|
</Shell>
|
||||||
|
);
|
||||||
|
}
|
|
@ -22,7 +22,6 @@ import Shell, { ShellSubHeading } from "@components/Shell";
|
||||||
import { Tooltip } from "@components/Tooltip";
|
import { Tooltip } from "@components/Tooltip";
|
||||||
import ConfirmationDialogContent from "@components/dialog/ConfirmationDialogContent";
|
import ConfirmationDialogContent from "@components/dialog/ConfirmationDialogContent";
|
||||||
import { FieldsetLegend, Form, InputGroupBox, TextField, TextArea } from "@components/form/fields";
|
import { FieldsetLegend, Form, InputGroupBox, TextField, TextArea } from "@components/form/fields";
|
||||||
import { CalendarListContainer } from "@components/integrations/CalendarListContainer";
|
|
||||||
import ConnectIntegration from "@components/integrations/ConnectIntegrations";
|
import ConnectIntegration from "@components/integrations/ConnectIntegrations";
|
||||||
import DisconnectIntegration from "@components/integrations/DisconnectIntegration";
|
import DisconnectIntegration from "@components/integrations/DisconnectIntegration";
|
||||||
import IntegrationListItem from "@components/integrations/IntegrationListItem";
|
import IntegrationListItem from "@components/integrations/IntegrationListItem";
|
||||||
|
@ -31,6 +30,8 @@ import { Alert } from "@components/ui/Alert";
|
||||||
import Button from "@components/ui/Button";
|
import Button from "@components/ui/Button";
|
||||||
import Switch from "@components/ui/Switch";
|
import Switch from "@components/ui/Switch";
|
||||||
|
|
||||||
|
import { CalendarListContainer } from "../../lib/apps/calendar/components/CalendarListContainer";
|
||||||
|
|
||||||
type TWebhook = inferQueryOutput<"viewer.webhook.list">[number];
|
type TWebhook = inferQueryOutput<"viewer.webhook.list">[number];
|
||||||
|
|
||||||
function WebhookListItem(props: { webhook: TWebhook; onEditWebhook: () => void }) {
|
function WebhookListItem(props: { webhook: TWebhook; onEditWebhook: () => void }) {
|
||||||
|
@ -653,7 +654,7 @@ export default function IntegrationsPage() {
|
||||||
const { t } = useLocale();
|
const { t } = useLocale();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Shell heading={t("integrations")} subtitle={t("connect_your_favourite_apps")}>
|
<Shell heading={t("installed_apps")} subtitle={t("manage_your_connected_apps")}>
|
||||||
<ClientSuspense fallback={<Loader />}>
|
<ClientSuspense fallback={<Loader />}>
|
||||||
<IntegrationsContainer />
|
<IntegrationsContainer />
|
||||||
<CalendarListContainer />
|
<CalendarListContainer />
|
|
@ -0,0 +1,117 @@
|
||||||
|
import showToast from "@lib/notification";
|
||||||
|
|
||||||
|
import App from "@components/App";
|
||||||
|
|
||||||
|
export default function NukeMyCal() {
|
||||||
|
return (
|
||||||
|
<App
|
||||||
|
name="Nuke my Cal"
|
||||||
|
logo="/apps/nuke-my-cal.svg"
|
||||||
|
categories={["fun", "productivity"]}
|
||||||
|
author="/peer"
|
||||||
|
type="free" // "usage-based", "monthly", "one-time" or "free"
|
||||||
|
price={0} // 0 = free. if type="usage-based" it's the price per booking
|
||||||
|
commission={0} // only required for "usage-based" billing. % of commission for paid bookings
|
||||||
|
website="https://cal.com"
|
||||||
|
email="help@cal.com"
|
||||||
|
tos="https://cal.com/terms"
|
||||||
|
privacy="https://cal.com/privacy"
|
||||||
|
body={
|
||||||
|
<>
|
||||||
|
<style jsx>
|
||||||
|
{`
|
||||||
|
.pushable {
|
||||||
|
position: relative;
|
||||||
|
border: none;
|
||||||
|
background: transparent;
|
||||||
|
padding: 0;
|
||||||
|
cursor: pointer;
|
||||||
|
outline-offset: 4px;
|
||||||
|
transition: filter 250ms;
|
||||||
|
}
|
||||||
|
.shadow {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
border-radius: 12px;
|
||||||
|
background: hsl(0deg 0% 0% / 0.25);
|
||||||
|
will-change: transform;
|
||||||
|
transform: translateY(2px);
|
||||||
|
transition: transform 600ms cubic-bezier(0.3, 0.7, 0.4, 1);
|
||||||
|
}
|
||||||
|
.edge {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
border-radius: 12px;
|
||||||
|
background: linear-gradient(
|
||||||
|
to left,
|
||||||
|
hsl(340deg 100% 16%) 0%,
|
||||||
|
hsl(340deg 100% 32%) 8%,
|
||||||
|
hsl(340deg 100% 32%) 92%,
|
||||||
|
hsl(340deg 100% 16%) 100%
|
||||||
|
);
|
||||||
|
}
|
||||||
|
.front {
|
||||||
|
display: block;
|
||||||
|
position: relative;
|
||||||
|
padding: 12px 42px;
|
||||||
|
border-radius: 12px;
|
||||||
|
font-size: 1.25rem;
|
||||||
|
color: white;
|
||||||
|
background: hsl(345deg 100% 47%);
|
||||||
|
will-change: transform;
|
||||||
|
transform: translateY(-4px);
|
||||||
|
transition: transform 600ms cubic-bezier(0.3, 0.7, 0.4, 1);
|
||||||
|
}
|
||||||
|
.pushable:hover {
|
||||||
|
filter: brightness(110%);
|
||||||
|
}
|
||||||
|
.pushable:hover .front {
|
||||||
|
transform: translateY(-6px);
|
||||||
|
transition: transform 250ms cubic-bezier(0.3, 0.7, 0.4, 1.5);
|
||||||
|
}
|
||||||
|
.pushable:active .front {
|
||||||
|
transform: translateY(-2px);
|
||||||
|
transition: transform 34ms;
|
||||||
|
}
|
||||||
|
.pushable:hover .shadow {
|
||||||
|
transform: translateY(4px);
|
||||||
|
transition: transform 250ms cubic-bezier(0.3, 0.7, 0.4, 1.5);
|
||||||
|
}
|
||||||
|
.pushable:active .shadow {
|
||||||
|
transform: translateY(1px);
|
||||||
|
transition: transform 34ms;
|
||||||
|
}
|
||||||
|
.pushable:focus:not(:focus-visible) {
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
`}
|
||||||
|
</style>
|
||||||
|
<div>
|
||||||
|
Have an emergency? Need to reschedule all of your upcoming calendar events? Just click{" "}
|
||||||
|
<strong>Nuke my Cal</strong> and auto-reschedule the entire day. Give it a try!
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
Demo: <br />
|
||||||
|
<br />
|
||||||
|
</div>
|
||||||
|
<button
|
||||||
|
onClick={() => (
|
||||||
|
new Audio("/apps/nuke-my-cal.wav").play(),
|
||||||
|
showToast("All of your calendar events for today have been rescheduled", "success")
|
||||||
|
)}
|
||||||
|
className="pushable">
|
||||||
|
<span className="shadow"></span>
|
||||||
|
<span className="edge"></span>
|
||||||
|
<span className="front">Nuke my Cal</span>
|
||||||
|
</button>
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
import App from "@components/App";
|
||||||
|
|
||||||
|
export default function Stripe() {
|
||||||
|
return (
|
||||||
|
<App
|
||||||
|
name="Stripe"
|
||||||
|
logo="/apps/stripe.svg"
|
||||||
|
categories={["payments"]}
|
||||||
|
author="Cal.com"
|
||||||
|
type="usage-based" // "usage-based" or "monthly" or "one-time"
|
||||||
|
price={0.1} // price per installation. if "monthly" = price per month. if type="usage-based" = price per booking
|
||||||
|
commission={0} // only required for "usage-based" billing. % of commission for paid bookings
|
||||||
|
docs="https://stripe.com/docs"
|
||||||
|
website="https://zoom.us"
|
||||||
|
email="support@zoom.us"
|
||||||
|
tos="https://zoom.us/terms"
|
||||||
|
privacy="https://zoom.us/privacy"
|
||||||
|
body={
|
||||||
|
<>
|
||||||
|
Stripe provides payments infrastructure for the internet. Millions of businesses of all sizes—from
|
||||||
|
startups to large enterprises—use Stripe's software and APIs to accept payments, send payouts,
|
||||||
|
and manage their businesses online.
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
Use this Stripe App, build by the Cal.com team to start charging for your bookings today.
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
import App from "@components/App";
|
||||||
|
|
||||||
|
export default function Zoom() {
|
||||||
|
return (
|
||||||
|
<App
|
||||||
|
name="Zoom"
|
||||||
|
logo="/apps/zoom.svg"
|
||||||
|
categories={["video", "communication"]}
|
||||||
|
author="Cal.com"
|
||||||
|
type="usage-based" // "usage-based" or "monthly" or "one-time"
|
||||||
|
price={0} // 0 = free. if type="usage-based" it's the price per booking
|
||||||
|
commission={0.5} // only required for "usage-based" billing. % of commission for paid bookings
|
||||||
|
docs="https://zoom.us/download"
|
||||||
|
website="https://zoom.us"
|
||||||
|
email="support@zoom.us"
|
||||||
|
tos="https://zoom.us/terms"
|
||||||
|
privacy="https://zoom.us/privacy"
|
||||||
|
body={
|
||||||
|
<>
|
||||||
|
Start Zoom Meetings and make Zoom Phone calls with flawless video, crystal clear audio, and instant
|
||||||
|
screen sharing from any Slack channel, private group, or direct message using the /zoom slash
|
||||||
|
command.
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
The Zoom app for Slack can be installed individually by any Slack user with a Zoom account or be
|
||||||
|
deployed to the whole organization centrally by the Zoom account admin with a few simple steps.
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
|
@ -28,11 +28,11 @@ import { JSONObject } from "superjson/dist/types";
|
||||||
|
|
||||||
import { StripeData } from "@ee/lib/stripe/server";
|
import { StripeData } from "@ee/lib/stripe/server";
|
||||||
|
|
||||||
|
import getApps, { hasIntegration } from "@lib/apps/utils/AppUtils";
|
||||||
import { asStringOrThrow, asStringOrUndefined } from "@lib/asStringOrNull";
|
import { asStringOrThrow, asStringOrUndefined } from "@lib/asStringOrNull";
|
||||||
import { getSession } from "@lib/auth";
|
import { getSession } from "@lib/auth";
|
||||||
import { HttpError } from "@lib/core/http/error";
|
import { HttpError } from "@lib/core/http/error";
|
||||||
import { useLocale } from "@lib/hooks/useLocale";
|
import { useLocale } from "@lib/hooks/useLocale";
|
||||||
import getIntegrations, { hasIntegration } from "@lib/integrations/getIntegrations";
|
|
||||||
import { LocationType } from "@lib/location";
|
import { LocationType } from "@lib/location";
|
||||||
import showToast from "@lib/notification";
|
import showToast from "@lib/notification";
|
||||||
import prisma from "@lib/prisma";
|
import prisma from "@lib/prisma";
|
||||||
|
@ -1664,7 +1664,7 @@ export const getServerSideProps = async (context: GetServerSidePropsContext) =>
|
||||||
eventType.users.push(fallbackUser);
|
eventType.users.push(fallbackUser);
|
||||||
}
|
}
|
||||||
|
|
||||||
const integrations = getIntegrations(credentials);
|
const integrations = getApps(credentials);
|
||||||
|
|
||||||
const locationOptions: OptionTypeBase[] = [];
|
const locationOptions: OptionTypeBase[] = [];
|
||||||
|
|
||||||
|
|
|
@ -21,8 +21,6 @@ import { asStringOrNull } from "@lib/asStringOrNull";
|
||||||
import { getSession } from "@lib/auth";
|
import { getSession } from "@lib/auth";
|
||||||
import { DEFAULT_SCHEDULE } from "@lib/availability";
|
import { DEFAULT_SCHEDULE } from "@lib/availability";
|
||||||
import { useLocale } from "@lib/hooks/useLocale";
|
import { useLocale } from "@lib/hooks/useLocale";
|
||||||
import { getCalendarCredentials, getConnectedCalendars } from "@lib/integrations/calendar/CalendarManager";
|
|
||||||
import getIntegrations from "@lib/integrations/getIntegrations";
|
|
||||||
import prisma from "@lib/prisma";
|
import prisma from "@lib/prisma";
|
||||||
import { collectPageParameters, telemetryEventTypes, useTelemetry } from "@lib/telemetry";
|
import { collectPageParameters, telemetryEventTypes, useTelemetry } from "@lib/telemetry";
|
||||||
import { trpc } from "@lib/trpc";
|
import { trpc } from "@lib/trpc";
|
||||||
|
@ -32,12 +30,14 @@ import { Schedule as ScheduleType } from "@lib/types/schedule";
|
||||||
import { ClientSuspense } from "@components/ClientSuspense";
|
import { ClientSuspense } from "@components/ClientSuspense";
|
||||||
import Loader from "@components/Loader";
|
import Loader from "@components/Loader";
|
||||||
import { Form } from "@components/form/fields";
|
import { Form } from "@components/form/fields";
|
||||||
import { CalendarListContainer } from "@components/integrations/CalendarListContainer";
|
|
||||||
import { Alert } from "@components/ui/Alert";
|
import { Alert } from "@components/ui/Alert";
|
||||||
import Button from "@components/ui/Button";
|
import Button from "@components/ui/Button";
|
||||||
import Text from "@components/ui/Text";
|
import Text from "@components/ui/Text";
|
||||||
import Schedule from "@components/ui/form/Schedule";
|
import Schedule from "@components/ui/form/Schedule";
|
||||||
|
|
||||||
|
import { CalendarListContainer } from "../lib/apps/calendar/components/CalendarListContainer";
|
||||||
|
import { getCalendarCredentials, getConnectedCalendars } from "../lib/apps/calendar/managers/CalendarManager";
|
||||||
|
import getApps from "../lib/apps/utils/AppUtils";
|
||||||
import getEventTypes from "../lib/queries/event-types/get-event-types";
|
import getEventTypes from "../lib/queries/event-types/get-event-types";
|
||||||
|
|
||||||
dayjs.extend(utc);
|
dayjs.extend(utc);
|
||||||
|
|
|
@ -1,9 +0,0 @@
|
||||||
function RedirectPage() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function getServerSideProps() {
|
|
||||||
return { redirect: { permanent: false, destination: "/integrations" } };
|
|
||||||
}
|
|
||||||
|
|
||||||
export default RedirectPage;
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { expect, test } from "@playwright/test";
|
import { expect, test } from "@playwright/test";
|
||||||
|
|
||||||
import { hasIntegrationInstalled } from "../lib/integrations/getIntegrations";
|
import { hasIntegrationInstalled } from "../lib/apps/utils/AppUtils";
|
||||||
import { todo } from "./lib/testUtils";
|
import { todo } from "./lib/testUtils";
|
||||||
|
|
||||||
test.describe.serial("Stripe integration", () => {
|
test.describe.serial("Stripe integration", () => {
|
||||||
|
|
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 3.0 KiB |
Before Width: | Height: | Size: 264 B After Width: | Height: | Size: 264 B |
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 3.9 KiB |
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 4.5 KiB |
|
@ -0,0 +1,77 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
<svg xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://web.resource.org/cc/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" version="1.1" width="720" height="720" id="svg2">
|
||||||
|
<defs id="defs4">
|
||||||
|
<inkscape:path-effect effect="spiro" id="path-effect3201"/>
|
||||||
|
<inkscape:path-effect effect="spiro" id="path-effect3197"/>
|
||||||
|
<inkscape:path-effect effect="spiro" id="path-effect3193"/>
|
||||||
|
<inkscape:path-effect effect="spiro" id="path-effect3189"/>
|
||||||
|
<inkscape:path-effect effect="spiro" id="path-effect3185"/>
|
||||||
|
<inkscape:path-effect effect="spiro" id="path-effect3181"/>
|
||||||
|
<inkscape:path-effect effect="spiro" id="path-effect3177"/>
|
||||||
|
<inkscape:path-effect effect="spiro" id="path-effect3173"/>
|
||||||
|
<inkscape:path-effect effect="spiro" id="path-effect3169"/>
|
||||||
|
<inkscape:path-effect effect="spiro" id="path-effect3165"/>
|
||||||
|
<inkscape:path-effect effect="spiro" id="path-effect3161"/>
|
||||||
|
<inkscape:path-effect effect="spiro" id="path-effect3157"/>
|
||||||
|
<inkscape:path-effect effect="spiro" id="path-effect3153"/>
|
||||||
|
<inkscape:path-effect effect="spiro" id="path-effect3149"/>
|
||||||
|
<inkscape:path-effect effect="spiro" id="path-effect3149-6"/>
|
||||||
|
<inkscape:path-effect effect="spiro" id="path-effect3153-1"/>
|
||||||
|
<inkscape:path-effect effect="spiro" id="path-effect3157-8"/>
|
||||||
|
<inkscape:path-effect effect="spiro" id="path-effect3161-4"/>
|
||||||
|
<inkscape:path-effect effect="spiro" id="path-effect3165-8"/>
|
||||||
|
<inkscape:path-effect effect="spiro" id="path-effect3169-4"/>
|
||||||
|
<inkscape:path-effect effect="spiro" id="path-effect3173-0"/>
|
||||||
|
<inkscape:path-effect effect="spiro" id="path-effect3177-7"/>
|
||||||
|
<inkscape:path-effect effect="spiro" id="path-effect3181-6"/>
|
||||||
|
<inkscape:path-effect effect="spiro" id="path-effect3185-8"/>
|
||||||
|
<inkscape:path-effect effect="spiro" id="path-effect3189-9"/>
|
||||||
|
<inkscape:path-effect effect="spiro" id="path-effect3193-7"/>
|
||||||
|
<inkscape:path-effect effect="spiro" id="path-effect3197-3"/>
|
||||||
|
<inkscape:path-effect effect="spiro" id="path-effect3201-3"/>
|
||||||
|
</defs>
|
||||||
|
<path d="m 329.6885371631169,144.9454094414912 c 0,0 -9.3691648630806,-18.5615530306314 -37.6534361478519,-6.3639610390736" id="path2983" style="fill:none;stroke:#ff0000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:none"/>
|
||||||
|
<path d="m 326.8905349710195,144.9454094414912 c 0,0 -9.3691648630806,-18.5615530306314 -37.6534361478519,-6.3639610390736" id="path2983-8" style="fill:none;stroke:#ff0000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:none"/>
|
||||||
|
<path d="M 94.6324614631855,36.00250586938022 300.1705854663462,193.5309023590188 342.0166705927379,44.6173400524073 401.0934966535268,195.9922835541695 564.785535530295,54.46286483300981 476.1702964391128,237.8357638717294 616.4777583334849,232.9130014814282 525.4009848231031,347.3672270559314 647.2469385734796,426.1314253007506 502.0164078407082,428.5928064959011 630.0161976390828,582.4291311928135 446.6318834087184,497.5114799601184 426.9396080551219,662.4240200352077 337.0936017543393,529.5094354970756 211.5553463751634,700.5754285600419 223.863018471161,486.4352645819405 52.7863763367938,520.8946013140482 159.8631235719732,380.5958731904649 72.47865169038992,237.8357638717299 194.3246054407665,261.2188852256607 94.6324614631855,36.00250586938069 z" id="path3508" style="fill:#ff0000;stroke:none"/>
|
||||||
|
<path d="m 160.1985233083172,118.7982717399246 154.3242216264676,118.2770704473064 31.419302606586,-111.8087931572194 44.3566625034159,113.6568723829586 122.9049190198811,-106.2645554800019 -66.5349937551232,137.6819023175674 105.347073445612,-3.6961584514783 -68.3831880260988,85.9356839968712 91.4856164132948,59.1385352236531 -109.0434619875631,1.8480792257391 96.1061020907337,115.5049516086972 -137.6904731876862,-63.7587332880004 -14.7855541678056,123.8213081245232 -67.4590908906114,-99.7962781899145 -94.2579078197586,128.4415061888714 9.2409713548783,-160.7828926393062 -128.4495018328083,25.8731091603477 80.3964507874411,-105.3405158671315 -65.6108966196359,-107.1885950928715 91.4856164132951,17.5567526445221 -74.8518679745143,-169.0992491551333 z" id="path3512" style="fill:#ff8000;stroke:none"/>
|
||||||
|
<path d="m 226.2365903979516,204.2096633100054 99.1022747159463,75.9539014973134 20.1765110200129,-71.8001725091792 28.4844861459008,72.9869522200746 78.9257636959331,-68.2398333764925 -42.7267292188508,88.4150884617163 67.6506545965139,-2.373559421791 -43.9135828082631,55.1852565566419 58.7492526759201,37.9769507486567 -70.0243617753388,1.1867797108955 61.7163866494512,74.17373193097 -88.4205924112332,-40.9439000258953 -9.4948287153004,79.5142406299997 -43.3201560135574,-64.0861043883581 -60.529533060039,82.4811899072385 5.9342679470626,-103.2498348479099 -82.4863244641708,16.614915952537 51.6281311394449,-67.6464435210443 -42.1333024241446,-68.8332232319403 58.7492526759201,11.2744072535075 -48.0675703712075,-108.5903435469403 z" id="path3514" style="fill:#ffff00;stroke:none"/>
|
||||||
|
<path d="m -57.96064186096192,305.2593994140625 a 30.91234397888183,30.91234397888183 0 1 1 -61.82468795776368,0 30.91234397888183,30.91234397888183 0 1 1 61.82468795776368,0 z" transform="translate(435.3488372093023,54.09660107334526)" id="path3516" style="fill:#000000;fill-opacity:1;stroke:none"/>
|
||||||
|
<metadata>
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work>
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
|
||||||
|
<cc:license rdf:resource="http://creativecommons.org/licenses/publicdomain/"/>
|
||||||
|
<dc:publisher>
|
||||||
|
<cc:Agent rdf:about="http://openclipart.org/">
|
||||||
|
<dc:title>Open Clip Art Library</dc:title>
|
||||||
|
</cc:Agent>
|
||||||
|
</dc:publisher>
|
||||||
|
<dc:title>one eyed sun</dc:title>
|
||||||
|
<dc:date>2011-07-10T22:19:30</dc:date>
|
||||||
|
<dc:description>my mom came up with the name for this!</dc:description>
|
||||||
|
<dc:source>http://openclipart.org/detail/148927/one-eyed-sun-by-10binary</dc:source>
|
||||||
|
<dc:creator>
|
||||||
|
<cc:Agent>
|
||||||
|
<dc:title>10binary</dc:title>
|
||||||
|
</cc:Agent>
|
||||||
|
</dc:creator>
|
||||||
|
<dc:subject>
|
||||||
|
<rdf:Bag>
|
||||||
|
<rdf:li>clip art</rdf:li>
|
||||||
|
<rdf:li>clipart</rdf:li>
|
||||||
|
<rdf:li>eyed</rdf:li>
|
||||||
|
<rdf:li>one</rdf:li>
|
||||||
|
<rdf:li>sun</rdf:li>
|
||||||
|
</rdf:Bag>
|
||||||
|
</dc:subject>
|
||||||
|
</cc:Work>
|
||||||
|
<cc:License rdf:about="http://creativecommons.org/licenses/publicdomain/">
|
||||||
|
<cc:permits rdf:resource="http://creativecommons.org/ns#Reproduction"/>
|
||||||
|
<cc:permits rdf:resource="http://creativecommons.org/ns#Distribution"/>
|
||||||
|
<cc:permits rdf:resource="http://creativecommons.org/ns#DerivativeWorks"/>
|
||||||
|
</cc:License>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 6.9 KiB |
Before Width: | Height: | Size: 7.1 KiB After Width: | Height: | Size: 7.1 KiB |
Before Width: | Height: | Size: 509 B After Width: | Height: | Size: 509 B |
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 981 B After Width: | Height: | Size: 981 B |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
|
@ -1,18 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!-- Generator: Adobe Illustrator 25.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
|
||||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px"
|
|
||||||
viewBox="0 0 29.2 33" style="enable-background:new 0 0 29.2 33;" xml:space="preserve">
|
|
||||||
<style type="text/css">
|
|
||||||
.st0{fill:#F68D2E;}
|
|
||||||
</style>
|
|
||||||
<path class="st0" d="M27.2,18.5c-1.5-0.9-3.3-0.8-4.7,0.2c-0.3,0.2-0.6,0.2-0.9,0l-4.2-2.4c-0.1,0-0.1-0.1,0-0.1c0,0,0,0,0,0
|
|
||||||
l4.2-2.4c0.3-0.2,0.7-0.1,0.9,0.1c1.4,1,3.2,1.1,4.7,0.2c1.9-1.2,2.6-3.7,1.5-5.7c-1.1-2.1-3.7-2.8-5.8-1.7
|
|
||||||
c-1.5,0.8-2.4,2.4-2.2,4.1c0,0.3-0.1,0.7-0.4,0.8L16,13.9c-0.1,0-0.1,0-0.1,0c0,0,0,0,0-0.1V8.9c0-0.3,0.2-0.6,0.5-0.8
|
|
||||||
c2.1-1,3.1-3.5,2.1-5.7S15-0.6,12.8,0.4S9.7,3.9,10.7,6c0.4,0.9,1.2,1.7,2.1,2.1c0.3,0.1,0.5,0.4,0.5,0.8v4.9c0,0.1,0,0.1-0.1,0.1
|
|
||||||
c0,0,0,0-0.1,0l-4.2-2.4c-0.3-0.2-0.5-0.5-0.4-0.8C8.7,8.3,7,6.2,4.6,6S0.2,7.6,0,9.9s1.5,4.4,3.9,4.6c1,0.1,2-0.2,2.9-0.8
|
|
||||||
c0.3-0.2,0.6-0.2,0.9-0.1l4.2,2.4c0.1,0,0.1,0.1,0,0.1c0,0,0,0,0,0l-4.2,2.4c-0.3,0.2-0.7,0.1-0.9,0c-1.4-1-3.2-1-4.7-0.2
|
|
||||||
c-1.9,1.2-2.6,3.7-1.5,5.7c1.1,2.1,3.7,2.8,5.8,1.7c1.5-0.8,2.4-2.4,2.2-4.1c0-0.3,0.1-0.7,0.4-0.8l4.2-2.4c0.1,0,0.1,0,0.1,0
|
|
||||||
c0,0,0,0,0,0.1v4.9c0,0.3-0.2,0.6-0.5,0.8c-2.1,1-3.1,3.5-2.1,5.7s3.5,3.1,5.7,2.1c2.1-1,3.1-3.5,2.1-5.7c-0.4-0.9-1.2-1.7-2.1-2.1
|
|
||||||
c-0.3-0.1-0.5-0.4-0.5-0.8v-4.9c0-0.1,0-0.1,0.1-0.1c0,0,0,0,0.1,0l4.2,2.4c0.3,0.2,0.5,0.5,0.4,0.8c-0.2,2.3,1.5,4.4,3.9,4.6
|
|
||||||
c1.7,0.2,3.3-0.7,4.1-2.2C29.8,22.2,29.1,19.7,27.2,18.5L27.2,18.5z"/>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 1.5 KiB |
|
@ -594,6 +594,9 @@
|
||||||
"confirm_delete_account": "Yes, delete account",
|
"confirm_delete_account": "Yes, delete account",
|
||||||
"delete_account_confirmation_message": "Are you sure you want to delete your Cal.com account? Anyone who you've shared your account link with will no longer be able to book using it and any preferences you have saved will be lost.",
|
"delete_account_confirmation_message": "Are you sure you want to delete your Cal.com account? Anyone who you've shared your account link with will no longer be able to book using it and any preferences you have saved will be lost.",
|
||||||
"integrations": "Integrations",
|
"integrations": "Integrations",
|
||||||
|
"apps": "Apps",
|
||||||
|
"app_store": "App Store",
|
||||||
|
"app_store_description": "Connecting people, technology and the workplace.",
|
||||||
"settings": "Settings",
|
"settings": "Settings",
|
||||||
"event_type_moved_successfully": "Event type has been moved successfully",
|
"event_type_moved_successfully": "Event type has been moved successfully",
|
||||||
"next_step": "Skip step",
|
"next_step": "Skip step",
|
||||||
|
@ -641,6 +644,24 @@
|
||||||
"import_from": "Import from",
|
"import_from": "Import from",
|
||||||
"access_token": "Access token",
|
"access_token": "Access token",
|
||||||
"visit_roadmap": "Roadmap",
|
"visit_roadmap": "Roadmap",
|
||||||
|
"popular_categories": "Popular Categories",
|
||||||
|
"trending_apps": "Trending Apps",
|
||||||
|
"all_apps": "All Apps",
|
||||||
|
"installed_apps": "Installed Apps",
|
||||||
|
"manage_your_connected_apps": "Manage your connected apps",
|
||||||
|
"browse_apps": "Browse Apps",
|
||||||
|
"features": "Features",
|
||||||
|
"permissions": "Permissions",
|
||||||
|
"terms_and_privacy": "Terms and Privacy",
|
||||||
|
"build_by": "Build by {{author}}",
|
||||||
|
"subscribe": "Subscribe",
|
||||||
|
"buy": "Buy",
|
||||||
|
"install_app": "Install App",
|
||||||
|
"categories": "Categories",
|
||||||
|
"pricing": "Pricing",
|
||||||
|
"learn_more": "Learn more",
|
||||||
|
"privacy_policy": "Privacy Policy",
|
||||||
|
"terms_of_service": "Terms of Service",
|
||||||
"remove": "Remove",
|
"remove": "Remove",
|
||||||
"add": "Add",
|
"add": "Add",
|
||||||
"verify_wallet": "Verify Wallet",
|
"verify_wallet": "Verify Wallet",
|
||||||
|
|
|
@ -5,9 +5,8 @@ import { z } from "zod";
|
||||||
|
|
||||||
import { checkPremiumUsername } from "@ee/lib/core/checkPremiumUsername";
|
import { checkPremiumUsername } from "@ee/lib/core/checkPremiumUsername";
|
||||||
|
|
||||||
|
import { ALL_APPS } from "@lib/apps/utils/AppUtils";
|
||||||
import { checkRegularUsername } from "@lib/core/checkRegularUsername";
|
import { checkRegularUsername } from "@lib/core/checkRegularUsername";
|
||||||
import { getCalendarCredentials, getConnectedCalendars } from "@lib/integrations/calendar/CalendarManager";
|
|
||||||
import { ALL_INTEGRATIONS } from "@lib/integrations/getIntegrations";
|
|
||||||
import jackson from "@lib/jackson";
|
import jackson from "@lib/jackson";
|
||||||
import {
|
import {
|
||||||
isSAMLLoginEnabled,
|
isSAMLLoginEnabled,
|
||||||
|
@ -24,6 +23,10 @@ import { Schedule } from "@lib/types/schedule";
|
||||||
import { eventTypesRouter } from "@server/routers/viewer/eventTypes";
|
import { eventTypesRouter } from "@server/routers/viewer/eventTypes";
|
||||||
import { TRPCError } from "@trpc/server";
|
import { TRPCError } from "@trpc/server";
|
||||||
|
|
||||||
|
import {
|
||||||
|
getCalendarCredentials,
|
||||||
|
getConnectedCalendars,
|
||||||
|
} from "../../lib/apps/calendar/managers/CalendarManager";
|
||||||
import { createProtectedRouter, createRouter } from "../createRouter";
|
import { createProtectedRouter, createRouter } from "../createRouter";
|
||||||
import { resizeBase64Image } from "../lib/resizeBase64Image";
|
import { resizeBase64Image } from "../lib/resizeBase64Image";
|
||||||
import { viewerTeamsRouter } from "./viewer/teams";
|
import { viewerTeamsRouter } from "./viewer/teams";
|
||||||
|
@ -511,16 +514,16 @@ const loggedInViewerRouter = createProtectedRouter()
|
||||||
function countActive(items: { credentialIds: unknown[] }[]) {
|
function countActive(items: { credentialIds: unknown[] }[]) {
|
||||||
return items.reduce((acc, item) => acc + item.credentialIds.length, 0);
|
return items.reduce((acc, item) => acc + item.credentialIds.length, 0);
|
||||||
}
|
}
|
||||||
const integrations = ALL_INTEGRATIONS.map((integration) => ({
|
const apps = ALL_APPS.map((app) => ({
|
||||||
...integration,
|
...app,
|
||||||
credentialIds: credentials
|
credentialIds: credentials
|
||||||
.filter((credential) => credential.type === integration.type)
|
.filter((credential) => credential.type === app.type)
|
||||||
.map((credential) => credential.id),
|
.map((credential) => credential.id),
|
||||||
}));
|
}));
|
||||||
// `flatMap()` these work like `.filter()` but infers the types correctly
|
// `flatMap()` these work like `.filter()` but infers the types correctly
|
||||||
const conferencing = integrations.flatMap((item) => (item.variant === "conferencing" ? [item] : []));
|
const conferencing = apps.flatMap((item) => (item.variant === "conferencing" ? [item] : []));
|
||||||
const payment = integrations.flatMap((item) => (item.variant === "payment" ? [item] : []));
|
const payment = apps.flatMap((item) => (item.variant === "payment" ? [item] : []));
|
||||||
const calendar = integrations.flatMap((item) => (item.variant === "calendar" ? [item] : []));
|
const calendar = apps.flatMap((item) => (item.variant === "calendar" ? [item] : []));
|
||||||
|
|
||||||
return {
|
return {
|
||||||
conferencing: {
|
conferencing: {
|
||||||
|
|
|
@ -114,5 +114,5 @@
|
||||||
|
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: "Cal Sans";
|
font-family: "Cal Sans";
|
||||||
src: url("/cal.ttf");
|
src: url("/CalSans-SemiBold.woff2");
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,9 @@
|
||||||
@tailwind components;
|
@tailwind components;
|
||||||
@tailwind utilities;
|
@tailwind utilities;
|
||||||
|
|
||||||
|
@import "../node_modules/@glidejs/glide/dist/css/glide.core.min.css";
|
||||||
|
@import "../node_modules/@glidejs/glide/dist/css/glide.theme.min.css";
|
||||||
|
|
||||||
:root {
|
:root {
|
||||||
--brand-color: #292929;
|
--brand-color: #292929;
|
||||||
--brand-text-color: #ffffff;
|
--brand-text-color: #ffffff;
|
||||||
|
|
|
@ -131,5 +131,5 @@ module.exports = {
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
plugins: [require("@tailwindcss/forms")],
|
plugins: [require("@tailwindcss/forms"), require("@tailwindcss/typography")],
|
||||||
};
|
};
|
||||||
|
|
1897
apps/web/yarn.lock
|
@ -0,0 +1,796 @@
|
||||||
|
diff a/apps/web/yarn.lock b/apps/web/yarn.lock (rejected hunks)
|
||||||
|
@@ -94,187 +73,132 @@
|
||||||
|
jsesc "^2.5.1"
|
||||||
|
source-map "^0.5.0"
|
||||||
|
|
||||||
|
-"@babel/generator@^7.13.0", "@babel/generator@^7.13.9", "@babel/generator@^7.16.0":
|
||||||
|
- version "7.16.0"
|
||||||
|
- resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.16.0.tgz#d40f3d1d5075e62d3500bccb67f3daa8a95265b2"
|
||||||
|
- integrity sha512-RR8hUCfRQn9j9RPKEVXo9LiwoxLPYn6hNZlvUOR8tSnaxlD0p0+la00ZP9/SnRt6HchKr+X0fO2r8vrETiJGew==
|
||||||
|
+"@babel/generator@^7.13.0", "@babel/generator@^7.13.9", "@babel/generator@^7.16.8":
|
||||||
|
+ version "7.16.8"
|
||||||
|
+ resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.16.8.tgz#359d44d966b8cd059d543250ce79596f792f2ebe"
|
||||||
|
+ integrity sha512-1ojZwE9+lOXzcWdWmO6TbUzDfqLD39CmEhN8+2cX9XkDo5yW1OpgfejfliysR2AWLpMamTiOiAp/mtroaymhpw==
|
||||||
|
dependencies:
|
||||||
|
- "@babel/types" "^7.16.0"
|
||||||
|
+ "@babel/types" "^7.16.8"
|
||||||
|
jsesc "^2.5.1"
|
||||||
|
source-map "^0.5.0"
|
||||||
|
|
||||||
|
-"@babel/generator@^7.16.5":
|
||||||
|
- version "7.16.5"
|
||||||
|
- resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.16.5.tgz#26e1192eb8f78e0a3acaf3eede3c6fc96d22bedf"
|
||||||
|
- integrity sha512-kIvCdjZqcdKqoDbVVdt5R99icaRtrtYhYK/xux5qiWCBmfdvEYMFZ68QCrpE5cbFM1JsuArUNs1ZkuKtTtUcZA==
|
||||||
|
- dependencies:
|
||||||
|
- "@babel/types" "^7.16.0"
|
||||||
|
- jsesc "^2.5.1"
|
||||||
|
- source-map "^0.5.0"
|
||||||
|
-
|
||||||
|
-"@babel/helper-annotate-as-pure@^7.16.0":
|
||||||
|
- version "7.16.0"
|
||||||
|
- resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.16.0.tgz#9a1f0ebcda53d9a2d00108c4ceace6a5d5f1f08d"
|
||||||
|
- integrity sha512-ItmYF9vR4zA8cByDocY05o0LGUkp1zhbTQOH1NFyl5xXEqlTJQCEJjieriw+aFpxo16swMxUnUiKS7a/r4vtHg==
|
||||||
|
- dependencies:
|
||||||
|
- "@babel/types" "^7.16.0"
|
||||||
|
-
|
||||||
|
-"@babel/helper-compilation-targets@^7.13.10", "@babel/helper-compilation-targets@^7.16.0":
|
||||||
|
- version "7.16.0"
|
||||||
|
- resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.16.0.tgz#01d615762e796c17952c29e3ede9d6de07d235a8"
|
||||||
|
- integrity sha512-S7iaOT1SYlqK0sQaCi21RX4+13hmdmnxIEAnQUB/eh7GeAnRjOUgTYpLkUOiRXzD+yog1JxP0qyAQZ7ZxVxLVg==
|
||||||
|
+"@babel/helper-annotate-as-pure@^7.16.7":
|
||||||
|
+ version "7.16.7"
|
||||||
|
+ resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.16.7.tgz#bb2339a7534a9c128e3102024c60760a3a7f3862"
|
||||||
|
+ integrity sha512-s6t2w/IPQVTAET1HitoowRGXooX8mCgtuP5195wD/QJPV6wYjpujCGF7JuMODVX2ZAJOf1GT6DT9MHEZvLOFSw==
|
||||||
|
dependencies:
|
||||||
|
- "@babel/compat-data" "^7.16.0"
|
||||||
|
- "@babel/helper-validator-option" "^7.14.5"
|
||||||
|
- browserslist "^4.16.6"
|
||||||
|
- semver "^6.3.0"
|
||||||
|
+ "@babel/types" "^7.16.7"
|
||||||
|
|
||||||
|
-"@babel/helper-compilation-targets@^7.16.3":
|
||||||
|
- version "7.16.3"
|
||||||
|
- resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.16.3.tgz#5b480cd13f68363df6ec4dc8ac8e2da11363cbf0"
|
||||||
|
- integrity sha512-vKsoSQAyBmxS35JUOOt+07cLc6Nk/2ljLIHwmq2/NM6hdioUaqEXq/S+nXvbvXbZkNDlWOymPanJGOc4CBjSJA==
|
||||||
|
+"@babel/helper-compilation-targets@^7.13.10", "@babel/helper-compilation-targets@^7.16.7":
|
||||||
|
+ version "7.16.7"
|
||||||
|
+ resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.16.7.tgz#06e66c5f299601e6c7da350049315e83209d551b"
|
||||||
|
+ integrity sha512-mGojBwIWcwGD6rfqgRXVlVYmPAv7eOpIemUG3dGnDdCY4Pae70ROij3XmfrH6Fa1h1aiDylpglbZyktfzyo/hA==
|
||||||
|
dependencies:
|
||||||
|
- "@babel/compat-data" "^7.16.0"
|
||||||
|
- "@babel/helper-validator-option" "^7.14.5"
|
||||||
|
+ "@babel/compat-data" "^7.16.4"
|
||||||
|
+ "@babel/helper-validator-option" "^7.16.7"
|
||||||
|
browserslist "^4.17.5"
|
||||||
|
semver "^6.3.0"
|
||||||
|
|
||||||
|
-"@babel/helper-create-class-features-plugin@^7.16.0", "@babel/helper-create-class-features-plugin@^7.16.5":
|
||||||
|
- version "7.16.5"
|
||||||
|
- resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.16.5.tgz#5d1bcd096792c1ebec6249eebc6358eec55d0cad"
|
||||||
|
- integrity sha512-NEohnYA7mkB8L5JhU7BLwcBdU3j83IziR9aseMueWGeAjblbul3zzb8UvJ3a1zuBiqCMObzCJHFqKIQE6hTVmg==
|
||||||
|
+"@babel/helper-create-class-features-plugin@^7.16.10", "@babel/helper-create-class-features-plugin@^7.16.7":
|
||||||
|
+ version "7.16.10"
|
||||||
|
+ resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.16.10.tgz#8a6959b9cc818a88815ba3c5474619e9c0f2c21c"
|
||||||
|
+ integrity sha512-wDeej0pu3WN/ffTxMNCPW5UCiOav8IcLRxSIyp/9+IF2xJUM9h/OYjg0IJLHaL6F8oU8kqMz9nc1vryXhMsgXg==
|
||||||
|
dependencies:
|
||||||
|
- "@babel/helper-annotate-as-pure" "^7.16.0"
|
||||||
|
- "@babel/helper-environment-visitor" "^7.16.5"
|
||||||
|
- "@babel/helper-function-name" "^7.16.0"
|
||||||
|
- "@babel/helper-member-expression-to-functions" "^7.16.5"
|
||||||
|
- "@babel/helper-optimise-call-expression" "^7.16.0"
|
||||||
|
- "@babel/helper-replace-supers" "^7.16.5"
|
||||||
|
- "@babel/helper-split-export-declaration" "^7.16.0"
|
||||||
|
+ "@babel/helper-annotate-as-pure" "^7.16.7"
|
||||||
|
+ "@babel/helper-environment-visitor" "^7.16.7"
|
||||||
|
+ "@babel/helper-function-name" "^7.16.7"
|
||||||
|
+ "@babel/helper-member-expression-to-functions" "^7.16.7"
|
||||||
|
+ "@babel/helper-optimise-call-expression" "^7.16.7"
|
||||||
|
+ "@babel/helper-replace-supers" "^7.16.7"
|
||||||
|
+ "@babel/helper-split-export-declaration" "^7.16.7"
|
||||||
|
|
||||||
|
-"@babel/helper-environment-visitor@^7.16.5":
|
||||||
|
- version "7.16.5"
|
||||||
|
- resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.5.tgz#f6a7f38b3c6d8b07c88faea083c46c09ef5451b8"
|
||||||
|
- integrity sha512-ODQyc5AnxmZWm/R2W7fzhamOk1ey8gSguo5SGvF0zcB3uUzRpTRmM/jmLSm9bDMyPlvbyJ+PwPEK0BWIoZ9wjg==
|
||||||
|
- dependencies:
|
||||||
|
- "@babel/types" "^7.16.0"
|
||||||
|
-
|
||||||
|
-"@babel/helper-function-name@^7.12.13", "@babel/helper-function-name@^7.16.0":
|
||||||
|
- version "7.16.0"
|
||||||
|
- resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.16.0.tgz#b7dd0797d00bbfee4f07e9c4ea5b0e30c8bb1481"
|
||||||
|
- integrity sha512-BZh4mEk1xi2h4HFjWUXRQX5AEx4rvaZxHgax9gcjdLWdkjsY7MKt5p0otjsg5noXw+pB+clMCjw+aEVYADMjog==
|
||||||
|
+"@babel/helper-environment-visitor@^7.16.7":
|
||||||
|
+ version "7.16.7"
|
||||||
|
+ resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.7.tgz#ff484094a839bde9d89cd63cba017d7aae80ecd7"
|
||||||
|
+ integrity sha512-SLLb0AAn6PkUeAfKJCCOl9e1R53pQlGAfc4y4XuMRZfqeMYLE0dM1LMhqbGAlGQY0lfw5/ohoYWAe9V1yibRag==
|
||||||
|
dependencies:
|
||||||
|
- "@babel/helper-get-function-arity" "^7.16.0"
|
||||||
|
- "@babel/template" "^7.16.0"
|
||||||
|
- "@babel/types" "^7.16.0"
|
||||||
|
+ "@babel/types" "^7.16.7"
|
||||||
|
|
||||||
|
-"@babel/helper-get-function-arity@^7.16.0":
|
||||||
|
- version "7.16.0"
|
||||||
|
- resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.0.tgz#0088c7486b29a9cb5d948b1a1de46db66e089cfa"
|
||||||
|
- integrity sha512-ASCquNcywC1NkYh/z7Cgp3w31YW8aojjYIlNg4VeJiHkqyP4AzIvr4qx7pYDb4/s8YcsZWqqOSxgkvjUz1kpDQ==
|
||||||
|
+"@babel/helper-function-name@^7.12.13", "@babel/helper-function-name@^7.16.7":
|
||||||
|
+ version "7.16.7"
|
||||||
|
+ resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.16.7.tgz#f1ec51551fb1c8956bc8dd95f38523b6cf375f8f"
|
||||||
|
+ integrity sha512-QfDfEnIUyyBSR3HtrtGECuZ6DAyCkYFp7GHl75vFtTnn6pjKeK0T1DB5lLkFvBea8MdaiUABx3osbgLyInoejA==
|
||||||
|
dependencies:
|
||||||
|
- "@babel/types" "^7.16.0"
|
||||||
|
+ "@babel/helper-get-function-arity" "^7.16.7"
|
||||||
|
+ "@babel/template" "^7.16.7"
|
||||||
|
+ "@babel/types" "^7.16.7"
|
||||||
|
|
||||||
|
-"@babel/helper-hoist-variables@^7.16.0":
|
||||||
|
- version "7.16.0"
|
||||||
|
- resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.0.tgz#4c9023c2f1def7e28ff46fc1dbcd36a39beaa81a"
|
||||||
|
- integrity sha512-1AZlpazjUR0EQZQv3sgRNfM9mEVWPK3M6vlalczA+EECcPz3XPh6VplbErL5UoMpChhSck5wAJHthlj1bYpcmg==
|
||||||
|
+"@babel/helper-get-function-arity@^7.16.7":
|
||||||
|
+ version "7.16.7"
|
||||||
|
+ resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.7.tgz#ea08ac753117a669f1508ba06ebcc49156387419"
|
||||||
|
+ integrity sha512-flc+RLSOBXzNzVhcLu6ujeHUrD6tANAOU5ojrRx/as+tbzf8+stUCj7+IfRRoAbEZqj/ahXEMsjhOhgeZsrnTw==
|
||||||
|
dependencies:
|
||||||
|
- "@babel/types" "^7.16.0"
|
||||||
|
+ "@babel/types" "^7.16.7"
|
||||||
|
|
||||||
|
-"@babel/helper-member-expression-to-functions@^7.16.0":
|
||||||
|
- version "7.16.0"
|
||||||
|
- resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.16.0.tgz#29287040efd197c77636ef75188e81da8bccd5a4"
|
||||||
|
- integrity sha512-bsjlBFPuWT6IWhl28EdrQ+gTvSvj5tqVP5Xeftp07SEuz5pLnsXZuDkDD3Rfcxy0IsHmbZ+7B2/9SHzxO0T+sQ==
|
||||||
|
+"@babel/helper-hoist-variables@^7.16.7":
|
||||||
|
+ version "7.16.7"
|
||||||
|
+ resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.7.tgz#86bcb19a77a509c7b77d0e22323ef588fa58c246"
|
||||||
|
+ integrity sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg==
|
||||||
|
dependencies:
|
||||||
|
- "@babel/types" "^7.16.0"
|
||||||
|
+ "@babel/types" "^7.16.7"
|
||||||
|
|
||||||
|
-"@babel/helper-member-expression-to-functions@^7.16.5":
|
||||||
|
- version "7.16.5"
|
||||||
|
- resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.16.5.tgz#1bc9f7e87354e86f8879c67b316cb03d3dc2caab"
|
||||||
|
- integrity sha512-7fecSXq7ZrLE+TWshbGT+HyCLkxloWNhTbU2QM1NTI/tDqyf0oZiMcEfYtDuUDCo528EOlt39G1rftea4bRZIw==
|
||||||
|
+"@babel/helper-member-expression-to-functions@^7.16.7":
|
||||||
|
+ version "7.16.7"
|
||||||
|
+ resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.16.7.tgz#42b9ca4b2b200123c3b7e726b0ae5153924905b0"
|
||||||
|
+ integrity sha512-VtJ/65tYiU/6AbMTDwyoXGPKHgTsfRarivm+YbB5uAzKUyuPjgZSgAFeG87FCigc7KNHu2Pegh1XIT3lXjvz3Q==
|
||||||
|
dependencies:
|
||||||
|
- "@babel/types" "^7.16.0"
|
||||||
|
+ "@babel/types" "^7.16.7"
|
||||||
|
|
||||||
|
-"@babel/helper-module-imports@^7.16.0":
|
||||||
|
- version "7.16.0"
|
||||||
|
- resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.16.0.tgz#90538e60b672ecf1b448f5f4f5433d37e79a3ec3"
|
||||||
|
- integrity sha512-kkH7sWzKPq0xt3H1n+ghb4xEMP8k0U7XV3kkB+ZGy69kDk2ySFW1qPi06sjKzFY3t1j6XbJSqr4mF9L7CYVyhg==
|
||||||
|
+"@babel/helper-module-imports@^7.16.7":
|
||||||
|
+ version "7.16.7"
|
||||||
|
+ resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz#25612a8091a999704461c8a222d0efec5d091437"
|
||||||
|
+ integrity sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg==
|
||||||
|
dependencies:
|
||||||
|
- "@babel/types" "^7.16.0"
|
||||||
|
-
|
||||||
|
-"@babel/helper-module-transforms@^7.13.0", "@babel/helper-module-transforms@^7.16.0":
|
||||||
|
- version "7.16.0"
|
||||||
|
- resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.16.0.tgz#1c82a8dd4cb34577502ebd2909699b194c3e9bb5"
|
||||||
|
- integrity sha512-My4cr9ATcaBbmaEa8M0dZNA74cfI6gitvUAskgDtAFmAqyFKDSHQo5YstxPbN+lzHl2D9l/YOEFqb2mtUh4gfA==
|
||||||
|
- dependencies:
|
||||||
|
- "@babel/helper-module-imports" "^7.16.0"
|
||||||
|
- "@babel/helper-replace-supers" "^7.16.0"
|
||||||
|
- "@babel/helper-simple-access" "^7.16.0"
|
||||||
|
- "@babel/helper-split-export-declaration" "^7.16.0"
|
||||||
|
- "@babel/helper-validator-identifier" "^7.15.7"
|
||||||
|
- "@babel/template" "^7.16.0"
|
||||||
|
- "@babel/traverse" "^7.16.0"
|
||||||
|
- "@babel/types" "^7.16.0"
|
||||||
|
-
|
||||||
|
-"@babel/helper-module-transforms@^7.16.5":
|
||||||
|
- version "7.16.5"
|
||||||
|
- resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.16.5.tgz#530ebf6ea87b500f60840578515adda2af470a29"
|
||||||
|
- integrity sha512-CkvMxgV4ZyyioElFwcuWnDCcNIeyqTkCm9BxXZi73RR1ozqlpboqsbGUNvRTflgZtFbbJ1v5Emvm+lkjMYY/LQ==
|
||||||
|
- dependencies:
|
||||||
|
- "@babel/helper-environment-visitor" "^7.16.5"
|
||||||
|
- "@babel/helper-module-imports" "^7.16.0"
|
||||||
|
- "@babel/helper-simple-access" "^7.16.0"
|
||||||
|
- "@babel/helper-split-export-declaration" "^7.16.0"
|
||||||
|
- "@babel/helper-validator-identifier" "^7.15.7"
|
||||||
|
- "@babel/template" "^7.16.0"
|
||||||
|
- "@babel/traverse" "^7.16.5"
|
||||||
|
- "@babel/types" "^7.16.0"
|
||||||
|
+ "@babel/types" "^7.16.7"
|
||||||
|
|
||||||
|
-"@babel/helper-optimise-call-expression@^7.16.0":
|
||||||
|
- version "7.16.0"
|
||||||
|
- resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.16.0.tgz#cecdb145d70c54096b1564f8e9f10cd7d193b338"
|
||||||
|
- integrity sha512-SuI467Gi2V8fkofm2JPnZzB/SUuXoJA5zXe/xzyPP2M04686RzFKFHPK6HDVN6JvWBIEW8tt9hPR7fXdn2Lgpw==
|
||||||
|
+"@babel/helper-module-transforms@^7.13.0", "@babel/helper-module-transforms@^7.16.7":
|
||||||
|
+ version "7.16.7"
|
||||||
|
+ resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.16.7.tgz#7665faeb721a01ca5327ddc6bba15a5cb34b6a41"
|
||||||
|
+ integrity sha512-gaqtLDxJEFCeQbYp9aLAefjhkKdjKcdh6DB7jniIGU3Pz52WAmP268zK0VgPz9hUNkMSYeH976K2/Y6yPadpng==
|
||||||
|
+ dependencies:
|
||||||
|
+ "@babel/helper-environment-visitor" "^7.16.7"
|
||||||
|
+ "@babel/helper-module-imports" "^7.16.7"
|
||||||
|
+ "@babel/helper-simple-access" "^7.16.7"
|
||||||
|
+ "@babel/helper-split-export-declaration" "^7.16.7"
|
||||||
|
+ "@babel/helper-validator-identifier" "^7.16.7"
|
||||||
|
+ "@babel/template" "^7.16.7"
|
||||||
|
+ "@babel/traverse" "^7.16.7"
|
||||||
|
+ "@babel/types" "^7.16.7"
|
||||||
|
+
|
||||||
|
+"@babel/helper-optimise-call-expression@^7.16.7":
|
||||||
|
+ version "7.16.7"
|
||||||
|
+ resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.16.7.tgz#a34e3560605abbd31a18546bd2aad3e6d9a174f2"
|
||||||
|
+ integrity sha512-EtgBhg7rd/JcnpZFXpBy0ze1YRfdm7BnBX4uKMBd3ixa3RGAE002JZB66FJyNH7g0F38U05pXmA5P8cBh7z+1w==
|
||||||
|
dependencies:
|
||||||
|
- "@babel/types" "^7.16.0"
|
||||||
|
+ "@babel/types" "^7.16.7"
|
||||||
|
|
||||||
|
-"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.8.0":
|
||||||
|
- version "7.14.5"
|
||||||
|
- resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.14.5.tgz#5ac822ce97eec46741ab70a517971e443a70c5a9"
|
||||||
|
- integrity sha512-/37qQCE3K0vvZKwoK4XU/irIJQdIfCJuhU5eKnNxpFDsOkgFaUAwbv+RYw6eYgsC0E4hS7r5KqGULUogqui0fQ==
|
||||||
|
-
|
||||||
|
-"@babel/helper-plugin-utils@^7.16.5", "@babel/helper-plugin-utils@^7.8.3":
|
||||||
|
- version "7.16.5"
|
||||||
|
- resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.5.tgz#afe37a45f39fce44a3d50a7958129ea5b1a5c074"
|
||||||
|
- integrity sha512-59KHWHXxVA9K4HNF4sbHCf+eJeFe0Te/ZFGqBT4OjXhrwvA04sGfaEGsVTdsjoszq0YTP49RC9UKe5g8uN2RwQ==
|
||||||
|
-
|
||||||
|
-"@babel/helper-replace-supers@^7.16.0":
|
||||||
|
- version "7.16.0"
|
||||||
|
- resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.16.0.tgz#73055e8d3cf9bcba8ddb55cad93fedc860f68f17"
|
||||||
|
- integrity sha512-TQxuQfSCdoha7cpRNJvfaYxxxzmbxXw/+6cS7V02eeDYyhxderSoMVALvwupA54/pZcOTtVeJ0xccp1nGWladA==
|
||||||
|
- dependencies:
|
||||||
|
- "@babel/helper-member-expression-to-functions" "^7.16.0"
|
||||||
|
- "@babel/helper-optimise-call-expression" "^7.16.0"
|
||||||
|
- "@babel/traverse" "^7.16.0"
|
||||||
|
- "@babel/types" "^7.16.0"
|
||||||
|
+"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.16.7", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3":
|
||||||
|
+ version "7.16.7"
|
||||||
|
+ resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.7.tgz#aa3a8ab4c3cceff8e65eb9e73d87dc4ff320b2f5"
|
||||||
|
+ integrity sha512-Qg3Nk7ZxpgMrsox6HreY1ZNKdBq7K72tDSliA6dCl5f007jR4ne8iD5UzuNnCJH2xBf2BEEVGr+/OL6Gdp7RxA==
|
||||||
|
|
||||||
|
-"@babel/helper-replace-supers@^7.16.5":
|
||||||
|
- version "7.16.5"
|
||||||
|
- resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.16.5.tgz#96d3988bd0ab0a2d22c88c6198c3d3234ca25326"
|
||||||
|
- integrity sha512-ao3seGVa/FZCMCCNDuBcqnBFSbdr8N2EW35mzojx3TwfIbdPmNK+JV6+2d5bR0Z71W5ocLnQp9en/cTF7pBJiQ==
|
||||||
|
+"@babel/helper-replace-supers@^7.16.7":
|
||||||
|
+ version "7.16.7"
|
||||||
|
+ resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.16.7.tgz#e9f5f5f32ac90429c1a4bdec0f231ef0c2838ab1"
|
||||||
|
+ integrity sha512-y9vsWilTNaVnVh6xiJfABzsNpgDPKev9HnAgz6Gb1p6UUwf9NepdlsV7VXGCftJM+jqD5f7JIEubcpLjZj5dBw==
|
||||||
|
dependencies:
|
||||||
|
- "@babel/helper-environment-visitor" "^7.16.5"
|
||||||
|
- "@babel/helper-member-expression-to-functions" "^7.16.5"
|
||||||
|
- "@babel/helper-optimise-call-expression" "^7.16.0"
|
||||||
|
- "@babel/traverse" "^7.16.5"
|
||||||
|
- "@babel/types" "^7.16.0"
|
||||||
|
+ "@babel/helper-environment-visitor" "^7.16.7"
|
||||||
|
+ "@babel/helper-member-expression-to-functions" "^7.16.7"
|
||||||
|
+ "@babel/helper-optimise-call-expression" "^7.16.7"
|
||||||
|
+ "@babel/traverse" "^7.16.7"
|
||||||
|
+ "@babel/types" "^7.16.7"
|
||||||
|
|
||||||
|
-"@babel/helper-simple-access@^7.16.0":
|
||||||
|
- version "7.16.0"
|
||||||
|
- resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.16.0.tgz#21d6a27620e383e37534cf6c10bba019a6f90517"
|
||||||
|
- integrity sha512-o1rjBT/gppAqKsYfUdfHq5Rk03lMQrkPHG1OWzHWpLgVXRH4HnMM9Et9CVdIqwkCQlobnGHEJMsgWP/jE1zUiw==
|
||||||
|
+"@babel/helper-simple-access@^7.16.7":
|
||||||
|
+ version "7.16.7"
|
||||||
|
+ resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.16.7.tgz#d656654b9ea08dbb9659b69d61063ccd343ff0f7"
|
||||||
|
+ integrity sha512-ZIzHVyoeLMvXMN/vok/a4LWRy8G2v205mNP0XOuf9XRLyX5/u9CnVulUtDgUTama3lT+bf/UqucuZjqiGuTS1g==
|
||||||
|
dependencies:
|
||||||
|
- "@babel/types" "^7.16.0"
|
||||||
|
+ "@babel/types" "^7.16.7"
|
||||||
|
|
||||||
|
"@babel/helper-skip-transparent-expression-wrappers@^7.16.0":
|
||||||
|
version "7.16.0"
|
||||||
|
@@ -283,47 +207,38 @@
|
||||||
|
dependencies:
|
||||||
|
"@babel/types" "^7.16.0"
|
||||||
|
|
||||||
|
-"@babel/helper-split-export-declaration@^7.12.13", "@babel/helper-split-export-declaration@^7.16.0":
|
||||||
|
- version "7.16.0"
|
||||||
|
- resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.0.tgz#29672f43663e936df370aaeb22beddb3baec7438"
|
||||||
|
- integrity sha512-0YMMRpuDFNGTHNRiiqJX19GjNXA4H0E8jZ2ibccfSxaCogbm3am5WN/2nQNj0YnQwGWM1J06GOcQ2qnh3+0paw==
|
||||||
|
+"@babel/helper-split-export-declaration@^7.12.13", "@babel/helper-split-export-declaration@^7.16.7":
|
||||||
|
+ version "7.16.7"
|
||||||
|
+ resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz#0b648c0c42da9d3920d85ad585f2778620b8726b"
|
||||||
|
+ integrity sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw==
|
||||||
|
dependencies:
|
||||||
|
- "@babel/types" "^7.16.0"
|
||||||
|
-
|
||||||
|
-"@babel/helper-validator-identifier@^7.12.11", "@babel/helper-validator-identifier@^7.15.7":
|
||||||
|
- version "7.15.7"
|
||||||
|
- resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz#220df993bfe904a4a6b02ab4f3385a5ebf6e2389"
|
||||||
|
- integrity sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w==
|
||||||
|
+ "@babel/types" "^7.16.7"
|
||||||
|
|
||||||
|
-"@babel/helper-validator-option@^7.14.5":
|
||||||
|
- version "7.14.5"
|
||||||
|
- resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz#6e72a1fff18d5dfcb878e1e62f1a021c4b72d5a3"
|
||||||
|
- integrity sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow==
|
||||||
|
+"@babel/helper-validator-identifier@^7.12.11", "@babel/helper-validator-identifier@^7.16.7":
|
||||||
|
+ version "7.16.7"
|
||||||
|
+ resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz#e8c602438c4a8195751243da9031d1607d247cad"
|
||||||
|
+ integrity sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==
|
||||||
|
|
||||||
|
-"@babel/helpers@^7.13.10", "@babel/helpers@^7.16.0":
|
||||||
|
- version "7.16.0"
|
||||||
|
- resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.16.0.tgz#875519c979c232f41adfbd43a3b0398c2e388183"
|
||||||
|
- integrity sha512-dVRM0StFMdKlkt7cVcGgwD8UMaBfWJHl3A83Yfs8GQ3MO0LHIIIMvK7Fa0RGOGUQ10qikLaX6D7o5htcQWgTMQ==
|
||||||
|
- dependencies:
|
||||||
|
- "@babel/template" "^7.16.0"
|
||||||
|
- "@babel/traverse" "^7.16.0"
|
||||||
|
- "@babel/types" "^7.16.0"
|
||||||
|
+"@babel/helper-validator-option@^7.16.7":
|
||||||
|
+ version "7.16.7"
|
||||||
|
+ resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz#b203ce62ce5fe153899b617c08957de860de4d23"
|
||||||
|
+ integrity sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ==
|
||||||
|
|
||||||
|
-"@babel/helpers@^7.16.5":
|
||||||
|
- version "7.16.5"
|
||||||
|
- resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.16.5.tgz#29a052d4b827846dd76ece16f565b9634c554ebd"
|
||||||
|
- integrity sha512-TLgi6Lh71vvMZGEkFuIxzaPsyeYCHQ5jJOOX1f0xXn0uciFuE8cEk0wyBquMcCxBXZ5BJhE2aUB7pnWTD150Tw==
|
||||||
|
+"@babel/helpers@^7.13.10", "@babel/helpers@^7.16.7":
|
||||||
|
+ version "7.16.7"
|
||||||
|
+ resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.16.7.tgz#7e3504d708d50344112767c3542fc5e357fffefc"
|
||||||
|
+ integrity sha512-9ZDoqtfY7AuEOt3cxchfii6C7GDyyMBffktR5B2jvWv8u2+efwvpnVKXMWzNehqy68tKgAfSwfdw/lWpthS2bw==
|
||||||
|
dependencies:
|
||||||
|
- "@babel/template" "^7.16.0"
|
||||||
|
- "@babel/traverse" "^7.16.5"
|
||||||
|
- "@babel/types" "^7.16.0"
|
||||||
|
+ "@babel/template" "^7.16.7"
|
||||||
|
+ "@babel/traverse" "^7.16.7"
|
||||||
|
+ "@babel/types" "^7.16.7"
|
||||||
|
|
||||||
|
-"@babel/highlight@^7.10.4", "@babel/highlight@^7.16.0":
|
||||||
|
- version "7.16.0"
|
||||||
|
- resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.16.0.tgz#6ceb32b2ca4b8f5f361fb7fd821e3fddf4a1725a"
|
||||||
|
- integrity sha512-t8MH41kUQylBtu2+4IQA3atqevA2lRgqA2wyVB/YiWmsDSuylZZuXOUy9ric30hfzauEFfdsuk/eXTRrGrfd0g==
|
||||||
|
+"@babel/highlight@^7.10.4", "@babel/highlight@^7.16.7":
|
||||||
|
+ version "7.16.10"
|
||||||
|
+ resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.16.10.tgz#744f2eb81579d6eea753c227b0f570ad785aba88"
|
||||||
|
+ integrity sha512-5FnTQLSLswEj6IkgVw5KusNUUFY9ZGqe/TRFnP/BKYHYgfh7tc+C7mwiy95/yNP7Dh9x580Vv8r7u7ZfTBFxdw==
|
||||||
|
dependencies:
|
||||||
|
- "@babel/helper-validator-identifier" "^7.15.7"
|
||||||
|
+ "@babel/helper-validator-identifier" "^7.16.7"
|
||||||
|
chalk "^2.0.0"
|
||||||
|
js-tokens "^4.0.0"
|
||||||
|
|
||||||
|
@@ -466,6 +376,13 @@
|
||||||
|
dependencies:
|
||||||
|
"@babel/helper-plugin-utils" "^7.8.0"
|
||||||
|
|
||||||
|
+"@babel/plugin-syntax-jsx@^7.16.7":
|
||||||
|
+ version "7.16.7"
|
||||||
|
+ resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.16.7.tgz#50b6571d13f764266a113d77c82b4a6508bbe665"
|
||||||
|
+ integrity sha512-Esxmk7YjA8QysKeT3VhTXvF6y77f/a91SIs4pWb4H2eWGQkCKFgQaG6hdoEVZtGsrAcb2K5BW66XsOErD4WU3Q==
|
||||||
|
+ dependencies:
|
||||||
|
+ "@babel/helper-plugin-utils" "^7.16.7"
|
||||||
|
+
|
||||||
|
"@babel/plugin-syntax-logical-assignment-operators@^7.10.4", "@babel/plugin-syntax-logical-assignment-operators@^7.8.3":
|
||||||
|
version "7.10.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz#ca91ef46303530448b906652bac2e9fe9941f699"
|
||||||
|
@@ -522,70 +439,67 @@
|
||||||
|
dependencies:
|
||||||
|
"@babel/helper-plugin-utils" "^7.14.5"
|
||||||
|
|
||||||
|
-"@babel/plugin-syntax-typescript@^7.16.0":
|
||||||
|
- version "7.16.5"
|
||||||
|
- resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.16.5.tgz#f47a33e4eee38554f00fb6b2f894fa1f5649b0b3"
|
||||||
|
- integrity sha512-/d4//lZ1Vqb4mZ5xTep3dDK888j7BGM/iKqBmndBaoYAFPlPKrGU608VVBz5JeyAb6YQDjRu1UKqj86UhwWVgw==
|
||||||
|
+"@babel/plugin-syntax-typescript@^7.16.7":
|
||||||
|
+ version "7.16.7"
|
||||||
|
+ resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.16.7.tgz#39c9b55ee153151990fb038651d58d3fd03f98f8"
|
||||||
|
+ integrity sha512-YhUIJHHGkqPgEcMYkPCKTyGUdoGKWtopIycQyjJH8OjvRgOYsXsaKehLVPScKJWAULPxMa4N1vCe6szREFlZ7A==
|
||||||
|
dependencies:
|
||||||
|
- "@babel/helper-plugin-utils" "^7.16.5"
|
||||||
|
+ "@babel/helper-plugin-utils" "^7.16.7"
|
||||||
|
|
||||||
|
"@babel/plugin-transform-modules-commonjs@^7.14.5":
|
||||||
|
- version "7.16.5"
|
||||||
|
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.16.5.tgz#4ee03b089536f076b2773196529d27c32b9d7bde"
|
||||||
|
- integrity sha512-ABhUkxvoQyqhCWyb8xXtfwqNMJD7tx+irIRnUh6lmyFud7Jln1WzONXKlax1fg/ey178EXbs4bSGNd6PngO+SQ==
|
||||||
|
+ version "7.16.8"
|
||||||
|
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.16.8.tgz#cdee19aae887b16b9d331009aa9a219af7c86afe"
|
||||||
|
+ integrity sha512-oflKPvsLT2+uKQopesJt3ApiaIS2HW+hzHFcwRNtyDGieAeC/dIHZX8buJQ2J2X1rxGPy4eRcUijm3qcSPjYcA==
|
||||||
|
dependencies:
|
||||||
|
- "@babel/helper-module-transforms" "^7.16.5"
|
||||||
|
- "@babel/helper-plugin-utils" "^7.16.5"
|
||||||
|
- "@babel/helper-simple-access" "^7.16.0"
|
||||||
|
+ "@babel/helper-module-transforms" "^7.16.7"
|
||||||
|
+ "@babel/helper-plugin-utils" "^7.16.7"
|
||||||
|
+ "@babel/helper-simple-access" "^7.16.7"
|
||||||
|
babel-plugin-dynamic-import-node "^2.3.3"
|
||||||
|
|
||||||
|
-"@babel/plugin-transform-typescript@^7.16.1":
|
||||||
|
- version "7.16.1"
|
||||||
|
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.16.1.tgz#cc0670b2822b0338355bc1b3d2246a42b8166409"
|
||||||
|
- integrity sha512-NO4XoryBng06jjw/qWEU2LhcLJr1tWkhpMam/H4eas/CDKMX/b2/Ylb6EI256Y7+FVPCawwSM1rrJNOpDiz+Lg==
|
||||||
|
- dependencies:
|
||||||
|
- "@babel/helper-create-class-features-plugin" "^7.16.0"
|
||||||
|
- "@babel/helper-plugin-utils" "^7.14.5"
|
||||||
|
- "@babel/plugin-syntax-typescript" "^7.16.0"
|
||||||
|
-
|
||||||
|
-"@babel/preset-typescript@^7.14.5":
|
||||||
|
- version "7.16.5"
|
||||||
|
- resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.16.5.tgz#b86a5b0ae739ba741347d2f58c52f52e63cf1ba1"
|
||||||
|
- integrity sha512-lmAWRoJ9iOSvs3DqOndQpj8XqXkzaiQs50VG/zESiI9D3eoZhGriU675xNCr0UwvsuXrhMAGvyk1w+EVWF3u8Q==
|
||||||
|
+"@babel/plugin-transform-react-jsx@^7.14.5":
|
||||||
|
+ version "7.16.7"
|
||||||
|
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.16.7.tgz#86a6a220552afd0e4e1f0388a68a372be7add0d4"
|
||||||
|
+ integrity sha512-8D16ye66fxiE8m890w0BpPpngG9o9OVBBy0gH2E+2AR7qMR2ZpTYJEqLxAsoroenMId0p/wMW+Blc0meDgu0Ag==
|
||||||
|
dependencies:
|
||||||
|
- "@babel/helper-plugin-utils" "^7.16.5"
|
||||||
|
- "@babel/helper-validator-option" "^7.14.5"
|
||||||
|
- "@babel/plugin-transform-typescript" "^7.16.1"
|
||||||
|
+ "@babel/helper-annotate-as-pure" "^7.16.7"
|
||||||
|
+ "@babel/helper-module-imports" "^7.16.7"
|
||||||
|
+ "@babel/helper-plugin-utils" "^7.16.7"
|
||||||
|
+ "@babel/plugin-syntax-jsx" "^7.16.7"
|
||||||
|
+ "@babel/types" "^7.16.7"
|
||||||
|
|
||||||
|
-"@babel/runtime@^7.0.0":
|
||||||
|
- version "7.16.3"
|
||||||
|
- resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.16.3.tgz#b86f0db02a04187a3c17caa77de69840165d42d5"
|
||||||
|
- integrity sha512-WBwekcqacdY2e9AF/Q7WLFUWmdJGJTkbjqTjoMDgXkVZ3ZRUvOPsLb5KdwISoQVsbP+DQzVZW4Zhci0DvpbNTQ==
|
||||||
|
+"@babel/plugin-transform-typescript@^7.16.7":
|
||||||
|
+ version "7.16.8"
|
||||||
|
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.16.8.tgz#591ce9b6b83504903fa9dd3652c357c2ba7a1ee0"
|
||||||
|
+ integrity sha512-bHdQ9k7YpBDO2d0NVfkj51DpQcvwIzIusJ7mEUaMlbZq3Kt/U47j24inXZHQ5MDiYpCs+oZiwnXyKedE8+q7AQ==
|
||||||
|
dependencies:
|
||||||
|
- regenerator-runtime "^0.13.4"
|
||||||
|
+ "@babel/helper-create-class-features-plugin" "^7.16.7"
|
||||||
|
+ "@babel/helper-plugin-utils" "^7.16.7"
|
||||||
|
+ "@babel/plugin-syntax-typescript" "^7.16.7"
|
||||||
|
|
||||||
|
-"@babel/runtime@^7.1.2", "@babel/runtime@^7.12.0", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.13", "@babel/runtime@^7.12.5", "@babel/runtime@^7.13.10", "@babel/runtime@^7.13.17", "@babel/runtime@^7.14.5", "@babel/runtime@^7.15.4", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.2", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.0":
|
||||||
|
- version "7.16.0"
|
||||||
|
- resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.16.0.tgz#e27b977f2e2088ba24748bf99b5e1dece64e4f0b"
|
||||||
|
- integrity sha512-Nht8L0O8YCktmsDV6FqFue7vQLRx3Hb0B37lS5y0jDRqRxlBG4wIJHnf9/bgSE2UyipKFA01YtS+npRdTWBUyw==
|
||||||
|
+"@babel/preset-typescript@^7.14.5":
|
||||||
|
+ version "7.16.7"
|
||||||
|
+ resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.16.7.tgz#ab114d68bb2020afc069cd51b37ff98a046a70b9"
|
||||||
|
+ integrity sha512-WbVEmgXdIyvzB77AQjGBEyYPZx+8tTsO50XtfozQrkW8QB2rLJpH2lgx0TRw5EJrBxOZQ+wCcyPVQvS8tjEHpQ==
|
||||||
|
dependencies:
|
||||||
|
- regenerator-runtime "^0.13.4"
|
||||||
|
+ "@babel/helper-plugin-utils" "^7.16.7"
|
||||||
|
+ "@babel/helper-validator-option" "^7.16.7"
|
||||||
|
+ "@babel/plugin-transform-typescript" "^7.16.7"
|
||||||
|
|
||||||
|
-"@babel/runtime@^7.16.3":
|
||||||
|
+"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.12.0", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.13", "@babel/runtime@^7.12.5", "@babel/runtime@^7.13.10", "@babel/runtime@^7.13.17", "@babel/runtime@^7.14.5", "@babel/runtime@^7.15.4", "@babel/runtime@^7.16.3", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.2", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.0":
|
||||||
|
version "7.16.7"
|
||||||
|
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.16.7.tgz#03ff99f64106588c9c403c6ecb8c3bafbbdff1fa"
|
||||||
|
integrity sha512-9E9FJowqAsytyOY6LG+1KuueckRL+aQW+mKvXRXnuFGyRAyepJPmEo9vgMfXUA6O9u3IeEdv9MAkppFcaQwogQ==
|
||||||
|
dependencies:
|
||||||
|
regenerator-runtime "^0.13.4"
|
||||||
|
|
||||||
|
-"@babel/template@^7.12.13", "@babel/template@^7.16.0", "@babel/template@^7.3.3":
|
||||||
|
- version "7.16.0"
|
||||||
|
- resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.16.0.tgz#d16a35ebf4cd74e202083356fab21dd89363ddd6"
|
||||||
|
- integrity sha512-MnZdpFD/ZdYhXwiunMqqgyZyucaYsbL0IrjoGjaVhGilz+x8YB++kRfygSOIj1yOtWKPlx7NBp+9I1RQSgsd5A==
|
||||||
|
+"@babel/template@^7.12.13", "@babel/template@^7.16.7", "@babel/template@^7.3.3":
|
||||||
|
+ version "7.16.7"
|
||||||
|
+ resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.16.7.tgz#8d126c8701fde4d66b264b3eba3d96f07666d155"
|
||||||
|
+ integrity sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w==
|
||||||
|
dependencies:
|
||||||
|
- "@babel/code-frame" "^7.16.0"
|
||||||
|
- "@babel/parser" "^7.16.0"
|
||||||
|
- "@babel/types" "^7.16.0"
|
||||||
|
+ "@babel/code-frame" "^7.16.7"
|
||||||
|
+ "@babel/parser" "^7.16.7"
|
||||||
|
+ "@babel/types" "^7.16.7"
|
||||||
|
|
||||||
|
"@babel/traverse@7.13.0":
|
||||||
|
version "7.13.0"
|
||||||
|
@@ -642,12 +541,12 @@
|
||||||
|
lodash "^4.17.19"
|
||||||
|
to-fast-properties "^2.0.0"
|
||||||
|
|
||||||
|
-"@babel/types@^7.0.0", "@babel/types@^7.13.0", "@babel/types@^7.16.0", "@babel/types@^7.3.0", "@babel/types@^7.3.3":
|
||||||
|
- version "7.16.0"
|
||||||
|
- resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.16.0.tgz#db3b313804f96aadd0b776c4823e127ad67289ba"
|
||||||
|
- integrity sha512-PJgg/k3SdLsGb3hhisFvtLOw5ts113klrpLuIPtCJIU+BB24fqq6lf8RWqKJEjzqXR9AEH1rIb5XTqwBHB+kQg==
|
||||||
|
+"@babel/types@^7.0.0", "@babel/types@^7.13.0", "@babel/types@^7.16.0", "@babel/types@^7.16.7", "@babel/types@^7.16.8", "@babel/types@^7.3.0", "@babel/types@^7.3.3":
|
||||||
|
+ version "7.16.8"
|
||||||
|
+ resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.16.8.tgz#0ba5da91dd71e0a4e7781a30f22770831062e3c1"
|
||||||
|
+ integrity sha512-smN2DQc5s4M7fntyjGtyIPbRJv6wW4rU/94fmYJ7PKQuZkC0qGMHXJbg6sNGt12JmVr4k5YaptI/XtiLJBnmIg==
|
||||||
|
dependencies:
|
||||||
|
- "@babel/helper-validator-identifier" "^7.15.7"
|
||||||
|
+ "@babel/helper-validator-identifier" "^7.16.7"
|
||||||
|
to-fast-properties "^2.0.0"
|
||||||
|
|
||||||
|
"@bcoe/v8-coverage@^0.2.3":
|
||||||
|
@@ -1958,9 +1851,9 @@
|
||||||
|
tsyringe "^4.6.0"
|
||||||
|
|
||||||
|
"@playwright/test@^1.17.1":
|
||||||
|
- version "1.17.1"
|
||||||
|
- resolved "https://registry.yarnpkg.com/@playwright/test/-/test-1.17.1.tgz#9e5aca496d2c90ce95ca19ac2c3a8867a4f606d3"
|
||||||
|
- integrity sha512-mMZS5OMTN/vUlqd1JZkFoAk2FsIZ4/E/00tw5it2c/VF4+3z/aWO+PPd8ShEGzYME7B16QGWNPjyFpDQI1t4RQ==
|
||||||
|
+ version "1.18.1"
|
||||||
|
+ resolved "https://registry.yarnpkg.com/@playwright/test/-/test-1.18.1.tgz#efaa3aa9c7f8aebeb75cd45fd9737529e9b30fbd"
|
||||||
|
+ integrity sha512-v6jAM2GpRvf4MUvSLkrAXg101XT9mLu2X2NbCnEoj7GHBXwavDlAJDMwh4Hn8oipDxB6MS6FTcr7opXsIMNwrA==
|
||||||
|
dependencies:
|
||||||
|
"@babel/code-frame" "^7.14.5"
|
||||||
|
"@babel/core" "^7.14.8"
|
||||||
|
@@ -1978,20 +1871,23 @@
|
||||||
|
"@babel/plugin-syntax-object-rest-spread" "^7.8.3"
|
||||||
|
"@babel/plugin-syntax-optional-catch-binding" "^7.8.3"
|
||||||
|
"@babel/plugin-transform-modules-commonjs" "^7.14.5"
|
||||||
|
+ "@babel/plugin-transform-react-jsx" "^7.14.5"
|
||||||
|
"@babel/preset-typescript" "^7.14.5"
|
||||||
|
- colors "^1.4.0"
|
||||||
|
+ babel-plugin-module-resolver "^4.1.0"
|
||||||
|
+ colors "1.4.0"
|
||||||
|
commander "^8.2.0"
|
||||||
|
debug "^4.1.1"
|
||||||
|
expect "=27.2.5"
|
||||||
|
jest-matcher-utils "=27.2.5"
|
||||||
|
jpeg-js "^0.4.2"
|
||||||
|
+ json5 "^2.2.0"
|
||||||
|
mime "^2.4.6"
|
||||||
|
minimatch "^3.0.3"
|
||||||
|
ms "^2.1.2"
|
||||||
|
open "^8.3.0"
|
||||||
|
pirates "^4.0.1"
|
||||||
|
pixelmatch "^5.2.1"
|
||||||
|
- playwright-core "=1.17.1"
|
||||||
|
+ playwright-core "=1.18.1"
|
||||||
|
pngjs "^5.0.0"
|
||||||
|
rimraf "^3.0.2"
|
||||||
|
source-map-support "^0.4.18"
|
||||||
|
@@ -3510,16 +3395,27 @@ babel-plugin-jest-hoist@^26.6.2:
|
||||||
|
"@types/babel__core" "^7.0.0"
|
||||||
|
"@types/babel__traverse" "^7.0.6"
|
||||||
|
|
||||||
|
-babel-plugin-jest-hoist@^27.2.0:
|
||||||
|
- version "27.2.0"
|
||||||
|
- resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.2.0.tgz#79f37d43f7e5c4fdc4b2ca3e10cc6cf545626277"
|
||||||
|
- integrity sha512-TOux9khNKdi64mW+0OIhcmbAn75tTlzKhxmiNXevQaPbrBYK7YKjP1jl6NHTJ6XR5UgUrJbCnWlKVnJn29dfjw==
|
||||||
|
+babel-plugin-jest-hoist@^27.4.0:
|
||||||
|
+ version "27.4.0"
|
||||||
|
+ resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.4.0.tgz#d7831fc0f93573788d80dee7e682482da4c730d6"
|
||||||
|
+ integrity sha512-Jcu7qS4OX5kTWBc45Hz7BMmgXuJqRnhatqpUhnzGC3OBYpOmf2tv6jFNwZpwM7wU7MUuv2r9IPS/ZlYOuburVw==
|
||||||
|
dependencies:
|
||||||
|
"@babel/template" "^7.3.3"
|
||||||
|
"@babel/types" "^7.3.3"
|
||||||
|
"@types/babel__core" "^7.0.0"
|
||||||
|
"@types/babel__traverse" "^7.0.6"
|
||||||
|
|
||||||
|
+babel-plugin-module-resolver@^4.1.0:
|
||||||
|
+ version "4.1.0"
|
||||||
|
+ resolved "https://registry.yarnpkg.com/babel-plugin-module-resolver/-/babel-plugin-module-resolver-4.1.0.tgz#22a4f32f7441727ec1fbf4967b863e1e3e9f33e2"
|
||||||
|
+ integrity sha512-MlX10UDheRr3lb3P0WcaIdtCSRlxdQsB1sBqL7W0raF070bGl1HQQq5K3T2vf2XAYie+ww+5AKC/WrkjRO2knA==
|
||||||
|
+ dependencies:
|
||||||
|
+ find-babel-config "^1.2.0"
|
||||||
|
+ glob "^7.1.6"
|
||||||
|
+ pkg-up "^3.1.0"
|
||||||
|
+ reselect "^4.0.0"
|
||||||
|
+ resolve "^1.13.1"
|
||||||
|
+
|
||||||
|
babel-preset-current-node-syntax@^1.0.0:
|
||||||
|
version "1.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz#b4399239b89b2a011f9ddbe3e4f401fc40cff73b"
|
||||||
|
@@ -4223,7 +4109,7 @@ colorette@^2.0.16:
|
||||||
|
resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.16.tgz#713b9af84fdb000139f04546bd4a93f62a5085da"
|
||||||
|
integrity sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g==
|
||||||
|
|
||||||
|
-colors@^1.4.0:
|
||||||
|
+colors@1.4.0:
|
||||||
|
version "1.4.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78"
|
||||||
|
integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==
|
||||||
|
@@ -5597,6 +5471,14 @@ finalhandler@~1.1.2:
|
||||||
|
statuses "~1.5.0"
|
||||||
|
unpipe "~1.0.0"
|
||||||
|
|
||||||
|
+find-babel-config@^1.2.0:
|
||||||
|
+ version "1.2.0"
|
||||||
|
+ resolved "https://registry.yarnpkg.com/find-babel-config/-/find-babel-config-1.2.0.tgz#a9b7b317eb5b9860cda9d54740a8c8337a2283a2"
|
||||||
|
+ integrity sha512-jB2CHJeqy6a820ssiqwrKMeyC6nNdmrcgkKWJWmpoxpE8RKciYJXCcXRq1h2AzCo5I5BJeN2tkGEO3hLTuePRA==
|
||||||
|
+ dependencies:
|
||||||
|
+ json5 "^0.5.1"
|
||||||
|
+ path-exists "^3.0.0"
|
||||||
|
+
|
||||||
|
find-up@^2.1.0:
|
||||||
|
version "2.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7"
|
||||||
|
@@ -5604,6 +5486,13 @@ find-up@^2.1.0:
|
||||||
|
dependencies:
|
||||||
|
locate-path "^2.0.0"
|
||||||
|
|
||||||
|
+find-up@^3.0.0:
|
||||||
|
+ version "3.0.0"
|
||||||
|
+ resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73"
|
||||||
|
+ integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==
|
||||||
|
+ dependencies:
|
||||||
|
+ locate-path "^3.0.0"
|
||||||
|
+
|
||||||
|
find-up@^4.0.0, find-up@^4.1.0:
|
||||||
|
version "4.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19"
|
||||||
|
@@ -7526,13 +7382,18 @@ json-stringify-safe@~5.0.1:
|
||||||
|
resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"
|
||||||
|
integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=
|
||||||
|
|
||||||
|
-json5@2.x, json5@^2.1.2:
|
||||||
|
+json5@2.x, json5@^2.1.2, json5@^2.2.0:
|
||||||
|
version "2.2.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.0.tgz#2dfefe720c6ba525d9ebd909950f0515316c89a3"
|
||||||
|
integrity sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==
|
||||||
|
dependencies:
|
||||||
|
minimist "^1.2.5"
|
||||||
|
|
||||||
|
+json5@^0.5.1:
|
||||||
|
+ version "0.5.1"
|
||||||
|
+ resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821"
|
||||||
|
+ integrity sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=
|
||||||
|
+
|
||||||
|
jsonfile@^4.0.0:
|
||||||
|
version "4.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb"
|
||||||
|
@@ -7807,6 +7668,14 @@ locate-path@^2.0.0:
|
||||||
|
p-locate "^2.0.0"
|
||||||
|
path-exists "^3.0.0"
|
||||||
|
|
||||||
|
+locate-path@^3.0.0:
|
||||||
|
+ version "3.0.0"
|
||||||
|
+ resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e"
|
||||||
|
+ integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==
|
||||||
|
+ dependencies:
|
||||||
|
+ p-locate "^3.0.0"
|
||||||
|
+ path-exists "^3.0.0"
|
||||||
|
+
|
||||||
|
locate-path@^5.0.0:
|
||||||
|
version "5.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0"
|
||||||
|
@@ -8824,7 +8684,7 @@ p-limit@^1.1.0:
|
||||||
|
dependencies:
|
||||||
|
p-try "^1.0.0"
|
||||||
|
|
||||||
|
-p-limit@^2.2.0:
|
||||||
|
+p-limit@^2.0.0, p-limit@^2.2.0:
|
||||||
|
version "2.3.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1"
|
||||||
|
integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==
|
||||||
|
@@ -8838,6 +8698,13 @@ p-locate@^2.0.0:
|
||||||
|
dependencies:
|
||||||
|
p-limit "^1.1.0"
|
||||||
|
|
||||||
|
+p-locate@^3.0.0:
|
||||||
|
+ version "3.0.0"
|
||||||
|
+ resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4"
|
||||||
|
+ integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==
|
||||||
|
+ dependencies:
|
||||||
|
+ p-limit "^2.0.0"
|
||||||
|
+
|
||||||
|
p-locate@^4.1.0:
|
||||||
|
version "4.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07"
|
||||||
|
@@ -9000,7 +8867,7 @@ path-key@^3.0.0, path-key@^3.1.0:
|
||||||
|
resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375"
|
||||||
|
integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==
|
||||||
|
|
||||||
|
-path-parse@^1.0.6:
|
||||||
|
+path-parse@^1.0.6, path-parse@^1.0.7:
|
||||||
|
version "1.0.7"
|
||||||
|
resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735"
|
||||||
|
integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==
|
||||||
|
@@ -9154,10 +9019,17 @@ pkg-dir@^4.2.0:
|
||||||
|
dependencies:
|
||||||
|
find-up "^4.0.0"
|
||||||
|
|
||||||
|
-playwright-core@=1.17.1:
|
||||||
|
- version "1.17.1"
|
||||||
|
- resolved "https://registry.yarnpkg.com/playwright-core/-/playwright-core-1.17.1.tgz#a16e0f89284a0ed8ae6d77e1c905c84b8a2ba022"
|
||||||
|
- integrity sha512-C3c8RpPiC3qr15fRDN6dx6WnUkPLFmST37gms2aoHPDRvp7EaGDPMMZPpqIm/QWB5J40xDrQCD4YYHz2nBTojQ==
|
||||||
|
+pkg-up@^3.1.0:
|
||||||
|
+ version "3.1.0"
|
||||||
|
+ resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-3.1.0.tgz#100ec235cc150e4fd42519412596a28512a0def5"
|
||||||
|
+ integrity sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==
|
||||||
|
+ dependencies:
|
||||||
|
+ find-up "^3.0.0"
|
||||||
|
+
|
||||||
|
+playwright-core@=1.18.1:
|
||||||
|
+ version "1.18.1"
|
||||||
|
+ resolved "https://registry.yarnpkg.com/playwright-core/-/playwright-core-1.18.1.tgz#a5cf3f212d10692382e2acd1f7bc8c9ff9bbb849"
|
||||||
|
+ integrity sha512-NALGl8R1GHzGLlhUApmpmfh6M1rrrPcDTygWvhTbprxwGB9qd/j9DRwyn4HTQcUB6o0/VOpo46fH9ez3+D/Rog==
|
||||||
|
dependencies:
|
||||||
|
commander "^8.2.0"
|
||||||
|
debug "^4.1.1"
|
||||||
|
@@ -9325,9 +9181,9 @@ prettier-linter-helpers@^1.0.0:
|
||||||
|
fast-diff "^1.1.2"
|
||||||
|
|
||||||
|
prettier@^2.3.2:
|
||||||
|
- version "2.4.1"
|
||||||
|
- resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.4.1.tgz#671e11c89c14a4cfc876ce564106c4a6726c9f5c"
|
||||||
|
- integrity sha512-9fbDAXSBcc6Bs1mZrDYb3XKzDLm4EXXL9sC1LqKP5rZkT6KRr/rf9amVUcODVXgguK/isJz0d0hP72WeaKWsvA==
|
||||||
|
+ version "2.5.1"
|
||||||
|
+ resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.5.1.tgz#fff75fa9d519c54cf0fce328c1017d94546bc56a"
|
||||||
|
+ integrity sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg==
|
||||||
|
|
||||||
|
pretty-format@^26.6.2:
|
||||||
|
version "26.6.2"
|
||||||
|
@@ -9594,32 +9439,16 @@ raw-body@2.4.2:
|
||||||
|
unpipe "1.0.0"
|
||||||
|
|
||||||
|
react-calendar@^3.3.1:
|
||||||
|
- version "3.5.0"
|
||||||
|
- resolved "https://registry.yarnpkg.com/react-calendar/-/react-calendar-3.5.0.tgz#ba7bc0b76e389ec91b385f34328f02457998678c"
|
||||||
|
- integrity sha512-WrDOON59188ciC7jw5YrlM/EgLTWM9TD9dflRWjgd9rlMxPScX8dNG4tJGE+z8d4xaEVccJmHbiYGCGsYdXdxQ==
|
||||||
|
+ version "3.6.0"
|
||||||
|
+ resolved "https://registry.yarnpkg.com/react-calendar/-/react-calendar-3.6.0.tgz#aec0a066439942972eb980b9f47730ba17f60eb3"
|
||||||
|
+ integrity sha512-hUNuPUPmiT6RGp7kZhes/yi/G9Kk1pitdzy8LShGW6wTC920HEF3hZkyZ8yT6HZNT3HPaav441i9E9pHQVrwEA==
|
||||||
|
dependencies:
|
||||||
|
"@wojtekmaj/date-utils" "^1.0.2"
|
||||||
|
get-user-locale "^1.2.0"
|
||||||
|
merge-class-names "^1.1.1"
|
||||||
|
prop-types "^15.6.0"
|
||||||
|
|
||||||
|
-react-date-picker@^8.3.3:
|
||||||
|
- version "8.3.5"
|
||||||
|
- resolved "https://registry.yarnpkg.com/react-date-picker/-/react-date-picker-8.3.5.tgz#3972db3fc1f37cfd6b09c09bf4988817b4d2be72"
|
||||||
|
- integrity sha512-s0Zo1xiK5xg8KGj+as84LeHS4guCdHKp/Ap6tkZMOr77A3REtezKrfLTiUeOM1xBScraBFajrZaQ/CFBNX09Cg==
|
||||||
|
- dependencies:
|
||||||
|
- "@types/react-calendar" "^3.0.0"
|
||||||
|
- "@wojtekmaj/date-utils" "^1.0.3"
|
||||||
|
- get-user-locale "^1.2.0"
|
||||||
|
- make-event-props "^1.1.0"
|
||||||
|
- merge-class-names "^1.1.1"
|
||||||
|
- merge-refs "^1.0.0"
|
||||||
|
- prop-types "^15.6.0"
|
||||||
|
- react-calendar "^3.3.1"
|
||||||
|
- react-fit "^1.0.3"
|
||||||
|
- update-input-width "^1.2.2"
|
||||||
|
-
|
||||||
|
-react-date-picker@^8.3.6:
|
||||||
|
+react-date-picker@^8.3.3, react-date-picker@^8.3.6:
|
||||||
|
version "8.3.6"
|
||||||
|
resolved "https://registry.yarnpkg.com/react-date-picker/-/react-date-picker-8.3.6.tgz#446142bee5691aea66a2bac53313357aca561cd4"
|
||||||
|
integrity sha512-c1rThf0jSKROoSGLpUEPtcC8VE+XoVgqxh+ng9aLYQvjDMGWQBgoat6Qrj8nRVzvCPpdXV4jqiCB3z2vVVuseA==
|
||||||
|
@@ -10055,6 +9873,11 @@ require-main-filename@^2.0.0:
|
||||||
|
resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b"
|
||||||
|
integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==
|
||||||
|
|
||||||
|
+reselect@^4.0.0:
|
||||||
|
+ version "4.1.5"
|
||||||
|
+ resolved "https://registry.yarnpkg.com/reselect/-/reselect-4.1.5.tgz#852c361247198da6756d07d9296c2b51eddb79f6"
|
||||||
|
+ integrity sha512-uVdlz8J7OO+ASpBYoz1Zypgx0KasCY20H+N8JD13oUMtPvSHQuscrHop4KbXrbsBcdB9Ds7lVK7eRkBIfO43vQ==
|
||||||
|
+
|
||||||
|
resolve-cwd@^3.0.0:
|
||||||
|
version "3.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d"
|
||||||
|
@@ -10082,13 +9905,14 @@ resolve-url@^0.2.1:
|
||||||
|
resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a"
|
||||||
|
integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=
|
||||||
|
|
||||||
|
-resolve@^1.10.0, resolve@^1.18.1, resolve@^1.20.0:
|
||||||
|
- version "1.20.0"
|
||||||
|
- resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975"
|
||||||
|
- integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==
|
||||||
|
+resolve@^1.10.0, resolve@^1.13.1, resolve@^1.18.1, resolve@^1.21.0:
|
||||||
|
+ version "1.22.0"
|
||||||
|
+ resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.0.tgz#5e0b8c67c15df57a89bdbabe603a002f21731198"
|
||||||
|
+ integrity sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==
|
||||||
|
dependencies:
|
||||||
|
- is-core-module "^2.2.0"
|
||||||
|
- path-parse "^1.0.6"
|
||||||
|
+ is-core-module "^2.8.1"
|
||||||
|
+ path-parse "^1.0.7"
|
||||||
|
+ supports-preserve-symlinks-flag "^1.0.0"
|
||||||
|
|
||||||
|
resolve@^2.0.0-next.3:
|
||||||
|
version "2.0.0-next.3"
|
||||||
|
@@ -10905,6 +10714,11 @@ supports-hyperlinks@^2.0.0:
|
||||||
|
has-flag "^4.0.0"
|
||||||
|
supports-color "^7.0.0"
|
||||||
|
|
||||||
|
+supports-preserve-symlinks-flag@^1.0.0:
|
||||||
|
+ version "1.0.0"
|
||||||
|
+ resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09"
|
||||||
|
+ integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==
|
||||||
|
+
|
||||||
|
swarm-js@^0.1.40:
|
||||||
|
version "0.1.40"
|
||||||
|
resolved "https://registry.yarnpkg.com/swarm-js/-/swarm-js-0.1.40.tgz#b1bc7b6dcc76061f6c772203e004c11997e06b99"
|