import {Box, Skeleton} from '@chakra-ui/react' import * as React from 'react' import {ISectionConnection, ISectionOptions} from '../../index' import {useAppDispatch, useAppSelector, withRedux} from '../../internal/redux' import {internalActions} from '../../internal/redux/slices' import {useJaenPageContext} from '../../internal/services/page' import {JaenSectionProvider} from '../../internal/services/section' import {useSectionData} from '../../internal/services/section/useSectionData' import {IJaenSectionItem, JaenSectionPath} from '../../types' import {SectionAddPopover, SectionManagePopover} from './components/popovers' type SectionPropsCallback = (args: { count: number totalSections: number section: IJaenSectionItem }) => {[key: string]: any} export interface SectionFieldProps { name: string // chapterName displayName: string sections: ISectionConnection[] as?: React.ComponentType> sectionAs?: React.ComponentType> props?: {[key: string]: any} sectionProps?: {[key: string]: any} | SectionPropsCallback className?: string style?: React.CSSProperties sectionClassName?: string sectionStyle?: React.CSSProperties } const SectionField = ({ name, displayName, sections, ...rest }: SectionFieldProps) => { const dispatch = useAppDispatch() const isEditing = useAppSelector(state => state.internal.status.isEditing) // sections to dictionary with key as section name const sectionsDict = React.useMemo(() => { return sections.reduce< Record< string, { Component: ISectionConnection options: {displayName: string; name: string} } > >( (acc, Section) => ({ ...acc, [Section.options.name]: { Component: Section, options: Section.options } }), {} ) }, [sections]) const {jaenPage} = useJaenPageContext() const {data: section, sectionPath} = useSectionData(name) const handleSectionAdd = React.useCallback( (sectionItemType: string, between: [string | null, string | null]) => { dispatch( internalActions.section_add({ pageId: jaenPage.id, sectionItemType, path: sectionPath, between }) ) }, [] ) const handleSectionAppend = React.useCallback( (sectionName: string, id: string, ptrNext: string | null) => { handleSectionAdd(sectionName, [id, ptrNext || null]) }, [] ) const handleSectionPrepend = React.useCallback( (sectionName: string, id: string, ptrPrev: string | null) => { handleSectionAdd(sectionName, [ptrPrev || null, id]) }, [] ) const handleSectionDelete = React.useCallback( (id: string, ptrPrev: string | null, ptrNext: string | null) => { dispatch( internalActions.section_remove({ pageId: jaenPage.id, sectionId: id, path: sectionPath, between: [ptrPrev, ptrNext] }) ) }, [] ) const sectionsOptions = React.useMemo( () => sections.map(s => ({ name: s.options.name, displayName: s.options.displayName })), [sections] ) const Wrapper = rest.as || Box return ( {isEditing && section.items.length === 0 ? ( Add to {displayName} } sections={sectionsOptions} onSelect={name => handleSectionAdd(name, [null, null])}> ) : ( section.items.map((item, index) => { const s = sectionsDict[item.type] if (!s) { console.error( `Section type ${item.type} is not found in sections dictionary!` ) return null } const {Component: Section, options} = s const SectionWrapper = rest.sectionAs || Box const sectionProps = typeof rest.sectionProps === 'function' ? rest.sectionProps({ count: index + 1, totalSections: section.items.length, section: item }) : rest.sectionProps return ( ) }) )} ) } const LazySectionManagement = React.memo( (props: { isEditing: boolean sectionPath: JaenSectionPath Component: ISectionConnection options: ISectionOptions allOptions: ISectionOptions[] itemId: string itemPositon: number itemPtrPrev: string | null itemPtrNext: string | null onDelete: ( id: string, ptrPrev: string | null, ptrNext: string | null ) => void onAppend: (sectionName: string, id: string, ptrNext: string | null) => void onPrepend: (sectionName: string, id: string, ptrPrev: string | null) => void }) => { const item = ( ) return ( ) } ) export default withRedux(SectionField)