style: consistent import modal (#206)

* style(import-modal): design similar to new media management sync modal

* chore(docker): change dev build to beta
This commit is contained in:
Samuel Chau
2025-06-14 04:03:50 +09:30
committed by GitHub
parent 22d4029e20
commit 876df945e4
2 changed files with 68 additions and 40 deletions

View File

@@ -1,5 +1,6 @@
import React, {useState, useEffect} from 'react';
import PropTypes from 'prop-types';
import {Loader, Check, Upload} from 'lucide-react';
import Modal from './Modal';
import {getArrConfigs} from '@api/arr';
@@ -58,53 +59,80 @@ const ImportModal = ({isOpen, onClose, onImport, type}) => {
isOpen={isOpen}
onClose={onClose}
title={`Import ${type}`}
width='xl'
footer={
<div className='flex justify-end gap-2'>
<button
onClick={onClose}
className='px-4 py-2 text-gray-600 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700 rounded transition-colors'>
Cancel
</button>
<div className='flex justify-end'>
<button
onClick={handleImport}
disabled={!selectedArr || isLoading || isImporting}
className='px-4 py-2 bg-blue-500 hover:bg-blue-600 disabled:bg-blue-300 dark:disabled:bg-blue-700 text-white rounded transition-colors'>
{isImporting ? 'Importing...' : 'Import'}
className='inline-flex items-center gap-1.5 px-3 py-1.5 rounded bg-gray-700/50 border border-gray-700 text-gray-200 hover:bg-gray-700 transition-colors disabled:opacity-50 disabled:cursor-not-allowed text-sm'
>
{isImporting ? (
<>
<Check className='w-4 h-4 text-green-500' />
<span>Importing...</span>
</>
) : (
<>
<Upload className='w-4 h-4 text-blue-500' />
<span>Import</span>
</>
)}
</button>
</div>
}>
<div className='space-y-4'>
<div>
<label className='block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1'>
Select Arr
</label>
{isLoading ? (
<div className='animate-pulse bg-gray-200 dark:bg-gray-700 h-10 rounded'></div>
) : arrs.length > 0 ? (
<select
value={selectedArr}
onChange={e => {
setSelectedArr(e.target.value);
setError('');
}}
className='w-full px-3 py-2 bg-white dark:bg-gray-700 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500'>
<option value=''>Select an arr...</option>
{arrs.map(arr => (
<option key={arr.id} value={arr.id}>
{arr.name} ({arr.type})
</option>
))}
</select>
) : (
<div className='text-sm text-red-500'>
No arr instances configured. Please add one in
settings.
</div>
)}
{isLoading ? (
<div className='flex items-center justify-center py-8'>
<Loader className='w-6 h-6 animate-spin text-blue-500' />
<span className='ml-2'>Loading...</span>
</div>
{error && <p className='text-sm text-red-500'>{error}</p>}
</div>
) : arrs.length === 0 ? (
<div className='text-center py-8'>
<p className='text-gray-600'>No arr instances configured</p>
</div>
) : (
<div className='bg-gradient-to-br from-gray-800 to-gray-900 rounded-lg border border-gray-700 overflow-hidden'>
<table className='w-full'>
<thead>
<tr className='bg-gray-800/50 border-b border-gray-700'>
<th className='text-left py-3 px-4 text-sm font-medium text-gray-300'>Name</th>
<th className='text-left py-3 px-4 text-sm font-medium text-gray-300'>Type</th>
<th className='text-right py-3 px-4 text-sm font-medium text-gray-300'>Select</th>
</tr>
</thead>
<tbody>
{arrs.map((arr, index) => (
<tr
key={arr.id}
className={`cursor-pointer select-none transition-colors hover:bg-gray-700/50 ${index !== arrs.length - 1 ? 'border-b border-gray-700/50' : ''}`}
onClick={() => setSelectedArr(arr.id)}
>
<td className='py-3 px-4'>
<span className='font-medium text-gray-200'>{arr.name}</span>
</td>
<td className='py-3 px-4'>
<span className='text-sm text-gray-400'>{arr.type}</span>
</td>
<td className='py-3 px-4'>
<div className='flex justify-end'>
<div className={`w-6 h-6 rounded-full flex items-center justify-center transition-all duration-200 ${
selectedArr === arr.id
? 'bg-blue-500'
: 'bg-gray-700 hover:bg-gray-600'
}`}>
{selectedArr === arr.id && (
<Check size={14} className='text-white' />
)}
</div>
</div>
</td>
</tr>
))}
</tbody>
</table>
</div>
)}
{error && <p className='text-sm text-red-500 mt-4'>{error}</p>}
</Modal>
);
};