import { UserAttributeSpec, validators } from "anastasis-core"; import { isAfter, parse } from "date-fns"; import { h, VNode } from "preact"; import { useState } from "preact/hooks"; import { DateInput } from "../../components/fields/DateInput"; import { PhoneNumberInput } from "../../components/fields/NumberInput"; import { TextInput } from "../../components/fields/TextInput"; import { useAnastasisContext } from "../../context/anastasis"; import { AnastasisClientFrame, withProcessLabel } from "./index"; export function AttributeEntryScreen(): VNode { const reducer = useAnastasisContext(); const state = reducer?.currentReducerState; const currentIdentityAttributes = state && "identity_attributes" in state ? state.identity_attributes || {} : {}; const [attrs, setAttrs] = useState>( currentIdentityAttributes, ); if (!reducer) { return
no reducer in context
; } if ( !reducer.currentReducerState || !("required_attributes" in reducer.currentReducerState) ) { return
invalid state
; } const reqAttr = reducer.currentReducerState.required_attributes || []; let hasErrors = false; const fieldList: VNode[] = reqAttr.map((spec, i: number) => { const value = attrs[spec.name]; const error = checkIfValid(value, spec); hasErrors = hasErrors || error !== undefined; return ( setAttrs({ ...attrs, [spec.name]: v })} spec={spec} errorMessage={error} value={value} /> ); }); return ( reducer.transition("enter_user_attributes", { identity_attributes: attrs, }) } >
{fieldList}

This personal information will help to locate your secret.

This stays private

The information you have entered here:

  • Will be hashed, and therefore unreadable
  • The non-hashed version is not shared
); } interface AttributeEntryFieldProps { isFirst: boolean; value: string; setValue: (newValue: string) => void; spec: UserAttributeSpec; errorMessage: string | undefined; } const possibleBirthdayYear: Array = []; for (let i = 0; i < 100; i++) { possibleBirthdayYear.push(2020 - i); } function AttributeEntryField(props: AttributeEntryFieldProps): VNode { return (
{props.spec.type === "date" && } {props.spec.type === 'number' && } {props.spec.type === "string" && ( )}
This stays private
); } const YEAR_REGEX = /^[0-9]+-[0-9]+-[0-9]+$/; function checkIfValid( value: string, spec: UserAttributeSpec, ): string | undefined { const pattern = spec["validation-regex"]; if (pattern) { const re = new RegExp(pattern); if (!re.test(value)) return "The value is invalid"; } const logic = spec["validation-logic"]; if (logic) { const func = (validators as any)[logic]; if (func && typeof func === "function" && !func(value)) return "Please check the value"; } const optional = spec.optional; if (!optional && !value) { return "This value is required"; } if ("date" === spec.type) { if (!YEAR_REGEX.test(value)) { return "The date doesn't follow the format"; } try { const v = parse(value, "yyyy-MM-dd", new Date()); if (Number.isNaN(v.getTime())) { return "Some numeric values seems out of range for a date"; } if ("birthdate" === spec.name && isAfter(v, new Date())) { return "A birthdate cannot be in the future"; } } catch (e) { return "Could not parse the date"; } } return undefined; }