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.

179 lines
4.1 KiB

2 years ago
  1. <template>
  2. <div class="group tw-mb-[20px]">
  3. <div class="tw-flex tw-justify-between tw-items-center tw-mb-[20px]">
  4. <h3 class="t14 tw-font-bold tw-mb-0 md:t16">{{ $t(label) }}</h3>
  5. <button class="'seeMore tw-transition tw-btn-md tw-body-4 tw-text-secondary-default tw-px-[16px] tw-py-[9px]"
  6. @click="clearAll()">
  7. {{ $t("Clear all") }}
  8. </button>
  9. </div>
  10. <div>
  11. <div class="optionGroup tw-border tw-rounded-[10px] tw-bg-white tw-p-[15px]">
  12. <additionalOption v-for="(item, index) in packages" :key="index" :index="index + 1" :item="item"
  13. :hasValue="hasValue" :seeMore="seeMore" @disabled="disabled($event)" @selected="total($event)">
  14. </additionalOption>
  15. </div>
  16. <button v-show="length !== undefined && length > 3" :class="[
  17. 'seeMore tw-transition tw-btn-md tw-text-primary-1 tw-border tw-border-solid tw-border-primary-1 tw-px-[30px] tw-py-[8.5px] tw-mt-[20px] tw-w-full tw-rounded-xl hover:tw-bg-primary-3 xl:hover:tw-bg-transparent xl:tw-border-none',
  18. seeMore ? 'open' : '',
  19. ]" @click="seeMore = !seeMore">
  20. {{ $t(seeMoreText) }}
  21. </button>
  22. </div>
  23. </div>
  24. </template>
  25. <script>
  26. import additionalOption from "./additionalOption.vue";
  27. export default {
  28. components: {
  29. additionalOption,
  30. },
  31. props: {
  32. label: {
  33. type: String,
  34. },
  35. packages: {
  36. type: Array,
  37. },
  38. },
  39. data() {
  40. return {
  41. hasValue: null,
  42. totalPrice: [],
  43. seeMore: false,
  44. };
  45. },
  46. computed: {
  47. seeMoreText() {
  48. if (this.seeMore == false) {
  49. return "See more";
  50. } else {
  51. return "See less";
  52. }
  53. },
  54. length() {
  55. if (this.packages) {
  56. return this.packages.length;
  57. } else {
  58. return 0;
  59. }
  60. },
  61. },
  62. methods: {
  63. disabled(i) {
  64. this.hasValue = i;
  65. },
  66. total(obj) {
  67. let hasObj = this.totalPrice.some(
  68. (item) => item.addon_service_id == obj.addon_service_id
  69. );
  70. if (!hasObj) {
  71. this.totalPrice.push(obj);
  72. } else {
  73. let oldObj = this.totalPrice.find(
  74. (f) => f.addon_service_id == obj.addon_service_id
  75. );
  76. if (oldObj) {
  77. oldObj.addon_service_name = obj.addon_service_name;
  78. oldObj.number = obj.number;
  79. oldObj.total = obj.total;
  80. }
  81. }
  82. this.$emit("totalPrice", this.totalPrice);
  83. },
  84. clearAll() {
  85. this.hasValue = null;
  86. this.totalPrice = [];
  87. this.$emit("totalPrice", []);
  88. },
  89. },
  90. };
  91. </script>
  92. <style lang="scss" scoped>
  93. .custom-button {
  94. background-position: center;
  95. background-repeat: no-repeat;
  96. background-size: 12px;
  97. }
  98. .button {
  99. &-reduce {
  100. background-image: url("~/assets/svg/reduce.svg");
  101. background-color: #e5e5e5;
  102. }
  103. &-add {
  104. background-image: url("~/assets/svg/add.svg");
  105. background-color: #f48800;
  106. }
  107. }
  108. :deep() {
  109. .optionGroup {
  110. .optionItem:last-child {
  111. border: none !important;
  112. margin: 0 !important;
  113. padding: 0 !important;
  114. }
  115. }
  116. }
  117. .seeMore {
  118. &-hide {
  119. position: relative;
  120. max-height: 295px;
  121. overflow: hidden;
  122. &::after {
  123. content: "";
  124. display: block;
  125. position: absolute;
  126. background: url("~/assets/img/gradient_white.png") repeat-x left bottom;
  127. width: 100%;
  128. height: 130px;
  129. left: 0;
  130. bottom: 0;
  131. z-index: 1;
  132. transition: bottom 0.5s;
  133. }
  134. }
  135. &-show {
  136. position: relative;
  137. max-height: 100%;
  138. overflow: initial;
  139. &::after {
  140. display: none;
  141. }
  142. }
  143. @media screen and (min-width: 1366px) {
  144. position: relative;
  145. display: flex;
  146. align-items: center;
  147. justify-content: center;
  148. &::after {
  149. content: "";
  150. display: inline-block;
  151. position: relative;
  152. background-image: url("~/assets/svg/arrow-down-primary.svg");
  153. background-position: center center;
  154. background-repeat: no-repeat;
  155. background-size: 100%;
  156. width: 9px;
  157. height: 6px;
  158. margin-left: 16px;
  159. transition: all 0.2s linear;
  160. }
  161. &.open {
  162. &::after {
  163. transform: rotate(180deg);
  164. }
  165. }
  166. }
  167. }
  168. </style>