refactor: clean up dependencies and enhance component functionality
- Removed unused dependencies related to @dnd-kit from pnpm-lock.yaml. - Updated Vite configuration to set the base path. - Added input styles to the main CSS file. - Enhanced BackgroundImage component to include an overflowHidden prop for better layout control. - Deleted the DraggableItem component as it was no longer needed. - Updated routing to include new Publicity and Content pages, and modified navigation in Menu and NotFound components.
This commit is contained in:
1 parent
29029bb608
commit
2d66abc610
51 files changed
+469
-142
No files matched your search
@@ -0,0 +1,207 @@
|
||||
import { BackgroundImage, Image } from "@/components";
|
||||
import { getStaticImage } from "@/utils";
|
||||
import clsx from "clsx";
|
||||
import { useState } from "react";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
|
||||
/**
|
||||
* tab列表
|
||||
* 1. 01工作室介绍
|
||||
* 2. 02带教活动
|
||||
* 3. 03带教心得
|
||||
* 4. 04成果展示
|
||||
*/
|
||||
const tabList = [
|
||||
{
|
||||
id: 1,
|
||||
name: "01工作室介绍",
|
||||
image: getStaticImage("content/工作室介绍未选中.png"),
|
||||
selectedImage: getStaticImage("content/工作室介绍选中.png"),
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: "02带教活动",
|
||||
image: getStaticImage("content/带教活动未选中.png"),
|
||||
selectedImage: getStaticImage("content/带教活动选中.png"),
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: "03带教心得",
|
||||
image: getStaticImage("content/带教心得未选中.png"),
|
||||
selectedImage: getStaticImage("content/带教心得选中.png"),
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
name: "04成果展示",
|
||||
image: getStaticImage("content/成果展示未选中.png"),
|
||||
selectedImage: getStaticImage("content/成果展示选中.png"),
|
||||
},
|
||||
];
|
||||
|
||||
/**
|
||||
* 侧边栏
|
||||
* 论与技能转向培训
|
||||
* 教学实践与反思
|
||||
* 项目与课题研究
|
||||
* 经验传承与资源共享
|
||||
* 交流与展示活动
|
||||
*/
|
||||
const sideBarList = [
|
||||
{
|
||||
name: "理论与技能转向培训",
|
||||
image: getStaticImage("content/理论与技能专项培训-未选中.png"),
|
||||
selectedImage: getStaticImage("content/理论与技能专项培训-选中.png"),
|
||||
},
|
||||
{
|
||||
name: "教学实践与反思",
|
||||
image: getStaticImage("content/教学实践与反思-未选中.png"),
|
||||
selectedImage: getStaticImage("content/教学实践与反思-选中.png"),
|
||||
},
|
||||
{
|
||||
name: "项目与课题研究",
|
||||
image: getStaticImage("content/项目与课题研究-未选中.png"),
|
||||
selectedImage: getStaticImage("content/项目与课题研究-选中.png"),
|
||||
},
|
||||
{
|
||||
name: "经验传承与资源共享",
|
||||
image: getStaticImage("content/经验传承与资源共享-未选中.png"),
|
||||
selectedImage: getStaticImage("content/经验传承与资源共享-选中.png"),
|
||||
},
|
||||
{
|
||||
name: "交流与展示活动",
|
||||
image: getStaticImage("content/交流与展示活动-未选中.png"),
|
||||
selectedImage: getStaticImage("content/交流与展示活动-选中.png"),
|
||||
},
|
||||
];
|
||||
|
||||
export const Tab = ({
|
||||
changeTab,
|
||||
className,
|
||||
}: {
|
||||
changeTab?: (id: number) => void;
|
||||
className?: string;
|
||||
}) => {
|
||||
const [selectedTabId, setSelectedTabId] = useState(1);
|
||||
return (
|
||||
<>
|
||||
{/* tab */}
|
||||
<div className={clsx("w-full flex justify-end", className)}>
|
||||
{tabList.map((item) => (
|
||||
<Image
|
||||
key={item.id}
|
||||
src={selectedTabId === item.id ? item.selectedImage : item.image}
|
||||
alt={item.name}
|
||||
button
|
||||
onClick={() => {
|
||||
setSelectedTabId(item.id);
|
||||
changeTab?.(item.id);
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<TabContent
|
||||
className="h-[calc(100%-200px)]"
|
||||
selectedTabId={selectedTabId}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
const TabContent = ({
|
||||
className,
|
||||
selectedTabId,
|
||||
}: {
|
||||
className?: string;
|
||||
selectedTabId: number;
|
||||
}) => {
|
||||
const [selectedSideBarId, setSelectedSideBarId] = useState(0);
|
||||
return (
|
||||
<>
|
||||
<div className={clsx("overflow-y-auto custom-scrollbar", className)}>
|
||||
{/* 通过tab切换内容 */}
|
||||
{selectedTabId === 1 && (
|
||||
<Image
|
||||
height={942}
|
||||
src={getStaticImage("content/图文.png")}
|
||||
alt="工作室介绍"
|
||||
/>
|
||||
)}
|
||||
{selectedTabId === 2 && (
|
||||
<div className="flex gap-10 pt-8">
|
||||
{/* 侧边栏 */}
|
||||
<div className="flex flex-col gap-10">
|
||||
{sideBarList.map((item, index) => (
|
||||
<Image
|
||||
key={item.name}
|
||||
src={
|
||||
selectedSideBarId === index
|
||||
? item.selectedImage
|
||||
: item.image
|
||||
}
|
||||
alt={item.name}
|
||||
button
|
||||
onClick={() => {
|
||||
setSelectedSideBarId(index);
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
<BackgroundImage
|
||||
src={getStaticImage("content/视频区域框.png")}
|
||||
width={1354}
|
||||
height={766}
|
||||
>
|
||||
<div className="h-full flex justify-center items-center">
|
||||
<span className="text-[#82B2D6] text-4xl font-bold">
|
||||
图文、视频展示理论与技能专项培训内容
|
||||
</span>
|
||||
</div>
|
||||
</BackgroundImage>
|
||||
</div>
|
||||
)}
|
||||
{selectedTabId === 3 && (
|
||||
<div className="text-center text-[#82B2D6] text-4xl font-bold">
|
||||
暂无内容
|
||||
</div>
|
||||
)}
|
||||
{selectedTabId === 4 && (
|
||||
<div className="text-center text-[#82B2D6] text-4xl font-bold">
|
||||
暂无内容
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default function PublicityPage() {
|
||||
const navigate = useNavigate();
|
||||
|
||||
const changeTab = (id: number) => {
|
||||
console.log(id);
|
||||
};
|
||||
|
||||
return (
|
||||
<BackgroundImage
|
||||
src={getStaticImage("content/内页底图02.png")}
|
||||
className="h-full w-full relative"
|
||||
backgroundSize="cover"
|
||||
backgroundPosition="center"
|
||||
>
|
||||
<div className=" w-full h-full pt-25">
|
||||
<Image
|
||||
src={getStaticImage("components/按钮-返回.png")}
|
||||
alt="返回"
|
||||
button
|
||||
className="absolute top-0 right-0"
|
||||
onClick={() => {
|
||||
navigate("/publicity");
|
||||
}}
|
||||
/>
|
||||
|
||||
<Tab changeTab={changeTab} />
|
||||
</div>
|
||||
</BackgroundImage>
|
||||
);
|
||||
}
|
||||
+2
-1
@@ -47,6 +47,7 @@ export default function Home() {
|
||||
|
||||
const handleSelectTeacher = (teacherId: number) => {
|
||||
setSelectedTeacherId(teacherId);
|
||||
navigate("/Publicity");
|
||||
};
|
||||
|
||||
const handleStartExperiment = () => {
|
||||
@@ -66,7 +67,7 @@ export default function Home() {
|
||||
alt="返回"
|
||||
button
|
||||
className="absolute top-0 right-0"
|
||||
onClick={handleStartExperiment}
|
||||
onClick={() => navigate("/")}
|
||||
/>
|
||||
|
||||
<Image
|
||||
|
||||
+30
-28
@@ -1,35 +1,37 @@
|
||||
import { Link } from 'react-router-dom';
|
||||
import { Home, ArrowLeft } from 'lucide-react';
|
||||
import { Link } from "react-router-dom";
|
||||
import { Home, ArrowLeft } from "lucide-react";
|
||||
|
||||
export default function NotFound() {
|
||||
return (
|
||||
<div className="max-w-2xl mx-auto text-center">
|
||||
<div className="bg-white rounded-xl shadow-lg p-12">
|
||||
<div className="mb-8">
|
||||
<h1 className="text-9xl font-bold text-indigo-600 mb-4">404</h1>
|
||||
<h2 className="text-3xl font-bold text-gray-800 mb-2">
|
||||
页面未找到
|
||||
</h2>
|
||||
<p className="text-gray-600 text-lg">
|
||||
抱歉,您访问的页面不存在或已被移除。
|
||||
</p>
|
||||
</div>
|
||||
<div className="h-full w-full relative bg-white">
|
||||
<div className="max-w-2xl mx-auto text-center">
|
||||
<div className="bg-white rounded-xl shadow-lg p-12">
|
||||
<div className="mb-8">
|
||||
<h1 className="text-9xl font-bold text-indigo-600 mb-4">404</h1>
|
||||
<h2 className="text-3xl font-bold text-gray-800 mb-2">
|
||||
页面未找到
|
||||
</h2>
|
||||
<p className="text-gray-600 text-lg">
|
||||
抱歉,您访问的页面不存在或已被移除。
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col sm:flex-row gap-4 justify-center">
|
||||
<Link
|
||||
to="/"
|
||||
className="inline-flex items-center justify-center gap-2 px-6 py-3 bg-indigo-600 text-white rounded-lg hover:bg-indigo-700 transition-colors font-semibold"
|
||||
>
|
||||
<Home size={20} />
|
||||
返回首页
|
||||
</Link>
|
||||
<button
|
||||
onClick={() => window.history.back()}
|
||||
className="inline-flex items-center justify-center gap-2 px-6 py-3 border-2 border-indigo-600 text-indigo-600 rounded-lg hover:bg-indigo-50 transition-colors font-semibold"
|
||||
>
|
||||
<ArrowLeft size={20} />
|
||||
返回上一页
|
||||
</button>
|
||||
<div className="flex flex-col sm:flex-row gap-4 justify-center">
|
||||
<Link
|
||||
to="/"
|
||||
className="inline-flex items-center justify-center gap-2 px-6 py-3 bg-indigo-600 text-white rounded-lg hover:bg-indigo-700 transition-colors font-semibold"
|
||||
>
|
||||
<Home size={20} />
|
||||
返回首页
|
||||
</Link>
|
||||
<button
|
||||
onClick={() => window.history.back()}
|
||||
className="inline-flex items-center justify-center gap-2 px-6 py-3 border-2 border-indigo-600 text-indigo-600 rounded-lg hover:bg-indigo-50 transition-colors font-semibold"
|
||||
>
|
||||
<ArrowLeft size={20} />
|
||||
返回上一页
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,184 @@
|
||||
import { BackgroundImage, Image } from "@/components";
|
||||
import { getStaticImage } from "@/utils";
|
||||
import { useState } from "react";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
|
||||
// 解答弹窗组件
|
||||
interface DialogBoxProps {
|
||||
isOpen: boolean;
|
||||
onClose: () => void;
|
||||
}
|
||||
|
||||
/**
|
||||
* 功能列表
|
||||
* 1. 01工作室介绍
|
||||
* 2. 02带教活动
|
||||
* 3. 03带教心得
|
||||
* 4. 04成果展示
|
||||
*/
|
||||
const functionList = [
|
||||
{
|
||||
id: 1,
|
||||
name: "01工作室介绍",
|
||||
image: getStaticImage("publicity/01未选中.png"),
|
||||
selectedImage: getStaticImage("publicity/01工作室介绍选中.png"),
|
||||
position: "absolute bottom-25 left-[35%]",
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: "02带教活动",
|
||||
image: getStaticImage("publicity/02未选中.png"),
|
||||
selectedImage: getStaticImage("publicity/02带教活动选中.png"),
|
||||
position: "absolute bottom-65 left-[50%]",
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: "03带教心得",
|
||||
image: getStaticImage("publicity/03未选中.png"),
|
||||
selectedImage: getStaticImage("publicity/03带教心得选中.png"),
|
||||
position: "absolute bottom-100 left-[65%]",
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
name: "04成果展示",
|
||||
image: getStaticImage("publicity/04未选中.png"),
|
||||
selectedImage: getStaticImage("publicity/04成果展示选中.png"),
|
||||
position: "absolute bottom-130 left-[80%]",
|
||||
},
|
||||
];
|
||||
|
||||
function DialogBox({ isOpen, onClose }: DialogBoxProps) {
|
||||
if (!isOpen) return null;
|
||||
|
||||
return (
|
||||
<div className="fixed inset-0 z-50 flex items-start justify-center pt-10 pointer-events-none">
|
||||
{/* 遮罩层 */}
|
||||
{/* <div className="absolute inset-0 bg-black bg-opacity-50" /> */}
|
||||
|
||||
{/* 解答框 */}
|
||||
<BackgroundImage
|
||||
src={getStaticImage("publicity/功能-输入.png")}
|
||||
alt="解答框"
|
||||
width={877}
|
||||
height={218}
|
||||
overflowHidden={false}
|
||||
className="relative z-10 pointer-events-auto"
|
||||
>
|
||||
<div className="relative w-full h-full pt-20 pl-8">
|
||||
{/* 数字人头像 */}
|
||||
<Image
|
||||
src={getStaticImage("publicity/数字人-头像框.png")}
|
||||
alt="数字人头像"
|
||||
className="absolute -left-10 -top-10 z-10"
|
||||
/>
|
||||
{/* 关闭按钮 */}
|
||||
<Image
|
||||
src={getStaticImage("publicity/按钮-关闭.png")}
|
||||
alt="关闭按钮"
|
||||
className="absolute -right-5 -top-5"
|
||||
button
|
||||
onClick={onClose}
|
||||
/>
|
||||
{/* 输入框 */}
|
||||
<BackgroundImage
|
||||
src={getStaticImage("publicity/输入框.png")}
|
||||
alt="输入框"
|
||||
width={811}
|
||||
height={100}
|
||||
>
|
||||
<textarea
|
||||
placeholder="有什么我能帮你的吗直接输入即可.……"
|
||||
className="w-full h-full pl-15 pr-35 pt-4"
|
||||
></textarea>
|
||||
|
||||
{/* icon语音输入和发送按钮 */}
|
||||
<Image
|
||||
src={getStaticImage("publicity/功能-语音输入.png")}
|
||||
className="absolute right-20 bottom-6"
|
||||
button
|
||||
/>
|
||||
<Image
|
||||
src={getStaticImage("publicity/功能-发送.png")}
|
||||
className="absolute right-4 bottom-6"
|
||||
button
|
||||
/>
|
||||
</BackgroundImage>
|
||||
</div>
|
||||
</BackgroundImage>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default function PublicityPage() {
|
||||
const navigate = useNavigate();
|
||||
const [isDialogOpen, setIsDialogOpen] = useState(false);
|
||||
const [selectedFunctionId, setSelectedFunctionId] = useState(0);
|
||||
|
||||
const handleOpenDialog = () => {
|
||||
setIsDialogOpen(true);
|
||||
};
|
||||
|
||||
const handleCloseDialog = () => {
|
||||
setIsDialogOpen(false);
|
||||
};
|
||||
|
||||
return (
|
||||
<BackgroundImage
|
||||
src={getStaticImage("publicity/内页底图01.png")}
|
||||
className="h-full w-full relative"
|
||||
backgroundSize="cover"
|
||||
backgroundPosition="center"
|
||||
>
|
||||
{/* 功能列表 */}
|
||||
{functionList.map((item) => (
|
||||
<Image
|
||||
key={item.id}
|
||||
src={selectedFunctionId === item.id ? item.selectedImage : item.image}
|
||||
alt={item.name}
|
||||
className={`${item.position} transition-all duration-300`}
|
||||
button
|
||||
onClick={() => {
|
||||
setSelectedFunctionId(item.id);
|
||||
navigate(`/content/${item.id}`);
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
|
||||
<Image
|
||||
src={getStaticImage("components/按钮-返回.png")}
|
||||
alt="返回"
|
||||
button
|
||||
className="absolute top-0 right-0"
|
||||
onClick={() => {
|
||||
navigate("/menu");
|
||||
}}
|
||||
/>
|
||||
|
||||
{/* 标题 */}
|
||||
<Image
|
||||
src={getStaticImage("publicity/名师工作室-标题.png")}
|
||||
alt="标题"
|
||||
className="absolute left-0 top-30"
|
||||
/>
|
||||
|
||||
{/* 数字人 */}
|
||||
<Image
|
||||
src={getStaticImage("publicity/曹君名师数字人分身.png")}
|
||||
alt="数字人"
|
||||
className="absolute left-0 -bottom-20"
|
||||
/>
|
||||
|
||||
{/* 提示 */}
|
||||
<Image
|
||||
src={getStaticImage("publicity/点击提示.png")}
|
||||
alt="提示"
|
||||
className="absolute left-0 -bottom-10"
|
||||
button
|
||||
onClick={handleOpenDialog}
|
||||
/>
|
||||
|
||||
{/* 解答弹窗 */}
|
||||
<DialogBox isOpen={isDialogOpen} onClose={handleCloseDialog} />
|
||||
</BackgroundImage>
|
||||
);
|
||||
}
|
||||
Reference in new issue
Block a user