• Operand
  • # (b)ring mi - belles.

gram:pain

> ./lib/pain_web/live/book_live.sface

Lenses
(coming soon!)


<style>
  section { margin: 1rem 0 1rem; }
  h2 { font-weight: 600; margin-bottom: 1rem; }
  h3 { font-weight: 500; }
  section p { margin-bottom: 1rem; }
  #number-people { display: flex; flex-direction: column; }
  #number-people .join { align-self: center; }
  hr { margin: 0 0 2rem; }
  ul { margin-top: 1rem; margin-bottom: 1rem; padding-left: 1rem; list-style: disc; }
  ul.services li { margin-bottom: 1rem; }
  .employ-generic { align-self: center; }
  .bypass { max-width: 40rem; margin: auto; }
  .form {
    display: grid;
    align-items: center;
    grid-template-columns: auto auto 1fr;
    grid-gap: 1rem;
    margin-bottom: 2rem;
    text-align: right;
  }
  .field { display: contents; }
  .required :deep(label)::before { content: '*'; color: #117864; }
  .field :deep(label) { grid-column: 2; }
  .field :deep(input) { grid-column: 3; }
  a.conditions { text-decoration: underline; }

  h1 {
    @apply p-6 font-semibold text-2xl text-brand w-full
    place-content-center;
    width: auto;
  }
  .accommodation {
    font-style: italic;
    max-width: 32rem;
    border-left: 4px solid #888;
    padding-left: 8px;
  }
  .accommodation a { text-decoration: underline; }
  .bill { margin: 2rem 0; }
</style>

<Page id="pain-book">
  {#if System.get_env("ORDER_BYPASS")}
    <div class="bypass"><Accion accion="Bypass" click="bypass">
      In a hurry? Use a pre-made order.
    </Accion></div>
  {/if}

  <div class="order">
  <h1><a href="https://painawayofphilly.com">Pain Away of Philly</a></h1>
  <h2>
    {if @booked, do: "Your order is booked.",
    else: "Book #{ngettext("an appointment", "appointments", @number)}"}
  </h2>

  {#if @booked}
    <ul>
      <li>on {scheduled_block(@schedule) |> Calendar.strftime("%A, %m/%d, %Y")}</li>
      <li>at {scheduled_block(@schedule) |> Calendar.strftime("%H:%M (%I:%M %P)")}</li>
    </ul>
    <hr/>
    {explain_services(assigns)}
  {#else}
  <h2>How many people are you booking for?</h2>

  <p class="accommodation">
    We can accommodate a party up to 10 people at once. If you would
    like to book an appointment for 5 or more people, please call us at
    267-690-4138, or <a href="mailto:painawayphilly@gmail.com">email us</a>.
  </p>

  <section id="number-people">
    <div class="join">
      <button class={"btn", "join-item", "btn-active": @number == 1}
        phx-value-num={1} :on-click="number" >Only me</button>
      {#for n <- [2,3,4]}
        <button class={"btn", "join-item", "btn-active": @number == n}
          phx-value-num={n} :on-click="number" >+{n-1}</button>
      {/for}
    </div>
  </section>

    {#if (map_size(@services) < @number)
    || map_size(needing_choice(@limbs)) > 0}
    <h2>How can we help you?</h2>

    <section class="join join-vertical">
      {#for class <- classed_services()["classes"]}
      <Class {=class} id={class["name"]}
        choose="choose_service" chosen={@services} {=@number}
        is_open={@open_class == class["name"]} open="open_class" />
      {#else}<p>Seems like an error has occurred.</p>{/for}
    </section>

    {#for {num, limbs} <- needing_choice(@limbs)}
      <.modal id={"choose-limb-#{num}"} show>
        <p>Customer # {num} <br/> {@services[num]}</p>
        <h2>Please choose any areas you need help on:</h2>

        <p>Once you're here, you can choose among our various massage techniques:</p>
        <ul>
          <li>Tui-Na Massage</li>
          <li>Swedish Massage</li>
          <li>Deep Tissue Massage</li>
          <li>Scalp</li>
          <li>Abdominal</li>
          <li>Lymph nodes drainage </li>
          <li>Facial </li>
        </ul>

        <button class="btn btn-primary" :on-click="done_choosing_limbs" phx-value-num={num} >
          Done
        </button>
        {#if body_areas(limbs) |> length > 0}
        <button class="btn" :on-click="clear_limbs" phx-value-num={num} >
          Clear choices
        </button>
        {/if}

        <BodyMap choose="choose_limb" number={num} chosen={@limbs[num] || []} />
      </.modal>
    {/for}

    {explain_services(assigns)}
  {#else}
    <Accion accion="Change" click="clear_services">
      <h2>You are booking:</h2>
    </Accion>
    {explain_services(assigns)}
    <hr/>

    {#if !@schedule}
      <h2>Please schedule:</h2>
      <Schedule id="schedule" schedule="schedule"
        {=employee_keys()} service_keys={service_keys(@services)} />
    {#else}
      <Accion accion="Change" click="clear_schedule" shape="">
        <h2>Your {ngettext("appointment is", "appointments are", @number)} going to be:</h2>
      </Accion>

      <ul>
        <li>on {scheduled_block(@schedule) |> Calendar.strftime("%A, %m/%d, %Y")}</li>
        <li>at {scheduled_block(@schedule) |> Calendar.strftime("%H:%M (%I:%M %P)")}</li>
      </ul>

      <hr/>

      {#if map_size(@employed) < @number}
        <Accion accion={if @display_bios, do: "Hide bio", else: "Display bio"}
          click="render_bios" shape={!@display_bios}>
          <h2>Please choose {@number} {ngettext("therapist", "therapists", @number)}:</h2>
        </Accion>

        <ServiceMap {=@services} />

        <Choices {=@number} choices={@employed} accion="employ" name="_any"
          labels={@calendars |> bookable_any(@services, @employed, &(&1))}
          enabled={@calendars |> bookable_any(@services, @employed, &(&1 > 0))}
        ><span class="employ-generic">No preference</span></Choices>

        <Choices {=@number} choices={@employed} accion="employ" name="_masc"
          labels={@calendars |> bookable_as_gender(@services, @employed, "masculine", &(&1))}
          enabled={@calendars |> bookable_as_gender(@services, @employed, "masculine", &(&1 > 0))}
        ><span class="employ-generic">Any - masculine</span></Choices>

        <Choices {=@number} choices={@employed} accion="employ" name="_fem"
          labels={@calendars |> bookable_as_gender(@services, @employed, "feminine", &(&1))}
          enabled={@calendars |> bookable_as_gender(@services, @employed, "feminine", &(&1 > 0))}
        ><span class="employ-generic">Any - feminine</span></Choices>

        {#for employee <- all_employees()}
        <Employee {=employee} id={employee["name"]} {=@display_bios}
          employ="employ" choices={@employed} {=@number}
          bookable={@calendars |> employee_bookable?(employee, @services, @employed)}
        />
        {#else}<p>Seems like an error has occurred.</p>{/for}
      {#else}
        <Accion accion="Change" click="clear_employees" shape="">
          <h2>Your therapist {ngettext("choice is", "choices are", @number)}:</h2>
        </Accion>

        <ul>{#for employee <- Map.values(@employed)}
          <li>{#case employee}
          {#match "_any"}No preference
          {#match "_masc"}Any (masculine)
          {#match "_fem"}Any (feminine)
          {#match name}{name}
          {/case}</li>
        {/for}</ul>

        <hr/>

        <h2>Nearly done; your information is needed.</h2>

        <Form for={@customer} change="customer"><div class="form">
          <Form.Field name="name" class="field required" >
            <Form.Label/>
            <Form.TextInput class="input input-bordered" value={@customer["name"]} />
          </Form.Field>

          <Form.Field name="email" class="field required">
            <Form.Label/>
            <Form.EmailInput class="input input-bordered" value={@customer["email"]} />
          </Form.Field>

          <Form.Field name="phone" class="field required">
            <Form.Label/>
            <Form.TelephoneInput class="input input-bordered" value={@customer["phone"]} />
          </Form.Field>

          <Form.Field name="reference" class="field">
            <Form.Label>How did you hear of us?</Form.Label>
            <Form.TextInput class="input input-bordered" value={@customer["reference"]} />
          </Form.Field>

          <Form.Field name="conditions" class="field required">
            <Form.Label>
              I agree to the
              <a href="#" class="conditions"
                phx-click={show_modal("conditions-modal")}
              >conditions</a>.
            </Form.Label>
            <Form.Checkbox class="toggle toggle-primary" value={@customer["conditions"]} />
          </Form.Field>
        </div></Form>

        <.modal id="conditions-modal">
          <Conditions id="conditions-render"/>
          <button class="btn btn-primary"
                phx-click={hide_modal("conditions-modal")}
          >Done</button>
        </.modal>

        <p class="accommodation">
          Please remember to be here for the beginning of your scheduled appointment.
          In case you are too late, we may be unable to honor the booking you made,
          because of scheduling collisions and high demand.
        </p>

        {#if (@services |> chosen_services |> map_size) > 0}
        <p class="bill">
          Once your appointments have ended, you'll be charged a sum of: <br/>
          ${sum_services(chosen_services(@services)) + sum_addons(@addons, @all_addons)}
          (plus taxes)
        </p>
        {/if}

        <Accion click="book" classes={["btn-primary"]}
          accion={"Book your #{ngettext("appointment", "appointments", @number)}"}
          disabled={@customer["conditions"] == "false" || @customer
          |> Map.take(~w[name phone email])
          |> Map.values() |> Enum.map(&(String.length(&1) == 0)) |> Enum.any?}
        >
          <h2>Please proceed once you're ready.</h2>
        </Accion>
      {/if}
    {/if}
  {/if}
  {/if}
</div>
</Page>