Hey is a decentralized and permissionless social media app built with Lens Protocol 馃尶
at main 107 lines 3.0 kB view raw
1import { Regex } from "@hey/data/regex"; 2import { useCreateGroupMutation } from "@hey/indexer"; 3import type { ApolloClientError } from "@hey/types/errors"; 4import { group } from "@lens-protocol/metadata"; 5import { useCallback, useState } from "react"; 6import { z } from "zod"; 7import AvatarUpload from "@/components/Shared/AvatarUpload"; 8import { 9 Button, 10 Form, 11 Input, 12 TextArea, 13 useZodForm 14} from "@/components/Shared/UI"; 15import errorToast from "@/helpers/errorToast"; 16import uploadMetadata from "@/helpers/uploadMetadata"; 17import useTransactionLifecycle from "@/hooks/useTransactionLifecycle"; 18import { useCreateGroupStore } from "./CreateGroup"; 19 20const ValidationSchema = z.object({ 21 description: z.string().max(260, { 22 message: "Description should not exceed 260 characters" 23 }), 24 name: z 25 .string() 26 .max(100, { message: "Name should not exceed 100 characters" }) 27 .regex(Regex.accountNameValidator, { 28 message: "Account name must not contain restricted symbols" 29 }) 30}); 31 32const CreateGroupModal = () => { 33 const { setScreen, setTransactionHash } = useCreateGroupStore(); 34 const [pfpUrl, setPfpUrl] = useState<string | undefined>(); 35 const [isSubmitting, setIsSubmitting] = useState(false); 36 const handleTransactionLifecycle = useTransactionLifecycle(); 37 38 const form = useZodForm({ 39 schema: ValidationSchema 40 }); 41 42 const onCompleted = (hash: string) => { 43 setIsSubmitting(false); 44 setTransactionHash(hash); 45 setScreen("minting"); 46 }; 47 48 const onError = useCallback((error: ApolloClientError) => { 49 setIsSubmitting(false); 50 errorToast(error); 51 }, []); 52 53 const [createGroup] = useCreateGroupMutation({ 54 onCompleted: async ({ createGroup }) => { 55 if (createGroup.__typename === "CreateGroupResponse") { 56 return onCompleted(createGroup.hash); 57 } 58 59 return await handleTransactionLifecycle({ 60 onCompleted, 61 onError, 62 transactionData: createGroup 63 }); 64 }, 65 onError 66 }); 67 68 const handleCreateGroup = async (data: z.infer<typeof ValidationSchema>) => { 69 setIsSubmitting(true); 70 71 const metadataUri = await uploadMetadata( 72 group({ 73 description: data.description || undefined, 74 icon: pfpUrl, 75 name: data.name 76 }) 77 ); 78 79 return await createGroup({ variables: { request: { metadataUri } } }); 80 }; 81 82 return ( 83 <Form className="space-y-4 p-5" form={form} onSubmit={handleCreateGroup}> 84 <Input label="Name" placeholder="Name" {...form.register("name")} /> 85 <TextArea 86 label="Description" 87 placeholder="Please provide additional details" 88 {...form.register("description")} 89 /> 90 <AvatarUpload 91 isSmall 92 setSrc={(src) => setPfpUrl(src)} 93 src={pfpUrl || ""} 94 /> 95 <Button 96 className="flex w-full justify-center" 97 disabled={isSubmitting} 98 loading={isSubmitting} 99 type="submit" 100 > 101 Create group 102 </Button> 103 </Form> 104 ); 105}; 106 107export default CreateGroupModal;