feat:init

This commit is contained in:
zhongyidian committed 2025-12-29 19:19:10 +08:00
1 parent 53d0eeac6b
commit ae0c050010
494 files changed
+17701 -2318

No files matched your search

@@ -0,0 +1,129 @@
import { DragFill, type DragFillResult } from "@/components";
import { cn } from "@/lib/utils";
import type { DragQuizPanelProps } from "./types";
/** 拖拽题面板:使用 DragFill 组件 */
const DragQuizPanel = ({
visible,
zIndex = 10000,
title,
questionPrefix,
questionSuffix,
options,
blanks,
value,
error,
onChange,
}: DragQuizPanelProps) => {
if (!visible) return null;
return (
<div
className="fixed inset-0 flex items-center justify-center bg-black/40"
style={{ zIndex }}
>
<div className="relative w-[1728px] h-[972px] flex flex-col items-center pt-12 pb-14 gap-10">
{/* 题干卡片 */}
<div className="w-[1600px] min-h-[220px] rounded-[32px] bg-black/90 px-20 py-12 shadow-[0_20px_60px_rgba(240,190,117,0.8)] border-4 border-[#d4c5a9]">
<div className="text-[32px] leading-relaxed text-white">
{title && <div className="mb-4">{title}</div>}
<div>
{questionPrefix && <span>{questionPrefix}</span>}
{blanks.map((blank, index) => {
const filledResult = value.find((r) => r.blankId === blank.id);
const filledValue = filledResult?.optionValue || null;
return (
<span key={blank.id}>
<span
data-blank-id={blank.id}
className={cn(
"inline-flex items-center justify-center min-w-[140px] h-[56px] px-6 mx-3",
"rounded-xl border-2 transition-all duration-300 shadow-[0_4px_16px_rgba(0,0,0,0.2)]",
filledValue
? "border-[#f0be75] bg-gradient-to-br from-[#3a3020] to-[#2a2520] backdrop-blur-sm"
: "border-[#d4c5a9]/60 bg-white/10 backdrop-blur-sm hover:border-[#d4c5a9]"
)}
>
{filledValue ? (
<span className="text-[#f0be75] font-semibold flex items-center gap-3">
<span className="text-[28px]">{filledValue}</span>
<button
type="button"
className="w-7 h-7 flex items-center justify-center rounded-full bg-[#8b4513]/80 hover:bg-[#a0522d] text-white text-sm transition-all hover:scale-110 shadow-lg"
onClick={(e) => {
e.stopPropagation();
onChange(
value.filter((r) => r.blankId !== blank.id)
);
}}
>
×
</button>
</span>
) : (
<span className="text-white/40 text-[24px] font-light">
____
</span>
)}
</span>
{index < blanks.length - 1 && (
<span className="text-white/80 mx-1">、</span>
)}
</span>
);
})}
{questionSuffix && <span>{questionSuffix}</span>}
</div>
</div>
</div>
{/* 使用 DragFill 组件 */}
<div className="w-[1500px] mt-16">
<DragFill
options={options}
blanks={blanks}
value={value}
onChange={onChange}
hideLabels
showSubmitButton={false}
layout="vertical"
className="w-full"
renderOption={(option, isUsed) => (
<div
className={cn(
"relative h-[110px] px-10 flex items-center justify-center",
"rounded-[32px] transition-all duration-300",
"text-[32px] font-bold border-3 shadow-[0_8px_32px_rgba(0,0,0,0.3)]",
isUsed
? "border-[#8b7355] bg-[#3d3329] text-[#a89378] cursor-not-allowed opacity-50"
: "border-[#d4c5a9] bg-gradient-to-br from-[#4a3f35] to-[#3a2f25] text-[#f5e6d3] cursor-move hover:border-[#f0be75] hover:shadow-[0_12px_40px_rgba(240,190,117,0.7)] hover:scale-[1.02]"
)}
>
{!isUsed && (
<div className="absolute inset-0 rounded-[32px] bg-gradient-to-br from-[#d4c5a9]/20 to-transparent pointer-events-none" />
)}
<span className="relative z-10 drop-shadow-[0_2px_4px_rgba(0,0,0,0.3)]">
{option.label}
</span>
</div>
)}
renderBlank={(_blank) => {
// 返回一个隐藏元素,实际的空白区域在题干中
// 但需要通过 data-blank-id 让 DragFill 能找到它
return <div className="hidden" />;
}}
/>
</div>
{error && (
<div className="mt-6 text-center text-[26px] text-[#ff4d4f]">
{error}
</div>
)}
</div>
</div>
);
};
export default DragQuizPanel;