HEX
Server: nginx/1.18.0
System: Linux test-ipsremont 5.4.0-214-generic #234-Ubuntu SMP Fri Mar 14 23:50:27 UTC 2025 x86_64
User: ips (1000)
PHP: 8.0.30
Disabled: pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare,
Upload Files
File: //var/www/quadcode.com/src/components/blocks/main/Videos.svelte
<script lang="ts">
  import { t } from '$lib/translations';
  import { getLocaleUrl } from '$lib/translations';

  import arrow from '../../../assets/images/main/arr.svg';

  function getVideoId(url: string): string {
    const match = url.match(/(?:youtube\.com\/watch\?v=|youtu\.be\/)([^&\n?#]+)/);
    return match ? match[1] : '';
  }

  function getThumbnailUrl(videoId: string): string {
    return `https://img.youtube.com/vi/${videoId}/maxresdefault.jpg`;
  }

  function handleVideoClick(videoId: string, event: MouseEvent | KeyboardEvent) {
    const target = event.currentTarget as HTMLElement;
    const thumbnail = target.querySelector('.block-videos__card-thumbnail-img') as HTMLElement;
    const playButton = target.querySelector('.block-videos__card-play-button') as HTMLElement;
    const iframeContainer = target.querySelector('.block-videos__card-iframe-container') as HTMLElement;

    if (thumbnail && playButton && iframeContainer) {
      thumbnail.style.display = 'none';
      playButton.style.display = 'none';
      const iframe = iframeContainer.querySelector('iframe') as HTMLIFrameElement;
      if (iframe) {
        iframe.src = `https://www.youtube.com/embed/${videoId}?autoplay=1`;
        iframeContainer.style.display = 'block';
      }
    }
  }

  const videos = [
    {
      title: 'What Nobody Tells You About Opening Your Own Brokerage (Real Talk)',
      description:
         'Thinking about starting a brokerage? 💡 Here’s the unfiltered truth about what it REALLY takes. In this webinar, we dive deep into the things nobody tells...',
      contentUrl: 'https://www.youtube.com/watch?v=3_dZAp2bOp0',
    },
    {
      title: 'How to Launch a Brokerage Without Burning $100K?',
      description:
        'Learn how to start a fully functional, compliant brokerage without wasting time or overspending. In this webinar, we break down the real costs, smartest tools...',
      contentUrl: 'https://www.youtube.com/watch?v=lRWiCeYqYi8',
    },
    {
      title: 'Being an Affiliate vs Starting a Brokerage Firm (Which Makes More Money in 2025?)',
      description:
        'Should you become an affiliate marketer or launch your own brokerage firm in 2025? In this video, we break down the pros, cons, startup costs and earning...',
      contentUrl: 'https://www.youtube.com/watch?v=CKI1PGCKz3o',
    },
  ];
</script>

<div class="block-videos">
  <div class="container container-main">
    <div class="block-videos__header">
      <h2 class="block-videos__title">{$t('Video Tutorials')}</h2>
      <a href={getLocaleUrl('/video-tutorials')} class="block-videos__show-all">
        {$t('Show all')} <span><img src={arrow} alt="arrow" /></span>
      </a>
    </div>

    <div class="block-videos__grid">
      {#each videos as video (video.contentUrl)}
        {@const videoId = getVideoId(video.contentUrl)}
        {@const thumbnailUrl = getThumbnailUrl(videoId)}
        <div
          class="block-videos__card"
          on:click={(e) => handleVideoClick(videoId, e)}
          on:keydown={(e) => {
            if (e.key === 'Enter' || e.key === ' ') {
              e.preventDefault();
              handleVideoClick(videoId, e);
            }
          }}
          role="button"
          tabindex="0"
        >
          <div class="block-videos__card-thumbnail">
            <img src={thumbnailUrl} alt={video.title} class="block-videos__card-thumbnail-img" />
            <div class="block-videos__card-play-button">
              <svg width="68" height="68" viewBox="0 0 68 68" fill="none" xmlns="http://www.w3.org/2000/svg">
                <defs>
                  <clipPath id="clip0_913_8151_{videoId}">
                    <rect width="68" height="68" rx="34" fill="white" />
                  </clipPath>
                </defs>
                <g clip-path="url(#clip0_913_8151_{videoId})">
                  <rect width="68" height="68" rx="34" fill="#F9FBFC" fill-opacity="0.3" />
                  <path
                    d="M44.475 31.792C46.175 32.7735 46.175 35.2272 44.475 36.2087L27.9 45.7783C26.2 46.7598 24.075 45.5329 24.075 43.5699L24.075 24.4308C24.075 22.4678 26.2 21.2409 27.9 22.2224L44.475 31.792Z"
                    fill="#F9FBFC"
                  />
                </g>
              </svg>
            </div>
            <div class="block-videos__card-iframe-container" style="display: none;">
              <iframe
                width="100%"
                height="100%"
                title={video.title}
                frameborder="0"
                allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
                allowfullscreen
                class="block-videos__card-iframe"
              />
            </div>
          </div>
          <div class="block-videos__card-content">
            <h3 class="block-videos__card-title">{video.title}</h3>
            <p class="block-videos__card-description">{video.description}</p>
          </div>
        </div>
      {/each}
    </div>
  </div>
</div>

<style lang="scss">
  @import 'src/scss/variables';
  @import 'src/scss/media';
  @import 'src/scss/mixins';

  .block-videos {
    background: #f2f5f7;
    overflow: hidden;
    width: 100%;
    padding: 112px 0;

    .container-main {
      position: relative;
      max-width: 1440px;
      width: 100%;
      margin: 0 auto;
      padding: 0 56px;

      @media (max-width: 1366px) {
        padding: 0 40px;
      }
      @media (max-width: 1024px) {
        padding: 0 32px;
      }

      @media (max-width: 480px) {
        padding: 0 24px;
      }
      @media (max-width: 393px) {
        padding: 0 20px;
      }
    }

    &__header {
      display: flex;
      justify-content: space-between;
      align-items: center;
      margin-bottom: 24px;

      @include breakpoint-down('deskL') {
        margin-bottom: 24px;
      }

      @include breakpoint-down('deskS') {
        margin-bottom: 40px;
      }
    }

    &__title {
      font-weight: 400;
      font-size: 32px;
      line-height: 40px;
      color: #1b1c1d;

      @media (max-width: 1024px) {
        font-size: 28px;
        line-height: 36px;
      }

      @media (max-width: 480px) {
        font-size: 24px;
        line-height: 28px;
      }

      @media (max-width: 393px) {
        font-size: 20px;
        line-height: 26px;
      }
    }

    &__show-all {
      font-size: 14px;
      line-height: 20px;
      color: #1b1c1d;
      text-decoration: none;
      display: flex;
      align-items: center;
      gap: 4px;
      transition: all 0.2s ease;
      padding: 8px 12px;
      border: 1px solid #cdd1d4;
      border-radius: 48px;
      cursor: pointer;

      @media (max-width: 1366px) {
        padding: 6px 12px;
        line-height: 18px;
      }

      @media (max-width: 720px) {
        padding: 6px 6px 6px 12px;
        line-height: 18px;
      }

      img {
        width: 16px;
        height: 16px;
      }

      &:hover {
        border-color: transparent;
        background-color: #d4d8db;
      }

      &:active {
        background-color: #adb1b7;
        border-color: transparent;
      }

      span {
        font-size: 14px;
        line-height: 20px;
      }
    }

    &__grid {
      display: grid;
      grid-template-columns: repeat(3, 1fr);
      gap: 24px;

      @media (max-width: 720px) {
        display: flex;
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;

        &::-webkit-scrollbar {
          display: none;
        }

        -ms-overflow-style: none;
        scrollbar-width: none;
      }
    }

    &__card {
      width: 100%;

      @media (max-width: 720px) {
        width: 300px;
        flex-shrink: 0;
      }
    }

    &__card {
      cursor: pointer;
    }

    &__card-thumbnail {
      width: 100%;
      margin-bottom: 24px;
      border-radius: 20px;
      overflow: hidden;
      aspect-ratio: 16 / 9;
      background: #d9d9d9;
      position: relative;
    }

    &__card-thumbnail-img {
      width: 100%;
      height: 100%;
      object-fit: cover;
      display: block;
    }

    &__card-play-button {
      position: absolute;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
      z-index: 1;
      transition: transform 0.2s ease;

      svg {
        width: 68px;
        height: 68px;
        display: block;
      }
    }

    &__card:hover &__card-play-button {
      transform: translate(-50%, -50%) scale(1.1);
    }

    &__card-iframe-container {
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
    }

    &__card-iframe {
      width: 100%;
      height: 100%;
      border: none;
      display: block;
    }

    &__card-content {
      padding: 0 8px;
    }

    &__card-title {
      font-size: 20px;
      line-height: 26px;
      font-weight: 400;
      color: #1b1c1d;
      margin: 0 0 12px 0;
      letter-spacing: 0.1px;

      @media (max-width: 1024px) {
        font-size: 18px;
      }

      @media (max-width: 393px) {
        line-height: 24px;
      }
    }

    &__card-description {
      font-size: 16px;
      line-height: 24px;
      color: #525659;
      margin: 0;
      line-clamp: 3;
      display: -webkit-box;
      -webkit-line-clamp: 3;
      -webkit-box-orient: vertical;
      overflow: hidden;
    }
  }
</style>