From 0e742a485f3fa7d35d26b05980a293b5760e8418 Mon Sep 17 00:00:00 2001 From: Mark Powers Date: Sun, 14 Jul 2024 16:17:59 -0500 Subject: Initial commit --- src/App.vue | 11 ++ src/api.js | 201 ++++++++++++++++++++++++++++++++++++ src/assets/quasar-logo-vertical.svg | 15 +++ src/boot/.gitkeep | 0 src/components/EssentialLink.vue | 48 +++++++++ src/css/app.css | 2 + src/layouts/MainLayout.vue | 92 +++++++++++++++++ src/pages/BookPage.vue | 69 +++++++++++++ src/pages/ErrorNotFound.vue | 31 ++++++ src/pages/FormPage.vue | 116 +++++++++++++++++++++ src/pages/IndexPage.vue | 174 +++++++++++++++++++++++++++++++ src/pages/WorkoutPage.vue | 36 +++++++ src/router/index.js | 30 ++++++ src/router/routes.js | 22 ++++ 14 files changed, 847 insertions(+) create mode 100644 src/App.vue create mode 100644 src/api.js create mode 100644 src/assets/quasar-logo-vertical.svg create mode 100644 src/boot/.gitkeep create mode 100644 src/components/EssentialLink.vue create mode 100644 src/css/app.css create mode 100644 src/layouts/MainLayout.vue create mode 100644 src/pages/BookPage.vue create mode 100644 src/pages/ErrorNotFound.vue create mode 100644 src/pages/FormPage.vue create mode 100644 src/pages/IndexPage.vue create mode 100644 src/pages/WorkoutPage.vue create mode 100644 src/router/index.js create mode 100644 src/router/routes.js (limited to 'src') diff --git a/src/App.vue b/src/App.vue new file mode 100644 index 0000000..38442ee --- /dev/null +++ b/src/App.vue @@ -0,0 +1,11 @@ + + + diff --git a/src/api.js b/src/api.js new file mode 100644 index 0000000..ecd999d --- /dev/null +++ b/src/api.js @@ -0,0 +1,201 @@ +import { Notify } from 'quasar' + +var config = { + //"api_root": "http://localhost:3000", + "api_root": "https://postgrest.marks.kitchen", + "username": "mark", + "password": "bon@ppetit", +} + +function get_headers(){ + let headers = new Headers(); + headers.set('Authorization', 'Basic ' + btoa(config.username + ":" + config.password)); + headers.set('Content-Type', 'application/json'); + return headers +} + +async function get_forms(){ + let res = await fetch(`${config.api_root}/form?order=id.asc`, + { headers: get_headers(), } + ) + return await res.json() +} + +async function get_books(completed=false){ + if(completed){ + let res = await fetch(`${config.api_root}/book?order=completed.desc`, + { headers: get_headers(), } + ) + return await res.json() + } else { + let res = await fetch(`${config.api_root}/book?completed=eq.false`, + { headers: get_headers(), } + ) + return await res.json() + } +} + +async function insert(datatype, key, value){ + let data = { + "datatype": datatype, + "key": key, + "value": value, + "created": new Date().toISOString(), + } + const response = await fetch(`${config.api_root}/datapoint`, { + method: "POST", + headers: get_headers(), + body: JSON.stringify(data), + }) + if(!response.ok){ + Notify.create({ + "type": "negative", + "message": `Issue submitting ${datatype}` + }) + } +} + +async function submit_data(forms, form_data){ + console.log(Notify) + forms.forEach(form => { + if(form_data[form.prompt_id]?.length || form.type === "range"){ + if(form.type === "multiple_select"){ + // One row per item selected + form_data[form.prompt_id].forEach(o => { + insert(form.prompt_id, o, true) + }) + } else { + // No key for numeric or text inputs + insert(form.prompt_id, undefined, form_data[form.prompt_id]) + } + } + }) + Notify.create({ + "type": "positive", + "message": `Submitted sucessfully.` + }) +} + +async function edit_book(book_data){ + let data = { + "title": book_data.title, + "in_library": book_data.in_library, + "lcc": book_data.lcc + } + const response = await fetch(`${config.api_root}/book?id=eq.${book_data.id}`, { + method: "PATCH", + headers: get_headers(), + body: JSON.stringify(data), + }) + Notify.create({ + "type": "positive", + "message": `Submitted sucessfully.` + }) +} + +async function submit_book_data(book_form_data){ + Object.keys(book_form_data).forEach( key => { + let obj = book_form_data[key] + if(obj.completed){ + complete_book(key) + } + if(obj.progress.length > 0){ + create_book_datapoint(key, obj.progress) + } + }) + Notify.create({ + "type": "positive", + "message": `Submitted books sucessfully.` + }) +} + +async function create_option(form, value){ + let data = { + "extra": form.extra.map( (o) => {return { + "id": o.id, "display": o.display, + }}) + } + data["extra"].push({ + "id": value, "display": value, + }) + const response = await fetch( + `${config.api_root}/form?id=eq.${form.id}`, { + method: "PATCH", + headers: get_headers(), + body: JSON.stringify(data), + }) +} + +async function create_book_datapoint(book_id, pages){ + const response = await fetch( + `${config.api_root}/book_datapoint`, { + method: "POST", + headers: get_headers(), + body: JSON.stringify({ + "created": new Date().toISOString(), + "book_id": book_id, + "pages": pages, + }), + }) +} + +async function complete_book(book_id){ + const response = await fetch( + `${config.api_root}/book?id=eq.${book_id}`, { + method: "PATCH", + headers: get_headers(), + body: JSON.stringify({ + "completed": true, + }), + }) +} + +async function create_book(name){ + const response = await fetch( + `${config.api_root}/book`, { + method: "POST", + headers: get_headers(), + body: JSON.stringify({ + "title": name, + "completed": false + }), + }) + Notify.create({ + "type": "positive", + "message": `Created book.` + }) +} + +async function get_book_datapoint(){ + let res = await fetch(`${config.api_root}/book_datapoint`, + { headers: get_headers(), } + ) + return await res.json() +} + +async function create_form(data){ + const response = await fetch( + `${config.api_root}/form`, { + method: "POST", + headers: get_headers(), + body: JSON.stringify(data), + }) + Notify.create({ + "type": "positive", + "message": `Created form.` + }) +} + +export { + get_forms, + submit_data, + submit_book_data, + create_option, + get_books, + get_book_datapoint, + complete_book, + create_book_datapoint, + create_book, + create_form, + edit_book, +} diff --git a/src/assets/quasar-logo-vertical.svg b/src/assets/quasar-logo-vertical.svg new file mode 100644 index 0000000..8210831 --- /dev/null +++ b/src/assets/quasar-logo-vertical.svg @@ -0,0 +1,15 @@ + + + + + + + + + \ No newline at end of file diff --git a/src/boot/.gitkeep b/src/boot/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/src/components/EssentialLink.vue b/src/components/EssentialLink.vue new file mode 100644 index 0000000..0c738cd --- /dev/null +++ b/src/components/EssentialLink.vue @@ -0,0 +1,48 @@ + + + diff --git a/src/css/app.css b/src/css/app.css new file mode 100644 index 0000000..6886f8a --- /dev/null +++ b/src/css/app.css @@ -0,0 +1,2 @@ +/* app global css */ + diff --git a/src/layouts/MainLayout.vue b/src/layouts/MainLayout.vue new file mode 100644 index 0000000..86c7276 --- /dev/null +++ b/src/layouts/MainLayout.vue @@ -0,0 +1,92 @@ + + + diff --git a/src/pages/BookPage.vue b/src/pages/BookPage.vue new file mode 100644 index 0000000..3172239 --- /dev/null +++ b/src/pages/BookPage.vue @@ -0,0 +1,69 @@ + + + diff --git a/src/pages/ErrorNotFound.vue b/src/pages/ErrorNotFound.vue new file mode 100644 index 0000000..c1c178b --- /dev/null +++ b/src/pages/ErrorNotFound.vue @@ -0,0 +1,31 @@ + + + diff --git a/src/pages/FormPage.vue b/src/pages/FormPage.vue new file mode 100644 index 0000000..c3040e2 --- /dev/null +++ b/src/pages/FormPage.vue @@ -0,0 +1,116 @@ + + + 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 @@ + + + diff --git a/src/pages/WorkoutPage.vue b/src/pages/WorkoutPage.vue new file mode 100644 index 0000000..8a7f59f --- /dev/null +++ b/src/pages/WorkoutPage.vue @@ -0,0 +1,36 @@ + + + diff --git a/src/router/index.js b/src/router/index.js new file mode 100644 index 0000000..ca3cd61 --- /dev/null +++ b/src/router/index.js @@ -0,0 +1,30 @@ +import { route } from 'quasar/wrappers' +import { createRouter, createMemoryHistory, createWebHistory, createWebHashHistory } from 'vue-router' +import routes from './routes' + +/* + * If not building with SSR mode, you can + * directly export the Router instantiation; + * + * The function below can be async too; either use + * async/await or return a Promise which resolves + * with the Router instance. + */ + +export default route(function (/* { store, ssrContext } */) { + const createHistory = process.env.SERVER + ? createMemoryHistory + : (process.env.VUE_ROUTER_MODE === 'history' ? createWebHistory : createWebHashHistory) + + const Router = createRouter({ + scrollBehavior: () => ({ left: 0, top: 0 }), + routes, + + // Leave this as is and make changes in quasar.conf.js instead! + // quasar.conf.js -> build -> vueRouterMode + // quasar.conf.js -> build -> publicPath + history: createHistory(process.env.VUE_ROUTER_BASE) + }) + + return Router +}) diff --git a/src/router/routes.js b/src/router/routes.js new file mode 100644 index 0000000..b8500ad --- /dev/null +++ b/src/router/routes.js @@ -0,0 +1,22 @@ + +const routes = [ + { + path: '/', + component: () => import('layouts/MainLayout.vue'), + children: [ + { path: '', component: () => import('pages/IndexPage.vue') }, + { path: '/books', component: () => import('pages/BookPage.vue') }, + { path: '/forms', component: () => import('pages/FormPage.vue') }, + { path: '/workouts', component: () => import('pages/WorkoutPage.vue') }, + ] + }, + + // Always leave this as last one, + // but you can also remove it + { + path: '/:catchAll(.*)*', + component: () => import('pages/ErrorNotFound.vue') + } +] + +export default routes -- cgit v1.2.3