diff --git a/packages/shared/src/components/sidebar/sections/NetworkSection.tsx b/packages/shared/src/components/sidebar/sections/NetworkSection.tsx index 4a542ae749..0c2b8f2e46 100644 --- a/packages/shared/src/components/sidebar/sections/NetworkSection.tsx +++ b/packages/shared/src/components/sidebar/sections/NetworkSection.tsx @@ -2,7 +2,12 @@ import type { ReactElement } from 'react'; import React, { useMemo } from 'react'; import type { SidebarMenuItem } from '../common'; import { ListIcon } from '../common'; -import { DefaultSquadIcon, NewSquadIcon, SourceIcon } from '../../icons'; +import { + DefaultSquadIcon, + NewSquadIcon, + SourceIcon, + TimerIcon, +} from '../../icons'; import { Section } from '../Section'; import { Origin } from '../../../lib/log'; import { useSquadNavigation } from '../../../hooks'; @@ -11,13 +16,17 @@ import { SquadImage } from '../../squads/SquadImage'; import { SidebarSettingsFlags } from '../../../graphql/settings'; import { webappUrl } from '../../../lib/constants'; import type { SidebarSectionProps } from './common'; +import { useSquadPendingPosts } from '../../../hooks/squads/useSquadPendingPosts'; +import { Typography, TypographyColor } from '../../typography/Typography'; export const NetworkSection = ({ isItemsButton, ...defaultRenderSectionProps }: SidebarSectionProps): ReactElement => { const { squads } = useAuthContext(); + const { count, isModeratorInAnySquad } = useSquadPendingPosts(); const { openNewSquad } = useSquadNavigation(); + const menuItems: SidebarMenuItem[] = useMemo(() => { const squadItems = squads?.map((squad) => { @@ -33,8 +42,22 @@ export const NetworkSection = ({ path: `${webappUrl}squads/${handle}`, }; }) ?? []; - return [ + isModeratorInAnySquad && + count > 0 && { + icon: () => } />, + title: 'Pending Posts', + path: `${webappUrl}squads/moderate`, + rightIcon: () => ( + + {count} + + ), + }, { icon: (active: boolean) => ( } /> @@ -51,7 +74,7 @@ export const NetworkSection = ({ requiresLogin: true, }, ].filter(Boolean); - }, [openNewSquad, squads]); + }, [openNewSquad, squads, count, isModeratorInAnySquad]); return (
) => { return ( + )} {squads?.map((squad) => ( ))} diff --git a/packages/webapp/pages/squads/moderate.tsx b/packages/webapp/pages/squads/moderate.tsx new file mode 100644 index 0000000000..0079a0f6c1 --- /dev/null +++ b/packages/webapp/pages/squads/moderate.tsx @@ -0,0 +1,84 @@ +import type { ReactElement } from 'react'; +import type { GetServerSideProps } from 'next'; +import React, { useEffect } from 'react'; +import { ManageSquadPageContainer } from '@dailydotdev/shared/src/components/squads/utils'; +import { + SquadTab, + SquadTabs, +} from '@dailydotdev/shared/src/components/squads/SquadTabs'; +import { SquadModerationList } from '@dailydotdev/shared/src/components/squads/moderation/SquadModerationList'; +import { + PageHeader, + PageHeaderTitle, +} from '@dailydotdev/shared/src/components/layout/common'; +import { + Button, + ButtonVariant, +} from '@dailydotdev/shared/src/components/buttons/Button'; +import { ArrowIcon } from '@dailydotdev/shared/src/components/icons'; +import { useSquad } from '@dailydotdev/shared/src/hooks'; +import { useRouter } from 'next/router'; +import { verifyPermission } from '@dailydotdev/shared/src/graphql/squads'; +import { SourcePermissions } from '@dailydotdev/shared/src/graphql/sources'; +import { TypographyType } from '@dailydotdev/shared/src/components/typography/Typography'; +import { getLayout as getMainLayout } from '../../components/layouts/MainLayout'; + +interface ModerateSquadPageProps { + handle: string | null; +} + +export const getServerSideProps: GetServerSideProps< + ModerateSquadPageProps +> = async ({ query }) => { + return { + props: { + handle: (query.handle as string) || null, + }, + }; +}; + +export default function ModerateSquadPage({ + handle, +}: ModerateSquadPageProps): ReactElement { + const router = useRouter(); + const { squad, isLoading, isFetched } = useSquad({ + handle, + }); + const isModerator = + verifyPermission(squad, SourcePermissions.ModeratePost) || !handle; + + useEffect(() => { + if (isLoading || !isFetched) { + return; + } + + if (handle && !squad.moderationRequired) { + router.push(`/squads/${handle}`); + } + }, [handle, isFetched, isLoading, router, squad]); + + if (isLoading) { + return null; + } + + return ( + + +