diff --git a/space/components/account/user-logged-in.tsx b/space/components/account/user-logged-in.tsx
index d0f177038..a9930b5fd 100644
--- a/space/components/account/user-logged-in.tsx
+++ b/space/components/account/user-logged-in.tsx
@@ -1,6 +1,8 @@
"use client";
import Image from "next/image";
+// components
+import { UserAvatar } from "@/components/issues/navbar/user-avatar";
// hooks
import { useUser } from "@/hooks/store";
// assets
@@ -18,19 +20,7 @@ export const UserLoggedIn = () => {
-
- {user.avatar && user.avatar !== "" ? (
-
- {/* eslint-disable-next-line @next/next/no-img-element */}
-
-
- ) : (
-
- {(user.display_name ?? "U")[0]}
-
- )}
-
{user.display_name}
-
+
diff --git a/space/components/issues/navbar/controls.tsx b/space/components/issues/navbar/controls.tsx
index 888d85648..4b9bb7d5f 100644
--- a/space/components/issues/navbar/controls.tsx
+++ b/space/components/issues/navbar/controls.tsx
@@ -2,18 +2,16 @@
import { useEffect, FC } from "react";
import { observer } from "mobx-react-lite";
-import Link from "next/link";
-import { useRouter, useSearchParams, usePathname } from "next/navigation";
-// ui
-import { Avatar, Button } from "@plane/ui";
+import { useRouter, useSearchParams } from "next/navigation";
// components
import { IssueFiltersDropdown } from "@/components/issues/filters";
import { NavbarIssueBoardView } from "@/components/issues/navbar/issue-board-view";
import { NavbarTheme } from "@/components/issues/navbar/theme";
+import { UserAvatar } from "@/components/issues/navbar/user-avatar";
// helpers
import { queryParamGenerator } from "@/helpers/query-param-generator";
// hooks
-import { useProject, useUser, useIssueFilter, useIssueDetails } from "@/hooks/store";
+import { useProject, useIssueFilter, useIssueDetails } from "@/hooks/store";
// types
import { TIssueLayout } from "@/types/issue";
@@ -27,7 +25,6 @@ export const NavbarControls: FC = observer((props) => {
const { workspaceSlug, projectId } = props;
// router
const router = useRouter();
- const pathName = usePathname();
const searchParams = useSearchParams();
// query params
const board = searchParams.get("board") || undefined;
@@ -38,7 +35,6 @@ export const NavbarControls: FC = observer((props) => {
// hooks
const { issueFilters, isIssueFiltersUpdated, initIssueFilters } = useIssueFilter();
const { settings } = useProject();
- const { data: user } = useUser();
const { setPeekId } = useIssueDetails();
// derived values
const activeLayout = issueFilters?.display_filters?.layout || undefined;
@@ -115,20 +111,7 @@ export const NavbarControls: FC = observer((props) => {
- {user?.id ? (
-
-
-
- {user?.display_name || `${user?.first_name} ${user?.first_name}` || user?.email || "User"}
-
-
- ) : (
-
-
-
-
-
- )}
+
>
);
});
diff --git a/space/components/issues/navbar/user-avatar.tsx b/space/components/issues/navbar/user-avatar.tsx
new file mode 100644
index 000000000..51051a22a
--- /dev/null
+++ b/space/components/issues/navbar/user-avatar.tsx
@@ -0,0 +1,124 @@
+"use client";
+
+import { FC, Fragment, useEffect, useState } from "react";
+import { observer } from "mobx-react-lite";
+import Link from "next/link";
+import { usePathname, useSearchParams } from "next/navigation";
+import { usePopper } from "react-popper";
+import { LogOut } from "lucide-react";
+import { Popover, Transition } from "@headlessui/react";
+import { Avatar, Button } from "@plane/ui";
+// helpers
+import { API_BASE_URL } from "@/helpers/common.helper";
+import { queryParamGenerator } from "@/helpers/query-param-generator";
+// hooks
+import { useUser } from "@/hooks/store";
+// services
+import { AuthService } from "@/services/auth.service";
+
+const authService = new AuthService();
+
+export const UserAvatar: FC = observer(() => {
+ const pathName = usePathname();
+ const searchParams = useSearchParams();
+ // query params
+ const board = searchParams.get("board") || undefined;
+ const labels = searchParams.get("labels") || undefined;
+ const state = searchParams.get("state") || undefined;
+ const priority = searchParams.get("priority") || undefined;
+ const peekId = searchParams.get("peekId") || undefined;
+ // hooks
+ const { data: currentUser, signOut } = useUser();
+ // states
+ const [csrfToken, setCsrfToken] = useState(undefined);
+ const [referenceElement, setReferenceElement] = useState(null);
+ const [popperElement, setPopperElement] = useState(null);
+
+ useEffect(() => {
+ if (csrfToken === undefined)
+ authService.requestCSRFToken().then((data) => data?.csrf_token && setCsrfToken(data.csrf_token));
+ }, [csrfToken]);
+
+ const { styles, attributes } = usePopper(referenceElement, popperElement, {
+ placement: "bottom-end",
+ modifiers: [
+ {
+ name: "offset",
+ options: {
+ offset: [0, 40],
+ },
+ },
+ ],
+ });
+
+ // derived values
+ const { queryParam } = queryParamGenerator({ peekId, board, state, priority, labels });
+
+ return (
+
+ {currentUser?.id ? (
+
+
+
+
+
+
+
+
+ {csrfToken && (
+
+ )}
+
+
+
+
+
+ ) : (
+
+
+
+
+
+ )}
+
+ );
+});
diff --git a/space/components/issues/peek-overview/comment/comment-reactions.tsx b/space/components/issues/peek-overview/comment/comment-reactions.tsx
index 3c867a7e9..d340e695a 100644
--- a/space/components/issues/peek-overview/comment/comment-reactions.tsx
+++ b/space/components/issues/peek-overview/comment/comment-reactions.tsx
@@ -34,7 +34,7 @@ export const CommentReactions: React.FC = observer((props) => {
const commentReactions = peekId ? details[peekId].comments.find((c) => c.id === commentId)?.comment_reactions : [];
const groupedReactions = peekId ? groupReactions(commentReactions ?? [], "reaction") : {};
- const userReactions = commentReactions?.filter((r) => r.actor_detail.id === user?.id);
+ const userReactions = commentReactions?.filter((r) => r?.actor_detail?.id === user?.id);
const handleAddReaction = (reactionHex: string) => {
if (!workspaceSlug || !projectId || !peekId) return;
@@ -79,7 +79,7 @@ export const CommentReactions: React.FC = observer((props) => {
tooltipContent={
{reactions
- .map((r) => r.actor_detail.display_name)
+ .map((r) => r?.actor_detail?.display_name)
.splice(0, REACTIONS_LIMIT)
.join(", ")}
{reactions.length > REACTIONS_LIMIT && " and " + (reactions.length - REACTIONS_LIMIT) + " more"}
@@ -93,7 +93,7 @@ export const CommentReactions: React.FC
= observer((props) => {
else router.push(`/?next_path=${pathName}?${queryParam}`);
}}
className={`flex h-full items-center gap-1 rounded-md px-2 py-1 text-sm text-custom-text-100 ${
- commentReactions?.some((r) => r.actor_detail.id === user?.id && r.reaction === reaction)
+ commentReactions?.some((r) => r?.actor_detail?.id === user?.id && r.reaction === reaction)
? "bg-custom-primary-100/10"
: "bg-custom-background-80"
}`}
@@ -101,7 +101,7 @@ export const CommentReactions: React.FC = observer((props) => {
{renderEmoji(reaction)}
r.actor_detail.id === user?.id && r.reaction === reaction)
+ commentReactions?.some((r) => r?.actor_detail?.id === user?.id && r.reaction === reaction)
? "text-custom-primary-100"
: ""
}
diff --git a/space/store/user.store.ts b/space/store/user.store.ts
index 5e65a59fb..52cf3ca66 100644
--- a/space/store/user.store.ts
+++ b/space/store/user.store.ts
@@ -179,7 +179,6 @@ export class UserStore implements IUserStore {
* @returns {Promise}
*/
signOut = async (): Promise => {
- // await this.authService.signOut(API_BASE_URL);
- // this.store.resetOnSignOut();
+ this.store.reset();
};
}