Hey is a decentralized and permissionless social media app built with Lens Protocol 馃尶
1import { CheckCircleIcon } from "@heroicons/react/24/solid";
2import {
3 type AccountFragment,
4 AccountReportReason,
5 useReportAccountMutation
6} from "@hey/indexer";
7import { useState } from "react";
8import { z } from "zod";
9import SingleAccount from "@/components/Shared/Account/SingleAccount";
10import {
11 Button,
12 Card,
13 EmptyState,
14 ErrorMessage,
15 Form,
16 Select,
17 TextArea,
18 useZodForm
19} from "@/components/Shared/UI";
20import convertToTitleCase from "@/helpers/convertToTitleCase";
21import errorToast from "@/helpers/errorToast";
22import stopEventPropagation from "@/helpers/stopEventPropagation";
23
24const ValidationSchema = z.object({
25 additionalComment: z.string().max(260, {
26 message: "Additional comments should not exceed 260 characters"
27 })
28});
29
30interface ReportAccountProps {
31 account?: AccountFragment;
32}
33
34const ReportAccount = ({ account }: ReportAccountProps) => {
35 const [reason, setReason] = useState("");
36
37 const form = useZodForm({
38 schema: ValidationSchema
39 });
40
41 const [createReport, { data, error, loading }] = useReportAccountMutation({
42 onError: (error) => errorToast(error)
43 });
44
45 const reportAccount = async ({
46 additionalComment
47 }: z.infer<typeof ValidationSchema>) => {
48 const response = await createReport({
49 variables: {
50 request: {
51 account: account?.address,
52 additionalComment,
53 reason: reason as AccountReportReason
54 }
55 }
56 });
57
58 return response;
59 };
60
61 return (
62 <div onClick={stopEventPropagation}>
63 {data?.reportAccount === null ? (
64 <EmptyState
65 hideCard
66 icon={<CheckCircleIcon className="size-14" />}
67 message="Account reported"
68 />
69 ) : account ? (
70 <div className="p-5">
71 <Card className="p-3">
72 <SingleAccount
73 account={account}
74 hideFollowButton
75 hideUnfollowButton
76 showUserPreview={false}
77 />
78 </Card>
79 <div className="divider my-5" />
80 <Form className="space-y-4" form={form} onSubmit={reportAccount}>
81 {error ? (
82 <ErrorMessage error={error} title="Failed to report" />
83 ) : null}
84 <div>
85 <div className="label">Type</div>
86 <Select
87 onChange={(value) => setReason(value)}
88 options={[
89 {
90 disabled: true,
91 label: "Select type",
92 value: "Select type"
93 },
94 ...Object.entries(AccountReportReason).map(
95 ([key, value]) => ({
96 label: convertToTitleCase(key),
97 selected: reason === value,
98 value
99 })
100 )
101 ]}
102 />
103 </div>
104 {reason ? (
105 <>
106 <TextArea
107 label="Description"
108 placeholder="Please provide additional details"
109 {...form.register("additionalComment")}
110 />
111 <Button
112 className="flex w-full justify-center"
113 disabled={loading}
114 loading={loading}
115 type="submit"
116 >
117 Report
118 </Button>
119 </>
120 ) : null}
121 </Form>
122 </div>
123 ) : null}
124 </div>
125 );
126};
127
128export default ReportAccount;