diff --git a/src/popup/App.tsx b/src/popup/App.tsx index 2ae1a26..9630785 100644 --- a/src/popup/App.tsx +++ b/src/popup/App.tsx @@ -1,6 +1,7 @@ import { Icon, IconType } from '../blocks/Icon'; import { Panel } from '../blocks/Panel'; import './App.css'; +import { UserInfoHeader } from './components/UserInfoHeader/UserInfoHeader'; import { PopupContextProvider } from './hooks/PopupContext'; import { ActivityPage } from './pages/ActivityPage'; import { OverallPage } from './pages/OverallPage'; @@ -85,7 +86,7 @@ export const PopupApp: React.FC = () => {
- Codealike +
{tabs} diff --git a/src/popup/components/UserInfoHeader/UserInfoHeader.tsx b/src/popup/components/UserInfoHeader/UserInfoHeader.tsx new file mode 100644 index 0000000..fc808ce --- /dev/null +++ b/src/popup/components/UserInfoHeader/UserInfoHeader.tsx @@ -0,0 +1,70 @@ +import * as React from "react"; +import { getProfile } from "../../../shared/api/client"; +import { ProfileResponse } from "./type"; +import { usePopupContext } from "../../hooks/PopupContext"; +import { ConnectionStatus } from "../../../shared/db/types"; + +export const UserInfoHeader: React.FC = () => { + const { settings, updateSettings } = usePopupContext(); + const [state, setState] = React.useState<{ + identity: string | undefined; + }>({ + identity: settings.username, + }); + + const getUserProfile = React.useCallback(() => { + getProfile(settings.userToken as string) + .then((res: ProfileResponse) => { + setState((prev) => ({ + ...prev, + identity: res.Identity + })); + updateSettings({ + username: res.Identity + }) + }); + }, [settings, updateSettings]); + + React.useEffect(() => { + (async function () { + const { username, connectionStatus } = settings + + if (username) { + setState((prev) => ({ + ...prev, + identity: username + })); + } + + if (connectionStatus === ConnectionStatus.Connected && !username) { + getUserProfile(); + } + + if (connectionStatus === ConnectionStatus.Disconnected && username) { + setState((prev) => ({ + ...prev, + identity: '' + })); + updateSettings({ + username: '' + }) + } + })(); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [settings]); + + const { identity } = state; + return ( + <> +
+ Codealike + { + identity + ? ({identity}) + : (User not connected) + } + +
+ + ) +}; \ No newline at end of file diff --git a/src/popup/components/UserInfoHeader/type.ts b/src/popup/components/UserInfoHeader/type.ts new file mode 100644 index 0000000..50f1b90 --- /dev/null +++ b/src/popup/components/UserInfoHeader/type.ts @@ -0,0 +1,10 @@ +export interface ProfileResponse { + Identity: string + FullName: string + DisplayName: string + Address?: string + State?: string + Country?: string + AvatarUri: string + Email: string +} \ No newline at end of file diff --git a/src/shared/api/client.ts b/src/shared/api/client.ts index e8e5e35..7b88378 100644 --- a/src/shared/api/client.ts +++ b/src/shared/api/client.ts @@ -1,4 +1,5 @@ import { + ProfileResponse, TokenProperties, WebActivityLog, WebActivityRecord, @@ -82,6 +83,34 @@ export const authorize = (token: string): Promise<{ result: boolean }> => { }); }; +export const getProfile = (token: string): Promise => { + return new Promise((resolve, reject) => { + const { userId, uuid } = getTokenProperties(token); + const url = `${CodealikeHost}/account/${userId}/profile`; + console.log(`url: ${url}`) + + fetch(url, { + headers: getHeaders(userId, uuid), + method: 'GET', + }) + .then((result) => { + if (result.status === 200) { + return result.json() + } else { + reject(); + } + }) + .then((response) => { + console.log('Response body:', response); + resolve(response); + }) + .catch((err) => { + console.log((err as Error).message); + reject(); + }); + }); +}; + const getTokenProperties = (token: string): TokenProperties => { if (token === undefined) { throw new Error(InvalidTokenError); diff --git a/src/shared/db/types.ts b/src/shared/db/types.ts index e31518c..aae0f7a 100644 --- a/src/shared/db/types.ts +++ b/src/shared/db/types.ts @@ -61,6 +61,7 @@ export interface Preferences { limits: Record; displayTimeOnBadge: boolean; lastUpdateStats?: Statistics; + username?: string } export interface Statistics { @@ -78,3 +79,14 @@ export interface TokenProperties { userId: string; uuid: string; } + +export interface ProfileResponse { + Identity: string + FullName: string + DisplayName: string + Address?: string + State?: string + Country?: string + AvatarUri: string + Email: string +}