<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width" />

    <title>Gradio theme gallery</title>
    <meta name="description" content="Discover all gradio themes created by the community." />

    <meta property="og:url" content="https://freddyaboulton-gradio-themes-gallery.hf.space/" />
    <meta property="og:type" content="website" />
    <meta property="og:title" content="Gradio - Theme Gallery" />
    <meta property="og:description" content="Discover all gradio themes created by the community." />
    <meta property="og:image" content="https://huggingface-projects-diffusers-gallery.hf.space/Fo6vR6JX0AEjbw1.jpeg" />

    <meta name="twitter:card" content="player" />
    <meta property="twitter:url" content="https://freddyaboulton-gradio-themes-gallery.hf.space/" />
    <meta name="twitter:description" content="Discover all gradio themes created by the community." />

    <meta name="twitter:site" content="@huggingface" />
    <meta name="twitter:title" content="Gradio - Theme Gallery" />

    <meta name="twitter:image" content="https://huggingface-projects-diffusers-gallery.hf.space/Fo6vR6JX0AEjbw1.jpeg" />
    <meta name="twitter:player" content="https://freddyaboulton-gradio-themes-gallery.hf.space/index.html" />
    <meta name="twitter:player:width" content="100%" />
    <meta name="twitter:player:height" content="600" />

    <script src="https://cdnjs.cloudflare.com/ajax/libs/iframe-resizer/4.3.1/iframeResizer.contentWindow.min.js"></script>
    <script src="https://cdn.tailwindcss.com"></script>

    <style>

		iframe {
			display: block;
			border: none;
			width: 100%;
			height: 600px;
			pointer-events: none;
		}

		.grid-container {
			display: grid;
			grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
			grid-gap: 10px;
      margin-top: 3.5rem;
		}

		.grid-item {
			position: relative;
      overflow-y: hidden;
      border-radius: 10px;
      border: 1px solid rgb(55 65 81);
		}
    .grid-item:hover {
      filter: brightness(75%);
    }

		.grid-item a {
			position: absolute;
			top: 0;
			left: 0;
			width: 100%;
			height: 100%;
			display: block;
			z-index: 1;
		}
    </style>

    <script type="module">
      import Alpine from "https://cdn.skypack.dev/alpinejs@3.13.9";
      import Intersect from "https://cdn.skypack.dev/@alpinejs/intersect";
      Alpine.plugin(Intersect);

      Alpine.data("themesData", () => ({
        async init() {
          const data = await this.getThemes(this.page, this.sort, this.useTestData);
          this.themes = data.themes;
          this.totalPages = data.totalPages;
        },
        themes: [],
        filter: "all",
        sort: "likes",
        page: 1,
        totalPages: -1,
        mode: "light",
        useTestData: false,
        buttonClass(attr, filter) {
          if (this[attr] === filter) {
            return "text-orange-600 bg-gradient-to-br from-orange-300 to-orange-100 px-2 md:px-3 py-1 rounded-full";
          }
          return "text-gray-800 hover:to-orange-300/100 hover:text-orange-600 dark:hover:bg-white";
        },
        async switchData() {
          this.page = 1;
          this.useTestData = !this.useTestData;
          const data = await this.getThemes(this.page, this.sort, this.useTestData);
          this.themes = data.themes;
          this.totalPages = data.totalPages;
        },
        async switchTheme() {
          this.mode = this.mode === "light" ? "dark": "light";
          console.log(this.mode);
        },
        async sortThemes(sort) {
          this.sort = sort;
          this.page = 1;
          const data = await this.getThemes(this.page, this.sort, this.useTestData);
          this.themes = data.themes;
          this.totalPages = data.totalPages;
        },
        async getThemes(page, sort, useTestData) {
          const filename = useTestData ? "test_data.json" : "subdomains.json"
          const res = await fetch(
            `https://huggingface.co/datasets/freddyaboulton/gradio-theme-subdomains/resolve/main/${filename}`
          );
          const data = await res.json();
          if(sort === 'likes') {
            data.sort((a, b) => (b.likes - a.likes));
          }else {
            data.sort((a, b) => (new Date(b.lastModified) - new Date(a.lastModified)));
          }
          const pageThemes = data.slice((page - 1) * 15, page * 15);

          console.log(pageThemes);

          return {
            themes: pageThemes,
            totalPages: Math.floor(data.length + 15  - 1, 15)
          };
        },
        async nextPage() {
          if (this.page < this.totalPages) {
            this.page += 1;
            const data = await this.getThemes(this.page, this.sort, this.useTestData);
            this.themes = this.themes.concat(data.themes);
            this.totalPages = data.totalPages;
          }
        },
      }));
      Alpine.start();
    </script>
  </head>

  <body class="pb-10 pt-5 bg-white relative">
    <section
      x-data="themesData"
    >
      <section class="container px-6 grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-14 mx-auto relative">
        <div class="col-span-2 lg:col-span-1 flex flex-col gap-14 row-start">
          <h1 class="text-lg font-semibold text-gray-800 whitespace-nowrap">Gradio Themes Gallery</h1>
        </div>
        <div class="col-span-2 md:col-span-3 flex items-center gap-14 flex flex-wrap lg-auto lg:ml-auto text-sm">
          <div class="flex gap-2">
            <span class="md:px-3 py-1 text-gray-800">sort by</span>
            <button
            :class="buttonClass('sort', 'likes')"
            @click="sortThemes('likes')"
            >
              Most Likes
            </button>
            <button
              :class="buttonClass('sort', 'recent')"
              @click="sortThemes('recent')"
            >
              Recent
            </button>
          </div>
          <div class="flex gap-0">
            <!-- <input type="checkbox" @click="switchData()" class="rounded accent-orange-300">
            <span class="md:px-3 py-1 text-gray-800 ml-0">Use Test Data</span> -->
            <input type="checkbox" @click="switchTheme()" class="rounded accent-orange-300">
            <span class="md:px-3 py-1 text-gray-800 ml-0">Show Dark Mode</span>
            <!-- <button
              :class="buttonClass('useTestData', false)"
              class="px-2 md:px-3 py-1 rounded-full"
              @click="switchData()"
            >
              Use Test Data
            </button> -->
          </div>
        </div>
      </section>
      <div class="container px-6 grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-2 mx-auto my-8  relative">
      <template x-for="theme in themes" :key="theme.id">
        <div class="grid-item">
          <iframe :src="`${theme.subdomain}?_=${new Date().getTime()}&__theme=${mode}`" :alt="theme.id" scrolling="no" frameborder="0" loading="lazy"></iframe>
          <a :href="`https://huggingface.co/spaces/${theme.id}`" target="_blank"></a>
        </div>
      </template>
      </div>
      <div class="h-12 relative" x-intersect="nextPage" data-iframe-height></div>
    </section>
  </body>
</html>