GroupCard.vue 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. <template>
  2. <div class="col-12 col-md-6 col-xl-4 group-card">
  3. <div class="group-card-inner">
  4. <img
  5. v-if="group.metadata && group.metadata.hasOwnProperty('header')"
  6. :src="group.metadata.header.url"
  7. class="group-header-img" />
  8. <div
  9. v-else
  10. class="group-header-img"
  11. :class="{ compact: compact }">
  12. <div
  13. class="bg-light d-flex align-items-center justify-content-center rounded"
  14. style="width: 100%; height:100%;">
  15. </div>
  16. </div>
  17. <div class="group-card-inner-copy">
  18. <p class="font-weight-bold mb-0 text-dark" style="font-size: 16px;">
  19. {{ truncate(group.name || 'Untitled Group', titleLength) }}
  20. </p>
  21. <p class="text-muted mb-1" style="font-size: 12px;">
  22. {{ truncate(group.short_description, descriptionLength) }}
  23. </p>
  24. <p v-if="showStats" class="mb-0 small text-lighter">
  25. <span>
  26. <i class="fal fa-users"></i>
  27. <span class="small font-weight-bold">{{ prettyCount(group.member_count) }}</span>
  28. </span>
  29. <span v-if="!group.local" class="remote-label ml-3">
  30. <i class="fal fa-globe"></i> Remote
  31. </span>
  32. </p>
  33. </div>
  34. <div class="group-card-inner-foaf">
  35. </div>
  36. <div class="group-card-inner-cta">
  37. <router-link :to="`/groups/${group.id}`" class="btn btn-light btn-block font-weight-bold">
  38. Join Group
  39. </router-link>
  40. </div>
  41. </div>
  42. </div>
  43. </template>
  44. <script>
  45. export default {
  46. props: {
  47. group: {
  48. type: Object
  49. },
  50. compact: {
  51. type: Boolean,
  52. default: false
  53. },
  54. showStats: {
  55. type: Boolean,
  56. default: true
  57. },
  58. truncateTitleLength: {
  59. type: Number,
  60. default: 19
  61. },
  62. truncateDescriptionLength: {
  63. type: Number,
  64. default: 22
  65. }
  66. },
  67. data() {
  68. return {
  69. titleLength: 40,
  70. descriptionLength: 60
  71. }
  72. },
  73. mounted() {
  74. if(this.compact) {
  75. this.titleLength = 19;
  76. this.descriptionLength = 22;
  77. }
  78. if(this.truncateTitleLength != 19) {
  79. this.titleLength = this.truncateTitleLength;
  80. }
  81. if(this.truncateDescriptionLength != 22) {
  82. this.descriptionLength = this.truncateDescriptionLength;
  83. }
  84. },
  85. methods: {
  86. prettyCount(val) {
  87. return App.util.format.count(val);
  88. },
  89. truncate(str, limit = 140) {
  90. if(str.length <= limit) {
  91. return str;
  92. }
  93. return str.substr(0, limit) + ' ...';
  94. }
  95. }
  96. }
  97. </script>
  98. <style lang="scss" scoped>
  99. .group-card {
  100. margin-bottom: 15px;
  101. &-inner {
  102. display: flex;
  103. flex-direction: column;
  104. border: 1px solid var(--border-color);
  105. border-radius: 10px;
  106. overflow: hidden;
  107. &-copy {
  108. background-color: var(--light);
  109. padding: 1rem;
  110. }
  111. &-foaf {
  112. background-color: var(--light);
  113. height: 30px;
  114. }
  115. &-cta {
  116. background-color: var(--light);
  117. padding: 1rem;
  118. }
  119. }
  120. .member-label {
  121. padding: 2px 5px;
  122. font-size: 9px;
  123. color: rgba(75, 119, 190, 1);
  124. background: rgba(137, 196, 244, 0.2);
  125. border: 1px solid rgba(137, 196, 244, 0.3);
  126. font-weight: 500;
  127. text-transform: capitalize;
  128. border-radius: 3px;
  129. }
  130. .remote-label {
  131. padding: 2px 5px;
  132. font-size: 9px;
  133. color: #B45309;
  134. background: #FEF3C7;
  135. border: 1px solid #FCD34D;
  136. font-weight: 500;
  137. text-transform: capitalize;
  138. border-radius: 3px;
  139. }
  140. .group-header-img {
  141. width: 100%;
  142. height: 150px;
  143. object-fit: cover;
  144. padding: 0px;
  145. overflow: hidden;
  146. }
  147. }
  148. </style>