Hey is a decentralized and permissionless social media app built with Lens Protocol 馃尶
at main 97 lines 2.8 kB view raw
1import { InformationCircleIcon } from "@heroicons/react/24/outline"; 2import { TRANSFORMS } from "@hey/data/constants"; 3import sanitizeDStorageUrl from "@hey/helpers/sanitizeDStorageUrl"; 4import type { SyntheticEvent } from "react"; 5import Cropper from "react-easy-crop"; 6import ChooseFile from "@/components/Shared/ChooseFile"; 7import { Button, Image, Modal } from "@/components/Shared/UI"; 8import useImageCropUpload from "@/hooks/useImageCropUpload"; 9 10interface CoverUploadProps { 11 src: string; 12 setSrc: (src: string) => void; 13} 14 15const CoverUpload = ({ src, setSrc }: CoverUploadProps) => { 16 const { 17 pictureSrc, 18 crop, 19 setCrop, 20 zoom, 21 setZoom, 22 showModal, 23 uploading, 24 uploadedPicture, 25 renderPictureUrl, 26 onFileChange, 27 onCropComplete, 28 handleUploadAndSave, 29 handleModalClose 30 } = useImageCropUpload({ 31 aspect: 1350 / 350, 32 label: "cover", 33 setSrc, 34 src, 35 transform: TRANSFORMS.COVER 36 }); 37 38 return ( 39 <> 40 <div className="space-y-1.5"> 41 <div className="label">Cover</div> 42 <div className="space-y-3"> 43 <div> 44 <Image 45 alt="Cover picture crop preview" 46 className="h-[175px] w-[675px] rounded-lg object-cover" 47 onError={(event: SyntheticEvent<HTMLImageElement>) => { 48 const target = event.currentTarget; 49 target.src = sanitizeDStorageUrl(src); 50 }} 51 src={uploadedPicture || renderPictureUrl} 52 /> 53 </div> 54 <ChooseFile onChange={(event) => onFileChange(event)} /> 55 </div> 56 </div> 57 <Modal 58 onClose={handleModalClose} 59 show={showModal} 60 size="lg" 61 title="Crop cover picture" 62 > 63 <div className="space-y-5 p-5"> 64 <div className="relative flex size-64 w-full"> 65 <Cropper 66 aspect={1350 / 350} 67 crop={crop} 68 image={pictureSrc} 69 onCropChange={setCrop} 70 onCropComplete={onCropComplete} 71 onZoomChange={setZoom} 72 zoom={zoom} 73 /> 74 </div> 75 <div className="flex w-full flex-wrap items-center justify-between gap-y-3"> 76 <div className="flex items-center space-x-1 text-left text-gray-500 text-sm dark:text-gray-200"> 77 <InformationCircleIcon className="size-4" /> 78 <div> 79 Optimal cover picture size is <b>1350x350</b> 80 </div> 81 </div> 82 <Button 83 disabled={uploading || !pictureSrc} 84 loading={uploading} 85 onClick={handleUploadAndSave} 86 type="submit" 87 > 88 Upload 89 </Button> 90 </div> 91 </div> 92 </Modal> 93 </> 94 ); 95}; 96 97export default CoverUpload;