Compare commits
No commits in common. "15473c6f9cd9a1c4bca3e71d6a5ddac8ea9422c9" and "a2cb36866cf1b10e2a81e85534872b423d42ad08" have entirely different histories.
15473c6f9c
...
a2cb36866c
|
|
@ -1,101 +0,0 @@
|
||||||
import React, { useState } from 'react';
|
|
||||||
import { usePopupManager } from './Popup';
|
|
||||||
|
|
||||||
// 单独的“添加飘窗”表单弹窗组件
|
|
||||||
const AddPopupForm = () => {
|
|
||||||
const { addPopup } = usePopupManager();
|
|
||||||
const [isOpen, setIsOpen] = useState(false);
|
|
||||||
const [formData, setFormData] = useState({
|
|
||||||
title: '',
|
|
||||||
description: '',
|
|
||||||
backgroundImage: '',
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
const handleChange = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
|
|
||||||
const { name, value } = e.target;
|
|
||||||
setFormData((prev) => ({ ...prev, [name]: value }));
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleSubmit = (e: React.FormEvent) => {
|
|
||||||
e.preventDefault();
|
|
||||||
if (!formData.title.trim() || !formData.description.trim()) return;
|
|
||||||
addPopup({
|
|
||||||
title: formData.title,
|
|
||||||
description: formData.description,
|
|
||||||
backgroundImage: formData.backgroundImage || undefined,
|
|
||||||
});
|
|
||||||
setIsOpen(false);
|
|
||||||
setFormData({ title: '', description: '', backgroundImage: '' });
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<button
|
|
||||||
onClick={() => setIsOpen(true)}
|
|
||||||
className="px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700 transition"
|
|
||||||
>
|
|
||||||
+ 添加飘窗
|
|
||||||
</button>
|
|
||||||
{isOpen && (
|
|
||||||
<div className="fixed inset-0 bg-black bg-opacity-40 flex items-center justify-center z-50 p-4">
|
|
||||||
<div className="bg-white rounded-lg w-full max-w-md p-6 relative">
|
|
||||||
<button
|
|
||||||
onClick={() => setIsOpen(false)}
|
|
||||||
className="absolute top-3 right-3 text-gray-500 hover:text-gray-800"
|
|
||||||
>
|
|
||||||
×
|
|
||||||
</button>
|
|
||||||
<h2 className="text-xl font-bold mb-4">添加飘窗</h2>
|
|
||||||
<form onSubmit={handleSubmit}>
|
|
||||||
<input
|
|
||||||
name="title"
|
|
||||||
placeholder="标题"
|
|
||||||
value={formData.title}
|
|
||||||
onChange={handleChange}
|
|
||||||
className="w-full mb-3 px-3 py-2 border rounded"
|
|
||||||
required
|
|
||||||
/>
|
|
||||||
<input
|
|
||||||
name="backgroundImage"
|
|
||||||
placeholder="背景图 URL(可选)"
|
|
||||||
type="url"
|
|
||||||
value={formData.backgroundImage}
|
|
||||||
onChange={handleChange}
|
|
||||||
className="w-full mb-3 px-3 py-2 border rounded"
|
|
||||||
/>
|
|
||||||
<textarea
|
|
||||||
name="description"
|
|
||||||
placeholder="详细说明"
|
|
||||||
value={formData.description}
|
|
||||||
onChange={handleChange}
|
|
||||||
rows={3}
|
|
||||||
className="w-full mb-4 px-3 py-2 border rounded"
|
|
||||||
required
|
|
||||||
|
|
||||||
/>
|
|
||||||
|
|
||||||
<div className="flex justify-end gap-2">
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
onClick={() => setIsOpen(false)}
|
|
||||||
className="px-3 py-1.5 border rounded"
|
|
||||||
>
|
|
||||||
取消
|
|
||||||
</button>
|
|
||||||
<button type="submit" className="px-3 py-1.5 bg-blue-600 text-white rounded">
|
|
||||||
创建
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
</>
|
|
||||||
|
|
||||||
);
|
|
||||||
|
|
||||||
};
|
|
||||||
export default AddPopupForm;
|
|
||||||
|
|
@ -1,85 +0,0 @@
|
||||||
// src/components/FloatingPopupManager.tsx
|
|
||||||
import React, { useState, createContext, useContext, type ReactNode } from 'react';
|
|
||||||
|
|
||||||
type PopupItem = {
|
|
||||||
id: string;
|
|
||||||
title: string;
|
|
||||||
description: string;
|
|
||||||
backgroundImage?: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
type PopupContextType = {
|
|
||||||
addPopup: (popup: Omit<PopupItem, 'id'>) => void;
|
|
||||||
};
|
|
||||||
|
|
||||||
const PopupContext = createContext<PopupContextType | undefined>(undefined);
|
|
||||||
|
|
||||||
export const usePopupManager = () => {
|
|
||||||
const context = useContext(PopupContext);
|
|
||||||
if (!context) {
|
|
||||||
throw new Error('usePopupManager must be used within a PopupProvider');
|
|
||||||
}
|
|
||||||
return context;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const FloatingPopupManager: React.FC<{ children: ReactNode }> = ({ children }) => {
|
|
||||||
const [popups, setPopups] = useState<PopupItem[]>([]);
|
|
||||||
|
|
||||||
const addPopup = (popup: Omit<PopupItem, 'id'>) => {
|
|
||||||
const newPopup: PopupItem = {
|
|
||||||
...popup,
|
|
||||||
id: Date.now().toString(),
|
|
||||||
};
|
|
||||||
setPopups((prev) => [...prev, newPopup]);
|
|
||||||
};
|
|
||||||
|
|
||||||
const removePopup = (id: string) => {
|
|
||||||
setPopups((prev) => prev.filter((p) => p.id !== id));
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<PopupContext.Provider value={{ addPopup }}>
|
|
||||||
{children}
|
|
||||||
|
|
||||||
{/* 渲染所有飘窗 */}
|
|
||||||
<div className="fixed bottom-4 right-4 space-y-3 z-[9999] pointer-events-none">
|
|
||||||
{popups.map((popup, index) => (
|
|
||||||
<div
|
|
||||||
key={popup.id}
|
|
||||||
className="pointer-events-auto relative bg-white shadow-xl rounded-lg w-80 overflow-hidden border border-gray-200"
|
|
||||||
style={{
|
|
||||||
transform: `translateY(${index * 12}px)`,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{/* 背景区域 */}
|
|
||||||
{popup.backgroundImage ? (
|
|
||||||
<div className="h-32 w-full overflow-hidden">
|
|
||||||
<img
|
|
||||||
src={popup.backgroundImage}
|
|
||||||
alt=""
|
|
||||||
className="w-full h-full object-cover opacity-90"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
) : (
|
|
||||||
<div className="h-32 bg-gradient-to-r from-blue-500 to-indigo-600"></div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{/* 内容 */}
|
|
||||||
<div className="p-4">
|
|
||||||
<div className="flex justify-between items-start">
|
|
||||||
<h3 className="text-lg font-bold text-gray-800">{popup.title}</h3>
|
|
||||||
<button
|
|
||||||
onClick={() => removePopup(popup.id)}
|
|
||||||
className="text-gray-500 hover:text-gray-800 text-xl font-bold"
|
|
||||||
>
|
|
||||||
×
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<p className="mt-2 text-gray-600 text-sm">{popup.description}</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</PopupContext.Provider>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
@ -52,7 +52,7 @@ const Train = () => {
|
||||||
{ src: '/images/carousel-3.jpg', colSpan: 2, link: 'https://www.baidu.com' },
|
{ src: '/images/carousel-3.jpg', colSpan: 2, link: 'https://www.baidu.com' },
|
||||||
{ src: '/images/carousel-4.jpg', colSpan: 3, link: 'https://www.baidu.com' },
|
{ src: '/images/carousel-4.jpg', colSpan: 3, link: 'https://www.baidu.com' },
|
||||||
{ src: '/logo/logo2.png', colSpan: 1, link: '' },
|
{ src: '/logo/logo2.png', colSpan: 1, link: '' },
|
||||||
{ src: '/images/carousel-5.jpg', colSpan: 2, link: 'https://www.baidu.com' },
|
{ src: '/images/carousel-5.jpg', colSpan: 1, link: 'https://www.baidu.com' },
|
||||||
{ src: '/images/carousel-7.jpg', colSpan: 3, link: 'https://www.baidu.com' },
|
{ src: '/images/carousel-7.jpg', colSpan: 3, link: 'https://www.baidu.com' },
|
||||||
];
|
];
|
||||||
{/* 弹性 默认纵向 大屏横向 */ }
|
{/* 弹性 默认纵向 大屏横向 */ }
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,6 @@ import { Hotline } from "@/components/news/body/FireNews/Hotline";
|
||||||
import { AutoCarouselDemo } from "@/components/AutoCarousel";
|
import { AutoCarouselDemo } from "@/components/AutoCarousel";
|
||||||
import Footer from "@/components/news/footer/footer";
|
import Footer from "@/components/news/footer/footer";
|
||||||
import Train from "@/components/news/body/Train";
|
import Train from "@/components/news/body/Train";
|
||||||
import AddPopupForm from "@/components/news/body/PopupfloatingMangement/AddPopup";
|
|
||||||
|
|
||||||
|
|
||||||
export function meta( ) {
|
export function meta( ) {
|
||||||
return [
|
return [
|
||||||
|
|
@ -46,8 +44,6 @@ export default function Home() {
|
||||||
</div>
|
</div>
|
||||||
<Footer />
|
<Footer />
|
||||||
<Train />
|
<Train />
|
||||||
<AddPopupForm />
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue