From 0e742a485f3fa7d35d26b05980a293b5760e8418 Mon Sep 17 00:00:00 2001
From: Mark Powers <mark@marks.kitchen>
Date: Sun, 14 Jul 2024 16:17:59 -0500
Subject: Initial commit

---
 src/pages/IndexPage.vue | 174 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 174 insertions(+)
 create mode 100644 src/pages/IndexPage.vue

(limited to 'src/pages/IndexPage.vue')

diff --git a/src/pages/IndexPage.vue b/src/pages/IndexPage.vue
new file mode 100644
index 0000000..b97d68e
--- /dev/null
+++ b/src/pages/IndexPage.vue
@@ -0,0 +1,174 @@
+<template>
+  <q-page class="row q-pa-md q-gutter-md">
+    <div>
+      <q-btn label="Log Books" color="primary" @click="books_dialog = true" size="large"/>
+    </div>
+    <q-dialog v-model="books_dialog" persistent full-width>
+      <q-card>
+        <q-form @submit.prevent="submit_books">
+          <q-card-section
+            v-for="(book, index) in books" :key="index" class="row">
+            <q-input
+              :label="book.title" type="number"
+              class="col-10"
+              v-model="book_form_data[book.id].progress"
+            ></q-input>
+            <q-toggle
+              v-model="book_form_data[book.id].completed"
+              label="Completed?"
+              class="col-2"
+            />
+          </q-card-section>
+          <q-card-section>
+            <div class="row">
+              <q-input
+                label="New book" type="text"
+                class="col-10"
+                v-model="new_book_data.name"
+              ></q-input>
+              <q-btn label="Submit" @click="submit_book()" color="primary" size="large"/>
+            </div>
+          </q-card-section>
+          <q-card-actions align="right" class="text-primary">
+            <q-btn label="Submit" type="submit" color="primary" size="large"/>
+            <q-btn flat label="Cancel" v-close-popup size="large"/>
+          </q-card-actions>
+        </q-form>
+      </q-card>
+    </q-dialog>
+    <q-form class="q-gutter-md col-11" @submit.prevent="submit">
+      <div v-for="(form, index) in forms" :key="index">
+        <template v-if="form.type === 'multiple_select'">
+          <div class="row">
+            <q-select
+              :label="form.prompt"
+              filled
+              v-model="form_data[form.prompt_id]"
+              use-input
+              use-chips
+              multiple
+              input-debounce="0"
+              :options="form.filter_options"
+              @filter="form.filterFn"
+              @new-value="form.createValue"
+              class="col-12"
+            ></q-select>
+          </div>
+        </template>
+        <template v-else-if="form.type === 'number'">
+          <q-input
+            :label="form.prompt"
+            type="number"
+            v-model="form_data[form.prompt_id]"
+          ></q-input>
+        </template>
+        <template v-else-if="form.type === 'range'">
+          <span>{{ form.prompt }}</span>
+          <q-slider
+            :min="form.extra.min"
+            :max="form.extra.max"
+            v-model="form_data[form.prompt_id]"
+          ></q-slider>
+        </template>
+        <template v-else-if="form.type === 'text'">
+          <!-- TODO autofill -->
+          <q-input
+            :label="form.prompt"
+            type="text"
+            v-model="form_data[form.prompt_id]"
+          ></q-input>
+        </template>
+        <template v-else-if="form.type === 'textarea'">
+          <q-input
+            :label="form.prompt"
+            type="text"
+            v-model="form_data[form.prompt_id]"
+          ></q-input>
+        </template>
+      </div>
+      <q-btn label="Submit" type="submit" color="primary" size="large"/>
+    </q-form>
+  </q-page>
+</template>
+
+<script>
+import { defineComponent, ref } from 'vue'
+import {
+  get_forms,
+  get_books,
+  submit_data,
+  submit_book_data,
+  create_option,
+  complete_book,
+  create_book_datapoint,
+  create_book,
+} from '../api.js'
+
+export default defineComponent({
+  name: 'IndexPage',
+  setup() {
+    let forms = ref([])
+    let form_data = ref({})
+    get_forms().then(json => {
+      forms.value = json
+      forms.value.forEach(f => {
+        if(f.type === 'multiple_select'){
+          form_data.value[f.prompt_id] = []
+          let str_options = f.extra.map(o => o.id)
+          f.filter_options = str_options
+          f.filterFn = function(val, update) {
+            update(() => {
+              if (val === '') {
+                f.filter_options = str_options
+              } else {
+                const needle = val.toLowerCase()
+                f.filter_options = str_options.filter(
+                  v => v.toLowerCase().indexOf(needle) > -1
+                )
+              }
+            })
+          }
+          f.createValue = function(val, done) {
+            if (val.length > 1) {
+              if (!str_options.includes(val)) {
+                create_option(f, val)
+                done(val, 'add-unique')
+              }
+            }
+          }
+        }
+      })
+    })
+
+    let books = ref([])
+    let book_form_data = ref({})
+    let new_book_data = ref({})
+    get_books().then(json => {
+      books.value = json
+      books.value.forEach( book => {
+        book_form_data.value[book.id] = {
+          "completed": false,
+          "progress": "",
+        }
+      })
+    })
+    let books_dialog = ref(false)
+
+    return {
+      forms, form_data,
+      books, book_form_data, new_book_data,
+      books_dialog,
+      submit_book(){
+        create_book(new_book_data.value.name)
+      },
+      submit(){
+        submit_data(forms.value, form_data.value)
+      },
+      submit_books(){
+        submit_book_data(book_form_data.value)
+        books_dialog.value = false
+      }
+    }
+  }
+})
+</script>
-- 
cgit v1.2.3

