ConnectAppCard.tsx raw
1 import { CheckIcon, CopyIcon, EyeIcon } from "lucide-react";
2 import { useEffect, useState } from "react";
3 import { AppStoreApp } from "src/components/connections/SuggestedAppData";
4 import Loading from "src/components/Loading";
5 import QRCode from "src/components/QRCode";
6 import { Badge } from "src/components/ui/badge";
7 import { Button } from "src/components/ui/button";
8 import {
9 Card,
10 CardContent,
11 CardHeader,
12 CardTitle,
13 } from "src/components/ui/card";
14 import { LinkButton } from "src/components/ui/custom/link-button";
15 import { copyToClipboard } from "src/lib/clipboard";
16 import { cn } from "src/lib/utils";
17 import { App } from "src/types";
18
19 export function ConnectAppCard({
20 app,
21 pairingUri,
22 appStoreApp,
23 }: {
24 app: App;
25 pairingUri: string;
26 appStoreApp?: AppStoreApp;
27 }) {
28 const [timeout, setTimeout] = useState(false);
29 const [isQRCodeVisible, setIsQRCodeVisible] = useState(false);
30 const copy = () => {
31 copyToClipboard(pairingUri);
32 };
33
34 useEffect(() => {
35 const timeoutId = window.setTimeout(() => {
36 setTimeout(true);
37 }, 30000);
38
39 return () => window.clearTimeout(timeoutId);
40 }, []);
41
42 return (
43 <Card className="w-full">
44 <CardHeader>
45 <CardTitle className="text-center">Connection Secret</CardTitle>
46 </CardHeader>
47 <CardContent className="flex flex-col items-center gap-5">
48 {!app.lastUsedAt ? (
49 <>
50 <div className="flex flex-row items-center gap-2 text-sm z-10">
51 <Loading className="size-4" />
52 <p>Waiting for app to connect</p>
53 </div>
54 {timeout && (
55 <div className="text-sm flex flex-col gap-2 items-center text-center">
56 Connecting is taking longer than usual.
57 <LinkButton to={`/apps/${app?.id}`} variant="secondary">
58 Continue anyway
59 </LinkButton>
60 </div>
61 )}
62 </>
63 ) : (
64 <Badge variant="positive">
65 <CheckIcon />
66 App connected
67 </Badge>
68 )}
69 {!appStoreApp?.hideConnectionQr && (
70 <div className="relative">
71 <div
72 className={cn(!isQRCodeVisible && "blur-md cursor-pointer")}
73 onClick={() => setIsQRCodeVisible(true)}
74 >
75 <QRCode value={pairingUri} />
76 {appStoreApp && (
77 <img
78 src={appStoreApp.logo}
79 className="absolute w-12 h-12 top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 bg-muted p-1 rounded-xl"
80 />
81 )}
82 </div>
83 {!isQRCodeVisible && (
84 <Button
85 onClick={() => {
86 setIsQRCodeVisible(true);
87 }}
88 className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2"
89 >
90 <EyeIcon />
91 Reveal QR
92 </Button>
93 )}
94 </div>
95 )}
96 <div className="flex gap-2">
97 <Button onClick={copy} variant="outline">
98 <CopyIcon />
99 Copy Connection Secret
100 </Button>
101 {/* For now not showing open in-app, only works well on Android, not on Desktop or iOS */}
102 {/* <ExternalLinkButton to={pairingUri} variant="outline">
103 <ExternalLinkIcon />
104 Open In App
105 </ExternalLinkButton> */}
106 </div>
107 </CardContent>
108 </Card>
109 );
110 }
111