174 lines
6.7 KiB
TypeScript
174 lines
6.7 KiB
TypeScript
import React, { useState } from 'react';
|
|
import { Button } from '../ui/button';
|
|
import { Input } from '../ui/input';
|
|
import { Stamp, Eye } from 'lucide-react';
|
|
import { useToast } from '../../context/ToastContext';
|
|
|
|
interface WatermarkSettingsModalProps {
|
|
onClose: () => void;
|
|
onSave: () => void;
|
|
}
|
|
|
|
export const WatermarkSettingsModal: React.FC<WatermarkSettingsModalProps> = ({
|
|
onClose,
|
|
onSave,
|
|
}) => {
|
|
const { addToast: _addToast } = useToast();
|
|
const [enabled, setEnabled] = useState(true);
|
|
const [text, setText] = useState('PREVIEW - DO NOT USE');
|
|
const [opacity, setOpacity] = useState(30);
|
|
const [position, setPosition] = useState(4); // 0-8 grid
|
|
|
|
const positions = [
|
|
'Top Left',
|
|
'Top Center',
|
|
'Top Right',
|
|
'Mid Left',
|
|
'Center',
|
|
'Mid Right',
|
|
'Bot Left',
|
|
'Bot Center',
|
|
'Bot Right',
|
|
];
|
|
|
|
return (
|
|
<div className="fixed inset-0 z-[100] flex items-center justify-center p-4">
|
|
<div
|
|
className="absolute inset-0 bg-kodo-void/90 backdrop-blur-sm"
|
|
onClick={onClose}
|
|
></div>
|
|
<div className="relative w-full max-w-2xl bg-kodo-graphite border border-kodo-steel rounded-xl shadow-2xl overflow-hidden animate-scaleIn flex flex-col md:flex-row">
|
|
{/* Left: Controls */}
|
|
<div className="w-full md:w-1/2 p-6 border-r border-kodo-steel bg-kodo-ink">
|
|
<div className="flex justify-between items-center mb-6">
|
|
<h3 className="font-bold text-white flex items-center gap-2">
|
|
<Stamp className="w-4 h-4 text-kodo-magenta" /> Watermark
|
|
</h3>
|
|
</div>
|
|
|
|
<div className="space-y-6">
|
|
<label className="flex items-center justify-between cursor-pointer">
|
|
<span className="text-sm font-medium text-white">
|
|
Enable Watermarking
|
|
</span>
|
|
<div
|
|
onClick={() => setEnabled(!enabled)}
|
|
className={`w-10 h-5 rounded-full relative transition-colors ${enabled ? 'bg-kodo-magenta' : 'bg-gray-600'}`}
|
|
>
|
|
<div
|
|
className={`absolute top-1 w-3 h-3 bg-white rounded-full transition-all ${enabled ? 'left-6' : 'left-1'}`}
|
|
></div>
|
|
</div>
|
|
</label>
|
|
|
|
<div className={!enabled ? 'opacity-50 pointer-events-none' : ''}>
|
|
<Input
|
|
label="Watermark Text"
|
|
value={text}
|
|
onChange={(e) => setText(e.target.value)}
|
|
/>
|
|
|
|
<div className="mt-4">
|
|
<label className="block text-xs font-bold text-gray-400 uppercase mb-2">
|
|
Position
|
|
</label>
|
|
<div className="grid grid-cols-3 gap-2">
|
|
{positions.map((_pos, i) => (
|
|
<button
|
|
key={i}
|
|
onClick={() => setPosition(i)}
|
|
className={`h-10 rounded border text-[10px] uppercase font-bold transition-all ${position === i ? 'bg-kodo-magenta border-kodo-magenta text-white' : 'bg-kodo-void border-kodo-steel text-gray-500 hover:border-gray-400'}`}
|
|
>
|
|
{/* Icon representation usually better, but text works for demo */}
|
|
<div
|
|
className={`w-2 h-2 rounded-full mx-auto ${position === i ? 'bg-white' : 'bg-gray-600'}`}
|
|
></div>
|
|
</button>
|
|
))}
|
|
</div>
|
|
</div>
|
|
|
|
<div className="mt-4">
|
|
<div className="flex justify-between text-xs text-gray-400 mb-2">
|
|
<span className="font-bold uppercase">Opacity</span>
|
|
<span>{opacity}%</span>
|
|
</div>
|
|
<input
|
|
type="range"
|
|
min="0"
|
|
max="100"
|
|
value={opacity}
|
|
onChange={(e) => setOpacity(Number(e.target.value))}
|
|
className="w-full h-1 bg-kodo-steel rounded-lg appearance-none cursor-pointer [&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:w-4 [&::-webkit-slider-thumb]:h-4 [&::-webkit-slider-thumb]:bg-kodo-magenta [&::-webkit-slider-thumb]:rounded-full"
|
|
/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="mt-8 pt-4 border-t border-kodo-steel flex gap-3">
|
|
<Button variant="ghost" onClick={onClose} className="flex-1">
|
|
Cancel
|
|
</Button>
|
|
<Button
|
|
variant="primary"
|
|
onClick={() => {
|
|
onSave();
|
|
onClose();
|
|
}}
|
|
className="flex-1"
|
|
>
|
|
Save Settings
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Right: Preview */}
|
|
<div className="w-full md:w-1/2 bg-black relative flex items-center justify-center overflow-hidden">
|
|
<div className="absolute top-4 right-4 z-10 bg-black/50 px-2 py-1 rounded text-xs text-white font-mono flex items-center gap-2">
|
|
<Eye className="w-3 h-3" /> PREVIEW
|
|
</div>
|
|
|
|
{/* Dummy Content */}
|
|
<div className="w-3/4 aspect-square bg-gray-800 rounded-lg relative overflow-hidden shadow-2xl">
|
|
<img
|
|
src="https://picsum.photos/id/237/600/600"
|
|
className="w-full h-full object-cover opacity-80"
|
|
/>
|
|
|
|
{/* Watermark Overlay */}
|
|
{enabled && (
|
|
<div
|
|
className={`absolute inset-0 flex p-4 ${
|
|
position === 0
|
|
? 'items-start justify-start'
|
|
: position === 1
|
|
? 'items-start justify-center'
|
|
: position === 2
|
|
? 'items-start justify-end'
|
|
: position === 3
|
|
? 'items-center justify-start'
|
|
: position === 4
|
|
? 'items-center justify-center'
|
|
: position === 5
|
|
? 'items-center justify-end'
|
|
: position === 6
|
|
? 'items-end justify-start'
|
|
: position === 7
|
|
? 'items-end justify-center'
|
|
: 'items-end justify-end'
|
|
}`}
|
|
>
|
|
<span
|
|
className="text-white font-bold text-xl uppercase whitespace-nowrap transform -rotate-12 border-4 border-white/50 px-4 py-1"
|
|
style={{ opacity: opacity / 100 }}
|
|
>
|
|
{text}
|
|
</span>
|
|
</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|