Phase 2 UI Adjustments/Edits by bonamin

This commit is contained in:
2026-02-17 09:56:07 +02:00
parent 2b48426fe5
commit 59c5049305
16 changed files with 1588 additions and 609 deletions

View File

@@ -0,0 +1,98 @@
import { useState, useEffect } from "react";
import { getLanguageName } from "./melodyUtils";
/**
* Modal for editing translations of a field (Name or Description).
* Props:
* open - boolean
* onClose - function
* field - string label ("Name" or "Description")
* value - dict { lang_code: text }
* onChange - function(updatedDict)
* languages - array of lang codes ["en", "el", "sr"]
* multiline - boolean (use textarea instead of input)
*/
export default function TranslationModal({
open,
onClose,
field,
value,
onChange,
languages,
multiline = false,
}) {
const [draft, setDraft] = useState({});
useEffect(() => {
if (open) {
setDraft({ ...value });
}
}, [open, value]);
if (!open) return null;
const updateDraft = (lang, text) => {
setDraft((prev) => ({ ...prev, [lang]: text }));
};
const handleSave = () => {
onChange(draft);
onClose();
};
return (
<div className="fixed inset-0 z-50 flex items-center justify-center">
<div className="fixed inset-0 bg-black/50" onClick={onClose} />
<div className="relative bg-white rounded-lg shadow-xl w-full max-w-lg mx-4 max-h-[80vh] overflow-y-auto">
<div className="p-6">
<h3 className="text-lg font-semibold text-gray-900 mb-4">
Translations {field}
</h3>
<div className="space-y-3">
{languages.map((lang) => (
<div key={lang}>
<label className="block text-sm font-medium text-gray-700 mb-1">
{getLanguageName(lang)}{" "}
<span className="text-gray-400 font-mono text-xs uppercase">
({lang})
</span>
</label>
{multiline ? (
<textarea
value={draft[lang] || ""}
onChange={(e) => updateDraft(lang, e.target.value)}
rows={2}
className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 text-sm"
/>
) : (
<input
type="text"
value={draft[lang] || ""}
onChange={(e) => updateDraft(lang, e.target.value)}
className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 text-sm"
/>
)}
</div>
))}
</div>
<div className="flex justify-end gap-3 mt-6">
<button
type="button"
onClick={onClose}
className="px-4 py-2 bg-gray-100 text-gray-700 text-sm rounded-md hover:bg-gray-200 transition-colors"
>
Cancel
</button>
<button
type="button"
onClick={handleSave}
className="px-4 py-2 bg-blue-600 text-white text-sm rounded-md hover:bg-blue-700 transition-colors"
>
Save Translations
</button>
</div>
</div>
</div>
</div>
);
}