# ZeenScheduleCard

Компонент ZeenScheduleCard

# Примеры:

Размеры:

ZeenScheduleCard

zeen-schedule-card-min-width

zeen-schedule-card-padding-vertical

zeen-schedule-card-padding-horizontal

zeen-schedule-card-border-radius

zeen-schedule-card-title-size

По умолчанию наследуется от main-small-text

zeen-schedule-card-title-line-height

zeen-schedule-card-title-font-weight

zeen-schedule-card-subtitle-size

По умолчанию наследуется от main-smallest-text

zeen-schedule-card-subtitle-line-height

zeen-schedule-card-subtitle-font-weight

zeen-schedule-card-subtitle-margin-top

zeen-schedule-card-live-padding-vertical

zeen-schedule-card-live-padding-horizontal

zeen-schedule-card-live-margin-right

zeen-schedule-card-live-border-radius

zeen-schedule-card-live-img-size

По умолчанию наследуется от action-icon-min-width-middle

zeen-schedule-card-live-text

По умолчанию наследуется от main-smallest-text

zeen-schedule-card-live-text-line-height

zeen-schedule-card-live-text-font-weight

zeen-schedule-card-live-text-margin-left

zeen-schedule-card-time-text

zeen-schedule-card-time-text-line-height

zeen-schedule-card-time-text-font-weight

zeen-schedule-card-button-size

zeen-schedule-card-footer-margin-top

Цвета:

zeen-schedule-card-color

По умолчанию наследуется от main-color

zeen-schedule-card-color-hold

По умолчанию наследуется от main-light

zeen-schedule-card-color-done

По умолчанию наследуется от main-light

zeen-schedule-card-live-color

По умолчанию наследуется от main-light

zeen-schedule-card-text-color

По умолчанию наследуется от main-light

zeen-schedule-card-text-color-hold

По умолчанию наследуется от main-text-color

zeen-schedule-card-text-color-done

По умолчанию наследуется от dark-1

zeen-schedule-card-live-img-color

По умолчанию наследуется от main-light

zeen-schedule-card-button-color

По умолчанию наследуется от main-color

zeen-schedule-card-button-color-hold

По умолчанию наследуется от main-color

zeen-schedule-card-button-color-done

По умолчанию наследуется от main-color

11:00-11:20

Диджитал-привлечение в корпоративном бизнесе. Есть ли место подвигу?

# props

Название Тип Обязательный По умолчанию Описание
speech Object - {} Объект спича
hall Object - {} Объект с залом
speakersText Array - ['спикер', 'спикера', 'спикеров'] Массив с текстом спикеров
showSpeakersAvatar Boolean - false Показывать аватары спикеров
speakersLimit Number - 3 Кол-во спикеров
speakerAvatarSize Number - 30 Размер аватарки спикера

# emits

Название Описание
cardClick Срабатывает при клике по карточке передает объект с hall и speech
cardButtonClick Срабатывает при клике по кнопке карточки передает объект с hall и speech

# slots

Название Описание
live-icon иконка live
button-icon-done иконка кнопки
button-icon иконка кнопки

# Source Code - исходный код компонента

