import { useRouter } from "next/router"; import { useEffect, useState } from "react"; import useAddAppMutation from "@calcom/app-store/_utils/useAddAppMutation"; import { InstallAppButton } from "@calcom/app-store/components"; import { useLocale } from "@calcom/lib/hooks/useLocale"; import type { AppFrontendPayload as App } from "@calcom/types/App"; import type { CredentialFrontendPayload as Credential } from "@calcom/types/Credential"; import { Button } from "../button"; import { FiPlus } from "../icon"; import { showToast } from "../toast"; interface AppCardProps { app: App; credentials?: Credential[]; searchText?: string; } export function AppCard({ app, credentials, searchText }: AppCardProps) { const { t } = useLocale(); const router = useRouter(); const mutation = useAddAppMutation(null, { onSuccess: (data) => { // Refresh SSR page content without actual reload router.replace(router.asPath); 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 allowedMultipleInstalls = app.categories && app.categories.indexOf("calendar") > -1; const appAdded = (credentials && credentials.length) || 0; const [searchTextIndex, setSearchTextIndex] = useState(undefined); useEffect(() => { setSearchTextIndex(searchText ? app.name.toLowerCase().indexOf(searchText.toLowerCase()) : undefined); }, [app.name, searchText]); return (
{app.name

{searchTextIndex != undefined && searchText ? ( <> {app.name.substring(0, searchTextIndex)} {app.name.substring(searchTextIndex, searchTextIndex + searchText.length)} {app.name.substring(searchTextIndex + searchText.length)} ) : ( app.name )}

{/* TODO: add reviews
{props.rating} stars {props.reviews} reviews
*/}

{app.description}

{app.isGlobal || (credentials && credentials.length > 0 && allowedMultipleInstalls) ? !app.isGlobal && ( !data.installed)} wrapperClassName="[@media(max-width:260px)]:w-full" render={({ useDefaultComponent, ...props }) => { if (useDefaultComponent) { props = { ...props, onClick: () => { mutation.mutate({ type: app.type, variant: app.variant, slug: app.slug }); }, }; } return ( ); }} /> ) : credentials && credentials.length === 0 && ( !data.installed)} render={({ useDefaultComponent, ...props }) => { if (useDefaultComponent) { props = { ...props, onClick: () => { mutation.mutate({ type: app.type, variant: app.variant, slug: app.slug }); }, disabled: !!props.disabled, }; } return ( ); }} /> )}
{appAdded > 0 && ( {t("installed", { count: appAdded })} )} {app.isTemplate && ( Template )} {(app.isDefault || (!app.isDefault && app.isGlobal)) && ( {t("default")} )}
); }