mirror of
https://github.com/woodchen-ink/CoverView.git
synced 2025-07-18 05:51:56 +08:00
feat: integrate with unsplash in stylish theme
This commit is contained in:
parent
2c486fb92b
commit
be27d89435
3
.gitignore
vendored
3
.gitignore
vendored
@ -12,6 +12,7 @@
|
|||||||
/build
|
/build
|
||||||
|
|
||||||
# misc
|
# misc
|
||||||
|
.env
|
||||||
.DS_Store
|
.DS_Store
|
||||||
.env.local
|
.env.local
|
||||||
.env.development.local
|
.env.development.local
|
||||||
@ -21,3 +22,5 @@
|
|||||||
npm-debug.log*
|
npm-debug.log*
|
||||||
yarn-debug.log*
|
yarn-debug.log*
|
||||||
yarn-error.log*
|
yarn-error.log*
|
||||||
|
|
||||||
|
|
||||||
|
25
package-lock.json
generated
25
package-lock.json
generated
@ -3327,6 +3327,11 @@
|
|||||||
"@types/node": "*"
|
"@types/node": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@types/content-type": {
|
||||||
|
"version": "1.1.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/content-type/-/content-type-1.1.5.tgz",
|
||||||
|
"integrity": "sha512-dgMN+syt1xb7Hk8LU6AODOfPlvz5z1CbXpPuJE5ZrX9STfBOIXF09pEB8N7a97WT9dbngt3ksDCm6GW6yMrxfQ=="
|
||||||
|
},
|
||||||
"@types/eslint": {
|
"@types/eslint": {
|
||||||
"version": "7.29.0",
|
"version": "7.29.0",
|
||||||
"resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.29.0.tgz",
|
"resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.29.0.tgz",
|
||||||
@ -5820,9 +5825,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dotenv": {
|
"dotenv": {
|
||||||
"version": "10.0.0",
|
"version": "16.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.1.tgz",
|
||||||
"integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q=="
|
"integrity": "sha512-1K6hR6wtk2FviQ4kEiSjFiH5rpzEVi8WW0x96aztHVMhEspNpc4DVOUTEHtEva5VThQ8IaBX1Pe4gSzpVVUsKQ=="
|
||||||
},
|
},
|
||||||
"dotenv-expand": {
|
"dotenv-expand": {
|
||||||
"version": "5.1.0",
|
"version": "5.1.0",
|
||||||
@ -12483,6 +12488,11 @@
|
|||||||
"workbox-webpack-plugin": "^6.4.1"
|
"workbox-webpack-plugin": "^6.4.1"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"dotenv": {
|
||||||
|
"version": "10.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz",
|
||||||
|
"integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q=="
|
||||||
|
},
|
||||||
"path-parse": {
|
"path-parse": {
|
||||||
"version": "1.0.7",
|
"version": "1.0.7",
|
||||||
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
|
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
|
||||||
@ -14069,6 +14079,15 @@
|
|||||||
"resolved": "https://registry.npmjs.org/unquote/-/unquote-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/unquote/-/unquote-1.1.1.tgz",
|
||||||
"integrity": "sha1-j97XMk7G6IoP+LkF58CYzcCG1UQ="
|
"integrity": "sha1-j97XMk7G6IoP+LkF58CYzcCG1UQ="
|
||||||
},
|
},
|
||||||
|
"unsplash-js": {
|
||||||
|
"version": "7.0.15",
|
||||||
|
"resolved": "https://registry.npmjs.org/unsplash-js/-/unsplash-js-7.0.15.tgz",
|
||||||
|
"integrity": "sha512-WGqKp9wl2m2tAUPyw2eMZs/KICR+A52tCaRapzVXWxkA4pjHqsaGwiJXTEW7hBy4Pu0QmP6KxTt2jST3tluawA==",
|
||||||
|
"requires": {
|
||||||
|
"@types/content-type": "^1.1.3",
|
||||||
|
"content-type": "^1.0.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
"upath": {
|
"upath": {
|
||||||
"version": "1.2.0",
|
"version": "1.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz",
|
||||||
|
@ -6,11 +6,13 @@
|
|||||||
"@testing-library/jest-dom": "^4.2.4",
|
"@testing-library/jest-dom": "^4.2.4",
|
||||||
"@testing-library/react": "^9.5.0",
|
"@testing-library/react": "^9.5.0",
|
||||||
"@testing-library/user-event": "^7.2.1",
|
"@testing-library/user-event": "^7.2.1",
|
||||||
|
"dotenv": "^16.0.1",
|
||||||
"react": "^16.13.1",
|
"react": "^16.13.1",
|
||||||
"react-component-export-image": "^0.1.6",
|
"react-component-export-image": "^0.1.6",
|
||||||
"react-dom": "^16.13.1",
|
"react-dom": "^16.13.1",
|
||||||
"react-scripts": "^5.0.1",
|
"react-scripts": "^5.0.1",
|
||||||
"react-select": "^3.1.0"
|
"react-select": "^3.1.0",
|
||||||
|
"unsplash-js": "^7.0.15"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "react-scripts start",
|
"start": "react-scripts start",
|
||||||
|
@ -1,17 +1,19 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import Editor from './Editor';
|
import Editor from './Editor';
|
||||||
import Info from './Info'
|
import Info from './Info'
|
||||||
class App extends React.Component {
|
import { ImgProvider } from '../utils/ImgContext'
|
||||||
|
|
||||||
render() {
|
const App = () => {
|
||||||
return (
|
|
||||||
<div className="">
|
return (
|
||||||
|
<ImgProvider>
|
||||||
|
<div>
|
||||||
<Editor />
|
<Editor />
|
||||||
<Info/>
|
<Info />
|
||||||
</div>
|
</div>
|
||||||
);
|
</ImgProvider>
|
||||||
}
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export default App;
|
export default App;
|
@ -1,28 +1,34 @@
|
|||||||
import React from "react";
|
import React, { useContext } from "react";
|
||||||
import { exportComponentAsPNG } from "react-component-export-image";
|
import { exportComponentAsPNG } from "react-component-export-image";
|
||||||
import "./CoverImage.css";
|
import "./CoverImage.css";
|
||||||
|
import { ImgContext } from "../utils/ImgContext";
|
||||||
|
import unsplash from "../utils/unsplashConfig";
|
||||||
|
|
||||||
class ComponentToImg extends React.Component {
|
const ComponentToImg = (props) => {
|
||||||
constructor(props) {
|
|
||||||
super(props);
|
const { unsplashImage } = useContext(ImgContext);
|
||||||
this.componentRef = React.createRef();
|
const componentRef = React.createRef();
|
||||||
|
|
||||||
|
// download image and trigger download on unsplash api
|
||||||
|
const downloadImage = () => {
|
||||||
|
exportComponentAsPNG(componentRef, 'cover')
|
||||||
|
unsplash.photos.trackDownload({ downloadLocation: unsplashImage.downloadLink, });
|
||||||
|
console.log(unsplashImage.downloadLink)
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<React.Fragment>
|
||||||
|
<div ref={componentRef}>{props.children}</div>
|
||||||
|
<button
|
||||||
|
className="border p-2 bg-gray-700 hover:bg-gray-800 flex items-center text-white text-xl rounded-lg m-4 px-4"
|
||||||
|
onClick={() => downloadImage()}>
|
||||||
|
<svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4"></path></svg>
|
||||||
|
<span className="mx-2">Download</span>
|
||||||
|
</button>
|
||||||
|
</React.Fragment>
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
|
||||||
<React.Fragment>
|
|
||||||
<div ref={this.componentRef}>{this.props.children}</div>
|
|
||||||
<button
|
|
||||||
className="border p-2 bg-gray-700 hover:bg-gray-800 flex items-center text-white text-xl rounded-lg m-4 px-4"
|
|
||||||
onClick={() => exportComponentAsPNG(this.componentRef, 'cover')}>
|
|
||||||
<svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4"></path></svg>
|
|
||||||
<span className="mx-2">Download</span>
|
|
||||||
</button>
|
|
||||||
</React.Fragment>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default ComponentToImg;
|
export default ComponentToImg;
|
||||||
|
@ -5,6 +5,8 @@ import ModernTheme from "./Themes/ModernTheme";
|
|||||||
import BasicTheme from "./Themes/BasicTheme";
|
import BasicTheme from "./Themes/BasicTheme";
|
||||||
import OutlineTheme from "./Themes/OutlineTheme";
|
import OutlineTheme from "./Themes/OutlineTheme";
|
||||||
import PreviewTheme from "./Themes/PreviewTheme";
|
import PreviewTheme from "./Themes/PreviewTheme";
|
||||||
|
import StylishTheme from "./Themes/StylishTheme";
|
||||||
|
|
||||||
|
|
||||||
const CoverImage = (props) => {
|
const CoverImage = (props) => {
|
||||||
// hexToRgbA(hex, opacity) {
|
// hexToRgbA(hex, opacity) {
|
||||||
@ -28,6 +30,7 @@ const CoverImage = (props) => {
|
|||||||
case 'modern': return <ModernTheme config={props} />
|
case 'modern': return <ModernTheme config={props} />
|
||||||
case 'outline': return <OutlineTheme config={props} />
|
case 'outline': return <OutlineTheme config={props} />
|
||||||
case 'preview': return <PreviewTheme config={props} />
|
case 'preview': return <PreviewTheme config={props} />
|
||||||
|
case 'stylish': return <StylishTheme config={props} />
|
||||||
|
|
||||||
default: return <BasicTheme config={props} />
|
default: return <BasicTheme config={props} />
|
||||||
}
|
}
|
||||||
|
@ -7,16 +7,16 @@ import RandomTheme from './RandomTheme';
|
|||||||
|
|
||||||
const defaultSettings = {
|
const defaultSettings = {
|
||||||
title: "How I built my first project with react",
|
title: "How I built my first project with react",
|
||||||
bgColor: "#fee856",
|
bgColor: "#ffe9e3",
|
||||||
pattern: "",
|
pattern: "",
|
||||||
download: "PNG",
|
download: "PNG",
|
||||||
author: 'Rutik Wankhade',
|
author: 'Rutik Wankhade',
|
||||||
icon: { 'label': 'react', 'value': 'react' },
|
icon: { 'label': 'react', 'value': 'react' },
|
||||||
devIconOptions: {},
|
devIconOptions: {},
|
||||||
font: 'font-Anek',
|
font: 'font-Anek',
|
||||||
theme: 'modern',
|
theme: 'stylish',
|
||||||
customIcon: '',
|
customIcon: '',
|
||||||
platform:'hashnode'
|
platform: 'hashnode'
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -29,6 +29,8 @@ const devIconsUrl = "https://raw.githubusercontent.com/devicons/devicon/master/d
|
|||||||
|
|
||||||
class Editor extends React.Component {
|
class Editor extends React.Component {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
state = defaultSettings;
|
state = defaultSettings;
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
console.log("Mount")
|
console.log("Mount")
|
||||||
@ -56,7 +58,6 @@ class Editor extends React.Component {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<div className="flex md:flex-row flex-col bg-gray-50 ">
|
<div className="flex md:flex-row flex-col bg-gray-50 ">
|
||||||
@ -189,10 +190,13 @@ class Editor extends React.Component {
|
|||||||
value={this.state.theme}
|
value={this.state.theme}
|
||||||
|
|
||||||
className="focus:outline-none text-gray-700 text-xl p-2 rounded border">
|
className="focus:outline-none text-gray-700 text-xl p-2 rounded border">
|
||||||
<option>basic</option>
|
<option>stylish</option>
|
||||||
<option>modern</option>
|
<option>modern</option>
|
||||||
<option>outline</option>
|
<option>basic</option>
|
||||||
<option>preview</option>
|
<option>preview</option>
|
||||||
|
<option>outline</option>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
@ -201,19 +205,19 @@ class Editor extends React.Component {
|
|||||||
|
|
||||||
|
|
||||||
<div className="flex flex-col m-2">
|
<div className="flex flex-col m-2">
|
||||||
<span className="font-medium">Platform</span>
|
<span className="font-medium">Platform</span>
|
||||||
|
|
||||||
<select
|
<select
|
||||||
onChange={(e) => this.setState({ platform: e.target.value })}
|
onChange={(e) => this.setState({ platform: e.target.value })}
|
||||||
value={this.state.platform}
|
value={this.state.platform}
|
||||||
|
|
||||||
className="focus:outline-none text-gray-700 text-xl p-2 rounded border">
|
className="focus:outline-none text-gray-700 text-xl p-2 rounded border">
|
||||||
<option>hashnode</option>
|
<option>hashnode</option>
|
||||||
<option>dev</option>
|
<option>dev</option>
|
||||||
|
|
||||||
|
|
||||||
</select>
|
|
||||||
</div>
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<span className="text-sm mt-4 text-center text-gray-400">Made with 💖 by <a href="https://rutikwankhade.dev"
|
<span className="text-sm mt-4 text-center text-gray-400">Made with 💖 by <a href="https://rutikwankhade.dev"
|
||||||
|
162
src/components/Themes/StylishTheme.js
Normal file
162
src/components/Themes/StylishTheme.js
Normal file
@ -0,0 +1,162 @@
|
|||||||
|
import React, { useState, useEffect, useContext } from 'react';
|
||||||
|
import unsplash from "../../utils/unsplashConfig";
|
||||||
|
import { ImgContext } from '../../utils/ImgContext';
|
||||||
|
|
||||||
|
const StylishTheme = ({ config }) => {
|
||||||
|
const { bgColor, title, author, font, icon, customIcon, platform } = config;
|
||||||
|
|
||||||
|
// const [image, setImage] = useState({})
|
||||||
|
|
||||||
|
const [imageList, setImageList] = useState([]);
|
||||||
|
const [searchText, setSearchText] = useState('dev');
|
||||||
|
|
||||||
|
const { unsplashImage, setUnsplashImage } = useContext(ImgContext);
|
||||||
|
|
||||||
|
const searchImages = () => {
|
||||||
|
|
||||||
|
unsplash.search
|
||||||
|
.getPhotos({
|
||||||
|
query: searchText,
|
||||||
|
page: 1,
|
||||||
|
per_page: 25
|
||||||
|
|
||||||
|
|
||||||
|
})
|
||||||
|
.then(response => {
|
||||||
|
// console.log(response.response.results);
|
||||||
|
setImageList(response.response.results)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
|
||||||
|
unsplash.search
|
||||||
|
.getPhotos({
|
||||||
|
query: 'dev',
|
||||||
|
page: 1,
|
||||||
|
per_page: 25
|
||||||
|
|
||||||
|
})
|
||||||
|
.then(response => {
|
||||||
|
// console.log(response.response.results);
|
||||||
|
setImageList(response.response.results)
|
||||||
|
});
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
const selectImage = (image) => {
|
||||||
|
setUnsplashImage({
|
||||||
|
url: image.urls.regular,
|
||||||
|
name: image.user.name,
|
||||||
|
avatar: image.user.profile_image.small,
|
||||||
|
profile: `${image.user.links.html}?utm_source=https://coverview.vercel.app&utm_medium=referral`,
|
||||||
|
downloadLink: image.links.download_location
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
// unsplash.photos.trackDownload({ downloadLocation: image.links.download_location, });
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className=" bg-white rounded">
|
||||||
|
|
||||||
|
|
||||||
|
<div className={`overflow-y-hidden flex flex-col rounded ${platform}`}
|
||||||
|
style={{ backgroundColor: bgColor }}
|
||||||
|
>
|
||||||
|
|
||||||
|
<div className="flex flex-row items-center justify-center p-4 ">
|
||||||
|
|
||||||
|
<div className="h-full w-1/2 bg-white rounded-l-xl">
|
||||||
|
<div className={`${font} px-12 justify-center text-left rounded-xl h-full p-4 flex flex-col`}>
|
||||||
|
<h1 className=" text-4xl font-bold text-gray-800">{title}</h1>
|
||||||
|
<div className="flex items-center mt-10 text-left">
|
||||||
|
{
|
||||||
|
customIcon ?
|
||||||
|
<div className="w-12 h-12 ">
|
||||||
|
<img src={customIcon} alt="img" className="rounded-full bg-white p-1 border-white" />
|
||||||
|
</div>
|
||||||
|
:
|
||||||
|
<div className="mr-2 items-center justify-center flex">
|
||||||
|
<i className={`devicon-${icon.value}-plain dev-icon text-3xl`}></i>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
<h2 className="text-xl font-semibold text-left ">{author}</h2>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="w-1/2 h-96">
|
||||||
|
|
||||||
|
|
||||||
|
{unsplashImage ?
|
||||||
|
<div className='relative group'>
|
||||||
|
<img src={unsplashImage.url && unsplashImage.url} className=" rounded-r-xl object-cover h-96 w-full" alt="preview" />
|
||||||
|
<button
|
||||||
|
onClick={() => setUnsplashImage('')}
|
||||||
|
className="absolute top-4 right-2 cursor-pointer">
|
||||||
|
<svg className="group-hover:inline-block hidden w-6 h-6 text-gray-800 bg-white p-1 rounded-full z-10" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M6 18L18 6M6 6l12 12"></path></svg>
|
||||||
|
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<div className="absolute bottom-4 right-4 opacity-80">
|
||||||
|
<div className=" group-hover:flex hidden items-center">
|
||||||
|
<span className="text-sm text-white mx-2">Photo by</span>
|
||||||
|
<a href={unsplashImage.profile} target="_blank" rel="noreferrer" className="cursor-pointer flex items-center bg-gray-300 rounded-full text-sm">
|
||||||
|
<img src={unsplashImage.avatar && unsplashImage.avatar} alt={unsplashImage.name} className="h-6 w-6 rounded-full mr-2" />
|
||||||
|
|
||||||
|
<span className="pr-2">{unsplashImage.name}</span>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<a href="https://unsplash.com/?utm_source=https://coverview.vercel.app&utm_medium=referral" className="text-sm text-white mx-2">Unsplash</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
:
|
||||||
|
<div className="flex flex-col p-2 bg-white items-center justify-center">
|
||||||
|
|
||||||
|
<div className="flex bg-gray-50 rounded-full border mb-2">
|
||||||
|
<input type="text"
|
||||||
|
value={searchText}
|
||||||
|
placeholder="Search image"
|
||||||
|
className="focus:outline-none w-max text-lg bg-gray-50 p-1 px-4 rounded-full border border-gray-50"
|
||||||
|
onChange={(e) => setSearchText(e.target.value)}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<button onClick={() => searchImages(searchText)}>
|
||||||
|
<svg className="w-9 h-9 p-2 bg-gray-700 hover:bg-gray-800 text-white rounded-full" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"></path></svg>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div className="overflow-y-scroll overflow-x-hidden h-80">
|
||||||
|
{
|
||||||
|
imageList.map(image => {
|
||||||
|
return <img src={image.urls.regular}
|
||||||
|
key={image.id}
|
||||||
|
alt={image.alt_description}
|
||||||
|
className="rounded m-2 cursor-pointer"
|
||||||
|
onClick={() => selectImage(image)
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default StylishTheme;
|
14
src/utils/ImgContext.js
Normal file
14
src/utils/ImgContext.js
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import React, { createContext, useState } from "react";
|
||||||
|
const ImgContext = createContext();
|
||||||
|
|
||||||
|
const ImgProvider = ({ children }) => {
|
||||||
|
const [unsplashImage, setUnsplashImage] = useState();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ImgContext.Provider value={{ unsplashImage, setUnsplashImage }}>
|
||||||
|
{children}
|
||||||
|
</ImgContext.Provider>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export {ImgProvider, ImgContext}
|
8
src/utils/unsplashConfig.js
Normal file
8
src/utils/unsplashConfig.js
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
import { createApi } from 'unsplash-js';
|
||||||
|
|
||||||
|
const key= process.env.REACT_APP_API_ACCESS_KEY
|
||||||
|
const unsplash = createApi({
|
||||||
|
accessKey: key
|
||||||
|
});
|
||||||
|
|
||||||
|
export default unsplash;
|
Loading…
x
Reference in New Issue
Block a user