You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

597 line
19 KiB

  1. <script>
  2. import { ref, onMounted, onUnmounted, computed } from "vue";
  3. import ApiServiece from "@/services/ApiService";
  4. import { useRouter } from "vue-router";
  5. import { ChevronDownIcon } from "@zhuowenli/vue-feather-icons";
  6. import simplebar from "simplebar-vue";
  7. import logoWhite from "@/assets/images/logo-white.svg";
  8. import logoDark from "@/assets/images/logo-dark.svg";
  9. import { useStore } from "vuex";
  10. import Swal from "sweetalert2";
  11. import { toast } from "vue3-toastify";
  12. import "vue3-toastify/dist/index.css";
  13. export default {
  14. data() {
  15. return {
  16. logoDark: logoDark,
  17. logoWhite: logoWhite,
  18. };
  19. },
  20. setup() {
  21. const settings = ref()
  22. const logo = ref()
  23. const router = useRouter();
  24. const currentLogo = ref(logoDark);
  25. const store = useStore();
  26. const user = computed(() => store.getters["user/getUser"]);
  27. const updateLogo = () => {
  28. const isDarkTheme =
  29. document.body.getAttribute("data-pc-theme") === "dark";
  30. currentLogo.value = isDarkTheme ? logoWhite : logoDark;
  31. };
  32. const logoutUser = async () => {
  33. try {
  34. const result = await Swal.fire({
  35. text: "شما از سیستم خارج خواهید شد.",
  36. icon: "warning",
  37. showCancelButton: true,
  38. confirmButtonColor: "#3085d6",
  39. cancelButtonColor: "#d33",
  40. confirmButtonText: "بله، خارج شوم",
  41. cancelButtonText: "خیر، باقی بمانم",
  42. });
  43. if (result.isConfirmed) {
  44. await store.dispatch("user/logout");
  45. router.push({ name: "otpLogin" });
  46. console.log("User logged out successfully.");
  47. }
  48. } catch (error) {
  49. console.error("Error logging out:", error);
  50. toast.error("خطا", "مشکلی در فرآیند خروج به وجود آمد.");
  51. }
  52. };
  53. const gotoAccount = () => {
  54. router.push({ name: "profile" });
  55. console.log("asdasd");
  56. };
  57. const getSettings = async () => {
  58. const localLogo = localStorage.getItem("logo")
  59. if(localLogo){
  60. logo.value = localLogo;
  61. }
  62. else {
  63. try {
  64. const response = await ApiServiece.get("settings/logo_fav");
  65. settings.value = response.data.data;
  66. logo.value = settings.value.value;
  67. localStorage.setItem("logo" , logo.value)
  68. } catch (error) {
  69. console.error("Error fetching settings:", error);
  70. }
  71. }
  72. };
  73. onMounted(() => {
  74. updateLogo();
  75. getSettings();
  76. const observer = new MutationObserver(() => {
  77. updateLogo();
  78. });
  79. observer.observe(document.body, {
  80. attributes: true,
  81. attributeFilter: ["data-pc-theme"],
  82. });
  83. onUnmounted(() => {
  84. observer.disconnect();
  85. });
  86. });
  87. return { currentLogo, user, logoutUser, gotoAccount , logo , settings };
  88. },
  89. components: {
  90. ChevronDownIcon,
  91. simplebar,
  92. },
  93. methods: {
  94. changeLayoutType(layoutType) {
  95. // Update the layout type in the store
  96. this.$store.commit("changeLayoutType", { layoutType });
  97. // Set the layout attribute based on the layout type
  98. document.body.setAttribute("data-pc-layout", layoutType);
  99. },
  100. },
  101. computed: {
  102. layoutType: {
  103. get() {
  104. return this.$store.state.layout.layoutType;
  105. },
  106. set(layoutType) {
  107. this.$store.commit("changeLayoutType", { layoutType });
  108. },
  109. },
  110. },
  111. watch: {
  112. layoutType: {
  113. immediate: true,
  114. deep: true,
  115. handler(newVal, oldVal) {
  116. if (newVal !== oldVal) {
  117. switch (newVal) {
  118. case "horizontal":
  119. document.body.setAttribute("data-pc-layout", "horizontal");
  120. break;
  121. case "vertical":
  122. document.body.setAttribute("data-pc-layout", "vertical");
  123. }
  124. }
  125. },
  126. },
  127. },
  128. mounted() {
  129. const activeListItem = document.querySelector("li.active");
  130. if (activeListItem) {
  131. const parentElementOrSelf = activeListItem?.parentElement
  132. ? activeListItem.parentElement
  133. : activeListItem;
  134. if (
  135. parentElementOrSelf &&
  136. !parentElementOrSelf.classList.contains("pc-navbar")
  137. ) {
  138. const closestItem =
  139. parentElementOrSelf.parentElement.closest(".pc-item");
  140. if (closestItem) {
  141. closestItem.classList.add("active");
  142. closestItem.children[1].classList.add("show");
  143. }
  144. }
  145. /**
  146. * Sidebar menu collapse
  147. */
  148. if (document.querySelectorAll(".navbar-content .collapse")) {
  149. let collapses = document.querySelectorAll(".navbar-content .collapse");
  150. collapses.forEach((collapse) => {
  151. collapse.addEventListener("show.bs.collapse", (e) => {
  152. e.stopPropagation();
  153. let closestCollapse = collapse.parentElement.closest(".collapse");
  154. if (closestCollapse) {
  155. let siblingCollapses =
  156. closestCollapse.querySelectorAll(".collapse");
  157. siblingCollapses.forEach((siblingCollapse) => {
  158. if (siblingCollapse.classList.contains("show")) {
  159. siblingCollapse.classList.remove("show");
  160. siblingCollapse.parentElement.firstChild.setAttribute(
  161. "aria-expanded",
  162. "false"
  163. );
  164. }
  165. });
  166. } else {
  167. let getSiblings = (elem) => {
  168. // Setup siblings array and get the first sibling
  169. let siblings = [];
  170. let sibling = elem.parentNode.firstChild;
  171. // Loop through each sibling and push to the array
  172. while (sibling) {
  173. if (sibling.nodeType === 1 && sibling !== elem) {
  174. siblings.push(sibling);
  175. }
  176. sibling = sibling.nextSibling;
  177. }
  178. return siblings;
  179. };
  180. let siblings = getSiblings(collapse.parentElement);
  181. siblings.forEach((item) => {
  182. if (item.childNodes.length > 2) {
  183. item.firstElementChild.setAttribute("aria-expanded", "false");
  184. item.firstElementChild.classList.remove("active");
  185. }
  186. let ids = item.querySelectorAll("*[id]");
  187. ids.forEach((item1) => {
  188. item1.classList.remove("show");
  189. item1.parentElement.firstChild.setAttribute(
  190. "aria-expanded",
  191. "false"
  192. );
  193. item1.parentElement.firstChild.classList.remove("active");
  194. if (item1.childNodes.length > 2) {
  195. let val = item1.querySelectorAll("ul li a");
  196. val.forEach((subitem) => {
  197. if (subitem.hasAttribute("aria-expanded"))
  198. subitem.setAttribute("aria-expanded", "false");
  199. });
  200. }
  201. });
  202. });
  203. }
  204. });
  205. // Hide nested collapses on `hide.bs.collapse`
  206. collapse.addEventListener("hide.bs.collapse", (e) => {
  207. e.stopPropagation();
  208. let childCollapses = collapse.querySelectorAll(".collapse");
  209. childCollapses.forEach((childCollapse) => {
  210. let childCollapseInstance = childCollapse;
  211. childCollapseInstance.classList.remove("show");
  212. childCollapseInstance.parentElement.firstChild.setAttribute(
  213. "aria-expanded",
  214. "false"
  215. );
  216. });
  217. });
  218. });
  219. }
  220. } else {
  221. console.error("No list item with class 'active' found.");
  222. }
  223. },
  224. };
  225. </script>
  226. <template>
  227. <div class="navbar-wrapper" id="navbar-wrapper">
  228. <div class="m-header">
  229. <!-- ======== Change your logo from here ============ -->
  230. <img
  231. v-if="currentLogo === logoDark"
  232. :src="logo"
  233. alt="logo image"
  234. class="logo-img"
  235. />
  236. <img
  237. v-else
  238. :src="logo"
  239. alt="logo image"
  240. class="logo-img"
  241. />
  242. </div>
  243. <simplebar data-simplebar class="navbar-content pc-trigger">
  244. <ul class="pc-navbar">
  245. <li class="pc-item" :class="{ active: this.$route.path === '/users' }">
  246. <router-link to="/users" class="pc-link">
  247. <span class="pc-micon">
  248. <i class="ph-duotone ph-user-circle"></i>
  249. </span>
  250. <span class="pc-mtext">کاربران</span></router-link
  251. >
  252. </li>
  253. <li
  254. class="pc-item"
  255. :class="{
  256. active:
  257. this.$route.path === '/banners' ||
  258. this.$route.path === '/addBanner' ||
  259. this.$route.name === 'editBanner',
  260. }"
  261. >
  262. <router-link to="/banners" class="pc-link">
  263. <span class="pc-micon">
  264. <i class="ph-duotone ph-flag"></i>
  265. </span>
  266. <span class="pc-mtext">بنر ها</span></router-link
  267. >
  268. </li>
  269. <li class="pc-item" :class="{ active: this.$route.path === '/brands' }">
  270. <router-link to="/brands" class="pc-link">
  271. <span class="pc-micon">
  272. <i class="ph-duotone ph-briefcase"></i>
  273. </span>
  274. <span class="pc-mtext">برند ها</span></router-link
  275. >
  276. </li>
  277. <li
  278. class="pc-item"
  279. :class="{ active: this.$route.path === '/attributes' }"
  280. >
  281. <router-link to="/attributes" class="pc-link">
  282. <span class="pc-micon">
  283. <i class="ph-duotone ph-star"></i>
  284. </span>
  285. <span class="pc-mtext">ویژگی ها</span></router-link
  286. >
  287. </li>
  288. <li
  289. class="pc-item"
  290. :class="{ active: this.$route.path === '/idenities' }"
  291. >
  292. <router-link to="/idenities" class="pc-link">
  293. <span class="pc-micon">
  294. <i class="ph-duotone ph-barcode"></i>
  295. </span>
  296. <span class="pc-mtext">مشخصات</span></router-link
  297. >
  298. </li>
  299. <li
  300. class="pc-item"
  301. :class="{
  302. active:
  303. this.$route.path === '/blogs' ||
  304. this.$route.path === '/addBlog' ||
  305. this.$route.name === 'editBlog',
  306. }"
  307. >
  308. <router-link to="/blogs" class="pc-link">
  309. <span class="pc-micon">
  310. <i class="ph-duotone ph-pencil"></i>
  311. </span>
  312. <span class="pc-mtext">بلاگ ها</span></router-link
  313. >
  314. </li>
  315. <li
  316. class="pc-item"
  317. :class="{
  318. active:
  319. this.$route.path === '/products' ||
  320. this.$route.path === '/addProduct' ||
  321. this.$route.name === 'editProduct',
  322. }"
  323. >
  324. <router-link to="/products" class="pc-link">
  325. <span class="pc-micon">
  326. <i class="ph-duotone ph-bag"></i>
  327. </span>
  328. <span class="pc-mtext">محصولات</span></router-link
  329. >
  330. </li>
  331. <li
  332. class="pc-item"
  333. :class="{
  334. active:
  335. this.$route.path === '/discounts' ||
  336. this.$route.path === '/addDiscount' ||
  337. this.$route.name === 'editDiscount',
  338. }"
  339. >
  340. <router-link to="/discounts" class="pc-link">
  341. <span class="pc-micon">
  342. <i class="ph-duotone ph-tag"></i>
  343. </span>
  344. <span class="pc-mtext">تخفیف ها</span></router-link
  345. >
  346. </li>
  347. <!-- سفاراشات -->
  348. <li class="pc-item pc-hasmenu">
  349. <BLink
  350. class="pc-link"
  351. data-bs-toggle="collapse"
  352. href="#collapse-orders"
  353. role="button"
  354. aria-expanded="false"
  355. aria-controls="collapse-orders"
  356. >
  357. <span class="pc-micon">
  358. <i class="ph-duotone ph-shopping-cart"></i>
  359. </span>
  360. <span class="pc-mtext">سفارشات</span>
  361. <span class="pc-arrow">
  362. <ChevronDownIcon></ChevronDownIcon>
  363. </span>
  364. </BLink>
  365. <div class="collapse" id="collapse-orders">
  366. <ul class="pc-submenu">
  367. <li
  368. class="pc-item"
  369. :class="{
  370. active:
  371. this.$route.path === '/orders' ||
  372. this.$route.name === 'singleOrder',
  373. }"
  374. >
  375. <router-link to="/orders" class="pc-link">
  376. <span class="pc-mtext">سفارشات</span></router-link
  377. >
  378. </li>
  379. <li
  380. class="pc-item"
  381. :class="{ active: this.$route.path === '/approvedOrders' }"
  382. >
  383. <router-link to="/approvedOrders" class="pc-link">
  384. <span class="pc-mtext">آیتم های تایید شده</span></router-link
  385. >
  386. </li>
  387. </ul>
  388. </div>
  389. </li>
  390. <!-- دسته ها -->
  391. <!-- <li class="pc-item pc-hasmenu">
  392. <BLink
  393. class="pc-link"
  394. data-bs-toggle="collapse"
  395. href="#collapse-categories"
  396. role="button"
  397. aria-expanded="false"
  398. aria-controls="collapse-categories"
  399. >
  400. <span class="pc-micon">
  401. <i class="ph-duotone ph-folder"></i>
  402. </span>
  403. <span class="pc-mtext">دسته ها</span>
  404. <span class="pc-arrow">
  405. <ChevronDownIcon></ChevronDownIcon>
  406. </span>
  407. </BLink>
  408. <div class="collapse" id="collapse-categories">
  409. <ul class="pc-submenu">
  410. <li
  411. class="pc-item"
  412. :class="{ active: this.$route.path === '/cats' }"
  413. >
  414. <router-link to="/cats" class="pc-link">
  415. <span class="pc-mtext">دسته محصولات</span></router-link
  416. >
  417. </li>
  418. <li
  419. class="pc-item"
  420. :class="{ active: this.$route.path === '/blogCat' }"
  421. >
  422. <router-link to="/blogCat" class="pc-link">
  423. <span class="pc-mtext">دسته بلاگ</span></router-link
  424. >
  425. </li>
  426. </ul>
  427. </div>
  428. </li> -->
  429. <li
  430. class="pc-item"
  431. :class="{ active: this.$route.path === '/comments' }"
  432. >
  433. <router-link to="/comments" class="pc-link">
  434. <span class="pc-micon">
  435. <i class="ph-duotone ph-chat"></i>
  436. </span>
  437. <span class="pc-mtext">نظرات</span></router-link
  438. >
  439. </li>
  440. <li
  441. class="pc-item"
  442. :class="{
  443. active:
  444. this.$route.path === '/faqs' || this.$route.name === 'editFaqs',
  445. }"
  446. >
  447. <router-link to="/faqs" class="pc-link">
  448. <span class="pc-micon">
  449. <i class="ph-duotone ph-file-text"></i>
  450. </span>
  451. <span class="pc-mtext">پرسش و پاسخ</span></router-link
  452. >
  453. </li>
  454. <li class="pc-item pc-hasmenu">
  455. <BLink
  456. class="pc-link"
  457. data-bs-toggle="collapse"
  458. href="#collapse26"
  459. role="button"
  460. aria-expanded="false"
  461. aria-controls="collapse26"
  462. >
  463. <span class="pc-micon">
  464. <i class="ph-duotone ph-folder"></i>
  465. </span>
  466. <span class="pc-mtext">دسته ها</span
  467. ><span class="pc-arrow">
  468. <ChevronDownIcon></ChevronDownIcon>
  469. </span>
  470. </BLink>
  471. <div class="collapse" id="collapse26">
  472. <ul class="pc-submenu">
  473. <li
  474. class="pc-item"
  475. :class="{ active: this.$route.path === '/cats' }"
  476. >
  477. <router-link to="/cats" class="pc-link">
  478. <span class="pc-mtext">دسته محصولات</span></router-link
  479. >
  480. </li>
  481. <li
  482. class="pc-item"
  483. :class="{ active: this.$route.path === '/blogCat' }"
  484. >
  485. <router-link to="/blogCat" class="pc-link">
  486. <span class="pc-mtext">دسته بلاگ</span></router-link
  487. >
  488. </li>
  489. </ul>
  490. </div>
  491. </li>
  492. <li class="pc-item" :class="{ active: this.$route.path === '/calls' }">
  493. <router-link to="/calls" class="pc-link">
  494. <span class="pc-micon">
  495. <i class="ph-duotone ph-clock"></i>
  496. </span>
  497. <span class="pc-mtext">برسی فرم ها</span></router-link
  498. >
  499. </li>
  500. <li class="pc-item" :class="{ active: this.$route.path === '/settings' }">
  501. <router-link to="/settings" class="pc-link">
  502. <span class="pc-micon">
  503. <i class="ph-duotone ph-gear"></i>
  504. </span>
  505. <span class="pc-mtext">تنظیمات</span></router-link
  506. >
  507. </li>
  508. <!-- other -->
  509. </ul>
  510. </simplebar>
  511. <BCard no-body class="pc-user-card">
  512. <BCardBody>
  513. <div class="d-flex align-items-center">
  514. <div class="flex-shrink-0">
  515. <img
  516. src="@/assets/images/user/avatar-1.jpg"
  517. alt="user-image"
  518. class="user-avtar wid-45 rounded-circle"
  519. />
  520. </div>
  521. <div class="flex-grow-1 ms-3 me-2">
  522. <h6 class="mb-0">{{ user?.name }}</h6>
  523. <small v-if="user?.role === `admin`">مدیر</small>
  524. <small v-if="user?.role === `client`">مشتری</small>
  525. </div>
  526. <BDropdown variant="purple" dropup no-caret toggle-class="p-0">
  527. <template v-slot:button-content>
  528. <span
  529. class="btn btn-icon btn-link-secondary avtar arrow-none p-0 dropdown-toggle"
  530. >
  531. <i class="ph-duotone ph-windows-logo"></i>
  532. </span>
  533. </template>
  534. <BRow xl="6">
  535. <BCol @click="gotoAccount()" xl="6">
  536. <BDropdownItem class="pc-user-links p-0">
  537. <i class="ph-duotone ph-user"></i>
  538. <br />
  539. <span>حساب من</span>
  540. </BDropdownItem>
  541. </BCol>
  542. <BCol @click="logoutUser" xl="6">
  543. <BDropdownItem class="pc-user-links p-0">
  544. <i class="ph-duotone ph-power"></i> <br />
  545. <span>خروج</span>
  546. </BDropdownItem>
  547. </BCol>
  548. </BRow>
  549. </BDropdown>
  550. </div>
  551. </BCardBody>
  552. </BCard>
  553. </div>
  554. </template>
  555. <style scoped>
  556. .logo-img {
  557. width: auto; /* Prevent scaling */
  558. height: 80px; /* Set a larger fixed height */
  559. max-width: 100%; /* Ensure the image doesn't overflow */
  560. display: block; /* Center the image if necessary */
  561. margin: 0 auto; /* Center the logo horizontally */
  562. border-radius: 8px; /* Soft rounded corners */
  563. box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1); /* Soft shadow for depth */
  564. transition: transform 0.3s ease-in-out, box-shadow 0.3s ease-in-out; /* Smooth transition */
  565. }
  566. .m-header {
  567. display: flex;
  568. justify-content: center; /* Center the logo horizontally */
  569. align-items: center; /* Center the logo vertically */
  570. padding: 20px 0; /* Add vertical padding around the header */
  571. }
  572. </style>