import React, { useCallback, useContext, useEffect, useMemo, useState } from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import { mapToCssModules, tagPropType } from 'reactstrap/src/utils';
import { AccordionContext } from 'reactstrap/src/AccordionContext';
import { Collapse } from 'reactstrap';
import { emptyObject, processIncludeVariables, useReactorNavigation } from '../..';
import { useSelector } from 'react-redux';
/* agregar include_variables y use_spinner */
/**
* Componente que renderiza el body de un Accordion de Bootstrap.
* @name Reactor.Components.Layout.AccordionBody
* @param {string} id Identificador unico de body
* @param {string} options Json string de propiedades que van al Collapse dentro del Body
* @param {string} href Operacion que se va a ejecutar con tarjet operation al abrir el panel
* @param {string} data Json string con data que se envia a la operacion (solo si href tiene un valor)
* @param {string?} include_variables Lista de variables que se incluyen en la data (separadas por espacio)
* @param {string?} context Contexto contenedor de las variables que se van a incluir, es requerido si se incluyen variables
* @param {BooleanString} [use_spinner = "true"] Si es true se muestra un spinner mientras se espera la respuesta del servidor
* @class
* @example
<accordion default_open="1">
<accordion_item options='{"className":"card card-style"}'>
<div class="card-header d-flex">
<div class="align-self-center">
<h6 class="pt-1 font-14 font-600">Factura 0000-111111</h6>
</div>
<div class="align-self-center ms-auto text-end">
<h6 class="pt-1 font-14 font-600">10/03/2022</h6>
</div>
</div>
<accordion_header target="1">
<!-- header -->
<div class="card-body d-flex mb-2" style="height: auto; padding: 0.5rem 1rem;">
<div class="align-self-center" style="max-width: 240px">
<h6 class="mb-n1 font-12 opacity-60">Heladera con Freezer Gafa 282 Litros</h6>
<h6 class="pt-1 mb-n1 font-12 opacity-60">Smart TV 43" Samsung</h6>
<h6 class="pt-1 mb-n1 font-12 opacity-60">Aire Acondicionado Split</h6>
</div>
<div class="align-self-center ms-auto text-end pt-1">
<p class="mb-0 font-11 opacity-70" style="line-height: 10px">Monto a pagar</p>
<p class="mb-0 font-15 color-blue-dark font-700">$20.000,00</p>
<p class="mb-0 font-11 opacity-70" style="line-height: 10px">Vence</p>
<p class="mb-0 font-13 color-blue-dark font-700">19/03/2022</p>
</div>
</div>
<!-- comprobante fin -->
</accordion_header>
<accordion_body id="1" href='Operacion' data='{"propiedad": "valor"}'>
<strong>
This is the second item's accordion body.
</strong>
You can modify any of this with custom CSS or overriding our default variables. It's also worth noting that just about any HTML can go within the{' '}
<code>
.accordion-body
</code>
, though the transition does limit overflow.
</accordion_body>
</accordion_item>
*/
export const AccordionBody = ({children, id, options, href, data, use_spinner = "true", include_variables, context, debug = "false"}) => {
return (
<AccordionBodyBs accordionId={id} href={href} data={data} include_variables={include_variables} context={context} use_spinner={use_spinner} {...(options ? JSON.parse(options) : {})}>
{children}
</AccordionBodyBs>
);
}
const propTypes = {
tag: tagPropType,
className: PropTypes.string,
cssModule: PropTypes.object,
innerRef: PropTypes.oneOfType([
PropTypes.object,
PropTypes.string,
PropTypes.func,
]),
children: PropTypes.node,
accordionId: PropTypes.string.isRequired,
};
const defaultProps = {
tag: 'div'
};
const AccordionBodyBs = (props) => {
const {
href,
data,
use_spinner,
include_variables,
context,
className,
cssModule,
tag: Tag,
innerRef,
children,
accordionId,
...attributes
} = props;
const variablesState = useSelector(state => context === "_" ? state.app.variables : state.app.variables[context] ) || null;
const getVariables = useCallback(() => {
return context && processIncludeVariables({variablesState, include_variables});
}, [context, variablesState, include_variables]);
const navigation = useReactorNavigation({data, navOptions: emptyObject, target: "operation", to: href});
const { open } = useContext(AccordionContext);
const classes = mapToCssModules(classNames(
className,
'accordion-collapse',
), cssModule);
const isOpen = useMemo(()=>Array.isArray(open) ? open.includes(accordionId) : open === accordionId, [accordionId, open]);
const [ loaded, setLoaded ] = useState(false);
useEffect(()=>{
if(loaded){
if(href && isOpen){
navigation.execute({event: "open", ...getVariables()});
}
if(href && !isOpen){
navigation.execute({event: "close", ...getVariables()});
}
}else{
const timer = setTimeout(()=>{
setLoaded(true);
}, 50);
return ()=>clearTimeout(timer);
}
}, [isOpen]);
return (
<Collapse
{...attributes}
className={classes}
ref={innerRef}
isOpen={isOpen}>
<Tag className="accordion-body">{children}</Tag>
</Collapse>
);
};
AccordionBodyBs.propTypes = propTypes;
AccordionBodyBs.defaultProps = defaultProps;