Files
gongxue-new/docs/.vitepress/theme/components/EnrollModal.vue

124 lines
4.3 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<script setup lang="ts">
import { ref, watch, onUnmounted } from 'vue'
import { X } from 'lucide-vue-next'
interface Props {
isOpen: boolean
}
const props = defineProps<Props>()
const emit = defineEmits<{ (e: 'close'): void }>()
const containerRef = ref<HTMLDivElement | null>(null)
const modalRef = ref<HTMLDivElement | null>(null)
watch(() => props.isOpen, (open) => {
if (!containerRef.value) return
if (open) {
document.body.style.overflow = 'hidden'
document.body.style.touchAction = 'none'
containerRef.value.innerHTML = `
<div class="loading-indicator" style="text-align: center; padding: 2rem;">
<div style="border: 4px solid #3b82f6; border-top: 4px solid transparent; border-radius: 50%; width: 48px; height: 48px; animation: spin 1s linear infinite; margin: 0 auto 1rem;"></div>
<p style="color: #6b7280;">表单加载中...</p>
</div>
<style>
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
</style>
`
const iframe = document.createElement('iframe')
iframe.id = 'goldendata_form_xFYow5'
iframe.src = 'https://baoming.gongxue100.com/f/xFYow5?background=white&banner=show&embedded=true&inner_redirect=false'
iframe.width = '100%'
iframe.height = '918'
iframe.frameBorder = '0'
iframe.style.border = 'none'
iframe.onload = () => {
const loader = containerRef.value?.querySelector('.loading-indicator') as HTMLElement | null
if (loader) loader.style.display = 'none'
}
iframe.onerror = () => {
const loader = containerRef.value?.querySelector('.loading-indicator') as HTMLElement | null
if (loader) {
loader.innerHTML = `
<div style="text-align: center; padding: 2rem;">
<div style="width: 48px; height: 48px; background: #fee2e2; border-radius: 50%; display: flex; align-items: center; justify-content: center; margin: 0 auto 1rem;">
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#ef4444" stroke-width="2">
<line x1="18" y1="6" x2="6" y2="18"></line>
<line x1="6" y1="6" x2="18" y2="18"></line>
</svg>
</div>
<p style="color: #6b7280; margin-bottom: 1rem;">表单加载失败</p>
<button onclick="window.location.reload()" style="background: #3b82f6; color: white; border: none; padding: 0.5rem 1rem; border-radius: 0.5rem; cursor: pointer;">重新加载</button>
</div>
`
}
}
containerRef.value.appendChild(iframe)
} else {
document.body.style.overflow = ''
document.body.style.touchAction = ''
if (containerRef.value) {
containerRef.value.innerHTML = ''
}
}
})
onUnmounted(() => {
document.body.style.overflow = ''
document.body.style.touchAction = ''
})
</script>
<template>
<div v-if="isOpen" class="fixed inset-0 z-[9999] flex items-center justify-center p-4">
<div
class="absolute inset-0 bg-black/60 backdrop-blur-sm"
@click="emit('close')"
/>
<div
ref="modalRef"
class="relative bg-white rounded-3xl shadow-2xl w-full max-w-4xl max-h-[90vh] overflow-hidden animate-slide-up flex flex-col"
>
<button
@click="emit('close')"
class="absolute top-4 right-4 p-2 rounded-full hover:bg-gray-100 transition-colors z-10"
>
<X :size="24" class="text-gray-500" />
</button>
<div class="flex-1 overflow-y-auto">
<div class="p-6 md:p-8">
<div class="flex items-center gap-3 mb-6">
<div class="p-2 bg-orange-100 text-orange-600 rounded-xl">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z"/>
<circle cx="12" cy="10" r="3"/>
</svg>
</div>
<div>
<h3 class="font-bold text-xl text-gray-900">报名上课</h3>
<p class="text-xs text-gray-500">填写信息获取专属学习规划</p>
</div>
</div>
<div
ref="containerRef"
class="w-full min-h-[800px]"
/>
</div>
</div>
</div>
</div>
</template>