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