From 9264bf6adb9e441741cfd49cb10333a32430be70 Mon Sep 17 00:00:00 2001 From: Rodean Fraser Date: Tue, 11 Nov 2025 21:49:59 -0500 Subject: [PATCH 01/10] feature/BA-2725 profile summary drawer --- .../context/ChatRoomProvider/constants.ts | 8 +++ .../common/context/ChatRoomProvider/index.tsx | 3 + .../common/context/ChatRoomProvider/types.ts | 16 +++++ .../common/graphql/fragments/RoomTitle.ts | 7 +- .../modules/messages/common/utils.ts | 17 +++-- .../AllChatRoomsList/ChatRoomItem/index.tsx | 4 +- .../ChatRoomHeader/ChatRoomOptions/index.tsx | 4 ++ .../ChatRoomHeader/ChatRoomOptions/types.ts | 1 + .../web/ChatRoom/ChatRoomHeader/index.tsx | 27 +++++-- .../web/ChatRoomsComponent/constants.ts | 1 + .../messages/web/ChatRoomsComponent/index.tsx | 18 +++-- .../messages/web/ChatRoomsComponent/types.ts | 3 + .../MessagesList/__storybook__/stories.tsx | 2 + .../web/ProfileSummary/Body/index.tsx | 71 +++++++++++++++++++ .../web/ProfileSummary/Body/styled.tsx | 32 +++++++++ .../messages/web/ProfileSummary/Body/types.ts | 10 +++ .../web/ProfileSummary/Header/index.tsx | 30 ++++++++ .../web/ProfileSummary/Header/styled.tsx | 15 ++++ .../web/ProfileSummary/Header/types.ts | 7 ++ .../messages/web/ProfileSummary/index.tsx | 43 +++++++++++ .../messages/web/ProfileSummary/types.ts | 3 + .../web/icons/ProfileNoCircleIcon/index.tsx | 20 ++++++ .../components/web/icons/index.ts | 1 + 23 files changed, 326 insertions(+), 17 deletions(-) create mode 100644 packages/components/modules/messages/web/ProfileSummary/Body/index.tsx create mode 100644 packages/components/modules/messages/web/ProfileSummary/Body/styled.tsx create mode 100644 packages/components/modules/messages/web/ProfileSummary/Body/types.ts create mode 100644 packages/components/modules/messages/web/ProfileSummary/Header/index.tsx create mode 100644 packages/components/modules/messages/web/ProfileSummary/Header/styled.tsx create mode 100644 packages/components/modules/messages/web/ProfileSummary/Header/types.ts create mode 100644 packages/components/modules/messages/web/ProfileSummary/index.tsx create mode 100644 packages/components/modules/messages/web/ProfileSummary/types.ts create mode 100644 packages/design-system/components/web/icons/ProfileNoCircleIcon/index.tsx diff --git a/packages/components/modules/messages/common/context/ChatRoomProvider/constants.ts b/packages/components/modules/messages/common/context/ChatRoomProvider/constants.ts index a5046481..19f23a3c 100644 --- a/packages/components/modules/messages/common/context/ChatRoomProvider/constants.ts +++ b/packages/components/modules/messages/common/context/ChatRoomProvider/constants.ts @@ -3,4 +3,12 @@ import { ChatRoomState } from './types' export const INITIAL_CHAT_ROOM_STATE: ChatRoomState = { id: undefined, participants: undefined, + leftPanelContent: 0, + singleChatProfileDetails: { + pk: undefined, + name: undefined, + username: undefined, + imageUrl: undefined, + biography: undefined, + }, } diff --git a/packages/components/modules/messages/common/context/ChatRoomProvider/index.tsx b/packages/components/modules/messages/common/context/ChatRoomProvider/index.tsx index 58c69091..ab4819df 100644 --- a/packages/components/modules/messages/common/context/ChatRoomProvider/index.tsx +++ b/packages/components/modules/messages/common/context/ChatRoomProvider/index.tsx @@ -14,8 +14,11 @@ const ChatRoomProvider: FC = ({ children }) => { if (!storeRef.current) { storeRef.current = create((set) => ({ ...INITIAL_CHAT_ROOM_STATE, + setChatRoom: (state: ChatRoomState) => set(state), resetChatRoom: () => set({ ...INITIAL_CHAT_ROOM_STATE }), + setLeftPanelContent: (content: number) => set({ leftPanelContent: content }), + setSingleChatProfileDetails: (details) => set({ singleChatProfileDetails: { ...details } }), })) } return {children} diff --git a/packages/components/modules/messages/common/context/ChatRoomProvider/types.ts b/packages/components/modules/messages/common/context/ChatRoomProvider/types.ts index 6b095cbb..923e1ce5 100644 --- a/packages/components/modules/messages/common/context/ChatRoomProvider/types.ts +++ b/packages/components/modules/messages/common/context/ChatRoomProvider/types.ts @@ -1,6 +1,14 @@ export type ChatRoomState = { id?: string participants?: (string | null | undefined)[] + leftPanelContent?: number + singleChatProfileDetails?: { + pk: number | undefined + name: string | null | undefined + username: string | null | undefined + imageUrl: string | null | undefined + biography?: string | null | undefined + } } type ChatRoomFunctions = { @@ -9,6 +17,14 @@ type ChatRoomFunctions = { replace?: boolean | undefined, ) => void resetChatRoom: () => void + setLeftPanelContent: (content: number) => void + setSingleChatProfileDetails: (details: { + pk: number | undefined + name: string | undefined + username: string | undefined + imageUrl: string | undefined + biography?: string | undefined + }) => void } export type UseChatRoom = ChatRoomState & ChatRoomFunctions diff --git a/packages/components/modules/messages/common/graphql/fragments/RoomTitle.ts b/packages/components/modules/messages/common/graphql/fragments/RoomTitle.ts index 3afb5001..1b095ec0 100644 --- a/packages/components/modules/messages/common/graphql/fragments/RoomTitle.ts +++ b/packages/components/modules/messages/common/graphql/fragments/RoomTitle.ts @@ -9,10 +9,15 @@ export const RoomTitleFragment = graphql` node { profile { id + pk name - image(width: 100, height: 100) { + image(width: 128, height: 128) { url } + biography + urlPath { + path + } } role } diff --git a/packages/components/modules/messages/common/utils.ts b/packages/components/modules/messages/common/utils.ts index 4b33c955..91c60b0c 100644 --- a/packages/components/modules/messages/common/utils.ts +++ b/packages/components/modules/messages/common/utils.ts @@ -20,12 +20,15 @@ export const useGroupNameAndAvatar = ( headerRef as GroupTitleFragment$key, ) return { + pk: undefined, + path: undefined, + biography: undefined, title: header?.title, avatar: header?.image?.url, } } -const useRoomNameAndAvatar = (headerRef: RoomTitleFragment$key | null | undefined) => { +export const useSingleChatDetails = (headerRef: RoomTitleFragment$key | null | undefined) => { const { currentProfile } = useCurrentProfile() const header = useFragment(RoomTitleFragment, headerRef) if (!header?.participants) { @@ -39,22 +42,28 @@ const useRoomNameAndAvatar = (headerRef: RoomTitleFragment$key | null | undefine ) if (otherParticipant === undefined) { return { + pk: undefined, title: 'Deleted User', avatar: undefined, + path: undefined, + biography: undefined, } } return { + pk: otherParticipant?.node?.profile?.pk, title: otherParticipant?.node?.profile?.name, avatar: otherParticipant?.node?.profile?.image?.url, + path: otherParticipant?.node?.profile?.urlPath?.path, + biography: otherParticipant?.node?.profile?.biography, } } -export const useNameAndAvatar = (roomHeader: TitleFragment$data) => { - const roomNameAndAvatar = useRoomNameAndAvatar(roomHeader) +export const useChatroomDetails = (roomHeader: TitleFragment$data) => { + const singleChatDetails = useSingleChatDetails(roomHeader) const groupNameAndAvatar = useGroupNameAndAvatar(roomHeader) if (roomHeader.isGroup) return groupNameAndAvatar - return roomNameAndAvatar + return singleChatDetails } export const getParticipantCountString = (participantCount: number | null | undefined) => { diff --git a/packages/components/modules/messages/web/AllChatRoomsList/ChatRoomItem/index.tsx b/packages/components/modules/messages/web/AllChatRoomsList/ChatRoomItem/index.tsx index 79883293..f39f6128 100644 --- a/packages/components/modules/messages/web/AllChatRoomsList/ChatRoomItem/index.tsx +++ b/packages/components/modules/messages/web/AllChatRoomsList/ChatRoomItem/index.tsx @@ -21,7 +21,7 @@ import { TitleFragment, UnreadMessagesCountFragment, useArchiveChatRoomMutation, - useNameAndAvatar, + useChatroomDetails, useUnreadChatMutation, } from '../../../common' import { StyledChatCard } from './styled' @@ -52,7 +52,7 @@ const ChatRoomItem: FC = ({ const chatCardRef = useRef(null) const { currentProfile } = useCurrentProfile() - const { title, avatar } = useNameAndAvatar(headerFragment) + const { title, avatar } = useChatroomDetails(headerFragment) const { lastMessageTime } = lastMessageFragment const lastMessage = lastMessageFragment.lastMessage?.content diff --git a/packages/components/modules/messages/web/ChatRoom/ChatRoomHeader/ChatRoomOptions/index.tsx b/packages/components/modules/messages/web/ChatRoom/ChatRoomHeader/ChatRoomOptions/index.tsx index 5c5a0b77..dc6046ac 100644 --- a/packages/components/modules/messages/web/ChatRoom/ChatRoomHeader/ChatRoomOptions/index.tsx +++ b/packages/components/modules/messages/web/ChatRoom/ChatRoomHeader/ChatRoomOptions/index.tsx @@ -11,11 +11,15 @@ const ChatRoomOptions: FC = ({ onArchiveClicked, onDetailsClicked, onLeaveClicked, + onContactDetailsClicked, }) => ( {isArchived ? 'Unarchive Chat' : 'Archive Chat'} + + Contact Details + {isGroup ? ( <> diff --git a/packages/components/modules/messages/web/ChatRoom/ChatRoomHeader/ChatRoomOptions/types.ts b/packages/components/modules/messages/web/ChatRoom/ChatRoomHeader/ChatRoomOptions/types.ts index 1547823d..d5a9564b 100644 --- a/packages/components/modules/messages/web/ChatRoom/ChatRoomHeader/ChatRoomOptions/types.ts +++ b/packages/components/modules/messages/web/ChatRoom/ChatRoomHeader/ChatRoomOptions/types.ts @@ -5,4 +5,5 @@ export interface ChatRoomOptionsProps { onArchiveClicked: () => void onDetailsClicked: () => void onLeaveClicked: () => void + onContactDetailsClicked: () => void } diff --git a/packages/components/modules/messages/web/ChatRoom/ChatRoomHeader/index.tsx b/packages/components/modules/messages/web/ChatRoom/ChatRoomHeader/index.tsx index 279744e1..20a9e695 100644 --- a/packages/components/modules/messages/web/ChatRoom/ChatRoomHeader/index.tsx +++ b/packages/components/modules/messages/web/ChatRoom/ChatRoomHeader/index.tsx @@ -1,4 +1,4 @@ -import { FC, useState } from 'react' +import { FC, useEffect, useState } from 'react' import { useCurrentProfile } from '@baseapp-frontend/authentication' import { AvatarWithPlaceholder } from '@baseapp-frontend/design-system/components/web/avatars' @@ -20,10 +20,11 @@ import { getParticipantCountString, useArchiveChatRoomMutation, useChatRoom, + useChatroomDetails, useCheckIsAdmin, - useNameAndAvatar, } from '../../../common' import { RoomTitleFragment } from '../../../common/graphql/fragments/RoomTitle' +import { LEFT_PANEL_CONTENT } from '../../ChatRoomsComponent/constants' import LeaveGroupDialog from '../../__shared__/LeaveGroupDialog' import ChatRoomOptions from './ChatRoomOptions' import { BackButtonContainer, ChatHeaderContainer, ChatTitleContainer } from './styled' @@ -37,14 +38,28 @@ const ChatRoomHeader: FC = ({ roomId, }) => { const roomHeader = useFragment(TitleFragment, roomTitleRef) + const [open, setOpen] = useState(false) const { currentProfile } = useCurrentProfile() const isUpToMd = useResponsive('up', 'md') - const { resetChatRoom } = useChatRoom() + const { resetChatRoom, setSingleChatProfileDetails, setLeftPanelContent } = useChatRoom() const { isGroup } = roomHeader - const { title, avatar } = useNameAndAvatar(roomHeader) + const { title, avatar, path, pk, biography } = useChatroomDetails(roomHeader) + + useEffect(() => { + if (!isGroup) { + setSingleChatProfileDetails({ + pk: pk ?? undefined, + name: title ?? '', + username: path ?? '', + imageUrl: avatar ?? '', + biography: biography ?? '', + }) + } + }, [pk, title, path, avatar, biography]) + const { participants } = useFragment(RoomTitleFragment, roomHeader) const { isSoleAdmin } = useCheckIsAdmin(participants as MembersListFragment$data['participants']) const members = getParticipantCountString(participantsCount) @@ -148,6 +163,10 @@ const ChatRoomHeader: FC = ({ popover.onClose() setOpen(true) }} + onContactDetailsClicked={() => { + popover.onClose() + setLeftPanelContent(LEFT_PANEL_CONTENT.profileSummary) + }} /> diff --git a/packages/components/modules/messages/web/ChatRoomsComponent/constants.ts b/packages/components/modules/messages/web/ChatRoomsComponent/constants.ts index e7c1ee55..9ebf389f 100644 --- a/packages/components/modules/messages/web/ChatRoomsComponent/constants.ts +++ b/packages/components/modules/messages/web/ChatRoomsComponent/constants.ts @@ -4,4 +4,5 @@ export const LEFT_PANEL_CONTENT = { createGroupChat: 2, editGroupChat: 3, groupDetails: 4, + profileSummary: 5, } as const diff --git a/packages/components/modules/messages/web/ChatRoomsComponent/index.tsx b/packages/components/modules/messages/web/ChatRoomsComponent/index.tsx index d1dc3521..8b1bcb87 100644 --- a/packages/components/modules/messages/web/ChatRoomsComponent/index.tsx +++ b/packages/components/modules/messages/web/ChatRoomsComponent/index.tsx @@ -1,6 +1,6 @@ 'use client' -import { FC, useState } from 'react' +import { FC } from 'react' import { useResponsive } from '@baseapp-frontend/design-system/hooks/web' @@ -13,10 +13,11 @@ import ChatRoom from '../ChatRoom' import DefaultGroupChatCreate from '../GroupChatCreate' import DefaultGroupChatDetails from '../GroupChatDetails' import DefaultGroupChatEdit from '../GroupChatEdit' +import DefaultProfileSummary from '../ProfileSummary' import DefaultSingleChatCreate from '../SingleChatCreate' import { LEFT_PANEL_CONTENT } from './constants' import { ChatRoomContainer, ChatRoomsContainer, ChatRoomsListContainer } from './styled' -import { ChatRoomsComponentProps, LeftPanelContentValues } from './types' +import { ChatRoomsComponentProps } from './types' const ChatRoomsComponent: FC = ({ chatRoomsQueryData, @@ -31,15 +32,14 @@ const ChatRoomsComponent: FC = ({ GroupChatEditComponentProps = {}, SingleChatCreateComponent = DefaultSingleChatCreate, SingleChatCreateComponentProps = {}, + ProfileSummaryComponent = DefaultProfileSummary, }) => { const isUpToMd = useResponsive('up', 'md') - const [leftPanelContent, setLeftPanelContent] = useState( - LEFT_PANEL_CONTENT.chatRoomList, - ) const [groupDetailsQueryRef, loadGroupDetailsQuery] = useQueryLoader(GroupDetailsQuery) - const { id: selectedRoom } = useChatRoom() + + const { id: selectedRoom, leftPanelContent, setLeftPanelContent } = useChatRoom() const displayGroupDetails = () => { if (selectedRoom) { @@ -99,6 +99,12 @@ const ChatRoomsComponent: FC = ({ {...SingleChatCreateComponentProps} /> ) + case LEFT_PANEL_CONTENT.profileSummary: + return ( + setLeftPanelContent(LEFT_PANEL_CONTENT.chatRoomList)} + /> + ) default: return ( SingleChatCreateComponent?: FC SingleChatCreateComponentProps?: Partial + ProfileSummaryComponent?: FC + ProfileSummaryComponentProps?: Partial } diff --git a/packages/components/modules/messages/web/MessagesList/__storybook__/stories.tsx b/packages/components/modules/messages/web/MessagesList/__storybook__/stories.tsx index d183fc12..15ff668e 100644 --- a/packages/components/modules/messages/web/MessagesList/__storybook__/stories.tsx +++ b/packages/components/modules/messages/web/MessagesList/__storybook__/stories.tsx @@ -10,6 +10,8 @@ const mockChatRoomStore = create((set) => ({ id: 'room-123', setChatRoom: (newState) => set(newState), resetChatRoom: () => set({ id: '' }), + setLeftPanelContent: (_content) => {}, + setSingleChatProfileDetails: (_details) => {}, })) const meta: Meta = { diff --git a/packages/components/modules/messages/web/ProfileSummary/Body/index.tsx b/packages/components/modules/messages/web/ProfileSummary/Body/index.tsx new file mode 100644 index 00000000..d230f345 --- /dev/null +++ b/packages/components/modules/messages/web/ProfileSummary/Body/index.tsx @@ -0,0 +1,71 @@ +import { FC } from 'react' + +import { CircledAvatar } from '@baseapp-frontend/design-system/components/web/avatars' +import { IconButton } from '@baseapp-frontend/design-system/components/web/buttons' +import { + NewGroupIcon, + ProfileNoCircleIcon, +} from '@baseapp-frontend/design-system/components/web/icons' +import { TypographyWithEllipsis } from '@baseapp-frontend/design-system/components/web/typographies' + +import { Box, Typography } from '@mui/material' + +import { HeaderContainer, Subheader, SubheaderContainer, TitleContainer } from './styled' +import { BodyProps } from './types' + +const Body: FC = ({ avatar, avatarSize = 144, biography, username, name, pk }) => { + const formattedUsername = username ? username.replace(/^\/+/, '') : '' + const profilePath = username ?? `/profile/${pk}` + return ( + + + + + + {name} + + + {`@${formattedUsername}`} + + + + + window.open(profilePath, '_blank')} + sx={{ maxWidth: 'fit-content', gap: '8px' }} + > + + + Go to profile + + + + + + + Add contact to a group + + + + + + About + + + + + {biography} + + + + + ) +} + +export default Body diff --git a/packages/components/modules/messages/web/ProfileSummary/Body/styled.tsx b/packages/components/modules/messages/web/ProfileSummary/Body/styled.tsx new file mode 100644 index 00000000..af5f5557 --- /dev/null +++ b/packages/components/modules/messages/web/ProfileSummary/Body/styled.tsx @@ -0,0 +1,32 @@ +import { Box } from '@mui/material' +import { styled } from '@mui/material/styles' + +export const HeaderContainer = styled(Box)(({ theme }) => ({ + display: 'grid', + gridTemplateRows: '144px auto', + justifyItems: 'center', + width: '100%', + padding: theme.spacing(3.5), + gap: theme.spacing(2), +})) + +export const TitleContainer = styled(Box)(() => ({ + width: '100%', + textAlign: 'center', + display: 'grid', + justifyItems: 'center', + gridTemplateRows: '22px 22px', + gap: '8px', +})) + +export const SubheaderContainer = styled(Box)(({ theme }) => ({ + display: 'flex', + flexDirection: 'column', + padding: theme.spacing(2), + gap: theme.spacing(1), +})) + +export const Subheader = styled(Box)(({ theme }) => ({ + paddingTop: theme.spacing(2), + paddingBottom: theme.spacing(2), +})) diff --git a/packages/components/modules/messages/web/ProfileSummary/Body/types.ts b/packages/components/modules/messages/web/ProfileSummary/Body/types.ts new file mode 100644 index 00000000..f008793e --- /dev/null +++ b/packages/components/modules/messages/web/ProfileSummary/Body/types.ts @@ -0,0 +1,10 @@ +import { PropsWithChildren } from 'react' + +export interface BodyProps extends PropsWithChildren { + avatar?: string + avatarSize?: number + biography?: string | null + name?: string | null + username?: string | null + pk?: number | undefined +} diff --git a/packages/components/modules/messages/web/ProfileSummary/Header/index.tsx b/packages/components/modules/messages/web/ProfileSummary/Header/index.tsx new file mode 100644 index 00000000..0dbfb789 --- /dev/null +++ b/packages/components/modules/messages/web/ProfileSummary/Header/index.tsx @@ -0,0 +1,30 @@ +import { FC } from 'react' + +import { IconButton } from '@baseapp-frontend/design-system/components/web/buttons' +import { Iconify } from '@baseapp-frontend/design-system/components/web/images' + +import { Typography } from '@mui/material' + +import { ProfileSummaryHeaderContainer } from './styled' +import { HeaderProps } from './types' + +const Header: FC = ({ + backIcon = 'eva:arrow-ios-back-fill', + backIconProps = {}, + onBackButtonClicked, +}) => ( + + + + + + Contact Details + + +) + +export default Header diff --git a/packages/components/modules/messages/web/ProfileSummary/Header/styled.tsx b/packages/components/modules/messages/web/ProfileSummary/Header/styled.tsx new file mode 100644 index 00000000..e8b78a59 --- /dev/null +++ b/packages/components/modules/messages/web/ProfileSummary/Header/styled.tsx @@ -0,0 +1,15 @@ +import { Box } from '@mui/material' +import { styled } from '@mui/material/styles' + +export const ProfileSummaryHeaderContainer = styled(Box)(({ theme }) => ({ + borderBottom: `1px ${theme.palette.divider} solid`, + width: '100%', + padding: theme.spacing(2), + display: 'grid', + gridTemplateColumns: '24px auto 24px', + gap: theme.spacing(1.5), + alignItems: 'center', + [theme.breakpoints.down('sm')]: { + padding: `${theme.spacing(2)} ${theme.spacing(1.5)} ${theme.spacing(2)}`, + }, +})) diff --git a/packages/components/modules/messages/web/ProfileSummary/Header/types.ts b/packages/components/modules/messages/web/ProfileSummary/Header/types.ts new file mode 100644 index 00000000..5e6fe49f --- /dev/null +++ b/packages/components/modules/messages/web/ProfileSummary/Header/types.ts @@ -0,0 +1,7 @@ +import { IconifyProps } from '@baseapp-frontend/design-system/components/web/images' + +export interface HeaderProps { + backIcon?: IconifyProps['icon'] + backIconProps?: Partial> + onBackButtonClicked: VoidFunction +} diff --git a/packages/components/modules/messages/web/ProfileSummary/index.tsx b/packages/components/modules/messages/web/ProfileSummary/index.tsx new file mode 100644 index 00000000..52027617 --- /dev/null +++ b/packages/components/modules/messages/web/ProfileSummary/index.tsx @@ -0,0 +1,43 @@ +'use client' + +import { FC, Suspense } from 'react' + +import { LoadingState } from '@baseapp-frontend/design-system/components/web/displays' + +import { useChatRoom } from '../../common' +import Body from './Body' +import Header from './Header' +import { ProfileSummaryProps } from './types' + +const ProfileSummary: FC = ({ onBackButtonClicked }) => { + const { singleChatProfileDetails } = useChatRoom() + const { imageUrl, name, username, biography, pk } = singleChatProfileDetails || {} + + return ( + <> +
+ + + ) +} + +const SuspendedProfileSummary: FC = ({ onBackButtonClicked, ...props }) => ( + +
+ + + } + > + + +) + +export default SuspendedProfileSummary diff --git a/packages/components/modules/messages/web/ProfileSummary/types.ts b/packages/components/modules/messages/web/ProfileSummary/types.ts new file mode 100644 index 00000000..8fce8c43 --- /dev/null +++ b/packages/components/modules/messages/web/ProfileSummary/types.ts @@ -0,0 +1,3 @@ +export type ProfileSummaryProps = { + onBackButtonClicked: () => void +} diff --git a/packages/design-system/components/web/icons/ProfileNoCircleIcon/index.tsx b/packages/design-system/components/web/icons/ProfileNoCircleIcon/index.tsx new file mode 100644 index 00000000..eec717cf --- /dev/null +++ b/packages/design-system/components/web/icons/ProfileNoCircleIcon/index.tsx @@ -0,0 +1,20 @@ +import { FC } from 'react' + +import { SvgIcon, SvgIconProps } from '@mui/material' + +const ProfileNoCircleIcon: FC = ({ sx, ...props }) => ( + + + + + + +) + +export default ProfileNoCircleIcon diff --git a/packages/design-system/components/web/icons/index.ts b/packages/design-system/components/web/icons/index.ts index 6e189b4d..4c5a98aa 100644 --- a/packages/design-system/components/web/icons/index.ts +++ b/packages/design-system/components/web/icons/index.ts @@ -28,6 +28,7 @@ export { default as OutlinedCheckMarkIcon } from './OutlinedCheckMarkIcon' export { default as OutlinedEditIcon } from './OutlinedEditIcon' export { default as PenEditIcon } from './PenEditIcon' export { default as PinIcon } from './PinIcon' +export { default as ProfileNoCircleIcon } from './ProfileNoCircleIcon' export { default as SendMessageIcon } from './SendMessageIcon' export { default as ShareIcon } from './ShareIcon' export { default as ThreeDotsIcon } from './ThreeDotsIcon' From 8fbca84f0bcbe170997731a2bdd0af31c02f0fb6 Mon Sep 17 00:00:00 2001 From: Rodean Fraser Date: Sun, 16 Nov 2025 21:06:44 -0500 Subject: [PATCH 02/10] qa updates --- .../ChatRoomHeader/ChatRoomOptions/index.tsx | 8 ++- .../web/ProfileSummary/Body/index.tsx | 63 +++++++++++-------- .../web/ProfileSummary/Body/styled.tsx | 11 +++- 3 files changed, 51 insertions(+), 31 deletions(-) diff --git a/packages/components/modules/messages/web/ChatRoom/ChatRoomHeader/ChatRoomOptions/index.tsx b/packages/components/modules/messages/web/ChatRoom/ChatRoomHeader/ChatRoomOptions/index.tsx index dc6046ac..5f212acf 100644 --- a/packages/components/modules/messages/web/ChatRoom/ChatRoomHeader/ChatRoomOptions/index.tsx +++ b/packages/components/modules/messages/web/ChatRoom/ChatRoomHeader/ChatRoomOptions/index.tsx @@ -17,9 +17,11 @@ const ChatRoomOptions: FC = ({ {isArchived ? 'Unarchive Chat' : 'Archive Chat'} - - Contact Details - + {!isGroup && ( + + Contact Details + + )} {isGroup ? ( <> diff --git a/packages/components/modules/messages/web/ProfileSummary/Body/index.tsx b/packages/components/modules/messages/web/ProfileSummary/Body/index.tsx index d230f345..816fbb1e 100644 --- a/packages/components/modules/messages/web/ProfileSummary/Body/index.tsx +++ b/packages/components/modules/messages/web/ProfileSummary/Body/index.tsx @@ -8,9 +8,15 @@ import { } from '@baseapp-frontend/design-system/components/web/icons' import { TypographyWithEllipsis } from '@baseapp-frontend/design-system/components/web/typographies' -import { Box, Typography } from '@mui/material' +import { Box, Divider, Typography } from '@mui/material' -import { HeaderContainer, Subheader, SubheaderContainer, TitleContainer } from './styled' +import { + ButtonContainer, + HeaderContainer, + Subheader, + SubheaderContainer, + TitleContainer, +} from './styled' import { BodyProps } from './types' const Body: FC = ({ avatar, avatarSize = 144, biography, username, name, pk }) => { @@ -30,37 +36,44 @@ const Body: FC = ({ avatar, avatarSize = 144, biography, username, na - window.open(profilePath, '_blank')} - sx={{ maxWidth: 'fit-content', gap: '8px' }} - > - - - Go to profile - - - - - - - Add contact to a group - - + + window.open(profilePath, '_blank')} + sx={{ maxWidth: 'fit-content', gap: '8px' }} + > + + + Go to profile + + + + + + Add contact to a group + + + About + - {biography} + {biography?.split('\n').map((line, index) => ( + + {line} + {index < biography.split('\n').length - 1 &&
} +
+ ))}
diff --git a/packages/components/modules/messages/web/ProfileSummary/Body/styled.tsx b/packages/components/modules/messages/web/ProfileSummary/Body/styled.tsx index af5f5557..b29556e0 100644 --- a/packages/components/modules/messages/web/ProfileSummary/Body/styled.tsx +++ b/packages/components/modules/messages/web/ProfileSummary/Body/styled.tsx @@ -22,11 +22,16 @@ export const TitleContainer = styled(Box)(() => ({ export const SubheaderContainer = styled(Box)(({ theme }) => ({ display: 'flex', flexDirection: 'column', - padding: theme.spacing(2), gap: theme.spacing(1), })) +export const ButtonContainer = styled(Box)(({ theme }) => ({ + display: 'flex', + flexDirection: 'column', + gap: theme.spacing(1), + padding: theme.spacing(2), +})) + export const Subheader = styled(Box)(({ theme }) => ({ - paddingTop: theme.spacing(2), - paddingBottom: theme.spacing(2), + padding: theme.spacing(2), })) From 45f5d2c9ef6bbb53cf02ec29dd5ea30348b426d9 Mon Sep 17 00:00:00 2001 From: Rodean Fraser Date: Tue, 25 Nov 2025 00:01:37 -0500 Subject: [PATCH 03/10] review updates --- .../context/ChatRoomProvider/constants.ts | 10 +---- .../common/context/ChatRoomProvider/index.tsx | 1 - .../common/context/ChatRoomProvider/types.ts | 22 ++++------- .../context/useChatRoom}/constants.ts | 0 .../graphql/fragments/ProfileSummary.ts | 30 ++++++++++++++ .../common/graphql/fragments/RoomTitle.ts | 7 +--- .../graphql/queries/GroupDetailsQuery.ts | 1 + .../modules/messages/common/utils.ts | 15 ++----- .../AllChatRoomsList/ChatRoomItem/index.tsx | 4 +- .../web/ChatRoom/ChatRoomHeader/index.tsx | 24 +++--------- .../web/ChatRoom/ChatRoomHeader/types.ts | 1 + .../__storybook__/ChatRoomWithQuery/index.tsx | 1 + .../modules/messages/web/ChatRoom/index.tsx | 2 + .../modules/messages/web/ChatRoom/types.ts | 1 + .../messages/web/ChatRoomsComponent/index.tsx | 19 ++++++++- .../messages/web/ChatRoomsComponent/types.ts | 2 +- .../MessagesList/__storybook__/stories.tsx | 1 - .../web/ProfileSummary/Body/index.tsx | 39 ++++++++++++++++--- .../messages/web/ProfileSummary/Body/types.ts | 8 ++-- .../messages/web/ProfileSummary/index.tsx | 20 +++++----- .../messages/web/ProfileSummary/types.ts | 5 +++ .../web/icons/ProfileNoCircleIcon/index.tsx | 4 +- 22 files changed, 128 insertions(+), 89 deletions(-) rename packages/components/modules/messages/{web/ChatRoomsComponent => common/context/useChatRoom}/constants.ts (100%) create mode 100644 packages/components/modules/messages/common/graphql/fragments/ProfileSummary.ts diff --git a/packages/components/modules/messages/common/context/ChatRoomProvider/constants.ts b/packages/components/modules/messages/common/context/ChatRoomProvider/constants.ts index 19f23a3c..7c1cc13f 100644 --- a/packages/components/modules/messages/common/context/ChatRoomProvider/constants.ts +++ b/packages/components/modules/messages/common/context/ChatRoomProvider/constants.ts @@ -1,14 +1,8 @@ +import { LEFT_PANEL_CONTENT } from '../useChatRoom/constants' import { ChatRoomState } from './types' export const INITIAL_CHAT_ROOM_STATE: ChatRoomState = { id: undefined, participants: undefined, - leftPanelContent: 0, - singleChatProfileDetails: { - pk: undefined, - name: undefined, - username: undefined, - imageUrl: undefined, - biography: undefined, - }, + leftPanelContent: LEFT_PANEL_CONTENT.chatRoomList, } diff --git a/packages/components/modules/messages/common/context/ChatRoomProvider/index.tsx b/packages/components/modules/messages/common/context/ChatRoomProvider/index.tsx index ab4819df..d6b849b1 100644 --- a/packages/components/modules/messages/common/context/ChatRoomProvider/index.tsx +++ b/packages/components/modules/messages/common/context/ChatRoomProvider/index.tsx @@ -18,7 +18,6 @@ const ChatRoomProvider: FC = ({ children }) => { setChatRoom: (state: ChatRoomState) => set(state), resetChatRoom: () => set({ ...INITIAL_CHAT_ROOM_STATE }), setLeftPanelContent: (content: number) => set({ leftPanelContent: content }), - setSingleChatProfileDetails: (details) => set({ singleChatProfileDetails: { ...details } }), })) } return {children} diff --git a/packages/components/modules/messages/common/context/ChatRoomProvider/types.ts b/packages/components/modules/messages/common/context/ChatRoomProvider/types.ts index 923e1ce5..76e3985f 100644 --- a/packages/components/modules/messages/common/context/ChatRoomProvider/types.ts +++ b/packages/components/modules/messages/common/context/ChatRoomProvider/types.ts @@ -1,30 +1,22 @@ +import { ValueOf } from '@baseapp-frontend/utils' + +import { LEFT_PANEL_CONTENT } from '../useChatRoom/constants' + export type ChatRoomState = { id?: string participants?: (string | null | undefined)[] leftPanelContent?: number - singleChatProfileDetails?: { - pk: number | undefined - name: string | null | undefined - username: string | null | undefined - imageUrl: string | null | undefined - biography?: string | null | undefined - } } +export type LeftPanelContentValues = ValueOf + type ChatRoomFunctions = { setChatRoom: ( partial: Partial | ((state: ChatRoomState) => Partial), replace?: boolean | undefined, ) => void resetChatRoom: () => void - setLeftPanelContent: (content: number) => void - setSingleChatProfileDetails: (details: { - pk: number | undefined - name: string | undefined - username: string | undefined - imageUrl: string | undefined - biography?: string | undefined - }) => void + setLeftPanelContent: (content: LeftPanelContentValues) => void } export type UseChatRoom = ChatRoomState & ChatRoomFunctions diff --git a/packages/components/modules/messages/web/ChatRoomsComponent/constants.ts b/packages/components/modules/messages/common/context/useChatRoom/constants.ts similarity index 100% rename from packages/components/modules/messages/web/ChatRoomsComponent/constants.ts rename to packages/components/modules/messages/common/context/useChatRoom/constants.ts diff --git a/packages/components/modules/messages/common/graphql/fragments/ProfileSummary.ts b/packages/components/modules/messages/common/graphql/fragments/ProfileSummary.ts new file mode 100644 index 00000000..d22e1d00 --- /dev/null +++ b/packages/components/modules/messages/common/graphql/fragments/ProfileSummary.ts @@ -0,0 +1,30 @@ +import { graphql } from 'react-relay' + +export const ProfileSummaryFragment = graphql` + fragment ProfileSummaryFragment on ChatRoom + @argumentDefinitions( + avatarSize: { type: "Int", defaultValue: 100 } + count: { type: "Int", defaultValue: 5 } + ) { + id + participants(first: $count) { + edges { + node { + profile { + id + pk + name + image(width: $avatarSize, height: $avatarSize) { + url + } + biography + urlPath { + path + } + } + role + } + } + } + } +` diff --git a/packages/components/modules/messages/common/graphql/fragments/RoomTitle.ts b/packages/components/modules/messages/common/graphql/fragments/RoomTitle.ts index 1b095ec0..8f1e09e1 100644 --- a/packages/components/modules/messages/common/graphql/fragments/RoomTitle.ts +++ b/packages/components/modules/messages/common/graphql/fragments/RoomTitle.ts @@ -9,15 +9,10 @@ export const RoomTitleFragment = graphql` node { profile { id - pk name - image(width: 128, height: 128) { + image(width: 100, height: 128) { url } - biography - urlPath { - path - } } role } diff --git a/packages/components/modules/messages/common/graphql/queries/GroupDetailsQuery.ts b/packages/components/modules/messages/common/graphql/queries/GroupDetailsQuery.ts index 4a976fba..452d02f6 100644 --- a/packages/components/modules/messages/common/graphql/queries/GroupDetailsQuery.ts +++ b/packages/components/modules/messages/common/graphql/queries/GroupDetailsQuery.ts @@ -7,6 +7,7 @@ export const GroupDetailsQuery = graphql` participantsCount ...GroupTitleFragment ...MembersListFragment + ...ProfileSummaryFragment } } ` diff --git a/packages/components/modules/messages/common/utils.ts b/packages/components/modules/messages/common/utils.ts index 91c60b0c..566c00d0 100644 --- a/packages/components/modules/messages/common/utils.ts +++ b/packages/components/modules/messages/common/utils.ts @@ -20,15 +20,12 @@ export const useGroupNameAndAvatar = ( headerRef as GroupTitleFragment$key, ) return { - pk: undefined, - path: undefined, - biography: undefined, title: header?.title, avatar: header?.image?.url, } } -export const useSingleChatDetails = (headerRef: RoomTitleFragment$key | null | undefined) => { +export const useRoomNameAndAvatar = (headerRef: RoomTitleFragment$key | null | undefined) => { const { currentProfile } = useCurrentProfile() const header = useFragment(RoomTitleFragment, headerRef) if (!header?.participants) { @@ -42,25 +39,19 @@ export const useSingleChatDetails = (headerRef: RoomTitleFragment$key | null | u ) if (otherParticipant === undefined) { return { - pk: undefined, title: 'Deleted User', avatar: undefined, - path: undefined, - biography: undefined, } } return { - pk: otherParticipant?.node?.profile?.pk, title: otherParticipant?.node?.profile?.name, avatar: otherParticipant?.node?.profile?.image?.url, - path: otherParticipant?.node?.profile?.urlPath?.path, - biography: otherParticipant?.node?.profile?.biography, } } -export const useChatroomDetails = (roomHeader: TitleFragment$data) => { - const singleChatDetails = useSingleChatDetails(roomHeader) +export const useNameAndAvatar = (roomHeader: TitleFragment$data) => { + const singleChatDetails = useRoomNameAndAvatar(roomHeader) const groupNameAndAvatar = useGroupNameAndAvatar(roomHeader) if (roomHeader.isGroup) return groupNameAndAvatar return singleChatDetails diff --git a/packages/components/modules/messages/web/AllChatRoomsList/ChatRoomItem/index.tsx b/packages/components/modules/messages/web/AllChatRoomsList/ChatRoomItem/index.tsx index f39f6128..79883293 100644 --- a/packages/components/modules/messages/web/AllChatRoomsList/ChatRoomItem/index.tsx +++ b/packages/components/modules/messages/web/AllChatRoomsList/ChatRoomItem/index.tsx @@ -21,7 +21,7 @@ import { TitleFragment, UnreadMessagesCountFragment, useArchiveChatRoomMutation, - useChatroomDetails, + useNameAndAvatar, useUnreadChatMutation, } from '../../../common' import { StyledChatCard } from './styled' @@ -52,7 +52,7 @@ const ChatRoomItem: FC = ({ const chatCardRef = useRef(null) const { currentProfile } = useCurrentProfile() - const { title, avatar } = useChatroomDetails(headerFragment) + const { title, avatar } = useNameAndAvatar(headerFragment) const { lastMessageTime } = lastMessageFragment const lastMessage = lastMessageFragment.lastMessage?.content diff --git a/packages/components/modules/messages/web/ChatRoom/ChatRoomHeader/index.tsx b/packages/components/modules/messages/web/ChatRoom/ChatRoomHeader/index.tsx index 20a9e695..96d34d54 100644 --- a/packages/components/modules/messages/web/ChatRoom/ChatRoomHeader/index.tsx +++ b/packages/components/modules/messages/web/ChatRoom/ChatRoomHeader/index.tsx @@ -1,4 +1,4 @@ -import { FC, useEffect, useState } from 'react' +import { FC, useState } from 'react' import { useCurrentProfile } from '@baseapp-frontend/authentication' import { AvatarWithPlaceholder } from '@baseapp-frontend/design-system/components/web/avatars' @@ -20,11 +20,10 @@ import { getParticipantCountString, useArchiveChatRoomMutation, useChatRoom, - useChatroomDetails, useCheckIsAdmin, + useNameAndAvatar, } from '../../../common' import { RoomTitleFragment } from '../../../common/graphql/fragments/RoomTitle' -import { LEFT_PANEL_CONTENT } from '../../ChatRoomsComponent/constants' import LeaveGroupDialog from '../../__shared__/LeaveGroupDialog' import ChatRoomOptions from './ChatRoomOptions' import { BackButtonContainer, ChatHeaderContainer, ChatTitleContainer } from './styled' @@ -35,6 +34,7 @@ const ChatRoomHeader: FC = ({ participantsCount, roomTitleRef, onDisplayGroupDetailsClicked, + onDisplayProfileSummaryClicked, roomId, }) => { const roomHeader = useFragment(TitleFragment, roomTitleRef) @@ -43,22 +43,10 @@ const ChatRoomHeader: FC = ({ const { currentProfile } = useCurrentProfile() const isUpToMd = useResponsive('up', 'md') - const { resetChatRoom, setSingleChatProfileDetails, setLeftPanelContent } = useChatRoom() + const { resetChatRoom } = useChatRoom() const { isGroup } = roomHeader - const { title, avatar, path, pk, biography } = useChatroomDetails(roomHeader) - - useEffect(() => { - if (!isGroup) { - setSingleChatProfileDetails({ - pk: pk ?? undefined, - name: title ?? '', - username: path ?? '', - imageUrl: avatar ?? '', - biography: biography ?? '', - }) - } - }, [pk, title, path, avatar, biography]) + const { title, avatar } = useNameAndAvatar(roomHeader) const { participants } = useFragment(RoomTitleFragment, roomHeader) const { isSoleAdmin } = useCheckIsAdmin(participants as MembersListFragment$data['participants']) @@ -165,7 +153,7 @@ const ChatRoomHeader: FC = ({ }} onContactDetailsClicked={() => { popover.onClose() - setLeftPanelContent(LEFT_PANEL_CONTENT.profileSummary) + onDisplayProfileSummaryClicked() }} /> diff --git a/packages/components/modules/messages/web/ChatRoom/ChatRoomHeader/types.ts b/packages/components/modules/messages/web/ChatRoom/ChatRoomHeader/types.ts index 2987d9c4..b6a579a3 100644 --- a/packages/components/modules/messages/web/ChatRoom/ChatRoomHeader/types.ts +++ b/packages/components/modules/messages/web/ChatRoom/ChatRoomHeader/types.ts @@ -7,6 +7,7 @@ export interface ChatRoomHeaderProps { participantsCount: number roomTitleRef: TitleFragment$key onDisplayGroupDetailsClicked: VoidFunction + onDisplayProfileSummaryClicked: VoidFunction roomId?: string } diff --git a/packages/components/modules/messages/web/ChatRoom/__storybook__/ChatRoomWithQuery/index.tsx b/packages/components/modules/messages/web/ChatRoom/__storybook__/ChatRoomWithQuery/index.tsx index c22e0427..3c37609a 100644 --- a/packages/components/modules/messages/web/ChatRoom/__storybook__/ChatRoomWithQuery/index.tsx +++ b/packages/components/modules/messages/web/ChatRoom/__storybook__/ChatRoomWithQuery/index.tsx @@ -26,6 +26,7 @@ const ChatRoomWithQuery = () => { alert('Group details clicked')} + onDisplayProfileSummaryClicked={() => alert('Profile summary clicked')} MessagesListProps={{ roomRef: data.chatRoom as MessagesListFragment$key }} /> ) diff --git a/packages/components/modules/messages/web/ChatRoom/index.tsx b/packages/components/modules/messages/web/ChatRoom/index.tsx index f58cf400..d4ba9f8c 100644 --- a/packages/components/modules/messages/web/ChatRoom/index.tsx +++ b/packages/components/modules/messages/web/ChatRoom/index.tsx @@ -22,6 +22,7 @@ const ChatRoom: FC = ({ SendMessage = DefaultSendMessage, SendMessageProps = {}, onDisplayGroupDetailsClicked, + onDisplayProfileSummaryClicked, }) => { // TODO: pre load this query and instead of lazyload const { chatRoom } = useLazyLoadQuery( @@ -47,6 +48,7 @@ const ChatRoom: FC = ({ participantsCount={chatRoom.participantsCount} roomTitleRef={chatRoom} onDisplayGroupDetailsClicked={onDisplayGroupDetailsClicked} + onDisplayProfileSummaryClicked={onDisplayProfileSummaryClicked} roomId={roomId} /> diff --git a/packages/components/modules/messages/web/ChatRoom/types.ts b/packages/components/modules/messages/web/ChatRoom/types.ts index e82c4ef8..1c2c0a93 100644 --- a/packages/components/modules/messages/web/ChatRoom/types.ts +++ b/packages/components/modules/messages/web/ChatRoom/types.ts @@ -10,4 +10,5 @@ export interface ChatRoomProps { SendMessage?: FC SendMessageProps?: Partial onDisplayGroupDetailsClicked: () => void + onDisplayProfileSummaryClicked: () => void } diff --git a/packages/components/modules/messages/web/ChatRoomsComponent/index.tsx b/packages/components/modules/messages/web/ChatRoomsComponent/index.tsx index 8b1bcb87..5c85685d 100644 --- a/packages/components/modules/messages/web/ChatRoomsComponent/index.tsx +++ b/packages/components/modules/messages/web/ChatRoomsComponent/index.tsx @@ -8,6 +8,7 @@ import { useQueryLoader } from 'react-relay' import { GroupDetailsQuery as GroupDetailsQueryType } from '../../../../__generated__/GroupDetailsQuery.graphql' import { GroupDetailsQuery, useChatRoom } from '../../common' +import { LEFT_PANEL_CONTENT } from '../../common/context/useChatRoom/constants' import DefaultAllChatRoomsList from '../AllChatRoomsList' import ChatRoom from '../ChatRoom' import DefaultGroupChatCreate from '../GroupChatCreate' @@ -15,7 +16,6 @@ import DefaultGroupChatDetails from '../GroupChatDetails' import DefaultGroupChatEdit from '../GroupChatEdit' import DefaultProfileSummary from '../ProfileSummary' import DefaultSingleChatCreate from '../SingleChatCreate' -import { LEFT_PANEL_CONTENT } from './constants' import { ChatRoomContainer, ChatRoomsContainer, ChatRoomsListContainer } from './styled' import { ChatRoomsComponentProps } from './types' @@ -48,6 +48,13 @@ const ChatRoomsComponent: FC = ({ } } + const displayProfileSummary = () => { + if (selectedRoom) { + setLeftPanelContent(LEFT_PANEL_CONTENT.profileSummary) + loadGroupDetailsQuery({ roomId: selectedRoom }, { fetchPolicy: 'network-only' }) + } + } + const shouldRenderLeftPanel = isUpToMd || leftPanelContent !== LEFT_PANEL_CONTENT.chatRoomList || !selectedRoom const shouldRenderRightPanel = @@ -100,8 +107,10 @@ const ChatRoomsComponent: FC = ({ /> ) case LEFT_PANEL_CONTENT.profileSummary: + if (!groupDetailsQueryRef) return null return ( setLeftPanelContent(LEFT_PANEL_CONTENT.chatRoomList)} /> ) @@ -119,7 +128,13 @@ const ChatRoomsComponent: FC = ({ const renderRightPanelContent = () => { if (!selectedRoom) return
- return + return ( + + ) } return ( diff --git a/packages/components/modules/messages/web/ChatRoomsComponent/types.ts b/packages/components/modules/messages/web/ChatRoomsComponent/types.ts index 83dc378a..2a63bf31 100644 --- a/packages/components/modules/messages/web/ChatRoomsComponent/types.ts +++ b/packages/components/modules/messages/web/ChatRoomsComponent/types.ts @@ -6,13 +6,13 @@ import { ValueOf } from '@baseapp-frontend/utils' import { BoxProps } from '@mui/material' import { ChatRoomsQuery$data } from '../../../../__generated__/ChatRoomsQuery.graphql' +import { LEFT_PANEL_CONTENT } from '../../common/context/useChatRoom/constants' import { AllChatRoomsListProps } from '../AllChatRoomsList/types' import { GroupChatCreateProps } from '../GroupChatCreate/types' import { GroupChatDetailsProps } from '../GroupChatDetails/types' import { GroupChatEditProps } from '../GroupChatEdit/types' import { ProfileSummaryProps } from '../ProfileSummary/types' import { SingleChatCreateProps } from '../SingleChatCreate/types' -import { LEFT_PANEL_CONTENT } from './constants' export interface HidableContainerProps extends BoxProps { hide: boolean diff --git a/packages/components/modules/messages/web/MessagesList/__storybook__/stories.tsx b/packages/components/modules/messages/web/MessagesList/__storybook__/stories.tsx index 15ff668e..c12cab5b 100644 --- a/packages/components/modules/messages/web/MessagesList/__storybook__/stories.tsx +++ b/packages/components/modules/messages/web/MessagesList/__storybook__/stories.tsx @@ -11,7 +11,6 @@ const mockChatRoomStore = create((set) => ({ setChatRoom: (newState) => set(newState), resetChatRoom: () => set({ id: '' }), setLeftPanelContent: (_content) => {}, - setSingleChatProfileDetails: (_details) => {}, })) const meta: Meta = { diff --git a/packages/components/modules/messages/web/ProfileSummary/Body/index.tsx b/packages/components/modules/messages/web/ProfileSummary/Body/index.tsx index 816fbb1e..82e8e9bf 100644 --- a/packages/components/modules/messages/web/ProfileSummary/Body/index.tsx +++ b/packages/components/modules/messages/web/ProfileSummary/Body/index.tsx @@ -1,5 +1,6 @@ import { FC } from 'react' +import { useCurrentProfile } from '@baseapp-frontend/authentication' import { CircledAvatar } from '@baseapp-frontend/design-system/components/web/avatars' import { IconButton } from '@baseapp-frontend/design-system/components/web/buttons' import { @@ -9,7 +10,10 @@ import { import { TypographyWithEllipsis } from '@baseapp-frontend/design-system/components/web/typographies' import { Box, Divider, Typography } from '@mui/material' +import { useFragment } from 'react-relay' +import { ProfileSummaryFragment$key } from '../../../../../__generated__/ProfileSummaryFragment.graphql' +import { ProfileSummaryFragment } from '../../../common/graphql/fragments/ProfileSummary' import { ButtonContainer, HeaderContainer, @@ -19,9 +23,32 @@ import { } from './styled' import { BodyProps } from './types' -const Body: FC = ({ avatar, avatarSize = 144, biography, username, name, pk }) => { +const Body: FC = ({ avatarSize = 144, chatRoomRef }) => { + const { currentProfile } = useCurrentProfile() + const profileSummary = useFragment( + ProfileSummaryFragment, + chatRoomRef, + ) + const getSingleChatDetails = () => { + const details = profileSummary?.participants?.edges?.map((edge) => { + if (edge?.node?.profile?.id !== currentProfile?.id) { + return { + name: edge?.node?.profile?.name, + avatar: edge?.node?.profile?.image?.url, + username: edge?.node?.profile?.urlPath?.path, + biography: edge?.node?.profile?.biography, + pk: edge?.node?.profile?.pk, + } + } + return null + }) + return details?.find((detail) => detail !== null) + } + + const { name, avatar, username, biography, pk } = getSingleChatDetails() || {} const formattedUsername = username ? username.replace(/^\/+/, '') : '' - const profilePath = username ?? `/profile/${pk}` + const profilePath = username ?? (pk ? `/profile/${pk}` : undefined) + return ( @@ -30,9 +57,11 @@ const Body: FC = ({ avatar, avatarSize = 144, biography, username, na {name} - - {`@${formattedUsername}`} - + {formattedUsername && ( + + {`@${formattedUsername}`} + + )} diff --git a/packages/components/modules/messages/web/ProfileSummary/Body/types.ts b/packages/components/modules/messages/web/ProfileSummary/Body/types.ts index f008793e..881c24ed 100644 --- a/packages/components/modules/messages/web/ProfileSummary/Body/types.ts +++ b/packages/components/modules/messages/web/ProfileSummary/Body/types.ts @@ -1,10 +1,8 @@ import { PropsWithChildren } from 'react' +import { ProfileSummaryFragment$key } from '../../../../../__generated__/ProfileSummaryFragment.graphql' + export interface BodyProps extends PropsWithChildren { - avatar?: string avatarSize?: number - biography?: string | null - name?: string | null - username?: string | null - pk?: number | undefined + chatRoomRef: ProfileSummaryFragment$key } diff --git a/packages/components/modules/messages/web/ProfileSummary/index.tsx b/packages/components/modules/messages/web/ProfileSummary/index.tsx index 52027617..ce85e4d3 100644 --- a/packages/components/modules/messages/web/ProfileSummary/index.tsx +++ b/packages/components/modules/messages/web/ProfileSummary/index.tsx @@ -4,25 +4,23 @@ import { FC, Suspense } from 'react' import { LoadingState } from '@baseapp-frontend/design-system/components/web/displays' -import { useChatRoom } from '../../common' +import { usePreloadedQuery } from 'react-relay' + +import { GroupDetailsQuery } from '../../common' import Body from './Body' import Header from './Header' import { ProfileSummaryProps } from './types' -const ProfileSummary: FC = ({ onBackButtonClicked }) => { - const { singleChatProfileDetails } = useChatRoom() - const { imageUrl, name, username, biography, pk } = singleChatProfileDetails || {} +const ProfileSummary: FC = ({ onBackButtonClicked, queryRef }) => { + const data = usePreloadedQuery(GroupDetailsQuery, queryRef) + if (!data.chatRoom) { + return + } return ( <>
- + ) } diff --git a/packages/components/modules/messages/web/ProfileSummary/types.ts b/packages/components/modules/messages/web/ProfileSummary/types.ts index 8fce8c43..e97d206e 100644 --- a/packages/components/modules/messages/web/ProfileSummary/types.ts +++ b/packages/components/modules/messages/web/ProfileSummary/types.ts @@ -1,3 +1,8 @@ +import { PreloadedQuery } from 'react-relay' + +import { GroupDetailsQuery } from '../../../../__generated__/GroupDetailsQuery.graphql' + export type ProfileSummaryProps = { + queryRef: PreloadedQuery onBackButtonClicked: () => void } diff --git a/packages/design-system/components/web/icons/ProfileNoCircleIcon/index.tsx b/packages/design-system/components/web/icons/ProfileNoCircleIcon/index.tsx index eec717cf..c095b153 100644 --- a/packages/design-system/components/web/icons/ProfileNoCircleIcon/index.tsx +++ b/packages/design-system/components/web/icons/ProfileNoCircleIcon/index.tsx @@ -7,11 +7,11 @@ const ProfileNoCircleIcon: FC = ({ sx, ...props }) => ( From e72e448d82fd8ccb64806423fa327adf99312c7f Mon Sep 17 00:00:00 2001 From: Rodean Fraser Date: Tue, 25 Nov 2025 00:08:29 -0500 Subject: [PATCH 04/10] fix aria label --- .../modules/messages/web/ProfileSummary/Body/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/components/modules/messages/web/ProfileSummary/Body/index.tsx b/packages/components/modules/messages/web/ProfileSummary/Body/index.tsx index 82e8e9bf..57435563 100644 --- a/packages/components/modules/messages/web/ProfileSummary/Body/index.tsx +++ b/packages/components/modules/messages/web/ProfileSummary/Body/index.tsx @@ -80,7 +80,7 @@ const Body: FC = ({ avatarSize = 144, chatRoomRef }) => { From 56a6e1e3761e22c81d24017abc126b2344e3d86a Mon Sep 17 00:00:00 2001 From: Rodean Fraser Date: Tue, 25 Nov 2025 00:12:14 -0500 Subject: [PATCH 05/10] code rabbit update --- .../modules/messages/web/ProfileSummary/Body/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/components/modules/messages/web/ProfileSummary/Body/index.tsx b/packages/components/modules/messages/web/ProfileSummary/Body/index.tsx index 57435563..01308e72 100644 --- a/packages/components/modules/messages/web/ProfileSummary/Body/index.tsx +++ b/packages/components/modules/messages/web/ProfileSummary/Body/index.tsx @@ -70,7 +70,7 @@ const Body: FC = ({ avatarSize = 144, chatRoomRef }) => { size="small" aria-label="go to profile" onClick={() => window.open(profilePath, '_blank')} - sx={{ maxWidth: 'fit-content', gap: '8px' }} + disabled={!profilePath} > From 1bd4d8f426cbc6a1926f72c51cf78cf494b7c848 Mon Sep 17 00:00:00 2001 From: Rodean Fraser Date: Tue, 25 Nov 2025 09:12:58 -0500 Subject: [PATCH 06/10] fix image sizing --- .../modules/messages/common/graphql/fragments/RoomTitle.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/components/modules/messages/common/graphql/fragments/RoomTitle.ts b/packages/components/modules/messages/common/graphql/fragments/RoomTitle.ts index 8f1e09e1..3afb5001 100644 --- a/packages/components/modules/messages/common/graphql/fragments/RoomTitle.ts +++ b/packages/components/modules/messages/common/graphql/fragments/RoomTitle.ts @@ -10,7 +10,7 @@ export const RoomTitleFragment = graphql` profile { id name - image(width: 100, height: 128) { + image(width: 100, height: 100) { url } } From bc036def80d86a15f77bb32496d2853eafcaa842 Mon Sep 17 00:00:00 2001 From: Rodean Fraser Date: Wed, 26 Nov 2025 03:22:08 -0500 Subject: [PATCH 07/10] more review changes --- .../ChatRoom/ChatRoomHeader/ChatRoomOptions/index.tsx | 11 +++++------ .../messages/web/ProfileSummary/Body/index.tsx | 8 +++++--- .../messages/web/ProfileSummary/Body/styled.tsx | 1 + 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/packages/components/modules/messages/web/ChatRoom/ChatRoomHeader/ChatRoomOptions/index.tsx b/packages/components/modules/messages/web/ChatRoom/ChatRoomHeader/ChatRoomOptions/index.tsx index 5f212acf..6e7b34cf 100644 --- a/packages/components/modules/messages/web/ChatRoom/ChatRoomHeader/ChatRoomOptions/index.tsx +++ b/packages/components/modules/messages/web/ChatRoom/ChatRoomHeader/ChatRoomOptions/index.tsx @@ -17,11 +17,6 @@ const ChatRoomOptions: FC = ({ {isArchived ? 'Unarchive Chat' : 'Archive Chat'} - {!isGroup && ( - - Contact Details - - )} {isGroup ? ( <> @@ -33,7 +28,11 @@ const ChatRoomOptions: FC = ({ - ) : null} + ) : ( + + Contact Details + + )} ) diff --git a/packages/components/modules/messages/web/ProfileSummary/Body/index.tsx b/packages/components/modules/messages/web/ProfileSummary/Body/index.tsx index 01308e72..d567810b 100644 --- a/packages/components/modules/messages/web/ProfileSummary/Body/index.tsx +++ b/packages/components/modules/messages/web/ProfileSummary/Body/index.tsx @@ -31,6 +31,8 @@ const Body: FC = ({ avatarSize = 144, chatRoomRef }) => { ) const getSingleChatDetails = () => { const details = profileSummary?.participants?.edges?.map((edge) => { + const profileId = edge?.node?.profile?.id + if (!profileId) return null if (edge?.node?.profile?.id !== currentProfile?.id) { return { name: edge?.node?.profile?.name, @@ -97,10 +99,10 @@ const Body: FC = ({ avatarSize = 144, chatRoomRef }) => { - {biography?.split('\n').map((line, index) => ( - + {biography?.split('\n').map((line, index, lines) => ( + {line} - {index < biography.split('\n').length - 1 &&
} + {index < lines.length - 1 &&
}
))}
diff --git a/packages/components/modules/messages/web/ProfileSummary/Body/styled.tsx b/packages/components/modules/messages/web/ProfileSummary/Body/styled.tsx index b29556e0..afbca205 100644 --- a/packages/components/modules/messages/web/ProfileSummary/Body/styled.tsx +++ b/packages/components/modules/messages/web/ProfileSummary/Body/styled.tsx @@ -28,6 +28,7 @@ export const SubheaderContainer = styled(Box)(({ theme }) => ({ export const ButtonContainer = styled(Box)(({ theme }) => ({ display: 'flex', flexDirection: 'column', + alignItems: 'flex-start', gap: theme.spacing(1), padding: theme.spacing(2), })) From a325e7cb7a0889842db0727d0e42d6a8b7bddf99 Mon Sep 17 00:00:00 2001 From: Rodean Fraser Date: Wed, 26 Nov 2025 03:33:54 -0500 Subject: [PATCH 08/10] function name changes --- .../messages/common/context/ChatRoomProvider/index.tsx | 4 ++-- packages/components/modules/messages/common/utils.ts | 4 ++-- .../modules/messages/web/ChatRoom/ChatRoomHeader/index.tsx | 1 - .../modules/messages/web/ProfileSummary/Body/index.tsx | 4 ++-- 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/packages/components/modules/messages/common/context/ChatRoomProvider/index.tsx b/packages/components/modules/messages/common/context/ChatRoomProvider/index.tsx index d6b849b1..cc166e95 100644 --- a/packages/components/modules/messages/common/context/ChatRoomProvider/index.tsx +++ b/packages/components/modules/messages/common/context/ChatRoomProvider/index.tsx @@ -5,7 +5,7 @@ import { FC, PropsWithChildren, createContext, useRef } from 'react' import { StoreApi, create } from 'zustand' import { INITIAL_CHAT_ROOM_STATE } from './constants' -import { ChatRoomState, UseChatRoom } from './types' +import { ChatRoomState, LeftPanelContentValues, UseChatRoom } from './types' export const ChatRoomContext = createContext | null>(null) @@ -17,7 +17,7 @@ const ChatRoomProvider: FC = ({ children }) => { setChatRoom: (state: ChatRoomState) => set(state), resetChatRoom: () => set({ ...INITIAL_CHAT_ROOM_STATE }), - setLeftPanelContent: (content: number) => set({ leftPanelContent: content }), + setLeftPanelContent: (content: LeftPanelContentValues) => set({ leftPanelContent: content }), })) } return {children} diff --git a/packages/components/modules/messages/common/utils.ts b/packages/components/modules/messages/common/utils.ts index 566c00d0..39e31438 100644 --- a/packages/components/modules/messages/common/utils.ts +++ b/packages/components/modules/messages/common/utils.ts @@ -51,10 +51,10 @@ export const useRoomNameAndAvatar = (headerRef: RoomTitleFragment$key | null | u } export const useNameAndAvatar = (roomHeader: TitleFragment$data) => { - const singleChatDetails = useRoomNameAndAvatar(roomHeader) + const roomNameAndAvatar = useRoomNameAndAvatar(roomHeader) const groupNameAndAvatar = useGroupNameAndAvatar(roomHeader) if (roomHeader.isGroup) return groupNameAndAvatar - return singleChatDetails + return roomNameAndAvatar } export const getParticipantCountString = (participantCount: number | null | undefined) => { diff --git a/packages/components/modules/messages/web/ChatRoom/ChatRoomHeader/index.tsx b/packages/components/modules/messages/web/ChatRoom/ChatRoomHeader/index.tsx index 96d34d54..0fd36397 100644 --- a/packages/components/modules/messages/web/ChatRoom/ChatRoomHeader/index.tsx +++ b/packages/components/modules/messages/web/ChatRoom/ChatRoomHeader/index.tsx @@ -47,7 +47,6 @@ const ChatRoomHeader: FC = ({ const { isGroup } = roomHeader const { title, avatar } = useNameAndAvatar(roomHeader) - const { participants } = useFragment(RoomTitleFragment, roomHeader) const { isSoleAdmin } = useCheckIsAdmin(participants as MembersListFragment$data['participants']) const members = getParticipantCountString(participantsCount) diff --git a/packages/components/modules/messages/web/ProfileSummary/Body/index.tsx b/packages/components/modules/messages/web/ProfileSummary/Body/index.tsx index d567810b..9115b781 100644 --- a/packages/components/modules/messages/web/ProfileSummary/Body/index.tsx +++ b/packages/components/modules/messages/web/ProfileSummary/Body/index.tsx @@ -29,7 +29,7 @@ const Body: FC = ({ avatarSize = 144, chatRoomRef }) => { ProfileSummaryFragment, chatRoomRef, ) - const getSingleChatDetails = () => { + const getroomNameAndAvatar = () => { const details = profileSummary?.participants?.edges?.map((edge) => { const profileId = edge?.node?.profile?.id if (!profileId) return null @@ -47,7 +47,7 @@ const Body: FC = ({ avatarSize = 144, chatRoomRef }) => { return details?.find((detail) => detail !== null) } - const { name, avatar, username, biography, pk } = getSingleChatDetails() || {} + const { name, avatar, username, biography, pk } = getroomNameAndAvatar() || {} const formattedUsername = username ? username.replace(/^\/+/, '') : '' const profilePath = username ?? (pk ? `/profile/${pk}` : undefined) From 1744858e06f26ee2e66ff680eb7863a0a17284f7 Mon Sep 17 00:00:00 2001 From: Rodean Fraser Date: Wed, 26 Nov 2025 08:44:43 -0500 Subject: [PATCH 09/10] code rabbit fix --- .../modules/messages/web/ProfileSummary/Body/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/components/modules/messages/web/ProfileSummary/Body/index.tsx b/packages/components/modules/messages/web/ProfileSummary/Body/index.tsx index 9115b781..a9d5a5dc 100644 --- a/packages/components/modules/messages/web/ProfileSummary/Body/index.tsx +++ b/packages/components/modules/messages/web/ProfileSummary/Body/index.tsx @@ -71,7 +71,7 @@ const Body: FC = ({ avatarSize = 144, chatRoomRef }) => { window.open(profilePath, '_blank')} + onClick={() => window.open(profilePath, '_blank', 'noopener,noreferrer')} disabled={!profilePath} > From 1fc60693f4478d14e7eb9289719c26c9e2770810 Mon Sep 17 00:00:00 2001 From: Rodean Fraser Date: Wed, 26 Nov 2025 09:36:23 -0500 Subject: [PATCH 10/10] changelogs --- packages/components/CHANGELOG.md | 8 ++++++++ packages/components/package.json | 2 +- packages/design-system/CHANGELOG.md | 6 ++++++ packages/design-system/package.json | 2 +- packages/wagtail/CHANGELOG.md | 7 +++++++ packages/wagtail/package.json | 2 +- 6 files changed, 24 insertions(+), 3 deletions(-) diff --git a/packages/components/CHANGELOG.md b/packages/components/CHANGELOG.md index 19029a38..20f37778 100644 --- a/packages/components/CHANGELOG.md +++ b/packages/components/CHANGELOG.md @@ -1,5 +1,13 @@ # @baseapp-frontend/components +## 1.4.7 + +### Patch Changes + +- Updated messages to show additional detail regarding chat participant in non group chats +- Updated dependencies + - @baseapp-frontend/design-system@1.1.4 + ## 1.4.6 ### Patch Changes diff --git a/packages/components/package.json b/packages/components/package.json index 99d5cd10..a9fe80fc 100644 --- a/packages/components/package.json +++ b/packages/components/package.json @@ -1,7 +1,7 @@ { "name": "@baseapp-frontend/components", "description": "BaseApp components modules such as comments, notifications, messages, and more.", - "version": "1.4.6", + "version": "1.4.7", "sideEffects": false, "scripts": { "build": "rm -rf dist && pnpm relay && tsc --build tsconfig.build.json", diff --git a/packages/design-system/CHANGELOG.md b/packages/design-system/CHANGELOG.md index dab45c9a..4ae73bf8 100644 --- a/packages/design-system/CHANGELOG.md +++ b/packages/design-system/CHANGELOG.md @@ -1,5 +1,11 @@ # @baseapp-frontend/design-system +## 1.1.4 + +### Patch Changes + +- Added new icon ProfileNoCircleIcon + ## 1.1.3 ### Patch Changes diff --git a/packages/design-system/package.json b/packages/design-system/package.json index a02c7432..662aace6 100644 --- a/packages/design-system/package.json +++ b/packages/design-system/package.json @@ -1,7 +1,7 @@ { "name": "@baseapp-frontend/design-system", "description": "Design System components and configurations.", - "version": "1.1.3", + "version": "1.1.4", "sideEffects": false, "scripts": { "build": "rm -rf dist && tsc --build tsconfig.build.json", diff --git a/packages/wagtail/CHANGELOG.md b/packages/wagtail/CHANGELOG.md index 9903c1eb..f936c992 100644 --- a/packages/wagtail/CHANGELOG.md +++ b/packages/wagtail/CHANGELOG.md @@ -1,5 +1,12 @@ # @baseapp-frontend/wagtail +## 1.0.41 + +### Patch Changes + +- Updated dependencies + - @baseapp-frontend/design-system@1.1.4 + ## 1.0.40 ### Patch Changes diff --git a/packages/wagtail/package.json b/packages/wagtail/package.json index 4ad46d7c..253e9a2b 100644 --- a/packages/wagtail/package.json +++ b/packages/wagtail/package.json @@ -1,7 +1,7 @@ { "name": "@baseapp-frontend/wagtail", "description": "BaseApp Wagtail", - "version": "1.0.40", + "version": "1.0.41", "main": "./index.ts", "types": "dist/index.d.ts", "sideEffects": false,