diff --git a/src/components/announcements/TcAnnouncementsTable.tsx b/src/components/announcements/TcAnnouncementsTable.tsx index df28b871..0fec5768 100644 --- a/src/components/announcements/TcAnnouncementsTable.tsx +++ b/src/components/announcements/TcAnnouncementsTable.tsx @@ -21,6 +21,7 @@ import { useSnackbar } from '../../context/SnackbarContext'; import { MdModeEdit, MdDelete } from 'react-icons/md'; import Loading from '../global/Loading'; import { truncateCenter } from '../../helpers/helper'; +import moment from 'moment'; interface Channel { channelId: string; @@ -61,12 +62,14 @@ interface Announcement { interface AnnouncementsTableProps { announcements: Announcement[]; isLoading: boolean; + selectedZone: string; handleRefreshList: () => void; } function TcAnnouncementsTable({ announcements, isLoading, + selectedZone, handleRefreshList, }: AnnouncementsTableProps) { const { deleteAnnouncements } = useAppStore(); @@ -78,6 +81,13 @@ function TcAnnouncementsTable({ string | null >(null); + const formatDateBasedOnTimezone = ( + date: string | number | Date, + timezone: string + ) => { + return moment(date).tz(timezone).format('DD/MM/YYYY, h:mm:ss a'); + }; + const handleClick = ( event: React.MouseEvent, id: string @@ -228,57 +238,60 @@ function TcAnnouncementsTable({ /> ); - case 'users': - return ( -
- { - const users = item.options.users; - if (users && users.length > 0) { - const displayedUsers = users - .slice(0, 2) - .map((user: { ngu: any }) => `@${user.ngu}`) - .join(', '); - const moreUsersIndicator = users.length > 2 ? '...' : ''; - return `${displayedUsers}${moreUsersIndicator}`; - } - return ''; - }) - .filter((text: string) => text !== '') - .join(', ')} - variant="subtitle2" - /> -
- ); - case 'roles': - return ( -
- { - const roles = item.options.roles; - if (roles && roles.length > 0) { - const displayedRoles = roles - .slice(0, 2) - .map((role: { name: any }) => role.name) - .join(', '); - const moreRolesIndicator = roles.length > 2 ? '...' : ''; - return `${displayedRoles}${moreRolesIndicator}`; - } - return ''; - }) - .filter((text: string) => text !== '') - .join(', ')} - variant="subtitle2" - /> -
- ); + // case 'users': + // return ( + //
+ // { + // const users = item.options.users; + // if (users && users.length > 0) { + // const displayedUsers = users + // .slice(0, 2) + // .map((user: { ngu: any }) => `@${user.ngu}`) + // .join(', '); + // const moreUsersIndicator = users.length > 2 ? '...' : ''; + // return `${displayedUsers}${moreUsersIndicator}`; + // } + // return ''; + // }) + // .filter((text: string) => text !== '') + // .join(', ')} + // variant="subtitle2" + // /> + //
+ // ); + // case 'roles': + // return ( + //
+ // { + // const roles = item.options.roles; + // if (roles && roles.length > 0) { + // const displayedRoles = roles + // .slice(0, 2) + // .map((role: { name: any }) => role.name) + // .join(', '); + // const moreRolesIndicator = roles.length > 2 ? '...' : ''; + // return `${displayedRoles}${moreRolesIndicator}`; + // } + // return ''; + // }) + // .filter((text: string) => text !== '') + // .join(', ')} + // variant="subtitle2" + // /> + //
+ // ); case 'scheduledAt': return (
@@ -346,39 +359,35 @@ function TcAnnouncementsTable({ key={announcement.id} className={`my-5 ${index % 2 === 0 ? 'bg-gray-100' : ''}`} > - {[ - 'title', - 'channels', - 'users', - 'roles', - 'scheduledAt', - 'actions', - ].map((cellType, cellIndex, array) => ( - - {renderTableCell(announcement, cellType)} - - ))} + {['title', 'channels', 'scheduledAt', 'actions'].map( + (cellType, cellIndex, array) => ( + + {renderTableCell(announcement, cellType)} + + ) + )} ))} @@ -394,7 +403,7 @@ function TcAnnouncementsTable({ sx={{ borderBottom: 'none' }} className="uppercase text-gray-400" style={{ - width: '20%', + width: '60%', borderBottom: 'none', whiteSpace: 'nowrap', padding: '0 1rem', @@ -416,7 +425,7 @@ function TcAnnouncementsTable({ > - - - */} + {/* - + */} ); - const button = getByText('Schedule Announcement'); + const button = getByText('Select Date for Announcement'); expect(button).toBeInTheDocument(); fireEvent.click(button); diff --git a/src/components/announcements/create/publicMessageContainer/TcPublicMessageContainer.spec.tsx b/src/components/announcements/create/publicMessageContainer/TcPublicMessageContainer.spec.tsx index 17b3daf7..88d1b3d1 100644 --- a/src/components/announcements/create/publicMessageContainer/TcPublicMessageContainer.spec.tsx +++ b/src/components/announcements/create/publicMessageContainer/TcPublicMessageContainer.spec.tsx @@ -38,23 +38,13 @@ describe('TcPublicMessageContainer', () => { expect(screen.getByText(/Public Message/i)).toBeInTheDocument(); }); - it('renders the "Send message to:" text', () => { - expect(screen.getByText(/Send message to:/i)).toBeInTheDocument(); - }); - - it('renders the message about bot delivery', () => { + it('renders the message about bot distribute', () => { const message = - /Our bot will deliver the announcement across chosen channels with the necessary access to share the specified message\./i; + /Our bot will distribute the announcement through selected channels with the required access to share the designated message./i; expect(screen.getByText(message)).toBeInTheDocument(); }); it('renders the "Write message here:" text', () => { expect(screen.getByText(/Write message here:/i)).toBeInTheDocument(); }); - - it('renders the auto-generated safety message prompt', () => { - const message = - /If you don’t write a custom message then this auto-generated safety message wlll be sent out/i; - expect(screen.getByText(message)).toBeInTheDocument(); - }); }); diff --git a/src/components/announcements/create/publicMessageContainer/TcPublicMessageContainer.tsx b/src/components/announcements/create/publicMessageContainer/TcPublicMessageContainer.tsx index 673afe84..9c54ec29 100644 --- a/src/components/announcements/create/publicMessageContainer/TcPublicMessageContainer.tsx +++ b/src/components/announcements/create/publicMessageContainer/TcPublicMessageContainer.tsx @@ -67,9 +67,7 @@ function TcPublicMessageContainer({ setSelectedChannels(flattenChannels(channels)); }, [channels, selectedSubChannels]); - const [message, setMessage] = useState( - `This message was sent to you because you’re part of ${community?.name}. To verify the legitimacy of this message, see the official announcement here ⁠👥together-crew⁠ and verify the bot ID If you don’t want to receive any more private message from ${community?.name}, please adjust your settings here: https://app.togethercrew.com/community-settings/` - ); + const [message, setMessage] = useState(''); const handleChange = (event: React.ChangeEvent) => { setMessage(event.target.value); @@ -94,6 +92,7 @@ function TcPublicMessageContainer({ label: channel.name, }) ); + setSelectedChannels(formattedChannels); setMessage(publicAnnouncementsData.template); } @@ -103,7 +102,7 @@ function TcPublicMessageContainer({ return (
-
+
@@ -116,14 +115,14 @@ function TcPublicMessageContainer({ />
-
+ {/*
-
+
*/} Select Channels -
+
diff --git a/src/components/announcements/create/scheduleAnnouncement/TcScheduleAnnouncement.spec.tsx b/src/components/announcements/create/scheduleAnnouncement/TcScheduleAnnouncement.spec.tsx index 870106c8..b07aef74 100644 --- a/src/components/announcements/create/scheduleAnnouncement/TcScheduleAnnouncement.spec.tsx +++ b/src/components/announcements/create/scheduleAnnouncement/TcScheduleAnnouncement.spec.tsx @@ -4,8 +4,52 @@ import '@testing-library/jest-dom'; import TcScheduleAnnouncement from './TcScheduleAnnouncement'; describe('TcScheduleAnnouncement Tests', () => { + // Mock functions for the new props + const mockHandleScheduledDate = jest.fn(); + const mockSetIsDateValid = jest.fn(); + test('renders the component without crashing', () => { - render(); - expect(screen.getByText('Schedule Announcement')).toBeInTheDocument(); + render( + + ); + + // Since the initial text is "Select Date for Announcement", we should assert this text. + expect( + screen.getByText('Select Date for Announcement') + ).toBeInTheDocument(); + }); + + test('initially displays the calendar icon', () => { + render( + + ); + + // Assuming your TcButton component renders an icon, this test checks for its presence. + const calendarIcon = screen.getByTestId('MdCalendarMonth'); + expect(calendarIcon).toBeInTheDocument(); + }); + + test('displays the button to open date-time popover', () => { + render( + + ); + + // Check if the button that is supposed to open the date-time popover is rendered. + const button = screen.getByRole('button', { + name: /select date for announcement/i, + }); + expect(button).toBeInTheDocument(); }); }); diff --git a/src/components/announcements/create/scheduleAnnouncement/TcScheduleAnnouncement.tsx b/src/components/announcements/create/scheduleAnnouncement/TcScheduleAnnouncement.tsx index e68e28cb..394f88f4 100644 --- a/src/components/announcements/create/scheduleAnnouncement/TcScheduleAnnouncement.tsx +++ b/src/components/announcements/create/scheduleAnnouncement/TcScheduleAnnouncement.tsx @@ -5,22 +5,28 @@ import TcText from '../../../shared/TcText'; import TcButton from '../../../shared/TcButton'; import moment from 'moment'; import TcDateTimePopover from './TcDateTimePopover'; +import { validateDateTime } from '../../../../helpers/helper'; export interface ITcScheduleAnnouncementProps { isEdit?: boolean; preSelectedTime?: string; handleSchaduledDate: ({ selectedTime }: { selectedTime: string }) => void; + isDateValid: boolean; + setIsDateValid: (isValid: boolean) => void; } function TcScheduleAnnouncement({ isEdit = false, preSelectedTime, handleSchaduledDate, + isDateValid, + setIsDateValid, }: ITcScheduleAnnouncementProps) { const [anchorEl, setAnchorEl] = useState(null); const [activeTab, setActiveTab] = useState(0); const [selectedDate, setSelectedDate] = useState(null); const [selectedTime, setSelectedTime] = useState(null); + const [dateTimeDisplay, setDateTimeDisplay] = useState( 'Select Date for Announcement' ); @@ -40,6 +46,8 @@ function TcScheduleAnnouncement({ if (date) { setSelectedDate(date); setActiveTab(1); + const isValid = validateDateTime(date, selectedTime); + setIsDateValid(isValid); } }; @@ -54,6 +62,8 @@ function TcScheduleAnnouncement({ }); setDateTimeDisplay(fullDateTime.format('D MMMM YYYY @ hh:mm A')); } + const isValid = validateDateTime(selectedDate, time); + setIsDateValid(isValid); } }; @@ -74,26 +84,23 @@ function TcScheduleAnnouncement({ useEffect(() => { if (isEdit && preSelectedTime) { - const date = moment(preSelectedTime); - - setSelectedDate(date.toDate()); - setSelectedTime(date.toDate()); - setDateTimeDisplay(date.format('D MMMM YYYY @ hh:mm A')); + const dateTime = moment(preSelectedTime); + const date = dateTime.toDate(); + setSelectedDate(date); + setSelectedTime(date); + setDateTimeDisplay(dateTime.format('D MMMM YYYY @ hh:mm A')); + setIsDateValid(validateDateTime(date, date)); } }, [isEdit, preSelectedTime]); return (
-
+
- + - +
+ {!isDateValid && ( + + )} ([]); const [users, setUsers] = useState([]); const [loading, setLoading] = useState(false); + const [isDateValid, setIsDateValid] = useState(true); const platformId = community?.platforms.find( (platform) => platform.disconnectedAt === null @@ -134,6 +141,13 @@ function CreateNewAnnouncements() {
+ { + setScheduledAt(selectedTime); + }} + isDateValid={isDateValid} + setIsDateValid={setIsDateValid} + /> - + + + + + +
+ {/* - { - setScheduledAt(selectedTime); - }} - /> + /> */}
handleCreateAnnouncements(e) } diff --git a/src/pages/announcements/edit-announcements/index.tsx b/src/pages/announcements/edit-announcements/index.tsx index 7b0bc067..07075306 100644 --- a/src/pages/announcements/edit-announcements/index.tsx +++ b/src/pages/announcements/edit-announcements/index.tsx @@ -16,6 +16,9 @@ import { useSnackbar } from '../../../context/SnackbarContext'; import { useToken } from '../../../context/TokenContext'; import { CreateAnnouncementsPayloadData } from '../create-new-announcements'; import SimpleBackdrop from '../../../components/global/LoadingBackdrop'; +import { MdOutlineAnnouncement } from 'react-icons/md'; +import TcIconContainer from '../../../components/announcements/create/TcIconContainer'; +import TcText from '../../../components/shared/TcText'; export interface DiscordChannel { channelId: string; @@ -69,6 +72,7 @@ function Index() { const [roles, setRoles] = useState([]); const [users, setUsers] = useState([]); const [loading, setLoading] = useState(false); + const [isDateValid, setIsDateValid] = useState(true); const platformId = community?.platforms.find( (platform) => platform.disconnectedAt === null @@ -160,6 +164,8 @@ function Index() { if (data) { showMessage('Announcement updated successfully', 'success'); router.push('/announcements'); + } else { + fetchPlatformChannels(); } } catch (error) { showMessage('Failed to create announcement', 'error'); @@ -187,6 +193,15 @@ function Index() {
+ { + setScheduledAt(selectedTime); + }} + isDateValid={isDateValid} + setIsDateValid={setIsDateValid} + /> - + + + + + +
+ {/* - { - setScheduledAt(selectedTime); - }} - /> + /> */}
handleEditAnnouncements(e)} />
diff --git a/src/pages/announcements/index.tsx b/src/pages/announcements/index.tsx index a055b024..2e8c06c6 100644 --- a/src/pages/announcements/index.tsx +++ b/src/pages/announcements/index.tsx @@ -208,6 +208,7 @@ function Index() { } handleRefreshList={fetchData} isLoading={loading} + selectedZone={selectedZone} />
) : (