Skip to content

Commit

Permalink
Implement quick view modal (#76)
Browse files Browse the repository at this point in the history
  • Loading branch information
ltan02 authored Apr 10, 2024
1 parent 959c022 commit 472dae0
Show file tree
Hide file tree
Showing 4 changed files with 255 additions and 75 deletions.
21 changes: 21 additions & 0 deletions frontend/src/components/buttons/CloseButton.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import React from 'react';

export default function CloseButton({ onClick, size = 'sm' }) {
return (
<button
type="button"
className={`bg-mv-white border-dark-grey border-solid border rounded-[5px] shadow-searchBarShadow flex items-center justify-center whitespace-nowrap ${
size === 'sm' ? 'px-[20px] py-[10px]' : 'py-[15px] px-[101px]'
}`}
onClick={onClick}
>
<p
className={`text-mv-black font-medium leading-5 ${
size === 'sm' ? 'text-sm' : 'text-base'
} `}
>
Close
</p>
</button>
);
}
18 changes: 15 additions & 3 deletions frontend/src/components/buttons/ViewModelButton.jsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,25 @@
import React from 'react';

export default function ViewModelButton({ onClick }) {
export default function ViewModelButton({ onClick, size = 'sm' }) {
const buttonStyle = {
sm: 'px-[29px] py-[12.5px]',
lg: 'px-[76px] py-[15px]',
};

const textStyle = {
sm: 'text-sm',
lg: 'text-base',
};

return (
<button
type="button"
className="bg-mv-green border-solid border-mv-green rounded-[5px] w-full shadow-searchBarShadow px-[29px] py-[12.5px] flex items-center justify-center gap-2.5"
className={`bg-mv-green border-solid border-mv-green rounded-[5px] shadow-searchBarShadow flex items-center justify-center gap-2.5 ${buttonStyle[size]}`}
onClick={onClick}
>
<div className="text-mv-white text-sm font-medium">View model</div>
<div className={`text-mv-white font-medium ${textStyle[size]}`}>
View model
</div>
</button>
);
}
161 changes: 89 additions & 72 deletions frontend/src/components/cards/VehicleItemCard.jsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import React from 'react';
import React, { useState } from 'react';
import { useNavigate } from 'react-router';
import DirectionsBusIcon from '@mui/icons-material/DirectionsBus';
import AgricultureIcon from '@mui/icons-material/Agriculture';
import StarsOutlinedIcon from '@mui/icons-material/StarsOutlined';
import AddToListButton from '../buttons/AddToListButton';
import ViewModelButton from '../buttons/ViewModelButton';
import QuickViewButton from '../buttons/QuickViewButton';
import QuickViewModal from '../modals/QuickViewModal';

export default function VehicleItemCard({
vehicleId,
Expand All @@ -16,94 +17,110 @@ export default function VehicleItemCard({
price,
imageUrl,
}) {
const [isQuickViewOpen, setIsQuickViewOpen] = useState(false);

const navigate = useNavigate();

const handleViewClick = () => {
navigate(`/listings/${vehicleId}`);
};

return (
<div className="flex w-full h-[314px] rounded-[20px] shadow-searchBarShadow">
<div className="w-1/3 relative rounded-l-[20px]">
<img
className="w-full h-full rounded-l-[20px] object-cover object-center"
src={imageUrl}
alt={description}
/>
<div className="absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2">
<QuickViewButton />
</div>
</div>
<div className="w-2/3 flex pl-[46px] pt-[42px] pb-[30px] pr-[36px]">
<div className="w-[70%] flex flex-col gap-y-[21px]">
<div
className="font-semibold text-xl text-mv-black tracking-[0.5px] leading-7"
style={{
display: '-webkit-box',
WebkitLineClamp: 3,
WebkitBoxOrient: 'vertical',
overflow: 'hidden',
textOverflow: 'ellipsis',
}}
>
{description}
<>
<div className="flex w-full h-[314px] rounded-[20px] shadow-searchBarShadow">
<div className="w-1/3 relative rounded-l-[20px]">
<img
className="w-full h-full rounded-l-[20px] object-cover object-center"
src={imageUrl}
alt={description}
/>
<div className="absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2">
<QuickViewButton onClick={() => setIsQuickViewOpen(true)} />
</div>
</div>
<div className="w-2/3 flex pl-[46px] pt-[42px] pb-[30px] pr-[36px]">
<div className="w-[70%] flex flex-col gap-y-[21px]">
<div
className="font-semibold text-xl text-mv-black tracking-[0.5px] leading-7"
style={{
display: '-webkit-box',
WebkitLineClamp: 3,
WebkitBoxOrient: 'vertical',
overflow: 'hidden',
textOverflow: 'ellipsis',
}}
>
{description}
</div>

<div className="flex flex-col text-mv-black text-base mr-[50px] gap-y-[20px]">
<div className="flex flex-row justify-between">
<div className="flex flex-row items-center justify-center gap-x-[19px]">
<DirectionsBusIcon
className="text-dark-grey"
sx={{ fontSize: 25 }}
/>
<div className="flex flex-col leading-6 tracking-[0.5px]">
<p className="font-medium">Model</p>
<p className="font-normal">{modelNumber}</p>
<div className="flex flex-col text-mv-black text-base mr-[50px] gap-y-[20px]">
<div className="flex flex-row w-[100%] justify-between">
<div className="flex flex-row items-center justify-center gap-x-[19px]">
<DirectionsBusIcon
className="text-dark-grey"
sx={{ fontSize: 25 }}
/>
<div className="flex flex-col leading-6 tracking-[0.5px]">
<p className="font-medium">Model</p>
<p className="font-normal">{modelNumber}</p>
</div>
</div>
</div>
<div className="flex flex-row items-center justify-center gap-x-[19px]">
<StarsOutlinedIcon
className="text-dark-grey"
sx={{ fontSize: 25 }}
/>
<div className="flex flex-col leading-6 tracking-[0.5px]">
<p className="font-medium">Engine no.</p>
<p className="font-normal">{engineNumber}</p>
<div className="flex flex-row items-center justify-center gap-x-[19px]">
<StarsOutlinedIcon
className="text-dark-grey"
sx={{ fontSize: 25 }}
/>
<div className="flex flex-col leading-6 tracking-[0.5px]">
<p className="font-medium">Engine no.</p>
<p className="font-normal">{engineNumber}</p>
</div>
</div>
</div>
</div>
<div className="flex flex-row justify-between">
<div className="flex flex-row items-center justify-center gap-x-[19px]">
<AgricultureIcon
className="text-dark-grey"
sx={{ fontSize: 25 }}
/>
<div className="flex flex-col leading-6 tracking-[0.5px]">
<p className="font-medium">Chassis</p>
<p className="font-normal">{chassisNumber}</p>
<div className="flex flex-row justify-between">
<div className="flex flex-row items-center justify-center gap-x-[19px]">
<AgricultureIcon
className="text-dark-grey"
sx={{ fontSize: 25 }}
/>
<div className="flex flex-col leading-6 tracking-[0.5px]">
<p className="font-medium">Chassis</p>
<p className="font-normal">{chassisNumber}</p>
</div>
</div>
</div>
</div>
</div>
</div>
<div className="w-[30%] flex flex-col items-center justify-between gap-y-[13px]">
<span>
<p className="text-mv-black text-base font-normal leading-5 tracking-[0.1px]">
Current bid
</p>
</span>
<span className="mb-[5px]">
<p className="text-mv-black text-[28px] font-medium leading-5 tracking-[0.1px]">{`₱${price}`}</p>
</span>
<ViewModelButton onClick={handleViewClick} />
<span className="mb-[2px]">
<p className="text-base text-mv-black font-medium leading-5 tracking-[0.1px]">
or
</p>
</span>
<AddToListButton />
<div className="w-[30%] flex flex-col items-center justify-between gap-y-[13px]">
<span>
<p className="text-mv-black text-base font-normal leading-5 tracking-[0.1px]">
Current bid
</p>
</span>
<span className="mb-[5px]">
<p className="text-mv-black text-[28px] font-medium leading-5 tracking-[0.1px]">{`₱${price}`}</p>
</span>
<ViewModelButton onClick={handleViewClick} />
<span className="mb-[2px]">
<p className="text-base text-mv-black font-medium leading-5 tracking-[0.1px]">
or
</p>
</span>
<AddToListButton />
</div>
</div>
</div>
</div>
{isQuickViewOpen && (
<QuickViewModal
isOpen={isQuickViewOpen}
onClose={() => setIsQuickViewOpen(false)}
id={vehicleId}
description={description}
modelNumber={modelNumber}
chassisNumber={chassisNumber}
engineNumber={engineNumber}
price={price}
/>
)}
</>
);
}
130 changes: 130 additions & 0 deletions frontend/src/components/modals/QuickViewModal.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
import React, { useEffect } from 'react';
import DirectionsBusIcon from '@mui/icons-material/DirectionsBus';
import AgricultureIcon from '@mui/icons-material/Agriculture';
import StarsOutlinedIcon from '@mui/icons-material/StarsOutlined';
import { useNavigate } from 'react-router-dom';
import ImageSlideshow from '../imageSlideshows/ImageSlideshow';
import truck from '../../assets/truck.png';
import truck2 from '../../assets/truck2.png';
import truck3 from '../../assets/truck3.png';
import truck4 from '../../assets/truck4.png';
import truck5 from '../../assets/truck5.png';
import ViewModelButton from '../buttons/ViewModelButton';
import CloseButton from '../buttons/CloseButton';

export default function QuickViewModal({
isOpen,
onClose,
id,
description,
modelNumber,
chassisNumber,
engineNumber,
price,
}) {
if (!isOpen) return null;

const navigate = useNavigate();

const handleOutsideClick = (e) => {
if (e.target.id === 'modal-overlay') {
onClose();
}
};

useEffect(() => {
window.addEventListener('click', handleOutsideClick);
return () => {
window.removeEventListener('click', handleOutsideClick);
};
}, []);

return (
<div
id="modal-overlay"
className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50"
>
<div
className="bg-mv-white h-[615px] max-w-[1000px] w-[70%] flex py-[55px] px-[45px] rounded-[20px]"
onClick={(e) => e.stopPropagation()}
>
<div className="flex w-[50%] mr-[35px]">
<ImageSlideshow images={[truck, truck2, truck3, truck4, truck5]} />
</div>
<div className="flex flex-col items-start w-[47%]">
<h3 className="text-mv-black text-xl font-semibold leading-[28px]">
{description}
</h3>

<div className="flex text-mv-black text-base mt-[20px]">
<div className="flex flex-col items-start gap-y-[23px]">
<div className="flex flex-row items-center justify-center gap-x-[19px]">
<DirectionsBusIcon
className="text-dark-grey"
sx={{ fontSize: 25 }}
/>
<div className="flex flex-col leading-6 tracking-[0.5px]">
<p className="font-medium">Model</p>
<p className="font-normal">{modelNumber}</p>
</div>
</div>
<div className="flex flex-row items-center justify-center gap-x-[19px]">
<AgricultureIcon
className="text-dark-grey"
sx={{ fontSize: 25 }}
/>
<div className="flex flex-col leading-6 tracking-[0.5px]">
<p className="font-medium">Chassis</p>
<p className="font-normal">{chassisNumber}</p>
</div>
</div>
</div>
<div className="inline-flex flex-col items-start">
<div className="flex flex-row items-center justify-center gap-x-[19px]">
<StarsOutlinedIcon
className="text-dark-grey"
sx={{ fontSize: 25 }}
/>
<div className="flex flex-col leading-6 tracking-[0.5px]">
<p className="font-medium">Engine no.</p>
<p className="font-normal">{engineNumber}</p>
</div>
</div>
</div>
</div>

<div className="flex flex-col mt-[44px] w-[100%] pr-[36px]">
<div className="flex w-[100%] justify-between items-center">
<p className="text-mv-black text-base font-normal leading-[25px]">
Bid status:
</p>
<p className="text-dark-grey text-right text-base font-normal leading-[25px]">
You haven&apos;t bid
</p>
</div>

<div className="flex w-[100%] justify-between items-center mt-[22px]">
<p className="text-mv-black text-base font-normal leading-[25px]">
Highest bid:
</p>
<p className="text-mv-black text-2xl text-right font-medium leading-[25px]">
{`₱${price}`}
</p>
</div>
</div>

<div className="flex flex-col w-full items-center mt-[33px] gap-y-[15px]">
<ViewModelButton
onClick={() => {
onClose();
navigate(`/listings/${id}`);
}}
size="lg"
/>
<CloseButton onClick={onClose} size="lg" />
</div>
</div>
</div>
</div>
);
}

0 comments on commit 472dae0

Please sign in to comment.