import Link from "next/link"; import { useRouter } from "next/router"; import React, { useState } from "react"; import useAddAppMutation from "@calcom/app-store/_utils/useAddAppMutation"; import { InstallAppButton } from "@calcom/app-store/components"; import DisconnectIntegration from "@calcom/features/apps/components/DisconnectIntegration"; import LicenseRequired from "@calcom/features/ee/common/components/v2/LicenseRequired"; import Shell from "@calcom/features/shell/Shell"; import classNames from "@calcom/lib/classNames"; import { APP_NAME, COMPANY_NAME, SUPPORT_MAIL_ADDRESS } from "@calcom/lib/constants"; import { useLocale } from "@calcom/lib/hooks/useLocale"; import { trpc } from "@calcom/trpc/react"; import { App as AppType } from "@calcom/types/App"; import { Button, showToast, SkeletonButton, SkeletonText, HeadSeo, Badge } from "@calcom/ui"; import { FiBookOpen, FiCheck, FiExternalLink, FiFile, FiFlag, FiMail, FiPlus, FiShield, } from "@calcom/ui/components/icon"; const Component = ({ name, type, logo, slug, variant, body, categories, author, price = 0, commission, isGlobal = false, feeType, docs, website, email, tos, privacy, isProOnly, images, isTemplate, }: Parameters[0]) => { const { t } = useLocale(); const hasImages = images && images.length > 0; const router = useRouter(); const mutation = useAddAppMutation(null, { onSuccess: (data) => { if (data?.setupPending) return; showToast(t("app_successfully_installed"), "success"); }, onError: (error) => { if (error instanceof Error) showToast(error.message || t("app_could_not_be_installed"), "error"); }, }); const priceInDollar = Intl.NumberFormat("en-US", { style: "currency", currency: "USD", useGrouping: false, }).format(price); const [existingCredentials, setExistingCredentials] = useState([]); const appCredentials = trpc.viewer.appCredentialsByType.useQuery( { appType: type }, { onSuccess(data) { setExistingCredentials(data); }, } ); // variant not other allows, an app to be shown in calendar category without requiring an actual calendar connection e.g. vimcal // Such apps, can only be installed once. const allowedMultipleInstalls = categories.indexOf("calendar") > -1 && variant !== "other"; return (
{hasImages && (
{images ? ( images.map((img) => ( {`Screenshot )) ) : ( )}
)}
{name}

{name}

{categories[0]} {" "} • {t("published_by", { author })}

{isTemplate && ( Template - Available in Dev Environment only for testing )}
{!appCredentials.isLoading ? ( isGlobal || (existingCredentials.length > 0 && allowedMultipleInstalls ? (
{!isGlobal && ( { if (useDefaultComponent) { props = { ...props, onClick: () => { mutation.mutate({ type, variant, slug }); }, loading: mutation.isLoading, }; } return ( ); }} /> )}
) : existingCredentials.length > 0 ? ( { router.replace("/apps/installed"); }} /> ) : ( { if (useDefaultComponent) { props = { ...props, onClick: () => { mutation.mutate({ type, variant, slug }); }, loading: mutation.isLoading, }; } return ( ); }} /> )) ) : ( )} {price !== 0 && ( {feeType === "usage-based" ? commission + "% + " + priceInDollar + "/booking" : priceInDollar} {feeType === "monthly" && "/" + t("month")} )}
{body}

{t("pricing")}

{price === 0 ? ( t("free_to_use_apps") ) : ( <> {Intl.NumberFormat("en-US", { style: "currency", currency: "USD", useGrouping: false, }).format(price)} {feeType === "monthly" && "/" + t("month")} )}

{t("learn_more")}


{t("every_app_published", { appName: APP_NAME, companyName: COMPANY_NAME })} {t("report_app")}
); }; export default function App(props: { name: string; description: AppType["description"]; type: AppType["type"]; isGlobal?: AppType["isGlobal"]; logo: string; slug: string; variant: string; body: React.ReactNode; categories: string[]; author: string; pro?: boolean; price?: number; commission?: number; feeType?: AppType["feeType"]; docs?: string; website?: string; email: string; // required tos?: string; privacy?: string; licenseRequired: AppType["licenseRequired"]; isProOnly: AppType["isProOnly"]; images?: string[]; isTemplate?: boolean; }) { const { t } = useLocale(); return ( {props.licenseRequired ? ( ) : ( )} ); }