From 9f91acee5b729a05899686d6586787bcc15c2ebb Mon Sep 17 00:00:00 2001 From: Amitosh Swain Mahapatra Date: Sun, 7 Feb 2021 19:58:18 +0530 Subject: [PATCH] Implement profile page view --- frontend/src/components/Snowflake.tsx | 2 + frontend/src/components/UserInfo.tsx | 39 +++++++++ .../src/components/feed/CurrentUserInfo.tsx | 39 +-------- .../components/profile/ProfilePage.module.css | 3 + .../src/components/profile/ProfilePage.tsx | 81 +++++++++++++++++++ frontend/src/lib/api.ts | 16 ++-- snowflake/controllers/api/users.py | 15 +++- 7 files changed, 152 insertions(+), 43 deletions(-) diff --git a/frontend/src/components/Snowflake.tsx b/frontend/src/components/Snowflake.tsx index 8ec686c..41f64c1 100644 --- a/frontend/src/components/Snowflake.tsx +++ b/frontend/src/components/Snowflake.tsx @@ -4,6 +4,7 @@ import {Redirect, Route, Switch} from "react-router-dom"; import FeedPage from "./feed/FeedPage"; import styles from './Snowflake.module.css'; import OneOnOnesPage from "./one-on-ones/OneOnOnesPage"; +import ProfilePage from "./profile/ProfilePage"; export default function Snowflake() { return ( @@ -16,6 +17,7 @@ export default function Snowflake() { + diff --git a/frontend/src/components/UserInfo.tsx b/frontend/src/components/UserInfo.tsx index e69de29..5776b32 100644 --- a/frontend/src/components/UserInfo.tsx +++ b/frontend/src/components/UserInfo.tsx @@ -0,0 +1,39 @@ +import React from "react"; +import {User} from "../lib/auth"; +import {Link} from "react-router-dom"; + +export default function UserInfo(props: User) { + const {name, profilePic, username, designation, teamName} = props; + return ( +
+
+
+ {name} +
+

+ + {name} + +

+

+ {designation} @ {teamName} +

+
+
+
+
+ + {/*{{appreciations_given}}*/} + + Given +
+
+ + {/*{{appreciations_received}}*/} + + Received +
+
+
); +} diff --git a/frontend/src/components/feed/CurrentUserInfo.tsx b/frontend/src/components/feed/CurrentUserInfo.tsx index f800374..12b0b10 100644 --- a/frontend/src/components/feed/CurrentUserInfo.tsx +++ b/frontend/src/components/feed/CurrentUserInfo.tsx @@ -1,41 +1,8 @@ import {useAuth} from "../../hooks/use-auth"; -import {Link} from "react-router-dom"; import React from "react"; +import UserInfo from "../UserInfo"; export default function CurrentUserInfo() { - const auth = useAuth(); - const {name, profilePic: avatar, username, designation, teamName} = auth.user!; - - return ( -
-
-
- {name} -
-

- - {name} - -

-

- {designation} @ {teamName} -

-
-
-
-
- - {/*{{appreciations_given}}*/} - - Given -
-
- - {/*{{appreciations_received}}*/} - - Received -
-
-
); + const {user} = useAuth(); + return user ? : Logged out; } diff --git a/frontend/src/components/profile/ProfilePage.module.css b/frontend/src/components/profile/ProfilePage.module.css index e69de29..0995287 100644 --- a/frontend/src/components/profile/ProfilePage.module.css +++ b/frontend/src/components/profile/ProfilePage.module.css @@ -0,0 +1,3 @@ +.container { + width: 50rem; +} diff --git a/frontend/src/components/profile/ProfilePage.tsx b/frontend/src/components/profile/ProfilePage.tsx index e69de29..a2d2f23 100644 --- a/frontend/src/components/profile/ProfilePage.tsx +++ b/frontend/src/components/profile/ProfilePage.tsx @@ -0,0 +1,81 @@ +import React, {useCallback} from "react"; +import {Link, Route, Switch, useParams, useRouteMatch} from "react-router-dom"; +import UserInfo from "../UserInfo"; +import {useAsync} from "../../hooks/use-async"; +import {userByUsername} from "../../lib/api"; +import Loading from "../Loading"; +import styles from './ProfilePage.module.css'; + +type ProfilePageRouteParams = { + username: string +} + +type TabItemProps = React.ComponentPropsWithoutRef & { + path: string +} + +function TabItem({path, children}: TabItemProps) { + const match = useRouteMatch(path); + + const classes = []; + + if (match && match.path === path && match.isExact) { + classes.push('is-active') + } + + return ( +
  • {children}
  • + ) +} + +export default function ProfilePage() { + const {username} = useParams(); + + const loadUserInfo = useCallback(() => userByUsername(username), [username]); + const {value: user, status} = useAsync(loadUserInfo); + + const {path, url} = useRouteMatch(); + + return ( +
    + {status === "pending" && } + {user && } + {status === "success" && ( +
    + +
    +
      + + + + + + About + + + + + + + + Mentions + + + + + + + + Personal Objectives + + +
    +
    + + + +
    +
    )} +
    + ); +} diff --git a/frontend/src/lib/api.ts b/frontend/src/lib/api.ts index 765bc85..1739cbe 100644 --- a/frontend/src/lib/api.ts +++ b/frontend/src/lib/api.ts @@ -51,26 +51,30 @@ async function get(url: string): Promise { return response.data } -export async function appreciations(): Promise { +export function appreciations(): Promise { return get("/api/appreciations"); } -export async function notificationCount(): Promise { +export function notificationCount(): Promise { return get("/api/notifications/_count"); } -export async function appreciationComments(id: number): Promise { +export function appreciationComments(id: number): Promise { return get(`/api/appreciations/${id}/comments`); } -export async function appreciationLikes(id: number): Promise { +export function appreciationLikes(id: number): Promise { return get(`/api/appreciations/${id}/likes`); } -export async function oneOnOnes(): Promise { +export function oneOnOnes(): Promise { return get("/api/one_on_ones") } -export async function oneOnOneById(id: number | string): Promise { +export function oneOnOneById(id: number | string): Promise { return get(`/api/one_on_ones/${id}`) } + +export function userByUsername(username: string): Promise { + return get(`/api/users/${username}`) +} diff --git a/snowflake/controllers/api/users.py b/snowflake/controllers/api/users.py index 0d1d2f8..5547e5b 100644 --- a/snowflake/controllers/api/users.py +++ b/snowflake/controllers/api/users.py @@ -1,6 +1,7 @@ from flask import Blueprint, request +from flask_login import login_required -from .response import bad_request +from .response import bad_request, not_found from ...models import User from ...schemas.user import UserSchema @@ -10,6 +11,7 @@ @blueprint.route('/_autocomplete') +@login_required def autocomplete(): term = request.args.get('q') @@ -19,3 +21,14 @@ def autocomplete(): users = User.find_by_name_prefix(term) return schema.jsonify(users, many=True) + + +@blueprint.route('/') +@login_required +def get_user_by_id(username): + user = User.get_by_username(username) + + if not user: + return not_found() + + return schema.jsonify(user)