EventCard.vue 6.23 KB
Newer Older
Thomas Citharel's avatar
Thomas Citharel committed
1
<template>
Thomas Citharel's avatar
Thomas Citharel committed
2
3
  <router-link
    class="card"
Thomas Citharel's avatar
Thomas Citharel committed
4
    :to="{ name: RouteName.EVENT, params: { uuid: event.uuid } }"
Thomas Citharel's avatar
Thomas Citharel committed
5
  >
6
    <div class="card-image">
Thomas Citharel's avatar
Thomas Citharel committed
7
8
9
10
11
      <figure class="image is-16by9">
        <lazy-image-wrapper
          :picture="event.picture"
          style="height: 100%; position: absolute; top: 0; left: 0; width: 100%"
        />
12
13
14
15
16
17
18
19
20
21
        <div
          class="tag-container"
          v-if="event.tags || event.status !== EventStatus.CONFIRMED"
        >
          <b-tag type="is-info" v-if="event.status === EventStatus.TENTATIVE">
            {{ $t("Tentative") }}
          </b-tag>
          <b-tag type="is-danger" v-if="event.status === EventStatus.CANCELLED">
            {{ $t("Cancelled") }}
          </b-tag>
22
23
          <router-link
            :to="{ name: RouteName.TAG, params: { tag: tag.title } }"
24
            v-for="tag in (event.tags || []).slice(0, 3)"
25
26
            :key="tag.slug"
          >
27
            <b-tag type="is-light" dir="auto">{{ tag.title }}</b-tag>
28
          </router-link>
Thomas Citharel's avatar
Thomas Citharel committed
29
        </div>
Thomas Citharel's avatar
Thomas Citharel committed
30
31
      </figure>
    </div>
Thomas Citharel's avatar
Thomas Citharel committed
32
33
34
    <div class="card-content">
      <div class="media">
        <div class="media-left">
Thomas Citharel's avatar
Thomas Citharel committed
35
          <date-calendar-icon
Thomas Citharel's avatar
Thomas Citharel committed
36
            :small="true"
Thomas Citharel's avatar
Thomas Citharel committed
37
38
39
            v-if="!mergedOptions.hideDate"
            :date="event.beginsOn"
          />
Thomas Citharel's avatar
Thomas Citharel committed
40
        </div>
Thomas Citharel's avatar
Thomas Citharel committed
41
        <div class="media-content">
42
43
44
45
46
47
          <h3
            class="event-title"
            :title="event.title"
            dir="auto"
            :lang="event.language"
          >
48
49
            {{ event.title }}
          </h3>
Thomas Citharel's avatar
Thomas Citharel committed
50
          <div class="content-end">
51
            <div class="event-organizer" dir="auto">
Thomas Citharel's avatar
Thomas Citharel committed
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
              <figure
                class="image is-24x24"
                v-if="organizer(event) && organizer(event).avatar"
              >
                <img
                  class="is-rounded"
                  :src="organizer(event).avatar.url"
                  alt=""
                />
              </figure>
              <b-icon v-else icon="account-circle" />
              <span class="organizer-name">
                {{ organizerDisplayName(event) }}
              </span>
            </div>
            <inline-address
68
              dir="auto"
Thomas Citharel's avatar
Thomas Citharel committed
69
70
71
72
73
74
              v-if="event.physicalAddress"
              class="event-subtitle"
              :physical-address="event.physicalAddress"
            />
            <div
              class="event-subtitle"
75
              dir="auto"
Thomas Citharel's avatar
Thomas Citharel committed
76
              v-else-if="event.options && event.options.isOnline"
77
            >
Thomas Citharel's avatar
Thomas Citharel committed
78
79
80
              <b-icon icon="video" />
              <span>{{ $t("Online") }}</span>
            </div>
81
          </div>
Thomas Citharel's avatar
Thomas Citharel committed
82
        </div>
Thomas Citharel's avatar
Thomas Citharel committed
83
84
      </div>
    </div>
85
  </router-link>
Thomas Citharel's avatar
Thomas Citharel committed
86
87
88
</template>

<script lang="ts">
89
90
91
92
93
94
import {
  IEvent,
  IEventCardOptions,
  organizerDisplayName,
  organizer,
} from "@/types/event.model";
95
96
import { Component, Prop, Vue } from "vue-property-decorator";
import DateCalendarIcon from "@/components/Event/DateCalendarIcon.vue";
Thomas Citharel's avatar
Thomas Citharel committed
97
import LazyImageWrapper from "@/components/Image/LazyImageWrapper.vue";
98
import { Actor, Person } from "@/types/actor";
99
import { EventStatus, ParticipantRole } from "@/types/enums";
100
import RouteName from "../../router/name";
101
import InlineAddress from "@/components/Address/InlineAddress.vue";
Thomas Citharel's avatar
Thomas Citharel committed
102