<template lang="pug">
  .schedule-card(
    v-if="speech && speech.status"
    @click="cardClick"
    :class="[`schedule-card__${speech.status}`]"
    :style="cardStyles"
  )
    .schedule-card__wrapper-text
      span.schedule-card__time(
        v-if="speech.time_begin"
        :class="timeClass"
      ) 
        slot(v-if="isLiveIconVisible" name="live-icon" :speech="speech")
          svg.schedule-card__live-img(viewBox="0 0 16 14" xmlns="http://www.w3.org/2000/svg")
            path(
              d="M3.45301 1.16705C3.38625 1.09893 3.30672 1.04464 3.21896 1.00726C3.13121 \
              0.969895 3.03695 0.950182 2.94158 0.949253C2.8462 0.948324 2.75158 0.966198 2.66312 \
              1.00185C2.57465 1.03751 2.49408 1.09024 2.42601 1.15705C1.65596 1.92263 1.04512 2.83311 \
              0.628737 3.83596C0.212354 4.83881 -0.00133197 5.91419 6.24671e-06 7.00005C-0.00124271 \
              8.12757 0.22926 9.24331 0.677209 10.278C1.12516 11.3128 1.78099 12.2444 2.60401 \
              13.015C2.74253 13.1431 2.9255 13.2121 3.11408 13.2074C3.30266 13.2028 3.48199 13.1248 \
              3.61401 12.99C3.93001 12.674 3.89101 12.171 3.58701 11.88C2.9265 11.2506 2.4009 10.4934 \
              2.04212 9.65447C1.68335 8.81556 1.49891 7.91246 1.50001 7.00005C1.50001 5.15405 2.24101 \
              3.48005 3.44301 2.26205C3.73301 1.96705 3.76301 1.47705 3.45301 1.16705Z"
            )
            path(
              d="M5.214 2.92878C5.0823 2.79327 4.90225 2.71549 4.71331 2.71249C4.52437 2.70949 \
              4.34194 2.78152 4.206 2.91278C3.66483 3.44686 3.2353 4.08324 2.94242 4.7849C2.64953 \
              5.48655 2.49914 6.23945 2.5 6.99978C2.5 8.69178 3.23 10.2128 4.393 11.2638C4.53025 \
              11.385 4.70889 11.4488 4.89191 11.442C5.07492 11.4351 5.24826 11.358 5.376 11.2268C5.704 \
              10.8988 5.643 10.3828 5.335 10.0928C4.91281 9.69591 4.57651 9.21667 4.34689 8.68467C4.11727 \
              8.15267 3.99921 7.57922 4 6.99978C4 5.84978 4.457 4.80578 5.2 4.03978C5.486 3.74578 5.533 \
              3.24678 5.214 2.92878Z"
            )
            path(
              d="M10.7863 2.92878C10.918 2.79327 11.0981 2.71549 11.287 2.71249C11.4759 2.70949 \
              11.6584 2.78152 11.7943 2.91278C12.3355 3.44686 12.765 4.08324 13.0579 4.7849C13.3508 \
              5.48655 13.5012 6.23945 13.5003 6.99978C13.5003 8.69178 12.7703 10.2128 11.6073 11.2638C11.4701 \
              11.385 11.2914 11.4488 11.1084 11.442C10.9254 11.4351 10.7521 11.358 10.6243 11.2268C10.2963 \
              10.8988 10.3573 10.3828 10.6653 10.0928C11.0875 9.69591 11.4238 9.21667 11.6534 8.68467C11.883 \
              8.15267 12.0011 7.57922 12.0003 6.99978C12.0003 5.84978 11.5433 4.80578 10.8003 4.03978C10.5143 \
              3.74578 10.4673 3.24678 10.7863 2.92878Z"
            )
            path(
              d="M12.5471 1.16705C12.6138 1.09893 12.6933 1.04464 12.7811 1.00726C12.8689 0.969895 \
              12.9631 0.950182 13.0585 0.949253C13.1539 0.948324 13.2485 0.966198 13.3369 1.00185C13.4254 \
              1.03751 13.506 1.09024 13.5741 1.15705C14.3441 1.92263 14.9549 2.83311 15.3713 3.83596C15.7877 \
              4.83881 16.0014 5.91419 16.0001 7.00005C16.0013 8.12757 15.7708 9.24331 15.3229 10.278C14.8749 \
              11.3128 14.2191 12.2444 13.3961 13.015C13.2575 13.1431 13.0746 13.2121 12.886 13.2074C12.6974 \
              13.2028 12.5181 13.1248 12.3861 12.99C12.0701 12.674 12.1091 12.171 12.4141 11.88C13.0744 11.2505 \
              13.5998 10.4933 13.9584 9.65435C14.317 8.81544 14.5013 7.91238 14.5001 7.00005C14.5001 5.15405 \
              13.7591 3.48005 12.5571 2.26205C12.2671 1.96705 12.2371 1.47705 12.5471 1.16705Z"
            )
            path(
              d="M8 5.5C7.60218 5.5 7.22064 5.65804 6.93934 5.93934C6.65804 6.22064 6.5 6.60218 6.5 7C6.5 \
              7.39782 6.65804 7.77936 6.93934 8.06066C7.22064 8.34196 7.60218 8.5 8 8.5C8.39782 8.5 8.77936 8.34196 \
              9.06066 8.06066C9.34196 7.77936 9.5 7.39782 9.5 7C9.5 6.60218 9.34196 6.22064 9.06066 5.93934C8.77936 \
              5.65804 8.39782 5.5 8 5.5Z"
            )
        span {{speech.time_begin}}-
        span {{speech.time_end}}

      p.schedule-card__title(v-if="speech.title" :class="titleClass") {{speech.title}}

    .schedule-card__footer(
      :class="footerClass"
    )
      template(v-if="cardSizeHandler > 1")
        div(v-if='!showSpeakersAvatar')
          p.schedule-card__subtitle(
            v-if="visibleOnlyOneSpeaker"
          ) {{speech.speakers[0].name}}

          template(v-else-if="speakersLength > 1")

            span.schedule-card__subtitle(
              v-for="(speaker, i) in speakersWithLimit"
              :key="speaker.id"
            ) {{ speaker.name + (i < speakersLimit-1 ? ', ' : '')}}

            p.schedule-card__subtitle(
              v-if="speakersLength > speakersLimit"
            ) {{`+ ${speakersLength - speakersLimit} ${speakersWord}`}}

        .schedule-card__avatars(v-else)
          ZeenAvatar.schedule-card__avatar(
            v-for="(speaker, i) in speakersWithLimit"
            :userName="speaker.name"
            :src="i < speakersLimit && speaker.picture"
            :size="speakerAvatarSize"
            :customStyle='{"left": 22 * i + "px"}'
            :backgroundColor='avatarBackgroundColor'
          )
            span(v-if='i >= speakersLimit') {{ '+' + (speakersLength - speakersLimit) }}
      slot(name="edit" :speech="speech")
      span.schedule-card__button(@click.stop="cardButton" v-if='showPlayBtn')
        slot(name="button-icon" :speech="speech")
          svg(width="100%" height="100%" viewBox="0 0 12 12" xmlns="http://www.w3.org/2000/svg")
            path(d="M7.38761 7.77028C8.46254 7.01867 9 6.64287 9 6.00011C9 \
              5.35735 8.46254 4.98155 7.38761 4.22994C7.09087 4.02246 6.79656 \
              3.82711 6.52611 3.66433C6.28885 3.52152 6.02014 3.3738 5.74193 \
              3.22879C4.66953 2.66982 4.13333 2.39033 3.65241 2.69977C3.1715 3.0092 \
              3.12779 3.65699 3.04038 4.95255C3.01566 5.31894 3 5.67812 3 6.00011C3 6.3221 3.01566 \
              6.68128 3.04038 7.04767C3.12779 8.34324 3.1715 8.99102 3.65242 9.30046C4.13333 9.60989 \
              4.66953 9.33041 5.74193 8.77143C6.02014 8.62643 6.28884 8.4787 6.52611 8.3359C6.79656 \
              8.17311 7.09087 7.97776 7.38761 7.77028Z" stroke-width="1.5"
            )

