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
+}