project-standalo-sonic-cloud/components/LabelProfileForm.tsx

162 lines
5.6 KiB
TypeScript

'use client'
import { useState } from 'react'
export interface LabelProfileFormData {
name: string
description?: string
logoUrl?: string
website?: string
}
export interface LabelProfileFormProps {
label: LabelProfileFormData
onSave: (data: LabelProfileFormData) => void | Promise<void>
onCancel?: () => void
isLoading?: boolean
}
export function LabelProfileForm({
label,
onSave,
onCancel,
isLoading = false
}: LabelProfileFormProps) {
const [formData, setFormData] = useState<LabelProfileFormData>(label)
const [hasChanges, setHasChanges] = useState(false)
const handleChange = (field: keyof LabelProfileFormData, value: string) => {
setFormData({ ...formData, [field]: value })
setHasChanges(true)
}
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault()
onSave(formData)
}
const handleReset = () => {
setFormData(label)
setHasChanges(false)
onCancel?.()
}
return (
<form onSubmit={handleSubmit} className="space-y-6">
{/* Name */}
<div>
<label htmlFor="name" className="block text-sm font-medium text-zinc-300 mb-2">
Label Name *
</label>
<input
type="text"
id="name"
value={formData.name}
onChange={(e) => handleChange('name', e.target.value)}
className="w-full px-4 py-3 bg-zinc-800 border border-zinc-700 rounded-lg text-white focus:outline-none focus:ring-2 focus:ring-purple-500"
required
/>
<p className="mt-2 text-xs text-zinc-500">
This is how your label will appear to artists and listeners
</p>
</div>
{/* Description */}
<div>
<label htmlFor="description" className="block text-sm font-medium text-zinc-300 mb-2">
Description
</label>
<textarea
id="description"
value={formData.description || ''}
onChange={(e) => handleChange('description', e.target.value)}
rows={4}
maxLength={500}
placeholder="Tell us about your label, its mission, and what makes it unique..."
className="w-full px-4 py-3 bg-zinc-800 border border-zinc-700 rounded-lg text-white placeholder-zinc-500 focus:outline-none focus:ring-2 focus:ring-purple-500 resize-none"
/>
<div className="mt-2 flex justify-between text-xs text-zinc-500">
<span>Brief description for your label profile</span>
<span>{formData.description?.length || 0}/500</span>
</div>
</div>
{/* Logo URL */}
<div>
<label htmlFor="logoUrl" className="block text-sm font-medium text-zinc-300 mb-2">
Logo URL
</label>
<input
type="url"
id="logoUrl"
value={formData.logoUrl || ''}
onChange={(e) => handleChange('logoUrl', e.target.value)}
placeholder="https://example.com/logo.png"
className="w-full px-4 py-3 bg-zinc-800 border border-zinc-700 rounded-lg text-white placeholder-zinc-500 focus:outline-none focus:ring-2 focus:ring-purple-500"
/>
{/* Logo Preview */}
{formData.logoUrl && (
<div className="mt-4 p-4 bg-zinc-800 rounded-lg border border-zinc-700">
<p className="text-xs text-zinc-400 mb-2">Preview:</p>
<div className="w-32 h-32 rounded-lg overflow-hidden bg-zinc-900">
<img
src={formData.logoUrl}
alt="Logo preview"
className="w-full h-full object-cover"
onError={(e) => {
const target = e.target as HTMLImageElement
target.style.display = 'none'
}}
/>
</div>
</div>
)}
</div>
{/* Website */}
<div>
<label htmlFor="website" className="block text-sm font-medium text-zinc-300 mb-2">
Website
</label>
<div className="relative">
<div className="absolute left-4 top-1/2 -translate-y-1/2 pointer-events-none">
<svg className="w-5 h-5 text-zinc-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M21 12a9 9 0 01-9 9m9-9a9 9 0 00-9-9m9 9H3m9 9a9 9 0 01-9-9m9 9c1.657 0 3-4.03 3-9s-1.343-9-3-9m0 18c-1.657 0-3-4.03-3-9s1.343-9 3-9m-9 9a9 9 0 019-9" />
</svg>
</div>
<input
type="url"
id="website"
value={formData.website || ''}
onChange={(e) => handleChange('website', e.target.value)}
placeholder="https://yourlabel.com"
className="w-full pl-12 pr-4 py-3 bg-zinc-800 border border-zinc-700 rounded-lg text-white placeholder-zinc-500 focus:outline-none focus:ring-2 focus:ring-purple-500"
/>
</div>
</div>
{/* Buttons */}
<div className="flex gap-4 pt-4">
{(hasChanges || onCancel) && (
<button
type="button"
onClick={handleReset}
disabled={isLoading}
className="px-6 py-3 bg-zinc-800 hover:bg-zinc-700 disabled:bg-zinc-800 disabled:text-zinc-500 text-white font-medium rounded-lg transition"
>
Cancel
</button>
)}
<button
type="submit"
disabled={isLoading || !hasChanges}
className="flex-1 px-6 py-3 bg-purple-500 hover:bg-purple-600 disabled:bg-zinc-700 disabled:text-zinc-500 text-white font-medium rounded-lg transition"
>
{isLoading ? 'Saving...' : 'Save Changes'}
</button>
</div>
</form>
)
}