AvatarIcon.vue 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. <template>
  2. <info-tooltip class='avatar_icon' :noEvents='user === null'>
  3. <template slot='content'>
  4. <template v-if='userData'>
  5. <div class='avatar_icon__header'>
  6. <div
  7. class='avatar_icon__icon avatar_icon__icon--small picture_circle'
  8. :style='{
  9. "background-color": proxyUser.color,
  10. "background-image": pictureURL,
  11. }'
  12. @click='goToUser'
  13. >
  14. {{letter}}
  15. </div>
  16. <div class='avatar_icon__header_info'>
  17. <span class='avatar_icon__username' @click.stop='goToUser'>{{proxyUser.username}}</span>
  18. <span class='avatar_icon__date'>User since {{proxyUser.createdAt | formatDate('date') }}</span>
  19. </div>
  20. </div>
  21. <div class='avatar_icon__description' v-if='proxyUser.description'>
  22. {{proxyUser.description}}
  23. </div>
  24. </template>
  25. <template v-else>Loading...</template>
  26. </template>
  27. <div
  28. slot='display'
  29. class='avatar_icon__icon picture_circle'
  30. :class='{"avatar_icon__icon--small": size === "small"}'
  31. :style='{
  32. "background-color": proxyUser.color,
  33. "background-image": pictureURL
  34. }'
  35. @click.stop='goToUser'
  36. >
  37. {{letter}}
  38. </div>
  39. </info-tooltip>
  40. </template>
  41. <script>
  42. import InfoTooltip from './InfoTooltip'
  43. import AjaxErrorHandler from '../assets/js/errorHandler'
  44. export default {
  45. name: 'AvatarIcon',
  46. props: ['user', 'size'],
  47. components: { InfoTooltip },
  48. data () {
  49. return {
  50. userData: null
  51. }
  52. },
  53. computed: {
  54. //So that you never access a null variable
  55. proxyUser () {
  56. if(this.userData) {
  57. //Data loaded via api
  58. return this.userData;
  59. } else if (this.user) {
  60. //Data provided as a prop
  61. return this.user;
  62. }
  63. return {};
  64. },
  65. letter () {
  66. if(this.proxyUser.username && !this.proxyUser.picture) {
  67. return this.proxyUser.username[0].toUpperCase();
  68. } else {
  69. return '';
  70. }
  71. },
  72. pictureURL () {
  73. if(this.proxyUser.picture) {
  74. return "url(" + this.proxyUser.picture + ")";
  75. }
  76. return null;
  77. }
  78. },
  79. methods: {
  80. loadUser () {
  81. //If user is already loaded or no user provided as a prop
  82. if(this.userData || this.user === null) return;
  83. this.axios
  84. .get('/api/v1/user/' + this.proxyUser.username)
  85. .then((res) => {
  86. this.userData = res.data;
  87. })
  88. .catch(AjaxErrorHandler(this.$store));
  89. },
  90. goToUser () {
  91. if(this.user === null) return;
  92. this.$router.push('/user/' + this.user.username)
  93. }
  94. },
  95. mounted() { this.loadUser(); }
  96. }
  97. </script>
  98. <style lang='scss'>
  99. @import '../assets/scss/variables.scss';
  100. .avatar_icon {
  101. @at-root #{&}__icon {
  102. font-size: 0.7rem;
  103. margin-right: 0.25rem;
  104. color: rgba(0, 0, 0, 0.87);
  105. }
  106. @at-root #{&}__header {
  107. display: flex;
  108. align-items: center;
  109. }
  110. @at-root #{&}__icon {
  111. height: 3rem;
  112. width: 3rem;
  113. line-height: 3rem;
  114. cursor: pointer;
  115. @include text($font--role-emphasis, 2rem)
  116. text-align: center;
  117. border-radius: 100%;
  118. background-color: $color__gray--darkest;
  119. color: #fff;
  120. @at-root #{&}--small {
  121. height: 2.5rem;
  122. width: 2.5rem;
  123. font-size: 1.75rem;
  124. line-height: 2.5rem;
  125. }
  126. }
  127. @at-root #{&}__header_info {
  128. display: flex;
  129. flex-direction: column;
  130. height: 2.5rem;
  131. }
  132. @at-root #{&}__username {
  133. cursor: pointer;
  134. }
  135. @at-root #{&}__date {
  136. color: $color__darkgray--primary;
  137. font-size: 0.9rem;
  138. }
  139. @at-root #{&}__description {
  140. margin-top: 0.25rem;
  141. font-size: 0.9rem;
  142. }
  143. }
  144. </style>