Skip to content

Commit

Permalink
Add search user posts for moderators
Browse files Browse the repository at this point in the history
  • Loading branch information
samchuk-vlad committed Jul 17, 2024
1 parent 1aa0111 commit ca4a2f1
Show file tree
Hide file tree
Showing 5 changed files with 283 additions and 133 deletions.
Original file line number Diff line number Diff line change
@@ -1,27 +1,52 @@
import AddressAvatar from '@/components/AddressAvatar'
import Button from '@/components/Button'
import Name from '@/components/Name'
import { env } from '@/env.mjs'
import useAuthorizedForModeration from '@/hooks/useAuthorizedForModeration'
import { TabButton } from '@/modules/chat/HomePage/ChatTabs'
import { getModerationReasonsQuery } from '@/services/datahub/moderation/query'
import { getPaginatedPostIdsByPostIdAndAccount } from '@/services/datahub/posts/queryByAccount'
import { useSendEvent } from '@/stores/analytics'
import { useProfilePostsModal } from '@/stores/profile-posts-modal'
import { cx } from '@/utils/class-names'
import { Transition } from '@headlessui/react'
import { useRouter } from 'next/router'
import { useEffect, useState } from 'react'
import { createPortal } from 'react-dom'
import { HiOutlineChevronLeft } from 'react-icons/hi2'
import SkeletonFallback from '../../../SkeletonFallback'
import { useModerateWithSuccessToast } from '../ChatItemMenus'
import ProfilePostsList from './ProfilePostsList'

