Hey is a decentralized and permissionless social media app built with Lens Protocol 馃尶
at main 109 lines 3.0 kB view raw
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;