diff options
-rw-r--r-- | components/ModelForm.vue | 135 | ||||
-rw-r--r-- | pages/create.vue | 103 | ||||
-rw-r--r-- | pages/models/_id/edit.vue | 50 | ||||
-rw-r--r-- | pages/models/_id/index.vue | 3 | ||||
-rw-r--r-- | store/models.js | 26 |
5 files changed, 215 insertions, 102 deletions
diff --git a/components/ModelForm.vue b/components/ModelForm.vue new file mode 100644 index 0000000..12821df --- /dev/null +++ b/components/ModelForm.vue @@ -0,0 +1,135 @@ +<template lang="pug"> + form.mt-3 + .shadow(class="sm:overflow-hidden sm:rounded-md") + .space-y-6.bg-white.px-4.py-5(class="sm:p-6") + div + label.block.text-sm.font-medium.text-gray-700(for="name") Name + .mt-1 + input#name.mt-1.block.w-full.rounded-md.border-gray-300.border-1.px-2.py-1( + name="name" + class="focus:border-green-500 focus:ring-green-500 sm:text-sm" + placeholder="My super project" + required + v-model="form.name" + ) + div + label.block.text-sm.font-medium.text-gray-700(for="description") Description + span.text-gray-300 (Optional) + .mt-1 + textarea#description.mt-1.block.w-full.rounded-md.border-gray-300.border-1.px-2.py-1( + name="description" rows="3" + class="focus:border-green-500 focus:ring-green-500 sm:text-sm" + placeholder="Now this is the story all about how, My life got flipped-turned upside down... " + v-model="form.description" + ) + div + label.block.text-sm.font-medium.text-gray-700(for="duration") Duration + .mt-1 + input#duration.mt-1.block.w-full.rounded-md.border-gray-300.border-1.px-2.py-1( + name="duration" + type="number" + step="0.01" + class="focus:border-green-500 focus:ring-green-500 sm:text-sm" + required + v-model="form.duration" + ) + p.text-sm.text-gray-500 Print duration in minutes + div + label.block.text-sm.font-medium.text-gray-700(for="height") Height + .mt-1 + input#height.mt-1.block.w-full.rounded-md.border-gray-300.border-1.px-2.py-1( + name="height" + type="number" + step="0.01" + class="focus:border-green-500 focus:ring-green-500 sm:text-sm" + required + v-model="form.height" + ) + p.text-sm.text-gray-500 Height in mm + div + label.block.text-sm.font-medium.text-gray-700(for="weight") Weight + .mt-1 + input#weight.mt-1.block.w-full.rounded-md.border-gray-300.border-1.px-2.py-1( + name="weight" + type="number" + step="0.01" + class="focus:border-green-500 focus:ring-green-500 sm:text-sm" + required + v-model="form.weight" + ) + p.text-sm.text-gray-500 Weight in g + div + label.block.text-sm.font-medium.text-gray-700(for="printer") Printer + span.text-gray-300 (Optional) + .mt-1 + input#printer.mt-1.block.w-full.rounded-md.border-gray-300.border-1.px-2.py-1( + name="printer" + class="focus:border-green-500 focus:ring-green-500 sm:text-sm" + placeholder="Formlabs Form 3BL" + v-model="form.printer" + ) + div + label.block.text-sm.font-medium.text-gray-700(for="material") Material + span.text-gray-300 (Optional) + .mt-1 + input#material.mt-1.block.w-full.rounded-md.border-gray-300.border-1.px-2.py-1( + name="material" + class="focus:border-green-500 focus:ring-green-500 sm:text-sm" + placeholder="PLA" + v-model="form.material" + ) + .py-3.text-right(class="sm:px-6") + button.inline-flex.justify-center.rounded-md.border.border-transparent.bg-green-600.py-2.px-4.text-sm.font-medium.text-white.shadow-sm( + type="submit" + :class="{'hover:bg-green-700 focus:outline-none focus:ring-2 focus:ring-green-500 focus:ring-offset-2': true, 'opacity-25 cursor-default': isLoading}" + :disabled="isLoading" + :readonly="isLoading" + @click="save" + ) + <svg class="animate-spin -ml-1 mr-3 h-5 w-5 text-white" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" v-if="isLoading"> + <circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle> + <path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path> + </svg> + | Save + p.text-sm.text-gray-700.mt-2(v-if="!form.id") You will add assets like images and STL/OBJ later. +</template> + +<script> +import { mapGetters } from "vuex"; + +export default { + name: "ModelForm", + props: ["data"], + data() { + return { + form: {}, + }; + }, + computed: { + ...mapGetters(["isLoading"]), + }, + created() { + if (this.data) this.form = { ...this.data }; + }, + methods: { + save(event) { + const f = this.form; + + if (f.name && f.duration && f.height && f.weight) { + const action = this.form.id ? "models/editModel" : "models/createModel"; + this.$store.dispatch(action, this.form).then((response) => { + if (response.status == 201 || response.status == 200) { + this.$toast.success("Model has been saved"); + setTimeout(() => { + window.location.href = "/models/" + response.data.id; + }, 1000); + } else { + this.$toast.error(response.data.error); + } + }); + } + event.preventDefault(); + }, + }, +}; +</script> diff --git a/pages/create.vue b/pages/create.vue index dd59ffc..8063b7b 100644 --- a/pages/create.vue +++ b/pages/create.vue @@ -2,93 +2,13 @@ .mx-auto.w-90p.py-6(class="sm:px-6 lg:px-8 md:max-w-7xl") h1.text-3xl.font-bold Create a new model p Fill all the required fieds to upload your 3D model into Verden! - form.mt-3 - .shadow(class="sm:overflow-hidden sm:rounded-md") - .space-y-6.bg-white.px-4.py-5(class="sm:p-6") - div - label.block.text-sm.font-medium.text-gray-700(for="name") Name - .mt-1 - input#name.mt-1.block.w-full.rounded-md.border-gray-300.border-1.px-2.py-1( - name="name" - class="focus:border-green-500 focus:ring-green-500 sm:text-sm" - placeholder="My super project" - required - v-model="form.name" - ) - div - label.block.text-sm.font-medium.text-gray-700(for="description") Description - span.text-gray-300 (Optional) - .mt-1 - textarea#description.mt-1.block.w-full.rounded-md.border-gray-300.border-1.px-2.py-1( - name="description" rows="3" - class="focus:border-green-500 focus:ring-green-500 sm:text-sm" - placeholder="Now this is the story all about how, My life got flipped-turned upside down... " - v-model="form.description" - ) - div - label.block.text-sm.font-medium.text-gray-700(for="duration") Duration - .mt-1 - input#duration.mt-1.block.w-full.rounded-md.border-gray-300.border-1.px-2.py-1( - name="duration" - type="number" - step="0.01" - class="focus:border-green-500 focus:ring-green-500 sm:text-sm" - required - v-model="form.duration" - ) - p.text-sm.text-gray-500 Print duration in minutes - div - label.block.text-sm.font-medium.text-gray-700(for="height") Height - .mt-1 - input#height.mt-1.block.w-full.rounded-md.border-gray-300.border-1.px-2.py-1( - name="height" - type="number" - step="0.01" - class="focus:border-green-500 focus:ring-green-500 sm:text-sm" - required - v-model="form.height" - ) - p.text-sm.text-gray-500 Height in mm - div - label.block.text-sm.font-medium.text-gray-700(for="weight") Weight - .mt-1 - input#weight.mt-1.block.w-full.rounded-md.border-gray-300.border-1.px-2.py-1( - name="weight" - type="number" - step="0.01" - class="focus:border-green-500 focus:ring-green-500 sm:text-sm" - required - v-model="form.weight" - ) - p.text-sm.text-gray-500 Weight in g - div - label.block.text-sm.font-medium.text-gray-700(for="printer") Printer - span.text-gray-300 (Optional) - .mt-1 - input#printer.mt-1.block.w-full.rounded-md.border-gray-300.border-1.px-2.py-1( - name="printer" - class="focus:border-green-500 focus:ring-green-500 sm:text-sm" - placeholder="Formlabs Form 3BL" - v-model="form.printer" - ) - div - label.block.text-sm.font-medium.text-gray-700(for="material") Material - span.text-gray-300 (Optional) - .mt-1 - input#material.mt-1.block.w-full.rounded-md.border-gray-300.border-1.px-2.py-1( - name="material" - class="focus:border-green-500 focus:ring-green-500 sm:text-sm" - placeholder="PLA" - v-model="form.material" - ) - .py-3.text-right(class="sm:px-6") - button.inline-flex.justify-center.rounded-md.border.border-transparent.bg-green-600.py-2.px-4.text-sm.font-medium.text-white.shadow-sm(type="submit", class="hover:bg-green-700 focus:outline-none focus:ring-2 focus:ring-green-500 focus:ring-offset-2" @click="save") Save - p.text-sm.text-gray-700.mt-2 You will add assets like images and STL/OBJ later. + model-form </template> <script> import ModelLoading from "@/components/ModelLoading.vue"; import ModelBoxCard from "@/components/ModelBoxCard.vue"; +import ModelForm from "@/components/ModelForm.vue"; import { mapGetters } from "vuex"; @@ -102,27 +22,8 @@ export default { ...mapGetters(["isLoading"]), ...mapGetters("auth", ["isLogged"]), }, - data() { - return { - form: {}, - }; - }, created() { if (!this.isLogged) window.location.href = "/signin?ref=/create"; }, - methods: { - save(event) { - const f = this.form; - - if (f.name && f.duration && f.height && f.weight) { - this.$store - .dispatch("models/createModel", this.form) - .then((response) => { - console.log(response); - }); - } - event.preventDefault(); - }, - }, }; </script> diff --git a/pages/models/_id/edit.vue b/pages/models/_id/edit.vue new file mode 100644 index 0000000..45755be --- /dev/null +++ b/pages/models/_id/edit.vue @@ -0,0 +1,50 @@ +<template lang="pug"> + .mx-auto.w-90p.py-6#modelpage(class="sm:px-6 lg:px-8 md:max-w-7xl") + h1.text-3xl.font-bold Edit {{ model.name }} + model-form(:data="model" v-if="model.id") +</template> + +<script> +import { mapGetters } from "vuex"; + +export default { + name: "ModelEditView", + layout: "default", + data() { + return { + model: {}, + }; + }, + head() { + return { + title: "Modifica " + this.model.name + " ยท Verden", + }; + }, + components: {}, + computed: { + ...mapGetters(["isLoading"]), + ...mapGetters("auth", ["isLogged", "me"]), + }, + async created() { + this.id = this.$route.params.id; + this.baseAPI = this.$config.api; + + if (!this.isLogged) { + window.location.href = "/models/" + this.id; + } else { + await this.$store.dispatch("auth/findMe"); + this.$store.dispatch("models/findModel", this.id).then((response) => { + if (response.status != 200) { + window.location.href = "/models"; + } else { + this.model = response.data; + if (!(this.model.author_id == this.me.id || this.me.is_staff)) { + window.location.href = "/models/" + this.id; + } + } + }); + } + }, + methods: {}, +}; +</script> diff --git a/pages/models/_id/index.vue b/pages/models/_id/index.vue index 909d5d9..1bb322e 100644 --- a/pages/models/_id/index.vue +++ b/pages/models/_id/index.vue @@ -50,8 +50,9 @@ p {{ model.description }} .mb-5.text-right(v-if="me && me.id == model.author_id") - button.inline-flex.leading-6.justify-center.rounded-md.border.border-transparent.bg-gray-600.py-2.px-4.mr-2.text-sm.font-medium.text-white.shadow-sm( + a.inline-flex.leading-6.justify-center.rounded-md.border.border-transparent.bg-gray-600.py-2.px-4.mr-2.text-sm.font-medium.text-white.shadow-sm( class="hover:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-gray-500 focus:ring-offset-2" + :href="'/models/'+model.id+'/edit'" ) <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6"> <path stroke-linecap="round" stroke-linejoin="round" d="M16.862 4.487l1.687-1.688a1.875 1.875 0 112.652 2.652L6.832 19.82a4.5 4.5 0 01-1.897 1.13l-2.685.8.8-2.685a4.5 4.5 0 011.13-1.897L16.863 4.487zm0 0L19.5 7.125" /> diff --git a/store/models.js b/store/models.js index 4f2297d..44dbb56 100644 --- a/store/models.js +++ b/store/models.js @@ -123,4 +123,30 @@ export const actions = { return res; }, + // Edit a model + async editModel({ commit, rootGetters }, payload) { + commit("loadingStatus", true, { root: true }); + let res = { status: 0, data: null }; + let api = this.$config.api; + + await fetch(`${api}/v1/models/${payload.id}`, { + method: "PUT", + headers: { + "Content-Type": "application/json", + Authorization: `Bearer ${rootGetters["auth/accessToken"]}`, + }, + body: JSON.stringify(payload), + }) + .then(async (response) => { + res.data = await response.json(); + res.status = response.status; + }) + .catch((e) => { + res.status = e.status; + }); + + commit("loadingStatus", false, { root: true }); + + return res; + }, }; |