Skip to content
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,31 +4,31 @@

# Interface: InterfaceGroupModal

Defined in: [src/screens/UserPortal/Volunteer/Groups/GroupModal.tsx:62](https://github.com/PalisadoesFoundation/talawa-admin/blob/main/src/screens/UserPortal/Volunteer/Groups/GroupModal.tsx#L62)
Defined in: [src/screens/UserPortal/Volunteer/Groups/GroupModal.tsx:63](https://github.com/PalisadoesFoundation/talawa-admin/blob/main/src/screens/UserPortal/Volunteer/Groups/GroupModal.tsx#L63)

## Properties

### eventId

> **eventId**: `string`

Defined in: [src/screens/UserPortal/Volunteer/Groups/GroupModal.tsx:65](https://github.com/PalisadoesFoundation/talawa-admin/blob/main/src/screens/UserPortal/Volunteer/Groups/GroupModal.tsx#L65)
Defined in: [src/screens/UserPortal/Volunteer/Groups/GroupModal.tsx:66](https://github.com/PalisadoesFoundation/talawa-admin/blob/main/src/screens/UserPortal/Volunteer/Groups/GroupModal.tsx#L66)

***

### group

> **group**: [`InterfaceVolunteerGroupInfo`](../../../../../../utils/interfaces/interfaces/InterfaceVolunteerGroupInfo.md)

Defined in: [src/screens/UserPortal/Volunteer/Groups/GroupModal.tsx:66](https://github.com/PalisadoesFoundation/talawa-admin/blob/main/src/screens/UserPortal/Volunteer/Groups/GroupModal.tsx#L66)
Defined in: [src/screens/UserPortal/Volunteer/Groups/GroupModal.tsx:67](https://github.com/PalisadoesFoundation/talawa-admin/blob/main/src/screens/UserPortal/Volunteer/Groups/GroupModal.tsx#L67)

***

### hide()

> **hide**: () => `void`

Defined in: [src/screens/UserPortal/Volunteer/Groups/GroupModal.tsx:64](https://github.com/PalisadoesFoundation/talawa-admin/blob/main/src/screens/UserPortal/Volunteer/Groups/GroupModal.tsx#L64)
Defined in: [src/screens/UserPortal/Volunteer/Groups/GroupModal.tsx:65](https://github.com/PalisadoesFoundation/talawa-admin/blob/main/src/screens/UserPortal/Volunteer/Groups/GroupModal.tsx#L65)

#### Returns

Expand All @@ -40,15 +40,15 @@ Defined in: [src/screens/UserPortal/Volunteer/Groups/GroupModal.tsx:64](https://

> **isOpen**: `boolean`

Defined in: [src/screens/UserPortal/Volunteer/Groups/GroupModal.tsx:63](https://github.com/PalisadoesFoundation/talawa-admin/blob/main/src/screens/UserPortal/Volunteer/Groups/GroupModal.tsx#L63)
Defined in: [src/screens/UserPortal/Volunteer/Groups/GroupModal.tsx:64](https://github.com/PalisadoesFoundation/talawa-admin/blob/main/src/screens/UserPortal/Volunteer/Groups/GroupModal.tsx#L64)

***

### refetchGroups()

> **refetchGroups**: () => `void`

Defined in: [src/screens/UserPortal/Volunteer/Groups/GroupModal.tsx:67](https://github.com/PalisadoesFoundation/talawa-admin/blob/main/src/screens/UserPortal/Volunteer/Groups/GroupModal.tsx#L67)
Defined in: [src/screens/UserPortal/Volunteer/Groups/GroupModal.tsx:68](https://github.com/PalisadoesFoundation/talawa-admin/blob/main/src/screens/UserPortal/Volunteer/Groups/GroupModal.tsx#L68)

#### Returns

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@

> `const` **default**: `React.FC`\<[`InterfaceGroupModal`](../interfaces/InterfaceGroupModal.md)\>

Defined in: [src/screens/UserPortal/Volunteer/Groups/GroupModal.tsx:70](https://github.com/PalisadoesFoundation/talawa-admin/blob/main/src/screens/UserPortal/Volunteer/Groups/GroupModal.tsx#L70)
Defined in: [src/screens/UserPortal/Volunteer/Groups/GroupModal.tsx:71](https://github.com/PalisadoesFoundation/talawa-admin/blob/main/src/screens/UserPortal/Volunteer/Groups/GroupModal.tsx#L71)
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

> **default**(`__namedParameters`): `ReactElement`\<`unknown`, `string` \| `JSXElementConstructor`\<`any`\>\>

Defined in: [src/shared-components/SidebarOrgSection/SidebarOrgSection.tsx:60](https://github.com/PalisadoesFoundation/talawa-admin/blob/main/src/shared-components/SidebarOrgSection/SidebarOrgSection.tsx#L60)
Defined in: [src/shared-components/SidebarOrgSection/SidebarOrgSection.tsx:56](https://github.com/PalisadoesFoundation/talawa-admin/blob/main/src/shared-components/SidebarOrgSection/SidebarOrgSection.tsx#L56)

## Parameters

Expand Down
16 changes: 8 additions & 8 deletions src/components/LeftDrawerOrg/LeftDrawerOrg.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ const successMocks: IMockedResponse[] = [
{
request: {
query: GET_ORGANIZATION_DATA_PG,
variables: { id: 'org-123', first: 10, after: null },
variables: { id: 'org-123', first: 1, after: null },
},
result: {
data: mockOrganizationData,
Expand All @@ -261,7 +261,7 @@ const loadingMocks: IMockedResponse[] = [
{
request: {
query: GET_ORGANIZATION_DATA_PG,
variables: { id: 'org-123', first: 10, after: null },
variables: { id: 'org-123', first: 1, after: null },
},
delay: 30000, // Never resolve to simulate loading
},
Expand All @@ -271,7 +271,7 @@ const errorMocks: IMockedResponse[] = [
{
request: {
query: GET_ORGANIZATION_DATA_PG,
variables: { id: 'org-123', first: 10, after: null },
variables: { id: 'org-123', first: 1, after: null },
},
error: new Error('Failed to fetch organization'),
},
Expand Down Expand Up @@ -401,7 +401,7 @@ describe('LeftDrawerOrg', () => {
expect(screen.getByText('Test City')).toBeInTheDocument();
});

const avatar = screen.getByAltText('Test Organization');
const avatar = screen.getByAltText('profileAvatar.altText');
expect(avatar).toBeInTheDocument();
expect(avatar).toHaveAttribute('src', 'https://example.com/avatar.jpg');
});
Comment on lines +404 to 407
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Consider testing translated alt text value instead of i18n key.

The test queries for the literal i18n key 'profileAvatar.altText' rather than a translated value. While this works because the mock translation function returns keys for untranslated strings, it tests an implementation detail rather than user-facing behavior.

💡 Suggested improvement

Add the translation to the mock and test for the actual translated value:

 const mockTImplementation = (key: string) => {
   const translations: Record<string, string> = {
     talawaAdminPortal: 'Talawa Admin Portal',
     adminPortal: 'Admin Portal',
     menu: 'Menu',
     plugins: 'Plugins',
     Dashboard: 'Dashboard',
     Members: 'Members',
     Events: 'Events',
     'Action Items': 'Action Items',
     Posts: 'Posts',
+    'profileAvatar.altText': 'Organization Avatar',
   };
   return translations[key] || key;
 };

Then update the test:

-  const avatar = screen.getByAltText('profileAvatar.altText');
+  const avatar = screen.getByAltText('Organization Avatar');
   expect(avatar).toBeInTheDocument();
   expect(avatar).toHaveAttribute('src', 'https://example.com/avatar.jpg');

This makes the test more robust to i18n key refactoring and better reflects actual user experience.

🤖 Prompt for AI Agents
In @src/components/LeftDrawerOrg/LeftDrawerOrg.spec.tsx around lines 404 - 407,
The test is asserting the alt text using the i18n key string; update the mock
translation used in the test suite so that the translation function returns a
real user-facing string (e.g., "Profile avatar") for the key used by the
component, then change the assertion to query for that translated value (replace
screen.getByAltText('profileAvatar.altText') with
screen.getByAltText('<translated string>') and verify its src). Ensure the mock
translator and the test reference the same translated text so the test checks
user-facing behavior rather than the raw i18n key.

Expand All @@ -411,7 +411,7 @@ describe('LeftDrawerOrg', () => {
{
request: {
query: GET_ORGANIZATION_DATA_PG,
variables: { id: 'org-123', first: 10, after: null },
variables: { id: 'org-123', first: 1, after: null },
},
result: {
data: mockOrganizationDataWithoutAvatar,
Expand All @@ -436,7 +436,7 @@ describe('LeftDrawerOrg', () => {
{
request: {
query: GET_ORGANIZATION_DATA_PG,
variables: { id: 'org-123', first: 10, after: null },
variables: { id: 'org-123', first: 1, after: null },
},
result: {
data: mockOrganizationDataWithoutCity,
Expand Down Expand Up @@ -908,7 +908,7 @@ describe('LeftDrawerOrg', () => {
// The query should be called with correct variables
expect(successMocks[0].request.variables).toEqual({
id: 'org-123',
first: 10,
first: 1,
after: null,
});
});
Expand All @@ -918,7 +918,7 @@ describe('LeftDrawerOrg', () => {
{
request: {
query: GET_ORGANIZATION_DATA_PG,
variables: { id: 'different-org', first: 10, after: null },
variables: { id: 'different-org', first: 1, after: null },
},
result: {
data: {
Expand Down
56 changes: 21 additions & 35 deletions src/screens/UserPortal/Volunteer/Groups/GroupModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
* Success or error messages are displayed using toast notifications based on the result of the mutation.
*/
import type { ChangeEvent } from 'react';
import { Button, Form, Modal } from 'react-bootstrap';
import { Button, Form } from 'react-bootstrap';
import type {
InterfaceCreateVolunteerGroup,
InterfaceVolunteerGroupInfo,
Expand Down Expand Up @@ -56,8 +56,9 @@ import {
import { PiUserListBold } from 'react-icons/pi';
import { TbListDetails } from 'react-icons/tb';
import { USER_VOLUNTEER_MEMBERSHIP } from 'GraphQl/Queries/EventVolunteerQueries';
import Avatar from 'components/Avatar/Avatar';
import { FaXmark } from 'react-icons/fa6';
import { ProfileAvatarDisplay } from 'shared-components/ProfileAvatarDisplay/ProfileAvatarDisplay';
import BaseModal from 'shared-components/BaseModal/BaseModal';

export interface InterfaceGroupModal {
isOpen: boolean;
Expand Down Expand Up @@ -187,19 +188,14 @@ const GroupModal: React.FC<InterfaceGroupModal> = ({
);

return (
<Modal className={styles.groupModal} onHide={hide} show={isOpen}>
<Modal.Header>
<p className={styles.titlemodal}>{t('manageGroup')}</p>
<Button
variant="danger"
onClick={hide}
className={styles.modalCloseBtn}
data-testid="modalCloseBtn"
>
<i className="fa fa-times"></i>
</Button>
</Modal.Header>
<Modal.Body>
<BaseModal
className={styles.groupModal}
show={isOpen}
onHide={hide}
title={t('manageGroup')}
data-testid="groupModal"
>
Comment on lines +191 to +197
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

❌ Fix incorrect prop name: data-testiddataTestId.

Line 196 uses data-testid but BaseModal expects dataTestId (camelCase) per its interface definition. This will cause a TypeScript error.

🔧 Proposed fix
     <BaseModal
       className={styles.groupModal}
       show={isOpen}
       onHide={hide}
       title={t('manageGroup')}
-      data-testid="groupModal"
+      dataTestId="groupModal"
     >
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<BaseModal
className={styles.groupModal}
show={isOpen}
onHide={hide}
title={t('manageGroup')}
data-testid="groupModal"
>
<BaseModal
className={styles.groupModal}
show={isOpen}
onHide={hide}
title={t('manageGroup')}
dataTestId="groupModal"
>
🤖 Prompt for AI Agents
In @src/screens/UserPortal/Volunteer/Groups/GroupModal.tsx around lines 191 -
197, The BaseModal usage passes a hyphenated prop name `data-testid` which
doesn’t match the component’s TypeScript interface; change the prop to camelCase
`dataTestId` on the BaseModal element (the instance that sets
className={styles.groupModal}, show={isOpen}, onHide={hide},
title={t('manageGroup')}) so it conforms to BaseModal’s expected prop name and
resolves the type error.

<>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Remove unnecessary fragment wrapper.

The <> and </> wrappers around the modal content (lines 198, 393) are unnecessary since BaseModal accepts children directly without requiring a fragment. Removing them will simplify the code structure.

♻️ Proposed refactor
     <BaseModal
       className={styles.groupModal}
       show={isOpen}
       onHide={hide}
       title={t('manageGroup')}
       dataTestId="groupModal"
     >
-      <>
         <div
           className={`btn-group ${styles.toggleGroup} mt-0 px-3 mb-4 w-100`}
           role="group"
         >
           {/* ...rest of content... */}
         </div>
-      </>
     </BaseModal>

Also applies to: 393-393

🤖 Prompt for AI Agents
In @src/screens/UserPortal/Volunteer/Groups/GroupModal.tsx at line 198, In
GroupModal, remove the unnecessary React fragment tokens ("<>" and "</>")
wrapping the modal children passed into BaseModal—locate the fragment around the
modal content inside the GroupModal component (surrounding the BaseModal
children) and delete both the opening and closing fragment so BaseModal receives
its children directly; ensure the remaining JSX stays valid and that no other
wrapper is required for multiple sibling elements.

<div
className={`btn-group ${styles.toggleGroup} mt-0 px-3 mb-4 w-100`}
role="group"
Expand Down Expand Up @@ -349,24 +345,14 @@ const GroupModal: React.FC<InterfaceGroupModal> = ({
className="d-flex gap-1 align-items-center"
data-testid="userName"
>
{avatarURL ? (
<img
src={avatarURL}
alt={t('volunteerAlt')}
data-testid={`image${id + 1}`}
className={styles.TableImage}
/>
) : (
<div className={styles.avatarContainer}>
<Avatar
key={id + '1'}
containerStyle={styles.imageContainer}
avatarStyle={styles.TableImage}
name={name}
alt={name}
/>
</div>
)}
<ProfileAvatarDisplay
key={id + '1'}
imageUrl={avatarURL}
fallbackName={t('volunteerAlt')}
dataTestId={'image' + (id + 1)}
className={styles.TableImage}
/>
Comment on lines +348 to +354
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

🧩 Analysis chain

🏁 Script executed:

# Check for translation keys in locale files
for locale in en es fr hi zh; do
  echo "=== Checking $locale ==="
  jq '.eventVolunteers.volunteerAlt // "NOT_FOUND"' "public/locales/$locale/translation.json" 2>/dev/null || echo "File or key not found"
done

Repository: PalisadoesFoundation/talawa-admin

Length of output: 210


🏁 Script executed:

# Check the GroupModal.tsx file context around lines 348-354
sed -n '340,360p' src/screens/UserPortal/Volunteer/Groups/GroupModal.tsx

Repository: PalisadoesFoundation/talawa-admin

Length of output: 1001


🏁 Script executed:

# Verify ProfileAvatarDisplay import and usage patterns in the file
grep -n "ProfileAvatarDisplay" src/screens/UserPortal/Volunteer/Groups/GroupModal.tsx | head -20

Repository: PalisadoesFoundation/talawa-admin

Length of output: 233


🏁 Script executed:

# Check locale files more directly for volunteerAlt key
echo "=== Checking all locale files for 'volunteerAlt' key ==="
for locale in en es fr hi zh; do
  file="public/locales/$locale/translation.json"
  if [ -f "$file" ]; then
    echo "--- $locale ---"
    grep -o '"volunteerAlt"' "$file" || echo "KEY NOT FOUND"
  else
    echo "File not found: $file"
  fi
done

Repository: PalisadoesFoundation/talawa-admin

Length of output: 338


🏁 Script executed:

# Check what translation keys are available in the eventVolunteers section
echo "=== Checking eventVolunteers section in English locale ==="
jq '.eventVolunteers' public/locales/en/translation.json

Repository: PalisadoesFoundation/talawa-admin

Length of output: 2807


🏁 Script executed:

# Verify the complete GroupModal context to understand i18n setup
sed -n '1,70p' src/screens/UserPortal/Volunteer/Groups/GroupModal.tsx

Repository: PalisadoesFoundation/talawa-admin

Length of output: 2797


Translation key verified; consider using template literals for consistency.

The volunteerAlt translation key is confirmed to exist in all locale files (en, es, fr, hi, zh) under eventVolunteers.volunteerAlt with value "Volunteer profile picture". The component usage is correct.

For code consistency, consider replacing string concatenation with template literals:

  • Line 349: key={${id}-avatar} instead of key={id + '1'}
  • Line 352: dataTestId={image-${id}} instead of dataTestId={'image' + (id + 1)}
🤖 Prompt for AI Agents
In @src/screens/UserPortal/Volunteer/Groups/GroupModal.tsx around lines 348 -
354, The ProfileAvatarDisplay usage should use template literals for consistent
string interpolation: replace the current key expression (key={id + '1'}) with a
template literal like key={`${id}-avatar`} and replace dataTestId={'image' + (id
+ 1)} with dataTestId={`image-${id}`}; update the JSX props on the
ProfileAvatarDisplay component accordingly to ensure stable keys and consistent
test IDs.


{name}
</TableCell>
<TableCell component="th" scope="row">
Expand Down Expand Up @@ -404,8 +390,8 @@ const GroupModal: React.FC<InterfaceGroupModal> = ({
)}
</div>
)}
</Modal.Body>
</Modal>
</>
</BaseModal>
);
};
export default GroupModal;
19 changes: 19 additions & 0 deletions src/shared-components/OrganizationCard/OrganizationCard.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ vi.mock('react-i18next', () => ({
'users.membershipStatus.member': 'Membership status: Member',
'users.membershipStatus.pending': 'Membership status: Pending',
'users.membershipStatus.notMember': 'Membership status: Not a member',
'profileAvatar.altText': 'Test Org',
};

return translations[key] || key;
Expand Down Expand Up @@ -361,6 +362,15 @@ describe('OrganizationCard', () => {
},
},
},
{
request: {
query: ORGANIZATION_LIST,
variables: {},
},
result: {
data: {},
},
},
];

render(
Expand Down Expand Up @@ -574,6 +584,15 @@ describe('OrganizationCard', () => {
},
},
},
{
request: {
query: ORGANIZATION_LIST,
variables: {},
},
result: {
data: {},
},
},
];

render(
Expand Down
24 changes: 7 additions & 17 deletions src/shared-components/OrganizationCard/OrganizationCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ import Button from 'react-bootstrap/Button';
import { useTranslation } from 'react-i18next';
import styles from 'style/app-fixed.module.css';
import { Tooltip } from '@mui/material';
import Avatar from 'components/Avatar/Avatar';
import { useNavigate } from 'react-router-dom';
import { InterfaceOrganizationCardProps } from 'types/OrganizationCard/interface';
import { ApolloError, useMutation } from '@apollo/client';
Expand All @@ -56,6 +55,7 @@ import { ORGANIZATION_LIST } from 'GraphQl/Queries/Queries';
import { USER_JOINED_ORGANIZATIONS_PG } from 'GraphQl/Queries/OrganizationQueries';
import { NotificationToast } from 'components/NotificationToast/NotificationToast';
import useLocalStorage from 'utils/useLocalstorage';
import { ProfileAvatarDisplay } from 'shared-components/ProfileAvatarDisplay/ProfileAvatarDisplay';

export interface InterfaceOrganizationCardPropsPG {
data: InterfaceOrganizationCardProps;
Expand Down Expand Up @@ -171,22 +171,12 @@ function OrganizationCard({
<div className={styles.innerContainer} data-cy="orgCardContainer">
{/* Container for the organization image */}
<div className={styles.orgImgContainer}>
{avatarURL ? (
<img
src={avatarURL}
alt={name}
crossOrigin="anonymous"
referrerPolicy="no-referrer"
loading="lazy"
decoding="async"
/>
) : (
<Avatar
name={name}
alt={name}
dataTestId="emptyContainerForImage"
/>
)}
<ProfileAvatarDisplay
fallbackName={name}
imageUrl={avatarURL}
dataTestId="emptyContainerForImage"
enableEnlarge
/>
</div>
<div className={styles.content}>
<div>
Expand Down
Loading
Loading