浏览代码

admin panel updates

master
unknown 9 个月前
父节点
当前提交
3c37d9929e
共有 26 个文件被更改,包括 371 次插入288 次删除
  1. +0
    -1
      dist/css/1359.4e6c38e0.css
  2. +0
    -1
      dist/css/1728.dfb1a48d.css
  3. +0
    -1
      dist/css/2165.32604f4b.css
  4. +0
    -1
      dist/css/2206.58428363.css
  5. +0
    -1
      dist/css/2489.647e025b.css
  6. +0
    -1
      dist/css/3207.bf681f03.css
  7. +0
    -1
      dist/css/5923.4e6c38e0.css
  8. +0
    -1
      dist/css/6204.dbc1223a.css
  9. +0
    -1
      dist/css/6490.91a34c47.css
  10. +0
    -1
      dist/css/8304.dfb1a48d.css
  11. +0
    -9
      dist/css/8344.19e16966.css
  12. +0
    -1
      dist/css/9375.03818774.css
  13. +0
    -1
      dist/css/9839.279dba1b.css
  14. +0
    -12
      dist/css/app.80538a0b.css
  15. +7
    -30
      dist/index.html
  16. +39
    -27
      src/components/modals/identity/addIdentity.vue
  17. +23
    -16
      src/components/modals/identity/editIdentity.vue
  18. +41
    -21
      src/views/live-preview/pages/blogs/addBlog.vue
  19. +43
    -24
      src/views/live-preview/pages/blogs/editBlog.vue
  20. +5
    -3
      src/views/live-preview/pages/discounts/addDiscount.vue
  21. +47
    -24
      src/views/live-preview/pages/discounts/editDiscount.vue
  22. +39
    -45
      src/views/live-preview/pages/faqs/editFaqs.vue
  23. +5
    -4
      src/views/live-preview/pages/orders/approvedOrders.vue
  24. +42
    -2
      src/views/live-preview/pages/orders/singleOrder.vue
  25. +38
    -16
      src/views/live-preview/pages/products/addProduct.vue
  26. +42
    -43
      src/views/live-preview/pages/products/editProduct.vue

+ 0
- 1
dist/css/1359.4e6c38e0.css 查看文件

@@ -1 +0,0 @@
.ls{margin-left:500px}

+ 0
- 1
dist/css/1728.dfb1a48d.css 查看文件

@@ -1 +0,0 @@
.component-page{position:relative;border:none;font-weight:500px;top:10px}

+ 0
- 1
dist/css/2165.32604f4b.css
文件差异内容过多而无法显示
查看文件


+ 0
- 1
dist/css/2206.58428363.css
文件差异内容过多而无法显示
查看文件


+ 0
- 1
dist/css/2489.647e025b.css
文件差异内容过多而无法显示
查看文件


+ 0
- 1
dist/css/3207.bf681f03.css
文件差异内容过多而无法显示
查看文件


+ 0
- 1
dist/css/5923.4e6c38e0.css 查看文件

@@ -1 +0,0 @@
.ls{margin-left:500px}

+ 0
- 1
dist/css/6204.dbc1223a.css
文件差异内容过多而无法显示
查看文件


+ 0
- 1
dist/css/6490.91a34c47.css
文件差异内容过多而无法显示
查看文件


+ 0
- 1
dist/css/8304.dfb1a48d.css 查看文件

@@ -1 +0,0 @@
.component-page{position:relative;border:none;font-weight:500px;top:10px}

+ 0
- 9
dist/css/8344.19e16966.css
文件差异内容过多而无法显示
查看文件


+ 0
- 1
dist/css/9375.03818774.css
文件差异内容过多而无法显示
查看文件


+ 0
- 1
dist/css/9839.279dba1b.css
文件差异内容过多而无法显示
查看文件


+ 0
- 12
dist/css/app.80538a0b.css
文件差异内容过多而无法显示
查看文件


+ 7
- 30
dist/index.html 查看文件

