Hey is a decentralized and permissionless social media app built with Lens Protocol 馃尶
1import { BeakerIcon, XCircleIcon } from "@heroicons/react/24/solid";
2import { BANNER_IDS, PERMISSIONS } from "@hey/data/constants";
3import {
4 useAddPostNotInterestedMutation,
5 useJoinGroupMutation
6} from "@hey/indexer";
7import type { ApolloClientError } from "@hey/types/errors";
8import { useCallback, useState } from "react";
9import { toast } from "sonner";
10import { Badge, Button, Card, H5 } from "@/components/Shared/UI";
11import errorToast from "@/helpers/errorToast";
12import useTransactionLifecycle from "@/hooks/useTransactionLifecycle";
13import useWaitForTransactionToComplete from "@/hooks/useWaitForTransactionToComplete";
14import { useAccountStore } from "@/store/persisted/useAccountStore";
15import { useBetaStore } from "@/store/persisted/useBetaStore";
16
17const BetaBanner = () => {
18 const { currentAccount } = useAccountStore();
19 const { betaBannerDismissed, setBetaBannerDismissed } = useBetaStore();
20 const handleTransactionLifecycle = useTransactionLifecycle();
21 const waitForTransactionToComplete = useWaitForTransactionToComplete();
22 const [isSubmitting, setIsSubmitting] = useState(false);
23
24 const onCompleted = async (hash: string) => {
25 await waitForTransactionToComplete(hash);
26 location.reload();
27 };
28
29 const onError = useCallback((error: ApolloClientError) => {
30 errorToast(error);
31 }, []);
32
33 const [dismissBetaBanner, { loading }] = useAddPostNotInterestedMutation({
34 onCompleted: () => {
35 toast.success("Dismissed");
36 setBetaBannerDismissed(true);
37 },
38 onError,
39 variables: { request: { post: BANNER_IDS.BETA } }
40 });
41
42 const [joinGroup] = useJoinGroupMutation({
43 onCompleted: async ({ joinGroup }) => {
44 if (joinGroup.__typename === "JoinGroupResponse") {
45 return onCompleted(joinGroup.hash);
46 }
47
48 return await handleTransactionLifecycle({
49 onCompleted,
50 onError,
51 transactionData: joinGroup
52 });
53 },
54 onError
55 });
56
57 if (!currentAccount?.hasSubscribed) {
58 return null;
59 }
60
61 if (currentAccount?.isBeta || betaBannerDismissed) {
62 return null;
63 }
64
65 const handleDismissBetaBanner = async () => {
66 return await dismissBetaBanner();
67 };
68
69 const handleJoinBeta = async () => {
70 setIsSubmitting(true);
71
72 return await joinGroup({
73 variables: { request: { group: PERMISSIONS.BETA } }
74 });
75 };
76
77 return (
78 <Card className="relative space-y-2">
79 <button
80 className="absolute top-3 right-3 cursor-pointer text-gray-400 hover:text-gray-600"
81 disabled={loading}
82 onClick={handleDismissBetaBanner}
83 type="button"
84 >
85 <XCircleIcon className="size-5" />
86 </button>
87 <div className="m-5">
88 <div className="flex items-center gap-2">
89 <BeakerIcon className="size-5 text-green-500" />
90 <H5>Join Hey Beta</H5>
91 <Badge>Pro</Badge>
92 </div>
93 <div className="mb-5 text-sm">
94 Get your badge and access exclusive features.
95 </div>
96 <Button
97 className="w-full"
98 loading={isSubmitting}
99 onClick={handleJoinBeta}
100 outline
101 >
102 Get Beta Access
103 </Button>
104 </div>
105 </Card>
106 );
107};
108
109export default BetaBanner;