Newer
Older
cortex-hub / frontend / src / features / settings / components / components / VoicesModal.js
import React from 'react';

export default function VoicesModal({ show, onClose, voiceList, voicesLoading }) {
  if (!show) return null;

  return (
    <div className="fixed inset-0 z-[100] flex items-center justify-center bg-black/50 p-4 transition-opacity" onClick={onClose}>
      <div className="bg-white dark:bg-gray-800 rounded-xl max-w-lg w-full p-6 shadow-2xl relative max-h-[85vh] flex flex-col" onClick={e => e.stopPropagation()}>
        <div className="flex justify-between items-center mb-4 border-b border-gray-100 dark:border-gray-700 pb-3">
          <div>
            <h3 className="text-xl font-bold text-gray-900 dark:text-gray-100">Available Cloud Voices</h3>
            <p className="text-xs text-gray-500 mt-1">Found {voiceList.length} voices to choose from.</p>
            <p className="text-xs text-indigo-500 font-medium mt-1">Highlighted voices (Chirp, Journey, Studio) use advanced AI for highest quality.</p>
          </div>
          <button onClick={onClose} className="text-gray-400 hover:text-gray-600 dark:hover:text-gray-300 text-3xl font-bold focus:outline-none">&times;</button>
        </div>
        <div className="overflow-y-auto flex-1 bg-gray-50 dark:bg-gray-900/50 border border-gray-100 dark:border-gray-700 p-2 rounded-lg">
          {voicesLoading ? (
            <div className="flex h-32 items-center justify-center">
              <div className="animate-spin rounded-full h-8 w-8 border-b-2 border-indigo-600 dark:border-indigo-400"></div>
            </div>
          ) : voiceList.length > 0 ? (
            <ul className="space-y-[2px]">
              {voiceList.map((v, i) => {
                let highlight = v.toLowerCase().includes('chirp') || v.toLowerCase().includes('journey') || v.toLowerCase().includes('studio');
                return (
                  <li key={i} className={`text-sm cursor-text font-mono select-all p-2 hover:bg-white dark:hover:bg-gray-800 rounded transition-colors border border-transparent hover:border-gray-200 dark:hover:border-gray-600 ${highlight ? 'text-indigo-600 dark:text-indigo-400 font-semibold' : 'text-gray-600 dark:text-gray-400'}`}>
                    {v}
                  </li>
                );
              })}
            </ul>
          ) : (
            <p className="text-center text-gray-500 mt-8">No voices found. Make sure your API key is configured and valid.</p>
          )}
        </div>
        <div className="mt-4 text-xs text-gray-500 dark:text-gray-400 flex justify-between items-center">
          <span>Double-click a name to select it, then paste it into the field.</span>
          <button onClick={onClose} className="px-4 py-2 bg-gray-100 hover:bg-gray-200 dark:bg-gray-700 dark:hover:bg-gray-600 text-gray-700 dark:text-gray-300 rounded-lg transition-colors font-medium">Close</button>
        </div>
      </div>
    </div>
  );
}