import { runtime } from "@/runtime" import { Button, Callout, Container, Flex, TextField } from "@radix-ui/themes" import { createFileRoute } from "@tanstack/react-router" import { Array, Effect, Option, Schema } from "effect" import { Component, Form } from "effect-fc" import { useContext, useSubscribables } from "effect-fc/hooks" const email = Schema.pattern( /^(?!\.)(?!.*\.\.)([A-Z0-9_+-.]*)[A-Z0-9_+-]@([A-Z0-9][A-Z0-9-]*\.)+[A-Z]{2,}$/i, { identifier: "email", title: "email", message: () => "Not an email address", }, ) const RegisterFormSchema = Schema.Struct({ email: Schema.String.pipe(email), password: Schema.String.pipe(Schema.minLength(3)), }) class RegisterForm extends Effect.Service()("RegisterForm", { scoped: Form.service({ schema: RegisterFormSchema, initialEncodedValue: { email: "", password: "" }, submit: () => Effect.void, }) }) {} class RegisterPage extends Component.makeUntraced("RegisterPage")(function*() { const form = yield* RegisterForm const emailField = Form.useField(form, ["email"]) const passwordField = Form.useField(form, ["password"]) const emailInput = yield* Form.useInput(emailField, { debounce: "200 millis" }) const passwordInput = yield* Form.useInput(passwordField, { debounce: "200 millis" }) const [canSubmit] = yield* useSubscribables(form.canSubmitSubscribable) return ( emailInput.setValue(e.target.value)} /> {Option.match(Array.head(emailInput.issues), { onSome: issue => ( {issue.message} ), onNone: () => <>, })} passwordInput.setValue(e.target.value)} /> {Option.match(Array.head(passwordInput.issues), { onSome: issue => ( {issue.message} ), onNone: () => <>, })} ) }) {} const RegisterRoute = Component.makeUntraced(function* RegisterRoute() { const context = yield* useContext(RegisterForm.Default, { finalizerExecutionMode: "fork" }) const RegisterRouteFC = yield* Effect.provide(RegisterPage, context) return }).pipe( Component.withRuntime(runtime.context) ) export const Route = createFileRoute("/form")({ component: RegisterRoute })