<div id="root"></div>
.App {
  background: #fff;
  color: #3c4151;
  font-family: "Gotham Pro", Arial, serif;
}

.download {
  position: relative;
  left: 50%;
  transform: translateX(-50%);
  text-align: center;
}

.download a {
  color: #3c4151;
  text-decoration: none;
}

.download a:hover {
  color: #1d62b4;
}

#launch {
  position: relative;
  left: 50%;
  transform: translateX(-50%);
  margin: 96px 0 64px 0;
  border: none;
  border-radius: 4px;
  color: #fff;
  display: block;
  padding: 0 64px;
  height: 44px;
  cursor: pointer;
  transition: background-color 0.2s;
  font-size: 15px;
  font-weight: 500;
  outline: 0;
  background-color: #4a90e2;
}

#launch:focus,
#launch:hover {
  background-color: #2171ce;
}

#launch:active {
  background-color: #1d62b4;
}

#raw_output {
  position: relative;
  left: 50%;
  transform: translateX(-50%);
  width: 50%;
  padding: 64px;
  margin: 32px 0;
  border: 1px solid #c1c6d1;
  border-radius: 4px;
  font-family: "Courier New", monospace;
  background-color: #3c4151;
  color: #fff;
  height: 200px;
}

.licenseAsk {
  width: 80%;
  margin: 0 auto;
  padding: 20px;
  border-radius: 4px;
  box-shadow: rgba(0, 0, 0, 0.1) 0 0 20px;
  margin-top: 20px;
  font-size: 16px;
  text-align: center;
  font-weight: bold;
}

.licenseAsk p {
  font-size: 14px;
  margin-bottom: 0;
  font-weight: normal;
}

#launch.disabled {
  background-color: gray;
  cursor: not-allowed;
}
View Compiled
import React, { Component } from "https://cdn.skypack.dev/react@^16.13.1";
import * as ReactDOM from "https://cdn.skypack.dev/react-dom@^16.13.1";
import FlatfileImporter from "https://cdn.skypack.dev/@flatfile/adapter";
import moment from "https://cdn.skypack.dev/moment";

const LICENSE_KEY = "a2f99b6a-15f1-479d-930a-527482f8d664";

class App extends Component {
  constructor(props) {
    super(props);
    this.launch = this.launch.bind(this);
    this.importer = new FlatfileImporter(LICENSE_KEY, {
      fields: [
        {
          label: "First Name",
          key: "firstName",
          alternates: ["fname"],
          description: "this is awesome",
          validators: [
            {
              validate: "required"
            }
          ]
        },
        {
          label: "Last Name",
          key: "lastName"
        },
        {
          label: "Email Address",
          key: "email",
          validators: [
            { validate: "unique" },
            {
              validate: "regex_matches",
              regex:
                "(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|\"(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21\\x23-\\x5b\\x5d-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])*\")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21-\\x5a\\x53-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])+)\\])",
              error: "Must be a valid email address"
            }
          ]
        },
        {
          label: "Country",
          key: "country",
          // type: "select",
          // options: ["CA", "US"],
          validators: [{ validate: "regex_matches", regex: "^[A-Z]{2}$" }]
        },

        {
          label: "HQ Location",
          key: "address",
          type: "select",
          options: [
            { value: "CA", label: "London, ON - Canada" },
            { value: "US", label: "NY, New York - USA" }
          ]
        },
        {
          label: "Zip Code",
          key: "zipCode",
          validators: [
            {
              validate: "regex_matches",
              regex: "^([0-9]{5})|([0-9]{5}-[0-9]{4})$"
            }
          ]
        },
        {
          label: "Create Date",
          key: "createDate"
        }
      ],
      type: "People",
      // title: "We hope you are enjoying Flatfile.",
      // allowInvalidSubmit: false,
      i18nOverrides: {
        en_US: {}
      },
      managed: true,
      allowCustom: true,
      disableManualInput: false,
      devMode: true
    });

    this.importer.setCustomer({
      userId: "1234",
      name: "John Doe",
      email: "john@doe.com",
      companyName: "Acme Inc.",
      companyId: "1234"
    });

    this.importer.registerRecordHook((record, index) => {
      const IDataHookResponse = {};

      if (record.fullName) {
        const components = record.fullName.split(" ");
        out.firstName = { value: components.shift() };
        out.lastName = { value: components.join(" ") };
      } else if (record.firstName && !record.lastName) {
        if (record.firstName.includes(" ")) {
          const components = record.firstName.split(" ");
          out.firstName = { value: components.shift() };
          out.lastName = { value: components.join(" ") };
        }
      }
      if (record.zipCode && record.zipCode.length < 5) {
        out.zipCode = {
          value: record.zipCode.padStart(5, "0"),
          info: [
            { message: "Zipcode was padded with zeroes", level: "warning" }
          ]
        };
      }
      if (record.createDate) {
        let thisDate = moment(record.createDate).format("YYYY-MM-DD");
        if (thisDate !== "Invalid date") {
          out.createDate = {
            value: moment(record.createDate).format("YYYY-MM-DD"),
            info: moment(record.createDate).isAfter(moment())
              ? [
                  {
                    message: "Date cannot be in the future",
                    level: "error"
                  }
                ]
              : []
          };
        } else {
          out.createDate = {
            info: [
              {
                message: "please check that the date is formatted YYYY-MM-DD",
                level: "error"
              }
            ]
          };
        }
      }

      if (record.country) {
        if (!countries.find((c) => c.code === record.country)) {
          const suggestion = countries.find(
            (c) =>
              c.name.toLowerCase().indexOf(record.country.toLowerCase()) !== -1
          );
          out.country = {
            value: suggestion ? suggestion.code : record.country,
            info: !suggestion
              ? [
                  {
                    message: "Country code is not valid",
                    level: "error"
                  }
                ]
              : []
          };
          out.address = {
            value: suggestion.code === "CA" ? "CA" : null
          };
        } else {
          out.country = {
            value: record.country
          };
        }
      }
      console.log(out);
      return out;
    });
    this.state = {
      results: "Your raw output will appear here."
    };
  }

  async launch() {
    if (!LICENSE_KEY) {
      return alert("Set LICENSE_KEY on Line 8 before continuing.");
    }
    try {
      let results = await this.importer.requestDataFromUser();
      console.log(results);
      this.importer.displayLoader();
      // emulate a server call, replace the timeout with an XHR request
      setTimeout(() => {
        this.importer.displaySuccess("Success!");

        this.setState({
          results: JSON.stringify(results.validData, null, 2)
        });
      }, 1500);
    } catch (e) {
      console.info(e || "window close");
    }
  }

  render() {
    return (
      <div className="App">
        {LICENSE_KEY ? null : (
          <div className="licenseAsk">
            Obtain your license key from the{" "}
            <a href="https://flatfile.io/app" target="_blank">
              Flatfile Dashboard &rarr;
            </a>
            <p>
              Once you've found it, set the <code>LICENSE_KEY</code> variable on
              Line 8 before continuing.
            </p>
          </div>
        )}
        <input
          type="button"
          id="launch"
          className={LICENSE_KEY ? null : "disabled"}
          value="Launch Importer"
          onClick={this.launch}
        />
        <div className="download">
          <a href="MOCK_DATA.csv" target="_blank" rel="noopener noreferrer">
            Download a sample csv file here
          </a>
        </div>
        <textarea id="raw_output" readOnly value={this.state.results} />
      </div>
    );
  }
}

ReactDOM.render(<App />, document.getElementById("root"));
View Compiled

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.