import clsx from 'clsx' import dayjs from 'dayjs' import { useState } from 'react' import Textarea from 'react-expanding-textarea' import { Contract, MAX_DESCRIPTION_LENGTH } from 'common/contract' import { exhibitExts, parseTags } from 'common/util/parse' import { useAdmin } from 'web/hooks/use-admin' import { updateContract } from 'web/lib/firebase/contracts' import { Row } from '../layout/row' import { Content } from '../editor' import { TextEditor, useTextEditor } from 'web/components/editor' import { Button } from '../button' import { Spacer } from '../layout/spacer' import { Editor, Content as ContentType } from '@tiptap/react' import { insertContent } from '../editor/utils' export function ContractDescription(props: { contract: Contract isCreator: boolean className?: string }) { const { contract, isCreator, className } = props const isAdmin = useAdmin() return (
{isCreator || isAdmin ? ( ) : ( )}
) } function editTimestamp() { return `${dayjs().format('MMM D, h:mma')}: ` } function RichEditContract(props: { contract: Contract; isAdmin?: boolean }) { const { contract, isAdmin } = props const [editing, setEditing] = useState(false) const [editingQ, setEditingQ] = useState(false) const [isSubmitting, setIsSubmitting] = useState(false) const { editor, upload } = useTextEditor({ max: MAX_DESCRIPTION_LENGTH, defaultValue: contract.description, disabled: isSubmitting, }) async function saveDescription() { if (!editor) return const tags = parseTags( `${editor.getText()} ${contract.tags.map((tag) => `#${tag}`).join(' ')}` ) const lowercaseTags = tags.map((tag) => tag.toLowerCase()) await updateContract(contract.id, { description: editor.getJSON(), tags, lowercaseTags, }) } return editing ? ( <> ) : ( <> {isAdmin && 'Admin: '} ) } function EditQuestion(props: { contract: Contract editing: boolean setEditing: (editing: boolean) => void }) { const { contract, editing, setEditing } = props const [text, setText] = useState(contract.question) function questionChanged(oldQ: string, newQ: string) { return `

${editTimestamp()}${oldQ} → ${newQ}

` } function joinContent(oldContent: ContentType, newContent: string) { const editor = new Editor({ content: oldContent, extensions: exhibitExts }) editor.commands.focus('end') insertContent(editor, newContent) return editor.getJSON() } const onSave = async (newText: string) => { setEditing(false) await updateContract(contract.id, { question: newText, description: joinContent( contract.description, questionChanged(contract.question, newText) ), }) } return editing ? (