Skip to content

Commit

Permalink
feat: photo
Browse files Browse the repository at this point in the history
  • Loading branch information
ttiimmothy committed Nov 23, 2023
1 parent 6589964 commit 26a2e49
Show file tree
Hide file tree
Showing 7 changed files with 120 additions and 43 deletions.
5 changes: 4 additions & 1 deletion src/components/utils/buttons/UploadButton.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
const UploadButton: React.FC = () => {
const UploadButton: React.FC<{
showUploadImageModal: React.Dispatch<React.SetStateAction<boolean>>;
}> = ({ showUploadImageModal }) => {
return (
<button
type="submit"
className="border-gray-700 h-full w-20 flex justify-center items-center rounded-md text-md px-11 py-2 border-2 hover:bg-gray-700 hover:text-white"
onClick={() => showUploadImageModal}
>
upload
</button>
Expand Down
2 changes: 1 addition & 1 deletion src/components/utils/modals/CreateReviewModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { TextareaInput } from "../inputs/TextareaInput";
import TextInput from "../inputs/TextInput";
import NumberInput from "../inputs/NumberInput";
import FileInput from "../inputs/FileInput";
import { uploadImage } from "../../../utils/imageService";
import { uploadImage } from "../../../utils/uploadImageService";
import { useCallback } from "react";
import { createReview } from "../../../api/review/reviewApiIndex";

Expand Down
31 changes: 21 additions & 10 deletions src/components/utils/modals/PhotoModal.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,31 @@
import { IoClose } from "react-icons/io5";

const PhotoModal: React.FC<{
selectedImage: string;
closePopUp: () => void;
imageRef: React.MutableRefObject<HTMLDivElement | null>;
}> = ({ selectedImage, closePopUp, imageRef }) => {
return (
<div className="fixed top-0 left-0 w-full h-full flex items-center justify-center bg-black bg-opacity-70">
<div className="bg-white p-4 rounded-xl" ref={imageRef}>
<img
src={selectedImage}
alt="popup"
className="max-w-full m-2"
width={500}
height={"auto"}
/>
<div className="flex justify-end px-2">
<button onClick={closePopUp}>Close</button>
<div className="bg-white rounded-xl" ref={imageRef}>
<div className="flex items-center justify-end p-2 px-4 border-b border-solid border-slate-200 rounded-t">
<button
className="p-2 ml-auto text-black float-right text-3xl leading-none font-semibold outline-none rounded-full hover:bg-gray-200 focus:outline-none"
onClick={closePopUp}
>
<span className="bg-transparent text-black text-2xl block outline-none focus:outline-none">
<IoClose size={20} />
</span>
</button>
</div>
<div className="p-4">
<img
src={selectedImage}
alt="popup"
className="max-w-full m-2 rounded-md"
width={500}
height={"auto"}
/>
</div>
</div>
</div>
Expand Down
42 changes: 42 additions & 0 deletions src/components/utils/modals/UploadImageModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { IoClose } from "react-icons/io5";

interface UploadImageModalProps {
show: boolean;
setShow: React.Dispatch<React.SetStateAction<boolean>>;
modalRef: React.MutableRefObject<HTMLDivElement | null>;
restaurant_id?: string;
}

const UploadImageModal: React.FC<UploadImageModalProps> = ({
show,
setShow,
modalRef,
}) => {
return show ? (
<div className="justify-center items-center flex overflow-x-hidden overflow-y-auto fixed inset-0 z-50 outline-none focus:outline-none">
<div className="opacity-25 fixed inset-0 z-40 bg-black"></div>
<div className="relative w-1/4 min-w-[400px] my-6 mx-auto z-40">
<div
className="border-0 rounded-lg shadow-lg relative flex flex-col w-full bg-white outline-none focus:outline-none"
ref={modalRef}
>
<div className="flex items-center justify-between p-2 px-4 border-b border-solid border-slate-200 rounded-t">
<h3 className="text-lg font-semibold">Create New Review</h3>
<button
className="p-2 ml-auto text-black float-right text-3xl leading-none font-semibold outline-none rounded-full hover:bg-gray-200 focus:outline-none"
onClick={() => setShow(false)}
>
<span className="bg-transparent text-black text-2xl block outline-none focus:outline-none">
<IoClose size={20} />
</span>
</button>
</div>
</div>
</div>
</div>
) : (
<></>
);
};

export default UploadImageModal;
43 changes: 28 additions & 15 deletions src/pages/restaurant/RestaurantOverviewPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,12 @@ import {
import useOnClickOutside from "../../components/hooks/useOnClickOutside";
import RestaurantOverviewButton from "../../components/utils/buttons/RestaurantOverviewButton";
import ReviewCard from "../../components/utils/cards/ReviewCard";
import CreateReviewModal from "../../components/utils/modals/CreateReviewModal";
import RestaurantDetailSkeletonLoader from "../../components/skeletonLoader/RestaurantDetailSkeletonLoader";
import PhotoModal from "../../components/utils/modals/PhotoModal";
import ErrorPage from "../error/ErrorPage";
import UploadButton from "../../components/utils/buttons/UploadButton";
import UploadImageModal from "../../components/utils/modals/UploadImageModal";
import CreateReviewModal from "../../components/utils/modals/CreateReviewModal";
import PhotoModal from "../../components/utils/modals/PhotoModal";

function isUUID(id: string) {
const uuidPattern =
Expand All @@ -31,13 +32,15 @@ const RestaurantOverviewPage: React.FC = () => {
const { id } = useParams();

const [page, setPage] = useState("Reviews");
const [shownCreateReviewModal, setShowCreateReviewModal] = useState(false);
const [showCreateReviewModal, setShowCreateReviewModal] = useState(false);
const [showUploadImageModal, setShowUploadImageModal] = useState(false);
const [popUpOpen, setPopUpOpen] = useState(false);
const [selectedImage, setSelectedImage] = useState<string>("");
const [loading, setLoading] = useState(true);

const imageRef = useRef<null | HTMLDivElement>(null);
const formRef = useRef<null | HTMLDivElement>(null);
const modalRef = useRef<null | HTMLDivElement>(null);

const dispatch = useDispatch<AppDispatch>();
const restaurantDetail = useSelector(
Expand Down Expand Up @@ -82,11 +85,14 @@ const RestaurantOverviewPage: React.FC = () => {
setSelectedImage(image);
setPopUpOpen(true);
};

const closePopUp = () => {
setPopUpOpen(false);
};

useOnClickOutside(imageRef, () => setPopUpOpen(false));
useOnClickOutside(formRef, () => setShowCreateReviewModal(false));
useOnClickOutside(modalRef, () => setShowUploadImageModal(false));

const loadDefaultImage = (type: string, id: string) => {
if (type === "review") {
Expand Down Expand Up @@ -127,11 +133,16 @@ const RestaurantOverviewPage: React.FC = () => {
restaurantDetail && (
<>
<CreateReviewModal
show={shownCreateReviewModal}
show={showCreateReviewModal}
setShow={setShowCreateReviewModal}
formRef={formRef}
restaurant_id={id}
/>
<UploadImageModal
show={showUploadImageModal}
setShow={setShowUploadImageModal}
modalRef={modalRef}
/>
<div className="max-w-5xl mx-auto px-3 py-3">
<div className="flex font-semibold justify-between">
<div className="flex flex-col lg:flex-row gap-8 pr-1">
Expand Down Expand Up @@ -213,19 +224,19 @@ const RestaurantOverviewPage: React.FC = () => {
)}
{reviewPhotos.length > 0 && (
<div className="grid lg:grid-cols-3 md:grid-cols-2 grid-cols-1 gap-4">
{reviewPhotos.map((review, index) => (
{reviewPhotos.map((reviewPhoto, index) => (
<div
className="shadow-md rounded-lg cursor-pointer h-fit bg-white hover:bg-slate-200"
onClick={() => openPopUp(review.photo_url)}
key={`review ${index}`}
onClick={() => openPopUp(reviewPhoto.photo_url)}
key={`review photo ${index}`}
>
<img
src={review.photo_url}
src={reviewPhoto.photo_url}
width="350"
height="200"
className="object-cover w-full h-auto rounded-lg"
onError={() =>
loadDefaultImage("review", review.photo_id)
loadDefaultImage("review", reviewPhoto.photo_id)
}
/>
</div>
Expand All @@ -245,25 +256,27 @@ const RestaurantOverviewPage: React.FC = () => {
<>
<div className="flex justify-between">
<h1 className="text-2xl font-bold my-4">Menus</h1>
<UploadButton />
<UploadButton showUploadImageModal={setShowUploadImageModal} />
</div>
{menuPhotos.length === 0 && (
<div>No menu photos are provided for this restaurant</div>
)}
{menuPhotos.length > 0 && (
<div className="grid lg:grid-cols-3 md:grid-cols-2 grid-cols-1 gap-4">
{menuPhotos.map((menu, index) => (
{menuPhotos.map((menuPhoto, index) => (
<div
className="shadow-md rounded-lg cursor-pointer h-fit bg-white hover:bg-slate-200"
onClick={() => openPopUp(menu.photo_url)}
key={`menu ${index}`}
onClick={() => openPopUp(menuPhoto.photo_url)}
key={`menu photo ${index}`}
>
<img
src={menu.photo_url}
src={menuPhoto.photo_url}
width="350"
height="200"
className="object-cover w-full h-auto rounded-lg"
onError={() => loadDefaultImage("menu", menu.photo_id)}
onError={() =>
loadDefaultImage("menu", menuPhoto.photo_id)
}
/>
</div>
))}
Expand Down
40 changes: 24 additions & 16 deletions src/pages/review/ReviewPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { format } from "date-fns";
import { useDispatch, useSelector } from "react-redux";
import { AppDispatch, IRootState } from "../../store";
import { getReviewThunk } from "../../redux/review/reviewSlice";
import { getRestaurantThunk } from "../../redux/restaurant/restaurantSlice";

function isUUID(id: string) {
const uuidPattern =
Expand All @@ -33,18 +34,27 @@ const ReviewPage: React.FC = () => {
const restaurant = useSelector(
(state: IRootState) => state.restaurant.restaurant
);
const reviewPhotos = useSelector(
(state: IRootState) => state.photo.reviewPhotos
);

useEffect(() => {
const fetchReview = async () => {
const fetchReview = () => {
if (!id || !isUUID(id)) return;
dispatch(getReviewThunk(id));
};

fetchReview();
}, [id, dispatch]);

useEffect(() => {
const fetchRestaurant = () => {
if (!id || !isUUID(id)) return;
if (review?.restaurant_id) {
dispatch(getRestaurantThunk(review.restaurant_id));
}
};

fetchRestaurant();
}, [dispatch, review, id]);

return (
<div className="container justify-center mb-8 px-4 gap-8 mx-auto mt-10">
<div className="relative">
Expand Down Expand Up @@ -75,18 +85,16 @@ const ReviewPage: React.FC = () => {
}
icon={<IoTime />}
/>
<div className="h-40">
<div className="mb-1">Photos</div>
<img
src={
reviewPhotos.filter(
(reviewPhoto) => reviewPhoto.review_id === id
)[0].photo_url
}
alt="review photo"
className="object-cover h-[100%] w-auto rounded-md"
/>
</div>
{review.photo && (
<div className="h-40">
<div className="mb-1">Photos</div>
<img
src={review.photo}
alt="review photo"
className="object-cover h-[100%] w-auto rounded-md"
/>
</div>
)}
</div>
)}
</div>
Expand Down
File renamed without changes.

0 comments on commit 26a2e49

Please sign in to comment.