Skip to content

Commit 5a75a49

Browse files
committed
feat(ui): implement modal window with large image view
1 parent 103190c commit 5a75a49

File tree

3 files changed

+109
-17
lines changed

3 files changed

+109
-17
lines changed

src/components/App.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { Component } from 'react';
22
import Searchbar from './Searchbar';
3-
import { ImageGallery } from './ImageGallery';
3+
import ImageGallery from './ImageGallery';
44
import ImagePortalWelcome from './ImagePortalWelcome';
55
import { LoadMoreBtn } from './Button';
66
import { SearchResultInfo } from './SearchResultInfo';

src/components/ImageGallery.jsx

Lines changed: 78 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,88 @@
1+
import { Component } from 'react';
12
import { Container, Col, Row, Image } from 'react-bootstrap';
3+
import { ImageModal } from './Modal';
24

3-
export const ImageGallery = ({ images }) => (
4-
<Container className="justify-content-center">
5-
<Row xs={1} sm={2} md={3} lg={4} className="g-4">
6-
<ImageGalleryItem images={images} />
7-
</Row>
8-
</Container>
9-
);
10-
11-
const ImageGalleryItem = ({ images }) => (
12-
<>
13-
{images.map(({ id, webformatURL, largeImageURL, tags }) => (
14-
<Col key={id}>
5+
class ImageGallery extends Component {
6+
constructor(props) {
7+
super(props);
8+
9+
this.state = {
10+
showModal: false,
11+
selectedImage: null,
12+
};
13+
}
14+
15+
openModal = image => {
16+
this.setState({
17+
showModal: true,
18+
selectedImage: image,
19+
});
20+
};
21+
22+
closeModal = () => {
23+
this.setState({
24+
showModal: false,
25+
selectedImage: null,
26+
});
27+
};
28+
29+
render() {
30+
const { images } = this.props;
31+
const { showModal, selectedImage } = this.state;
32+
33+
return (
34+
<Container className="justify-content-center">
35+
<Row xs={1} sm={2} md={3} lg={4} className="g-4">
36+
{images.map(
37+
({ id, webformatURL, largeImageURL, tags, user, userImageURL }) => (
38+
<ImageGallery.Item
39+
key={id}
40+
id={id}
41+
webformatURL={webformatURL}
42+
largeImageURL={largeImageURL}
43+
tags={tags}
44+
user={user}
45+
userImageURL={userImageURL}
46+
openModal={this.openModal}
47+
/>
48+
)
49+
)}
50+
</Row>
51+
52+
<ImageModal
53+
showModal={showModal}
54+
selectedImage={selectedImage}
55+
closeModal={this.closeModal}
56+
/>
57+
</Container>
58+
);
59+
}
60+
}
61+
62+
class ImageGalleryItem extends Component {
63+
render() {
64+
const { id, largeImageURL, tags, openModal, user, userImageURL } =
65+
this.props;
66+
67+
return (
68+
<Col
69+
key={id}
70+
onClick={() =>
71+
openModal({ id, largeImageURL, tags, user, userImageURL })
72+
}
73+
>
1574
<Image
16-
src={webformatURL}
75+
src={largeImageURL}
1776
alt={tags}
77+
role="button"
1878
rounded
1979
style={{ objectFit: 'cover', height: '100%', width: '100%' }}
2080
/>
2181
</Col>
22-
))}
23-
</>
24-
);
82+
);
83+
}
84+
}
2585

2686
ImageGallery.Item = ImageGalleryItem;
87+
88+
export default ImageGallery;

src/components/Modal.jsx

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { Image, Modal } from 'react-bootstrap';
2+
3+
export const ImageModal = ({ showModal, closeModal, selectedImage }) => (
4+
<Modal show={showModal} onHide={closeModal} size="lg" centered>
5+
{selectedImage && (
6+
<>
7+
<Modal.Header closeButton>
8+
<Image
9+
src={selectedImage.userImageURL}
10+
roundedCircle
11+
width={35}
12+
height={35}
13+
className="me-2"
14+
/>
15+
<Modal.Title>{selectedImage.user}</Modal.Title>
16+
</Modal.Header>
17+
<Modal.Body className="p-0">
18+
<Image
19+
src={selectedImage.largeImageURL}
20+
alt={selectedImage.tags}
21+
fluid
22+
/>
23+
</Modal.Body>
24+
<Modal.Footer className="justify-content-start">
25+
{selectedImage.tags}
26+
</Modal.Footer>
27+
</>
28+
)}
29+
</Modal>
30+
);

0 commit comments

Comments
 (0)