import { CopyAllOutlined, InfoOutlined, Refresh } from '@mui/icons-material' import clsx from 'clsx' import { ComponentType, ReactNode, useEffect, useState } from 'react' import { useTranslation } from 'react-i18next' import { ApprovalProposalContext, ApprovalProposalContextType, Entity, IconButtonLinkProps, LoadingData, StatefulEntityDisplayProps, } from '@dao-dao/types' import { extractProposalDescriptionAndMetadata, formatDate, } from '@dao-dao/utils' import { ApprovalBadge } from '../ApprovalBadge' import { CopyToClipboardUnderline } from '../CopyToClipboard' import { IconButton } from '../icon_buttons' import { MarkdownRenderer } from '../MarkdownRenderer' export interface ProposalContentDisplayProps { title: string description: string innerContentDisplay: ReactNode creator?: { address: string entity: LoadingData } createdAt?: Date onRefresh?: () => void refreshing?: boolean duplicateUrl?: string IconButtonLink?: ComponentType EntityDisplay?: ComponentType approvalContext?: ApprovalProposalContext } export const ProposalContentDisplay = ({ title, description, innerContentDisplay, creator, createdAt, onRefresh, refreshing, duplicateUrl, IconButtonLink, EntityDisplay, approvalContext, }: ProposalContentDisplayProps) => { const { t } = useTranslation() const [refreshSpinning, setRefreshSpinning] = useState(false) // Start spinning refresh icon if refreshing sets to true. Turn off once the // iteration completes (in `onAnimationIteration` below). useEffect(() => { refreshing && setRefreshSpinning(true) }, [refreshing]) return ( <>
{approvalContext && ( )}

{title}

{approvalContext && approvalContext.type === ApprovalProposalContextType.Approver && (

{t('info.approverProposalExplanation', { context: approvalContext.status, })}

)}
{IconButtonLink && duplicateUrl && (!approvalContext || approvalContext.type === ApprovalProposalContextType.Approval) && ( )} {/* Refresh button that shows up after votes load or while votes are loading. */} {onRefresh && ( setRefreshSpinning(false) : undefined } onClick={() => { // Perform one spin even if refresh completes immediately. It // will stop after 1 iteration if `refreshing` does not become // true. setRefreshSpinning(true) onRefresh() }} variant="ghost" /> )}
{!!creator?.address && ( )} {!!createdAt && ( <> {/* eslint-disable-next-line i18next/no-literal-string */} {!!creator?.address &&

}

{formatDate(createdAt)}

)}
{innerContentDisplay && (
{innerContentDisplay}
)}
) }