fix alert-settings ui and add relay config
Some checks failed
Deploy MyApp on Same Server / build-and-deploy (push) Has been cancelled
Some checks failed
Deploy MyApp on Same Server / build-and-deploy (push) Has been cancelled
This commit is contained in:
133
src/components/alert-settings/RuleFormCard.tsx
Normal file
133
src/components/alert-settings/RuleFormCard.tsx
Normal file
@@ -0,0 +1,133 @@
|
||||
'use client'
|
||||
|
||||
import { Trash2 } from 'lucide-react'
|
||||
import { SENSOR_TYPES, COMPARISON_TYPES, SensorType, ComparisonType } from './constants'
|
||||
import { getSensorIcon, getSensorLabel, getSensorUnit, getComparisonLabel } from './utils'
|
||||
import { CreateAlertRuleRequest } from '@/lib/api'
|
||||
|
||||
type RuleFormCardProps = {
|
||||
rule: CreateAlertRuleRequest
|
||||
index: number
|
||||
totalRules: number
|
||||
onUpdate: (index: number, updates: Partial<CreateAlertRuleRequest>) => void
|
||||
onRemove: (index: number) => void
|
||||
}
|
||||
|
||||
export function RuleFormCard({ rule, index, totalRules, onUpdate, onRemove }: RuleFormCardProps) {
|
||||
const needsMax = COMPARISON_TYPES.find(c => c.value === rule.comparisonType)?.needsMax
|
||||
const SensorIcon = getSensorIcon(rule.sensorType)
|
||||
|
||||
return (
|
||||
<div className="bg-gradient-to-br from-orange-50 to-red-50 border border-orange-200 rounded-xl p-3 relative shadow-sm">
|
||||
{/* Header - Compact */}
|
||||
<div className="flex items-center justify-between mb-2">
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="text-xs font-bold text-orange-700 bg-white/80 px-2 py-0.5 rounded-full shadow-sm">
|
||||
{totalRules === 1 ? '⚡ شرط' : `⚡ شرط ${index + 1}`}
|
||||
</span>
|
||||
{/* Compact summary of current selection */}
|
||||
<span className="text-xs text-gray-500 hidden sm:inline">
|
||||
<SensorIcon className="w-3 h-3 inline ml-1" />
|
||||
{getSensorLabel(rule.sensorType)}
|
||||
{' | '}
|
||||
{getComparisonLabel(rule.comparisonType)}
|
||||
{' | '}
|
||||
{rule.value1}{needsMax ? ` - ${rule.value2 ?? '?'}` : ''} {getSensorUnit(rule.sensorType)}
|
||||
</span>
|
||||
</div>
|
||||
{totalRules > 1 && (
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => onRemove(index)}
|
||||
className="p-1.5 text-red-500 hover:bg-red-100 rounded-lg transition-colors"
|
||||
title="حذف این شرط"
|
||||
>
|
||||
<Trash2 className="w-3.5 h-3.5" />
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Compact row: Sensor | Comparison | Value */}
|
||||
<div className="flex flex-col sm:flex-row gap-2">
|
||||
{/* Sensor Type - Compact Select */}
|
||||
<div className="flex-1 min-w-0">
|
||||
<select
|
||||
value={rule.sensorType}
|
||||
onChange={(e) => onUpdate(index, { sensorType: Number(e.target.value) as SensorType })}
|
||||
className="w-full appearance-none px-3 py-2 pr-8 bg-white border border-orange-200 rounded-lg text-sm font-medium text-gray-700 focus:ring-2 focus:ring-orange-500 focus:border-orange-500 cursor-pointer"
|
||||
style={{
|
||||
backgroundImage: `url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 8l4 4 4-4'/%3e%3c/svg%3e")`,
|
||||
backgroundPosition: 'left 0.5rem center',
|
||||
backgroundRepeat: 'no-repeat',
|
||||
backgroundSize: '1.25rem'
|
||||
}}
|
||||
>
|
||||
{SENSOR_TYPES.map(sensor => (
|
||||
<option key={sensor.value} value={sensor.value}>
|
||||
{sensor.label} ({sensor.unit})
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
{/* Comparison Type - Compact Select */}
|
||||
<div className="flex-1 min-w-0">
|
||||
<select
|
||||
value={rule.comparisonType}
|
||||
onChange={(e) => onUpdate(index, { comparisonType: Number(e.target.value) as ComparisonType })}
|
||||
className="w-full appearance-none px-3 py-2 pr-8 bg-white border border-orange-200 rounded-lg text-sm font-medium text-gray-700 focus:ring-2 focus:ring-orange-500 focus:border-orange-500 cursor-pointer"
|
||||
style={{
|
||||
backgroundImage: `url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 8l4 4 4-4'/%3e%3c/svg%3e")`,
|
||||
backgroundPosition: 'left 0.5rem center',
|
||||
backgroundRepeat: 'no-repeat',
|
||||
backgroundSize: '1.25rem'
|
||||
}}
|
||||
>
|
||||
{COMPARISON_TYPES.map(comp => (
|
||||
<option key={comp.value} value={comp.value}>
|
||||
{comp.label}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
{/* Threshold Values - Compact Inputs */}
|
||||
<div className="flex gap-1.5 items-center flex-1">
|
||||
<div className="relative flex-1 min-w-0">
|
||||
<input
|
||||
type="number"
|
||||
step="0.01"
|
||||
value={rule.value1}
|
||||
onChange={(e) => onUpdate(index, { value1: Number(e.target.value) })}
|
||||
className="w-full px-3 py-2 pl-10 bg-white border border-orange-200 rounded-lg text-sm font-medium focus:ring-2 focus:ring-orange-500 focus:border-orange-500"
|
||||
placeholder={needsMax ? 'از' : 'مقدار'}
|
||||
required
|
||||
/>
|
||||
<span className="absolute left-2 top-1/2 -translate-y-1/2 text-xs text-gray-400 font-medium">
|
||||
{getSensorUnit(rule.sensorType)}
|
||||
</span>
|
||||
</div>
|
||||
{needsMax && (
|
||||
<>
|
||||
<span className="text-gray-400 text-sm flex-shrink-0">-</span>
|
||||
<div className="relative flex-1 min-w-0">
|
||||
<input
|
||||
type="number"
|
||||
step="0.01"
|
||||
value={rule.value2 ?? ''}
|
||||
onChange={(e) => onUpdate(index, { value2: Number(e.target.value) })}
|
||||
className="w-full px-3 py-2 pl-10 bg-white border border-orange-200 rounded-lg text-sm font-medium focus:ring-2 focus:ring-orange-500 focus:border-orange-500"
|
||||
placeholder="تا"
|
||||
required
|
||||
/>
|
||||
<span className="absolute left-2 top-1/2 -translate-y-1/2 text-xs text-gray-400 font-medium">
|
||||
{getSensorUnit(rule.sensorType)}
|
||||
</span>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user