166 lines
5.3 KiB
JavaScript
166 lines
5.3 KiB
JavaScript
import React, { useEffect, useState } from "react";
|
|
import axios from "axios";
|
|
import ReactDOM from "react-dom";
|
|
|
|
export default function SocialLinks() {
|
|
const [data, setData] = useState(null);
|
|
const [loading, setLoading] = useState(true);
|
|
const [error, setError] = useState(null);
|
|
const [showQRCode, setShowQRCode] = useState(false);
|
|
const [activeLink, setActiveLink] = useState(null);
|
|
const [isMobile, setIsMobile] = useState(false);
|
|
|
|
useEffect(() => {
|
|
const checkMobile = () => {
|
|
setIsMobile(window.innerWidth <= 768);
|
|
};
|
|
|
|
checkMobile();
|
|
window.addEventListener('resize', checkMobile);
|
|
|
|
return () => window.removeEventListener('resize', checkMobile);
|
|
}, []);
|
|
|
|
useEffect(() => {
|
|
if (showQRCode && isMobile) {
|
|
document.body.style.overflow = 'hidden';
|
|
} else {
|
|
document.body.style.overflow = '';
|
|
}
|
|
return () => {
|
|
document.body.style.overflow = '';
|
|
};
|
|
}, [showQRCode, isMobile]);
|
|
|
|
useEffect(() => {
|
|
async function fetchData() {
|
|
try {
|
|
setLoading(true);
|
|
const res = await axios.get("/api/get-component-data", {
|
|
params: { component_name: "SocialLinks" },
|
|
});
|
|
console.log('SocialLinks Data:', res.data);
|
|
setData(res.data.data);
|
|
} catch (err) {
|
|
console.error('SocialLinks Error:', err);
|
|
setError("获取SocialLinks数据失败");
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
}
|
|
fetchData();
|
|
}, []);
|
|
|
|
const handleClose = () => {
|
|
setShowQRCode(false);
|
|
setActiveLink(null);
|
|
};
|
|
|
|
if (loading) return null;
|
|
if (error) return null;
|
|
if (!data || !Array.isArray(data.items) || !data.items.length) return null;
|
|
|
|
return (
|
|
<nav className="nav social !mb-3">
|
|
{data.items.map((elm, i) => {
|
|
console.log('Social Item:', elm);
|
|
return (
|
|
<div key={i} className="relative inline-block">
|
|
<a
|
|
className={`!text-[#cacaca] text-[1rem] transition-all duration-[0.2s] ease-in-out translate-y-0 motion-reduce:transition-none hover:translate-y-[-0.15rem] hover:!text-[#1fc76f] m-[0_.7rem_0_0]`}
|
|
href={isMobile ? undefined : elm.item_link}
|
|
target="_blank"
|
|
rel="noopener noreferrer"
|
|
onClick={(e) => {
|
|
if (isMobile && elm.item_title?.toLowerCase() === 'wechat') {
|
|
e.preventDefault();
|
|
setShowQRCode(!showQRCode);
|
|
setActiveLink(showQRCode ? null : i);
|
|
}
|
|
}}
|
|
onMouseEnter={() => {
|
|
if (!isMobile && elm.item_title?.toLowerCase() === 'wechat') {
|
|
setShowQRCode(true);
|
|
setActiveLink(i);
|
|
}
|
|
}}
|
|
onMouseLeave={() => {
|
|
if (!isMobile && elm.item_title?.toLowerCase() === 'wechat') {
|
|
setShowQRCode(false);
|
|
setActiveLink(null);
|
|
}
|
|
}}
|
|
>
|
|
{elm.item_html_code ? (
|
|
<span
|
|
style={{
|
|
display: 'inline-block',
|
|
width: '1.5rem',
|
|
height: '1.5rem',
|
|
verticalAlign: 'middle',
|
|
lineHeight: 0,
|
|
}}
|
|
dangerouslySetInnerHTML={{ __html: elm.item_html_code }}
|
|
/>
|
|
) : (
|
|
<i
|
|
className={`uil ${elm.item_subtitle||''} before:content-[${elm.item_description||''}] !text-[${elm.item_color||'#cacaca'}] text-[1rem]`}
|
|
/>
|
|
)}
|
|
</a>
|
|
{isMobile && (
|
|
<QrCodeModal
|
|
open={showQRCode && activeLink === i && elm.item_title?.toLowerCase() === 'wechat' && elm.item_image}
|
|
onClose={handleClose}
|
|
image={elm.item_image}
|
|
/>
|
|
)}
|
|
{!isMobile && showQRCode && activeLink === i && elm.item_title?.toLowerCase() === 'wechat' && elm.item_image && (
|
|
<div
|
|
className="absolute bottom-full left-1/2 transform -translate-x-1/2 mb-2 z-[9999]"
|
|
onClick={handleClose}
|
|
>
|
|
<div
|
|
className="bg-white rounded-lg shadow-lg p-4"
|
|
onClick={(e) => e.stopPropagation()}
|
|
>
|
|
<img
|
|
src={elm.item_image}
|
|
alt="微信二维码"
|
|
className="object-cover mx-auto w-32 h-32"
|
|
/>
|
|
<div className="text-center text-sm mt-2 text-gray-600">
|
|
扫码关注公众号
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)}
|
|
</div>
|
|
)})}
|
|
</nav>
|
|
);
|
|
}
|
|
|
|
function QrCodeModal({ open, onClose, image }) {
|
|
if (!open) return null;
|
|
return ReactDOM.createPortal(
|
|
<div
|
|
className="fixed inset-0 flex items-center justify-center bg-black/50 z-[9999]"
|
|
style={{ pointerEvents: 'auto' }}
|
|
onClick={onClose}
|
|
>
|
|
<div
|
|
className="bg-white rounded-lg shadow-lg p-4 mx-4 max-w-[320px] w-full"
|
|
onClick={e => e.stopPropagation()}
|
|
>
|
|
<img
|
|
src={image}
|
|
alt="微信二维码"
|
|
className="object-cover mx-auto w-full max-w-[280px] h-auto"
|
|
/>
|
|
<div className="text-center text-sm mt-2 text-gray-600">扫码关注公众号</div>
|
|
</div>
|
|
</div>,
|
|
document.body
|
|
);
|
|
} |