@@ -1,30 +1,7 @@
<!DOCTYPE html>
<html lang="">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<link rel="icon" href="/favicon.svg" />
<link rel="stylesheet" href="/fonts/vazir.css" />
<script
defer="defer"
src="https://bazarce.liara.run/script.js"
data-website-id="7baabdd5-3224-41c1-9267-d2a1abd29d01"
></script>
<title>LightAble</title>
<script defer="defer" src="/js/chunk-vendors.f384eb27.js"></script>
<script defer="defer" src="/js/app.274a0e78.js"></script>
<link href="/css/chunk-vendors.fd1119e3.css" rel="stylesheet" />
<link href="/css/app.80538a0b.css" rel="stylesheet" />
<script defer src="https://bazarce.liara.run/script.js" data-website-id="7baabdd5-3224-41c1-9267-d2a1abd29d01"></script>
</head>
<body lang>
<noscript
><strong
>We're sorry but LightAble doesn't work properly without JavaScript
enabled. Please enable it to continue.</strong
></noscript
>
<div id="app"></div>
</body>
</html>
<!doctype html><html lang=""><head><meta charset="utf-8"/><meta http-equiv="X-UA-Compatible" content="IE=edge"/><meta name="viewport" content="width=device-width,initial-scale=1"/><link rel="icon" id="favicon" href="/favicon.svg"/><link rel="stylesheet" href="/fonts/vazir.css"/><script defer="defer" src="https://bazarce.liara.run/script.js" data-website-id="7baabdd5-3224-41c1-9267-d2a1abd29d01"></script><title>NovinPlast</title><script defer="defer" src="/js/chunk-vendors.ae561124.js"></script><script defer="defer" src="/js/app.2907bfa5.js"></script><link href="/css/chunk-vendors.fd1119e3.css" rel="stylesheet"><link href="/css/app.cbef7f68.css" rel="stylesheet"></head><body lang><noscript><strong>We're sorry but NovinPlast doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div><script>document.addEventListener("DOMContentLoaded", function () {
const faviconUrl = localStorage.getItem("logo");
if (faviconUrl) {
const faviconLink = document.getElementById("favicon");
faviconLink.href = faviconUrl;
}
});</script></body></html>

+ 39
- 27
src/components/modals/identity/addIdentity.vue 查看文件

@@ -47,21 +47,14 @@
<label class="form-label">انتخاب دسته</label>

<div class="color-picker-wrapper">
<select
class="form-control selector"
@change="clearError(`selectedCat`)"
<VueSelect
style="--vs-min-height: 48px; --vs-border-radius: 8px"
:isLoading="categorySelectorLoader"
v-model="selectedCat"
:class="{ 'is-invalid': errors.selectedCat }"
placeholder="انتخاب دسته"
>
<option
v-for="cat in localCat"
:key="cat.id"
:value="cat.id"
>
{{ cat.title }}
</option>
</select>
:options="formattedCategories"
placeholder="دسته ای را انتخاب کنید"
@search="handleSearch"
/>
</div>
<small v-if="errors.selectedCat" class="text-danger">
{{ errors.selectedCat }}
@@ -101,29 +94,46 @@
</template>

<script>
import { ref, toRef, watch } from "vue";
import { ref, computed } from "vue";
import VueSelect from "vue3-select-component";
import { toast } from "vue3-toastify";
import "vue3-toastify/dist/index.css";
import ApiServiece from "@/services/ApiService";