103
104
@Component({
  components: {
105
    DateCalendarIcon,
Thomas Citharel's avatar
Thomas Citharel committed
106
    LazyImageWrapper,
107
    InlineAddress,
108
109
  },
})
Thomas Citharel's avatar
Thomas Citharel committed
110
111
export default class EventCard extends Vue {
  @Prop({ required: true }) event!: IEvent;
112

113
114
115
116
  @Prop({ required: false }) options!: IEventCardOptions;

  ParticipantRole = ParticipantRole;

117
118
  EventStatus = EventStatus;

119
120
  RouteName = RouteName;

121
122
123
124
  organizerDisplayName = organizerDisplayName;

  organizer = organizer;

125
126
127
128
129
  defaultOptions: IEventCardOptions = {
    hideDate: false,
    loggedPerson: false,
    hideDetails: false,
    organizerActor: null,
Thomas Citharel's avatar
Thomas Citharel committed
130
    memberofGroup: false,
131
132
133
134
135
  };

  get mergedOptions(): IEventCardOptions {
    return { ...this.defaultOptions, ...this.options };
  }
136

Thomas Citharel's avatar
Thomas Citharel committed
137
  get actor(): Actor {
138
139
140
141
    return Object.assign(
      new Person(),
      this.event.organizerActor || this.mergedOptions.organizerActor
    );
142
  }
Thomas Citharel's avatar
Thomas Citharel committed
143
144
}
</script>
145

146
<style lang="scss" scoped>
147
@use "@/styles/_mixins" as *;
148
149
@use "@/styles/_event-card";

150
151
152
a.card {
  display: block;
  background: $secondary;
Thomas Citharel's avatar
Thomas Citharel committed
153
  color: #3c376e;
154

155
156
157
158
159
  &:hover {
    // box-shadow: 0 0 5px 0 rgba(0, 0, 0, 1);
    transform: scale(1.01, 1.01);
    &:after {
      opacity: 1;
160
    }
161
162
163
164
165
  }

  border-radius: 5px;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
  transition: all 0.6s cubic-bezier(0.165, 0.84, 0.44, 1);
166

167
168
  &:after {
    content: "";
169
    border-radius: 5px;
170
171
172
173
174
175
176
177
    position: absolute;
    z-index: -1;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
    opacity: 0;
178
    transition: all 0.6s cubic-bezier(0.165, 0.84, 0.44, 1);
179
  }
180

181
182
183
184
  div.tag-container {
    position: absolute;
    top: 10px;
    right: 0;
185
    @include margin-right(-3px);
186
187
188
    z-index: 10;
    max-width: 40%;

189
190
191
192
193
194
195
196
197
198
199
200
201
    a {
      text-decoration: none;

      span.tag {
        margin: 5px auto;
        text-overflow: ellipsis;
        overflow: hidden;
        display: block;
        font-size: 0.9em;
        line-height: 1.75em;
        background-color: #e6e4f4;
        color: #3c376e;
      }
202
    }
203
  }
204

205
206
  div.card-image {
    background: $secondary;
Thomas Citharel's avatar
Thomas Citharel committed
207

208
209
210
    figure.image {
      background-size: cover;
      background-position: center;
Thomas Citharel's avatar
Thomas Citharel committed
211
    }
212
  }
Thomas Citharel's avatar
Thomas Citharel committed
213

214
  .card-content {
Thomas Citharel's avatar
Thomas Citharel committed
215
    height: 100%;
216
217
    padding: 0.5rem;

Thomas Citharel's avatar
Thomas Citharel committed
218
219
220
221
    & > .media {
      position: relative;
      display: flex;
      flex-direction: column;
Thomas Citharel's avatar
Thomas Citharel committed
222
      height: 100%;
Thomas Citharel's avatar
Thomas Citharel committed
223
224
225
226
227
228
229
230

      & > .media-left {
        margin-top: -15px;
        height: 0;
        display: flex;
        align-items: flex-end;
        align-self: flex-start;
        margin-bottom: 15px;
231
        @include margin-left(0);
Thomas Citharel's avatar
Thomas Citharel committed
232
      }
233
234
235
236
237

      & > .media-content {
        flex: 1;
        width: 100%;
        overflow-x: inherit;
Thomas Citharel's avatar
Thomas Citharel committed
238
239
240
        display: flex;
        flex-direction: column;
        justify-content: space-between;
241
      }
Thomas Citharel's avatar
Thomas Citharel committed
242
243
    }

244
    .event-title {
245
246
      font-size: 18px;
      line-height: 24px;
247
      display: -webkit-box;
248
      -webkit-line-clamp: 3;
249
250
      -webkit-box-orient: vertical;
      overflow: hidden;
Thomas Citharel's avatar
Thomas Citharel committed
251
      font-weight: bold;
252
253
    }

254
255
256
257
    .content-end {
      padding-top: 8px;
    }

258
259
    .event-subtitle {
      font-size: 0.85rem;
260
    }
261

262
263
    .organizer-name {
      font-size: 14px;
264
265
    }
  }
266
}
267
</style>