import { createInfiniteScroll } from '@solid-primitives/pagination' import { clsx } from 'clsx' import { createEffect, createSignal, For, on, Show } from 'solid-js' import { useInbox } from '../../../context/inbox' import { useLocalize } from '../../../context/localize' import { Author } from '../../../graphql/schema/core.gen' import { hideModal } from '../../../stores/ui' import { useAuthorsStore } from '../../../stores/zine/authors' import { AuthorBadge } from '../../Author/AuthorBadge' import { Modal } from '../../Nav/Modal' import { Button } from '../Button' import { DropdownSelect } from '../DropdownSelect' import { Loading } from '../Loading' import styles from './InviteMembers.module.scss' type InviteAuthor = Author & { selected: boolean } type Props = { title?: string variant?: 'coauthors' | 'recipients' } const PAGE_SIZE = 50 export const InviteMembers = (props: Props) => { const { t } = useLocalize() const roles = [ { title: t('Editor'), description: t('Can write and edit text directly, and accept or reject suggestions from others'), }, { title: t('Co-author'), description: t('Can make any changes, accept or reject suggestions, and share access with others'), }, { title: t('Commentator'), description: t('Can offer edits and comments, but cannot edit the post or share access with others'), }, ] const { sortedAuthors } = useAuthorsStore({ sortBy: 'name' }) const { actions: { loadChats, createChat }, } = useInbox() const [authorsToInvite, setAuthorsToInvite] = createSignal() const [searchResultAuthors, setSearchResultAuthors] = createSignal() const [collectionToInvite, setCollectionToInvite] = createSignal([]) const fetcher = async (page: number) => { await new Promise((resolve, reject) => { const checkDataLoaded = () => { if (sortedAuthors().length > 0) { resolve(true) } else { setTimeout(checkDataLoaded, 100) } } setTimeout(() => reject(new Error('Timeout waiting for sortedAuthors')), 10000) checkDataLoaded() }) const start = page * PAGE_SIZE const end = start + PAGE_SIZE const authors = authorsToInvite()?.map((author) => ({ ...author, selected: false })) return authors?.slice(start, end) } const [pages, infiniteScrollLoader, { end }] = createInfiniteScroll(fetcher) createEffect( on( () => sortedAuthors(), (currentAuthors) => { setAuthorsToInvite(currentAuthors.map((author) => ({ ...author, selected: false }))) }, { defer: true }, ), ) const handleInputChange = async (value: string) => { if (value.length > 1) { const match = authorsToInvite().filter((author) => author.name.toLowerCase().includes(value.toLowerCase()), ) setSearchResultAuthors(match) } else { setSearchResultAuthors() } } const handleInvite = (id) => { setCollectionToInvite((prev) => [...prev, id]) } const handleCloseModal = () => { setSearchResultAuthors() setCollectionToInvite() hideModal() } const handleCreate = async () => { try { const initChat = await createChat(collectionToInvite(), 'chat Title') console.debug('[components.Inbox] create chat result:', initChat) hideModal() await loadChats() } catch (error) { console.error('handleCreate chat', error) } } return (

{props.title || t('Invite collaborators')}

{ if (props.variant === 'recipients') return handleInputChange(e.target.value) }} onInput={(e) => { if (props.variant === 'coauthors') return handleInputChange(e.target.value) }} />

{t('Coming soon')}

{t( 'We are working on collaborative editing of articles and in the near future you will have an amazing opportunity - to create together with your colleagues', )}

{(author) => (
handleInvite(id)} />
)}
{t('Loading')}
) }