Skip to content

Commit

Permalink
feat: add skeleton loader, closes #26
Browse files Browse the repository at this point in the history
co-authored-by: wingck <ckwwingo@gmail.com>
  • Loading branch information
ttiimmothy and wingck committed Nov 24, 2023
1 parent 9f802cd commit 94ce306
Show file tree
Hide file tree
Showing 12 changed files with 113 additions and 24 deletions.
21 changes: 21 additions & 0 deletions src/components/skeletonLoader/RestaurantCardSkeletonLoader.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import ContentLoader from "react-content-loader";

const RestaurantCardSkeletonLoader: React.FC<{ width: string }> = ({
width,
}) => (
<ContentLoader
speed={1}
width={width}
height={285}
viewBox={`0 0 ${width} 285`}
backgroundColor="#f3f3f3"
foregroundColor="#ecebeb"
>
<rect x="0" y="0" rx="0" ry="0" width="363" height="190" />
<rect x="48" y="202" rx="0" ry="0" width="80" height="20" />
<rect x="48" y="230" rx="0" ry="0" width="120" height="20" />
<rect x="48" y="257" rx="0" ry="0" width="200" height="20" />
</ContentLoader>
);

export default RestaurantCardSkeletonLoader;
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import ContentLoader from "react-content-loader";

const RestaurantDetailSkeletonLoader = () => (
const RestaurantDetailSkeletonLoader: React.FC = () => (
<ContentLoader
speed={1}
width={340}
Expand Down
2 changes: 1 addition & 1 deletion src/components/utils/cards/ReviewCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ const ReviewCard: React.FC<Review> = (props: Review) => {
<div className="flex gap-1">
{Array.from({ length: props.rating }).map((_, index) => (
<span className="text-yellow-400" key={index}>
{<IoStar />}
<IoStar />
</span>
))}
</div>
Expand Down
27 changes: 23 additions & 4 deletions src/pages/home/HomePage.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
import { useForm, Controller } from "react-hook-form";
import { useEffect } from "react";
import { useEffect, useState } from "react";
import { Link, useNavigate } from "react-router-dom";
import { useDispatch, useSelector } from "react-redux";

import { AppDispatch, IRootState } from "../../store";
import { getRestaurantsByQueryThunk } from "../../redux/restaurant/restaurantSlice";
import RestaurantCardSkeletonLoader from "../../components/skeletonLoader/RestaurantCardSkeletonLoader";
import RestaurantCard from "../../components/utils/cards/RestaurantCard";
import SearchInput from "../../components/utils/inputs/SearchInput";

export default function HomePage(): JSX.Element {
const [loading, setLoading] = useState(true);
const navigate = useNavigate();
const { control, handleSubmit } = useForm();

Expand All @@ -24,6 +27,12 @@ export default function HomePage(): JSX.Element {
fetchRestaurants();
}, [dispatch]);

useEffect(() => {
if (restaurants.length > 0) {
setLoading(false);
}
}, [restaurants]);

return (
<div>
<form
Expand Down Expand Up @@ -67,9 +76,19 @@ export default function HomePage(): JSX.Element {
</Link>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
{restaurants.map((restaurant) => (
<RestaurantCard {...restaurant} key={restaurant.restaurant_id} />
))}
{loading &&
Array.from({
length: 6,
}).map((_, index) => (
<RestaurantCardSkeletonLoader
key={`loader ${index}`}
width="363"
/>
))}
{!loading &&
restaurants.map((restaurant) => (
<RestaurantCard {...restaurant} key={restaurant.restaurant_id} />
))}
</div>
</div>
</div>
Expand Down
15 changes: 11 additions & 4 deletions src/pages/login/LoginPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { useForm, Controller } from "react-hook-form";
import { Link, useNavigate } from "react-router-dom";
import { closeSnackbar, enqueueSnackbar } from "notistack";
import { useDispatch, useSelector } from "react-redux";
import { loginThunk } from "../../redux/auth/authSlice";
import { loginThunk, updateMessage } from "../../redux/auth/authSlice";
import { AppDispatch, IRootState } from "../../store";

import TextInput from "../../components/utils/inputs/TextInput";
Expand All @@ -27,16 +27,23 @@ function LoginPage() {
setTimeout(() => {
navigate("/");
}, 1000);
} else if (loginSuccess === false) {
} else if (loginSuccess === false && message) {
enqueueSnackbar(`${message} You may try again`, {
variant: "error",
});
}

setTimeout(() => {
closeSnackbar();
}, 2000);
}, [loginSuccess, navigate, message]);
}, [loginSuccess, navigate, message, dispatch]);

useEffect(() => {
setTimeout(() => {
if (message) {
dispatch(updateMessage(""));
}
}, 2000);
}, [dispatch, message]);

return (
<form
Expand Down
6 changes: 6 additions & 0 deletions src/pages/restaurant/CreateRestaurantPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,12 @@ const CreateRestaurantPage: React.FC = () => {
fetchPaymentMethods();
}, [user?.role, dispatch]);

useEffect(() => {
if (!user?.user_id) {
navigate("/");
}
}, [user, navigate]);

const createNewRestaurant = async (
restaurant: RestaurantForm,
start_time: Date,
Expand Down
31 changes: 27 additions & 4 deletions src/pages/restaurant/RestaurantHomePage.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useEffect } from "react";
import { useEffect, useState } from "react";
import { useNavigate, useSearchParams } from "react-router-dom";
import { Controller, useForm } from "react-hook-form";
import { useDispatch, useSelector } from "react-redux";
Expand All @@ -7,8 +7,11 @@ import { AppDispatch, IRootState } from "../../store";
import { getRestaurantsByQueryThunk } from "../../redux/restaurant/restaurantSlice";
import RestaurantCard from "../../components/utils/cards/RestaurantCard";
import SearchInput from "../../components/utils/inputs/SearchInput";
import RestaurantCardSkeletonLoader from "../../components/skeletonLoader/RestaurantCardSkeletonLoader";

const RestaurantHomePage = () => {
const [loading, setLoading] = useState(true);

const dispatch = useDispatch<AppDispatch>();
const restaurants = useSelector(
(state: IRootState) => state.restaurant.restaurants
Expand All @@ -35,6 +38,16 @@ const RestaurantHomePage = () => {
fetchRestaurants();
}, [searchParams, dispatch]);

useEffect(() => {
if (restaurants.length > 0 && !searchParams.get("search")) {
setLoading(false);
}

if (searchParams.get("search")) {
setLoading(false);
}
}, [restaurants, searchParams]);

const handleSubmitSearch = (data: { name: string }) => {
navigate(`/restaurants/?search=${data.name}`);
navigate(0);
Expand All @@ -60,9 +73,19 @@ const RestaurantHomePage = () => {
)}
/>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4 my-6">
{restaurants.map((restaurant, index) => (
<RestaurantCard {...restaurant} key={`restaurant${index}`} />
))}
{loading &&
Array.from({
length: 10,
}).map((_, index) => (
<RestaurantCardSkeletonLoader
key={`loader ${index}`}
width="330"
/>
))}
{!loading &&
restaurants.map((restaurant, index) => (
<RestaurantCard {...restaurant} key={`restaurant${index}`} />
))}
</div>
</form>
</>
Expand Down
2 changes: 1 addition & 1 deletion src/pages/restaurant/RestaurantOverviewPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ const RestaurantOverviewPage: React.FC = () => {
length: Math.round(restaurantDetail.averageRating),
}).map((_, index) => (
<span className="text-yellow-400" key={index}>
{<IoStar size={12} />}
<IoStar size={12} />
</span>
))}
</div>
Expand Down
12 changes: 10 additions & 2 deletions src/pages/signUp/SignUpPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { useDispatch, useSelector } from "react-redux";
import { closeSnackbar, enqueueSnackbar } from "notistack";

