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