<commit_before>import React, { useState } from "react";

import { Register } from "../../shared/entities";
import { registerUser } from "../api";
import { FieldErrors, getErrorMessage, getFieldErrors } from "../components/FieldErrors";
import { WriteResource } from "../resource";

const isFormInvalid = (form: RegistrationForm): boolean =>
  Object.values(form).some(value => value.trim() === "") || form.password !== form.confirmPassword;

interface RegistrationForm extends Register {
  readonly confirmPassword: string;
}

const RegistrationScreen = () => {
  const [registrationResource, setRegistrationResource] = useState<
    WriteResource<RegistrationForm, void>
  >({
    data: {
      email: "",
      password: "",
      confirmPassword: "",
      name: ""
    }
  });
  const { data } = registrationResource;
  const errorMessage = getErrorMessage(registrationResource);
  const fieldErrors = getFieldErrors(registrationResource);

  const setForm = (field: keyof RegistrationForm) => (e: React.ChangeEvent<HTMLInputElement>) =>
    setRegistrationResource({
      data: { ...data, [field]: e.currentTarget.value }
    });

  return "resource" in registrationResource ? (
    <div>
      Thanks for signing up for DistrictBuilder! Please click the link in your registration email to
      continue.
    </div>
  ) : (
    <form
      onSubmit={(e: React.FormEvent) => {
        e.preventDefault();
        setRegistrationResource({ data, isPending: true });
        registerUser(
          registrationResource.data.name,
          registrationResource.data.email,
          registrationResource.data.password
        )
          .then(() => setRegistrationResource({ data, resource: void 0 }))
          .catch(errors => {
            setRegistrationResource({ data, errors });
          });
      }}
    >
      {errorMessage ? <div style={{ color: "red" }}>{errorMessage}</div> : null}
      <div>
        <input type="text" placeholder="Name" onChange={setForm("name")} />
        <FieldErrors field={"name"} errors={fieldErrors} />
      </div>
      <div>
        <input type="text" placeholder="Email" onChange={setForm("email")} />
        <FieldErrors field={"email"} errors={fieldErrors} />
      </div>
      <div>
        <input type="password" placeholder="Password" onChange={setForm("password")} />
        <FieldErrors field={"password"} errors={fieldErrors} />
      </div>
      <div>
        <input
          type="password"
          placeholder="<PASSWORD> password"
          onChange={setForm("confirmPassword")}
        />
      </div>
      <div>
        <button
          type="submit"
          disabled={
            ("isPending" in registrationResource && registrationResource.isPending) ||
            isFormInvalid(data)
          }
        >
          Register
        </button>
      </div>
    </form>
  );
};

export default RegistrationScreen;
<commit_msg>componentize registration screen<commit_after>/** @jsx jsx */
import React, { useState } from "react";
import { Button, Flex, Heading, jsx } from "theme-ui";

import { Register } from "../../shared/entities";
import { registerUser } from "../api";
import CenteredCard from "../components/CenteredCard";
import Field from "../components/Field";
import FormError from "../components/FormError";
import { WriteResource } from "../resource";

const isFormInvalid = (form: RegistrationForm): boolean =>
  Object.values(form).some(value => value.trim() === "") || form.password !== form.confirmPassword;

interface RegistrationForm extends Register {
  readonly confirmPassword: string;
}

const RegistrationScreen = () => {
  const [registrationResource, setRegistrationResource] = useState<
    WriteResource<RegistrationForm, void>
  >({
    data: {
      email: "",
      password: "",
      confirmPassword: "",
      name: ""
    }
  });
  const { data } = registrationResource;

  const setForm = (field: keyof RegistrationForm) => (e: React.ChangeEvent<HTMLInputElement>) =>
    setRegistrationResource({
      data: { ...data, [field]: e.currentTarget.value }
    });

  return "resource" in registrationResource ? (
    <div>
      Thanks for signing up for DistrictBuilder! Please click the link in your registration email to
      continue.
    </div>
  ) : (
    <CenteredCard>
      <Flex
        as="form"
        sx={{ flexDirection: "column" }}
        onSubmit={(e: React.FormEvent) => {
          e.preventDefault();
          setRegistrationResource({ data, isPending: true });
          registerUser(
            registrationResource.data.name,
            registrationResource.data.email,
            registrationResource.data.password
          )
            .then(() => setRegistrationResource({ data, resource: void 0 }))
            .catch(errors => {
              setRegistrationResource({ data, errors });
            });
        }}
      >
        <Heading as="h2" sx={{ textAlign: "left" }}>
          Create an account
        </Heading>
        <FormError resource={registrationResource} />
        <Field
          field="name"
          label="Name"
          resource={registrationResource}
          inputProps={{ onChange: setForm("name") }}
        />
        <Field
          field="email"
          label="Email"
          resource={registrationResource}
          inputProps={{ onChange: setForm("email") }}
        />
        <Field
          field="password"
          label="Password"
          resource={registrationResource}
          inputProps={{ onChange: setForm("password"), type: "password" }}
        />
        <Field
          field="confirmPassword"
          label="Confirm password"
          resource={registrationResource}
          inputProps={{ onChange: setForm("confirmPassword"), type: "password" }}
        />
        <Button
          type="submit"
          disabled={
            ("isPending" in registrationResource && registrationResource.isPending) ||
            isFormInvalid(data)
          }
        >
          Let’s go!
        </Button>
      </Flex>
    </CenteredCard>
  );
};

export default RegistrationScreen;

{'fraction_non_alphanumeric': 0.13685592385953396, 'fraction_numerical': 0.0004922874958976042, 'mean_word_length': 2.500861573808156, 'pattern_counts': {'":': 0, '<': 50, '<?xml version=': 0, '>': 66, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7546055', 'n_tokens_mistral': 1572, 'n_tokens_neox': 1572, 'n_words': 368}