選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。
 
 
 

827 行
28 KiB

  1. <template>
  2. <Layout>
  3. <BRow>
  4. <BCol sm="12">
  5. <BCard no-body>
  6. <BCardHeader>
  7. <div class="d-flex justify-content-between align-items-center">
  8. <h5>ویرایش بنر</h5>
  9. <!-- Help and Modal buttons -->
  10. <div>
  11. <button
  12. v-if="pageType === 'main_page'"
  13. data-bs-toggle="modal"
  14. data-bs-target="#mainPageBanner"
  15. class="btn btn-info btn-sm mx-2"
  16. @click="showHelp"
  17. >
  18. <i class="fa fa-question-circle"></i> راهنمایی بنر صفحه اصلی
  19. </button>
  20. <button
  21. data-bs-toggle="modal"
  22. data-bs-target="#catBanner"
  23. class="btn btn-info btn-sm mx-2"
  24. @click="showModal"
  25. v-if="pageType === 'category'"
  26. >
  27. <i class="fa fa-info-circle"></i> راهنمایی بنر دسته ها
  28. </button>
  29. <button
  30. data-bs-toggle="modal"
  31. data-bs-target="#specialPageBanner"
  32. class="btn btn-info btn-sm mx-2"
  33. @click="showModal"
  34. v-if="pageType === 'special_page'"
  35. >
  36. <i class="fa fa-info-circle"></i> راهنمایی بنر فروش ویژه
  37. </button>
  38. <button
  39. data-bs-toggle="modal"
  40. data-bs-target="#specialPageBanner"
  41. class="btn btn-info btn-sm mx-2"
  42. @click="showModal"
  43. v-if="pageType === 'blog_page'"
  44. >
  45. <i class="fa fa-info-circle"></i>ر راهنمایی بنر بلاگ
  46. </button>
  47. <button
  48. v-if="pageType === 'brand'"
  49. data-bs-toggle="modal"
  50. data-bs-target="#brandBanner"
  51. class="btn btn-info btn-sm mx-2"
  52. @click="showModal"
  53. >
  54. <i class="fa fa-info-circle"></i> راهنمایی بنر برند
  55. </button>
  56. </div>
  57. </div>
  58. </BCardHeader>
  59. <BCardBody>
  60. <BRow class="g-3">
  61. <BCol md="6">
  62. <div class="form-group">
  63. <label class="form-label">عنوان</label>
  64. <input
  65. type="text"
  66. v-model="title"
  67. class="form-control"
  68. placeholder="عنوان بنر"
  69. :class="{ 'is-invalid': errors.title }"
  70. @input="clearError('title')"
  71. />
  72. </div>
  73. <small v-if="errors.title" class="text-danger">
  74. {{ errors.title }}
  75. </small>
  76. </BCol>
  77. <BCol md="6">
  78. <div class="form-group">
  79. <label class="form-label">پنل نمایش</label>
  80. <select
  81. class="form-select"
  82. aria-label="Default select example"
  83. v-model="pannel"
  84. @change="clearError('pannel')"
  85. :class="{ 'is-invalid': errors.pannel }"
  86. placeholder="انخاب پنل"
  87. >
  88. <option value="wholesale">پنل عمده فروشی</option>
  89. <option value="web">وب سایت و اپلیکیشن</option>
  90. </select>
  91. </div>
  92. <small v-if="errors.pannel" class="text-danger">
  93. {{ errors.pannel }}
  94. </small>
  95. </BCol>
  96. <BCol v-if="pannel === 'web' && pannel" md="6">
  97. <div class="form-group">
  98. <label class="form-label">نمایش در</label>
  99. <select
  100. v-model="pageType"
  101. :class="{ 'is-invalid': errors.pageType }"
  102. class="form-select"
  103. aria-label="Default select example"
  104. @change="clearError('pageType')"
  105. placeholder="انخاب صفحه اصلی"
  106. >
  107. <option value="main_page">صفحه اصلی</option>
  108. <option value="category">صفحه دسته</option>
  109. <option value="special_page">صفحه فروش ویژه</option>
  110. <option value="brand">صفحه برند</option>
  111. <option value="blog_page">صفحه بلاگ</option>
  112. </select>
  113. </div>
  114. <small v-if="errors.pageType" class="text-danger">
  115. {{ errors.pageType }}
  116. </small>
  117. </BCol>
  118. <BCol v-if="pageType === 'category' && pannel === 'web'" md="6">
  119. <div class="form-group">
  120. <label class="form-label">صفحه دسته</label>
  121. <VueSelect
  122. style="--vs-min-height: 48px; --vs-border-radius: 8px"
  123. v-model="selectedCatPage"
  124. @change="clearError('selectedCatPage')"
  125. label="label"
  126. :isLoading="categoryPageSelectorLoader"
  127. :reduce="(option) => option.value"
  128. :options="formattedCatPages"
  129. @search="handleCategoryPageSearch"
  130. placeholder="دسته ای را انتخاب کنید"
  131. />
  132. </div>
  133. <small v-if="errors.selectedCatPage" class="text-danger">
  134. {{ errors.selectedCatPage }}
  135. </small>
  136. </BCol>
  137. <BCol v-if="pageType === 'brand' && pannel === 'web'" md="6">
  138. <div class="form-group">
  139. <label class="form-label">صفحه برند</label>
  140. <VueSelect
  141. style="--vs-min-height: 48px; --vs-border-radius: 8px"
  142. v-model="selectedBrandPage"
  143. label="label"
  144. :isLoading="brandSelectorLoader"
  145. :reduce="(option) => option.value"
  146. :options="formattedBrands"
  147. @change="clearError(`selectedBrandPage`)"
  148. placeholder="برندی را انتخاب کنید"
  149. @search="handleBrandSearch"
  150. />
  151. </div>
  152. <small v-if="errors.selectedBrandPage" class="text-danger">
  153. {{ errors.selectedBrandPage }}
  154. </small>
  155. </BCol>
  156. <BCol v-if="pannel == 'web' && pannel" md="6">
  157. <div class="form-group">
  158. <label class="form-label">انتخاب صفحه فرود</label>
  159. <select
  160. class="form-select"
  161. aria-label="Default select example"
  162. v-model="landingType"
  163. @change="clearError('landingType')"
  164. :class="{ 'is-invalid': errors.landingType }"
  165. placeholder="انتخاب صفحه فرود"
  166. >
  167. <option value="product">صفحه محصولات</option>
  168. <option value="cat">صفحه دسته ها</option>
  169. </select>
  170. </div>
  171. <small v-if="errors.landingType" class="text-danger">
  172. {{ errors.landingType }}
  173. </small>
  174. </BCol>
  175. <BCol
  176. v-if="landingType === 'product'"
  177. sm="6"
  178. class="mt-3"
  179. style="margin-top: 30px"
  180. >
  181. <label for="token">صفحه کدام محصول</label>
  182. <VueSelect
  183. style="
  184. --vs-min-height: 48px;
  185. --vs-border-radius: 8px;
  186. margin-top: 7px;
  187. "
  188. v-model="selectedLandingProduct"
  189. :reduce="(option) => option.value"
  190. label="label"
  191. :isLoading="productSelectorLoader"
  192. :options="formattedProducts"
  193. @search="handleProductSearch"
  194. placeholder="محصولی را انتخاب کنید"
  195. />
  196. <small v-if="errors.selectedLandingProduct" class="text-danger">
  197. {{ errors.selectedLandingProduct }}
  198. </small>
  199. </BCol>
  200. <BCol v-if="landingType === 'cat'" md="6">
  201. <div class="form-group">
  202. <label class="form-label">صفحه کدام دسته </label>
  203. <VueSelect
  204. style="--vs-min-height: 48px; --vs-border-radius: 8px"
  205. :isLoading="categorySelectorLoader"
  206. @change="clearError('selectedLandingCat')"
  207. label="label"
  208. v-model="selectedLandingCat"
  209. :reduce="(option) => option.value"
  210. :options="formattedCategories"
  211. placeholder="دسته ای را انتخاب کنید"
  212. @search="handleSearch"
  213. />
  214. </div>
  215. <small v-if="errors.selectedLandingCat" class="text-danger">
  216. {{ errors.selectedLandingCat }}
  217. </small>
  218. </BCol>
  219. <BCol v-if="pageType === 'main_page' && pannel === 'web'" md="6">
  220. <div class="form-group">
  221. <label class="form-label">موقعیت در صفحه اصلی</label>
  222. <select
  223. class="form-select"
  224. aria-label="Default select example"
  225. v-model="selectedLoc"
  226. @change="clearError('selectedLoc')"
  227. :class="{ 'is-invalid': errors.selectedLoc }"
  228. placeholder="موقعیت بنر"
  229. >
  230. <option value="A">َA-Slideshow</option>
  231. <option value="B">B-Banner</option>
  232. <option value="C">C-Banner</option>
  233. <option value="D">D-Banner</option>
  234. <option value="E">E-Banner</option>
  235. <option value="F">F-Banner</option>
  236. <option value="G">G-Banner</option>
  237. <option value="H">H-Banner</option>
  238. <option value="I">I-Banner</option>
  239. <option value="J">J-Banner</option>
  240. </select>
  241. </div>
  242. <small v-if="errors.selectedLoc" class="text-danger">
  243. {{ errors.selectedLoc }}
  244. </small>
  245. </BCol>
  246. <BCol v-if="pageType === 'category' && pannel === 'web'" md="6">
  247. <div class="form-group">
  248. <label class="form-label">موقعیت در صفحه دسته ها</label>
  249. <select
  250. class="form-select"
  251. aria-label="Default select example"
  252. v-model="selectedLoc"
  253. @change="clearError('selectedLoc')"
  254. :class="{ 'is-invalid': errors.selectedLoc }"
  255. placeholder="موقعیت بنر"
  256. >
  257. <option value="A">َA-Slideshow</option>
  258. <option value="B">B-Banner</option>
  259. <option value="C">C-Banner</option>
  260. <option value="D">D-Banner</option>
  261. <option value="E">E-Banner</option>
  262. <option value="F">F-Banner</option>
  263. <option value="G">G-Banner</option>
  264. <option value="H">H-Banner</option>
  265. <option value="I">I-Banner</option>
  266. </select>
  267. </div>
  268. <small v-if="errors.selectedLoc" class="text-danger">
  269. {{ errors.selectedLoc }}
  270. </small>
  271. </BCol>
  272. <BCol
  273. v-if="pageType === 'special_page' && pannel === 'web'"
  274. md="6"
  275. >
  276. <div class="form-group">
  277. <label class="form-label">موقعیت در صفحه فروش ویژه</label>
  278. <select
  279. class="form-select"
  280. aria-label="Default select example"
  281. v-model="selectedLoc"
  282. @change="clearError('selectedLoc')"
  283. :class="{ 'is-invalid': errors.selectedLoc }"
  284. placeholder="موقعیت بنر"
  285. :value="(selectedLoc = 'A')"
  286. >
  287. <option value="A">A-Slideshow</option>
  288. </select>
  289. </div>
  290. <small v-if="errors.selectedLoc" class="text-danger">
  291. {{ errors.selectedLoc }}
  292. </small>
  293. </BCol>
  294. <BCol v-if="pageType === 'brand' && pannel === 'web'" md="6">
  295. <div class="form-group">
  296. <label class="form-label">موقعیت در صفحه برند</label>
  297. <select
  298. class="form-select"
  299. aria-label="Default select example"
  300. v-model="selectedLoc"
  301. @change="clearError('selectedLoc')"
  302. :class="{ 'is-invalid': errors.selectedLoc }"
  303. placeholder="موقعیت بنر"
  304. >
  305. <option value="A">َA-Slideshow</option>
  306. <option value="B">B-Banner</option>
  307. <option value="C">C-Banner</option>
  308. <option value="D">D-Banner</option>
  309. <option value="E">E-Banner</option>
  310. <option value="F">F-Banner</option>
  311. <option value="G">G-Banner</option>
  312. <option value="H">H-Banner</option>
  313. <option value="I">I-Banner</option>
  314. <option value="J">J-Banner</option>
  315. </select>
  316. </div>
  317. <small v-if="errors.selectedLoc" class="text-danger">
  318. {{ errors.selectedLoc }}
  319. </small>
  320. </BCol>
  321. <BCol
  322. v-if="pageType === 'blog_page' && pannel === 'web'"
  323. md="6"
  324. >
  325. <div class="form-group">
  326. <label class="form-label">موقعیت در صفحه بلاگ</label>
  327. <select
  328. class="form-select"
  329. aria-label="Default select example"
  330. v-model="selectedLoc"
  331. @change="clearError('selectedLoc')"
  332. :class="{ 'is-invalid': errors.selectedLoc }"
  333. placeholder="موقعیت بنر"
  334. :value="(selectedLoc = 'A')"
  335. >
  336. <option value="A">A-Banner</option>
  337. </select>
  338. </div>
  339. <small v-if="errors.selectedLoc" class="text-danger">
  340. {{ errors.selectedLoc }}
  341. </small>
  342. </BCol>
  343. <BCol md="6">
  344. <div class="form-group">
  345. <label class="form-label">تصویر بنر</label>
  346. <input
  347. type="file"
  348. accept="image/*"
  349. @change="handleImageUpload"
  350. class="form-control"
  351. :class="{ 'is-invalid': errors.imagePreview }"
  352. />
  353. <div v-if="imagePreview" class="mt-2">
  354. <img
  355. :src="imagePreview"
  356. alt="Image Preview"
  357. class="img-fluid rounded shadow-sm Image-Preview"
  358. />
  359. </div>
  360. <small v-if="errors.imagePreview" class="text-danger">
  361. {{ errors.imagePreview }}
  362. </small>
  363. </div>
  364. </BCol>
  365. </BRow>
  366. </BCardBody>
  367. <BCardFooter>
  368. <div class="d-flex justify-content-center">
  369. <div class="text-center">
  370. <button
  371. type="submit"
  372. class="btn btn-primary"
  373. @click.prevent="submitForm"
  374. :disabled="loading"
  375. >
  376. <span v-if="loading">
  377. <i class="fa fa-spinner fa-spin"></i> ویرایش...
  378. </span>
  379. <span v-else>ویرایش</span>
  380. </button>
  381. </div>
  382. </div>
  383. </BCardFooter>
  384. </BCard>
  385. </BCol>
  386. </BRow>
  387. <mainPageBanner />
  388. <catBanner />
  389. <specialBanner />
  390. <brandBanner />
  391. </Layout>
  392. </template>
  393. <script>
  394. import VueSelect from "vue3-select-component";
  395. import { useRoute } from "vue-router";
  396. import catBanner from "@/components/modals/helperModals/catBanner.vue";
  397. import mainPageBanner from "@/components/modals/helperModals/mainPageBanner.vue";
  398. import specialBanner from "@/components/modals/helperModals/specialBanner.vue";
  399. import brandBanner from "@/components/modals/helperModals/brandBanner.vue";
  400. import { toast } from "vue3-toastify";
  401. import "vue3-toastify/dist/index.css";
  402. import ApiServiece from "@/services/ApiService";
  403. import { ref, onMounted, computed } from "vue";
  404. import Layout from "@/layout/custom.vue";
  405. export default {
  406. name: "SAMPLE-PAGE",
  407. components: {
  408. Layout,
  409. mainPageBanner,
  410. catBanner,
  411. VueSelect,
  412. specialBanner,
  413. brandBanner,
  414. },
  415. setup() {
  416. const route = useRoute();
  417. const title = ref();
  418. const pageType = ref();
  419. const products = ref([{ id: null, title: "" }]);
  420. const brands = ref([{ id: null, title: "" }]);
  421. const cats = ref([{ id: null, title: "" }]);
  422. const catPages = ref([{ id: null, title: "" }]);
  423. const landingType = ref();
  424. const selectedCatPage = ref();
  425. const selectedLandingCat = ref();
  426. const selectedLandingProduct = ref();
  427. const selectedLoc = ref();
  428. const pannel = ref();
  429. const image = ref();
  430. const imagePreview = ref();
  431. const selectedBrandPage = ref();
  432. const loading = ref(false);
  433. const errors = ref({});
  434. const categorySelectorLoader = ref(false);
  435. const productSelectorLoader = ref(false);
  436. const categoryPageSelectorLoader = ref(false);
  437. const brandSelectorLoader = ref(false);
  438. const formattedCategories = computed(() =>
  439. Array.isArray(cats.value)
  440. ? cats.value.map((cat) => ({
  441. value: cat.id,
  442. label: cat.title,
  443. }))
  444. : []
  445. );
  446. const handleSearch = async (searchTerm) => {
  447. if (searchTerm.length < 3) return;
  448. categorySelectorLoader.value = true;
  449. try {
  450. const response = await ApiServiece.get(
  451. `admin/categories?title=${searchTerm}`
  452. );
  453. cats.value = response.data.data;
  454. categorySelectorLoader.value = false;
  455. } catch (error) {
  456. categorySelectorLoader.value = false;
  457. cats.value = [];
  458. }
  459. };
  460. const formattedProducts = computed(() =>
  461. Array.isArray(products.value)
  462. ? products.value.map((product) => ({
  463. value: product.id,
  464. label: product.title,
  465. }))
  466. : []
  467. );
  468. const handleProductSearch = async (searchTerm) => {
  469. if (searchTerm.length < 3) return;
  470. productSelectorLoader.value = true;
  471. try {
  472. const response = await ApiServiece.get(
  473. `admin/products?title=${searchTerm}`
  474. );
  475. products.value = response.data.data;
  476. productSelectorLoader.value = false;
  477. } catch (error) {
  478. productSelectorLoader.value = false;
  479. products.value = [];
  480. }
  481. };
  482. const formattedCatPages = computed(() =>
  483. Array.isArray(catPages.value)
  484. ? catPages.value.map((catPage) => ({
  485. value: catPage.id,
  486. label: catPage.title,
  487. }))
  488. : []
  489. );
  490. const handleCategoryPageSearch = async (searchTerm) => {
  491. if (searchTerm.length < 3) return;
  492. categoryPageSelectorLoader.value = true;
  493. try {
  494. const response = await ApiServiece.get(
  495. `admin/categories/parents?title=${searchTerm}`
  496. );
  497. catPages.value = response.data.data;
  498. categoryPageSelectorLoader.value = false;
  499. } catch (error) {
  500. categoryPageSelectorLoader.value = false;
  501. catPages.value = [];
  502. }
  503. };
  504. const formattedBrands = computed(() =>
  505. Array.isArray(brands.value)
  506. ? brands.value.map((brand) => ({
  507. value: brand.id,
  508. label: brand.title,
  509. }))
  510. : []
  511. );
  512. const handleBrandSearch = async (searchTerm) => {
  513. if (searchTerm.length < 3) return;
  514. brandSelectorLoader.value = true;
  515. try {
  516. const response = await ApiServiece.get(
  517. `admin/brands?title=${searchTerm}`
  518. );
  519. brands.value = response.data.data;
  520. brandSelectorLoader.value = false;
  521. } catch (error) {
  522. brandSelectorLoader.value = false;
  523. brands.value = [];
  524. }
  525. };
  526. const handleImageUpload = (event) => {
  527. const file = event.target.files[0];
  528. if (file) {
  529. errors.value.image = null;
  530. image.value = file;
  531. const reader = new FileReader();
  532. reader.onload = () => {
  533. imagePreview.value = reader.result;
  534. };
  535. reader.readAsDataURL(file);
  536. }
  537. };
  538. const validateForm = () => {
  539. errors.value = {};
  540. if (!title.value) errors.value.title = "وارد کردن عنوان بنر الزامی است";
  541. if (!pageType.value)
  542. errors.value.pageType = "مشخص کنید بنر کجا نشان داده شود";
  543. if (pageType.value === "category" && !selectedCatPage.value)
  544. errors.value.selectedCatPage = "صفحه دسته را انتخاب کنید";
  545. if (pageType.value === "brand" && !selectedBrandPage.value)
  546. errors.value.selectedBrandPage = "صفحه برند را انتخاب کنید";
  547. if (!landingType.value)
  548. errors.value.landingType = "صفحه فرود را انتخاب نمایید";
  549. if (landingType.value === "cat" && !selectedLandingCat.value)
  550. errors.value.selectedLandingCat = "صفحه فرود دسته را انتخاب کنید";
  551. if (landingType.value === "product" && !selectedLandingProduct.value)
  552. errors.value.selectedLandingProduct = "صفحه فرود محصول را انتخاب کنید";
  553. if (!selectedLoc.value)
  554. errors.value.selectedLoc = "موقعیت بنر را انتخاب کنید";
  555. if (!pannel.value) errors.value.pannel = "پنل نمایش بنر را انتخاب کنید";
  556. if (!imagePreview.value)
  557. errors.value.imagePreview = "عکس بنر را وارد نمایید";
  558. return Object.keys(errors.value).length === 0;
  559. };
  560. const clearError = (field) => {
  561. errors.value[field] = "";
  562. };
  563. const getBanner = () => {
  564. ApiServiece.get(`admin/banners/${route.params.id}`)
  565. .then((resp) => {
  566. const data = resp.data.data;
  567. if (resp?.data?.data?.category?.title) {
  568. cats.value[0].id = resp?.data?.data?.category?.id;
  569. cats.value[0].title = resp?.data?.data?.category?.title;
  570. }
  571. if (resp?.data?.data?.product?.title) {
  572. products.value[0].id = resp?.data?.data?.product?.id;
  573. products.value[0].title = resp?.data?.data?.product?.title;
  574. }
  575. if (resp?.data?.data?.category_page?.title) {
  576. catPages.value[0].id = resp?.data?.data?.category_page?.id;
  577. catPages.value[0].title = resp?.data?.data?.category_page?.title;
  578. }
  579. if (resp?.data?.data?.brand_page?.title) {
  580. brands.value[0].id = resp?.data?.data?.brand_page?.id;
  581. brands.value[0].title = resp?.data?.data?.brand_page?.title;
  582. }
  583. title.value = data?.title;
  584. pannel.value = data?.panel;
  585. imagePreview.value = data?.image;
  586. selectedLoc.value = data?.location;
  587. selectedLandingCat.value = data?.category_id;
  588. selectedLandingProduct.value = data?.product_id;
  589. pageType.value = data.page_type;
  590. if (data.page_id && pageType.value === "category") {
  591. selectedCatPage.value = data?.page_id;
  592. }
  593. if (data.page_id && pageType.value === "brand") {
  594. selectedBrandPage.value = data?.page_id;
  595. }
  596. if (selectedLandingProduct.value) {
  597. landingType.value = "product";
  598. }
  599. if (selectedLandingCat.value) {
  600. landingType.value = "cat";
  601. }
  602. })
  603. .catch((err) => {
  604. console.log(err);
  605. });
  606. };
  607. onMounted(() => {
  608. getBanner();
  609. });
  610. const submitForm = () => {
  611. if (!validateForm()) {
  612. toast.error("لطفا فیلد های لازم را وارد نمایید", {
  613. position: "top-right",
  614. autoClose: 1000,
  615. });
  616. return;
  617. }
  618. loading.value = true;
  619. const formData = new FormData();
  620. formData.append("title", title.value);
  621. if (pageType.value === "category") {
  622. formData.append("page_id", selectedCatPage.value);
  623. }
  624. if (pageType.value === "brand") {
  625. formData.append("page_id", selectedBrandPage.value);
  626. }
  627. if (landingType.value === "product") {
  628. formData.append("product_id", selectedLandingProduct.value);
  629. }
  630. if (landingType.value === "cat") {
  631. formData.append("category_id", selectedLandingCat.value);
  632. }
  633. if (selectedLoc.value === "A") {
  634. formData.append("type", pageType.value === 'blog_page' ? "banner" : "slider");
  635. }
  636. if (selectedLoc.value !== "A") {
  637. formData.append("type", "banner");
  638. }
  639. if (pannel.value === "wholesale") {
  640. formData.append("type", "slider");
  641. formData.append("location", "A");
  642. }
  643. formData.append("location", selectedLoc.value);
  644. formData.append("panel", pannel.value);
  645. if(pannel.value === 'web')
  646. formData.append("page_type", pageType.value);
  647. if (image.value) {
  648. formData.append("image", image.value);
  649. }
  650. formData.append("sort", 1);
  651. formData.append("_method", "put");
  652. ApiServiece.post(`admin/banners/${route.params.id}`, formData, {
  653. headers: {
  654. "content-type": "multipart",
  655. Authorization: `Bearer ${localStorage.getItem("token")}`,
  656. },
  657. })
  658. .then((resp) => {
  659. loading.value = false;
  660. toast.success("!بنر با موفقیت ویرایش شد", {
  661. position: "top-right",
  662. autoClose: 1000,
  663. });
  664. console.log(resp);
  665. })
  666. .catch((error) => {
  667. loading.value = false;
  668. console.log(error.response.message);
  669. toast.error(`${error.response.data.message}`, {
  670. position: "top-right",
  671. autoClose: 1000,
  672. });
  673. });
  674. };
  675. return {
  676. cats,
  677. errors,
  678. title,
  679. products,
  680. selectedCatPage,
  681. submitForm,
  682. clearError,
  683. pageType,
  684. formattedProducts,
  685. landingType,
  686. selectedLandingCat,
  687. selectedLandingProduct,
  688. selectedLoc,
  689. pannel,
  690. handleImageUpload,
  691. image,
  692. imagePreview,
  693. loading,
  694. brands,
  695. handleSearch,
  696. formattedCategories,
  697. categorySelectorLoader,
  698. handleProductSearch,
  699. productSelectorLoader,
  700. formattedCatPages,
  701. handleCategoryPageSearch,
  702. categoryPageSelectorLoader,
  703. formattedBrands,
  704. brandSelectorLoader,
  705. handleBrandSearch,
  706. selectedBrandPage,
  707. };
  708. },
  709. };
  710. </script>
  711. <style scoped>
  712. .ql-editor {
  713. direction: rtl;
  714. text-align: right;
  715. }
  716. .ql-editor::before {
  717. content: attr(placeholder);
  718. direction: rtl !important;
  719. text-align: right;
  720. }
  721. .Image-Preview {
  722. min-width: 200px;
  723. max-height: 200px;
  724. min-height: 200px;
  725. max-width: 200px;
  726. object-fit: cover;
  727. border-radius: 8px;
  728. border: 1px solid #ddd;
  729. }
  730. .delete-btn {
  731. display: flex;
  732. align-items: center;
  733. padding: 3px;
  734. font-size: 10px;
  735. background-color: #e74c3c;
  736. color: white;
  737. border: none;
  738. border-radius: 5px;
  739. cursor: pointer;
  740. transition: background-color 0.3s ease, transform 0.2s ease;
  741. gap: 8px;
  742. margin-right: 200px;
  743. }
  744. .delete-btn:hover {
  745. background-color: #c0392b;
  746. transform: scale(1.05);
  747. }
  748. .delete-btn:active {
  749. background-color: #a93226;
  750. }
  751. .delete-btn:focus {
  752. outline: none;
  753. }
  754. </style>