summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--components/ModelForm.vue135
-rw-r--r--pages/create.vue103
-rw-r--r--pages/models/_id/edit.vue50
-rw-r--r--pages/models/_id/index.vue3
-rw-r--r--store/models.js26
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;
+ },
};