import React from 'react'
import {IJaenConnection} from '../../types'
import {cleanObject} from '../../utils/helper'
import {isAuthenticated} from '../../utils/hooks/isAuthenticated'
import {withRedux} from './internal/redux'
import {useField} from './internal/services/field/hooks'
import {JaenPageProvider} from './internal/services/page'
import SEO from './internal/services/page/SEO'
import {
SectionOptionsContext,
useJaenSectionContext
} from './internal/services/section'
import {IJaenPageProps} from './types'
/**
* @function connectPage Connects a gatsby page with Jaen.
*
* @see {@link connectTemplate} for more information.
*
* Warning: This component must be used to wrap a page, not a template.
*/
export const connectPage =
(
Component: React.ComponentType
,
options: {
displayName: string
children?: string[]
}
) => {
const MyComp: IJaenConnection
= props => {
const jaenPage = {
id: props.pageContext.jaenPageId,
...props.data?.jaenPage
}
return (
<>
>
)
}
MyComp.options = options
return MyComp
}
export type IPageConnection = ReturnType
/**
* @function connectTemplate Connects a gatsby template with Jaen.
*
* @param Component The template page to wrap
* @param {JaenTemplateOptions} templateOptions Configuration for the page
*
* Warning: This component must be used in conjunction with the graphql`
* query($jaenPageId: String!) {
* ...JaenPageData
* }
* ``
*
* @example
* ```
* export default connectTemplate(
* p => {
* return (
* <>
* Blog
* {JSON.stringify(p)}
* >
* )
* },
* {
* displayName: 'Simple Blog Page'
* }
* )
*
* export const query = graphql`
* query($jaenPageId: String!) {
* ...JaenPageData
* }
* `
* ```
*/
export const connectTemplate = (
Component: React.ComponentType
,
options: ITemplateOptions
) => {
const MyComp: IJaenConnection
= props => {
const jaenPage = {
id: props.pageContext.jaenPageId,
...props.data?.jaenPage
}
return (
<>
>
)
}
MyComp.options = options
return MyComp
}
export type ITemplateOptions = {
displayName: string
children: Array
isRootTemplate?: boolean
}
export type ITemplateConnection = ReturnType
export type ISectionOptions = {displayName: string; name: string}
/**
* @function connectSection Connects a section with Jaen.
*
* @param Component The component to wrap
*/
export const connectSection = (
Component: React.ComponentType
,
options: ISectionOptions
) => {
const MyComp: IJaenConnection
= props => {
const section = useJaenSectionContext()
React.useEffect(() => {
if (isAuthenticated() && section) {
// clean up props to prevent circular reference, react items or other issues in redux store / local storage
//section.register(cleanObject(props))
}
}, [])
return (
)
}
MyComp.options = options
return MyComp
}
export type ISectionConnection = ReturnType
export interface JaenFieldProps {
name: string
displayName?: string
defaultValue: IDefaultValue
style?: React.CSSProperties
className?: string
}
export interface FieldOptions {
fieldType: string
getAdminWidget?: (
props: {
field: {
defaultValue: IDefaultValue
value: IValue
onChange: (value: IValue) => void
name: string
}
} & IProps
) => JSX.Element
}
/**
* @function connectField - Connects a field to Jaen.
*
* @param Component The component to wrap
*
* @example
* ```
* const T = connectField(props => {
* const {name, defaultValue, style, className} = props.jaenField
* return null
* })
* ```
*/
export const connectField = (
Component: React.ComponentType<
React.PropsWithChildren<
P & {
jaenField: JaenFieldProps & {
staticValue?: IValue
value?: IValue
isEditing: boolean
onUpdateValue: (value: IValue) => void
}
}
>
>,
options: FieldOptions
) => {
const MyComp: IJaenConnection<
P & JaenFieldProps,
typeof options
> = props => {
const RegisterHelper: React.FC = withRedux(() => {
const field = useField(props.name, options.fieldType)
React.useEffect(() => {
if (isAuthenticated()) {
// clean up props to prevent circular reference, react items or other issues in redux store / local storage
field.register(cleanObject(props))
}
}, [])
return (
)
})
return
}
MyComp.options = options
return React.memo(MyComp)
}
export type IFieldConnection = ReturnType