jam-tracks / frontend /src /components /ScalesDisplay.jsx
Mina Emadi
applied the comments regarding chord progression, scale suggestions and UI/UX changes
25d51c9
Raw
History Blame Contribute Delete
2.5 kB
import React from 'react'
const KEY_NAMES = ['C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B']
function transposeNote(note, semitones) {
if (!note || semitones === 0) return note
const idx = KEY_NAMES.indexOf(note)
if (idx === -1) return note
return KEY_NAMES[(idx + semitones + 120) % 12]
}
function ScalesDisplay({ scales, semitones = 0 }) {
if (!scales || scales.length === 0) return null
return (
<div className="card rounded-xl p-5 animate-fade-in">
<h2 className="text-sm font-semibold text-white mb-3">Suggested Scales</h2>
<div className="flex gap-3 overflow-x-auto pb-2 scrollbar-thin">
{scales.map((scale, i) => {
const parts = scale.name.split(' ')
const scaleRoot = parts[0]
const scaleSuffix = parts.slice(1).join(' ')
const transposedRoot = transposeNote(scaleRoot, semitones)
const transposedNotes = scale.notes.map(n => transposeNote(n, semitones))
return (
<div
key={i}
className={`
flex-shrink-0 rounded-xl px-4 py-3 border transition-colors min-w-[200px]
${i === 0
? 'bg-accent-500/[0.08] border-accent-500/20'
: 'bg-surface-elevated border-white/[0.06]'
}
`}
>
{/* Header row */}
<div className="flex items-center gap-2 mb-2">
<span className="text-sm font-semibold text-white">
{transposedRoot} {scaleSuffix}
</span>
{scale.guitar_friendly && (
<span className="text-[10px] text-amber-400 font-medium">guitar</span>
)}
{i === 0 && (
<span className="text-[10px] px-1.5 py-0.5 rounded bg-accent-500/20 text-accent-400 font-medium ml-auto">
Best fit
</span>
)}
</div>
{/* Note chips */}
<div className="flex flex-wrap gap-1">
{transposedNotes.map((note, j) => (
<span
key={j}
className="text-[11px] px-1.5 py-0.5 rounded bg-surface text-gray-400"
>
{note}
</span>
))}
</div>
</div>
)
})}
</div>
</div>
)
}
export default React.memo(ScalesDisplay)