mirror of
https://github.com/aljazceru/landscape-template.git
synced 2025-12-30 04:24:26 +01:00
feat: added screenshots lightbox
This commit is contained in:
70
package-lock.json
generated
70
package-lock.json
generated
@@ -37,6 +37,7 @@
|
||||
"react-copy-to-clipboard": "^5.0.4",
|
||||
"react-dom": "^17.0.2",
|
||||
"react-icons": "^4.3.1",
|
||||
"react-image-lightbox": "^5.1.4",
|
||||
"react-loader-spinner": "^4.0.0",
|
||||
"react-loading-skeleton": "^3.0.2",
|
||||
"react-multi-carousel": "^2.6.5",
|
||||
@@ -17859,6 +17860,11 @@
|
||||
"url": "https://github.com/sindresorhus/execa?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/exenv": {
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmjs.org/exenv/-/exenv-1.2.2.tgz",
|
||||
"integrity": "sha1-KueOhdmJQVhnCwPUe+wfA72Ru50="
|
||||
},
|
||||
"node_modules/exit": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz",
|
||||
@@ -52647,6 +52653,19 @@
|
||||
"react": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/react-image-lightbox": {
|
||||
"version": "5.1.4",
|
||||
"resolved": "https://registry.npmjs.org/react-image-lightbox/-/react-image-lightbox-5.1.4.tgz",
|
||||
"integrity": "sha512-kTiAODz091bgT7SlWNHab0LSMZAPJtlNWDGKv7pLlLY1krmf7FuG1zxE0wyPpeA8gPdwfr3cu6sPwZRqWsc3Eg==",
|
||||
"dependencies": {
|
||||
"prop-types": "^15.7.2",
|
||||
"react-modal": "^3.11.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "16.x || 17.x",
|
||||
"react-dom": "16.x || 17.x"
|
||||
}
|
||||
},
|
||||
"node_modules/react-inspector": {
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/react-inspector/-/react-inspector-5.1.1.tgz",
|
||||
@@ -52668,8 +52687,7 @@
|
||||
},
|
||||
"node_modules/react-lifecycles-compat": {
|
||||
"version": "3.0.4",
|
||||
"integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==",
|
||||
"dev": true
|
||||
"integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA=="
|
||||
},
|
||||
"node_modules/react-loader-spinner": {
|
||||
"version": "4.0.0",
|
||||
@@ -52691,6 +52709,24 @@
|
||||
"react": ">=16.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-modal": {
|
||||
"version": "3.14.4",
|
||||
"resolved": "https://registry.npmjs.org/react-modal/-/react-modal-3.14.4.tgz",
|
||||
"integrity": "sha512-8surmulejafYCH9wfUmFyj4UfbSJwjcgbS9gf3oOItu4Hwd6ivJyVBETI0yHRhpJKCLZMUtnhzk76wXTsNL6Qg==",
|
||||
"dependencies": {
|
||||
"exenv": "^1.2.0",
|
||||
"prop-types": "^15.7.2",
|
||||
"react-lifecycles-compat": "^3.0.0",
|
||||
"warning": "^4.0.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^0.14.0 || ^15.0.0 || ^16 || ^17",
|
||||
"react-dom": "^0.14.0 || ^15.0.0 || ^16 || ^17"
|
||||
}
|
||||
},
|
||||
"node_modules/react-multi-carousel": {
|
||||
"version": "2.6.5",
|
||||
"resolved": "https://registry.npmjs.org/react-multi-carousel/-/react-multi-carousel-2.6.5.tgz",
|
||||
@@ -59042,7 +59078,6 @@
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz",
|
||||
"integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"loose-envify": "^1.0.0"
|
||||
}
|
||||
@@ -74466,6 +74501,11 @@
|
||||
"strip-final-newline": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"exenv": {
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmjs.org/exenv/-/exenv-1.2.2.tgz",
|
||||
"integrity": "sha1-KueOhdmJQVhnCwPUe+wfA72Ru50="
|
||||
},
|
||||
"exit": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz",
|
||||
@@ -101219,6 +101259,15 @@
|
||||
"integrity": "sha512-cB10MXLTs3gVuXimblAdI71jrJx8njrJZmNMEMC+sQu5B/BIOmlsAjskdqpn81y8UBVEGuHODd7/ci5DvoSzTQ==",
|
||||
"requires": {}
|
||||
},
|
||||
"react-image-lightbox": {
|
||||
"version": "5.1.4",
|
||||
"resolved": "https://registry.npmjs.org/react-image-lightbox/-/react-image-lightbox-5.1.4.tgz",
|
||||
"integrity": "sha512-kTiAODz091bgT7SlWNHab0LSMZAPJtlNWDGKv7pLlLY1krmf7FuG1zxE0wyPpeA8gPdwfr3cu6sPwZRqWsc3Eg==",
|
||||
"requires": {
|
||||
"prop-types": "^15.7.2",
|
||||
"react-modal": "^3.11.1"
|
||||
}
|
||||
},
|
||||
"react-inspector": {
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/react-inspector/-/react-inspector-5.1.1.tgz",
|
||||
@@ -101237,8 +101286,7 @@
|
||||
},
|
||||
"react-lifecycles-compat": {
|
||||
"version": "3.0.4",
|
||||
"integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==",
|
||||
"dev": true
|
||||
"integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA=="
|
||||
},
|
||||
"react-loader-spinner": {
|
||||
"version": "4.0.0",
|
||||
@@ -101254,6 +101302,17 @@
|
||||
"integrity": "sha512-rlALwuZEcjazUDeIy3+fEhm20Uk9Yd/zZGeITU034K2ts5/yEf7RuZaV2FyrPWypIII4LAsFEo9WDTPKp6G0fQ==",
|
||||
"requires": {}
|
||||
},
|
||||
"react-modal": {
|
||||
"version": "3.14.4",
|
||||
"resolved": "https://registry.npmjs.org/react-modal/-/react-modal-3.14.4.tgz",
|
||||
"integrity": "sha512-8surmulejafYCH9wfUmFyj4UfbSJwjcgbS9gf3oOItu4Hwd6ivJyVBETI0yHRhpJKCLZMUtnhzk76wXTsNL6Qg==",
|
||||
"requires": {
|
||||
"exenv": "^1.2.0",
|
||||
"prop-types": "^15.7.2",
|
||||
"react-lifecycles-compat": "^3.0.0",
|
||||
"warning": "^4.0.3"
|
||||
}
|
||||
},
|
||||
"react-multi-carousel": {
|
||||
"version": "2.6.5",
|
||||
"resolved": "https://registry.npmjs.org/react-multi-carousel/-/react-multi-carousel-2.6.5.tgz",
|
||||
@@ -106183,7 +106242,6 @@
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz",
|
||||
"integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"loose-envify": "^1.0.0"
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
"react-copy-to-clipboard": "^5.0.4",
|
||||
"react-dom": "^17.0.2",
|
||||
"react-icons": "^4.3.1",
|
||||
"react-image-lightbox": "^5.1.4",
|
||||
"react-loader-spinner": "^4.0.0",
|
||||
"react-loading-skeleton": "^3.0.2",
|
||||
"react-multi-carousel": "^2.6.5",
|
||||
|
||||
52
src/Components/Lightbox/Lightbox.tsx
Normal file
52
src/Components/Lightbox/Lightbox.tsx
Normal file
@@ -0,0 +1,52 @@
|
||||
|
||||
import { useEffect, useState } from 'react';
|
||||
import LightboxComponent from 'react-image-lightbox';
|
||||
import 'react-image-lightbox/style.css'; // This only needs to be imported once in your app
|
||||
import './styles.css'
|
||||
|
||||
|
||||
interface Props {
|
||||
images: string[];
|
||||
isOpen?: boolean;
|
||||
onClose?: () => void;
|
||||
initOpenIndex?: number;
|
||||
}
|
||||
|
||||
export default function Lightbox(props: Props) {
|
||||
|
||||
const [photoIndex, setPhotoIndex] = useState(0);
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (props.isOpen) {
|
||||
setIsOpen(true);
|
||||
setPhotoIndex(props.initOpenIndex ?? 0)
|
||||
} else
|
||||
setIsOpen(false);
|
||||
|
||||
}, [props.initOpenIndex, props.isOpen])
|
||||
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
{isOpen && <div className="z-[100000111]">
|
||||
<LightboxComponent
|
||||
wrapperClassName='fixed z-[10000022]'
|
||||
mainSrc={props.images[photoIndex]}
|
||||
nextSrc={props.images[(photoIndex + 1) % props.images.length]}
|
||||
prevSrc={props.images[(photoIndex + props.images.length - 1) % props.images.length]}
|
||||
onCloseRequest={() => props.onClose?.()}
|
||||
onMovePrevRequest={() =>
|
||||
setPhotoIndex((photoIndex + props.images.length - 1) % props.images.length
|
||||
)
|
||||
}
|
||||
onMoveNextRequest={() =>
|
||||
setPhotoIndex((photoIndex + 1) % props.images.length)
|
||||
}
|
||||
imagePadding={48}
|
||||
/>
|
||||
</div>}
|
||||
</>
|
||||
)
|
||||
}
|
||||
3
src/Components/Lightbox/styles.css
Normal file
3
src/Components/Lightbox/styles.css
Normal file
@@ -0,0 +1,3 @@
|
||||
.ReactModal__Overlay {
|
||||
z-index: 10000 !important;
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
import { useState } from 'react'
|
||||
import { BsJoystick } from 'react-icons/bs'
|
||||
import { MdClose, MdLocalFireDepartment } from 'react-icons/md';
|
||||
import { ModalCard } from 'src/Components/Modals/ModalsContainer/ModalsContainer';
|
||||
@@ -10,6 +11,7 @@ import ProjectCardSkeleton from './ProjectDetailsCard.Skeleton'
|
||||
import VoteButton from 'src/pages/ProjectPage/VoteButton/VoteButton';
|
||||
import { Wallet_Service } from 'src/services'
|
||||
import { useProjectDetailsQuery } from 'src/graphql';
|
||||
import Lightbox from 'src/Components/Lightbox/Lightbox'
|
||||
|
||||
|
||||
interface Props extends ModalCard {
|
||||
@@ -19,6 +21,8 @@ interface Props extends ModalCard {
|
||||
export default function ProjectDetailsCard({ onClose, direction, projectId, ...props }: Props) {
|
||||
|
||||
const dispatch = useAppDispatch();
|
||||
const [screenshotsOpen, setScreenshotsOpen] = useState(-1);
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -113,14 +117,26 @@ export default function ProjectDetailsCard({ onClose, direction, projectId, ...p
|
||||
<Button size='md' fullWidth className="bg-gray-200 hover:bg-gray-100 mb-24" onClick={onConnectWallet}><AiFillThunderbolt className='inline-block text-thunder transform scale-125' /> Connect Wallet to Vote</Button>
|
||||
}
|
||||
</div>
|
||||
{project.screenshots.length > 0 && <div className="mt-40">
|
||||
<h3 className="text-h5 font-bold mb-16">Screenshots</h3>
|
||||
<div className="grid grid-cols-2 gap-12 justify-items-center md:gap-24">
|
||||
{project.screenshots.map((screenshot, idx) => <div key={idx} className="w-full relative pt-[56%]">
|
||||
<img src={screenshot} className="absolute top-0 left-0 w-full h-full object-cover bg-gray-300 rounded-xl" alt='' />
|
||||
</div>)}
|
||||
{project.screenshots.length > 0 && <>
|
||||
<div className="mt-40">
|
||||
<h3 className="text-h5 font-bold mb-16">Screenshots</h3>
|
||||
<div className="grid grid-cols-2 gap-12 justify-items-center md:gap-24">
|
||||
{project.screenshots.map((screenshot, idx) => <div
|
||||
key={idx}
|
||||
className="w-full relative pt-[56%] cursor-pointer"
|
||||
onClick={() => setScreenshotsOpen(idx)}
|
||||
>
|
||||
<img src={screenshot} className="absolute top-0 left-0 w-full h-full object-cover bg-gray-300 rounded-xl" alt='' />
|
||||
</div>)}
|
||||
</div>
|
||||
</div>
|
||||
</div>}
|
||||
<Lightbox
|
||||
images={project.screenshots}
|
||||
isOpen={screenshotsOpen !== -1}
|
||||
initOpenIndex={screenshotsOpen}
|
||||
onClose={() => setScreenshotsOpen(-1)}
|
||||
/>
|
||||
</>}
|
||||
<hr className="my-40" />
|
||||
<div className="text-center">
|
||||
<h3 className="text-body4 font-regular">Are you the creator of this project?</h3>
|
||||
|
||||
Reference in New Issue
Block a user