veza/apps/web/src/components/modals/CreatorModal.tsx
senke fa56dfa77e refactor: Phase 3a — Global color class migration to SUMI semantics
- Replace all kodo-* color classes across ~100 TSX files:
  kodo-void → background, kodo-ink → card, kodo-graphite → muted,
  kodo-steel → muted-foreground, kodo-cyan → primary, kodo-magenta → destructive,
  kodo-lime → success, kodo-red → destructive, kodo-gold → warning
- Replace cyan-500, magenta-500, lime-500 default Tailwind colors with
  semantic equivalents (primary, destructive, success)
- Fix WaveformVisualizer hardcoded hex colors to SUMI values
- Delete global-effects.css (conflicting, redundant with index.css)

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-12 01:51:49 +01:00

172 lines
7 KiB
TypeScript

import React, { useState } from 'react';
import { Card } from '../ui/card';
import { Button } from '../ui/button';
import { Input, FileUpload } from '../ui/input';
import {
X,
Music,
Package,
BookOpen,
CheckCircle,
Tag,
Lock,
DollarSign,
} from 'lucide-react';
interface CreatorModalProps {
isOpen: boolean;
onClose: () => void;
}
export const CreatorModal: React.FC<CreatorModalProps> = ({
isOpen,
onClose,
}) => {
const [activeTab, setActiveTab] = useState<'track' | 'product' | 'course'>(
'track',
);
const [step, setStep] = useState(1);
if (!isOpen) return null;
return (
<div className="fixed inset-0 z-[100] flex items-center justify-center p-4">
<div
className="absolute inset-0 bg-background/90 backdrop-blur-sm"
onClick={onClose}
></div>
<div className="relative w-full max-w-4xl bg-muted border border-border rounded-2xl shadow-2xl animate-scaleIn overflow-hidden flex flex-col max-h-layout-modal-lg">
{/* Header */}
<div className="flex justify-between items-center p-8 border-b border-border bg-card">
<div className="flex items-center gap-4">
<h2 className="text-2xl font-heading font-bold text-white">
CREATOR STUDIO
</h2>
<div className="flex bg-muted rounded-lg p-1">
<button
onClick={() => setActiveTab('track')}
className={`px-4 py-1.5 rounded text-sm font-bold transition-all flex items-center gap-2 ${activeTab === 'track' ? 'bg-primary text-black' : 'text-muted-foreground hover:text-white'}`}
>
<Music className="w-4 h-4" /> Track
</button>
<button
onClick={() => setActiveTab('product')}
className={`px-4 py-1.5 rounded text-sm font-bold transition-all flex items-center gap-2 ${activeTab === 'product' ? 'bg-destructive text-white' : 'text-muted-foreground hover:text-white'}`}
>
<Package className="w-4 h-4" /> Product
</button>
<button
onClick={() => setActiveTab('course')}
className={`px-4 py-1.5 rounded text-sm font-bold transition-all flex items-center gap-2 ${activeTab === 'course' ? 'bg-warning text-black' : 'text-muted-foreground hover:text-white'}`}
>
<BookOpen className="w-4 h-4" /> Course
</button>
</div>
</div>
<Button variant="ghost" size="icon" onClick={onClose}>
<X className="w-6 h-6" />
</Button>
</div>
{/* Content */}
<div className="p-8 flex-1 overflow-y-auto">
{/* Progress Stepper */}
<div className="flex justify-between max-w-lg mx-auto mb-10 relative">
<div className="absolute top-1/2 left-0 w-full h-1 bg-muted -z-10"></div>
{[1, 2, 3].map((i) => (
<div
key={i}
className={`w-8 h-8 rounded-full flex items-center justify-center font-bold text-sm transition-colors ${step >= i ? 'bg-primary text-black' : 'bg-muted text-muted-foreground'}`}
>
{step > i ? <CheckCircle className="w-5 h-5" /> : i}
</div>
))}
</div>
{activeTab === 'track' && (
<div className="grid grid-cols-1 md:grid-cols-2 gap-8">
<div className="space-y-6">
<FileUpload />
<div className="bg-muted p-4 rounded-lg border border-border">
<h4 className="font-bold text-muted-foreground text-sm mb-2 uppercase">
File Requirements
</h4>
<ul className="text-xs text-muted-foreground space-y-1">
<li> WAV, FLAC, AIFF (Lossless preferred)</li>
<li> Max size 500MB</li>
<li> 44.1kHz / 24-bit minimum</li>
</ul>
</div>
</div>
<div className="space-y-4">
<Input label="Track Title" placeholder="e.g. Neon Nights" />
<div className="grid grid-cols-2 gap-4">
<Input label="BPM" placeholder="128" />
<Input label="Key" placeholder="F# Minor" />
</div>
<Input label="Genre" placeholder="Cyberpunk / Synthwave" />
<div className="pt-4">
<label className="block text-sm font-medium text-muted-foreground mb-2 font-body">
Visibility
</label>
<div className="grid grid-cols-3 gap-2">
<Button variant="outline" className="p-4 flex flex-col items-center justify-center gap-2 text-muted-foreground bg-muted/10 border-border">
<Tag className="w-5 h-5" />{' '}
<span className="text-xs font-bold">Public</span>
</Button>
<Button variant="outline" className="p-4 flex flex-col items-center justify-center gap-2">
<Lock className="w-5 h-5" />{' '}
<span className="text-xs font-bold">Private</span>
</Button>
<Button variant="outline" className="p-4 flex flex-col items-center justify-center gap-2">
<DollarSign className="w-5 h-5" />{' '}
<span className="text-xs font-bold">Premium</span>
</Button>
</div>
</div>
</div>
</div>
)}
{activeTab === 'product' && (
<div className="text-center py-12">
<h3 className="text-xl font-bold text-white mb-2">
Sell Your Sounds
</h3>
<p className="text-muted-foreground mb-6">
Create Sample Packs, Presets, or DAW Templates.
</p>
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
{['Sample Pack', 'Serum Presets', 'Ableton Template'].map(
(type) => (
<Card
key={type}
variant="default"
className="hover:border-destructive cursor-pointer group"
>
<Package className="w-8 h-8 text-destructive mb-4 transition-opacity group-hover:opacity-80" />
<h4 className="font-bold">{type}</h4>
</Card>
),
)}
</div>
</div>
)}
</div>
{/* Footer */}
<div className="p-8 border-t border-border bg-card flex justify-end gap-4">
<Button variant="ghost" onClick={onClose}>
CANCEL
</Button>
<Button
variant="primary"
onClick={() => setStep((s) => Math.min(3, s + 1))}
>
{step === 3 ? 'PUBLISH RELEASE' : 'NEXT STEP'}
</Button>
</div>
</div>
</div>
);
};