jingrow/components/contact/SocialLinks.jsx

165 lines
5.2 KiB
JavaScript

"use client";
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" },
});
setData(res.data.data);
} catch (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) => {
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
);
}