import { AppDispatch, IRootState } from "../../store";
import { registerThunk } from "../../redux/auth/authSlice";
import { registerThunk, updateMessage } from "../../redux/auth/authSlice";
import TextInput from "../../components/utils/inputs/TextInput";

const SignUpPage = () => {
Expand Down Expand Up @@ -33,7 +33,7 @@ const SignUpPage = () => {
navigate("/");
navigate(0);
}, 1000);
} else if (registerSuccess === false) {
} else if (registerSuccess === false && message) {
enqueueSnackbar(message, {
variant: "error",
});
Expand All @@ -44,6 +44,14 @@ const SignUpPage = () => {
}, 2000);
}, [registerSuccess, navigate, message]);

useEffect(() => {
setTimeout(() => {
if (message) {
dispatch(updateMessage(""));
}
}, 2000);
}, [dispatch, message]);

return (
<form
className="h-screen flex flex-col gap-6 justify-center max-w-sm mx-auto px-4"
Expand Down
9 changes: 7 additions & 2 deletions src/redux/auth/authSlice.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { createAsyncThunk, createSlice } from "@reduxjs/toolkit";
import { PayloadAction, createAsyncThunk, createSlice } from "@reduxjs/toolkit";
import { getCurrentUser, login, register } from "../../api/auth/authApiIndex";

export interface CurrentLoginUserInfo {
Expand Down Expand Up @@ -49,7 +49,11 @@ export const getCurrentUserThunk = createAsyncThunk(
const authSlice = createSlice({
name: "auth",
initialState,
reducers: {},
reducers: {
updateMessage: (state: IAuthState, action: PayloadAction<string>) => {
state.message = action.payload;
},
},
extraReducers: (builder) => {
builder.addCase(registerThunk.fulfilled, (state, action) => {
if (action.payload?.token) {
Expand Down Expand Up @@ -82,4 +86,5 @@ const authSlice = createSlice({
},
});

export const { updateMessage } = authSlice.actions;
export default authSlice.reducer;
6 changes: 3 additions & 3 deletions src/redux/photo/photoSlice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ export const createMenuPhotoThunk = createAsyncThunk(
}
);

const photoReducer = createSlice({
const photoSlice = createSlice({
name: "photo",
initialState,
reducers: {
Expand Down Expand Up @@ -85,5 +85,5 @@ const photoReducer = createSlice({
},
});

export const { updateReviewPhotos, updateMenuPhotos } = photoReducer.actions;
export default photoReducer.reducer;
export const { updateReviewPhotos, updateMenuPhotos } = photoSlice.actions;
export default photoSlice.reducer;
4 changes: 2 additions & 2 deletions src/redux/review/reviewSlice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export const createReviewThunk = createAsyncThunk(
}
);

const reviewReducer = createSlice({
const reviewSlice = createSlice({
name: "review",
initialState,
reducers: {},
Expand All @@ -73,4 +73,4 @@ const reviewReducer = createSlice({
},
});

export default reviewReducer.reducer;
export default reviewSlice.reducer;

0 comments on commit 94ce306

Please sign in to comment.