import React, { useState } from 'react' import { FormField, LoginFlow, RegistrationFlow, SettingsFlow } from '@oryd/kratos-client' import Button from '../Styled/StyledButton' import Messages from './Messages' import { camelize, methodConfig } from '../../helpers/form' import Field from './Field' import { CompleteSelfServiceLoginFlowWithPasswordMethod, CompleteSelfServiceSettingsFlowWithPasswordMethod } from '@oryd/kratos-client/api' import { TextInputProps } from 'react-native' interface Props { config?: LoginFlow | RegistrationFlow | SettingsFlow method: 'password' | 'profile' | 'link' onSubmit: (payload: T) => Promise submitLabel: string fieldTypeOverride?: ( field: FormField, props: TextInputProps ) => TextInputProps } const Form = < T extends | object | CompleteSelfServiceSettingsFlowWithPasswordMethod | CompleteSelfServiceLoginFlowWithPasswordMethod >({ config, onSubmit, submitLabel, method, fieldTypeOverride }: Props) => { if (!config) { return null } // The Form component keeps track of all the field values in the form. // To do so, we initialize const inner = methodConfig(config, method) if (!inner) { return null } const initialState: Partial = {} inner.fields.forEach((field: FormField) => { const key = field.name as keyof T initialState[key] = (field.value || '') as any // value can be string, number, ... - any is ok here! }) const [values, setValues] = useState(initialState as T) const [inProgress, setInProgress] = useState(false) const onChange = (name: string) => (value: any) => { setValues((values) => ({ ...values, [name]: value })) } const getValue = (name: string) => values[camelize(name)] const onPress = () => { setInProgress(true) onSubmit(values).then(() => { setInProgress(false) }) } return ( <> {inner.fields.map((field: FormField, k) => ( ))}