further refactoring

This commit is contained in:
2023-02-17 15:38:53 +10:00
parent ff75f142b3
commit 03f5c8d90f
11 changed files with 257 additions and 462 deletions

View File

@@ -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>

View File

@@ -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: "",

View File

@@ -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";

View File

@@ -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);

View File

@@ -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";

View File

@@ -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>

View File

@@ -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(

View File

@@ -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);
}
};

View File

@@ -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";

View File

@@ -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 = () => {

View File

@@ -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";