Extensions

Custom Code

With custom code, you can create your own custom homepage to the EMR and patient portal and footer to the EMR. You have access to all the Avon backend variables and functions via Avon APIs and you can connect to your own APIs as well.

Here is an example of a custom code page that you could upload for the EMR homepage:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>Basic Example with JSX</title>
    <style>
      body {
        text-align: center;
        font-size: 33px;
        font-family: "Syne", sans-serif;
      }
    </style>
    <script src="https://cdn.tailwindcss.com"></script>
    <link rel="preconnect" href="https://fonts.googleapis.com" />
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
    <link
      href="https://fonts.googleapis.com/css2?family=Syne:wght@400..800&display=swap"
      rel="stylesheet"
    />
  </head>
  <body>
    <div id="container"></div>
    <script src="https://cdn.jsdelivr.net/npm/react@18.2.0/umd/react.production.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/react-dom@18.2.0/umd/react-dom.production.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/@remix-run/router@1.7.1/dist/router.umd.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/react-router@6.14.1/dist/umd/react-router.production.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/react-router-dom@6.14.1/dist/umd/react-router-dom.production.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/@babel/standalone@7.22.9/babel.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
    <script>
      var exports = {};
    </script>
    <script type="text/babel">
      function App() {
        const [firstName, setFirstName] = React.useState("");
        const [greeting, setGreeting] = React.useState("");
        const [pulledAppointments, setPulledAppointments] =
          React.useState(false);
        const [appointmentsList, setAppointmentsList] = React.useState([]);

        const queryString = window.location.search;
        const urlParams = new URLSearchParams(queryString);
        const id = urlParams.get("id");
        const lightBrandColor = urlParams.get("lightBrandColor");
        const darkBrandColor = urlParams.get("darkBrandColor");
        const backgroundColor = urlParams.get("backgroundColor");
        const jwt = urlParams.get("jwt");

        React.useEffect(() => {
          const today = new Date();
          const hour = today.getHours();
          const wish = `Good ${
            (hour < 12 && "Morning") || (hour < 17 && "Afternoon") || "Evening"
          }`;

          setGreeting(wish);
        });

        // Pull all appointments that include the user and start after that current time
        React.useEffect(() => {
          const listAppointmentsLink = `https://demo-api.avonhealth.com/v2/appointments`;
          const currentTime = new Date().getTime();

          const hourInMilliseconds = 60 * 60 * 1000;

          (async () => {
            const response = await axios.get(listAppointmentsLink, {
              headers: {
                // Auth 
              },
              params: {
                attendees: [id],
                status: ["scheduled", "started", "completed"],
                search_from: new Date(currentTime - hourInMilliseconds),
              },
            });
            const appointmentsList = response.data.data;

            // Filter to only the appointments that have the user as a host or attendee and end after the current time
            setAppointmentsList(appointmentsList);
            setPulledAppointments(true);
          })();
        }, [id, jwt]);

        return (
          <div
            className="w-full h-screen font-playfair-display px-10 pt-8"
            style={{ backgroundColor: `#${backgroundColor}` }}
          >
            <div className="px-2 pb-6 text-3xl  flex justify-start">
              {greeting}!
            </div>
            <div className="flex flex-col md:flex-row w-full text-sm">
              <div className="w-full mx-2 flex flex-col justify-start">
                <div
                  className={`rounded rounded-xl p-6`}
                  style={{
                    backgroundColor: `#${lightBrandColor}`,
                  }}
                >
                  <div className="py-2 flex justify-start">
                    Welcome to Avon Health! Please be reminded of our practice
                    guidelines:
                  </div>
                  <div className="py-2 flex justify-start text-start">
                    <ul className="list-disc w-full ml-8">
                      <li>
                        For any medical questions or concerns related to your
                        treatment, we ask that you use our message feature in
                        the portal. We will address your queries within 72
                        hours.
                      </li>
                      <li>
                        In case of emergency, please dial 911. All appointments
                        are conducted via video call. If you need to reschedule
                        an appointment, we ask for a notice of 48 hours.
                      </li>
                    </ul>
                  </div>
                </div>

                <div className="flex flex-row">
                  <div className="w-full md:w-1/2 cursor-pointer">
                    <a
                      target="_top"
                      href="https://portal.avonhealth.com/chat?id=none"
                    >
                      <div className="bg-white shadow shadow-lg cursor-pointer p-6 mr-3 my-3">
                        <svg
                          className="m-auto my-6"
                          xmlns="http://www.w3.org/2000/svg"
                          width="50"
                          height="50"
                          viewBox="0 0 24 24"
                        >
                          <path d="M21.598 11.456c1.466 1.193 2.402 3.01 2.402 5.044 0 3.587-2.913 6.5-6.5 6.5-.817 0-1.599-.151-2.32-.427l6.418-11.117zm-11.903 8.409l-.363.634c-1.38 2.391-4.441 3.211-6.831 1.831-2.391-1.38-3.211-4.441-1.831-6.831l6.873-11.998c.931-1.613 2.626-2.511 4.365-2.501.839.005 1.688.221 2.466.67 1.842 1.063 2.752 3.125 2.441 5.108-.069.437-.196.869-.386 1.287-.98.124-1.909.415-2.756.843l.799-1.407c.828-1.434.336-3.271-1.098-4.099-1.434-.828-3.271-.335-4.099 1.099l-3.372 5.935 3.978 2.296c-.563 1.136-.879 2.415-.879 3.767 0 1.195.247 2.334.693 3.366zm3.75 1.714c-1.49-1.192-2.445-3.025-2.445-5.079 0-3.587 2.913-6.5 6.5-6.5.837 0 1.637.158 2.372.447l-6.427 11.132z" />
                        </svg>
                        Medication Refills
                      </div>
                    </a>
                  </div>

                  <div className="w-full md:w-1/2 cursor-pointer">
                    <a
                      target="_top"
                      href="https://portal.avonhealth.com/chat?id=none"
                    >
                      <div className="bg-white shadow shadow-lg cursor-pointer p-6 mr-3 my-3">
                        <svg
                          className="m-auto my-6"
                          xmlns="http://www.w3.org/2000/svg"
                          width="50"
                          height="50"
                          viewBox="0 0 24 24"
                        >
                          <path d="M19.619 21.671c-5.038 1.227-8.711-1.861-8.711-5.167 0-3.175 3.11-5.467 6.546-5.467 3.457 0 6.546 2.309 6.546 5.467 0 1.12-.403 2.22-1.117 3.073-.029 1 .558 2.435 1.088 3.479-1.419-.257-3.438-.824-4.352-1.385zm-10.711-5.167c0-4.117 3.834-7.467 8.546-7.467.886 0 1.74.119 2.544.338-.021-4.834-4.761-8.319-9.998-8.319-5.281 0-10 3.527-10 8.352 0 1.71.615 3.391 1.705 4.695.047 1.527-.851 3.718-1.661 5.313 2.168-.391 5.252-1.258 6.649-2.115.803.196 1.576.304 2.328.363-.067-.379-.113-.765-.113-1.16z"></path>
                        </svg>
                        Message My Care Team
                      </div>
                    </a>
                  </div>
                </div>
              </div>
              <div className="w-full mx-2">
                <div
                  className="rounded rounded-lg px-4 p-2 "
                  style={{ backgroundColor: "#00000019", color: "#00000099" }}
                >
                  <div className="flex justify-center items-center text-sm">
                    My Upcoming Appointments
                  </div>
                </div>
                {!pulledAppointments && (
                  <div className="flex justify-center items-center text-sm mt-6">
                    Loading all of your upcoming appointments...
                  </div>
                )}
                {pulledAppointments && appointmentsList.length === 0 && (
                  <div>
                    <div className="flex justify-center items-center text-sm mt-6">
                      Looks like you have no upcoming appointments!
                    </div>
                    <a
                      target="_top"
                      href="https://portal.avonhealth.com/schedule/appointment-type"
                    >
                      <button
                        className="px-8 py-4 rounded rounded-full cursor-pointer mb-1 mt-6"
                        style={{
                          backgroundColor: `#${darkBrandColor}`,
                          color: "#FFF",
                        }}
                      >
                        Book an appointment
                      </button>
                    </a>
                  </div>
                )}
                {appointmentsList.map((appointment, i) => (
                  <React.Fragment key={appointment.id}>
                    <div
                      className="w-full text-sm flex flex-row justify-between items-center bg-white rounded rounded-xl shadhow shadhow-lg p-4 my-2"
                      style={{ boxShadow: `4px 4px #D3D3D3` }}
                    >
                      <div className="flex flex-row w-full">
                        <div className="flex flex-col mx-4 justify-start w-full">
                          <div className=" text-xl flex justify-start">
                            {appointment.name}
                          </div>
                          <div className="flex flex-row">
                            <div className="flex flex-row items-center my-2">
                              <svg
                                xmlns="http://www.w3.org/2000/svg"
                                width="18"
                                height="18"
                                viewBox="0 0 24 24"
                                className=""
                              >
                                <path
                                  fill={`#5D9097`}
                                  d="M20 20h-4v-4h4v4zm-6-10h-4v4h4v-4zm6 0h-4v4h4v-4zm-12 6h-4v4h4v-4zm6 0h-4v4h4v-4zm-6-6h-4v4h4v-4zm16-8v22h-24v-22h3v1c0 1.103.897 2 2 2s2-.897 2-2v-1h10v1c0 1.103.897 2 2 2s2-.897 2-2v-1h3zm-2 6h-20v14h20v-14zm-2-7c0-.552-.447-1-1-1s-1 .448-1 1v2c0 .552.447 1 1 1s1-.448 1-1v-2zm-14 2c0 .552-.447 1-1 1s-1-.448-1-1v-2c0-.552.447-1 1-1s1 .448 1 1v2z"
                                />
                              </svg>
                              <div
                                className="ml-2 mr-6"
                                style={{ color: `#5D9097` }}
                              >
                                {new Date(
                                  appointment.start_time
                                ).toLocaleDateString("en-US", {
                                  weekday: "short",
                                  month: "short",
                                  day: "numeric",
                                })}
                              </div>
                            </div>
                            <div className="flex flex-row items-center my-2">
                              <svg
                                xmlns="http://www.w3.org/2000/svg"
                                width="18"
                                height="18"
                                viewBox="0 0 24 24"
                              >
                                <path
                                  fill={`#5D9097`}
                                  d="M12 0c-6.627 0-12 5.373-12 12s5.373 12 12 12 12-5.373 12-12-5.373-12-12-12zm7 14h-8v-9h2v7h6v2z"
                                />
                              </svg>
                              <div
                                className="ml-2 mr-4"
                                style={{ color: `#5D9097` }}
                              >
                                {new Date(
                                  appointment.start_time
                                ).toLocaleTimeString([], {
                                  hour: "numeric",
                                  minute: "2-digit",
                                })}
                              </div>
                            </div>
                          </div>
                        </div>
                      </div>
                      <div className="flex flex-col space-between text-xs">
                        <a
                          target="_blank"
                          href={appointment.video_call?.join_url ?? ""}
                        >
                          <div
                            className="px-2 py-2 rounded rounded-lg cursor-pointer mb-1"
                            style={{
                              background: `#${darkBrandColor}`,
                              color: "#FFF",
                            }}
                          >
                            <div className="flex flex-row items-center justify-center">
                              <svg
                                xmlns="http://www.w3.org/2000/svg"
                                width="16"
                                height="16"
                                viewBox="0 0 24 24"
                              >
                                <path
                                  fill="#FFF"
                                  d="M16 18c0 1.104-.896 2-2 2h-12c-1.105 0-2-.896-2-2v-12c0-1.104.895-2 2-2h12c1.104 0 2 .896 2 2v12zm8-14l-6 6.223v3.554l6 6.223v-16z"
                                />
                              </svg>
                              <div className="mx-2 px-4">Join</div>
                            </div>
                          </div>
                        </a>
                      </div>
                    </div>
                  </React.Fragment>
                ))}
              </div>
            </div>
          </div>
        );
      }

      setInterval(function () {
        ReactDOM.render(<App />, document.getElementById("container"));
      }, 50);
    </script>
  </body>
</html>

Previous
AI Scribe