Skip to content

Commit

Permalink
Merge pull request #28 from openrice-canada/feat/restaurant
Browse files Browse the repository at this point in the history
feat: photo
  • Loading branch information
ttiimmothy authored Nov 22, 2023
2 parents eaed4c2 + 191bf28 commit dccfd98
Show file tree
Hide file tree
Showing 20 changed files with 432 additions and 262 deletions.
8 changes: 3 additions & 5 deletions src/api/auth/authApiIndex.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
import { AxiosApiClientBuilder } from "../axiosIndex";
import { AuthType, AuthenticateResponse } from "./authType";
import { Auth, AuthenticateResponse } from "./authType";

const apiClient = new AxiosApiClientBuilder()
.withResourceName("/auth/user")
.withCredentials(true)
.build();

export const register = async (
user: AuthType
): Promise<AuthenticateResponse> => {
export const register = async (user: Auth): Promise<AuthenticateResponse> => {
return apiClient.post("/register", user);
};

export const login = async (user: AuthType): Promise<AuthenticateResponse> => {
export const login = async (user: Auth): Promise<AuthenticateResponse> => {
return apiClient.post("/login", user);
};

Expand Down
2 changes: 1 addition & 1 deletion src/api/auth/authType.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { CurrentLoginUserInfo } from "../../redux/auth/authSlice";

export type AuthType = {
export type Auth = {
username?: string;
email?: string;
password: string;
Expand Down
9 changes: 9 additions & 0 deletions src/api/photo/PhotoType.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export type Photo = {
photo_id: string;
photo_category_id: string;
review_id: string;
restaurant_id?: string;
photo_url: string;
active: boolean;
created_at: string;
};
16 changes: 16 additions & 0 deletions src/api/photo/photoApiIndex.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { AxiosApiClientBuilder } from "../axiosIndex";
import { Photo } from "./PhotoType";

const apiClient = new AxiosApiClientBuilder()
.withResourceName("/photo")
.build();

export const getReviewPhotos = async (
restaurantID: string
): Promise<Photo[]> => {
return apiClient.get("review", { params: { restaurantID } });
};

export const getMenuPhotos = async (restaurantID: string): Promise<Photo[]> => {
return apiClient.get("menu", { params: { restaurantID } });
};
2 changes: 1 addition & 1 deletion src/api/restaurant/restaurantApiIndex.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export const getRestaurants = async (
export const getRestaurantDetail = async (
restaurantId: string
): Promise<Restaurant> => {
return apiClient.get(restaurantId);
return apiClient.get(`id/${restaurantId}`);
};

export const createRestaurant = async (
Expand Down
4 changes: 2 additions & 2 deletions src/api/restaurantDish/restaurantDishApiIndex.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ import { AxiosApiClientBuilder } from "../axiosIndex";
import { RestaurantDish } from "./RestaurantDishType";

const apiClient = new AxiosApiClientBuilder()
.withResourceName("/restaurant-dish")
.withResourceName("/restaurant/dish")
.build();

export const createRestaurantDish = async (
restaurantDish: RestaurantDish
): Promise<RestaurantDish> => {
return apiClient.post("/restaurant-dish", restaurantDish);
return apiClient.post("", restaurantDish);
};
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ import { AxiosApiClientBuilder } from "../axiosIndex";
import { RestaurantPaymentMethod } from "./RestaurantPaymentMethodType";

const apiClient = new AxiosApiClientBuilder()
.withResourceName("/restaurant-payment")
.withResourceName("/restaurant/payment/method")
.build();

export const createRestaurantPaymentMethod = async (
restaurantPaymentMethod: RestaurantPaymentMethod
): Promise<RestaurantPaymentMethod> => {
return apiClient.post("/restaurant-payment-method", restaurantPaymentMethod);
return apiClient.post("", restaurantPaymentMethod);
};
2 changes: 1 addition & 1 deletion src/api/review/ReviewType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export type Review = {
modified_at: string;
};

export type CreateReviewRequest = {
export type CreateReviewDto = {
user_id: string;
restaurant_id: string;
title: string;
Expand Down
17 changes: 12 additions & 5 deletions src/api/review/reviewApiIndex.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { AxiosApiClientBuilder } from "../axiosIndex";
import { CreateReviewRequest, Review } from "./ReviewType";
import { CreateReviewDto, Review } from "./ReviewType";

const apiClient = new AxiosApiClientBuilder()
.withResourceName("/review")
Expand All @@ -16,11 +16,18 @@ export const getReviewsByRestaurantID = async (
};

export const createReview = async (
input: CreateReviewRequest
createReviewDto: CreateReviewDto,
imagePrefix: string,
restaurantID: string,
photoCategory: string
): Promise<Review> => {
return apiClient.post("", input);
return apiClient.post(
"",
{ createReviewDto, imagePrefix, restaurantID },
{ params: { photoCategory } }
);
};

export const getReview = async (reviewId: string): Promise<Review> => {
return apiClient.get(reviewId);
export const getReview = async (reviewID: string): Promise<Review> => {
return apiClient.get(`id/${reviewID}`);
};
2 changes: 1 addition & 1 deletion src/components/utils/cards/RestaurantCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ const RestaurantCard: React.FC<Restaurant> = (props: Restaurant) => {
);
return (
<Link
to={`/restaurant/${props.restaurant_id}`}
to={`/restaurant/id/${props.restaurant_id}`}
className="rounded-md shadow-lg hover:bg-slate-200"
>
<div className="w-full h-48 overflow-hidden">
Expand Down
14 changes: 8 additions & 6 deletions src/components/utils/cards/ReviewCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ const ReviewRow = ({ text, icon }: { text: string; icon: React.ReactNode }) => (
const ReviewCard: React.FC<Review> = (props: Review) => {
return (
<Link
to={`/review/${props.review_id}`}
to={`/review/id/${props.review_id}`}
className="rounded-md shadow-lg hover:bg-slate-200"
>
<div className="flex justify-between">
Expand All @@ -33,11 +33,13 @@ const ReviewCard: React.FC<Review> = (props: Review) => {
/>
<div className="flex gap-2 items-start">
<div>{<IoThumbsUpSharp />}</div>
{Array.from({ length: props.rating }).map((_, index) => (
<span className="text-yellow-400" key={index}>
{<IoStar />}
</span>
))}
<div className="flex gap-1">
{Array.from({ length: props.rating }).map((_, index) => (
<span className="text-yellow-400" key={index}>
{<IoStar />}
</span>
))}
</div>
</div>
<ReviewRow
text={
Expand Down
Original file line number Diff line number Diff line change
@@ -1,24 +1,25 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import { useNavigate } from "react-router-dom";
import { useSelector } from "react-redux";
import { Controller, useForm } from "react-hook-form";
import { IoClose } from "react-icons/io5";
import { closeSnackbar, enqueueSnackbar } from "notistack";
import { useNavigate } from "react-router-dom";

import { IRootState } from "../../../store";
import { TextareaInput } from "../inputs/TextareaInput";
import { uploadImage } from "../../../utils/imageService";
import { useDispatch, useSelector } from "react-redux";
import { AppDispatch, IRootState } from "../../../store";
import TextInput from "../inputs/TextInput";
import NumberInput from "../inputs/NumberInput";
import FileInput from "../inputs/FileInput";
import { createReviewThunk } from "../../../redux/reviews/reviewsSlice";
import { uploadImage } from "../../../utils/imageService";
import { useCallback } from "react";
import { createReview } from "../../../api/review/reviewApiIndex";

type AddReviewModalProps = {
isShown: boolean;
setIsShown: React.Dispatch<React.SetStateAction<boolean>>;
interface CreateReviewModalProps {
show: boolean;
setShow: React.Dispatch<React.SetStateAction<boolean>>;
formRef: React.MutableRefObject<HTMLDivElement | null>;
restaurant_id?: string;
};
}

export type ReviewForm = {
rating: number;
Expand All @@ -29,8 +30,8 @@ export type ReviewForm = {
photo?: any;
};

const AddReviewModal: React.FC<AddReviewModalProps> = (
props: AddReviewModalProps
const CreateReviewModal: React.FC<CreateReviewModalProps> = (
props: CreateReviewModalProps
) => {
const navigate = useNavigate();
const { control, handleSubmit } = useForm({
Expand All @@ -44,60 +45,64 @@ const AddReviewModal: React.FC<AddReviewModalProps> = (
} as ReviewForm,
});

const dispatch = useDispatch<AppDispatch>();
const user = useSelector((state: IRootState) => state.auth.currentUser);
const reviewID = useSelector(
(state: IRootState) => state.review.review?.review_id
);

const addReview = async (review: ReviewForm) => {
if (user?.user_id) {
dispatch(
createReviewThunk({
title: review.title,
content: review.content,
spending: review.spending,
rating: review.rating,
restaurant_id: props?.restaurant_id as string,
user_id: user?.user_id,
visit_date: new Date(review.visit_date),
})
);

if (review.photo) {
await uploadImage(
review.photo,
props?.restaurant_id as string,
"reviews",
reviewID
const createNewReview = useCallback(
async (review: ReviewForm) => {
if (user?.user_id) {
const res = await createReview(
{
title: review.title,
content: review.content,
spending: review.spending,
rating: review.rating,
restaurant_id: props?.restaurant_id as string,
user_id: user?.user_id,
visit_date: new Date(review.visit_date),
},
process.env.REACT_APP_IMAGE_PREFIX as string,
props.restaurant_id as string,
"Review"
);
}

enqueueSnackbar("Review added successfully", { variant: "success" });
setTimeout(() => {
navigate(`/restaurant/${props?.restaurant_id}`);
navigate(0);
}, 1000);
if (review.photo) {
await uploadImage(
review.photo,
props.restaurant_id as string,
"photos",
res?.review_id
);
}

setTimeout(() => {
closeSnackbar();
}, 2000);
} else {
enqueueSnackbar("You haven't login yet", { variant: "error" });
setTimeout(() => {
navigate(`/restaurant/${props?.restaurant_id}`);
navigate(0);
}, 1000);
enqueueSnackbar("Review and Review photo is added successfully", {
variant: "success",
});
props.setShow(false);
setTimeout(() => {
navigate(`/restaurant/id/${props?.restaurant_id}`);
navigate(0);
}, 1000);

setTimeout(() => {
closeSnackbar();
}, 2000);
}
};
setTimeout(() => {
closeSnackbar();
}, 2000);
} else {
enqueueSnackbar("You haven't login yet", { variant: "error" });
props.setShow(false);
setTimeout(() => {
navigate(`/restaurant/id/${props?.restaurant_id}`);
navigate(0);
}, 1000);

if (!props.isShown) return null;
setTimeout(() => {
closeSnackbar();
}, 2000);
}
},
[navigate, user?.user_id, props]
);

return (
return props.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">
Expand All @@ -106,10 +111,10 @@ const AddReviewModal: React.FC<AddReviewModalProps> = (
ref={props.formRef}
>
<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">Add Review</h3>
<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={() => props.setIsShown(false)}
onClick={() => props.setShow(false)}
>
<span className="bg-transparent text-black text-2xl block outline-none focus:outline-none">
<IoClose size={20} />
Expand All @@ -119,7 +124,7 @@ const AddReviewModal: React.FC<AddReviewModalProps> = (
<div className="relative p-6 flex flex-col items-center gap-6 overflow-auto">
<form
className="w-full gap-2 flex flex-col"
onSubmit={handleSubmit((review) => addReview(review))}
onSubmit={handleSubmit((review) => createNewReview(review))}
>
<Controller
control={control}
Expand Down Expand Up @@ -220,7 +225,9 @@ const AddReviewModal: React.FC<AddReviewModalProps> = (
</div>
</div>
</div>
) : (
<></>
);
};

export default AddReviewModal;
export default CreateReviewModal;
1 change: 0 additions & 1 deletion src/pages/map/MapPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { useEffect } from "react";
import { getRestaurantsByQueryThunk } from "../../redux/restaurant/restaurantSlice";
import { useDispatch, useSelector } from "react-redux";
import { AppDispatch, IRootState } from "../../store";

import MapComponent from "../../components/map/MapComponent";

const MapPage = () => {
Expand Down
2 changes: 1 addition & 1 deletion src/pages/restaurant/CreateRestaurantPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ const CreateRestaurantPage: React.FC = () => {

enqueueSnackbar("Restaurant added successfully!", { variant: "success" });
setTimeout(() => {
navigate(`/restaurant/${restaurantID}`);
navigate(`/restaurant/id/${restaurantID}`);
navigate(0);
}, 1000);

Expand Down
Loading

0 comments on commit dccfd98

Please sign in to comment.