CoursesPage.vue 5.16 KB
<template>
  <AppLayout :rightContent="rightContent">
    <div class="pb-16">
      <!-- Search Bar -->
      <div class="pb-2">
        <SearchBar placeholder="搜索" :isCoursePage="true" />
      </div>

      <!-- Featured Course Banner -->
      <div class="px-4 mb-5" v-if="bannerList.length">
        <van-swipe
          class="rounded-xl overflow-hidden shadow-lg h-40"
          :autoplay="3000"
          :show-indicators="true"
          indicator-color="rgba(255, 255, 255, 0.5)"
          indicator-active-color="#fbbf24"
        >
          <van-swipe-item
            v-for="(banner, index) in bannerList"
            :key="index"
            class="relative"
            @click="handleBannerClick(banner)"
          >
            <img
              :src="banner.banner || 'https://cdn.ipadbiz.cn/mlaj/images/featured-course.jpg'"
              :alt="banner.title || '课程横幅'"
              class="w-full h-full object-cover"
            />
            <div
              class="absolute inset-0 bg-gradient-to-b from-transparent to-black/50 flex flex-col justify-end p-4"
            >
              <h2 class="text-2xl font-bold text-amber-400 drop-shadow-md">{{ banner.post_title }}</h2>
              <p class="text-xl text-white font-semibold drop-shadow-sm">{{ banner.post_excerpt }}</p>
            </div>
          </van-swipe-item>
        </van-swipe>
      </div>

      <!-- Today's Live -->
      <!--<div class="px-4 mb-4">
        <div class="flex items-center mb-2">
          <h2 class="font-medium">今日直播</h2>
          <div
            class="ml-2 flex items-center bg-red-100 text-red-700 rounded px-2 py-1 text-xs"
          >
            <span class="font-medium">{{ hours }}</span>
            <span class="mx-1">:</span>
            <span class="font-medium">{{ minutes }}</span>
            <span class="mx-1">:</span>
            <span class="font-medium">00</span>
          </div>
        </div>

        <!~~ Live Stream Cards ~~>
        <div class="grid grid-cols-2 gap-4">
          <LiveStreamCard
            v-for="stream in liveStreams"
            :key="stream.id"
            :stream="stream"
          />
        </div>
      </div>-->

      <!-- Value Online Courses -->
      <div class="px-4 mb-4">
        <div class="flex justify-between items-center mb-2">
          <h2 class="font-medium">超值线上课</h2>
          <router-link to="/courses-list" class="text-xs text-gray-500 flex items-center">
            更多
            <svg
              xmlns="http://www.w3.org/2000/svg"
              class="h-3 w-3 ml-1"
              fill="none"
              viewBox="0 0 24 24"
              stroke="currentColor"
            >
              <path
                stroke-linecap="round"
                stroke-linejoin="round"
                stroke-width="2"
                d="M9 5l7 7-7 7"
              />
            </svg>
          </router-link>
        </div>

        <!-- Course Cards -->
        <div class="space-y-4">
          <CourseCard v-for="course in courses" :key="course.id" :course="course" />
        </div>
      </div>
    </div>
  </AppLayout>
</template>

<script setup lang="jsx">
import { computed, defineComponent, h } from "vue";
import { useRoute, useRouter } from 'vue-router'
import AppLayout from "@/components/layout/AppLayout.vue";
import SearchBar from "@/components/ui/SearchBar.vue";
import FrostedGlass from "@/components/ui/FrostedGlass.vue";
import CourseCard from "@/components/ui/CourseCard.vue";
import LiveStreamCard from "@/components/ui/LiveStreamCard.vue";
import { featuredCourse, liveStreams } from "@/utils/mockData";
import { useTitle } from '@vueuse/core';

// 导入接口
import { getCourseListAPI, getCourseBannerAPI } from "@/api/course";

const courses = ref([]);
const bannerList = ref([]);

onMounted(async () => {
  const res = await getCourseListAPI({ limit: 4 });
  if (res.code) {
    courses.value = res.data;
  }
  const bannerRes = await getCourseBannerAPI();
  if (bannerRes.code) {
    bannerList.value = bannerRes.list;
  }
})

const $route = useRoute();
const $router = useRouter();
useTitle($route.meta.title);

const handleBannerClick = (banner) => {
  if (!banner.post_link) return;
  if (banner.post_link.startsWith('http')) {
    window.location.href = banner.post_link;
  } else {
    $router.push(banner.post_link);
  }
};

// Current time for the countdown timer
const todayDate = new Date();
const formattedTime = featuredCourse.liveTime.split(":");
const hours = computed(() => formattedTime[0]);
const minutes = computed(() => formattedTime[1]);

// Right content component

const RightContent = defineComponent({
  setup() {
    return () => (
      <button class="p-2">
        <svg
          xmlns="http://www.w3.org/2000/svg"
          class="h-6 w-6 text-gray-700"
          fill="none"
          viewBox="0 0 24 24"
          stroke="currentColor"
        >
          <path
            stroke-linecap="round"
            stroke-linejoin="round"
            stroke-width="2"
            d="M12 5v.01M12 12v.01M12 19v.01M12 6a1 1 0 110-2 1 1 0 010 2zm0 7a1 1 0 110-2 1 1 0 010 2zm0 7a1 1 0 110-2 1 1 0 010 2z"
          />
        </svg>
      </button>
    );
  },
});

const rightContent = h(RightContent);
</script>