Add statuscard changes
This commit is contained in:
@@ -79,10 +79,10 @@ const Button = forwardRef<HTMLButtonElement, ButtonProps>(({
|
|||||||
|
|
||||||
const sizeClasses = {
|
const sizeClasses = {
|
||||||
xs: 'px-2 py-1 text-xs gap-1 min-h-6',
|
xs: 'px-2 py-1 text-xs gap-1 min-h-6',
|
||||||
sm: 'px-3 py-1.5 text-sm gap-1.5 min-h-8',
|
sm: 'px-3 py-1.5 text-sm gap-1.5 min-h-8 sm:min-h-10', // Better touch target on mobile
|
||||||
md: 'px-4 py-2 text-sm gap-2 min-h-10',
|
md: 'px-4 py-2 text-sm gap-2 min-h-10 sm:min-h-12',
|
||||||
lg: 'px-6 py-2.5 text-base gap-2 min-h-12',
|
lg: 'px-6 py-2.5 text-base gap-2 min-h-12 sm:min-h-14',
|
||||||
xl: 'px-8 py-3 text-lg gap-3 min-h-14'
|
xl: 'px-8 py-3 text-lg gap-3 min-h-14 sm:min-h-16'
|
||||||
};
|
};
|
||||||
|
|
||||||
const loadingSpinner = (
|
const loadingSpinner = (
|
||||||
|
|||||||
@@ -34,9 +34,12 @@ export interface StatusCardProps {
|
|||||||
icon?: LucideIcon;
|
icon?: LucideIcon;
|
||||||
variant?: 'primary' | 'outline';
|
variant?: 'primary' | 'outline';
|
||||||
onClick: () => void;
|
onClick: () => void;
|
||||||
|
priority?: 'primary' | 'secondary' | 'tertiary';
|
||||||
|
destructive?: boolean;
|
||||||
}>;
|
}>;
|
||||||
onClick?: () => void;
|
onClick?: () => void;
|
||||||
className?: string;
|
className?: string;
|
||||||
|
compact?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -74,7 +77,7 @@ export const getStatusColor = (status: string): StatusIndicatorConfig['color'] =
|
|||||||
* StatusCard - Reusable card component with consistent status styling
|
* StatusCard - Reusable card component with consistent status styling
|
||||||
*/
|
*/
|
||||||
export const StatusCard: React.FC<StatusCardProps> = ({
|
export const StatusCard: React.FC<StatusCardProps> = ({
|
||||||
id,
|
id: _id,
|
||||||
statusIndicator,
|
statusIndicator,
|
||||||
title,
|
title,
|
||||||
subtitle,
|
subtitle,
|
||||||
@@ -86,10 +89,23 @@ export const StatusCard: React.FC<StatusCardProps> = ({
|
|||||||
actions = [],
|
actions = [],
|
||||||
onClick,
|
onClick,
|
||||||
className = '',
|
className = '',
|
||||||
|
compact: _compact = false,
|
||||||
}) => {
|
}) => {
|
||||||
const StatusIcon = statusIndicator.icon;
|
const StatusIcon = statusIndicator.icon;
|
||||||
const hasInteraction = onClick || actions.length > 0;
|
const hasInteraction = onClick || actions.length > 0;
|
||||||
|
|
||||||
|
// Sort actions by priority
|
||||||
|
const sortedActions = [...actions].sort((a, b) => {
|
||||||
|
const priorityOrder = { primary: 0, secondary: 1, tertiary: 2 };
|
||||||
|
const aPriority = priorityOrder[a.priority || 'secondary'];
|
||||||
|
const bPriority = priorityOrder[b.priority || 'secondary'];
|
||||||
|
return aPriority - bPriority;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Split actions into primary and secondary groups
|
||||||
|
const primaryActions = sortedActions.filter(action => action.priority === 'primary');
|
||||||
|
const secondaryActions = sortedActions.filter(action => action.priority !== 'primary');
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card
|
<Card
|
||||||
className={`
|
className={`
|
||||||
@@ -201,21 +217,65 @@ export const StatusCard: React.FC<StatusCardProps> = ({
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Actions */}
|
{/* Enhanced Mobile-Responsive Actions */}
|
||||||
{actions.length > 0 && (
|
{actions.length > 0 && (
|
||||||
<div className="flex gap-2 pt-3 border-t border-[var(--border-primary)]">
|
<div className="pt-3 border-t border-[var(--border-primary)]">
|
||||||
{actions.map((action, index) => (
|
{/* Primary Actions - Full width on mobile, inline on desktop */}
|
||||||
<Button
|
{primaryActions.length > 0 && (
|
||||||
key={index}
|
<div className={`
|
||||||
variant={action.variant || 'outline'}
|
flex gap-2 mb-2
|
||||||
size="sm"
|
${primaryActions.length > 1 ? 'flex-col sm:flex-row' : ''}
|
||||||
className="flex-1"
|
`}>
|
||||||
onClick={action.onClick}
|
{primaryActions.map((action, index) => (
|
||||||
>
|
<Button
|
||||||
{action.icon && <action.icon className="w-4 h-4 mr-2" />}
|
key={`primary-${index}`}
|
||||||
{action.label}
|
variant={action.destructive ? 'outline' : (action.variant || 'primary')}
|
||||||
</Button>
|
size="sm"
|
||||||
))}
|
className={`
|
||||||
|
${primaryActions.length === 1 ? 'w-full sm:w-auto sm:min-w-[120px]' : 'flex-1'}
|
||||||
|
${action.destructive ? 'text-red-600 border-red-300 hover:bg-red-50 hover:border-red-400' : ''}
|
||||||
|
font-medium transition-all duration-200
|
||||||
|
`}
|
||||||
|
onClick={action.onClick}
|
||||||
|
>
|
||||||
|
{action.icon && <action.icon className="w-4 h-4 mr-2 flex-shrink-0" />}
|
||||||
|
<span className="truncate">{action.label}</span>
|
||||||
|
</Button>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* Secondary Actions - Compact horizontal layout */}
|
||||||
|
{secondaryActions.length > 0 && (
|
||||||
|
<div className="flex flex-wrap gap-2">
|
||||||
|
{secondaryActions.map((action, index) => (
|
||||||
|
<Button
|
||||||
|
key={`secondary-${index}`}
|
||||||
|
variant="outline"
|
||||||
|
size="sm"
|
||||||
|
className={`
|
||||||
|
flex-shrink-0 min-w-0
|
||||||
|
${action.destructive ? 'text-red-600 border-red-300 hover:bg-red-50 hover:border-red-400' : ''}
|
||||||
|
${secondaryActions.length > 3 ? 'text-xs px-2' : 'text-sm px-3'}
|
||||||
|
transition-all duration-200
|
||||||
|
`}
|
||||||
|
onClick={action.onClick}
|
||||||
|
>
|
||||||
|
{action.icon && <action.icon className={`
|
||||||
|
${secondaryActions.length > 3 ? 'w-3 h-3' : 'w-4 h-4'}
|
||||||
|
${action.label ? 'mr-1 sm:mr-2' : ''}
|
||||||
|
flex-shrink-0
|
||||||
|
`} />}
|
||||||
|
<span className={`
|
||||||
|
${secondaryActions.length > 3 ? 'hidden sm:inline' : ''}
|
||||||
|
truncate
|
||||||
|
`}>
|
||||||
|
{action.label}
|
||||||
|
</span>
|
||||||
|
</Button>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import { Plus, Search, Download, ShoppingCart, Truck, DollarSign, Calendar, Clock, CheckCircle, AlertCircle, Package, Eye, Loader } from 'lucide-react';
|
import { Plus, Search, Download, ShoppingCart, Truck, DollarSign, Calendar, Clock, CheckCircle, AlertCircle, Package, Eye, Loader, Edit, ArrowRight, Play, Pause, X, Save } from 'lucide-react';
|
||||||
import { Button, Input, Card, StatsGrid, StatusCard, getStatusColor, StatusModal } from '../../../../components/ui';
|
import { Button, Input, Card, StatsGrid, StatusCard, getStatusColor, StatusModal } from '../../../../components/ui';
|
||||||
import { formatters } from '../../../../components/ui/Stats/StatsPresets';
|
import { formatters } from '../../../../components/ui/Stats/StatsPresets';
|
||||||
import { PageHeader } from '../../../../components/layout';
|
import { PageHeader } from '../../../../components/layout';
|
||||||
@@ -20,6 +20,8 @@ const ProcurementPage: React.FC = () => {
|
|||||||
const [showForm, setShowForm] = useState(false);
|
const [showForm, setShowForm] = useState(false);
|
||||||
const [modalMode, setModalMode] = useState<'view' | 'edit'>('view');
|
const [modalMode, setModalMode] = useState<'view' | 'edit'>('view');
|
||||||
const [selectedPlan, setSelectedPlan] = useState<any>(null);
|
const [selectedPlan, setSelectedPlan] = useState<any>(null);
|
||||||
|
const [editingPlan, setEditingPlan] = useState<any>(null);
|
||||||
|
const [editFormData, setEditFormData] = useState<any>({});
|
||||||
|
|
||||||
const { currentTenant } = useTenantStore();
|
const { currentTenant } = useTenantStore();
|
||||||
const tenantId = currentTenant?.id || '';
|
const tenantId = currentTenant?.id || '';
|
||||||
@@ -38,6 +40,73 @@ const ProcurementPage: React.FC = () => {
|
|||||||
const updatePlanStatusMutation = useUpdateProcurementPlanStatus();
|
const updatePlanStatusMutation = useUpdateProcurementPlanStatus();
|
||||||
const triggerSchedulerMutation = useTriggerDailyScheduler();
|
const triggerSchedulerMutation = useTriggerDailyScheduler();
|
||||||
|
|
||||||
|
// Helper functions for stage transitions and edit functionality
|
||||||
|
const getNextStage = (currentStatus: string): string | null => {
|
||||||
|
const stageFlow: { [key: string]: string } = {
|
||||||
|
'draft': 'pending_approval',
|
||||||
|
'pending_approval': 'approved',
|
||||||
|
'approved': 'in_execution',
|
||||||
|
'in_execution': 'completed'
|
||||||
|
};
|
||||||
|
return stageFlow[currentStatus] || null;
|
||||||
|
};
|
||||||
|
|
||||||
|
const getStageActionConfig = (status: string) => {
|
||||||
|
const configs: { [key: string]: { label: string; icon: any; variant: 'primary' | 'outline'; color?: string } } = {
|
||||||
|
'draft': { label: 'Enviar a Aprobación', icon: ArrowRight, variant: 'primary' },
|
||||||
|
'pending_approval': { label: 'Aprobar', icon: CheckCircle, variant: 'primary' },
|
||||||
|
'approved': { label: 'Iniciar Ejecución', icon: Play, variant: 'primary' },
|
||||||
|
'in_execution': { label: 'Completar', icon: CheckCircle, variant: 'primary' }
|
||||||
|
};
|
||||||
|
return configs[status];
|
||||||
|
};
|
||||||
|
|
||||||
|
const canEdit = (status: string): boolean => {
|
||||||
|
return status === 'draft';
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleStageTransition = (planId: string, currentStatus: string) => {
|
||||||
|
const nextStage = getNextStage(currentStatus);
|
||||||
|
if (nextStage) {
|
||||||
|
updatePlanStatusMutation.mutate({
|
||||||
|
tenant_id: tenantId,
|
||||||
|
plan_id: planId,
|
||||||
|
status: nextStage as any
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleCancelPlan = (planId: string) => {
|
||||||
|
updatePlanStatusMutation.mutate({
|
||||||
|
tenant_id: tenantId,
|
||||||
|
plan_id: planId,
|
||||||
|
status: 'cancelled'
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleEditPlan = (plan: any) => {
|
||||||
|
setEditingPlan(plan);
|
||||||
|
setEditFormData({
|
||||||
|
special_requirements: plan.special_requirements || '',
|
||||||
|
planning_horizon_days: plan.planning_horizon_days || 14,
|
||||||
|
priority: plan.priority || 'medium'
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSaveEdit = () => {
|
||||||
|
// For now, we'll just update the special requirements since that's the main editable field
|
||||||
|
// In a real implementation, you might have a separate API endpoint for updating plan details
|
||||||
|
console.log('Saving plan edits:', editFormData);
|
||||||
|
setEditingPlan(null);
|
||||||
|
setEditFormData({});
|
||||||
|
// Here you would typically call an update API
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleCancelEdit = () => {
|
||||||
|
setEditingPlan(null);
|
||||||
|
setEditFormData({});
|
||||||
|
};
|
||||||
|
|
||||||
if (!tenantId) {
|
if (!tenantId) {
|
||||||
return (
|
return (
|
||||||
<div className="flex justify-center items-center h-64">
|
<div className="flex justify-center items-center h-64">
|
||||||
@@ -162,10 +231,24 @@ const ProcurementPage: React.FC = () => {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "trigger",
|
id: "trigger",
|
||||||
label: "Ejecutar Programador",
|
label: triggerSchedulerMutation.isPending ? "Ejecutando..." : "Ejecutar Programador",
|
||||||
variant: "outline" as const,
|
variant: "outline" as const,
|
||||||
icon: Calendar,
|
icon: triggerSchedulerMutation.isPending ? Loader : Calendar,
|
||||||
onClick: () => triggerSchedulerMutation.mutate(tenantId)
|
onClick: () => {
|
||||||
|
triggerSchedulerMutation.mutate(tenantId, {
|
||||||
|
onSuccess: (data) => {
|
||||||
|
console.log('✅ Scheduler ejecutado exitosamente:', data.message);
|
||||||
|
// Show success notification (if you have a notification system)
|
||||||
|
// toast.success(data.message);
|
||||||
|
},
|
||||||
|
onError: (error) => {
|
||||||
|
console.error('❌ Error ejecutando scheduler:', error);
|
||||||
|
// Show error notification
|
||||||
|
// toast.error('Error ejecutando el programador de compras');
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
disabled: triggerSchedulerMutation.isPending
|
||||||
}
|
}
|
||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
@@ -237,9 +320,9 @@ const ProcurementPage: React.FC = () => {
|
|||||||
</Card>
|
</Card>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Procurement Plans Grid */}
|
{/* Procurement Plans Grid - Mobile-Optimized */}
|
||||||
{activeTab === 'plans' && (
|
{activeTab === 'plans' && (
|
||||||
<div className="grid gap-4 md:grid-cols-2 lg:grid-cols-3">
|
<div className="grid gap-4 sm:grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-3">
|
||||||
{isPlansLoading ? (
|
{isPlansLoading ? (
|
||||||
<div className="col-span-full flex justify-center items-center h-32">
|
<div className="col-span-full flex justify-center items-center h-32">
|
||||||
<Loader className="w-8 h-8 animate-spin text-[var(--color-primary)]" />
|
<Loader className="w-8 h-8 animate-spin text-[var(--color-primary)]" />
|
||||||
@@ -247,50 +330,160 @@ const ProcurementPage: React.FC = () => {
|
|||||||
) : (
|
) : (
|
||||||
filteredPlans.map((plan) => {
|
filteredPlans.map((plan) => {
|
||||||
const statusConfig = getPlanStatusConfig(plan.status);
|
const statusConfig = getPlanStatusConfig(plan.status);
|
||||||
|
const nextStageConfig = getStageActionConfig(plan.status);
|
||||||
|
const isEditing = editingPlan?.id === plan.id;
|
||||||
|
const isEditable = canEdit(plan.status);
|
||||||
|
|
||||||
|
// Build actions array with proper priority hierarchy for better UX
|
||||||
|
const actions = [];
|
||||||
|
|
||||||
|
// Edit mode actions (highest priority when editing)
|
||||||
|
if (isEditing) {
|
||||||
|
actions.push(
|
||||||
|
{
|
||||||
|
label: 'Guardar',
|
||||||
|
icon: Save,
|
||||||
|
variant: 'primary' as const,
|
||||||
|
priority: 'primary' as const,
|
||||||
|
onClick: handleSaveEdit
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Cancelar',
|
||||||
|
icon: X,
|
||||||
|
variant: 'outline' as const,
|
||||||
|
priority: 'primary' as const,
|
||||||
|
destructive: true,
|
||||||
|
onClick: handleCancelEdit
|
||||||
|
}
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
// Primary action: Stage transition (most important)
|
||||||
|
if (nextStageConfig) {
|
||||||
|
actions.push({
|
||||||
|
label: nextStageConfig.label,
|
||||||
|
icon: nextStageConfig.icon,
|
||||||
|
variant: nextStageConfig.variant,
|
||||||
|
priority: 'primary' as const,
|
||||||
|
onClick: () => handleStageTransition(plan.id, plan.status)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Secondary actions: Edit and View
|
||||||
|
if (isEditable) {
|
||||||
|
actions.push({
|
||||||
|
label: 'Editar',
|
||||||
|
icon: Edit,
|
||||||
|
variant: 'outline' as const,
|
||||||
|
priority: 'secondary' as const,
|
||||||
|
onClick: () => handleEditPlan(plan)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
actions.push({
|
||||||
|
label: 'Ver',
|
||||||
|
icon: Eye,
|
||||||
|
variant: 'outline' as const,
|
||||||
|
priority: 'secondary' as const,
|
||||||
|
onClick: () => {
|
||||||
|
setSelectedPlan(plan);
|
||||||
|
setModalMode('view');
|
||||||
|
setShowForm(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Tertiary action: Cancel (least prominent, destructive)
|
||||||
|
if (!['completed', 'cancelled'].includes(plan.status)) {
|
||||||
|
actions.push({
|
||||||
|
label: 'Cancelar',
|
||||||
|
icon: X,
|
||||||
|
variant: 'outline' as const,
|
||||||
|
priority: 'tertiary' as const,
|
||||||
|
destructive: true,
|
||||||
|
onClick: () => handleCancelPlan(plan.id)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<StatusCard
|
<div key={plan.id} className="space-y-2">
|
||||||
key={plan.id}
|
<StatusCard
|
||||||
id={plan.plan_number}
|
id={plan.plan_number}
|
||||||
statusIndicator={statusConfig}
|
statusIndicator={statusConfig}
|
||||||
title={`Plan ${plan.plan_number}`}
|
title={`Plan ${plan.plan_number}`}
|
||||||
subtitle={new Date(plan.plan_date).toLocaleDateString('es-ES')}
|
subtitle={new Date(plan.plan_date).toLocaleDateString('es-ES')}
|
||||||
primaryValue={formatters.currency(plan.total_estimated_cost)}
|
primaryValue={formatters.currency(plan.total_estimated_cost)}
|
||||||
primaryValueLabel={`${plan.total_requirements} requerimientos`}
|
primaryValueLabel={`${plan.total_requirements} requerimientos`}
|
||||||
secondaryInfo={{
|
secondaryInfo={{
|
||||||
label: 'Período',
|
label: 'Período',
|
||||||
value: `${new Date(plan.plan_period_start).toLocaleDateString('es-ES')} - ${new Date(plan.plan_period_end).toLocaleDateString('es-ES')}`
|
value: `${new Date(plan.plan_period_start).toLocaleDateString('es-ES')} - ${new Date(plan.plan_period_end).toLocaleDateString('es-ES')}`
|
||||||
}}
|
}}
|
||||||
metadata={[
|
metadata={[
|
||||||
`${plan.planning_horizon_days} días de horizonte`,
|
`${plan.planning_horizon_days} días de horizonte`,
|
||||||
`Estrategia: ${plan.procurement_strategy}`,
|
`Estrategia: ${plan.procurement_strategy}`,
|
||||||
...(plan.special_requirements ? [`"${plan.special_requirements}"`] : [])
|
...(plan.special_requirements ? [`"${plan.special_requirements}"`] : [])
|
||||||
]}
|
]}
|
||||||
actions={[
|
actions={actions}
|
||||||
{
|
/>
|
||||||
label: 'Ver',
|
|
||||||
icon: Eye,
|
{/* Inline Edit Form for Draft Plans */}
|
||||||
variant: 'outline',
|
{isEditing && (
|
||||||
onClick: () => {
|
<Card className="p-4 border-l-4 border-l-[var(--color-primary)] bg-[var(--color-primary)]/5">
|
||||||
setSelectedPlan(plan);
|
<h4 className="text-sm font-semibold text-[var(--text-primary)] mb-3">
|
||||||
setModalMode('view');
|
Editando Plan {plan.plan_number}
|
||||||
setShowForm(true);
|
</h4>
|
||||||
}
|
<div className="space-y-3">
|
||||||
},
|
<div>
|
||||||
...(plan.status === 'pending_approval' ? [{
|
<label className="block text-xs font-medium text-[var(--text-secondary)] mb-1">
|
||||||
label: 'Aprobar',
|
Requerimientos Especiales
|
||||||
icon: CheckCircle,
|
</label>
|
||||||
variant: 'outline' as const,
|
<textarea
|
||||||
onClick: () => {
|
value={editFormData.special_requirements}
|
||||||
updatePlanStatusMutation.mutate({
|
onChange={(e) => setEditFormData((prev: any) => ({ ...prev, special_requirements: e.target.value }))}
|
||||||
tenant_id: tenantId,
|
placeholder="Ingrese requerimientos especiales para este plan..."
|
||||||
plan_id: plan.id,
|
className="w-full px-3 py-2 text-sm border border-[var(--border-primary)] rounded-lg
|
||||||
status: 'approved'
|
bg-[var(--bg-primary)] text-[var(--text-primary)] placeholder-[var(--text-tertiary)]
|
||||||
});
|
focus:ring-2 focus:ring-[var(--color-primary)]/20 focus:border-[var(--color-primary)]
|
||||||
}
|
transition-colors duration-200 resize-vertical min-h-[60px]"
|
||||||
}] : [])
|
rows={2}
|
||||||
]}
|
/>
|
||||||
/>
|
</div>
|
||||||
|
<div className="grid grid-cols-2 gap-3">
|
||||||
|
<div>
|
||||||
|
<label className="block text-xs font-medium text-[var(--text-secondary)] mb-1">
|
||||||
|
Días de Horizonte
|
||||||
|
</label>
|
||||||
|
<Input
|
||||||
|
type="number"
|
||||||
|
value={editFormData.planning_horizon_days}
|
||||||
|
onChange={(e) => setEditFormData((prev: any) => ({ ...prev, planning_horizon_days: parseInt(e.target.value) }))}
|
||||||
|
min="1"
|
||||||
|
max="365"
|
||||||
|
className="w-full"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label className="block text-xs font-medium text-[var(--text-secondary)] mb-1">
|
||||||
|
Prioridad
|
||||||
|
</label>
|
||||||
|
<select
|
||||||
|
value={editFormData.priority}
|
||||||
|
onChange={(e) => setEditFormData((prev: any) => ({ ...prev, priority: e.target.value }))}
|
||||||
|
className="w-full px-3 py-2 text-sm border border-[var(--border-primary)] rounded-lg
|
||||||
|
bg-[var(--bg-primary)] text-[var(--text-primary)]
|
||||||
|
focus:ring-2 focus:ring-[var(--color-primary)]/20 focus:border-[var(--color-primary)]
|
||||||
|
transition-colors duration-200"
|
||||||
|
>
|
||||||
|
<option value="low">Baja</option>
|
||||||
|
<option value="medium">Media</option>
|
||||||
|
<option value="high">Alta</option>
|
||||||
|
<option value="urgent">Urgente</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Card>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
})
|
})
|
||||||
)}
|
)}
|
||||||
|
|||||||
Reference in New Issue
Block a user