diff --git a/__mocks__/db/progresses.ts b/__mocks__/db/progresses.ts index 121e06554..a07d330eb 100644 --- a/__mocks__/db/progresses.ts +++ b/__mocks__/db/progresses.ts @@ -10,7 +10,42 @@ export const mockGetTaskProgress = { completed: '1', planned: '1', type: 'task', - userId: 'K1X2iixQVx1lnE0WYCtH', + userData: { + id: 'XAF7rSUvk4p0d098qWYS', + profileURL: 'https://my.realdevsquad.com/identity', + discordJoinedAt: '2020-02-01T08:33:38.278000+00:00', + roles: { + archived: false, + in_discord: true, + member: true, + super_user: true, + admin: true, + }, + created_at: 1693166951852, + yoe: '8', + github_created_at: 1341655281000, + updated_at: 1693224375990, + company: 'Amazon', + twitter_id: 'ankushdharkar', + first_name: 'Ankush', + ' instagram_id': 'ankushdharkar', + website: 'NA', + incompleteUserDetails: false, + discordId: '154585730465660929', + linkedin_id: 'ankushdharkar', + last_name: 'Dharkar', + picture: { + publicId: + 'profile/XAF7rSUvk4p0d098qWYS/me40uk7taytbjaa67mhe', + url: 'https://res.cloudinary.com/realdevsquad/image/upload/v1692058952/profile/XAF7rSUvk4p0d098qWYS/me40uk7taytbjaa67mhe.jpg', + }, + github_display_name: 'Ankush Dharkar', + company_name: 'Amazon', + github_id: 'ankushdharkar', + designation: 'SDE', + status: 'idle', + username: 'ankush', + }, taskId: 'OxYqJgf6Tyl90uci1mzs', }, { @@ -21,7 +56,42 @@ export const mockGetTaskProgress = { completed: 'testig task progress', planned: 'plan to test', type: 'task', - userId: 'K1X2iixQVx1lnE0WYCtH', + userData: { + id: 'XAF7rSUvk4p0d098qWYS', + profileURL: 'https://my.realdevsquad.com/identity', + discordJoinedAt: '2020-02-01T08:33:38.278000+00:00', + roles: { + archived: false, + in_discord: true, + member: true, + super_user: true, + admin: true, + }, + created_at: 1693166951852, + yoe: '8', + github_created_at: 1341655281000, + updated_at: 1693224375990, + company: 'Amazon', + twitter_id: 'ankushdharkar', + first_name: 'Ankush', + ' instagram_id': 'ankushdharkar', + website: 'NA', + incompleteUserDetails: false, + discordId: '154585730465660929', + linkedin_id: 'ankushdharkar', + last_name: 'Dharkar', + picture: { + publicId: + 'profile/XAF7rSUvk4p0d098qWYS/me40uk7taytbjaa67mhe', + url: 'https://res.cloudinary.com/realdevsquad/image/upload/v1692058952/profile/XAF7rSUvk4p0d098qWYS/me40uk7taytbjaa67mhe.jpg', + }, + github_display_name: 'Ankush Dharkar', + company_name: 'Amazon', + github_id: 'ankushdharkar', + designation: 'SDE', + status: 'idle', + username: 'ankush', + }, taskId: 'OxYqJgf6Tyl90uci1mzs', }, { @@ -32,10 +102,44 @@ export const mockGetTaskProgress = { completed: 'progress 2', planned: 'something planned', type: 'task', - userId: 'K1X2iixQVx1lnE0WYCtH', + userData: { + id: 'XAF7rSUvk4p0d098qWYS', + profileURL: 'https://my.realdevsquad.com/identity', + discordJoinedAt: '2020-02-01T08:33:38.278000+00:00', + roles: { + archived: false, + in_discord: true, + member: true, + super_user: true, + admin: true, + }, + created_at: 1693166951852, + yoe: '8', + github_created_at: 1341655281000, + updated_at: 1693224375990, + company: 'Amazon', + twitter_id: 'ankushdharkar', + first_name: 'Ankush', + ' instagram_id': 'ankushdharkar', + website: 'NA', + incompleteUserDetails: false, + discordId: '154585730465660929', + linkedin_id: 'ankushdharkar', + last_name: 'Dharkar', + picture: { + publicId: + 'profile/XAF7rSUvk4p0d098qWYS/me40uk7taytbjaa67mhe', + url: 'https://res.cloudinary.com/realdevsquad/image/upload/v1692058952/profile/XAF7rSUvk4p0d098qWYS/me40uk7taytbjaa67mhe.jpg', + }, + github_display_name: 'Ankush Dharkar', + company_name: 'Amazon', + github_id: 'ankushdharkar', + designation: 'SDE', + status: 'idle', + username: 'ankush', + }, taskId: 'OxYqJgf6Tyl90uci1mzs', }, - { id: 'zJHdjzAsvH8K6wg7de07', date: 1685491203632, @@ -47,7 +151,42 @@ export const mockGetTaskProgress = { planned: 'Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industrys standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.', type: 'task', - userId: 'demo-user-id-0', + userData: { + id: 'XAF7rSUvk4p0d098qWYS', + profileURL: 'https://my.realdevsquad.com/identity', + discordJoinedAt: '2020-02-01T08:33:38.278000+00:00', + roles: { + archived: false, + in_discord: true, + member: true, + super_user: true, + admin: true, + }, + created_at: 1693166951852, + yoe: '8', + github_created_at: 1341655281000, + updated_at: 1693224375990, + company: 'Amazon', + twitter_id: 'ankushdharkar', + first_name: 'Ankush', + ' instagram_id': 'ankushdharkar', + website: 'NA', + incompleteUserDetails: false, + discordId: '154585730465660929', + linkedin_id: 'ankushdharkar', + last_name: 'Dharkar', + picture: { + publicId: + 'profile/XAF7rSUvk4p0d098qWYS/me40uk7taytbjaa67mhe', + url: 'https://res.cloudinary.com/realdevsquad/image/upload/v1692058952/profile/XAF7rSUvk4p0d098qWYS/me40uk7taytbjaa67mhe.jpg', + }, + github_display_name: 'Ankush Dharkar', + company_name: 'Amazon', + github_id: 'ankushdharkar', + designation: 'SDE', + status: 'idle', + username: 'ankush', + }, taskId: 'demo-task-id-0', }, ], diff --git a/__tests__/Unit/Components/Calendar/UserSearchField.test.tsx b/__tests__/Unit/Components/Calendar/UserSearchField.test.tsx index 5fa0067ec..2f90e26f7 100644 --- a/__tests__/Unit/Components/Calendar/UserSearchField.test.tsx +++ b/__tests__/Unit/Components/Calendar/UserSearchField.test.tsx @@ -46,9 +46,10 @@ describe('SearchField component', () => { const input = screen.getByPlaceholderText('Enter username'); userEvent.type(input, 'muhammadmusab'); + await waitFor(() => expect(input).toHaveValue('muhammadmusab')); - const listItems = screen.getAllByRole('listitem'); + const listItems = await screen.findAllByRole('listitem'); expect(listItems[0].innerHTML).toEqual('muhammadmusab'); const button = screen.getByRole('button', { name: 'Submit' }); @@ -177,16 +178,16 @@ describe('SearchField component', () => { userEvent.type(input, 'mu'); await waitFor(() => expect(input).toHaveValue('mu')); - const suggestionsAfterFirstTyping = await waitFor(() => - screen.queryAllByRole('listitem') + const suggestionsAfterFirstTyping = await screen.findAllByRole( + 'listitem' ); expect(suggestionsAfterFirstTyping.length).toBeGreaterThan(0); userEvent.type(input, 'hammad'); await waitFor(() => expect(input).toHaveValue('muhammad')); - const suggestionsAfterSecondTyping = await waitFor(() => - screen.queryAllByRole('listitem') + const suggestionsAfterSecondTyping = await screen.findAllByRole( + 'listitem' ); expect(suggestionsAfterSecondTyping.length).toBeGreaterThan(0); expect(suggestionsAfterSecondTyping.length).toBeLessThan( @@ -197,6 +198,6 @@ describe('SearchField component', () => { await waitFor(() => expect(input).toHaveValue('')); const noSuggestions = screen.queryAllByRole('listitem'); - expect(noSuggestions).toEqual([]); + expect(noSuggestions).toHaveLength(0); }); }); diff --git a/__tests__/Unit/Components/Tasks/ProgressUpdateCard/LatestProgressUpdateCard.test.tsx b/__tests__/Unit/Components/Tasks/ProgressUpdateCard/LatestProgressUpdateCard.test.tsx index 9763bdaaa..e3fc0cc8c 100644 --- a/__tests__/Unit/Components/Tasks/ProgressUpdateCard/LatestProgressUpdateCard.test.tsx +++ b/__tests__/Unit/Components/Tasks/ProgressUpdateCard/LatestProgressUpdateCard.test.tsx @@ -1,13 +1,40 @@ import moment from 'moment'; -import { fireEvent, getAllByTestId, screen } from '@testing-library/react'; +import { fireEvent, screen } from '@testing-library/react'; import { Provider } from 'react-redux'; import { store } from '@/app/store'; import { renderWithRouter } from '@/test_utils/createMockRouter'; import { mockGetTaskProgress } from '../../../../../__mocks__/db/progresses'; import LatestProgressUpdateCard from '@/components/taskDetails/ProgressUpdateCard/LatestProgressUpdateCard'; import { readMoreFormatter } from '@/utils/common'; +import { DEFAULT_AVATAR } from '@/constants/url'; +import { useRouter } from 'next/router'; +jest.mock('next/router', () => ({ + useRouter: jest.fn(), +})); describe('LatestProgressUpdateCard Component', () => { + it('should render the default avatar when userProfileImage is undefined', () => { + const mockRouter = { + query: { dev: 'true' }, + }; + (useRouter as jest.Mock).mockReturnValue(mockRouter); + + const mockDataWithNoUserData = { + ...mockGetTaskProgress.data[2], + userData: undefined, + }; + + renderWithRouter( + + + + ); + const userAvatarImage = screen.getByAltText('Avatar'); + expect(userAvatarImage).toBeInTheDocument(); + const imageSrc = userAvatarImage.getAttribute('src'); + expect(imageSrc).toContain(DEFAULT_AVATAR); + }); + it('should render the component with the passed data', () => { renderWithRouter( @@ -46,30 +73,28 @@ describe('LatestProgressUpdateCard Component', () => { expect(date).toHaveTextContent(dateInAgoFormat); }); - - it('should render the tooltip on hover on the date and should not render on mouse out off date', () => { + it('should render the tooltip on hover on the date and should not render on mouse out of date', () => { renderWithRouter( ); - const momentDate = moment(mockGetTaskProgress.data[2].createdAt); - const fullDate = momentDate.format( - 'dddd, MMMM DD, YYYY, hh:mm A [GMT] Z' - ); - const tooltipString = `Updated at ${fullDate}`; - const dateElement = screen.getByTestId( 'latest-progress-update-card-date' ); fireEvent.mouseOver(dateElement); - const tooltip = screen.getByTestId('tooltip'); + const momentDate = moment(mockGetTaskProgress.data[2].createdAt); + const fullDate = momentDate.format( + 'dddd, MMMM DD, YYYY, hh:mm A [GMT] Z' + ); + const tooltipString = `Updated at ${fullDate}`; + const tooltip = screen.getByText(tooltipString); + expect(tooltip).toBeInTheDocument(); expect(tooltip).toHaveClass('fade-in'); - expect(tooltip).toHaveTextContent(tooltipString); fireEvent.mouseOut(dateElement); diff --git a/__tests__/Unit/Components/Tasks/ProgressUpdateCard/ProgressUpdateCard.test.tsx b/__tests__/Unit/Components/Tasks/ProgressUpdateCard/ProgressUpdateCard.test.tsx index d006fc9ea..5caad7ad8 100644 --- a/__tests__/Unit/Components/Tasks/ProgressUpdateCard/ProgressUpdateCard.test.tsx +++ b/__tests__/Unit/Components/Tasks/ProgressUpdateCard/ProgressUpdateCard.test.tsx @@ -5,6 +5,12 @@ import { store } from '@/app/store'; import { renderWithRouter } from '@/test_utils/createMockRouter'; import { mockGetTaskProgress } from '../../../../../__mocks__/db/progresses'; import ProgressUpdateCard from '@/components/taskDetails/ProgressUpdateCard/ProgressUpdateCard'; +import { DEFAULT_AVATAR } from '@/constants/url'; +import { useRouter } from 'next/router'; + +jest.mock('next/router', () => ({ + useRouter: jest.fn(), +})); let mockedOpenDetailsFunction: jest.Mock]>; @@ -14,6 +20,87 @@ beforeEach(() => { }); describe('ProgressUpdateCard Component', () => { + it('should render the default avatar when userData is undefined', () => { + const mockRouter = { + query: { dev: 'true' }, + }; + (useRouter as jest.Mock).mockReturnValue(mockRouter); + + const mockDataWithNoUserData = { + ...mockGetTaskProgress.data[2], + userData: undefined, + }; + + renderWithRouter( + + + + ); + const userAvatarImage = screen.getByAltText('Avatar'); + expect(userAvatarImage).toBeInTheDocument(); + const imageSrc = userAvatarImage.getAttribute('src'); + expect(imageSrc).toContain(DEFAULT_AVATAR); + }); + + it('should toggle the expanded state when the card is clicked', () => { + renderWithRouter( + + + + ); + + const progressUpdateCardContainer = screen.getByTestId( + 'progress-update-card-container' + ); + + expect(progressUpdateCardContainer).not.toHaveClass('expand'); + fireEvent.click(progressUpdateCardContainer); + expect(progressUpdateCardContainer).toHaveClass('expand'); + fireEvent.click(progressUpdateCardContainer); + expect(progressUpdateCardContainer).not.toHaveClass('expand'); + }); + + it('should check if the onCardClick function is called when user click on card', () => { + renderWithRouter( + + + + ); + const progressUpdateCardContainer = screen.getByTestId( + 'progress-update-card-container' + ); + fireEvent.click(progressUpdateCardContainer); + expect(progressUpdateCardContainer).toHaveClass( + 'progress-update-card__container expand' + ); + }); + + it('should toggle "Read More" state when the button is clicked', () => { + const mockLongCompletedData = { + ...mockGetTaskProgress.data[2], + completed: + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin lacinia bibendum nisi at feugiat.', + }; + + renderWithRouter( + + + + ); + + const readMoreButton = screen.getByTestId( + 'progress-update-read-more-toggle-button' + ); + expect(readMoreButton).toBeInTheDocument(); + expect(readMoreButton).toHaveTextContent('More'); + fireEvent.click(readMoreButton); + expect(readMoreButton).toHaveTextContent('Less'); + + fireEvent.click(readMoreButton); + + expect(readMoreButton).toHaveTextContent('More'); + }); + it('should render completed section string as title in card', () => { renderWithRouter( @@ -66,7 +153,7 @@ describe('ProgressUpdateCard Component', () => { fireEvent.mouseOver(dateElement); - const tooltip = screen.getByTestId('tooltip'); + const tooltip = screen.getByText(tooltipString); expect(tooltip).toHaveClass('fade-in'); expect(tooltip).toHaveTextContent(tooltipString); diff --git a/__tests__/Unit/Components/Tasks/ProgressUpdateCard/ProgressUpdateCardPresentation.test.tsx b/__tests__/Unit/Components/Tasks/ProgressUpdateCard/ProgressUpdateCardPresentation.test.tsx index 3660fc1ae..5d3ac6dbf 100644 --- a/__tests__/Unit/Components/Tasks/ProgressUpdateCard/ProgressUpdateCardPresentation.test.tsx +++ b/__tests__/Unit/Components/Tasks/ProgressUpdateCard/ProgressUpdateCardPresentation.test.tsx @@ -2,7 +2,7 @@ import moment from 'moment'; import { MouseEvent } from 'react'; import { Provider } from 'react-redux'; import { fireEvent, screen } from '@testing-library/react'; - +import { useRouter } from 'next/router'; import { mockGetTaskProgress } from '../../../../../__mocks__/db/progresses'; import { renderWithRouter } from '@/test_utils/createMockRouter'; import { readMoreFormatter } from '@/utils/common'; @@ -18,6 +18,9 @@ import ProgressUpdateCardPresentation from '@/components/taskDetails/ProgressUpd let initialProps: ProgressUpdateCardPresentationProps; const titleToShow = mockGetTaskProgress.data[1].completed; const momentDate = moment(mockGetTaskProgress.data[2].createdAt); +const username = 'mock-user-name'; +const userProfileImageUrl = + 'https://res.cloudinary.com/realdevsquad/image/upload/v1661061375/profile/xpHe38L/ogirm51v.jpg'; const fullDate = momentDate.format('DD-MM-YY'); const time = momentDate.format('hh:mmA'); const tooltipString = `Updated at ${fullDate}, ${time}`; @@ -29,6 +32,9 @@ let mockedOnMoreOrLessButtonClick: jest.Mock< [React.MouseEvent] >; let mockedOnCardClick: jest.Mock]>; +jest.mock('next/router', () => ({ + useRouter: jest.fn(), +})); const charactersToShow = 70; const dataToShowState = [ { @@ -114,6 +120,8 @@ describe('ProgressUpdateCardPresentation Component', () => { jest.fn]>(); mockedOnCardClick = jest.fn]>(); initialProps = { + username: username, + userProfileImageUrl: userProfileImageUrl, titleToShow: titleToShow, isExpanded: false, dateInAgoFormat: dateInAgoFormat, @@ -123,7 +131,102 @@ describe('ProgressUpdateCardPresentation Component', () => { onCardClick: mockedOnCardClick, }; }); + + it('should rotate the angle icon when expanded', () => { + (useRouter as jest.Mock).mockReturnValue({ + query: { dev: 'false' }, + }); + const props = { ...initialProps, isExpanded: true }; + renderWithRouter( + + + + ); + const angleIcon = screen.getByTestId('progress-update-card-angle-icon'); + expect(angleIcon).toHaveClass( + 'progress-update-card__angle-icon--expanded' + ); + }); + it('should have respective classes on date container and date text', () => { + (useRouter as jest.Mock).mockReturnValue({ + query: { dev: 'false' }, + }); + renderWithRouter( + + + + ); + const dateContainer = screen.getByTestId('progress-update-card-date'); + const dateText = screen.getByText(dateInAgoFormat); + + expect(dateContainer).toHaveClass( + 'progress-update-card__date-container' + ); + expect(dateText).toHaveClass('progress-update-card__date-text'); + }); + + it('should not rotate the angle icon when not expanded', () => { + (useRouter as jest.Mock).mockReturnValue({ + query: { dev: 'false' }, + }); + const props = { ...initialProps, isExpanded: false }; + renderWithRouter( + + + + ); + const angleIcon = screen.getByTestId('progress-update-card-angle-icon'); + expect(angleIcon).not.toHaveClass( + 'progress-update-card__angle-icon--expanded' + ); + }); + + it('should prevent event propagation when clicking on the date container', () => { + (useRouter as jest.Mock).mockReturnValue({ + query: { dev: 'false' }, + }); + renderWithRouter( + + + + ); + + const dateContainer = screen.getByTestId('progress-update-card-date'); + const stopPropagationMock = jest.fn(); + dateContainer.addEventListener( + 'click', + (event) => (event.stopPropagation = stopPropagationMock) + ); + fireEvent.click(dateContainer); + expect(stopPropagationMock).toHaveBeenCalled(); + }); + + it('should prevent event propagation when clicking on user avatar', () => { + (useRouter as jest.Mock).mockReturnValue({ + query: { dev: 'true' }, + }); + renderWithRouter( + + + + ); + + const userInfoLink = screen.getByTestId( + 'progress-update-card-user-info-link' + ); + const stopPropagationMock = jest.fn(); + userInfoLink.addEventListener( + 'click', + (event) => (event.stopPropagation = stopPropagationMock) + ); + fireEvent.click(userInfoLink); + expect(stopPropagationMock).toHaveBeenCalled(); + }); + it('should render completed section string as title in card', () => { + (useRouter as jest.Mock).mockReturnValue({ + query: { dev: 'false' }, + }); renderWithRouter( @@ -135,6 +238,9 @@ describe('ProgressUpdateCardPresentation Component', () => { ); }); it('should render date with ago format', () => { + (useRouter as jest.Mock).mockReturnValue({ + query: { dev: 'false' }, + }); renderWithRouter( @@ -143,8 +249,10 @@ describe('ProgressUpdateCardPresentation Component', () => { const date = screen.getByTestId('progress-update-card-date'); expect(date).toHaveTextContent(dateInAgoFormat); }); - - it('should not render the tooltip when isToolisTooltipVisible is false', () => { + it('should render user Image', () => { + (useRouter as jest.Mock).mockReturnValue({ + query: { dev: 'true' }, + }); const props: ProgressUpdateCardPresentationProps = { ...initialProps, }; @@ -153,10 +261,10 @@ describe('ProgressUpdateCardPresentation Component', () => { ); - - const tooltip = screen.getByTestId('tooltip'); - expect(tooltip).toHaveTextContent(tooltipString); - expect(tooltip).toHaveClass('tooltip fade-out'); + const userAvatarImage = screen.getByAltText('Avatar'); + expect(userAvatarImage).toBeInTheDocument(); + const imageSrc = userAvatarImage.getAttribute('src'); + expect(imageSrc).toContain(userProfileImageUrl); }); it('should have respective classes when element is expanded', () => { diff --git a/src/components/common/Tooltip/tooltip.module.scss b/src/components/common/Tooltip/tooltip.module.scss index ec48ad4ef..df6820fc1 100644 --- a/src/components/common/Tooltip/tooltip.module.scss +++ b/src/components/common/Tooltip/tooltip.module.scss @@ -2,7 +2,7 @@ .tooltip { position: absolute; - width: 17rem; + width: 18rem; // position - top, bottom, right, left will come from props for reusability background-color: $theme-primary; border: 1px solid $theme-primary; @@ -18,14 +18,13 @@ &::before { content: ''; position: absolute; - transform: rotate(45deg); - height: 12px; - bottom: -5px; - z-index: -1; - left: 8rem; - right: 8rem; - width: 13px; + height: 0.75rem; + width: 0.75rem; + bottom: 0; background: $theme-primary; + left: 50%; + transform: translateX(-50%) translateY(6px) rotate(45deg); + z-index: -1; } } diff --git a/src/components/common/UserAvatar/UserAvatar.tsx b/src/components/common/UserAvatar/UserAvatar.tsx new file mode 100644 index 000000000..7f67f32e8 --- /dev/null +++ b/src/components/common/UserAvatar/UserAvatar.tsx @@ -0,0 +1,15 @@ +import styles from './userAvatar.module.scss'; + +type UserAvatarProps = { + userProfileImageUrl: string; +}; + +export const UserAvatar = ({ userProfileImageUrl }: UserAvatarProps) => { + return ( + Avatar + ); +}; diff --git a/src/components/common/UserAvatar/userAvatar.module.scss b/src/components/common/UserAvatar/userAvatar.module.scss new file mode 100644 index 000000000..6a139edde --- /dev/null +++ b/src/components/common/UserAvatar/userAvatar.module.scss @@ -0,0 +1,11 @@ +@import '../../../styles/variables'; +.user-avatar { + width: 2rem; + height: 2rem; + border-radius: 50%; + object-fit: cover; + @media (width<=425px) { + width: 1.8rem; + height: 1.8rem; + } +} diff --git a/src/components/taskDetails/ProgressUpdateCard/LatestProgressUpdateCard.tsx b/src/components/taskDetails/ProgressUpdateCard/LatestProgressUpdateCard.tsx index 564b5bd61..44d3471e8 100644 --- a/src/components/taskDetails/ProgressUpdateCard/LatestProgressUpdateCard.tsx +++ b/src/components/taskDetails/ProgressUpdateCard/LatestProgressUpdateCard.tsx @@ -3,7 +3,7 @@ import React, { MouseEvent, useState } from 'react'; import { readMoreFormatter } from '@/utils/common'; import { ProgressDetailsData } from '@/types/standup.type'; import LatestProgressUpdateCardPresentation from './LatestProgressUpdateCardPresentation'; - +import { DEFAULT_AVATAR } from '@/constants/url'; type LatestProgressUpdateCardProps = { data: ProgressDetailsData; }; @@ -25,6 +25,15 @@ export default function LatestProgressUpdateCard({ const fullDate = momentDate.format('dddd, MMMM DD, YYYY, hh:mm A [GMT] Z'); const tooltipText = `Updated at ${fullDate}`; const charactersToShow = 70; + let username = ''; + let userProfileImageUrl = DEFAULT_AVATAR; + + if (data.userData) { + username = data.userData.username ?? ''; + if (data.userData.picture) { + userProfileImageUrl = data.userData.picture.url ?? DEFAULT_AVATAR; + } + } const dataToShow = [ { @@ -75,6 +84,8 @@ export default function LatestProgressUpdateCard({ return ( (
@@ -79,6 +92,36 @@ export default function LatestProgressUpdateCardPresentation({ + {isDevMode && + (username === '' ? ( + + ) : ( + + + + + + ))}
diff --git a/src/components/taskDetails/ProgressUpdateCard/ProgressUpdateCard.tsx b/src/components/taskDetails/ProgressUpdateCard/ProgressUpdateCard.tsx index 707938bb7..ad09a78dc 100644 --- a/src/components/taskDetails/ProgressUpdateCard/ProgressUpdateCard.tsx +++ b/src/components/taskDetails/ProgressUpdateCard/ProgressUpdateCard.tsx @@ -6,12 +6,14 @@ import { ProgressUpdateCardProps, ProgressUpdateDataToShow, } from './progressUpdateCard.types'; - +import { DEFAULT_AVATAR } from '@/constants/url'; export default memo(function ProgressUpdateCard({ data, }: ProgressUpdateCardProps) { const momentDate = moment(data?.createdAt); const dateInAgoFormat = momentDate.fromNow(); + const username = data.userData?.username ?? ''; + const userProfileImageUrl = data.userData?.picture?.url ?? DEFAULT_AVATAR; const charactersToShow = 70; const readMoreTitle = readMoreFormatter(data?.completed, charactersToShow); const titleToShow = readMoreTitle; @@ -74,6 +76,8 @@ export default memo(function ProgressUpdateCard({ +

+ {titleToShow} +

+
+ + event.stopPropagation()} + data-testid="progress-update-card-date" + > + + + {dateInAgoFormat} + + + + + {isDevMode && + (username === '' ? ( + + ) : ( + + event.stopPropagation()} + > + + + + ))} + + +
+ + ); +} diff --git a/src/components/taskDetails/ProgressUpdateCard/ProgressUpdateCardPresentation.tsx b/src/components/taskDetails/ProgressUpdateCard/ProgressUpdateCardPresentation.tsx index afe04ba1c..dcc468dfe 100644 --- a/src/components/taskDetails/ProgressUpdateCard/ProgressUpdateCardPresentation.tsx +++ b/src/components/taskDetails/ProgressUpdateCard/ProgressUpdateCardPresentation.tsx @@ -1,21 +1,25 @@ import React from 'react'; -import { FaAngleRight, FaRegClock } from 'react-icons/fa6'; -import Tooltip from '@/components/common/Tooltip/Tooltip'; +import { useRouter } from 'next/router'; import styles from './progress-update-card.module.scss'; import { ProgressUpdateCardPresentationProps, ProgressUpdateDataToShow, } from './progressUpdateCard.types'; +import ProgressUpdateCardOverview from './ProgressUpdateCardOverview'; export default function ProgressUpdateCardPresentation({ titleToShow, dateInAgoFormat, + username, + userProfileImageUrl, tooltipString, dataToShowState, onMoreOrLessButtonClick, onCardClick, isExpanded, }: ProgressUpdateCardPresentationProps) { + const router = useRouter(); + const isDevMode = router.query.dev === 'true'; const progressInfoMapping = dataToShowState.map( (datum: ProgressUpdateDataToShow) => (
{datum.isReadMoreEnabled ? 'Less' : 'More'} @@ -55,38 +60,15 @@ export default function ProgressUpdateCardPresentation({ data-testid="progress-update-card-container" onClick={onCardClick} > -
-

- {titleToShow} -

- - event.stopPropagation()} - data-testid="progress-update-card-date" - > - - - {dateInAgoFormat} - - - - -
+
) => void; export type ProgressUpdateCardPresentationProps = { titleToShow: string; dateInAgoFormat: string; + username: string; + userProfileImageUrl: string; tooltipString: string; dataToShowState: ProgressUpdateDataToShow[]; onMoreOrLessButtonClick: ( @@ -22,6 +24,8 @@ export type ProgressUpdateCardPresentationProps = { export type LatestProgressUpdateCardPresentationProps = { dataToShowState: ProgressUpdateDataToShow[]; + username: string; + userProfileImageUrl: string; tooltipText: string; onMoreOrLessButtonClick: ( e: MouseEvent, @@ -38,3 +42,13 @@ export type ProgressUpdateDataToShow = { shouldReadMoreButtonShow: boolean; isReadMoreEnabled: boolean; }; + +export type ProgressUpdateCardOverviewProps = { + titleToShow: string; + dateInAgoFormat: string; + username: string; + userProfileImageUrl: string; + tooltipString: string; + isDevMode: boolean; + isExpanded: boolean; +}; diff --git a/src/interfaces/user.type.ts b/src/interfaces/user.type.ts index 3539164b1..c56229fec 100644 --- a/src/interfaces/user.type.ts +++ b/src/interfaces/user.type.ts @@ -16,7 +16,7 @@ export type userDataType = { archived: boolean; admin: boolean; super_user: boolean; - memeber: boolean; + member: boolean; }; designation?: string; profileURL?: string; diff --git a/src/types/standup.type.ts b/src/types/standup.type.ts index 81811bb81..2be6ea425 100644 --- a/src/types/standup.type.ts +++ b/src/types/standup.type.ts @@ -1,3 +1,5 @@ +import { userDataType } from '@/interfaces/user.type'; + export type standupUpdateType = { type: string; completed: string; @@ -23,7 +25,7 @@ export type ProgressDetailsData = { id: string; planned: string; type: string; - userId: string; + userData?: userDataType; taskId?: string; };