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.
 
 
 

317 lines
7.4 KiB

  1. <template>
  2. <div
  3. class="modal fade"
  4. id="editAttribute"
  5. tabindex="-1"
  6. role="dialog"
  7. aria-labelledby="exampleModalLabel"
  8. aria-hidden="true"
  9. >
  10. <div class="modal-dialog modal-sm" role="document">
  11. <div class="modal-content">
  12. <div class="modal-header">
  13. <h5 class="modal-title" id="exampleModalLabel">ویرایش رنگ</h5>
  14. <button
  15. type="button"
  16. class="btn-close"
  17. data-bs-dismiss="modal"
  18. aria-label="Close"
  19. ></button>
  20. </div>
  21. <div class="modal-body">
  22. <form @submit.prevent="editAttribute">
  23. <BRow class="g-3">
  24. <!-- Brand Title -->
  25. <BCol lg="6">
  26. <div class="form-group">
  27. <label class="form-label">نام رنگ</label>
  28. <input
  29. v-model="localColorName"
  30. @input="clearError('localColorName')"
  31. type="text"
  32. class="form-control"
  33. placeholder="نام رنگ"
  34. :class="{ 'is-invalid': errors.colorName }"
  35. />
  36. <small v-if="errors.localColorName" class="text-danger">
  37. {{ errors.localColorName }}
  38. </small>
  39. </div>
  40. </BCol>
  41. <BCol lg="6">
  42. <div class="form-group">
  43. <label class="form-label">انتخاب رنگ</label>
  44. <div class="color-picker-wrapper">
  45. <input
  46. v-model="localColorCode"
  47. @input="clearError('localColorCode')"
  48. type="color"
  49. class="form-control color-picker"
  50. :class="{ 'is-invalid': errors.localColorCode }"
  51. />
  52. <span
  53. v-if="colorCode"
  54. class="color-display"
  55. :style="{ backgroundColor: localColorCode }"
  56. ></span>
  57. </div>
  58. <span> {{ localColorCode }}</span>
  59. <small v-if="errors.localColorCode" class="text-danger">
  60. {{ errors.localColorCode }}
  61. </small>
  62. </div>
  63. </BCol>
  64. </BRow>
  65. <!-- Submit Buttons -->
  66. <div
  67. class="d-flex justify-content-end gap-2"
  68. style="margin-top: 20px"
  69. >
  70. <button
  71. type="button"
  72. class="btn btn-secondary"
  73. data-bs-dismiss="modal"
  74. id="closeAttributeModal"
  75. >
  76. بستن
  77. </button>
  78. <button type="submit" class="btn btn-primary" :disabled="loading">
  79. <span
  80. v-if="loading"
  81. class="spinner-border spinner-border-sm"
  82. role="status"
  83. aria-hidden="true"
  84. ></span>
  85. ذخیره
  86. </button>
  87. </div>
  88. </form>
  89. </div>
  90. </div>
  91. </div>
  92. </div>
  93. </template>
  94. <script>
  95. import { ref, toRef, watch } from "vue";
  96. import { toast } from "vue3-toastify";
  97. import "vue3-toastify/dist/index.css";
  98. import ApiServiece from "@/services/ApiService";
  99. export default {
  100. props: {
  101. attributeValues: {
  102. type: Array,
  103. Required: true,
  104. },
  105. code: {
  106. type: String,
  107. Required: true,
  108. },
  109. title: {
  110. type: String,
  111. Required: true,
  112. },
  113. id: {
  114. type: String,
  115. Required: true,
  116. },
  117. },
  118. setup(props, { emit }) {
  119. const localColorName = ref();
  120. const localColorCode = ref();
  121. const localId = toRef(props.id);
  122. const localAttributeValues = toRef(props.attributeValues);
  123. const errors = ref({});
  124. const loading = ref(false);
  125. watch(
  126. () => props.attributeValues,
  127. (newVal) => (localAttributeValues.value = newVal)
  128. );
  129. watch(
  130. () => props.code,
  131. (newVal) => (localColorCode.value = newVal)
  132. );
  133. watch(
  134. () => props.title,
  135. (newVal) => (localColorName.value = newVal)
  136. );
  137. watch(
  138. () => props.id,
  139. (newVal) => (localId.value = newVal)
  140. );
  141. const validateForm = () => {
  142. errors.value = {};
  143. if (!localColorName.value)
  144. errors.value.colorName = "وارد کردن نام رنگ ضروری می باشد";
  145. if (!localColorCode.value)
  146. errors.value.colorCode = "انتخاب رنگ ضروری می باشد";
  147. return Object.keys(errors.value).length === 0;
  148. };
  149. const clearError = (field) => {
  150. errors.value[field] = "";
  151. };
  152. const editAttribute = () => {
  153. if (!validateForm()) return;
  154. loading.value = true;
  155. const formData = new FormData();
  156. console.log(localAttributeValues.value);
  157. formData.append("title", localColorName.value);
  158. formData.append("code", localColorCode.value);
  159. formData.append("attribute_id", localAttributeValues.value[0].id);
  160. ApiServiece.put(`admin/attribute-values/${localId.value}`, formData)
  161. .then((resp) => {
  162. console.log(resp);
  163. toast.success("!ویژگی با موفقیت ویرایش شد", {
  164. position: "top-right",
  165. autoClose: 1000,
  166. });
  167. })
  168. .then(() => {
  169. setTimeout(() => {
  170. document.getElementById("closeAttributeModal").click();
  171. emit("attribute-updated");
  172. }, 500);
  173. })
  174. .catch((error) => {
  175. console.error(error);
  176. toast.success("!مشکلی در ویرایش ویژگی پیش آمد", {
  177. position: "top-right",
  178. autoClose: 1000,
  179. });
  180. })
  181. .finally(() => {
  182. loading.value = false;
  183. });
  184. };
  185. return {
  186. errors,
  187. loading,
  188. clearError,
  189. editAttribute,
  190. localColorName,
  191. localColorCode,
  192. };
  193. },
  194. };
  195. </script>
  196. <style scoped>
  197. .modal-dialog {
  198. max-width: 50%;
  199. }
  200. .modal-content {
  201. padding: 20px;
  202. }
  203. .modal-body {
  204. padding: 20px;
  205. padding: 1rem 1.5rem;
  206. }
  207. .form-group {
  208. margin-bottom: 1rem;
  209. }
  210. .input-group {
  211. margin-top: 0.5rem;
  212. }
  213. .modal-dialog {
  214. max-width: 50%;
  215. }
  216. .modal-content {
  217. padding: 1.5rem;
  218. }
  219. .modal-header {
  220. border-bottom: 1px solid #dee2e6;
  221. padding-bottom: 1rem;
  222. }
  223. .form-group {
  224. margin-bottom: 1.5rem;
  225. }
  226. .input-group {
  227. margin-top: 0.5rem;
  228. }
  229. .Image-Preview {
  230. min-width: 100px;
  231. max-height: 100px;
  232. max-width: 100px;
  233. object-fit: cover;
  234. border-radius: 8px;
  235. border: 1px solid #ddd;
  236. }
  237. .delete-btn {
  238. display: flex;
  239. align-items: center;
  240. padding: 3px;
  241. font-size: 10px;
  242. background-color: #e74c3c;
  243. color: white;
  244. border: none;
  245. border-radius: 5px;
  246. cursor: pointer;
  247. transition: background-color 0.3s ease, transform 0.2s ease;
  248. gap: 8px; /* Space between icon and text */
  249. margin-right: 100px;
  250. }
  251. .delete-btn:hover {
  252. background-color: #c0392b;
  253. transform: scale(1.05);
  254. }
  255. .delete-btn:active {
  256. background-color: #a93226;
  257. }
  258. .delete-btn:focus {
  259. outline: none;
  260. }
  261. .color-picker-wrapper {
  262. position: relative;
  263. display: flex;
  264. align-items: center;
  265. }
  266. .color-picker {
  267. width: 300px;
  268. height: 45px;
  269. padding: 0;
  270. border-radius: 10px;
  271. border: none;
  272. cursor: pointer;
  273. }
  274. .color-display {
  275. width: 30px;
  276. height: 30px;
  277. margin-left: 10px;
  278. border-radius: 50%;
  279. border: 2px solid #ccc;
  280. display: inline-block;
  281. }
  282. </style>