150 lines
6.4 KiB
TypeScript
Executable File
150 lines
6.4 KiB
TypeScript
Executable File
import React from 'react';
|
|
import Spinner from './Spinner';
|
|
|
|
interface RawDownloadFormProps {
|
|
geIdAndLang: string;
|
|
setGeIdAndLang: (value: string) => void;
|
|
isLoading: boolean;
|
|
handleSubmit: (e: React.FormEvent) => void;
|
|
handleRawDownload: (e: React.FormEvent) => void;
|
|
isRawDownloading: boolean;
|
|
relatedProjects?: Array<{ ge_id: string, lang: string }>;
|
|
projectNote?: string | null;
|
|
currentGeId?: string;
|
|
currentLang?: string;
|
|
}
|
|
|
|
const RawDownloadForm: React.FC<RawDownloadFormProps> = ({
|
|
geIdAndLang,
|
|
setGeIdAndLang,
|
|
isLoading,
|
|
handleSubmit,
|
|
handleRawDownload,
|
|
isRawDownloading,
|
|
relatedProjects = [],
|
|
projectNote = null,
|
|
currentGeId = '',
|
|
currentLang = '',
|
|
}) => {
|
|
// Parse note into tags (split by comma)
|
|
const noteTags = projectNote
|
|
? projectNote.split(',').map(tag => tag.trim()).filter(Boolean)
|
|
: [];
|
|
|
|
return (
|
|
<div className="space-y-6">
|
|
{/* Input and Action Buttons */}
|
|
<form onSubmit={handleSubmit}>
|
|
<div className="flex gap-3">
|
|
<input
|
|
id="rawGeIdAndLang"
|
|
type="text"
|
|
value={geIdAndLang}
|
|
onChange={(e) => setGeIdAndLang(e.target.value)}
|
|
onFocus={(e) => e.target.select()}
|
|
className="flex-1 min-w-0 bg-slate-900/50 border border-slate-700 text-slate-100 text-sm rounded-lg focus:ring-indigo-500 focus:border-indigo-500 p-2.5 transition-colors duration-200"
|
|
placeholder="Nhập GE ID và Lang (ví dụ: 1000 de)"
|
|
disabled={isLoading || isRawDownloading}
|
|
/>
|
|
<button
|
|
type="submit"
|
|
disabled={isLoading || isRawDownloading}
|
|
className="flex justify-center items-center text-white bg-indigo-600 hover:bg-indigo-700 focus:ring-4 focus:outline-none focus:ring-indigo-800 font-medium rounded-lg text-sm px-5 py-2.5 transition-all duration-200 disabled:bg-indigo-900 disabled:text-slate-400 disabled:cursor-not-allowed whitespace-nowrap w-[130px]"
|
|
>
|
|
{isLoading ? (
|
|
<>
|
|
<Spinner />
|
|
<span>Đang tìm...</span>
|
|
</>
|
|
) : (
|
|
'Tải setting'
|
|
)}
|
|
</button>
|
|
<button
|
|
type="button"
|
|
onClick={handleRawDownload}
|
|
disabled={isLoading || isRawDownloading}
|
|
className="flex justify-center items-center text-white bg-emerald-600 hover:bg-emerald-700 focus:ring-4 focus:outline-none focus:ring-emerald-800 font-medium rounded-lg text-sm px-5 py-2.5 transition-all duration-200 disabled:bg-emerald-900 disabled:text-slate-400 disabled:cursor-not-allowed whitespace-nowrap w-[130px]"
|
|
>
|
|
{isRawDownloading ? (
|
|
<>
|
|
<Spinner />
|
|
<span>Đang tải...</span>
|
|
</>
|
|
) : (
|
|
'Tải raw'
|
|
)}
|
|
</button>
|
|
</div>
|
|
</form>
|
|
|
|
{/* Related Projects Section */}
|
|
<div className="bg-slate-800/30 border border-slate-700/50 rounded-xl p-4">
|
|
<div className="flex items-center gap-2 mb-3">
|
|
<svg className="w-4 h-4 text-indigo-400" viewBox="0 0 24 24" fill="currentColor">
|
|
<path fillRule="evenodd" d="M4.848 2.771A49.144 49.144 0 0 1 12 2.25c2.43 0 4.817.178 7.152.52 1.978.292 3.348 2.024 3.348 3.97v6.02c0 1.946-1.37 3.678-3.348 3.97a48.901 48.901 0 0 1-3.476.383.39.39 0 0 0-.297.17l-2.755 4.133a.75.75 0 0 1-1.248 0l-2.755-4.133a.39.39 0 0 0-.297-.17 48.9 48.9 0 0 1-3.476-.384c-1.978-.29-3.348-2.024-3.348-3.97V6.741c0-1.946 1.37-3.68 3.348-3.97Z" clipRule="evenodd" />
|
|
</svg>
|
|
<h3 className="text-sm font-semibold text-slate-300">Tựa cùng raw</h3>
|
|
</div>
|
|
|
|
<div className="flex flex-wrap gap-2">
|
|
{relatedProjects.length > 0 ? (
|
|
relatedProjects.map((project, idx) => {
|
|
const isCurrent = project.ge_id === currentGeId && project.lang.toUpperCase() === currentLang.toUpperCase();
|
|
return (
|
|
<div
|
|
key={idx}
|
|
className={`inline-flex items-center gap-2 px-3 py-1.5 rounded-lg transition-all duration-200 text-sm font-medium ${isCurrent
|
|
? 'bg-indigo-600/30 border border-indigo-500/60'
|
|
: 'bg-slate-700/50 border border-slate-600/50 hover:bg-slate-600/60 hover:border-slate-500/60'
|
|
}`}
|
|
>
|
|
<span className={isCurrent ? 'text-indigo-200 font-bold' : 'text-slate-200 font-semibold'}>
|
|
{project.ge_id}
|
|
</span>
|
|
<span className={`uppercase text-xs tracking-wider ${isCurrent ? 'text-indigo-300' : 'text-slate-400'}`}>
|
|
{project.lang}
|
|
</span>
|
|
</div>
|
|
);
|
|
})
|
|
) : (
|
|
<span className="text-sm text-slate-500 italic py-1">
|
|
Chưa có dữ liệu
|
|
</span>
|
|
)}
|
|
</div>
|
|
</div>
|
|
|
|
{/* Note Section */}
|
|
<div className="bg-slate-800/30 border border-slate-700/50 rounded-xl p-4">
|
|
<div className="flex items-center gap-2 mb-3">
|
|
<svg className="w-4 h-4 text-amber-400" viewBox="0 0 24 24" fill="currentColor">
|
|
<path fillRule="evenodd" d="M4.848 2.771A49.144 49.144 0 0 1 12 2.25c2.43 0 4.817.178 7.152.52 1.978.292 3.348 2.024 3.348 3.97v6.02c0 1.946-1.37 3.678-3.348 3.97a48.901 48.901 0 0 1-3.476.383.39.39 0 0 0-.297.17l-2.755 4.133a.75.75 0 0 1-1.248 0l-2.755-4.133a.39.39 0 0 0-.297-.17 48.9 48.9 0 0 1-3.476-.384c-1.978-.29-3.348-2.024-3.348-3.97V6.741c0-1.946 1.37-3.68 3.348-3.97Z" clipRule="evenodd" />
|
|
</svg>
|
|
<h3 className="text-sm font-semibold text-slate-300">Note</h3>
|
|
</div>
|
|
|
|
<div className="flex flex-wrap gap-2">
|
|
{noteTags.length > 0 ? (
|
|
noteTags.map((tag, idx) => (
|
|
<span
|
|
key={idx}
|
|
className="inline-flex items-center px-3 py-1.5 bg-amber-500/10 border border-amber-500/30 rounded-lg text-amber-200 text-sm font-medium hover:bg-amber-500/20 hover:border-amber-500/50 transition-all duration-200"
|
|
>
|
|
{tag}
|
|
</span>
|
|
))
|
|
) : (
|
|
<span className="text-sm text-slate-500 italic py-1">
|
|
Chưa có note
|
|
</span>
|
|
)}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default RawDownloadForm;
|