Skip to content

Commit

Permalink
feat: add step photo modal
Browse files Browse the repository at this point in the history
  • Loading branch information
antoine-giret committed Mar 17, 2024
1 parent 7e022ec commit a63c5cd
Show file tree
Hide file tree
Showing 3 changed files with 158 additions and 47 deletions.
92 changes: 92 additions & 0 deletions src/templates/trip/photo-modal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import {
Box,
Button,
Icon,
Modal,
ModalBody,
ModalCloseButton,
ModalContent,
ModalFooter,
ModalHeader,
ModalOverlay,
Text,
} from '@chakra-ui/react';
import { GatsbyImage, IGatsbyImageData } from 'gatsby-plugin-image';
import React, { useEffect } from 'react';
import { IoChevronBack, IoChevronForward } from 'react-icons/io5';

function PhotoModal({
open,
images,
selectedImageIndex,
toggle,
selectImageIndex,
}: {
images: { description: string; image: IGatsbyImageData }[];
selectedImageIndex: number;
selectImageIndex: (index: number) => void;
toggle: (open: boolean) => void;
open: boolean;
}): JSX.Element {
const photo = images?.[selectedImageIndex];

useEffect(() => {
function handleKeyUp({ key }: KeyboardEvent) {
if (key === 'ArrowRight') handleNext();
else if (key === 'ArrowLeft') handlePrev();
}

if (typeof window !== 'undefined') window.addEventListener('keyup', handleKeyUp);

return () => {
if (typeof window !== 'undefined') window.removeEventListener('keyup', handleKeyUp);
};
}, [open, selectedImageIndex]);

function handlePrev() {
selectImageIndex(selectedImageIndex === 0 ? images.length - 1 : selectedImageIndex - 1);
}

function handleNext() {
selectImageIndex((selectedImageIndex + 1) % images.length);
}

if (!photo) return <></>;

const { image, description } = photo;

return (
<Modal isOpen={open} onClose={() => toggle(false)} size="xl">
<ModalOverlay />
<ModalContent sx={{ width: '90%' }}>
<ModalHeader sx={{ minHeight: 'calc(32px + 1rem)' }} />
<ModalCloseButton />
<ModalBody as="figure" sx={{ padding: 0 }}>
<Box aspectRatio={4 / 3} overflow="hidden">
<GatsbyImage
alt={description}
image={image}
style={{ height: '100%', width: '100%' }}
title={description}
/>
</Box>
<Box as="figcaption" paddingTop={4} paddingX={4}>
<Text color="gray.600" fontSize="0.9rem">
{description}
</Text>
</Box>
</ModalBody>
<ModalFooter sx={{ justifyContent: 'space-between' }}>
<Button leftIcon={<Icon as={IoChevronBack} />} onClick={handlePrev} variant="ghost">
Précédent
</Button>
<Button onClick={handleNext} rightIcon={<Icon as={IoChevronForward} />} variant="ghost">
Suivant
</Button>
</ModalFooter>
</ModalContent>
</Modal>
);
}

export default PhotoModal;
109 changes: 63 additions & 46 deletions src/templates/trip/step.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import React, { useState } from 'react';
import { TripStep } from '../../fixtures';

import Cons from './cons';
import PhotoModal from './photo-modal';
import Pros from './pros';

function Step({
Expand All @@ -29,57 +30,73 @@ function Step({
[],
),
);
const [photoModalOpen, togglePhotoModal] = useState(false);
const [selectedImageIndex, selectImageIndex] = useState(0);

return (
<Box display="flex" flexDirection="column" gap={6}>
<Box display="flex" flexDirection="column" gap={1}>
<Box alignItems="center" display="flex" flexDirection="row" gap={2}>
<Avatar bgColor="green.500" name={`${stepIndex}`} size="xs" />
<Heading as="h3" color="green.500" fontSize="1.15rem" fontWeight={700}>
{title}
</Heading>
</Box>
<Box display="flex" flexDirection="column" gap={4} paddingLeft="calc(24px + 0.5rem)">
<Text color="gray.700" fontSize="0.9rem">
{distance} kms
</Text>
</Box>
</Box>
<Box
display="flex"
flexDirection="column"
gap={6}
paddingLeft={[0, 0, 'calc(24px + 0.5rem)']}
>
{images.length > 0 && (
<Box display="flex" flexDirection="column" gap={2}>
<Heading as="h4" color="gray.700" fontSize="1rem" fontWeight={700}>
Photos
<>
<Box display="flex" flexDirection="column" gap={6}>
<Box display="flex" flexDirection="column" gap={1}>
<Box alignItems="center" display="flex" flexDirection="row" gap={2}>
<Avatar bgColor="green.500" name={`${stepIndex}`} size="xs" />
<Heading as="h3" color="green.500" fontSize="1.15rem" fontWeight={700}>
{title}
</Heading>
<Box display="flex" flexDirection="row" flexWrap="wrap" gap={2}>
{images.map(({ image, description }, index) => (
<Box
aspectRatio={4 / 3}
borderRadius={16}
key={index}
overflow="hidden"
width={['100%', 'calc((100% - 0.5rem) / 2)', 'calc((100% - 1.5rem) / 4)']}
>
<GatsbyImage
alt={description}
image={image}
style={{ height: '100%', width: '100%' }}
title={description}
/>
</Box>
))}
</Box>
</Box>
)}
<Pros items={pros} />
<Cons items={cons} />
<Box display="flex" flexDirection="column" gap={4} paddingLeft="calc(24px + 0.5rem)">
<Text color="gray.700" fontSize="0.9rem">
{distance} kms
</Text>
</Box>
</Box>
<Box
display="flex"
flexDirection="column"
gap={6}
paddingLeft={[0, 0, 'calc(24px + 0.5rem)']}
>
{images.length > 0 && (
<Box display="flex" flexDirection="column" gap={2}>
<Heading as="h4" color="gray.700" fontSize="1rem" fontWeight={700}>
Photos
</Heading>
<Box display="flex" flexDirection="row" flexWrap="wrap" gap={2}>
{images.map(({ image, description }, index) => (
<Box
as="button"
aspectRatio={4 / 3}
borderRadius={16}
key={index}
onClick={() => {
selectImageIndex(index);
togglePhotoModal(true);
}}
overflow="hidden"
width={['100%', 'calc((100% - 0.5rem) / 2)', 'calc((100% - 1.5rem) / 4)']}
>
<GatsbyImage
alt={description}
image={image}
style={{ height: '100%', width: '100%' }}
title={description}
/>
</Box>
))}
</Box>
</Box>
)}
<Pros items={pros} />
<Cons items={cons} />
</Box>
</Box>
</Box>
<PhotoModal
images={images}
open={photoModalOpen}
selectedImageIndex={selectedImageIndex}
selectImageIndex={selectImageIndex}
toggle={(open) => togglePhotoModal(open)}
/>
</>
);
}

Expand Down
4 changes: 3 additions & 1 deletion src/theme.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import { theme as chakraTheme, extendBaseTheme } from '@chakra-ui/react';

const { Avatar, Button, Card, Divider, List, Tag } = chakraTheme.components;
const { Avatar, Button, Card, CloseButton, Divider, Modal, List, Tag } = chakraTheme.components;

const theme = extendBaseTheme({
components: {
Avatar,
Button,
Card,
CloseButton,
Divider,
Modal,
List,
Tag,
},
Expand Down

0 comments on commit a63c5cd

Please sign in to comment.