Files
MoonTVPlus/src/components/HttpWarningDialog.tsx
2025-12-17 22:09:09 +08:00

123 lines
4.2 KiB
TypeScript
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.
'use client';
import { AlertTriangle } from 'lucide-react';
import { useEffect, useState } from 'react';
import { createPortal } from 'react-dom';
import { getAuthInfoFromBrowserCookie } from '@/lib/auth';
interface HttpWarningDialogProps {
onClose: () => void;
}
export default function HttpWarningDialog({ onClose }: HttpWarningDialogProps) {
const [isVisible, setIsVisible] = useState(false);
const [shouldShow, setShouldShow] = useState(false);
useEffect(() => {
// 检查是否应该显示弹窗
const checkShouldShow = () => {
// 只在客户端执行
if (typeof window === 'undefined') return false;
// 检查是否已经选择不再提示
const dontShowAgain = localStorage.getItem('httpWarningDismissed');
if (dontShowAgain === 'true') return false;
// 检查是否是站长
const authInfo = getAuthInfoFromBrowserCookie();
if (!authInfo || authInfo.role !== 'owner') return false;
// 检查是否是 HTTP 环境(非 localhost 和 127.0.0.1
const { protocol, hostname } = window.location;
const isHttp = protocol === 'http:';
const isLocalhost = hostname === 'localhost' || hostname === '127.0.0.1';
// 只在 HTTP 且非本地环境下显示
return isHttp && !isLocalhost;
};
const shouldDisplay = checkShouldShow();
setShouldShow(shouldDisplay);
if (shouldDisplay) {
// 延迟显示动画
setTimeout(() => setIsVisible(true), 100);
}
}, []);
const handleDontShowAgain = () => {
localStorage.setItem('httpWarningDismissed', 'true');
handleClose();
};
const handleClose = () => {
setIsVisible(false);
setTimeout(() => {
onClose();
}, 300);
};
// 如果不需要显示,直接返回 null
if (!shouldShow) return null;
return createPortal(
<div
className={`fixed inset-0 bg-black bg-opacity-50 z-[9999] flex items-center justify-center p-4 transition-opacity duration-300 ${
isVisible ? 'opacity-100' : 'opacity-0'
}`}
onClick={handleClose}
>
<div
className={`bg-white dark:bg-gray-800 rounded-lg shadow-xl max-w-md w-full border border-yellow-200 dark:border-yellow-800 transition-all duration-300 ${
isVisible ? 'scale-100' : 'scale-95'
}`}
onClick={(e) => e.stopPropagation()}
>
<div className="p-6">
{/* 图标和标题 */}
<div className="flex items-start gap-4 mb-4">
<div className="flex-shrink-0">
<AlertTriangle className="w-8 h-8 text-yellow-500" />
</div>
<div className="flex-1">
<h3 className="text-lg font-semibold text-gray-900 dark:text-gray-100 mb-2">
HTTP
</h3>
<div className="text-sm text-gray-600 dark:text-gray-400 space-y-2">
<p>
使 HTTP 访使:
</p>
<ul className="list-disc list-inside space-y-1 ml-2">
<li>AI </li>
<li></li>
<li></li>
</ul>
<p className="mt-3 text-yellow-600 dark:text-yellow-500 font-medium">
HTTPS
</p>
</div>
</div>
</div>
{/* 按钮组 */}
<div className="flex gap-3 mt-6">
<button
onClick={handleDontShowAgain}
className="flex-1 px-4 py-2 text-sm font-medium text-gray-700 dark:text-gray-300 bg-gray-100 dark:bg-gray-700 hover:bg-gray-200 dark:hover:bg-gray-600 rounded-lg transition-colors"
>
</button>
<button
onClick={handleClose}
className="flex-1 px-4 py-2 text-sm font-medium text-white bg-blue-600 hover:bg-blue-700 rounded-lg transition-colors"
>
</button>
</div>
</div>
</div>
</div>,
document.body
);
}