@@ -10,9 +10,14 @@ import ReactCrop, {
1010
1111import { Button , Input } from "@/components" ;
1212import { useToast } from "@/context/ToastContext" ;
13- import { CursorArrowRaysIcon , XCircleIcon } from "@heroicons/react/24/outline" ;
13+ import {
14+ CursorArrowRaysIcon ,
15+ PhotoIcon ,
16+ XCircleIcon ,
17+ } from "@heroicons/react/24/outline" ;
1418import "react-image-crop/dist/ReactCrop.css" ;
1519import { getCroppedImage , isValidHttpUrl } from "./utils" ;
20+ import { PEXELS_QUERY_STRINGS } from "../constants" ;
1621
1722interface Props {
1823 aspect : number ;
@@ -74,11 +79,11 @@ const ImagePicker: React.FC<Props> = ({ aspect, children, onChange }) => {
7479 } ;
7580
7681 // function to fetch image data from image link
77- const getBase64FromUrl = async ( ) => {
78- if ( isValidHttpUrl ( imageLink ) ) {
82+ const getBase64FromUrl = async ( link ?: string ) => {
83+ if ( isValidHttpUrl ( link ?? imageLink ) ) {
7984 try {
8085 setFetchingImage ( true ) ;
81- let blob = await fetch ( imageLink ) . then ( ( r ) => r . blob ( ) ) ;
86+ let blob = await fetch ( link ?? imageLink ) . then ( ( r ) => r . blob ( ) ) ;
8287
8388 let dataUrl = await new Promise ( ( resolve ) => {
8489 let reader = new FileReader ( ) ;
@@ -133,6 +138,33 @@ const ImagePicker: React.FC<Props> = ({ aspect, children, onChange }) => {
133138 onChange ( null ) ;
134139 } ;
135140
141+ const fetchImageFromPexels = async ( ) => {
142+ try {
143+ const headers = new Headers ( ) ;
144+ headers . append (
145+ "Authorization" ,
146+ process . env . NEXT_PUBLIC_PEXELS_API_KEY ?? ""
147+ ) ;
148+ const res = await fetch (
149+ `${ process . env . NEXT_PUBLIC_PEXELS_QUERY_URL } /search?query=${
150+ PEXELS_QUERY_STRINGS [
151+ Math . floor ( Math . random ( ) * PEXELS_QUERY_STRINGS . length )
152+ ]
153+ } &per_page=1`,
154+ {
155+ method : "GET" ,
156+ headers,
157+ }
158+ ) ;
159+ const pictures = await res . json ( ) ;
160+ if ( pictures ?. photos . length ) {
161+ getBase64FromUrl ( pictures ?. photos [ 0 ] ?. src ?. medium ) ;
162+ }
163+ } catch ( error ) {
164+ console . log ( "Error while fetching images from pexels " , error ) ;
165+ }
166+ } ;
167+
136168 useEffect ( ( ) => {
137169 getBase64FromCanvas ( ) ;
138170 } , [ completedCrop ] ) ;
@@ -152,7 +184,7 @@ const ImagePicker: React.FC<Props> = ({ aspect, children, onChange }) => {
152184 leaveTo = "transform opacity-0 scale-95"
153185 >
154186 < Menu . Items className = "absolute md:w-96 w-72 p-3 right-0 z-30 top-full mt-2 origin-top-right dark:bg-black bg-white overflow-auto text-sm rounded-sm outline outline-[1px] dark:outline-zinc-400 outline-zinc-300 dark:dark:text-white text-zinc-900" >
155- < div className = "flex md:flex-row flex-col justify-start items-end w-full gap-2 mb-4 " >
187+ < div className = "flex md:flex-row flex-col justify-start items-end w-full gap-2 mb-3 " >
156188 < Input
157189 label = "Image url"
158190 className = "w-full"
@@ -166,9 +198,9 @@ const ImagePicker: React.FC<Props> = ({ aspect, children, onChange }) => {
166198 < Button
167199 disabled = { fetchingImage }
168200 className = "mb-[1px]"
169- onClick = { getBase64FromUrl }
201+ onClick = { ( ) => getBase64FromUrl ( ) }
170202 >
171- { fetchingImage ? "Fetching..." : " Upload" }
203+ Upload
172204 </ Button >
173205 </ div >
174206 < label
@@ -185,6 +217,12 @@ const ImagePicker: React.FC<Props> = ({ aspect, children, onChange }) => {
185217 accept = "image/*"
186218 onChange = { onSelectFile }
187219 />
220+ < button
221+ onClick = { fetchImageFromPexels }
222+ className = "w-full mt-3 inline-flex items-center text-center dark:border-zinc-400 border-zinc-400 rounded-sm px-2 py-1 border-[1px] text-zinc-900 dark:text-white"
223+ >
224+ < PhotoIcon className = "h-4 w-4 mr-2" /> From pexels
225+ </ button >
188226 { ! ! src && (
189227 < div className = "w-full flex flex-col justify-start items-end" >
190228 < button onClick = { resetImageSelection } >
0 commit comments