export default {
props: {
cats: {
type: Array,
Required: true,
},
components: {
VueSelect,
},
setup(props, { emit }) {
const localCat = toRef(props.cats);
const selectedCat = ref();
const title = ref();
const errors = ref({});
const loading = ref(false);
const categories = ref([]);
const categorySelectorLoader = ref(false);

const handleSearch = async (searchTerm) => {
if (searchTerm.length < 3) return;
categorySelectorLoader.value = true;
try {
const response = await ApiServiece.get(
`admin/categories?title=${searchTerm}`
);
categories.value = response.data.data;
categorySelectorLoader.value = false;
} catch (error) {
categorySelectorLoader.value = false;
categories.value = [];
}
};

watch(
() => props.cats,
(newVal) => (localCat.value = newVal)
const formattedCategories = computed(() =>
Array.isArray(categories.value)
? categories.value.map((category) => ({
value: category.id,
label: category.title,
}))
: []
);

const validateForm = () => {
@@ -169,7 +179,7 @@ export default {
.then(() => {
setTimeout(() => {
document.getElementById("close").click();
emit("identity-updated");
emit("attribute-updated");
selectedCat.value = "";
title.value = "";
}, 500);
@@ -191,7 +201,9 @@ export default {
loading,
clearError,
addIdentity,
localCat,
formattedCategories,
categorySelectorLoader,
handleSearch,
title,
selectedCat,
};


+ 23
- 16
src/components/modals/identity/editIdentity.vue 查看文件

@@ -45,21 +45,15 @@
<label class="form-label">انتخاب دسته</label>

<div class="color-picker-wrapper">
<select
class="form-control selector"
@change="clearError(`localCat`)"
<VueSelect
style="--vs-min-height: 48px; --vs-border-radius: 8px"
v-model="localCatId"
:class="{ 'is-invalid': errors.localCat }"
placeholder="انتخاب دسته"
>
<option
v-for="cat in localCat"
:key="cat.id"
:value="cat.id"
>
{{ cat.title }}
</option>
</select>
:options="formattedCategories"
label="label"
:reduce="(option) => option.value"
placeholder="دسته ای را انتخاب کنید"
/>
</div>
<small v-if="errors.selectedCat" class="text-danger">
{{ errors.selectedCat }}
@@ -99,8 +93,8 @@
</template>

<script>
import { ref, toRef, watch } from "vue";
import { ref, toRef, watch , computed } from "vue";
import VueSelect from "vue3-select-component";
import { toast } from "vue3-toastify";
import "vue3-toastify/dist/index.css";
import ApiServiece from "@/services/ApiService";
@@ -124,6 +118,9 @@ export default {
Required: true,
},
},
components: {
VueSelect,
},
setup(props, { emit }) {
const localCat = toRef(props.cats);
const localTitle = toRef(props.title);
@@ -152,6 +149,15 @@ export default {
(newVal) => (localCatId.value = newVal)
);

const formattedCategories = computed(() =>
Array.isArray(localCat.value)
? localCat.value.map((category) => ({
value: category.id,
label: category.title,
}))
: []
);

const validateForm = () => {
errors.value = {};
if (!localTitle.value)
@@ -213,6 +219,7 @@ export default {
localTitle,
localId,
localCatId,
formattedCategories,
};
},
};


+ 41
- 21
src/views/live-preview/pages/blogs/addBlog.vue 查看文件

@@ -94,17 +94,15 @@
<BCol md="6">
<div class="form-group">
<label class="form-label">دسته</label>
<select
:class="{ 'is-invalid': errors.blogCat }"
<VueSelect
:isLoading="categorySelectorLoader"
v-model="blogCat"
class="form-control"
:options="formattedCategories"
placeholder="دسته ای را انتخاب کنید"
@search="handleSearch"
@change="clearError('blogCat')"
placeholder="انتخاب دسته بلاگ"
>
<option v-for="cat in cats" :key="cat.id" :value="cat.id">
{{ cat.title }}
</option>
</select>
style="--vs-min-height: 48px; --vs-border-radius: 8px"
/>
</div>
<small v-if="errors.blogCat" class="text-danger">
{{ errors.blogCat }}
@@ -165,10 +163,11 @@
</template>

<script>
import VueSelect from "vue3-select-component";
import { toast } from "vue3-toastify";
import "vue3-toastify/dist/index.css";
import ApiServiece from "@/services/ApiService";
import { ref, onMounted, nextTick } from "vue";
import { ref, onMounted, nextTick , computed } from "vue";
import Layout from "@/layout/custom.vue";
import Quill from "quill";
import "quill/dist/quill.snow.css";
@@ -177,6 +176,7 @@ export default {
name: "SAMPLE-PAGE",
components: {
Layout,
VueSelect,
},
setup() {
const loading = ref(false);
@@ -189,19 +189,37 @@ export default {
const blogCat = ref();
const author = ref("");
const editor = ref(null);
const cats = ref([]);
const categories = ref([]);
const editorContent = ref("");
const categorySelectorLoader = ref(false)

const getCats = () => {
ApiServiece.get(`admin/blog-categories`)
.then((resp) => {
cats.value = resp.data.data;
})
.catch((err) => {
console.log(err);
});


const handleSearch = async (searchTerm) => {
if (searchTerm.length < 3) return;
categorySelectorLoader.value = true;
try {
const response = await ApiServiece.get(
`admin/blog-categories?title=${searchTerm}`
);
categories.value = response.data.data;
categorySelectorLoader.value = false;
} catch (error) {
categorySelectorLoader.value = false;
categories.value = [];
}
};

const formattedCategories = computed(() =>
Array.isArray(categories.value)
? categories.value.map((category) => ({
value: category.id,
label: category.title,
}))
: []
);

const removeImage = () => {
image.value = null;
imagePreview.value = null;
@@ -250,7 +268,6 @@ export default {
};

onMounted(() => {
getCats();
const quill = new Quill(editor.value, {
theme: "snow",
modules: {
@@ -336,7 +353,7 @@ export default {
slug,
summary,
editor,
cats,
categories,
errors,
image,
imagePreview,
@@ -348,6 +365,9 @@ export default {
author,
blogCat,
loading,
handleSearch,
categorySelectorLoader,
formattedCategories
};
},
};


+ 43
- 24
src/views/live-preview/pages/blogs/editBlog.vue 查看文件

@@ -89,17 +89,15 @@
<BCol md="6">
<div class="form-group">
<label class="form-label">دسته</label>
<select
:class="{ 'is-invalid': errors.blogCat }"
<VueSelect
style="--vs-min-height: 48px; --vs-border-radius: 8px"
:isLoading="categorySelectorLoader"
v-model="blogCat"
class="form-control"
@input="clearError('blogCat')"
placeholder="انتخاب دسته بلاگ"
>
<option v-for="cat in cats" :key="cat.id" :value="cat.id">
{{ cat.title }}
</option>
</select>
:options="formattedCategories"
:reduce="(option) => option.value"
placeholder="دسته ای را انتخاب نمایید"
@search="handleSearch"
/>
</div>
<small v-if="errors.blogCat" class="text-danger">
{{ errors.blogCat }}
@@ -161,10 +159,11 @@
</template>

<script>
import VueSelect from "vue3-select-component";
import { toast } from "vue3-toastify";
import "vue3-toastify/dist/index.css";
import ApiServiece from "@/services/ApiService";
import { ref, onMounted } from "vue";
import { ref, onMounted, computed } from "vue";
import Layout from "@/layout/custom.vue";
import Quill from "quill";
import "quill/dist/quill.snow.css";
@@ -173,6 +172,7 @@ export default {
name: "SAMPLE-PAGE",
components: {
Layout,
VueSelect,
},
setup() {
const blog = ref();
@@ -187,17 +187,34 @@ export default {
const blogCat = ref();
const author = ref("");
const editor = ref(null);
const cats = ref([]);
const categorySelectorLoader = ref(false);
const categories = ref([{ id: null, title: "" }]);
const editorContent = ref("");

const getCats = () => {
ApiServiece.get(`admin/blog-categories`)
.then((resp) => {
cats.value = resp.data.data;
})
.catch((err) => {
console.log(err);
});
const formattedCategories = computed(() =>
Array.isArray(categories.value)
? categories.value.map((category) => ({
value: category.id,
label: category.title,
}))
: []
);

const handleSearch = async (searchTerm) => {
if (searchTerm.length < 3) return;
categorySelectorLoader.value = true;

try {
const response = await ApiServiece.get(
`admin/blog-categories?title=${searchTerm}`
);
categories.value = response.data.data;
categorySelectorLoader.value = false;
} catch (error) {
categorySelectorLoader.value = false;
categories.value = [];
}
};

const handleImageChange = (event) => {
@@ -242,7 +259,9 @@ export default {
ApiServiece.get(`admin/blogs/${route.params.id}`)
.then((resp) => {
blog.value = resp.data.data;
console.log(blog.value);
categories.value[0].id = blog.value.blog_category_id;
categories.value[0].title = "test";

title.value = blog.value.title;
slug.value = blog.value.slug;
summary.value = blog.value.summary;
@@ -277,7 +296,6 @@ export default {

onMounted(() => {
getBlog();
getCats();
});

const submitForm = () => {
@@ -335,18 +353,19 @@ export default {
slug,
summary,
editor,
cats,
categories,
errors,
image,
imagePreview,
handleImageChange,
formattedCategories,
submitForm,
clearError,
editorContent,
author,
blogCat,
loading,
handleSearch,
};
},
};


+ 5
- 3
src/views/live-preview/pages/discounts/addDiscount.vue 查看文件

@@ -102,7 +102,7 @@
v-model="whichPart"
class="form-control"
:class="{ 'is-invalid': errors.whichPart }"
@select="clearError('whichPart')"
@change="clearError('whichPart')"
placeholder="انتخاب محل اعمال تخفبف"
>
<option value="cat">دسته</option>
@@ -124,12 +124,13 @@
:isLoading="categorySelectorLoader"
v-model="selectedCat"
:options="formattedCategories"
@change="clearError('selectedCat')"
placeholder="دسته ای را انتخاب کنید"
@search="handleSearch"
/>
</div>
<small v-if="errors.blogCat" class="text-danger">
{{ errors.blogCat }}
<small v-if="errors.selectedCat" class="text-danger">
{{ errors.selectedCat }}
</small>
</BCol>

@@ -149,6 +150,7 @@
v-model="selectedProduct"
:options="formattedProducts"
@search="handleProductSearch"
@change="clearError('selectedProduct')"
placeholder="محصولی را انتخاب کنید"
/>
<small v-if="errors.selectedProduct" class="text-danger">


+ 47
- 24
src/views/live-preview/pages/discounts/editDiscount.vue 查看文件

@@ -103,7 +103,7 @@
v-model="whichPart"
class="form-control"
:class="{ 'is-invalid': errors.whichPart }"
@select="clearError('whichPart')"
@change="clearError('whichPart')"
placeholder="انتخاب محل اعمل تخفیف"
>
<option value="cat">دسته</option>
@@ -121,10 +121,13 @@
<label class="form-label">دسته</label>
<VueSelect
style="--vs-min-height: 48px; --vs-border-radius: 8px"
:isLoading="categorySelectorLoader"
v-model="selectedCat"
:options="formattedCategories"
label="label"
:reduce="(option) => option.value"
@change="clearError('selectedCat')"
placeholder="دسته ای را انتخاب کنید"
@search="handleSearch"
/>
</div>
<small v-if="errors.selectedCat" class="text-danger">
@@ -137,9 +140,11 @@
<label class="form-label">محصول</label>
<VueSelect
style="--vs-min-height: 48px; --vs-border-radius: 8px"
:isLoading="categorySelectorLoader"
:isLoading="productSelectorLoader"
v-model="selectedProduct"
:options="formattedProducts"
@search="handleProductSearch"
@change="clearError('selectedProduct')"
placeholder="محصولی را انتخاب کنید "
/>
</div>
@@ -235,10 +240,12 @@ export default {
const maxUsage = ref();
const whichPart = ref();
const loading = ref(false);
const categories = ref([]);
const categories = ref([{ id: null, title: "" }]);
const errors = ref({});
const products = ref();
const products = ref([{ id: null, title: "" }]);
const discount = ref();
const categorySelectorLoader = ref(false);
const productSelectorLoader = ref(false);

const formattedCategories = computed(() =>
Array.isArray(categories.value)
@@ -258,24 +265,34 @@ export default {
: []
);

const getCats = () => {
ApiServiece.get(`admin/categories`)
.then((resp) => {
categories.value = resp.data.data;
})
.catch((err) => {
console.log(err);
});
const handleSearch = async (searchTerm) => {
if (searchTerm.length < 3) return;
categorySelectorLoader.value = true;
try {
const response = await ApiServiece.get(
`admin/categories?title=${searchTerm}`
);
categories.value = response.data.data;
categorySelectorLoader.value = false;
} catch (error) {
categorySelectorLoader.value = false;
categories.value = [];
}
};

const getProduct = () => {
ApiServiece.get(`admin/products`)
.then((resp) => {
products.value = resp.data.data;
})
.catch((err) => {
console.log(err);
});
const handleProductSearch = async (searchTerm) => {
if (searchTerm.length < 3) return;
productSelectorLoader.value = true;
try {
const response = await ApiServiece.get(
`admin/products?title=${searchTerm}`
);
products.value = response.data.data;
productSelectorLoader.value = false;
} catch (error) {
productSelectorLoader.value = false;
products.value = [];
}
};

const getDiscount = () => {
@@ -286,9 +303,12 @@ export default {
discountType.value = discount.value.type;
amount.value = discount.value.amount;
minOrder.value = discount.value.min_order;
selectedCat.value = discount.value.category_id;
if (discount.value.category_id) {
whichPart.value = "cat";
categories.value[0].id = discount.value.category_id;
categories.value[0].title = "test";
selectedCat.value = discount.value.category_id;
}

if (!discount.value.category_id && !discount.value.product_id) {
@@ -298,6 +318,9 @@ export default {
selectedProduct.value = discount.value.product_id;
if (discount.value.product_id) {
whichPart.value = "product";
products.value[0].id = discount.value.product_id;
products.value[0].title = "test";
selectedProduct.value = discount.value.product_id;
}

if (discount?.value.starts_at) {
@@ -367,8 +390,6 @@ export default {
};

onMounted(() => {
getCats();
getProduct();
getDiscount();
});

@@ -452,6 +473,8 @@ export default {
loading,
formattedCategories,
formattedProducts,
handleSearch,
handleProductSearch,
};
},
};


+ 39
- 45
src/views/live-preview/pages/faqs/editFaqs.vue 查看文件

@@ -19,21 +19,20 @@ export default {
const status = ref("");
const userAnswer = ref(null);
const loading = ref();
const isAnswerExist = ref(null)
const isAnswerExist = ref(null);

const getFaqs = () => {
ApiServiece.get(`admin/faqs/${route.params.id}?children=1`).then(
(resp) => {
faqs.value = resp.data.data;
console.log(faqs.value, "faqs");
text.value = faqs.value.text;
status.value = faqs.value.status;
answerText.value = faqs.value?.answer?.text;
console.log(resp.data.data);
if(faqs.value?.children.length > 0){
isAnswerExist.value = true
}
else {
isAnswerExist.value = false
if (faqs.value?.answer) {
isAnswerExist.value = true;
} else {
isAnswerExist.value = false;
}
}
);
@@ -82,54 +81,49 @@ export default {
});
};

const submitAnswer = (op) => {
const submitAnswer = () => {
loading.value = true;
const formData = new FormData();
formData.append("text", answerText.value);
if(faqs.value.children.length > 0 ){
ApiServiece.put(`admin/faqs/${faqs.value?.children[0]?.id}`, formData)
.then(() => {
loading.value = false
if (op == 0) {
toast.success("پاسخ با موفقیت اضافه شد", {
if (faqs.value.answer) {
ApiServiece.put(`admin/faqs/${faqs.value?.answer?.id}`, formData)
.then((resp) => {
console.log(resp, "resp");
loading.value = false;

toast.success(`${resp.data.message}`, {
position: "top-right",
autoClose: 3000,
});
getFaqs();
}
if (op == 1) {
toast.success("پاسخ با موفقیت ویرایش شد", {
})
.catch(() => {
toast.error("! خطا در ارسال پاسخ", {
position: "top-right",
autoClose: 3000,
});
getFaqs();
}
})
.catch(() => {
toast.error("! خطا در ارسال پاسخ", {
position: "top-right",
autoClose: 3000,
loading.value = false;
});
loading.value = false
});
}
else {
loading.value = false;
const formData = new FormData()
formData.append("parent_id" , route.params.id)
formData.append("text" , answerText.value)
} else {
loading.value = true;
const formData = new FormData();
formData.append("parent_id", route.params.id);
formData.append("text", answerText.value);
ApiServiece.post(`admin/faqs`, formData)
.catch(() => {
toast.error("! خطا در ارسال پاسخ", {
position: "top-right",
autoClose: 3000,
.then((resp) => {
toast.success(`${resp.data.message}`, {
position: "top-right",
autoClose: 3000,
});
loading.value = false;
})
.catch(() => {
toast.error("! خطا در ارسال پاسخ", {
position: "top-right",
autoClose: 3000,
});
loading.value = false;
});
loading.value = false
});
}
};

onMounted(() => {
@@ -160,7 +154,7 @@ export default {
answerText,
submitAnswer,
loading,
isAnswerExist
isAnswerExist,
};
},
};
@@ -227,7 +221,7 @@ export default {
variant="primary"
class="me-2"
:disabled="loading"
@click="submitAnswer(1)"
@click="submitAnswer(`edit`)"
>
<span
v-if="loading"
@@ -244,7 +238,7 @@ export default {
variant="primary"
class="me-2"
:disabled="loading"
@click="submitAnswer(0)"
@click="submitAnswer(`add`)"
>
<span
v-if="loading"


+ 5
- 4
src/views/live-preview/pages/orders/approvedOrders.vue 查看文件

@@ -59,10 +59,10 @@ export default {
};

const convertToJalali = (date) => {
return moment(date, "YYYY-MM-DD HH:mm:ss")
.locale("fa")
.format("jYYYY/jMM/jDD HH:mm:ss");
};
return moment(date, "YYYY-MM-DD HH:mm:ss")
.locale("fa")
.format("jYYYY/jMM/jDD HH:mm:ss");
};

const getFile = () => {
isLoading.value = true;
@@ -336,6 +336,7 @@ export default {
{{ product.product?.brand?.title }}
</td>
<td class="text-center">
<img
:src="product.product?.brand?.image"
alt="user-image"


+ 42
- 2
src/views/live-preview/pages/orders/singleOrder.vue 查看文件

@@ -49,7 +49,7 @@ export default {
ApiServiece.get(`admin/orders/${route.params.id}`)
.then((resp) => {
order.value = resp.data.data;
console.log(order.value);
console.log(order.value, "order");
})
.catch((error) => {
console.error("Failed to fetch order details:", error);
@@ -109,7 +109,7 @@ export default {
updateShippedCount,
updateNote,
updateStatus,
formatWithCommas
formatWithCommas,
};
},
};
@@ -126,6 +126,46 @@ export default {
<h5 class="mb-0">جزئیات سفارش</h5>
</BCardHeader>
<BCardBody v-if="order">
<div class="mb-4">
<BRow class="mb-2">
<BCol md="6"
><strong>نام مشتری:</strong>
{{ order?.user || "بدون نام" }}</BCol
>
</BRow>
<BRow class="mb-2">
<BCol md="6"
><strong>آدرس:</strong>
{{ order?.user_address || "بدون آدرس" }}</BCol
>
</BRow>
<BRow class="mb-2">
<BCol md="6"
><strong>هزینه ارسال:</strong>
{{ formatWithCommas(order.shipping_price) }} تومان</BCol
>
<BCol md="6"
><strong>تخفیف:</strong>
{{ formatWithCommas(order.discount) }} تومان</BCol
>
</BRow>
<BRow class="mb-2">
<BCol md="6"
><strong>قیمت کل:</strong>
{{
formatWithCommas(
order.total_price + order.shipping_price - order.discount
)
}}
تومان
</BCol>
<BCol md="6"
><strong>رنگ سفارش:</strong> {{ order.color || "---" }}</BCol
>
</BRow>
</div>

<!-- Order Details and Items Here -->

<h6 class="mt-4 mb-3">آیتم های سفارش</h6>


+ 38
- 16
src/views/live-preview/pages/products/addProduct.vue 查看文件

@@ -556,10 +556,7 @@
</div>
</div>
</BCardFooter>
<addIdentity
:cats="categories"
@identity-updated="handleIdentityUpdate"
/>
<addIdentity @identity-updated="handleIdentityUpdate" />
<addAttribute
:attributeValues="attributeValues"
@attribute-updated="handleAttributeUpdated()"
@@ -788,10 +785,18 @@ export default {
errors.value.description = "وارد کردن توضیحات محصول ضروری می باشد";
if (!productType.value)
errors.value.productType = "انتخاب حالت محصول ضروری می باشد";



if (!isChosen.value && spescial.value == 0)
errors.value.isChosen = "انتخاب کنید محصول منتخب هست یا خیر";
if (!spescial.value && isChosen.value == 0)
errors.value.spescial = "انتخاب کنید محصول ویژه هست یا خیر";





if (!retailePrice.value && productType.value == 1)
errors.value.retailePrice = "قیمت محصول تک را وارد نمایید";
if (!wholesalePrice.value && productType.value == 2)
@@ -868,8 +873,23 @@ export default {
formData.append("slug", slug.value);
formData.append("summary", summary.value);
formData.append("description", description.value);
formData.append("is_special", spescial.value);
formData.append("is_chosen", isChosen.value);

if (isChosen.value == 1) {
formData.append("is_chosen", isChosen.value);
formData.append("is_special", 0);
}
if (isChosen.value == 0 && spescial.value == 0) {
formData.append("is_chosen", 0);
formData.append("is_special", 0);
}

if (spescial.value == 1) {
formData.append("is_chosen", 0);
formData.append("is_special", spescial.value);
}


if (productType.value == 2) {
formData.append("wholesale_price", wholesalePrice.value);
}
@@ -894,12 +914,13 @@ export default {
expire.value,
"jYYYY/jMM/jDD HH:mm:ss"
).format("YYYY/MM/DD HH:mm:ss");
formData.append("special_expires_at", georgianDate);
}

formData.append("brand_id", selectedBrand.value);
formData.append("category_id", selectedCat.value);
if (productType.value === "2" || productType.value === "3") {
formData.append("count_in_carton", countInCarton.value);
}
@@ -970,15 +991,6 @@ export default {
position: "top-right",
autoClose: 1000,
});
})
.catch((error) => {
console.error(error);
toast.error(`${error?.response?.data?.message}`, {
position: "top-right",
autoClose: 1000,
});
})
.finally(() => {
loading.value = false;
title.value = "";
imagePreview.value = null;
@@ -1005,6 +1017,16 @@ export default {
relatedAttrebutes.value.forEach((identity) => {
identity.isChecked = false;
});
})
.catch((error) => {
loading.value = false;
toast.error(`${error?.response?.data?.message}`, {
position: "top-right",
autoClose: 1000,
});
})
.finally(() => {
loading.value = false;
});
};



+ 42
- 43
src/views/live-preview/pages/products/editProduct.vue 查看文件

@@ -289,6 +289,7 @@
<VueSelect
:isLoading="categorySelectorLoader"
v-model="selectedCat"
:reduce="(option) => option.value"
:options="formattedCategories"
placeholder="دسته ای را انتخاب کنید"
/>
@@ -305,6 +306,7 @@
v-model="selectedBrand"
:isLoading="brandSelectorLoader"
:options="formattedBrands"
:reduce="(option) => option.value"
placeholder="برندی را انتخاب کنید"
@search="handleBrandSearch"
/>
@@ -316,13 +318,16 @@

<BCard v-if="locals.length !== 0">
<BRow class="g-3 mt-2">
<!-- Loop through attributes -->
<div class="card-header">
<h5 class="mb-0">ویرایش ویژگی ها</h5>
</div>
<BCol
v-for="attrebute in locals"
:key="attrebute.id"
md="6"
lg="4"
>
<div class="card shadow-sm">
<div class="card-body">
<!-- Card Header with Delete Icon -->
@@ -330,9 +335,7 @@
class="d-flex justify-content-between align-items-center"
>
<!-- Optional Title or Heading for the card -->
<div class="card-title">
<!-- You can add a title or leave it empty if you don't need one -->
</div>
<div class="card-title"></div>

<!-- Delete Icon -->
<button
@@ -391,7 +394,7 @@
<button
class="btn btn-primary"
@click="
editAttribute(attrebute.id, attrebute.value)
editAttribute(attrebute.id, attrebute.value , attrebute.attribute_value_id)
"
>
ویرایش
@@ -834,6 +837,7 @@ export default {
code: null,
inventory: null,
isChecked: null,
attribute_value_id: null,
},
]);
const localIdentities = ref([]);
@@ -857,7 +861,7 @@ export default {
const productAttributes = ref([]);
const images = ref([{ file: null, preview: null }]);
const localImages = ref([{ preview: null }]);
const brands = ref();
const attrebutes = ref([]);
const selectedBrand = ref();
const selectedCat = ref();
@@ -877,27 +881,12 @@ export default {
const blogCat = ref();
const author = ref("");
const editor = ref(null);
const categories = ref([]);
const categories = ref([{ id: null, title: "" }]);
const brands = ref([{ id: null, title: "" }]);
const editorContent = ref("");
const categorySelectorLoader = ref(false);
const brandSelectorLoader = ref(false);

const getCats = () => {
ApiServiece.get("admin/categories").then((resp) => {
categories.value = resp.data.data;
});

console.log(categories.value, "cats");
};

const getBrands = () => {
ApiServiece.get("admin/brands").then((resp) => {
brands.value = resp.data.data;
});

console.log(brands.value, "brands");
};

const formattedCategories = computed(() =>
Array.isArray(categories.value)
? categories.value.map((category) => ({
@@ -931,7 +920,7 @@ export default {
ApiServiece.get(`admin/attributes?category_id=${selectedCat.value}`)
.then((resp) => {
identities.value = resp.data.data;
console.log(identities.value);
console.log(identities.value , "identities");
})
.then(() => {
localIdentitiesIds.value = localIdentities.value.map(
@@ -1155,10 +1144,15 @@ export default {
errors.value.description = "وارد کردن توضیحات محصول ضروری می باشد";
if (!productType.value)
errors.value.productType = "انتخاب حالت محصول ضروری می باشد";
if (!isChosen.value && spescial.value == 0)

if (isChosen.value === undefined || isChosen.value === null) {
errors.value.isChosen = "انتخاب کنید محصول منتخب هست یا خیر";
if (!spescial.value && isChosen.value == 0)
}

if (spescial.value === undefined || spescial.value === null) {
errors.value.spescial = "انتخاب کنید محصول ویژه هست یا خیر";
}

if (!retailePrice.value && productType.value == 1)
errors.value.retailePrice = "قیمت محصول تک را وارد نمایید";
if (!wholesalePrice.value && productType.value == 2)
@@ -1217,9 +1211,11 @@ export default {
const getProduct = () => {
ApiServiece.get(`admin/products/${route.params.id}`)
.then((resp) => {
console.log(resp);
categories.value[0].id = resp?.data?.data?.category.id;
categories.value[0].title = resp?.data?.data?.category.title;
brands.value[0].id = resp?.data?.data?.brand.id;
brands.value[0].title = resp?.data?.data?.brand.title;
productValueId.value = resp.data.data;
console.log(resp.data.data.product_attributes);
product.value = resp.data.data;
title.value = product.value?.title;
slug.value = product.value?.slug;
@@ -1233,6 +1229,9 @@ export default {
chosenPrice.value = product.value?.chosen_price;
spescial.value = product.value?.is_special;
spescialPrice.value = product.value?.special_price;
selectedCat.value = resp?.data?.data?.category.id;
selectedBrand.value = resp?.data?.data?.brand.id;

if (product.value?.special_expires_at) {
expire.value = moment(
product.value.special_expires_at,
@@ -1261,6 +1260,7 @@ export default {
title: productAttribute.attribute_value.title,
code: productAttribute.attribute_value.code,
inventory: productAttribute.inventory,
attribute_value_id: productAttribute.attribute_value_id,
isChecked: productAttribute.inventory > 0,
value: productAttribute.inventory,
};
@@ -1303,7 +1303,7 @@ export default {
});
};

const editAttribute = (id, inventory) => {
const editAttribute = (id, inventory , attrebuteValueId) => {
Swal.fire({
text: "آیا برای ویرایش ویژگی اطمینان دارید؟",
icon: "warning",
@@ -1315,6 +1315,7 @@ export default {
if (result.isConfirmed) {
const formData = new FormData();
formData.append("inventory", inventory);
formData.append("attribute_value_id", attrebuteValueId);

ApiServiece.put(
`admin/products/${route.params.id}/attributes/${id}`,
@@ -1373,8 +1374,6 @@ export default {

onMounted(() => {
getAttrebuteValues();
getCats();
getBrands();
});
let id = "";
const submitForm = () => {
@@ -1394,9 +1393,11 @@ export default {
formData.append("slug", slug.value);
formData.append("summary", summary.value);
formData.append("description", description.value);
if (productType.value === "2" || productType.value === "3") {

if (productType.value == 2 || productType.value == 3) {
formData.append("count_in_carton", countInCarton.value);
}

if (productType.value == 2) {
formData.append("wholesale_price", wholesalePrice.value);
}
@@ -1413,14 +1414,6 @@ export default {
formData.append("chosen_price", chosenPrice.value);
}

if (isChosen.value == 1 && spescial.value == 0) {
formData.append("is_chosen", isChosen.value);
}

if (isChosen.value == 0 && spescial.value == 1) {
formData.append("is_chosen", isChosen.value);
}

if (spescial.value == 1 && isChosen.value == 0) {
if (spescialPrice.value) {
formData.append("special_price", parseInt(spescialPrice.value, 10));
@@ -1436,11 +1429,17 @@ export default {
}
}

if (spescial.value == 1 && isChosen.value == 0) {
formData.append("is_special", spescial.value);
if (isChosen.value == 1) {
formData.append("is_chosen", isChosen.value);
formData.append("is_special", 0);
}
if (isChosen.value == 0 && spescial.value == 0) {
formData.append("is_chosen", 0);
formData.append("is_special", 0);
}

if (spescial.value == 0 && isChosen.value == 1) {
if (spescial.value == 1) {
formData.append("is_chosen", 0);
formData.append("is_special", spescial.value);
}



正在加载...
取消
保存