import React, { useEffect, useRef, useState } from "react";
import { useReactorNavigation } from "../../_core";
import { FormContext, uuid } from "../..";
import { getFormData } from "./FormExt";
/**
* Componente que renderiza un formulario especial para integrar Decidir.
* Todos los input dentro de Form deben contener la propiedad name con el identificador del campo
* @name Reactor.Components.Data.FormDecidir
* @param {string!} url_decidir Url de la API de decidir
* @param {string!} public_api_key Public key para acceder a los servicios
* @param {string!} action Nombre de la operación de destino
* @param {string?} data Json string con datos que pueden agregarse al form para evitar inputs de tipo hidden
* @param {NavigationTarget} [target = "menu"] Destino del resultado
* @param {DirectionType} direction Dirección en la que va a mostrarse el menú
* @param {string?} offcanvas_class Clase css que se va a dar al menú
* @param {BooleanString} [use_token = "false"] Establece si se debe guardar el token que devuelve Orquesta, sirve para luego poder continuar el flujo con otro form, si es false no se guarda y el flujo termina
* @param {BooleanString} [use_prev_token = "true"] Establece si debe enviarse el token que está en memoria, sirve para continuar la ejecución de un flujo, si es false el token se envía null
* @param {BooleanString} [use_spinner = "true"] Establece si se muestra un spinner mientras se espera la respuesta del servidor
* @param {BooleanString} [inhabilitar_cs = "false"] Para inhabilitar el Servicio de Control de Fraude Cybersource
* @class
* @example
<form_decidir
url_decidir="https://developers.decidir.com/api/v2"
public_api_key="e9cdb99fff374b5f91da4480c8dca741"
action="PagoDecidir"
target="menu"
direction="bottom"
offcanvas_class="rounded-m"
inhabilitar_cs="true"
>
<div class="menu-size" style="height:auto;" >
<div class="content mt-0 mb-2">
<div class="form-custom form-label form-icon">
<i class="bi bi-check-circle font-13"></i>
<select class="form-select rounded-xs" name="medioPago" value="{{opcionSeleccionada}}" aria-label="">
<optgroup label="Medios de Pago">
{{opciones|OpcionCombo}}
</optgroup>
</select>
<label for="medioPago" class="form-label-always-active color-highlight font-11">Medio de pago</label>
</div>
<div class="pb-3"></div>
<div class="form-custom form-label form-icon">
<i class="bi bi-hash font-14"></i>
<input type="number" class="form-control rounded-xs" name="importe" placeholder="ingrese el monto"/>
<label for="importe" class="form-label-always-active color-highlight font-11">Importe</label>
<span class="font-10">( Moneda: $ ARG )</span>
</div>
<div class="pb-3"></div>
<input
type="submit"
class="form-control rounded-xs btn btn-full gradient-highlight shadow-bg shadow-bg-s"
value="Depositar"
offcanvas_class="rounded-m"/>
</div>
</div>
</form_decidir>
*/
export const FormDecidir = ({ public_api_key, url_decidir, action, direction, target, children, offcanvas_class, data = "{}", to, use_token = "false", use_prev_token = "true", use_spinner = "true", inhabilitar_cs = "false" }) => {
const [formInputData, setFormInputData ] = useState({})
const navigation = useReactorNavigation({target, to: action, direction, offcanvasClass: offcanvas_class});
const ref = useRef();
const [ formName ] = useState(() => `form_${uuid()}`);
useEffect(()=>{
return ()=>{
ref.current = null;
}
}, [])
const sdkResponseHandler = (status, response) => {
if (status != 200 && status != 201) {
//Manejo de error: Ver Respuesta de Error
navigation.execute({response, ...getFormData(ref.current), ...JSON.parse(data), event: "error"});
} else {
//Manejo de respuesta donde response = {token: "99ab0740-4ef9-4b38-bdf9-c4c963459b22"}
navigation.execute({response, ...getFormData(ref.current), ...JSON.parse(data), event: "ok"});
}
}
const handleSubmit = (event) => {
event?.preventDefault();
const decidir = new window.Decidir(url_decidir, inhabilitar_cs === "true");
//Se indica la public API Key
decidir.setPublishableKey(public_api_key);
decidir.setTimeout(5000);//timeout de 5 segundos
//funcion para manejar la respuesta
decidir.createToken(ref.current, sdkResponseHandler);//formulario y callback
if(!to) return;
navigation.ToFrameDiv({...getFormData(ref.current), ...JSON.parse(data), event: "createToken", element: event.target.name}, action, formName, to, null, use_token === "true", use_prev_token === "true", use_spinner === "true" )
}
const handleChange = (event) => {
setFormInputData({...getFormData(ref.current), ...JSON.parse(data), event: "change", element: event.target.name});
if(!to) return;
navigation.ToFrameDiv({...getFormData(ref.current), ...JSON.parse(data), event: "change", element: event.target.name}, action, formName, to, null, use_token === "true", use_prev_token === "true", use_spinner === "true" )
}
return (
<FormContext.Provider value={{submit: handleSubmit, change: handleChange, formInputData}}>
<form
ref={ref}
onSubmit={handleSubmit}
onChange={handleChange}
>
{children}
</form>
</FormContext.Provider>
)
}