From faa5b34f9e26134aab041868214227b0cd177673 Mon Sep 17 00:00:00 2001 From: ttiimmothy Date: Tue, 21 Nov 2023 21:59:10 -0500 Subject: [PATCH] feat: review --- src/api/auth/authApiIndex.ts | 10 ++-- src/api/auth/authType.ts | 35 ++----------- src/api/restaurant/RestaurantType.ts | 17 +++--- .../restaurantPaymentMethodApiIndex.ts | 2 +- src/api/review/ReviewType.ts | 11 ++-- src/api/review/reviewApiIndex.ts | 4 +- .../RestaurantDetailSkeletonLoader.tsx | 0 src/components/utils/buttons/UploadButton.tsx | 12 +++++ src/components/utils/cards/RestaurantCard.tsx | 2 +- src/components/utils/cards/ReviewCard.tsx | 52 ++++++++++++------- .../utils/modals/AddReviewModal.tsx | 9 +--- .../restaurant/RestaurantOverviewPage.tsx | 46 ++++------------ src/pages/review/ReviewPage.tsx | 5 +- src/redux/auth/authSlice.ts | 50 +++++------------- 14 files changed, 100 insertions(+), 155 deletions(-) rename src/components/{loader => skeletonLoader}/RestaurantDetailSkeletonLoader.tsx (100%) create mode 100644 src/components/utils/buttons/UploadButton.tsx diff --git a/src/api/auth/authApiIndex.ts b/src/api/auth/authApiIndex.ts index 583b96d..67671a0 100644 --- a/src/api/auth/authApiIndex.ts +++ b/src/api/auth/authApiIndex.ts @@ -1,20 +1,18 @@ import { AxiosApiClientBuilder } from "../axiosIndex"; -import { User, AuthenticateResponse } from "./authType"; +import { AuthType, AuthenticateResponse } from "./authType"; const apiClient = new AxiosApiClientBuilder() .withResourceName("/auth/user") .withCredentials(true) .build(); -export const postUserRegister = async ( - user: User +export const register = async ( + user: AuthType ): Promise => { return apiClient.post("/register", user); }; -export const postUserAuth = async ( - user: User -): Promise => { +export const login = async (user: AuthType): Promise => { return apiClient.post("/login", user); }; diff --git a/src/api/auth/authType.ts b/src/api/auth/authType.ts index cac97f6..50a9ded 100644 --- a/src/api/auth/authType.ts +++ b/src/api/auth/authType.ts @@ -1,39 +1,14 @@ -export type User = { - email?: string; +import { CurrentLoginUserInfo } from "../../redux/auth/authSlice"; + +export type AuthType = { username?: string; + email?: string; password: string; role?: string; }; -export type UserEntity = { - user_id: string; - email: string; - username: string; - password: string; - created_at: string; - modifiedAt: string; - active: boolean; - role: string; - enabled: boolean; - authorities: [ - { - authority: string; - } - ]; - accountNonExpired?: boolean; - accountNonLocked?: boolean; - credentialsNonExpired?: boolean; -}; - export type AuthenticateResponse = { token?: string; message?: string; - user?: UserLogin; + user?: CurrentLoginUserInfo; }; - -export interface UserLogin { - user_id: string; - username: string; - email: string; - role: string; -} diff --git a/src/api/restaurant/RestaurantType.ts b/src/api/restaurant/RestaurantType.ts index 8c874e3..0b75626 100644 --- a/src/api/restaurant/RestaurantType.ts +++ b/src/api/restaurant/RestaurantType.ts @@ -9,7 +9,7 @@ export interface Restaurant { phone: string; intro: string; opening_hours: string; - cover_image?: string; + cover_image_url?: string; averageRating: number; reviewCount: number; active: boolean; @@ -24,14 +24,14 @@ export type SearchRestaurantQuery = { }; export type CreateRestaurantType = { + name: string; address: string; + district_id: string; latitude: string; longitude: string; - created_at?: string; - district_id: string; + postal_code: string; + phone: string; intro: string; - modified_at?: string; - name: string; opening_hours: | { monday: { from: string; to: string }; @@ -44,9 +44,8 @@ export type CreateRestaurantType = { holiday?: { from: string; to: string }; } | string; - phone: string; - postal_code: string; - restaurant_id?: string; + cover_image_url?: string; rating?: number; - coverImageUrl?: string; + created_at?: string; + modified_at?: string; }; diff --git a/src/api/restaurantPaymentMethod/restaurantPaymentMethodApiIndex.ts b/src/api/restaurantPaymentMethod/restaurantPaymentMethodApiIndex.ts index 50929d6..a1de655 100644 --- a/src/api/restaurantPaymentMethod/restaurantPaymentMethodApiIndex.ts +++ b/src/api/restaurantPaymentMethod/restaurantPaymentMethodApiIndex.ts @@ -8,5 +8,5 @@ const apiClient = new AxiosApiClientBuilder() export const createRestaurantPaymentMethod = async ( restaurantPaymentMethod: RestaurantPaymentMethod ): Promise => { - return apiClient.post("/restaurant-payment", restaurantPaymentMethod); + return apiClient.post("/restaurant-payment-method", restaurantPaymentMethod); }; diff --git a/src/api/review/ReviewType.ts b/src/api/review/ReviewType.ts index 818b4f6..939bba1 100644 --- a/src/api/review/ReviewType.ts +++ b/src/api/review/ReviewType.ts @@ -2,16 +2,17 @@ export type Review = { review_id: string; user_id: string; restaurant_id: string; - rating: number; + username: string; + restaurantName: string; title: string; - visit_date: string; content: string; + rating: number; spending: number; + visit_date: string; + photo?: string; + active: boolean; created_at: string; modified_at: string; - active: boolean; - username: string; - restaurantName: string; }; export type CreateReviewRequest = { diff --git a/src/api/review/reviewApiIndex.ts b/src/api/review/reviewApiIndex.ts index 678f07a..d3f2bfb 100644 --- a/src/api/review/reviewApiIndex.ts +++ b/src/api/review/reviewApiIndex.ts @@ -10,9 +10,9 @@ export const getReviews = async (): Promise => { }; export const getReviewsByRestaurantID = async ( - restaurantId: string + restaurantID: string ): Promise => { - return apiClient.get("", { params: { restaurantId } }); + return apiClient.get("", { params: { restaurantID } }); }; export const createReview = async ( diff --git a/src/components/loader/RestaurantDetailSkeletonLoader.tsx b/src/components/skeletonLoader/RestaurantDetailSkeletonLoader.tsx similarity index 100% rename from src/components/loader/RestaurantDetailSkeletonLoader.tsx rename to src/components/skeletonLoader/RestaurantDetailSkeletonLoader.tsx diff --git a/src/components/utils/buttons/UploadButton.tsx b/src/components/utils/buttons/UploadButton.tsx new file mode 100644 index 0000000..bd0a288 --- /dev/null +++ b/src/components/utils/buttons/UploadButton.tsx @@ -0,0 +1,12 @@ +const UploadButton: React.FC = () => { + return ( + + ); +}; + +export default UploadButton; diff --git a/src/components/utils/cards/RestaurantCard.tsx b/src/components/utils/cards/RestaurantCard.tsx index e3bb07a..50be326 100644 --- a/src/components/utils/cards/RestaurantCard.tsx +++ b/src/components/utils/cards/RestaurantCard.tsx @@ -22,7 +22,7 @@ const RestaurantCard: React.FC = (props: Restaurant) => { >
{props.name} diff --git a/src/components/utils/cards/ReviewCard.tsx b/src/components/utils/cards/ReviewCard.tsx index fa2168d..629fabf 100644 --- a/src/components/utils/cards/ReviewCard.tsx +++ b/src/components/utils/cards/ReviewCard.tsx @@ -13,7 +13,7 @@ import { format } from "date-fns"; const ReviewRow = ({ text, icon }: { text: string; icon: React.ReactNode }) => (
{icon}
-

{text}

+

{text}

); @@ -23,25 +23,39 @@ const ReviewCard: React.FC = (props: Review) => { to={`/review/${props.review_id}`} className="rounded-md shadow-lg hover:bg-slate-200" > -
- } /> - } /> - } /> -
-
{}
- {Array.from({ length: props.rating }).map((_, index) => ( - - {} - - ))} +
+
+ } /> + } /> + } + /> +
+
{}
+ {Array.from({ length: props.rating }).map((_, index) => ( + + {} + + ))} +
+ } + />
- } - /> + {props.photo && ( +
+ +
+ )}
); diff --git a/src/components/utils/modals/AddReviewModal.tsx b/src/components/utils/modals/AddReviewModal.tsx index 9cdbbd9..2eb2c87 100644 --- a/src/components/utils/modals/AddReviewModal.tsx +++ b/src/components/utils/modals/AddReviewModal.tsx @@ -68,14 +68,7 @@ const AddReviewModal: React.FC = ( await uploadImage( review.photo, props?.restaurant_id as string, - "photos", - reviewID - ); - - await uploadImage( - review.photo, - props?.restaurant_id as string, - "menus", + "reviews", reviewID ); } diff --git a/src/pages/restaurant/RestaurantOverviewPage.tsx b/src/pages/restaurant/RestaurantOverviewPage.tsx index 9c5a78d..5935c91 100644 --- a/src/pages/restaurant/RestaurantOverviewPage.tsx +++ b/src/pages/restaurant/RestaurantOverviewPage.tsx @@ -10,9 +10,10 @@ import useOnClickOutside from "../../components/hooks/useOnClickOutside"; import RestaurantOverviewButton from "../../components/utils/buttons/RestaurantOverviewButton"; import ReviewCard from "../../components/utils/cards/ReviewCard"; import AddReviewModal from "../../components/utils/modals/AddReviewModal"; -import RestaurantDetailSkeletonLoader from "../../components/loader/RestaurantDetailSkeletonLoader"; +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"; function isUUID(id: string) { const uuidPattern = @@ -55,25 +56,6 @@ const RestaurantOverviewPage: React.FC = () => { fetchRestaurantReview(); }, [id, dispatch]); - useEffect(() => { - if (id === "8879942f-fce4-41d2-8aab-3faeb8d8c909") { - setPhotos( - reviews.map((review) => ({ - id: review.review_id, - src: `${process.env.REACT_APP_IMAGE_PREFIX}/photos/${id}/${review.review_id}.jpg`, - })) - ); - setMenus( - reviews - .map((review) => ({ - id: review.review_id, - src: `${process.env.REACT_APP_IMAGE_PREFIX}/menus/${id}/${review.review_id}.jpg`, - })) - .sort((a, b) => a.id.localeCompare(b.id)) - ); - } - }, [id, reviews]); - useEffect(() => { if (!id || !isUUID(id)) { navigate("error"); @@ -129,9 +111,9 @@ const RestaurantOverviewPage: React.FC = () => {
{restaurantDetail && ( )}
@@ -140,7 +122,12 @@ const RestaurantOverviewPage: React.FC = () => { ) : (

{restaurantDetail.name}

-
{restaurantDetail.averageRating}
+ {restaurantDetail.averageRating && ( +
+
rating
+
{restaurantDetail.averageRating}
+
+ )}
{restaurantDetail?.address}
@@ -188,12 +175,6 @@ const RestaurantOverviewPage: React.FC = () => { <>

Photos

-
{photos.length === 0 &&
No photos in this restaurant
} {photos.length > 0 && ( @@ -228,12 +209,7 @@ const RestaurantOverviewPage: React.FC = () => { <>

Menus

- +
{menus.length === 0 && (
No menu photos are provided for this restaurant
diff --git a/src/pages/review/ReviewPage.tsx b/src/pages/review/ReviewPage.tsx index 03be3e1..df97332 100644 --- a/src/pages/review/ReviewPage.tsx +++ b/src/pages/review/ReviewPage.tsx @@ -30,6 +30,9 @@ const ReviewPage: React.FC = () => { const dispatch = useDispatch(); const review = useSelector((state: IRootState) => state.review.review); + const restaurant = useSelector( + (state: IRootState) => state.restaurant.restaurant + ); useEffect(() => { const fetchReview = async () => { @@ -43,7 +46,7 @@ const ReviewPage: React.FC = () => {
hero diff --git a/src/redux/auth/authSlice.ts b/src/redux/auth/authSlice.ts index b56cd00..42615af 100644 --- a/src/redux/auth/authSlice.ts +++ b/src/redux/auth/authSlice.ts @@ -1,21 +1,21 @@ import { createAsyncThunk, createSlice } from "@reduxjs/toolkit"; -import { UserLogin } from "../../api/auth/authType"; -import { - getCurrentUser, - postUserAuth, - postUserRegister, -} from "../../api/auth/authApiIndex"; +import { getCurrentUser, login, register } from "../../api/auth/authApiIndex"; + +export interface CurrentLoginUserInfo { + user_id: string; + username: string; + email: string; + role: string; +} export interface IAuthState { - users: UserLogin[]; - currentUser: UserLogin | null; + currentUser: CurrentLoginUserInfo | null; message: string; registerSuccess: boolean | null; loginSuccess: boolean | null; } const initialState: IAuthState = { - users: [], currentUser: null, message: "", registerSuccess: null, @@ -25,7 +25,7 @@ const initialState: IAuthState = { export const registerThunk = createAsyncThunk( "auth/register", async (user: { email: string; username: string; password: string }) => { - const response = await postUserRegister(user); + const response = await register(user); return response; } ); @@ -33,7 +33,7 @@ export const registerThunk = createAsyncThunk( export const loginThunk = createAsyncThunk( "auth/login", async (user: { username: string; password: string }) => { - const response = await postUserAuth(user); + const response = await login(user); return response; } ); @@ -49,31 +49,7 @@ export const getCurrentUserThunk = createAsyncThunk( const authSlice = createSlice({ name: "auth", initialState, - reducers: { - // getAllToDoItems: ( - // state: IAuthState, - // action: PayloadAction - // ) => { - // state.users = action.payload; - // }, - // addToDoItem: (state: IAuthState, action: PayloadAction) => { - // state.users.unshift(action.payload); - // }, - // updateToDoItem: ( - // state: IAuthState, - // action: PayloadAction<{ id: string; name: string }> - // ) => { - // const { id, name } = action.payload; - // state.users.filter((item) => item.user_id === id)[0].username = name; - // }, - // deleteToDoItem: (state: IAuthState, action: PayloadAction) => { - // const id = action.payload; - // state.users.splice( - // state.users.findIndex((item) => item.user_id === id), - // 1 - // ); - // }, - }, + reducers: {}, extraReducers: (builder) => { builder.addCase(registerThunk.fulfilled, (state, action) => { if (action.payload?.token) { @@ -106,6 +82,4 @@ const authSlice = createSlice({ }, }); -// export const { getAllToDoItems, addToDoItem, updateToDoItem, deleteToDoItem } = -// authSlice.actions; export default authSlice.reducer;