rescored / frontend /src /components /InstrumentSelector.tsx
calebhan's picture
file upload pipeline
a5359f9
/**
* Multi-instrument selector for choosing which instruments to transcribe.
*/
import { useState } from 'react';
import './InstrumentSelector.css';
export interface Instrument {
id: string;
label: string;
icon: string;
}
const INSTRUMENTS: Instrument[] = [
{ id: 'piano', label: 'Piano', icon: '๐ŸŽน' },
{ id: 'vocals', label: 'Vocals', icon: '๐ŸŽค' },
{ id: 'drums', label: 'Drums', icon: '๐Ÿฅ' },
{ id: 'bass', label: 'Bass', icon: '๐ŸŽธ' },
{ id: 'guitar', label: 'Guitar', icon: '๐ŸŽธ' },
{ id: 'other', label: 'Other Instruments', icon: '๐ŸŽต' }
];
export const VOCAL_INSTRUMENTS = [
{ id: 'violin', label: 'Violin', program: 40 },
{ id: 'flute', label: 'Flute', program: 73 },
{ id: 'clarinet', label: 'Clarinet', program: 71 },
{ id: 'saxophone', label: 'Saxophone', program: 64 },
{ id: 'trumpet', label: 'Trumpet', program: 56 },
{ id: 'voice', label: 'Singing Voice', program: 65 },
];
interface InstrumentSelectorProps {
selectedInstruments: string[];
onChange: (instruments: string[]) => void;
vocalInstrument?: string;
onVocalInstrumentChange?: (instrument: string) => void;
}
export function InstrumentSelector({
selectedInstruments,
onChange,
vocalInstrument = 'violin',
onVocalInstrumentChange
}: InstrumentSelectorProps) {
const handleToggle = (instrumentId: string) => {
const isSelected = selectedInstruments.includes(instrumentId);
if (isSelected) {
// Don't allow deselecting if it's the only selected instrument
if (selectedInstruments.length === 1) {
return;
}
const newInstruments = selectedInstruments.filter(id => id !== instrumentId);
console.log('[DEBUG] InstrumentSelector: Removing', instrumentId, '-> New list:', newInstruments);
onChange(newInstruments);
} else {
const newInstruments = [...selectedInstruments, instrumentId];
console.log('[DEBUG] InstrumentSelector: Adding', instrumentId, '-> New list:', newInstruments);
onChange(newInstruments);
}
};
const vocalsSelected = selectedInstruments.includes('vocals');
return (
<div className="instrument-selector">
<label className="selector-label">Select Instruments:</label>
<div className="instrument-grid">
{INSTRUMENTS.map(instrument => (
<button
key={instrument.id}
type="button"
className={`instrument-button ${selectedInstruments.includes(instrument.id) ? 'selected' : ''}`}
onClick={() => handleToggle(instrument.id)}
aria-pressed={selectedInstruments.includes(instrument.id)}
>
<span className="instrument-icon">{instrument.icon}</span>
<span className="instrument-label">{instrument.label}</span>
</button>
))}
</div>
{vocalsSelected && onVocalInstrumentChange && (
<div className="vocal-instrument-selector">
<label htmlFor="vocal-instrument">Transcribe vocals as:</label>
<select
id="vocal-instrument"
value={vocalInstrument}
onChange={(e) => onVocalInstrumentChange(e.target.value)}
>
{VOCAL_INSTRUMENTS.map(inst => (
<option key={inst.id} value={inst.id}>
{inst.label}
</option>
))}
</select>
</div>
)}
<p className="selector-hint">
Select at least one instrument to transcribe
</p>
</div>
);
}
export default InstrumentSelector;