further refactoring
This commit is contained in:
@@ -12,8 +12,7 @@
|
||||
type="password"
|
||||
label="New Password"
|
||||
required
|
||||
:error="formData.password.error"
|
||||
@blur="fieldValidate(formData.password)" />
|
||||
:error="formData.password.error" />
|
||||
<SMFormFooter>
|
||||
<template v-if="!isSuccessful" #left>
|
||||
<SMButton
|
||||
@@ -42,11 +41,6 @@ import SMMessage from "../SMMessage.vue";
|
||||
import SMButton from "../SMButton.vue";
|
||||
import SMFormFooter from "../SMFormFooter.vue";
|
||||
import SMInput from "../SMInput.vue";
|
||||
import {
|
||||
useValidation,
|
||||
isValidated,
|
||||
fieldValidate,
|
||||
} from "../../helpers/validation";
|
||||
|
||||
const formData = reactive({
|
||||
password: {
|
||||
@@ -78,21 +72,19 @@ const handleConfirm = async () => {
|
||||
if (isSuccessful.value == true) {
|
||||
closeDialog(true);
|
||||
} else {
|
||||
if (isValidated(formData)) {
|
||||
try {
|
||||
formLoading.value = true;
|
||||
await api.put({
|
||||
url: `/users/${userStore.id}`,
|
||||
body: {
|
||||
password: formData.password.value,
|
||||
},
|
||||
});
|
||||
try {
|
||||
formLoading.value = true;
|
||||
await api.put({
|
||||
url: `/users/${userStore.id}`,
|
||||
body: {
|
||||
password: formData.password.value,
|
||||
},
|
||||
});
|
||||
|
||||
isSuccessful.value = true;
|
||||
} catch (err) {
|
||||
formData.password.error =
|
||||
err.json?.message || "An unexpected error occurred";
|
||||
}
|
||||
isSuccessful.value = true;
|
||||
} catch (err) {
|
||||
formData.password.error =
|
||||
err.json?.message || "An unexpected error occurred";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -114,6 +106,4 @@ onMounted(() => {
|
||||
onUnmounted(() => {
|
||||
document.removeEventListener("keyup", eventKeyUp);
|
||||
});
|
||||
|
||||
useValidation(formData);
|
||||
</script>
|
||||
|
||||
@@ -32,7 +32,7 @@ import SMMessage from "../components/SMMessage.vue";
|
||||
import SMPanelList from "../components/SMPanelList.vue";
|
||||
import SMPanel from "../components/SMPanel.vue";
|
||||
import SMPage from "../components/SMPage.vue";
|
||||
import { timestampUtcToLocal } from "../helpers/common";
|
||||
import { timestampUtcToLocal } from "../helpers/datetime";
|
||||
|
||||
const formMessage = reactive({
|
||||
icon: "",
|
||||
|
||||
@@ -25,7 +25,8 @@
|
||||
import { ref, computed } from "vue";
|
||||
import { useRoute } from "vue-router";
|
||||
import SMPageError from "../components/SMPageError.vue";
|
||||
import { fullMonthString, timestampUtcToLocal } from "../helpers/common";
|
||||
import { fullMonthString } from "../helpers/common";
|
||||
import { timestampUtcToLocal } from "../helpers/datetime";
|
||||
import { useApplicationStore } from "../store/ApplicationStore";
|
||||
import { api } from "../helpers/api";
|
||||
import SMPage from "../components/SMPage.vue";
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<SMRow>
|
||||
<SMDialog :loading="formLoading">
|
||||
<h1>{{ page_title }}</h1>
|
||||
<SMForm v-model="form" @submit="handleSubmit">
|
||||
<SMForm :model-value="form" @submit="handleSubmit">
|
||||
<SMRow>
|
||||
<SMColumn><SMInput control="title" /></SMColumn>
|
||||
</SMRow>
|
||||
@@ -132,7 +132,6 @@ import SMPage from "../../components/SMPage.vue";
|
||||
import SMForm from "../../components/SMForm.vue";
|
||||
|
||||
const route = useRoute();
|
||||
const formLoading = ref(false);
|
||||
const page_title = route.params.id ? "Edit Event" : "Create New Event";
|
||||
const pageError = ref(200);
|
||||
|
||||
|
||||
@@ -51,12 +51,8 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, watch, reactive } from "vue";
|
||||
import EasyDataTable from "vue3-easy-data-table";
|
||||
import axios from "axios";
|
||||
import {
|
||||
relativeDate,
|
||||
timestampUtcToLocal,
|
||||
toParamString,
|
||||
} from "../../helpers/common";
|
||||
import { api } from "../../helpers/api";
|
||||
import { relativeDate, timestampUtcToLocal } from "../../helpers/datetime";
|
||||
import { useRouter } from "vue-router";
|
||||
import SMDialogConfirm from "../../components/dialogs/SMDialogConfirm.vue";
|
||||
import { openDialog } from "vue3-promise-dialog";
|
||||
@@ -65,7 +61,6 @@ import SMButton from "../../components/SMButton.vue";
|
||||
import { debounce } from "../../helpers/common";
|
||||
import SMHeading from "../../components/SMHeading.vue";
|
||||
import SMMessage from "../../components/SMMessage.vue";
|
||||
import { restParseErrors } from "../../helpers/validation";
|
||||
import SMLoadingIcon from "../../components/SMLoadingIcon.vue";
|
||||
|
||||
const router = useRouter();
|
||||
@@ -120,8 +115,9 @@ const loadFromServer = async () => {
|
||||
params["title"] = search.value;
|
||||
}
|
||||
|
||||
let res = await axios.get(`events${toParamString(params)}`, {
|
||||
redirect: false,
|
||||
let res = await api.get({
|
||||
url: "/events",
|
||||
params: params,
|
||||
});
|
||||
|
||||
if (!res.data.events) {
|
||||
@@ -193,7 +189,7 @@ const handleDelete = async (item) => {
|
||||
|
||||
if (result == true) {
|
||||
try {
|
||||
await axios.delete(`events${item.id}`);
|
||||
await api.delete(`events${item.id}`);
|
||||
loadFromServer();
|
||||
|
||||
formMessage.message = "Post deleted successfully";
|
||||
|
||||
@@ -1,31 +1,21 @@
|
||||
<template>
|
||||
<SMContainer :page-error="pageError" permission="admin/media">
|
||||
<SMPage :page-error="pageError" permission="admin/media">
|
||||
<SMRow>
|
||||
<SMDialog
|
||||
:loading="formLoading"
|
||||
:loading_message="formLoadingMessage">
|
||||
<SMDialog>
|
||||
<h1>{{ page_title }}</h1>
|
||||
<SMMessage
|
||||
v-if="formMessage.message"
|
||||
:icon="formMessage.icon"
|
||||
:type="formMessage.type"
|
||||
:message="formMessage.message" />
|
||||
<form @submit.prevent="handleSubmit">
|
||||
<SMForm
|
||||
:model-value="form"
|
||||
:loading_message="formLoadingMessage"
|
||||
@submit="handleSubmit">
|
||||
<SMRow>
|
||||
<SMColumn>
|
||||
<SMInput
|
||||
v-model="formData.file.value"
|
||||
type="file"
|
||||
label="File"
|
||||
required
|
||||
:error="formData.file.error"
|
||||
@blur="fieldValidate(formData.file)" />
|
||||
<SMInput control="file" type="file" />
|
||||
</SMColumn>
|
||||
</SMRow>
|
||||
<SMRow>
|
||||
<SMColumn>
|
||||
<SMInput
|
||||
v-model="formData.url.value"
|
||||
contorl="url"
|
||||
type="link"
|
||||
label="URL"
|
||||
:href="formData.url.value" />
|
||||
@@ -65,10 +55,10 @@
|
||||
<SMButton type="submit" label="Save" />
|
||||
</SMColumn>
|
||||
</SMRow>
|
||||
</form>
|
||||
</SMForm>
|
||||
</SMDialog>
|
||||
</SMRow>
|
||||
</SMContainer>
|
||||
</SMPage>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
@@ -76,133 +66,94 @@ import { ref, reactive, computed } from "vue";
|
||||
import SMInput from "../../components/SMInput.vue";
|
||||
import SMButton from "../../components/SMButton.vue";
|
||||
import SMDialog from "../../components/SMDialog.vue";
|
||||
import SMMessage from "../../components/SMMessage.vue";
|
||||
import axios from "axios";
|
||||
import {
|
||||
useValidation,
|
||||
isValidated,
|
||||
fieldValidate,
|
||||
restParseErrors,
|
||||
} from "../../helpers/validation";
|
||||
import SMForm from "../../components/SMForm.vue";
|
||||
import SMPage from "../../components/SMPage.vue";
|
||||
import { api } from "../../helpers/api";
|
||||
import { FormObject, FormControl } from "../../helpers/form";
|
||||
import { And, Required, FileSize } from "../../helpers/validate";
|
||||
import { useRoute } from "vue-router";
|
||||
import { bytesReadable } from "../../helpers/common";
|
||||
import { useRouter } from "vue-router";
|
||||
|
||||
const router = useRouter();
|
||||
const pageError = ref(200);
|
||||
const formLoading = ref(false);
|
||||
const formLoadingMessage = ref("");
|
||||
|
||||
const route = useRoute();
|
||||
const page_title = route.params.id ? "Edit Media" : "Upload Media";
|
||||
|
||||
const formMessage = reactive({
|
||||
icon: "",
|
||||
type: "",
|
||||
message: "",
|
||||
});
|
||||
const formData = reactive({
|
||||
file: {
|
||||
value: null,
|
||||
error: "",
|
||||
rules: {
|
||||
required: true,
|
||||
required_message: "A file is required",
|
||||
fileSize: 5242880,
|
||||
fileSize_message: "The file is larger than %b",
|
||||
},
|
||||
},
|
||||
url: {
|
||||
value: "",
|
||||
error: "",
|
||||
},
|
||||
mime: {
|
||||
value: "",
|
||||
error: "",
|
||||
},
|
||||
size: {
|
||||
value: "",
|
||||
error: "",
|
||||
},
|
||||
permission: {
|
||||
value: "",
|
||||
error: "",
|
||||
},
|
||||
const form = reactive(
|
||||
FormObject({
|
||||
file: FormControl("", And([Required(), FileSize(5242880)])),
|
||||
permission: FormControl(),
|
||||
})
|
||||
);
|
||||
|
||||
const fileData = reactive({
|
||||
url: "",
|
||||
mime: "",
|
||||
size: 0,
|
||||
});
|
||||
|
||||
const handleLoad = async () => {
|
||||
formLoading.value = true;
|
||||
formMessage.type = "error";
|
||||
formMessage.icon = "fa-solid fa-circle-exclamation";
|
||||
formMessage.message = "";
|
||||
|
||||
if (route.params.id) {
|
||||
try {
|
||||
let res = await axios.get(`media/${route.params.id}`);
|
||||
let res = await api.get(`media/${route.params.id}`);
|
||||
|
||||
console.log(res.data.media);
|
||||
|
||||
formData.file.value = res.data.media.name;
|
||||
formData.permission.value = res.data.media.permission;
|
||||
formData.url.value = res.data.media.url;
|
||||
formData.mime.value = res.data.media.mime;
|
||||
formData.size.value = res.data.media.size;
|
||||
form.file.value = res.data.media.name;
|
||||
form.permission.value = res.data.media.permission;
|
||||
fileData.url = res.data.media.url;
|
||||
fileData.mime = res.data.media.mime;
|
||||
fileData.size = res.data.media.size;
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
restParseErrors(formData, [formMessage, "message"], err);
|
||||
form.apiErrors(err);
|
||||
}
|
||||
}
|
||||
|
||||
formLoading.value = false;
|
||||
form.loading(false);
|
||||
};
|
||||
|
||||
const handleSubmit = async () => {
|
||||
formLoading.value = true;
|
||||
formMessage.type = "error";
|
||||
formMessage.icon = "fa-solid fa-circle-exclamation";
|
||||
formMessage.message = "";
|
||||
|
||||
try {
|
||||
if (isValidated(formData)) {
|
||||
let res = null;
|
||||
// let data = {
|
||||
// title: formData.title.value,
|
||||
// slug: formData.slug.value,
|
||||
// user_id: formData.user_id.value,
|
||||
// content: formData.content.value
|
||||
// }
|
||||
let res = null;
|
||||
// let data = {
|
||||
// title: formData.title.value,
|
||||
// slug: formData.slug.value,
|
||||
// user_id: formData.user_id.value,
|
||||
// content: formData.content.value
|
||||
// }
|
||||
|
||||
// if(route.params.id) {
|
||||
// res = await axios.put(`posts/${route.params.id}`, data);
|
||||
// } else {
|
||||
// res = await axios.post(`posts`, data);
|
||||
// }
|
||||
// if(route.params.id) {
|
||||
// res = await axios.put(`posts/${route.params.id}`, data);
|
||||
// } else {
|
||||
// res = await axios.post(`posts`, data);
|
||||
// }
|
||||
|
||||
let submitFormData = new FormData();
|
||||
if (formData.file.value instanceof File) {
|
||||
submitFormData.append("file", formData.file.value);
|
||||
}
|
||||
|
||||
submitFormData.append("permission", formData.permission.value);
|
||||
|
||||
await axios.post("media", submitFormData, {
|
||||
headers: {
|
||||
"Content-Type": "multipart/form-data",
|
||||
},
|
||||
onUploadProgress: (progressEvent) =>
|
||||
(formLoadingMessage.value = `Uploading Files ${Math.floor(
|
||||
(progressEvent.loaded / progressEvent.total) * 100
|
||||
)}%`),
|
||||
});
|
||||
|
||||
formMessage.type = "success";
|
||||
formMessage.message = "Your details have been updated";
|
||||
let submitFormData = new FormData();
|
||||
if (form.file.value instanceof File) {
|
||||
submitFormData.append("file", form.file.value);
|
||||
}
|
||||
|
||||
submitFormData.append("permission", form.permission.value);
|
||||
|
||||
await api.post({
|
||||
url: "/media",
|
||||
body: submitFormData,
|
||||
headers: {
|
||||
"Content-Type": "multipart/form-data",
|
||||
},
|
||||
progress: (progressEvent) =>
|
||||
(formLoadingMessage.value = `Uploading Files ${Math.floor(
|
||||
(progressEvent.loaded / progressEvent.total) * 100
|
||||
)}%`),
|
||||
});
|
||||
|
||||
form.message("Your details have been updated", "success");
|
||||
} catch (err) {
|
||||
restParseErrors(formData, [formMessage, "message"], err);
|
||||
form.apiErrors(err);
|
||||
}
|
||||
|
||||
formLoading.value = false;
|
||||
form.loading(false);
|
||||
};
|
||||
|
||||
const handleDelete = async () => {
|
||||
@@ -221,7 +172,7 @@ const handleDelete = async () => {
|
||||
|
||||
if (result) {
|
||||
try {
|
||||
await axios.delete(`media/${item.id}`);
|
||||
await api.delete(`media/${item.id}`);
|
||||
router.push({ name: "media" });
|
||||
} catch (err) {
|
||||
alert(
|
||||
@@ -233,9 +184,8 @@ const handleDelete = async () => {
|
||||
};
|
||||
|
||||
const computedFileSize = computed(() => {
|
||||
return bytesReadable(formData.size.value);
|
||||
return bytesReadable(fileData.size);
|
||||
});
|
||||
|
||||
useValidation(formData);
|
||||
handleLoad();
|
||||
</script>
|
||||
|
||||
@@ -54,8 +54,8 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, watch } from "vue";
|
||||
import EasyDataTable from "vue3-easy-data-table";
|
||||
import axios from "axios";
|
||||
import { relativeDate, toParamString } from "../../helpers/common";
|
||||
import { api } from "../../helpers/api";
|
||||
import { relativeDate } from "../../helpers/datetime";
|
||||
import { useRouter } from "vue-router";
|
||||
import DialogConfirm from "../../components/dialogs/SMDialogConfirm.vue";
|
||||
import { openDialog } from "vue3-promise-dialog";
|
||||
@@ -122,8 +122,9 @@ const loadFromServer = async () => {
|
||||
params["title"] = search.value;
|
||||
}
|
||||
|
||||
let res = await axios.get(`media${toParamString(params)}`, {
|
||||
redirect: false,
|
||||
let res = await api.get({
|
||||
url: "/media",
|
||||
params: params,
|
||||
});
|
||||
if (!res.data.media) {
|
||||
throw new Error("The server is currently not available");
|
||||
@@ -199,7 +200,7 @@ const handleDelete = async (item) => {
|
||||
|
||||
if (result) {
|
||||
try {
|
||||
await axios.delete(`media/${item.id}`);
|
||||
await api.delete(`media/${item.id}`);
|
||||
loadFromServer();
|
||||
} catch (err) {
|
||||
alert(
|
||||
|
||||
@@ -1,50 +1,26 @@
|
||||
<template>
|
||||
<SMContainer :page-error="pageError" permission="admin/posts">
|
||||
<SMPage :page-error="pageError" permission="admin/posts">
|
||||
<SMRow>
|
||||
<SMDialog :loading="formLoading">
|
||||
<SMDialog>
|
||||
<h1>{{ page_title }}</h1>
|
||||
<SMMessage
|
||||
v-if="formMessage.message"
|
||||
:icon="formMessage.icon"
|
||||
:type="formMessage.type"
|
||||
:message="formMessage.message" />
|
||||
<form @submit.prevent="submit">
|
||||
<SMForm :model-value="form" @submit="handleSubmit">
|
||||
<SMRow>
|
||||
<SMColumn
|
||||
><SMInput
|
||||
v-model="formData.title.value"
|
||||
label="Title"
|
||||
required
|
||||
:error="formData.title.error"
|
||||
@blur="
|
||||
fieldValidate(formData.title);
|
||||
updateSlug();
|
||||
"
|
||||
><SMInput control="title" @blur="updateSlug()"
|
||||
/></SMColumn>
|
||||
</SMRow>
|
||||
<SMRow>
|
||||
<SMColumn
|
||||
><SMInput
|
||||
v-model="formData.slug.value"
|
||||
label="Slug"
|
||||
required
|
||||
:error="formData.slug.error"
|
||||
@blur="fieldValidate(formData.slug)"
|
||||
/></SMColumn>
|
||||
<SMColumn><SMInput control="slug" /></SMColumn>
|
||||
<SMColumn>
|
||||
<SMDatepicker
|
||||
v-model="formData.publish_at.value"
|
||||
label="Publish Date"
|
||||
:error="formData.publish_at.error"
|
||||
@blur="
|
||||
fieldValidate(formData.publish_at)
|
||||
"></SMDatepicker>
|
||||
control="publish_at"
|
||||
label="Publish Date"></SMDatepicker>
|
||||
</SMColumn>
|
||||
</SMRow>
|
||||
<SMRow>
|
||||
<SMColumn>
|
||||
<SMInput
|
||||
v-model="formData.hero.value"
|
||||
control="hero"
|
||||
type="media"
|
||||
label="Hero image"
|
||||
required />
|
||||
@@ -53,16 +29,15 @@
|
||||
<SMRow>
|
||||
<SMColumn>
|
||||
<SMSelect
|
||||
v-model="formData.user_id.value"
|
||||
control="user_id"
|
||||
label="Created By"
|
||||
required
|
||||
:options="formData.user_id.options"></SMSelect>
|
||||
:options="authors"></SMSelect>
|
||||
</SMColumn>
|
||||
</SMRow>
|
||||
<SMRow>
|
||||
<SMColumn>
|
||||
<SMEditor
|
||||
v-model:srcContent="formData.content.value"
|
||||
v-model:srcContent="form.content.value"
|
||||
:mime-types="[
|
||||
'image/png',
|
||||
'image/jpeg',
|
||||
@@ -78,93 +53,54 @@
|
||||
</template>
|
||||
</SMFormFooter>
|
||||
</SMRow>
|
||||
</form>
|
||||
</SMForm>
|
||||
</SMDialog>
|
||||
</SMRow>
|
||||
</SMContainer>
|
||||
</SMPage>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive } from "vue";
|
||||
import { api } from "../../helpers/api";
|
||||
import { FormObject, FormControl } from "../../helpers/form";
|
||||
import { And, Required, Min, DateTime } from "../../helpers/validate";
|
||||
import {
|
||||
timestampLocalToUtc,
|
||||
timestampUtcToLocal,
|
||||
} from "../../helpers/datetime";
|
||||
import { useUserStore } from "../../store/UserStore";
|
||||
import { useRoute } from "vue-router";
|
||||
import SMInput from "../../components/SMInput.vue";
|
||||
import SMButton from "../../components/SMButton.vue";
|
||||
import SMDialog from "../../components/SMDialog.vue";
|
||||
import SMSelect from "../../components/SMSelect.vue";
|
||||
import SMDatepicker from "../../components/SMDatePicker.vue";
|
||||
import SMEditor from "../../components/SMEditor.vue";
|
||||
import SMMessage from "../../components/SMMessage.vue";
|
||||
import axios from "axios";
|
||||
import {
|
||||
useValidation,
|
||||
isValidated,
|
||||
fieldValidate,
|
||||
restParseErrors,
|
||||
} from "../../helpers/validation";
|
||||
import { useRoute } from "vue-router";
|
||||
import { useUserStore } from "../../store/UserStore";
|
||||
import SMPage from "../../components/SMPage.vue";
|
||||
import SMForm from "../../components/SMForm.vue";
|
||||
import SMFormFooter from "../../components/SMFormFooter.vue";
|
||||
import { timestampLocalToUtc, timestampUtcToLocal } from "../../helpers/common";
|
||||
|
||||
const route = useRoute();
|
||||
const formLoading = ref(false);
|
||||
const userStore = useUserStore();
|
||||
const page_title = route.params.id ? "Edit Post" : "Create New Post";
|
||||
const pageError = ref(200);
|
||||
const authors = ref({});
|
||||
|
||||
const formMessage = reactive({
|
||||
icon: "",
|
||||
type: "",
|
||||
message: "",
|
||||
});
|
||||
const formData = reactive({
|
||||
title: {
|
||||
value: "",
|
||||
error: "",
|
||||
rules: {
|
||||
required: true,
|
||||
required_message: "A post title is required",
|
||||
min: 8,
|
||||
min_message: "Your post title should be at least 8 letters long",
|
||||
},
|
||||
},
|
||||
slug: {
|
||||
value: "",
|
||||
error: "",
|
||||
rules: {
|
||||
required: true,
|
||||
required_message: "A slug is required",
|
||||
min: 6,
|
||||
min_message: "The slug least 6 letters long",
|
||||
},
|
||||
},
|
||||
publish_at: {
|
||||
value: null,
|
||||
error: "",
|
||||
rules: {
|
||||
datetime: true,
|
||||
},
|
||||
},
|
||||
hero: {
|
||||
value: "",
|
||||
error: "",
|
||||
},
|
||||
user_id: {
|
||||
options: {},
|
||||
value: userStore.id,
|
||||
error: "",
|
||||
},
|
||||
content: {
|
||||
value: "",
|
||||
error: "",
|
||||
},
|
||||
});
|
||||
|
||||
useValidation(formData);
|
||||
const form = reactive(
|
||||
FormObject({
|
||||
title: FormControl("", And([Required(), Min(8)])),
|
||||
slug: FormControl("", And([Required(), Min(6)])),
|
||||
publish_at: FormControl("", DateTime()),
|
||||
hero: FormControl(),
|
||||
user_id: FormControl(userStore.id),
|
||||
content: FormControl(),
|
||||
})
|
||||
);
|
||||
|
||||
const updateSlug = async () => {
|
||||
if (formData.slug.value == "" && formData.title.value != "") {
|
||||
if (form.slug.value == "" && form.title.value != "") {
|
||||
let idx = 0;
|
||||
let pre_slug = formData.title.value
|
||||
let pre_slug = form.title.value
|
||||
.toLowerCase()
|
||||
.replace(/[^a-z0-9]/gim, "-")
|
||||
.replace(/-+/g, "-")
|
||||
@@ -178,12 +114,17 @@ const updateSlug = async () => {
|
||||
slug += "-" + idx;
|
||||
}
|
||||
|
||||
await axios.get(`posts?slug=${slug}`);
|
||||
await api.get({
|
||||
url: "/posts",
|
||||
params: {
|
||||
slug: slug,
|
||||
},
|
||||
});
|
||||
idx++;
|
||||
} catch (error) {
|
||||
if (error.response.status == 404) {
|
||||
if (formData.slug.value == "") {
|
||||
formData.slug.value = slug;
|
||||
if (error.status == 404) {
|
||||
if (form.slug.value == "") {
|
||||
form.slug.value = slug;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -194,27 +135,24 @@ const updateSlug = async () => {
|
||||
};
|
||||
|
||||
const loadData = async () => {
|
||||
formLoading.value = true;
|
||||
formMessage.type = "error";
|
||||
formMessage.icon = "fa-solid fa-circle-exclamation";
|
||||
formMessage.message = "";
|
||||
form.loading(true);
|
||||
|
||||
if (route.params.id) {
|
||||
try {
|
||||
let res = await axios.get("posts/" + route.params.id);
|
||||
let res = await api.get("/posts/" + route.params.id);
|
||||
if (!res.data.post) {
|
||||
throw new Error("The server is currently not available");
|
||||
}
|
||||
|
||||
formData.title.value = res.data.post.title;
|
||||
formData.slug.value = res.data.post.slug;
|
||||
formData.user_id.value = res.data.post.user_id;
|
||||
formData.content.value = res.data.post.content;
|
||||
formData.publish_at.value = res.data.post.publish_at
|
||||
form.title.value = res.data.post.title;
|
||||
form.slug.value = res.data.post.slug;
|
||||
form.user_id.value = res.data.post.user_id;
|
||||
form.content.value = res.data.post.content;
|
||||
form.publish_at.value = res.data.post.publish_at
|
||||
? timestampUtcToLocal(res.data.post.publish_at)
|
||||
: "";
|
||||
formData.content.value = res.data.post.content;
|
||||
formData.hero.value = res.data.post.hero;
|
||||
form.content.value = res.data.post.content;
|
||||
form.hero.value = res.data.post.hero;
|
||||
} catch (err) {
|
||||
pageError.value = err.response.status;
|
||||
}
|
||||
@@ -223,33 +161,32 @@ const loadData = async () => {
|
||||
formLoading.value = false;
|
||||
};
|
||||
|
||||
const submit = async () => {
|
||||
const handleSubmit = async () => {
|
||||
try {
|
||||
if (isValidated(formData)) {
|
||||
let data = {
|
||||
title: formData.title.value,
|
||||
slug: formData.slug.value,
|
||||
publish_at: timestampLocalToUtc(formData.publish_at.value),
|
||||
user_id: formData.user_id.value,
|
||||
content: formData.content.value,
|
||||
hero: formData.hero.value,
|
||||
};
|
||||
let data = {
|
||||
title: form.title.value,
|
||||
slug: form.slug.value,
|
||||
publish_at: timestampLocalToUtc(form.publish_at.value),
|
||||
user_id: form.user_id.value,
|
||||
content: form.content.value,
|
||||
hero: form.hero.value,
|
||||
};
|
||||
|
||||
if (route.params.id) {
|
||||
await axios.put(`posts/${route.params.id}`, data);
|
||||
} else {
|
||||
await axios.post(`posts`, data);
|
||||
}
|
||||
|
||||
formMessage.type = "success";
|
||||
formMessage.message = "Your details have been updated";
|
||||
if (route.params.id) {
|
||||
await api.put({
|
||||
url: `/posts/${route.params.id}`,
|
||||
body: data,
|
||||
});
|
||||
} else {
|
||||
await api.post({
|
||||
url: "/posts",
|
||||
body: data,
|
||||
});
|
||||
}
|
||||
|
||||
form.message("Your details have been updated", "success");
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
formMessage.icon = "";
|
||||
formMessage.type = "error";
|
||||
formMessage.message = "";
|
||||
restParseErrors(formData, [formMessage, "message"], err);
|
||||
form.apiError(err);
|
||||
}
|
||||
|
||||
window.scrollTo({
|
||||
@@ -276,11 +213,13 @@ const attachmentAdd = async (event) => {
|
||||
fileFormData.append("file", event.attachment.file);
|
||||
|
||||
try {
|
||||
let res = await axios.post("media", fileFormData, {
|
||||
let res = await api.post({
|
||||
url: "/media",
|
||||
body: fileFormData,
|
||||
headers: {
|
||||
"Content-Type": "multipart/form-data",
|
||||
},
|
||||
onUploadProgress: (progressEvent) =>
|
||||
progress: (progressEvent) =>
|
||||
event.attachment.setUploadProgress(
|
||||
(progressEvent.loaded * progressEvent.total) / 100
|
||||
),
|
||||
@@ -302,25 +241,25 @@ const attachmentAdd = async (event) => {
|
||||
|
||||
const loadOptionsAuthors = async () => {
|
||||
try {
|
||||
let res = await axios.get(
|
||||
"users?fields=id,username,first_name,last_name&limit=100",
|
||||
{ redirect: false }
|
||||
);
|
||||
let res = await api.get({
|
||||
url: "/users",
|
||||
params: {
|
||||
fields: "id,username,first_name,last_name",
|
||||
limit: 100,
|
||||
},
|
||||
});
|
||||
|
||||
if (!res.data.users) {
|
||||
throw new Error("The server is currently not available");
|
||||
}
|
||||
|
||||
formData.user_id.options = {};
|
||||
authors.value = {};
|
||||
|
||||
res.data.users.forEach((item) => {
|
||||
formData.user_id.options[item.id] = `${item.username}`;
|
||||
authors.value[item.id] = `${item.username}`;
|
||||
});
|
||||
} catch (err) {
|
||||
formMessage.icon = "";
|
||||
formMessage.type = "error";
|
||||
formMessage.message = "";
|
||||
restParseErrors(formData, [formMessage, "message"], err);
|
||||
form.apiError(err);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -51,12 +51,11 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, watch, reactive } from "vue";
|
||||
import EasyDataTable from "vue3-easy-data-table";
|
||||
import axios from "axios";
|
||||
import { relativeDate, toParamString } from "../../helpers/common";
|
||||
import { relativeDate } from "../../helpers/datetime";
|
||||
import { useRouter } from "vue-router";
|
||||
import SMDialogConfirm from "../../components/dialogs/SMDialogConfirm.vue";
|
||||
import { openDialog } from "vue3-promise-dialog";
|
||||
|
||||
import { api } from "../../helpers/api";
|
||||
import SMToolbar from "../../components/SMToolbar.vue";
|
||||
import SMButton from "../../components/SMButton.vue";
|
||||
import { debounce } from "../../helpers/common";
|
||||
@@ -113,8 +112,9 @@ const loadFromServer = async () => {
|
||||
params["title"] = search.value;
|
||||
}
|
||||
|
||||
let res = await axios.get(`posts${toParamString(params)}`, {
|
||||
redirect: false,
|
||||
let res = await api.get({
|
||||
url: "/posts",
|
||||
params: params,
|
||||
});
|
||||
if (!res.data.posts) {
|
||||
throw new Error("The server is currently not available");
|
||||
@@ -195,7 +195,7 @@ const handleDelete = async (item) => {
|
||||
|
||||
if (result == true) {
|
||||
try {
|
||||
await axios.delete(`posts${item.id}`);
|
||||
await api.delete(`posts${item.id}`);
|
||||
loadFromServer();
|
||||
|
||||
formMessage.message = "Post deleted successfully";
|
||||
|
||||
@@ -1,48 +1,16 @@
|
||||
<template>
|
||||
<SMContainer>
|
||||
<SMPage>
|
||||
<SMRow>
|
||||
<SMDialog :loading="formLoading">
|
||||
<SMDialog>
|
||||
<SMHeading :heading="pageHeading" />
|
||||
<SMMessage
|
||||
v-if="formMessage.message"
|
||||
:icon="formMessage.icon"
|
||||
:type="formMessage.type"
|
||||
:message="formMessage.message" />
|
||||
<form @submit.prevent="submit">
|
||||
<SMForm :model-value="form" @submit="handleSubmit">
|
||||
<SMRow>
|
||||
<SMColumn
|
||||
><SMInput
|
||||
v-model="formData.first_name.value"
|
||||
label="First Name"
|
||||
required
|
||||
:error="formData.first_name.error"
|
||||
@blur="fieldValidate(formData.first_name)"
|
||||
/></SMColumn>
|
||||
<SMColumn
|
||||
><SMInput
|
||||
v-model="formData.last_name.value"
|
||||
label="Last Name"
|
||||
required
|
||||
:error="formData.last_name.error"
|
||||
@blur="fieldValidate(formData.last_name)"
|
||||
/></SMColumn>
|
||||
<SMColumn><SMInput control="first_name" /></SMColumn>
|
||||
<SMColumn><SMInput control="last_name" /></SMColumn>
|
||||
</SMRow>
|
||||
<SMRow>
|
||||
<SMColumn
|
||||
><SMInput
|
||||
v-model="formData.email.value"
|
||||
label="Email"
|
||||
required
|
||||
:error="formData.email.error"
|
||||
@blur="fieldValidate(formData.email)"
|
||||
/></SMColumn>
|
||||
<SMColumn
|
||||
><SMInput
|
||||
v-model="formData.phone.value"
|
||||
label="Phone"
|
||||
:error="formData.phone.error"
|
||||
@blur="fieldValidate(formData.phone)"
|
||||
/></SMColumn>
|
||||
<SMColumn><SMInput control="email" /></SMColumn>
|
||||
<SMColumn><SMInput control="phone" /></SMColumn>
|
||||
</SMRow>
|
||||
<SMRow>
|
||||
<SMFormFooter>
|
||||
@@ -55,137 +23,85 @@
|
||||
</template>
|
||||
</SMFormFooter>
|
||||
</SMRow>
|
||||
</form>
|
||||
</SMForm>
|
||||
</SMDialog>
|
||||
</SMRow>
|
||||
</SMContainer>
|
||||
</SMPage>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, computed } from "vue";
|
||||
import SMInput from "../../components/SMInput.vue";
|
||||
import SMButton from "../../components/SMButton.vue";
|
||||
import SMDialog from "../../components/SMDialog.vue";
|
||||
import SMMessage from "../../components/SMMessage.vue";
|
||||
import SMHeading from "../../components/SMHeading.vue";
|
||||
import SMFormFooter from "../../components/SMFormFooter.vue";
|
||||
import axios from "axios";
|
||||
import {
|
||||
useValidation,
|
||||
isValidated,
|
||||
fieldValidate,
|
||||
restParseErrors,
|
||||
} from "../../helpers/validation";
|
||||
import { reactive, computed } from "vue";
|
||||
import { api } from "../../helpers/api";
|
||||
import { FormObject, FormControl } from "../../helpers/form";
|
||||
import { And, Required, Email, Phone } from "../../helpers/validate";
|
||||
import { useUserStore } from "../../store/UserStore";
|
||||
import { useRoute } from "vue-router";
|
||||
import { openDialog } from "vue3-promise-dialog";
|
||||
import SMInput from "../../components/SMInput.vue";
|
||||
import SMButton from "../../components/SMButton.vue";
|
||||
import SMDialog from "../../components/SMDialog.vue";
|
||||
import SMForm from "../../components/SMForm.vue";
|
||||
import SMPage from "../../components/SMPage.vue";
|
||||
import SMHeading from "../../components/SMHeading.vue";
|
||||
import SMFormFooter from "../../components/SMFormFooter.vue";
|
||||
import SMDialogChangePassword from "../../components/dialogs/SMDialogChangePassword.vue";
|
||||
|
||||
let formLoading = ref(false);
|
||||
const route = useRoute();
|
||||
const userStore = useUserStore();
|
||||
|
||||
const formMessage = reactive({
|
||||
icon: "",
|
||||
type: "",
|
||||
message: "",
|
||||
});
|
||||
const formData = reactive({
|
||||
first_name: {
|
||||
value: "",
|
||||
error: "",
|
||||
rules: {
|
||||
required: true,
|
||||
required_message: "A first name is needed",
|
||||
min: 2,
|
||||
min_message: "Your first name should be at least 2 letters long",
|
||||
},
|
||||
},
|
||||
last_name: {
|
||||
value: "",
|
||||
error: "",
|
||||
rules: {
|
||||
required: true,
|
||||
required_message: "A last name is needed",
|
||||
min: 2,
|
||||
min_message: "Your last name should be at least 2 letters long",
|
||||
},
|
||||
},
|
||||
email: {
|
||||
value: "",
|
||||
error: "",
|
||||
rules: {
|
||||
required: true,
|
||||
required_message: "A email address is needed",
|
||||
email: true,
|
||||
email_message: "Your email address is not correct",
|
||||
},
|
||||
},
|
||||
phone: {
|
||||
value: "",
|
||||
error: "",
|
||||
rules: {
|
||||
phone: true,
|
||||
phone_message: "Your phone number does not look correct",
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
useValidation(formData);
|
||||
const form = reactive(
|
||||
FormObject({
|
||||
first_name: FormControl("", And([Required()])),
|
||||
last_name: FormControl("", And([Required()])),
|
||||
email: FormControl("", And([Required(), Email()])),
|
||||
phone: FormControl("", Phone()),
|
||||
})
|
||||
);
|
||||
|
||||
const loadData = async () => {
|
||||
if (route.params.id) {
|
||||
try {
|
||||
formLoading.value = true;
|
||||
let res = await axios.get(`users/${route.params.id}`);
|
||||
form.loading(true);
|
||||
let res = await api.get(`users/${route.params.id}`);
|
||||
|
||||
formData.first_name.value = res.data.user.first_name;
|
||||
formData.last_name.value = res.data.user.last_name;
|
||||
formData.phone.value = res.data.user.phone;
|
||||
formData.email.value = res.data.user.email;
|
||||
console.log(res);
|
||||
form.first_name.value = res.data.user.first_name;
|
||||
form.last_name.value = res.data.user.last_name;
|
||||
form.phone.value = res.data.user.phone;
|
||||
form.email.value = res.data.user.email;
|
||||
} catch (err) {
|
||||
formMessage.icon = "";
|
||||
formMessage.type = "error";
|
||||
formMessage.message = "";
|
||||
restParseErrors(formData, [formMessage, "message"], err);
|
||||
form.apiErrors(err);
|
||||
}
|
||||
} else {
|
||||
formData.first_name.value = userStore.firstName;
|
||||
formData.last_name.value = userStore.lastName;
|
||||
formData.phone.value = userStore.phone;
|
||||
formData.email.value = userStore.email;
|
||||
form.first_name.value = userStore.firstName;
|
||||
form.last_name.value = userStore.lastName;
|
||||
form.phone.value = userStore.phone;
|
||||
form.email.value = userStore.email;
|
||||
}
|
||||
|
||||
formLoading.value = false;
|
||||
form.loading(false);
|
||||
};
|
||||
|
||||
const submit = async () => {
|
||||
formMessage.type = "error";
|
||||
formMessage.icon = "fa-solid fa-circle-exclamation";
|
||||
formMessage.message = "";
|
||||
|
||||
const handleSubmit = async () => {
|
||||
try {
|
||||
if (isValidated(formData)) {
|
||||
formLoading.value = true;
|
||||
let res = await axios.put(`users/${userStore.id}`, {
|
||||
first_name: formData.first_name.value,
|
||||
last_name: formData.last_name.value,
|
||||
email: formData.email.value,
|
||||
phone: formData.phone.value,
|
||||
});
|
||||
form.loading(true);
|
||||
let res = await api.put({
|
||||
url: `users/${userStore.id}`,
|
||||
body: {
|
||||
first_name: form.first_name.value,
|
||||
last_name: form.last_name.value,
|
||||
email: form.email.value,
|
||||
phone: form.phone.value,
|
||||
},
|
||||
});
|
||||
|
||||
userStore.setUserDetails(res.data.user);
|
||||
userStore.setUserDetails(res.data.user);
|
||||
|
||||
formMessage.type = "success";
|
||||
formMessage.icon = "";
|
||||
formMessage.message = "Your details have been updated";
|
||||
}
|
||||
form.message("Your details have been updated", "success");
|
||||
} catch (err) {
|
||||
restParseErrors(formData, [formMessage, "message"], err);
|
||||
form.apiErrors(err);
|
||||
}
|
||||
|
||||
formLoading.value = false;
|
||||
form.loading(false);
|
||||
};
|
||||
|
||||
const handleChangePassword = () => {
|
||||
|
||||
@@ -35,8 +35,8 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, watch } from "vue";
|
||||
import EasyDataTable from "vue3-easy-data-table";
|
||||
import axios from "axios";
|
||||
import { relativeDate, toParamString } from "../../helpers/common";
|
||||
import { api } from "../../helpers/api";
|
||||
import { relativeDate } from "../../helpers/datetime";
|
||||
import { useRouter } from "vue-router";
|
||||
import DialogConfirm from "../../components/dialogs/SMDialogConfirm.vue";
|
||||
import { openDialog } from "vue3-promise-dialog";
|
||||
@@ -95,7 +95,10 @@ const loadFromServer = async () => {
|
||||
params["page"] = serverOptions.value.page;
|
||||
params["limit"] = serverOptions.value.rowsPerPage;
|
||||
|
||||
let res = await axios.get(`users${toParamString(params)}`);
|
||||
let res = await api.get({
|
||||
url: "/users",
|
||||
params: params,
|
||||
});
|
||||
items.value = res.data.users;
|
||||
|
||||
items.value.forEach((row) => {
|
||||
@@ -154,7 +157,7 @@ const handleDelete = async (user) => {
|
||||
|
||||
if (result == true) {
|
||||
try {
|
||||
await axios.delete(`users${user.id}`);
|
||||
await api.delete(`users${user.id}`);
|
||||
loadFromServer();
|
||||
|
||||
formMessage.message = "User deleted successfully";
|
||||
|
||||
Reference in New Issue
Block a user