</template>

<script>
import ZeenAvatar from '../ZeenAvatar/ZeenAvatar'
import {declOfNum} from '../../helpers/utils'

export default {
  name: 'ZeenScheduleCard',
  components: {
    ZeenAvatar,
  },
  props: {
    hall: {
      type: Object,
      default: () => {},
    },
    speech: {
      type: Object,
      default: () => {},
    },
    width: {
      type: Object,
    },
    coords: {
      type: Array,
      default: () => [],
    },
    speakersText: {
      type: Array,
      default: () => ['спикер', 'спикера', 'спикеров'],
    },
    showSpeakersAvatar: Boolean,
    speakersLimit: {
      type: Number,
      default: 3,
    },
    speakerAvatarSize: {
      type: Number,
      default: 30,
    },
  },
  methods: {
    cardClick() {
      this.$emit('cardClick', this.dataForEmit)
    },
    cardButton() {
      this.$emit('cardButtonClick', this.dataForEmit)
    },
  },
  computed: {
    titleClass() {
      return {'schedule-card__title_mini': this.cardSizeHandler === 1}
    },
    timeClass() {
      return {'schedule-card__time_mini': this.cardSizeHandler === 1}
    },
    footerClass() {
      return {'schedule-card__footer_mini': this.cardSizeHandler === 2}
    },
    avatarBackgroundColor() {
      return this.speech.status === 'online'
        ? 'var(--zeen-schedule-card-avatar-online-color)'
        : 'var(--zeen-schedule-card-avatar-color)'
    },
    visibleOnlyOneSpeaker() {
      return this.speakersLength === 1 || this.cardSizeHandler === 2
    },
    isLiveIconVisible() {
      return this.speech.status === 'online' && this.cardSizeHandler > 1
    },
    dataForEmit() {
      return {
        speech: this.speech ?? '',
        hall: this.hall ?? '',
      }
    },
    cardSizeHandler() {
      switch (this.cardWidth.steps) {
        case 2:
          return 2
        case 1:
          return 1
        default:
          return 3
      }
    },
    speakersWord() {
      return declOfNum(this.speakersLength - this.speakersLimit, this.speakersText)
    },
    speakersLength() {
      return this.speech?.speakers?.length ?? 0
    },
    speakersWithLimit() {
      return this.speech?.speakers?.slice(0, this.speakersLimit + this.showSpeakersAvatar) ?? []
    },
    cardWidth() {
      if (this.speech?.time_begin && this.speech?.time_end) {
        let idxStart
        let idxEnd
        this.width?.timeArray?.forEach((step, idx) => {
          if (step === this.speech.time_begin) {
            idxStart = idx
          }
          if (step === this.speech.time_end) {
            idxEnd = idx
          }
        })
        const steps = idxEnd - idxStart
        const width = this.width?.width * steps - 24
        return {width, steps}
      }
      return 0
    },
    position() {
      if (this.speech?.time_begin && this.coords?.length) {
        const coordObj = this.coords.find((item) => item.time === this.speech.time_begin)
        return coordObj?.coord ?? 0
      }
      return 0
    },
    cardStyles() {
      return {
        width: this.cardWidth?.width ? this.cardWidth.width + 'px' : undefined,
        left: this.position + 'px',
      }
    },
    showPlayBtn() {
      return this.speech?.status === 'online' || this.speech?.status === 'done'
    }
  },
}
</script>

