style: condition tab improvements - add button used instead of generic button - added move up / down functionality - streamlined delte button - improved basic styling

This commit is contained in:
Sam Chau
2025-01-12 07:14:20 +10:30
parent cffeb581d5
commit a89a014729
2 changed files with 77 additions and 63 deletions

View File

@@ -1,9 +1,10 @@
import React from 'react';
import PropTypes from 'prop-types';
import {Plus, InfoIcon} from 'lucide-react';
import {InfoIcon} from 'lucide-react';
import {usePatterns} from '@hooks/usePatterns';
import {createCondition} from './conditions/conditionTypes';
import ConditionCard from './conditions/ConditionCard';
import AddButton from '@ui/DataBar/AddButton';
const FormatConditionsTab = ({conditions, onConditionsChange}) => {
const {patterns, isLoading, error} = usePatterns();
@@ -45,38 +46,50 @@ const FormatConditionsTab = ({conditions, onConditionsChange}) => {
};
if (isLoading) {
return <div>Loading patterns...</div>;
return (
<div className='flex items-center justify-center h-full'>
<div className='text-gray-500 dark:text-gray-400'>
Loading patterns...
</div>
</div>
);
}
if (error) {
return <div>Error loading patterns: {error}</div>;
return (
<div className='flex items-center justify-center h-full'>
<div className='text-red-500 dark:text-red-400'>
Error loading patterns: {error}
</div>
</div>
);
}
return (
<div className='h-full flex flex-col space-y-4'>
{/* Header with Info and Add Button */}
<div className='flex gap-4 items-stretch'>
<div className='flex-1 flex gap-2 p-3 text-xs bg-blue-50 dark:bg-blue-900/20 border border-blue-200 dark:border-blue-800 rounded-lg'>
{/* Header Section */}
<div className='flex items-center gap-4 h-16'>
{/* Info Alert */}
<div
className='flex-1 flex items-center gap-2 px-3 py-2
bg-blue-50 dark:bg-blue-900/20
border border-blue-200 dark:border-blue-800
rounded-md'>
<InfoIcon className='h-4 w-4 text-blue-600 dark:text-blue-400 flex-shrink-0' />
<p className='text-blue-700 dark:text-blue-300'>
Conditions define how this format matches media
releases. Each condition can be marked as required or
negated. Required conditions must match for the format
to apply, while negated conditions must not match. Use
patterns to match against release titles and groups.
<p className='text-sm text-blue-700 dark:text-blue-300'>
Define matching rules using required and negated
conditions to control how formats are applied to media
releases.
</p>
</div>
<button
onClick={handleAddCondition}
className='flex items-center justify-center gap-2 px-4 text-white bg-blue-600 hover:bg-blue-700 rounded-lg'>
<Plus className='w-5 h-5' />
<span className='text-sm font-medium'>Add</span>
</button>
{/* Add Button */}
<AddButton onClick={handleAddCondition} label='Add Condition' />
</div>
{/* Scrollable Conditions List */}
<div className='flex-1 overflow-y-auto min-h-0'>
<div className='space-y-3'>
<div className='flex-1 overflow-y-auto min-h-0 scrollable pr-2'>
<div className='space-y-3 pb-4'>
{conditions.map((condition, index) => (
<ConditionCard
key={index}

View File

@@ -1,7 +1,7 @@
import React from 'react';
import PropTypes from 'prop-types';
import {CONDITION_TYPES, createCondition} from './conditionTypes';
import {ArrowUp, ArrowDown} from 'lucide-react';
import {ArrowUp, ArrowDown, X} from 'lucide-react';
import BrowserSelect from '@ui/BrowserSelect';
const ConditionCard = ({
@@ -17,17 +17,14 @@ const ConditionCard = ({
const conditionType = CONDITION_TYPES[condition.type?.toUpperCase()];
const Component = conditionType?.component;
// Convert condition types to options format
const typeOptions = Object.values(CONDITION_TYPES).map(type => ({
value: type.id,
label: type.name
}));
// When type changes, create a fresh condition of the new type
const handleTypeChange = e => {
const newType = e.target.value;
const newCondition = createCondition(newType);
// Preserve the name if it exists
if (condition.name) {
newCondition.name = condition.name;
}
@@ -35,10 +32,9 @@ const ConditionCard = ({
};
return (
<div className='relative bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg'>
{/* Main content with more right padding */}
<div className='p-4 pr-16 space-y-4'>
{/* Content remains the same */}
<div className='relative bg-gray-800 rounded-lg border border-gray-700 shadow-xl'>
{/* Main content */}
<div className='p-4 pr-14 space-y-4 '>
{/* Custom Name Input */}
<div className='mb-4'>
<input
@@ -49,21 +45,23 @@ const ConditionCard = ({
onChange({...condition, name: e.target.value})
}
placeholder='Enter a condition name...'
className='w-full px-3 py-2 text-sm border border-gray-300 dark:border-gray-600
rounded-md bg-gray-50 dark:bg-gray-800 text-gray-900 dark:text-gray-100
focus:outline-none focus:ring-2 focus:ring-blue-500 dark:focus:ring-blue-400'
className='w-full px-3 py-2 text-sm rounded-md
bg-gray-700 border border-gray-700
text-gray-200 placeholder:text-gray-400
focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500'
/>
</div>
<div className='flex items-center gap-4'>
<div className='flex items-center gap-4 '>
{/* Type Selection */}
<BrowserSelect
value={condition.type || ''}
onChange={handleTypeChange}
options={typeOptions}
placeholder='Select type...'
className='min-w-[140px] px-2 py-1.5 text-sm border border-gray-300 dark:border-gray-600
rounded-md bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100'
className='min-w-[140px] px-3 py-2 text-sm rounded-md
bg-gray-700 border border-gray-700
text-gray-200'
/>
{/* Render the specific condition component */}
@@ -76,9 +74,9 @@ const ConditionCard = ({
)}
{/* Universal Controls */}
<div className='flex items-center gap-3'>
<div className='flex items-center gap-3 ml-auto'>
{/* Required Checkbox */}
<label className='flex items-center gap-2 text-sm text-gray-700 dark:text-gray-300'>
<label className='flex items-center gap-2 cursor-pointer'>
<input
type='checkbox'
checked={condition.required}
@@ -88,13 +86,16 @@ const ConditionCard = ({
required: e.target.checked
})
}
className='rounded border-gray-300 dark:border-gray-600'
className='rounded border-gray-700 bg-gray-900
text-blue-500 focus:ring-blue-500'
/>
Required
<span className='text-sm font-medium text-gray-400'>
Required
</span>
</label>
{/* Negate Checkbox */}
<label className='flex items-center gap-2 text-sm text-gray-700 dark:text-gray-300'>
<label className='flex items-center gap-2 cursor-pointer'>
<input
type='checkbox'
checked={condition.negate}
@@ -104,46 +105,46 @@ const ConditionCard = ({
negate: e.target.checked
})
}
className='rounded border-gray-300 dark:border-gray-600'
className='rounded border-gray-700 bg-gray-900
text-blue-500 focus:ring-blue-500'
/>
Negate
<span className='text-sm font-medium text-gray-400'>
Negate
</span>
</label>
{/* Delete Button */}
<button
onClick={onDelete}
className='text-gray-400 hover:text-red-500 transition-colors'>
<svg
className='w-4 h-4'
fill='none'
stroke='currentColor'
viewBox='0 0 24 24'>
<path
strokeLinecap='round'
strokeLinejoin='round'
strokeWidth='2'
d='M6 18L18 6M6 6l12 12'
/>
</svg>
</button>
</div>
</div>
</div>
{/* Move Up/Down Buttons - Now positioned further right */}
<div className='absolute right-0 top-0 bottom-0 flex flex-col divide-y divide-gray-200 dark:divide-gray-700 border-l border-gray-200 dark:border-gray-700'>
{/* Control Buttons */}
<div
className='absolute right-0 top-0 bottom-0 flex flex-col
divide-y divide-gray-700 border-l border-gray-700'>
<button
onClick={onMoveUp}
disabled={isFirst}
className='flex items-center justify-center w-8 h-1/2 text-gray-500 hover:text-gray-900 hover:bg-gray-50 dark:text-gray-400 dark:hover:text-gray-100 dark:hover:bg-gray-700/50 disabled:opacity-50 disabled:hover:bg-transparent dark:disabled:hover:bg-transparent disabled:cursor-not-allowed transition-colors'>
className='flex items-center justify-center w-10 flex-1
text-gray-400 hover:text-gray-200 hover:bg-gray-700
disabled:opacity-50 disabled:pointer-events-none
transition-colors'>
<ArrowUp className='w-4 h-4' />
</button>
<button
onClick={onMoveDown}
disabled={isLast}
className='flex items-center justify-center w-8 h-1/2 text-gray-500 hover:text-gray-900 hover:bg-gray-50 dark:text-gray-400 dark:hover:text-gray-100 dark:hover:bg-gray-700/50 disabled:opacity-50 disabled:hover:bg-transparent dark:disabled:hover:bg-transparent disabled:cursor-not-allowed transition-colors'>
className='flex items-center justify-center w-10 flex-1
text-gray-400 hover:text-gray-200 hover:bg-gray-700
disabled:opacity-50 disabled:pointer-events-none
transition-colors'>
<ArrowDown className='w-4 h-4' />
</button>
<button
onClick={onDelete}
className='flex items-center justify-center w-10 flex-1
text-gray-400 hover:text-red-400 hover:bg-red-400/10
transition-colors'>
<X className='w-4 h-4' />
</button>
</div>
</div>
);