Files
sam-sales/ref/components/AssetDetailModal.tsx
2025-12-17 13:25:40 +09:00

174 lines
7.5 KiB
TypeScript

import React, { useEffect, useState } from 'react';
import { SalesAsset, AssetType } from '../types';
import { X, Copy, Check, MessageSquare, Play, Maximize2 } from 'lucide-react';
interface AssetDetailModalProps {
asset: SalesAsset | null;
onClose: () => void;
}
const AssetDetailModal: React.FC<AssetDetailModalProps> = ({ asset, onClose }) => {
const [copied, setCopied] = useState(false);
useEffect(() => {
const handleEsc = (e: KeyboardEvent) => {
if (e.key === 'Escape') onClose();
};
window.addEventListener('keydown', handleEsc);
return () => window.removeEventListener('keydown', handleEsc);
}, [onClose]);
if (!asset) return null;
const handleCopyScript = () => {
if (asset.script) {
navigator.clipboard.writeText(asset.script);
setCopied(true);
setTimeout(() => setCopied(false), 2000);
}
};
return (
<div className="fixed inset-0 z-50 flex items-center justify-center p-4 sm:p-6">
<div
className="absolute inset-0 bg-slate-900/60 backdrop-blur-sm transition-opacity"
onClick={onClose}
/>
<div className="relative w-full max-w-4xl max-h-[90vh] bg-white rounded-2xl shadow-2xl flex flex-col overflow-hidden animate-in fade-in zoom-in-95 duration-200">
{/* Header (Absolute for Video/Image types to float over, Relative for others) */}
<button
onClick={onClose}
className="absolute top-4 right-4 z-20 p-2 bg-black/20 hover:bg-black/40 text-white rounded-full transition-colors backdrop-blur-md"
>
<X size={20} />
</button>
<div className="flex-1 overflow-y-auto custom-scrollbar">
{/* Media Section */}
<div className="relative bg-slate-100 w-full min-h-[300px] md:min-h-[400px] flex items-center justify-center group">
{asset.type === AssetType.VIDEO && (
<iframe
src={`https://player.vimeo.com/video/${asset.src}?autoplay=1&title=0&byline=0&portrait=0`}
className="w-full h-full absolute inset-0"
frameBorder="0"
allow="autoplay; fullscreen; picture-in-picture"
allowFullScreen
title={asset.videoTitle}
></iframe>
)}
{asset.type === AssetType.IMAGE && (
<img
src={asset.src}
alt={asset.title}
className="w-full h-full object-contain bg-slate-900"
/>
)}
{asset.type === AssetType.STAT && (
<div className="w-full h-full flex flex-col items-center justify-center bg-brand-600 text-white p-12">
<div className="text-8xl font-extrabold tracking-tighter mb-4">{asset.statValue}</div>
<div className="text-2xl text-brand-100 font-medium">{asset.statLabel}</div>
</div>
)}
{asset.type === AssetType.TEXT && (
<div className="w-full h-full flex flex-col items-center justify-center bg-gradient-to-br from-slate-800 to-slate-900 text-white p-12 text-center">
<MessageSquare size={64} className="mb-6 opacity-50" />
<h2 className="text-3xl md:text-4xl font-bold max-w-2xl leading-tight">{asset.title}</h2>
<div className="mt-4 flex gap-2">
{asset.tags.map(tag => (
<span key={tag} className="text-xs font-semibold bg-white/10 px-3 py-1 rounded-full">{tag}</span>
))}
</div>
</div>
)}
</div>
{/* Content Section */}
<div className="p-6 md:p-8">
<div className="flex flex-col md:flex-row gap-8">
{/* Left: Info */}
<div className="flex-1">
<h2 className="text-2xl font-bold text-slate-900 mb-2 flex items-center gap-2">
{asset.title}
{asset.type !== AssetType.TEXT && (
<div className="flex gap-2">
{asset.tags.map(tag => (
<span key={tag} className="text-[10px] uppercase font-bold text-brand-600 bg-brand-50 px-2 py-1 rounded-md border border-brand-100">
{tag}
</span>
))}
</div>
)}
</h2>
<p className="text-slate-600 text-lg leading-relaxed mb-6">
{asset.content || asset.description}
</p>
{/* Additional Metadata if needed */}
<div className="grid grid-cols-2 gap-4 text-sm text-slate-500 bg-slate-50 p-4 rounded-xl">
<div>
<span className="block font-semibold text-slate-900 mb-1">Asset Type</span>
{asset.type}
</div>
<div>
<span className="block font-semibold text-slate-900 mb-1">Last Updated</span>
2024.05.20
</div>
</div>
</div>
{/* Right: Sales Script (The "Key" feature) */}
<div className="w-full md:w-96 bg-brand-50 rounded-xl p-6 border border-brand-100 flex flex-col">
<div className="flex items-center justify-between mb-4">
<h3 className="font-bold text-brand-900 flex items-center gap-2">
<MessageSquare size={18} />
Sales Pitch Script
</h3>
<button
onClick={handleCopyScript}
className="text-xs flex items-center gap-1 text-brand-600 hover:text-brand-800 font-medium transition-colors"
>
{copied ? <Check size={14} /> : <Copy size={14} />}
{copied ? 'Copied!' : 'Copy'}
</button>
</div>
<div className="flex-1 bg-white p-4 rounded-lg text-slate-700 text-sm leading-relaxed shadow-sm border border-brand-100 italic relative">
<span className="absolute top-2 left-2 text-4xl text-brand-100 font-serif leading-none"></span>
<div className="relative z-10 pt-2 pb-2 px-1">
{asset.script ? asset.script : "No specific script available for this asset. Use the description as a guide."}
</div>
<span className="absolute bottom-[-10px] right-4 text-4xl text-brand-100 font-serif leading-none rotate-180"></span>
</div>
<div className="mt-4 pt-4 border-t border-brand-200">
<p className="text-xs text-brand-600 text-center font-medium">
Tip: 고객의 .
</p>
</div>
</div>
</div>
</div>
</div>
{/* Footer Actions */}
<div className="p-4 border-t border-slate-100 bg-slate-50 flex justify-end gap-3">
<button
onClick={onClose}
className="px-5 py-2.5 rounded-xl border border-slate-300 text-slate-700 font-medium hover:bg-slate-100 transition-colors"
>
Close
</button>
<button className="px-5 py-2.5 rounded-xl bg-slate-900 text-white font-medium hover:bg-slate-800 transition-colors shadow-lg flex items-center gap-2">
Share Asset Link <Maximize2 size={16} />
</button>
</div>
</div>
</div>
);
};
export default AssetDetailModal;