From 5409e4e1b3d3fc9bbc8ba5dfe60ded7a2423d19b Mon Sep 17 00:00:00 2001 From: Alireza Date: Sat, 6 Sep 2025 16:49:21 +0330 Subject: [PATCH] completed admin panel --- .env | 2 +- src/components/AtrributesProduct.vue | 256 +++ src/components/ConfigCountriesSelect.vue | 103 + src/components/ProductInfo.vue | 176 ++ src/components/SpecificationsProduct.vue | 337 +++ src/components/customSidebar.vue | 110 +- src/components/modals/Brands/addBrand.vue | 290 ++- src/components/modals/Brands/editBrand.vue | 462 ++-- src/components/modals/addUser.vue | 65 +- .../attribute-value/addAttributeValue.vue | 360 +++ .../attribute-value/editAttributeValue.vue | 444 ++++ .../modals/attribute/addAttribute.vue | 295 ++- .../modals/attribute/editAttribute.vue | 436 ++-- src/components/modals/attribute/test.vue | 298 +++ src/components/modals/blogCat/addBlogCat.vue | 8 +- src/components/modals/blogCat/editBlogCat.vue | 191 +- .../modals/countries/CountriesModal.vue | 249 +++ src/components/modals/editUser.vue | 23 +- src/router/routes.js | 20 +- src/utils/code-countries.js | 1214 ++++++++++ .../attributes-value/attributes-value.vue | 463 ++++ .../pages/attributes/attributes.vue | 67 +- .../live-preview/pages/banners/addBanner.vue | 814 ++++--- .../live-preview/pages/banners/banners.vue | 6 +- .../live-preview/pages/banners/editBanner.vue | 869 ++++---- .../live-preview/pages/blogCats/blogCat.vue | 16 +- .../live-preview/pages/brands/brands.vue | 22 +- .../pages/countries/countries.vue | 526 +++++ .../pages/discounts/addDiscount.vue | 6 +- .../pages/discounts/editDiscount.vue | 25 +- .../pages/products/addProduct.vue | 829 ++----- .../pages/products/editProduct.vue | 1962 +++++------------ .../live-preview/pages/products/products.vue | 69 +- src/views/live-preview/pages/users/users.vue | 14 +- 34 files changed, 7595 insertions(+), 3432 deletions(-) create mode 100644 src/components/AtrributesProduct.vue create mode 100644 src/components/ConfigCountriesSelect.vue create mode 100644 src/components/ProductInfo.vue create mode 100644 src/components/SpecificationsProduct.vue create mode 100644 src/components/modals/attribute-value/addAttributeValue.vue create mode 100644 src/components/modals/attribute-value/editAttributeValue.vue create mode 100644 src/components/modals/attribute/test.vue create mode 100644 src/components/modals/countries/CountriesModal.vue create mode 100644 src/utils/code-countries.js create mode 100644 src/views/live-preview/pages/attributes-value/attributes-value.vue create mode 100644 src/views/live-preview/pages/countries/countries.vue diff --git a/.env b/.env index 092af7d..c4cd5b1 100644 --- a/.env +++ b/.env @@ -1 +1 @@ -VUE_APP_ROOT_URL = http://192.168.100.126:8000/api/v1/ \ No newline at end of file +VUE_APP_ROOT_URL = http://85.208.254.227/api/v1/ \ No newline at end of file diff --git a/src/components/AtrributesProduct.vue b/src/components/AtrributesProduct.vue new file mode 100644 index 0000000..332b447 --- /dev/null +++ b/src/components/AtrributesProduct.vue @@ -0,0 +1,256 @@ + + + + + \ No newline at end of file diff --git a/src/components/ConfigCountriesSelect.vue b/src/components/ConfigCountriesSelect.vue new file mode 100644 index 0000000..9783dab --- /dev/null +++ b/src/components/ConfigCountriesSelect.vue @@ -0,0 +1,103 @@ + + + + + \ No newline at end of file diff --git a/src/components/ProductInfo.vue b/src/components/ProductInfo.vue new file mode 100644 index 0000000..ef420e8 --- /dev/null +++ b/src/components/ProductInfo.vue @@ -0,0 +1,176 @@ + + + + + + + + @@ -131,13 +192,19 @@ import { ref } from "vue"; import { toast } from "vue3-toastify"; import "vue3-toastify/dist/index.css"; import ApiServiece from "@/services/ApiService"; +import {Steppy} from "vue3-steppy"; export default { + components: {Steppy}, setup(props, { emit }) { const image = ref(null); const imagePreview = ref(null); const description = ref(); const title = ref(); + const loadingStep = ref(false); + const step = ref(1); + const brandId = ref(null); + const locale = ref('fa'); const errors = ref({}); const loading = ref(false); @@ -150,8 +217,6 @@ export default { if (fileInput) { fileInput.value = ""; } - - console.log(image.value); }; const handleImageChange = (event) => { const file = event.target.files[0]; @@ -204,14 +269,14 @@ export default { } loading.value = true; - const formData = new FormData(); - formData.append("title", title.value); - formData.append("description", description.value); - formData.append("image", image.value); - console.log(image.value); - ApiServiece.post(`admin/brands`, formData, { + const params = { + title: title.value, + description: description.value, + locale: locale.value, + } + + ApiServiece.post(`admin/brands/${brandId.value}/translations`, params, { headers: { - "content-type": "multipart", Authorization: `Bearer ${localStorage.getItem("token")}`, }, }) @@ -224,11 +289,9 @@ export default { }) .then(() => { setTimeout(() => { - document.getElementById("close").click(); emit("brand-updated"); title.value = ""; description.value = ""; - image.value = null; imagePreview.value = null; }, 500); }) @@ -244,6 +307,44 @@ export default { }); }; + const handlerAddBrand = async () => { + if (!image.value) { + toast.error('تصویر برند نمی تواند خالی باشد.') + + return + } + + try { + loadingStep.value = true; + + const formData = new FormData(); + + formData.append("image", image.value); + + const { data: { message, success, data } } = await ApiServiece.post( + `admin/brands`, + formData, + { + headers: { + "content-type": "multipart", + Authorization: `Bearer ${localStorage.getItem("token")}`, + }, + }) + + if (success) { + toast.success(message) + + brandId.value = data?.id + + step.value++ + } + } catch (e) { + toast.error(e?.response?.data?.message) + } finally { + loadingStep.value = false; + } + } + return { errors, loading, @@ -255,6 +356,11 @@ export default { removeImage, title, description, + loadingStep, + step, + handlerAddBrand, + brandId, + locale }; }, }; diff --git a/src/components/modals/Brands/editBrand.vue b/src/components/modals/Brands/editBrand.vue index 5453fc5..d39aada 100644 --- a/src/components/modals/Brands/editBrand.vue +++ b/src/components/modals/Brands/editBrand.vue @@ -20,99 +20,157 @@ > @@ -120,13 +178,15 @@ + + + + \ No newline at end of file diff --git a/src/components/modals/attribute-value/editAttributeValue.vue b/src/components/modals/attribute-value/editAttributeValue.vue new file mode 100644 index 0000000..868dc48 --- /dev/null +++ b/src/components/modals/attribute-value/editAttributeValue.vue @@ -0,0 +1,444 @@ + + + + + \ No newline at end of file diff --git a/src/components/modals/attribute/addAttribute.vue b/src/components/modals/attribute/addAttribute.vue index dcef6ef..24386cc 100644 --- a/src/components/modals/attribute/addAttribute.vue +++ b/src/components/modals/attribute/addAttribute.vue @@ -11,7 +11,7 @@ @@ -103,8 +165,10 @@ import { ref, toRef, watch } from "vue"; import { toast } from "vue3-toastify"; import "vue3-toastify/dist/index.css"; import ApiServiece from "@/services/ApiService"; +import {Steppy} from "vue3-steppy"; export default { + components: {Steppy}, props: { attributeValues: { type: Array, @@ -112,11 +176,17 @@ export default { }, }, setup(props, { emit }) { - const colorName = ref(); + const attrName = ref(); const colorCode = ref(); const localAttributeValues = toRef(props.attributeValues); const errors = ref({}); const loading = ref(false); + const loadingAttr = ref(false); + const categories = ref([]); + const categoryId = ref(null); + const categoryResponse = ref(null); + const step = ref(1); + const locale = ref('fa'); watch( () => props.attributeValues, @@ -125,9 +195,9 @@ export default { const validateForm = () => { errors.value = {}; - if (!colorName.value) - errors.value.colorName = "وارد کردن نام رنگ ضروری می باشد"; - if (!colorCode.value) errors.value.colorCode = "انتخاب رنگ ضروری می باشد"; + // if (!attrName.value) + // errors.value.attrName = "وارد کردن نام ویژگی ضروری می باشد"; + if (!categoryId.value) errors.value.categoryId = "انتخاب دسته بندی ضروری می باشد"; return Object.keys(errors.value).length === 0; }; @@ -136,7 +206,7 @@ export default { errors.value[field] = ""; }; - const addAttribute = () => { + const handlerSubmitCategory = () => { if (!validateForm()) { toast.error("لطفا فیلد های لازم را وارد نمایید", { position: "top-right", @@ -144,30 +214,21 @@ export default { }); return; } + loading.value = true; - const formData = new FormData(); - console.log(localAttributeValues.value); - formData.append("title", colorName.value); - formData.append("code", colorCode.value); - console.log(localAttributeValues); - formData.append("attribute_id", 1); - - ApiServiece.post(`admin/attribute-values`, formData) - .then(() => { - - toast.success("!ویژگی با موفقیت اضافه شد", { + const params = { + category_id: categoryId.value, + } + + ApiServiece.post(`admin/attributes`, params) + .then(({ data }) => { + toast.success(data?.message, { position: "top-right", autoClose: 1000, }); - }) - .then(() => { - setTimeout(() => { - document.getElementById("close").click(); - emit("attribute-updated"); - colorName.value = ""; - colorCode.value = ""; - }, 500); + categoryResponse.value = data?.data?.id; + step.value++ }) .catch((error) => { toast.error(`${error.response.data.message}`, { @@ -180,13 +241,57 @@ export default { }); }; + const addAttribute = async () => { + try { + loadingAttr.value = true; + + const params = { + title: attrName.value, + locale: locale.value, + } + + const { data: { success, message } } = await ApiServiece.post(`admin/attributes/${categoryResponse.value}/translations`, params) + + if (success) { + toast.success(message) + //document.getElementById("close").click(); + emit("attribute-updated"); + } + } catch (e) { + toast.error(e?.response?.data?.message) + } finally { + loadingAttr.value = false; + } + } + + const getAttributes = async () => { + try { + const { data: { success, data } } = await ApiServiece.get(`admin/categories`) + + if (success) { + categories.value = data; + } + } catch (e) { + toast.error(e?.response?.data?.message) + } + } + + getAttributes() + return { errors, loading, clearError, - addAttribute, - colorName, + handlerSubmitCategory, + attrName, colorCode, + getAttributes, + categories, + loadingAttr, + categoryId, + step, + locale, + addAttribute }; }, }; diff --git a/src/components/modals/attribute/editAttribute.vue b/src/components/modals/attribute/editAttribute.vue index 2f3cfd7..0e104c2 100644 --- a/src/components/modals/attribute/editAttribute.vue +++ b/src/components/modals/attribute/editAttribute.vue @@ -19,77 +19,140 @@ > @@ -97,13 +160,15 @@ + + diff --git a/src/components/modals/blogCat/addBlogCat.vue b/src/components/modals/blogCat/addBlogCat.vue index e250236..85351d0 100644 --- a/src/components/modals/blogCat/addBlogCat.vue +++ b/src/components/modals/blogCat/addBlogCat.vue @@ -82,7 +82,6 @@ v-model="locale" class="form-control" placeholder="انتخاب کنید" - @change="handlerChangeLocale" >