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