Skip to content
Snippets Groups Projects
Select Git revision
  • 8356f60331eb632f5820fb5ba6ee6ece115502f5
  • master default protected
  • feat/redesign
  • feat/dockerfile
  • feat/nastenka
  • feat/crossroads
6 results

CardProgramItem.vue

Blame
  • user avatar
    Tomáš Valenta authored
    8356f603
    History
    CardProgramItem.vue 5.55 KiB
    <script setup>
      import { isLgScreenSize } from "../../utils"
      import CardProgramItemPoint from "./CardProgramItemPoint"
    </script>
    
    <template>
      <li
        :class="this.isOpen ? 'w-full': ''"
      >
        <div
          ref="closedVariant"
          class="
            bg-black flex flex-row items-center px-5 py-2 gap-5 justify-between duration-200 cursor-pointer
    
            xl:flex-col xl:gap-32 xl:py-8 xl:px-3
    
            hover:bg-grey-600
          "
          v-if="!this.isOpen"
          @click="openClose"
        >
          <div
            class="font-alt text-black text-7xl xl:text-9xl"
            style="text-shadow: -1px -1px 0 #fff, 1px -1px 0 #fff, -1px 1px 0 #fff, 1px 1px 0 #fff"
          >
            {{ number }}
          </div>
          <div
            class="
              text-white leading-7 text-2xl
    
              xl:rotate-180 xl:[writing-mode:vertical-rl]
            "
          >
            {{ title }}
          </div>
        </div>
    
        <div
          ref="openVariant"
          class="bg-white h-full"
          :class="
            !this.defaultIsOpen ?
    
            'w-0 [&_*]:!text-[0rem] [&_*]:!p-0 [&_*]:!gap-0 [&_*]:!leading-[0px] [&_*]:!delay-0 [&_*]:!duration-0'
              :
            'p-6 xl:p-12'
          "
        >
          <div
            class="
              flex flex-col gap-8
    
              xl:flex-row xl:gap-16
            "
          >
            <div
              class="w-full flex flex-col gap-8"
            >
              <h2
                class="
                  font-alt text-[3.25rem] duration-200 delay-100
    
                  xl:text-[6.5rem]
                "
              >
                {{ this.title }}
              </h2>
    
              <CardProgramItemPoint
                :number="points[0].number"
                :content="points[0].content"
              />
            </div>
    
            <div
              class="
                flex flex-col gap-7
                w-full
              "
            >
              <CardProgramItemPoint
                v-for="(point, index) in points.slice(1)"
                :number="point.number"
                :content="point.content"
              />
            </div>
          </div>
        </div>
      </li>
    </template>
    
    <script>
    export default {
      name: "CardProgramItem",
      props: ["slug", "title", "number", "content", "points", "defaultIsOpen"],
      data () {
        return {
          isOpen: this.defaultIsOpen
        }
      },
      methods: {
        openClose: function () {
          this.isOpen = !this.isOpen
    
          if (this.isOpen) {
            // So other items close when this one is opened
            let urlParams = new URLSearchParams(window.location.search)
            let url = new URL(window.location)
    
            urlParams.set("program_view", this.slug)
            url.search = urlParams
    
            window.history.replaceState(
              {},
              this.slug,
              url
            )
          }
        }
      },
      mounted () {
        this.$watch(
          "isOpen",
          (isNowOpen, wasOpen) => {
            if (isNowOpen && !wasOpen) {
              this.$refs.openVariant.classList.remove("w-0")
              this.$refs.openVariant.classList.remove("[&_*]:!text-[0rem]")
              this.$refs.openVariant.classList.remove("[&_*]:!p-0")
              this.$refs.openVariant.classList.remove("[&_*]:!gap-0")
              this.$refs.openVariant.classList.remove("[&_*]:!leading-[0px]")
              this.$refs.openVariant.classList.remove("[&_*]:!duration-0")
              this.$refs.openVariant.classList.remove("[&_*]:!delay-0")
    
              if (isLgScreenSize()) {
                this.$refs.openVariant.classList.add("duration-300")
              }
    
              this.$refs.openVariant.classList.add("w-full")
              this.$refs.openVariant.classList.add("xl:p-12")
              this.$refs.openVariant.classList.add("p-6")
    
              // Do this only after 20ms, after the browser's had time to hopefully catch up.
              setTimeout(
                () => {
                  const openVariantPosition = this.$refs.openVariant.getBoundingClientRect().top
                  const offsetPosition = openVariantPosition + window.pageYOffset - 90
    
                  window.scrollTo({
                    top: offsetPosition,
                    behavior: "instant"
                  })
                },
                20
              )
            } else if (!isNowOpen && wasOpen) {
              if (isLgScreenSize()) {
                this.$refs.openVariant.classList.remove("duration-300")
              }
    
              this.$refs.openVariant.classList.remove("w-full")
              this.$refs.openVariant.classList.remove("xl:p-12")
              this.$refs.openVariant.classList.remove("p-6")
    
              this.$refs.openVariant.classList.add("w-0")
              this.$refs.openVariant.classList.add("[&_*]:!text-[0rem]")
              this.$refs.openVariant.classList.add("[&_*]:!p-0")
              this.$refs.openVariant.classList.add("[&_*]:!gap-0")
              this.$refs.openVariant.classList.add("[&_*]:!leading-[0px]")
              this.$refs.openVariant.classList.add("[&_*]:!duration-0")
              this.$refs.openVariant.classList.add("[&_*]:!delay-0")
            }
          }
        )
    
        // --- BEGIN URL watch ---
    
        let previousUrl = null;
    
        setInterval(
          () => {
            const currentUrl = window.location.href;
    
            if (currentUrl != previousUrl) {
              // URL changed
              previousUrl = currentUrl;
    
              const params = new Proxy(
                new URLSearchParams(window.location.search), {
                  get: (searchParams, prop) => searchParams.get(prop),
                }
              )
    
              if (
                params.program_view !== null
                && params.program_view !== this.slug
              ) {
                this.isOpen = false
              }
    
              if (
                params.program_view !== null
                && params.program_view === this.slug
                && !this.isOpen
              ) {
                this.isOpen = true
              }
            }
          },
          1
        )
    
        // --- END URL watch ---
      }
    }
    </script>