const ProfilePostsListModal = () => {
type Tab = 'all' | 'contest'

type ProfilePostsListModalProps = {
tabsConfig?: {
defaultTab: Tab
}
}

const defaultHubId = env.NEXT_PUBLIC_MAIN_SPACE_ID
const chatIdByTab = {
all: env.NEXT_PUBLIC_MAIN_CHAT_ID,
contest: env.NEXT_PUBLIC_CONTEST_CHAT_ID,
}

const ProfilePostsListModal = ({ tabsConfig }: ProfilePostsListModalProps) => {
const [selectedTab, setSelectedTab] = useState<Tab>(
tabsConfig?.defaultTab || 'all'
)

const router = useRouter()

const {
isOpen,
closeModal,
messageId = '',
chatId = '',
hubId = '',
chatId = tabsConfig ? chatIdByTab[tabsConfig.defaultTab] : '',
hubId = tabsConfig ? defaultHubId : '',
address = '',
openModal,
} = useProfilePostsModal()

const { mutate: moderate } = useModerateWithSuccessToast(messageId, chatId)
Expand Down Expand Up @@ -52,6 +77,10 @@ const ProfilePostsListModal = () => {
closeModal()
}

useEffect(() => {
closeModal()
}, [closeModal, router.asPath])

return createPortal(
<>
<Transition
Expand Down Expand Up @@ -119,6 +148,41 @@ const ProfilePostsListModal = () => {
)}
</div>
<div className='relative mx-auto flex h-full max-h-full min-h-[400px] w-full flex-col items-center px-4'>
{tabsConfig && (
<div className='sticky top-14 mb-2 grid h-12 w-full grid-flow-col items-center gap-4 bg-background px-4'>
<TabButton
tab='all'
selectedTab={selectedTab}
setSelectedTab={(tab) => {
setSelectedTab(tab as any)
openModal({
address,
chatId: chatIdByTab[tab as Tab],
hubId: defaultHubId,
})
}}
size={'md'}
>
All memes
</TabButton>
<TabButton
className='flex flex-col items-center justify-center text-center'
tab='contest'
selectedTab={selectedTab}
setSelectedTab={(tab) => {
setSelectedTab(tab as any)
openModal({
address,
chatId: chatIdByTab[tab as Tab],
hubId: defaultHubId,
})
}}
size={'md'}
>
Contest
</TabButton>
</div>
)}
<ProfilePostsList address={address} chatId={chatId} hubId={hubId} />
</div>
</div>
Expand Down
132 changes: 2 additions & 130 deletions src/modules/chat/HomePage/ChatContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import Shield from '@/assets/icons/shield.svg'
import Button from '@/components/Button'
import LinkText from '@/components/LinkText'
import Notice from '@/components/Notice'
import { Skeleton } from '@/components/SkeletonFallback'
import ChatRoom from '@/components/chats/ChatRoom'
import LinkEvmAddressModal from '@/components/modals/LinkEvmAddressModal'
import Meme2EarnIntroModal, {
Expand All @@ -11,7 +10,6 @@ import Meme2EarnIntroModal, {
import Modal, { ModalFunctionalityProps } from '@/components/modals/Modal'
import { env } from '@/env.mjs'
import useIsAddressBlockedInChat from '@/hooks/useIsAddressBlockedInChat'
import useIsModerationAdmin from '@/hooks/useIsModerationAdmin'
import useLinkedEvmAddress from '@/hooks/useLinkedEvmAddress'
import usePostMemeThreshold from '@/hooks/usePostMemeThreshold'
import PointsWidget from '@/modules/points/PointsWidget'
Expand All @@ -22,13 +20,13 @@ import { useSendEvent } from '@/stores/analytics'
import { useExtensionData } from '@/stores/extension'
import { useMessageData } from '@/stores/message'
import { useMyMainAddress } from '@/stores/my-account'
import { cx } from '@/utils/class-names'
import { useLocalStorage } from '@uidotdev/usehooks'
import dayjs from 'dayjs'
import duration from 'dayjs/plugin/duration'
import Router, { useRouter } from 'next/router'
import { ReactNode, useEffect, useLayoutEffect, useState } from 'react'
import { useEffect, useLayoutEffect, useState } from 'react'
import { LuPlusCircle } from 'react-icons/lu'
import { TabState, Tabs, tabStates } from './ChatTabs'

dayjs.extend(duration)

Expand Down Expand Up @@ -126,132 +124,6 @@ export default function ChatContent({ className }: Props) {
)
}

const tabStates = [
'all',
'contest',
'not-approved',
'not-approved-contest',
] as const
type TabState = (typeof tabStates)[number]
function TabButton({
selectedTab,
setSelectedTab,
tab,
children,
className,
size = 'md',
}: {
tab: TabState
selectedTab: TabState
setSelectedTab: (tab: TabState) => void
children: ReactNode
className?: string
size?: 'md' | 'sm'
}) {
const isSelected = selectedTab === tab
return (
<Button
variant={isSelected ? 'primary' : 'transparent'}
className={cx(
'h-10 py-0 text-sm',
size === 'sm' ? 'px-2' : 'h-10',
isSelected ? 'bg-background-primary/30' : '',
className
)}
onClick={() => setSelectedTab(tab)}
>
{children}
</Button>
)
}

function Tabs({
setSelectedTab,
selectedTab,
}: {
selectedTab: TabState
setSelectedTab: (tab: TabState) => void
}) {
const isAdmin = useIsModerationAdmin()
const { data: serverTime, isLoading } = getServerTimeQuery.useQuery(null)
const daysLeft = dayjs(env.NEXT_PUBLIC_CONTEST_END_TIME).diff(
dayjs(serverTime ?? undefined),
'days'
)

const tabSize: 'sm' | 'md' = isAdmin ? 'sm' : 'md'

return (
<div className='sticky top-14 grid h-12 grid-flow-col items-center gap-1 bg-background px-4'>
{isAdmin && (
<>
<TabButton
tab='not-approved'
selectedTab={selectedTab}
setSelectedTab={setSelectedTab}
size={tabSize}
>
Pending
</TabButton>
<TabButton
tab='not-approved-contest'
selectedTab={selectedTab}
setSelectedTab={setSelectedTab}
size={tabSize}
>
Pending Contest
</TabButton>
</>
)}
<TabButton
tab='all'
selectedTab={selectedTab}
setSelectedTab={setSelectedTab}
size={tabSize}
>
{isAdmin ? 'Approved' : 'All memes'}
</TabButton>
<TabButton
className='flex flex-col items-center justify-center text-center'
tab='contest'
selectedTab={selectedTab}
setSelectedTab={setSelectedTab}
size={tabSize}
>
{!isAdmin ? (
<>
<span>{env.NEXT_PUBLIC_CONTEST_NAME}</span>
<span className='text-xs font-medium text-text-primary'>
{(() => {
if (isLoading || !serverTime)
return <Skeleton className='w-16' />
if (env.NEXT_PUBLIC_CONTEST_END_TIME < serverTime)
return <span className='text-text-red'>Contest ended</span>
if (daysLeft === 0) {
const hoursLeft = dayjs(
env.NEXT_PUBLIC_CONTEST_END_TIME
).diff(dayjs(serverTime ?? undefined), 'hours')
if (hoursLeft < 1) {
return <span>Less than an hour left</span>
}
return <span>{hoursLeft} hours left</span>
}
return (
<span>
{daysLeft} day{daysLeft > 1 ? 's' : ''} left
</span>
)
})()}
</span>
</>
) : (
<span>Contest</span>
)}
</TabButton>
</div>
)
}

function countdownText(timeLeft: number) {
const timeDuration = dayjs.duration({ milliseconds: timeLeft })
const minutes = Math.floor(timeDuration.asMinutes())
Expand Down
Loading

0 comments on commit ca4a2f1

Please sign in to comment.