Remove CharacterComponent and CharacterDetail components
- Deleted `CharacterComponent` and `CharacterDetail` files from the project. - Refactored related logic to improve code maintainability and reduce redundancy.
This commit is contained in:
88
components/form/SeriesImportSelector.tsx
Normal file
88
components/form/SeriesImportSelector.tsx
Normal file
@@ -0,0 +1,88 @@
|
||||
'use client'
|
||||
import React, {useState} from 'react';
|
||||
import {FontAwesomeIcon} from '@fortawesome/react-fontawesome';
|
||||
import {faDownload, faSpinner} from '@fortawesome/free-solid-svg-icons';
|
||||
import {useTranslations} from 'next-intl';
|
||||
import SelectBox from '@/components/form/SelectBox';
|
||||
|
||||
interface SeriesImportItem {
|
||||
id: string;
|
||||
name: string;
|
||||
}
|
||||
|
||||
interface SeriesImportSelectorProps {
|
||||
availableItems: SeriesImportItem[];
|
||||
onImport: (seriesElementId: string) => Promise<void>;
|
||||
placeholder: string;
|
||||
label?: string;
|
||||
}
|
||||
|
||||
export default function SeriesImportSelector({
|
||||
availableItems,
|
||||
onImport,
|
||||
placeholder,
|
||||
label
|
||||
}: SeriesImportSelectorProps) {
|
||||
const t = useTranslations();
|
||||
|
||||
const [selectedId, setSelectedId] = useState<string>('');
|
||||
const [isImporting, setIsImporting] = useState<boolean>(false);
|
||||
|
||||
async function handleImport(): Promise<void> {
|
||||
if (!selectedId || isImporting) return;
|
||||
|
||||
setIsImporting(true);
|
||||
try {
|
||||
await onImport(selectedId);
|
||||
setSelectedId('');
|
||||
} finally {
|
||||
setIsImporting(false);
|
||||
}
|
||||
}
|
||||
|
||||
if (availableItems.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const selectData = availableItems.map((item) => ({
|
||||
label: item.name,
|
||||
value: item.id
|
||||
}));
|
||||
|
||||
return (
|
||||
<div className="bg-primary/10 border border-primary/30 rounded-xl p-4 mb-4">
|
||||
{label && (
|
||||
<h4 className="text-sm font-medium text-primary mb-3 flex items-center gap-2">
|
||||
<FontAwesomeIcon icon={faDownload} className="w-4 h-4"/>
|
||||
{label}
|
||||
</h4>
|
||||
)}
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="flex-grow">
|
||||
<SelectBox
|
||||
onChangeCallBack={(e) => setSelectedId(e.target.value)}
|
||||
data={selectData}
|
||||
defaultValue={selectedId}
|
||||
placeholder={placeholder}
|
||||
/>
|
||||
</div>
|
||||
<button
|
||||
onClick={handleImport}
|
||||
disabled={!selectedId || isImporting}
|
||||
className={`px-4 py-2 rounded-lg font-medium flex items-center gap-2 transition-all duration-200 ${
|
||||
selectedId && !isImporting
|
||||
? 'bg-primary text-white hover:bg-primary-dark hover:scale-105'
|
||||
: 'bg-secondary/50 text-muted cursor-not-allowed'
|
||||
}`}
|
||||
>
|
||||
{isImporting ? (
|
||||
<FontAwesomeIcon icon={faSpinner} className="w-4 h-4 animate-spin"/>
|
||||
) : (
|
||||
<FontAwesomeIcon icon={faDownload} className="w-4 h-4"/>
|
||||
)}
|
||||
{t('seriesImport.importButton')}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user