<style lang="scss">
@import '../../styles/mixins.scss';
:root {
  /* Размеры */
  --zeen-schedule-card-min-width: 88px;
  --zeen-schedule-card-padding-vertical: 12px;
  --zeen-schedule-card-padding-horizontal: 12px;
  --zeen-schedule-card-border-radius: 20px;

  --zeen-schedule-card-title-size: var(--main-small-text);
  --zeen-schedule-card-title-line-height: 1.42;
  --zeen-schedule-card-title-font-weight: 500;

  --zeen-schedule-card-subtitle-size: var(--main-smallest-text);
  --zeen-schedule-card-subtitle-line-height: 1.5;
  --zeen-schedule-card-subtitle-font-weight: 400;
  --zeen-schedule-card-subtitle-margin-top: 10px;

  --zeen-schedule-card-live-padding-vertical: 4px;
  --zeen-schedule-card-live-padding-horizontal: 5px;
  --zeen-schedule-card-live-margin-right: 10px;
  --zeen-schedule-card-live-border-radius: 5px;
  --zeen-schedule-card-live-img-size: var(--action-icon-min-width-middle);
  --zeen-schedule-card-live-text: var(--main-smallest-text);
  --zeen-schedule-card-live-text-line-height: 1.33;
  --zeen-schedule-card-live-text-font-weight: 600;
  --zeen-schedule-card-live-text-margin-left: 4px;

  --zeen-schedule-card-time-text: 12px;
  --zeen-schedule-card-time-text-line-height: 1.42;
  --zeen-schedule-card-time-text-font-weight: 500;
  --zeen-schedule-card-time-border-radius: 8px;
  --zeen-schedule-card-time-padding: 4px 8px;

  --zeen-schedule-card-button-size: 32px;
  --zeen-schedule-card-button-svg-size: 12px;
  --zeen-schedule-card-footer-margin-top: 30px;
  --zeen-schedule-card-avatar-font-weight: 700;
  --zeen-schedule-card-avatar-text-size: 10;
  --zeen-schedule-avatar-border: 2px;
  --zeen-schedule-avatars-size: 30px;

  @include phones {
    --zeen-schedule-card-padding-vertical: 10px;
    --zeen-schedule-card-padding-horizontal: 15px;
    --zeen-schedule-card-live-text: 10px;
    --zeen-schedule-card-live-text-line-height: 1.4;
  }

  /* Цвета */
  --zeen-schedule-card-color: var(--main-color);
  --zeen-schedule-card-color-hold: var(--main-light);
  --zeen-schedule-card-color-done: var(--main-light);
  --zeen-schedule-card-box-shadow-color: rgba(0, 0, 0, 0.05);

  --zeen-schedule-card-live-color: var(--main-light);
  --zeen-schedule-card-text-color: var(--main-light);
  --zeen-schedule-card-text-color-hold: var(--main-text-color);
  --zeen-schedule-card-text-color-done: var(--dark-1);

  --zeen-schedule-card-live-img-color: var(--main-light);
  --zeen-schedule-card-button-color: var(--main-color);
  --zeen-schedule-card-button-color-hold: var(--main-color);
  --zeen-schedule-card-button-color-done: var(--main-color);
  --zeen-schedule-card-button-box-shadow: 0px 2px 7px rgba(116, 111, 135, 0.11);
  --zeen-schedule-card-button-background: var(--main-light);

  --zeen-schedule-card-avatar-online-color: var(--main-dark-color);
  --zeen-schedule-card-avatar-color: var(--gray-1);
  --zeen-schedule-card-avatar-text-color: var(--main-light);
  --zeen-schedule-card-avatar-text-hold-color: var(--gray-2);
  --zeen-schedule-card-avatar-text-done-color: var(--gray-2);

  --zeen-schedule-card-time-background: var(--main-dark-color);
  --zeen-schedule-card-time-background-hold: #f6f5f7;
  --zeen-schedule-card-time-background-done: #f6f5f7;
}
</style>

