      :component-did-update #(.qrcode (js/jQuery (r/dom-node %))
                                      (clj->js options))
      :reagent-render (constantly [:div])}))
+
+; action must be a function that takes a callback for the API call as a param
+(defn action-button [options text action & [alt-text]]
+  (let [loading-text [:i.spinner.loading.icon]
+        button-text  (atom text)]
+    (fn [options text action & [alt-text alt-action]]
+      [:div.ui.button
+       (merge options
+              {:on-click (fn []
+                           (reset! button-text loading-text)
+                           (if alt-text
+                             (action #(reset! button-text alt-text))
+                             (action #(reset! button-text text))))})
+       @button-text])))
 
 
 ;; Compenents

                 @attendees-db
                 event-id
                 attendee-id)]
        (let [button-text (atom (if @button-loading?
                                  [:i.spinner.loading.icon]
                                  (if (:CheckinTime @attendee)
                                    "Check out"
                                    "Check in")))

              check-in
              (fn [attendee-id]
                (check-in-or-out PUT
                                 (str "/attendees/" attendee-id "/checkin")
                                 #(reset! button-loading? true)
                                 (fn []
                                   (prn "Checked in!")
                                   (attendees-endpoint :read nil #(reset! button-loading? false)))))

              check-out
              (fn [attendee-id]
                (check-in-or-out DELETE
                                 (str "/attendees/" attendee-id "/checkin")
                                 #(reset! button-loading? true)
                                 (fn []
                                   (prn "Checked out!")
                                   (attendees-endpoint :read nil #(reset! button-loading? false)))))

              activity-check-in
              (fn [schedule-id checked-in callback]
                (check-in-or-out PUT
                                 (str "/schedules/" schedule-id "/checkin")
                                 #()
                                 (fn []
                                   (prn "Checked in!")
                                   (schedules-endpoint :read nil #(do
                                                                    ;(reset! checked-in true)
                                                                    (callback))))))

              activity-check-out
              (fn [schedule-id checked-in callback]
                (check-in-or-out DELETE
                                 (str "/schedules/" schedule-id "/checkin")
                                 #()
                                 (fn []
                                   (prn "Checked out!")
                                   (schedules-endpoint :read nil #(do
                                                                    ;(reset! checked-in false)
                                                                    (callback))))))]
          (when (seq event)
            [:div.sixteen.wide.column
             [:div.ui.segment
              [:div
               [:div.ui.vertical.segment
                [:h1.ui.header
                 (str (:FirstName @attendee) " " (:LastName @attendee))]]
               [:div.ui.vertical.segment
                [:div.ui.divided.items
                 [:div.item

                          (when schedule-id
                            (d/entity @schedules-db schedule-id))]
                      (let
                        [checked-in (atom (not (nil? (:CheckinTime schedule))))]
                        [:tr
                         [:td {:noWrap true}
                          (when activity
