diff --git a/src/constants/api.ts b/src/constants/api.ts index 79438b3..e6a15c4 100644 --- a/src/constants/api.ts +++ b/src/constants/api.ts @@ -8,6 +8,8 @@ const GET_REGIONS = `${BASE_URL}/regions`; const GET_REGENCIES = `${BASE_URL}/region/regencies`; const GET_PROVINCES = `${BASE_URL}/region/provinces`; +const GET_CURRENT_USER_STATS = `${BASE_URL}/user/profile`; + const GET_LIST_LOCATIONS_URI = `${BASE_URL}/locations`; const GET_LIST_TOP_LOCATIONS = `${BASE_URL}/locations/top-ratings` const GET_LIST_RECENT_LOCATIONS_RATING_URI = `${BASE_URL}/locations/recent` @@ -28,6 +30,7 @@ export { GET_REGIONS, GET_PROVINCES, GET_REGENCIES, + GET_CURRENT_USER_STATS, GET_LIST_RECENT_LOCATIONS_RATING_URI, GET_LIST_TOP_LOCATIONS, GET_LIST_LOCATIONS_URI, diff --git a/src/pages/LocationDetail/index.tsx b/src/pages/LocationDetail/index.tsx index db3aece..31558b6 100644 --- a/src/pages/LocationDetail/index.tsx +++ b/src/pages/LocationDetail/index.tsx @@ -639,6 +639,8 @@ function LocationDetail() { {/* {screen.width >= 1024 &&
+ // ADD USER DISTRIBUTION SOMETHING LIKE THIS + // https://www.w3schools.com/howto/tryit.asp?filename=tryhow_css_user_rating Lorem ipsum dolor sit amet consectetur adipisicing elit. Reprehenderit cumque aliquam doloribus in reiciendis? Laborum, ea assumenda, tempora dolore placeat aspernatur, cumque totam sequi debitis dolor nam eligendi suscipit aliquid?
} */} diff --git a/src/pages/UserFeed/index.tsx b/src/pages/UserFeed/index.tsx new file mode 100644 index 0000000..02b86fc --- /dev/null +++ b/src/pages/UserFeed/index.tsx @@ -0,0 +1,9 @@ +function UserFeed() { + return ( +
+

User feed

+
+ ) +} + +export default UserFeed; \ No newline at end of file diff --git a/src/pages/UserProfile/index.tsx b/src/pages/UserProfile/index.tsx new file mode 100644 index 0000000..16cfa4f --- /dev/null +++ b/src/pages/UserProfile/index.tsx @@ -0,0 +1,227 @@ +import { useSelector } from "react-redux"; +import { DEFAULT_AVATAR_IMG } from "../../constants/default"; +import { UserRootState } from "../../store/type"; +import "./style.css" +import { useEffect, useState } from "preact/compat"; +import { getUserStatsService } from "../../services"; +import { CustomInterweave, SeparatorWithAnchor } from "../../components"; + +interface UserStats { + followers: number, + score_count: number +} + +interface UserStatsReviews { + id: number, + comments: string, + name: string, + province_name: string, + score: number, + thumbnail: string +} + +interface ScoresDistrbution { + score: number +} + +interface UserStatsResponse { + reviews: Array, + user_stats: UserStats, + scores_distribution: Array +} + +const emptyUserStatsResponse: UserStatsResponse = { + reviews: Array(), + user_stats: { + followers: 0, + score_count: 0 + }, + scores_distribution: [ + { + score: 0 + } + ] +} + +function UserProfile() { + const [userStats, setUserStats] = useState(emptyUserStatsResponse); + + const user = useSelector((state: UserRootState) => state.auth) + + async function getUserStats() { + try { + const res = await getUserStatsService() + setUserStats(res.data) + } catch (err) { + console.log(err) + } + } + + function scoreDistributionLabel(val: string) { + if (val === '0') { + return `${val}-9` + } + + if (val === '99') { + return '100' + } + + return `${val}0-${val}9` + + } + + useEffect(() => { + getUserStats() + }, []) + + return ( +
+
+
+ +

{user.username}

+ {/*
+ + +
*/} +
+
+

{userStats?.user_stats.followers}

+

Followers

+
+
+

{userStats?.user_stats.score_count}

+

Reviews

+
+
+ +
+ +
+ +
+
+
+
+ 0 ? '#' : ''} /> + {userStats!.reviews.length > 0 ? + <> + {userStats!.reviews.map(x => ( +
+
+ + + +
+ +

{x.province_name}

+
+
{x.score}
+
+
+
+
+
+ +
+ +
+ ))} + + : + <> + No users review to display + + } +
+
+ {screen.width >= 1024 && +
+
+
+ + {Object.entries(userStats.scores_distribution[0]).map(x => ( +
+
{scoreDistributionLabel(x[0])}
+ {console.log(x[1]/userStats.user_stats.score_count * 100/100)} +
+
{x[1]}
+
+
+ )) + } +
+
+
+ } +
+
+
+
+ ) +} + +export default UserProfile; \ No newline at end of file diff --git a/src/pages/UserProfile/style.css b/src/pages/UserProfile/style.css new file mode 100644 index 0000000..2b59556 --- /dev/null +++ b/src/pages/UserProfile/style.css @@ -0,0 +1,13 @@ +.profile-nav { + white-space: nowrap; + overflow: hidden; + text-align: center; +} + +.profile-nav div { + display: inline-block; + padding: 0 2%; + text-transform: uppercase; + letter-spacing: 1px; + font-size: 0.75rem; +} \ No newline at end of file diff --git a/src/pages/index.tsx b/src/pages/index.tsx index 4822b49..9265824 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -8,11 +8,15 @@ import Login from './Login'; import NotFound from "./NotFound"; import AddLocation from "./AddLocation"; import Submissions from "./Submissions"; +import UserProfile from "./UserProfile"; +import UserFeed from "./UserFeed"; export { Login, Home, + UserProfile, + UserFeed, NotFound, diff --git a/src/routes/index.tsx b/src/routes/index.tsx index af291de..07f0ea1 100644 --- a/src/routes/index.tsx +++ b/src/routes/index.tsx @@ -5,7 +5,9 @@ import { LocationDetail, NewsEvent, Story, - AddLocation + AddLocation, + UserProfile, + UserFeed } from '../pages'; const routes = [ @@ -43,7 +45,17 @@ const routes = [ path: "/add-location", name: "AddLocation", element: - } + }, + { + path: "/user/profile", + name: "UserProfile", + element: + }, + { + path: "/user/feed", + name: "UserFeed", + element: + }, ] export default routes; \ No newline at end of file diff --git a/src/services/index.ts b/src/services/index.ts index d4d3518..775f453 100644 --- a/src/services/index.ts +++ b/src/services/index.ts @@ -9,6 +9,7 @@ import { getImagesByLocationService } from "./images" import { createAccountService, loginService, logoutService } from "./auth"; import { postReviewLocation, getCurrentUserLocationReviewService } from "./review"; import { getRegionsService, getProvincesService, getRegenciesService} from "./regions"; +import { getUserStatsService } from "./users"; export { createAccountService, @@ -19,6 +20,8 @@ export { getProvincesService, getRegenciesService, + getUserStatsService, + getListLocationsService, getListRecentLocationsRatingsService, getListTopLocationsService, diff --git a/src/services/locations.ts b/src/services/locations.ts index 266da77..4f24991 100644 --- a/src/services/locations.ts +++ b/src/services/locations.ts @@ -114,7 +114,7 @@ async function getLocationTagsService(id: Number) { async function createLocationService(data: FormData): Promise { const newState: IHttpResponse = { data: null, error: null}; try { - const response = await client({ method: 'POST', url: POST_CREATE_LOCATION, data: data}) + const response = await client({ method: 'POST', url: POST_CREATE_LOCATION, data: data, withCredentials: true}) newState.data = response.data; newState.status = response.status return newState; diff --git a/src/services/users.ts b/src/services/users.ts new file mode 100644 index 0000000..0f67a9e --- /dev/null +++ b/src/services/users.ts @@ -0,0 +1,24 @@ +import { AxiosError } from "axios"; +import { GET_CURRENT_USER_STATS } from "../constants/api"; +import { IHttpResponse } from "../types/common"; +import { client } from "./config"; + + +async function getUserStatsService(): Promise { + const newState: IHttpResponse = { data: null, error: null }; + try { + const res = await client({ method: 'GET', url: GET_CURRENT_USER_STATS, withCredentials: true}) + newState.data = res.data + newState.status = res.status + return newState + } catch(error) { + let err = error as AxiosError + newState.error = err + newState.status = err.status + throw(newState) + } +} + +export { + getUserStatsService, +} \ No newline at end of file