<style scoped lang="scss">
@import '../../styles/mixins.scss';

.schedule-card {
  box-sizing: border-box;
  min-width: var(--zeen-schedule-card-min-width);
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  align-items: flex-start;
  padding: var(--zeen-schedule-card-padding-vertical) var(--zeen-schedule-card-padding-horizontal);
  background: var(--zeen-schedule-card-color);
  border-radius: var(--zeen-schedule-card-border-radius);
  box-shadow: 0px 3px 20px var(--zeen-schedule-card-box-shadow-color);
  cursor: pointer;

  &__wrapper-text {
    display: flex;
    flex-direction: column;
    width: 100%;
  }

  &__title {
    text-overflow: ellipsis;
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    overflow: hidden;

    margin: 0;
    font-size: var(--zeen-schedule-card-title-size);
    line-height: var(--zeen-schedule-card-title-line-height);
    font-weight: var(--zeen-schedule-card-title-font-weight);
    color: var(--zeen-schedule-card-text-color);

    &_mini {
      -webkit-line-clamp: 1;
    }
  }

  &__subtitle {
    margin: 0;
    font-size: var(--zeen-schedule-card-subtitle-size);
    line-height: var(--zeen-schedule-card-subtitle-line-height);
    font-weight: var(--zeen-schedule-card-subtitle-font-weight);
    color: var(--zeen-schedule-card-text-color);
    margin-top: var(--zeen-schedule-card-subtitle-margin-top);
    &:nth-child(3) {
      margin-top: 0;
    }
  }

  &__footer {
    display: flex;
    justify-content: space-between;
    align-items: center;
    width: 100%;
    margin-top: var(--zeen-schedule-card-footer-margin-top);
    &_mini {
      .schedule-card__time {
        flex: 0 0 auto;
      }
    }
  }

  &__live-img {
    width: var(--zeen-schedule-card-live-img-size);
    height: auto;
    fill: var(--zeen-schedule-card-live-img-color);
    margin-right: 5px;
  }

  &__time {
    display: flex;
    align-items: center;
    flex: 1 1 auto;
    width: fit-content;
    padding: var(--zeen-schedule-card-time-padding);
    margin-bottom: var(--zeen-schedule-card-time-border-radius);
    background: var(--zeen-schedule-card-time-background);
    border-radius: var(--zeen-schedule-card-time-border-radius);
    color: var(--zeen-schedule-card-text-color);
    font-size: var(--zeen-schedule-card-time-text);
    line-height: var(--zeen-schedule-card-time-text-line-height);
    font-weight: var(--zeen-schedule-card-time-text-font-weight);
    white-space: nowrap;
    flex-wrap: wrap;

    &_mini {
      background: linear-gradient(90deg, var(--zeen-schedule-card-time-background) 20%, rgba(246, 245, 247, 0) 95%);
    }
  }

  &__button {
    display: flex;
    align-items: center;
    justify-content: center;
    width: var(--zeen-schedule-card-button-size);
    height: var(--zeen-schedule-card-button-size);
    fill: var(--zeen-schedule-card-button-color);
    background: var(--zeen-schedule-card-button-background);
    box-shadow: var(--zeen-schedule-card-button-box-shadow);
    border-radius: 50%;
    cursor: pointer;

    svg {
      width: var(--zeen-schedule-card-button-svg-size);
      height: var(--zeen-schedule-card-button-svg-size);
    }
  }

  &__avatars {
    position: relative;
    height: var(--zeen-schedule-avatars-size);
  }

  &__avatar {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    left: 0;
    border: var(--zeen-schedule-avatar-border) solid var(--zeen-schedule-card-color);

    span {
      font-weight: var(--zeen-schedule-card-avatar-font-weight);
      font-size: var(--zeen-schedule-card-avatar-text-size);
      line-height: 1.5;
      color: var(--zeen-schedule-card-avatar-text-color);
    }
  }

  &__hold {
    background: var(--zeen-schedule-card-color-hold);
    .schedule-card__title {
      color: var(--zeen-schedule-card-text-color-hold);
    }
    .schedule-card__subtitle {
      color: var(--zeen-schedule-card-text-color-hold);
    }
    .schedule-card__time {
      background: var(--zeen-schedule-card-time-background-hold);
      color: var(--zeen-schedule-card-button-color-hold);

      &_mini {
        background: linear-gradient(
          90deg,
          var(--zeen-schedule-card-time-background-hold) 20%,
          rgba(246, 245, 247, 0) 95%
        );
      }
    }
    .schedule-card__button {
      fill: var(--zeen-schedule-card-button-color-hold);
    }

    .schedule-card__avatar {
      border-color: var(--zeen-schedule-card-color-done);

      span {
        color: var(--zeen-schedule-card-avatar-text-hold-color);
      }
    }
  }

  &__done {
    background: var(--zeen-schedule-card-color-done);
    .schedule-card__title {
      color: var(--zeen-schedule-card-text-color-done);
    }
    .schedule-card__subtitle {
      color: var(--zeen-schedule-card-text-color-done);
    }
    .schedule-card__time {
      background: var(--zeen-schedule-card-time-background-done);
      color: var(--zeen-schedule-card-text-color-done);

      &_mini {
        background: linear-gradient(
          90deg,
          var(--zeen-schedule-card-time-background-done) 20%,
          rgba(246, 245, 247, 0) 95%
        );
      }
    }
    .schedule-card__button {
      fill: var(--zeen-schedule-card-button-color-done);
    }

    .schedule-card__avatar {
      border-color: var(--zeen-schedule-card-color-done);

      span {
        color: var(--zeen-schedule-card-avatar-text-done-color);
      }
    }
  }
}
</style>