Card.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. <template>
  2. <main class="cursor-pointer" @click="open">
  3. <div>
  4. <div class="flex space-x-3">
  5. <div class="flex-shrink-0">
  6. <img
  7. class="h-10 w-10 rounded-full"
  8. :src="posterAvatar"
  9. alt=""
  10. />
  11. </div>
  12. <div class="min-w-0 flex-1">
  13. <p class="text-sm font-medium text-gray-900">
  14. <a href="javascript://" class="hover:underline">{{poster}}</a>
  15. </p>
  16. <p class="text-sm text-gray-500">
  17. <a href="javascript://" class="hover:underline">
  18. <!-- <time datetime="2020-12-09T11:43:00">December 9 at 11:43 AM</time> -->
  19. <time datetime="2020-12-09T11:43:00">{{postedDisplay}}</time>
  20. </a>
  21. </p>
  22. </div>
  23. <div class="flex-shrink-0 self-center flex">
  24. <div class="relative inline-block text-left">
  25. <div>
  26. <button @click="toggleMenu" type="button" class="-m-2 p-2 rounded-full flex items-center text-gray-400 hover:text-gray-600" id="options-menu-0-button" aria-expanded="false" aria-haspopup="true">
  27. <span class="sr-only">Open options</span>
  28. <!-- Heroicon name: solid/dots-vertical -->
  29. <svg class="h-5 w-5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
  30. <path d="M10 6a2 2 0 110-4 2 2 0 010 4zM10 12a2 2 0 110-4 2 2 0 010 4zM10 18a2 2 0 110-4 2 2 0 010 4z" />
  31. </svg>
  32. </button>
  33. </div>
  34. <!--
  35. Dropdown menu, show/hide based on menu state.
  36. Entering: "transition ease-out duration-100"
  37. From: "transform opacity-0 scale-95"
  38. To: "transform opacity-100 scale-100"
  39. Leaving: "transition ease-in duration-75"
  40. From: "transform opacity-100 scale-100"
  41. To: "transform opacity-0 scale-95"
  42. -->
  43. <div
  44. v-if="showFeedMenu"
  45. class="origin-top-right absolute right-0 mt-2 w-56 rounded-md shadow-lg bg-white ring-1 ring-black ring-opacity-5 focus:outline-none"
  46. role="menu"
  47. aria-orientation="vertical"
  48. aria-labelledby="options-menu-0-button"
  49. tabindex="-1"
  50. >
  51. <div class="py-1" role="none">
  52. <!-- Active: "bg-gray-100 text-gray-900", Not Active: "text-gray-700" -->
  53. <a href="javascript://" class="text-gray-700 flex px-4 py-2 text-sm" role="menuitem" tabindex="-1" id="options-menu-0-item-0">
  54. <!-- Heroicon name: solid/star -->
  55. <svg class="mr-3 h-5 w-5 text-gray-400" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
  56. <path
  57. d="M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z"
  58. />
  59. </svg>
  60. <span>Add to favorites</span>
  61. </a>
  62. <a href="javascript://" class="text-gray-700 flex px-4 py-2 text-sm" role="menuitem" tabindex="-1" id="options-menu-0-item-1">
  63. <!-- Heroicon name: solid/code -->
  64. <svg class="mr-3 h-5 w-5 text-gray-400" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
  65. <path
  66. fill-rule="evenodd"
  67. d="M12.316 3.051a1 1 0 01.633 1.265l-4 12a1 1 0 11-1.898-.632l4-12a1 1 0 011.265-.633zM5.707 6.293a1 1 0 010 1.414L3.414 10l2.293 2.293a1 1 0 11-1.414 1.414l-3-3a1 1 0 010-1.414l3-3a1 1 0 011.414 0zm8.586 0a1 1 0 011.414 0l3 3a1 1 0 010 1.414l-3 3a1 1 0 11-1.414-1.414L16.586 10l-2.293-2.293a1 1 0 010-1.414z"
  68. clip-rule="evenodd"
  69. />
  70. </svg>
  71. <span>Embed</span>
  72. </a>
  73. <a href="javascript://" class="text-gray-700 flex px-4 py-2 text-sm" role="menuitem" tabindex="-1" id="options-menu-0-item-2">
  74. <!-- Heroicon name: solid/flag -->
  75. <svg class="mr-3 h-5 w-5 text-gray-400" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
  76. <path fill-rule="evenodd" d="M3 6a3 3 0 013-3h10a1 1 0 01.8 1.6L14.25 8l2.55 3.4A1 1 0 0116 13H6a1 1 0 00-1 1v3a1 1 0 11-2 0V6z" clip-rule="evenodd" />
  77. </svg>
  78. <span>Report content</span>
  79. </a>
  80. </div>
  81. </div>
  82. </div>
  83. </div>
  84. </div>
  85. <h2 id="question-title-81614" class="mt-4 text-base font-medium text-gray-900">
  86. {{title}}
  87. </h2>
  88. </div>
  89. <div class="mt-2 text-sm text-gray-700 space-y-4">
  90. <p v-html="descDisplay" />
  91. </div>
  92. <div class="mt-6 flex justify-between space-x-8">
  93. <div class="flex space-x-6">
  94. <span class="hidden inline-flex items-center text-sm">
  95. <button type="button" class="inline-flex space-x-2 text-gray-400 hover:text-gray-500">
  96. <!-- Heroicon name: solid/thumb-up -->
  97. <svg class="h-5 w-5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
  98. <path
  99. d="M2 10.5a1.5 1.5 0 113 0v6a1.5 1.5 0 01-3 0v-6zM6 10.333v5.43a2 2 0 001.106 1.79l.05.025A4 4 0 008.943 18h5.416a2 2 0 001.962-1.608l1.2-6A2 2 0 0015.56 8H12V4a2 2 0 00-2-2 1 1 0 00-1 1v.667a4 4 0 01-.8 2.4L6.8 7.933a4 4 0 00-.8 2.4z"
  100. />
  101. </svg>
  102. <span class="font-medium text-gray-900">{{firstPostDisplay}}</span>
  103. <span class="sr-only">first post</span>
  104. </button>
  105. </span>
  106. <span class="inline-flex items-center text-sm">
  107. <button type="button" class="inline-flex space-x-2 text-gray-400 hover:text-gray-500">
  108. <!-- Heroicon name: solid/chat-alt -->
  109. <svg class="h-5 w-5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
  110. <path fill-rule="evenodd" d="M18 5v8a2 2 0 01-2 2h-5l-5 4v-4H4a2 2 0 01-2-2V5a2 2 0 012-2h12a2 2 0 012 2zM7 8H5v2h2V8zm2 0h2v2H9V8zm6 0h-2v2h2V8z" clip-rule="evenodd" />
  111. </svg>
  112. <span class="font-medium text-gray-900">{{numReplies}}</span>
  113. <span class="sr-only">replies</span>
  114. </button>
  115. </span>
  116. <span class="inline-flex items-center text-sm">
  117. <button type="button" class="inline-flex space-x-2 text-gray-400 hover:text-gray-500">
  118. <!-- Heroicon name: solid/eye -->
  119. <svg class="h-5 w-5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
  120. <path d="M10 12a2 2 0 100-4 2 2 0 000 4z" />
  121. <path fill-rule="evenodd" d="M.458 10C1.732 5.943 5.522 3 10 3s8.268 2.943 9.542 7c-1.274 4.057-5.064 7-9.542 7S1.732 14.057.458 10zM14 10a4 4 0 11-8 0 4 4 0 018 0z" clip-rule="evenodd" />
  122. </svg>
  123. <span class="font-medium text-gray-900">{{numViews}}</span>
  124. <span class="sr-only">views</span>
  125. </button>
  126. </span>
  127. </div>
  128. <div class="flex text-sm">
  129. <span class="inline-flex items-center text-sm">
  130. <button type="button" class="inline-flex space-x-2 text-gray-400 hover:text-gray-500">
  131. <!-- Heroicon name: solid/share -->
  132. <svg class="hidden h-5 w-5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
  133. <path d="M15 8a3 3 0 10-2.977-2.63l-4.94 2.47a3 3 0 100 4.319l4.94 2.47a3 3 0 10.895-1.789l-4.94-2.47a3.027 3.027 0 000-.74l4.94-2.47C13.456 7.68 14.19 8 15 8z" />
  134. </svg>
  135. <span class="font-medium text-gray-600 italic">{{firstPostDisplay}}</span>
  136. </button>
  137. </span>
  138. </div>
  139. </div>
  140. </main>
  141. </template>
  142. <script>
  143. /* Import modules. */
  144. import moment from 'moment'
  145. export default {
  146. props: {
  147. id: String,
  148. title: String,
  149. description: String,
  150. url: String,
  151. firstPost: Number,
  152. posted: Number,
  153. poster: String,
  154. posterAvatar: String,
  155. numViews: Number,
  156. numReplies: Number,
  157. },
  158. data: () => {
  159. return {
  160. showFeedMenu: null,
  161. }
  162. },
  163. computed: {
  164. descDisplay() {
  165. return this.description.replace(/\n/g, '<br />')
  166. },
  167. firstPostDisplay() {
  168. return moment.unix(this.firstPost).format('MMM D, YYYY @ h:mm a')
  169. },
  170. postedDisplay() {
  171. return moment.unix(this.posted).format('MMMM D, YYYY @ h:mm A')
  172. },
  173. },
  174. methods: {
  175. toggleMenu() {
  176. /* Toggle menu. */
  177. this.showFeedMenu = !this.showFeedMenu
  178. // this.$set(this.showFeedMenu, _menuid, !this.showFeedMenu[_menuid])
  179. // console.log('showFeedMenu', _menuid, this.showFeedMenu[_menuid])
  180. },
  181. open() {
  182. window.open(this.url)
  183. },
  184. },
  185. created: function () {
  186. // console.log('CARD ID', this.id)
  187. this.showFeedMenu = false
  188. },
  189. }
  190. </script>