- DynamicPricingPage: add 'Нагрузка' tab with monthly occupancy bar chart (2025/2026 data), year selector, summary stats, and editable occupancy-based pricing rules (threshold ranges → price modifiers) - HousekeepingPage: add maintenance note button (wrench icon) on task cards — housekeeper can report broken items with a description that gets sent to technical service; notes displayed in orange badge - BookingWidgetPage: fix 'Забронировать' button with full form flow (browse → form → success), add configurable form fields (required/optional/custom), add additional services toggle in settings and at checkout, add extra beds + children count in guest selector with auto-pricing Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
503 lines
23 KiB
TypeScript
503 lines
23 KiB
TypeScript
import { useState } from 'react'
|
||
import { CheckCircle2, Clock, Sparkles, User, ListChecks, Settings2, Save, Wrench, X as XIcon, Send } from 'lucide-react'
|
||
import { MOCK_HK_TASKS } from '../data/mockData'
|
||
import type { HousekeepingTask } from '../types'
|
||
import { cn } from '../lib/utils'
|
||
import { Badge } from '../components/ui/Badge'
|
||
|
||
function Toggle({ on, onChange }: { on: boolean; onChange: () => void }) {
|
||
return (
|
||
<button
|
||
onClick={onChange}
|
||
className={cn('relative w-10 h-5.5 rounded-full transition-colors shrink-0 h-[22px]', on ? 'bg-brand-600' : 'bg-slate-200 dark:bg-slate-600')}
|
||
>
|
||
<div className={cn('absolute top-0.5 w-4.5 h-4.5 rounded-full bg-white shadow-sm transition-transform w-[18px] h-[18px]', on ? 'left-[20px]' : 'left-0.5')} />
|
||
</button>
|
||
)
|
||
}
|
||
|
||
type Column = 'pending' | 'in_progress' | 'done'
|
||
|
||
const COLUMNS: { id: Column; label: string; icon: React.ElementType; color: string }[] = [
|
||
{ id: 'pending', label: 'Ожидают', icon: Clock, color: 'text-amber-600 dark:text-amber-400' },
|
||
{ id: 'in_progress', label: 'В процессе', icon: Sparkles, color: 'text-blue-600 dark:text-blue-400' },
|
||
{ id: 'done', label: 'Готово', icon: CheckCircle2, color: 'text-emerald-600 dark:text-emerald-400' },
|
||
]
|
||
|
||
const PRIORITY_COLORS = {
|
||
high: 'bg-red-100 text-red-700 dark:bg-red-900/30 dark:text-red-300',
|
||
normal: 'bg-slate-100 text-slate-700 dark:bg-slate-700 dark:text-slate-300',
|
||
low: 'bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-300',
|
||
}
|
||
|
||
const PRIORITY_LABELS = { high: 'Срочно', normal: 'Обычный', low: 'Низкий' }
|
||
|
||
const TYPE_COLORS = {
|
||
cleaning: 'bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-300',
|
||
inspection: 'bg-amber-100 text-amber-700 dark:bg-amber-900/30 dark:text-amber-300',
|
||
maintenance: 'bg-orange-100 text-orange-700 dark:bg-orange-900/30 dark:text-orange-300',
|
||
}
|
||
|
||
const TYPE_LABELS = {
|
||
cleaning: 'Уборка',
|
||
inspection: 'Проверка',
|
||
maintenance: 'Ремонт',
|
||
}
|
||
|
||
export function HousekeepingPage() {
|
||
const [tasks, setTasks] = useState<HousekeepingTask[]>(MOCK_HK_TASKS)
|
||
const [activeTab, setActiveTab] = useState<'tasks' | 'plans'>('tasks')
|
||
const [planSaved, setPlanSaved] = useState(false)
|
||
|
||
// Cleaning plan settings
|
||
const [plans, setPlans] = useState({
|
||
checkoutAuto: true,
|
||
checkoutPriority: 'high' as 'high' | 'normal',
|
||
checkoutInspection: true,
|
||
|
||
dailyEnabled: true,
|
||
dailyIntervalDays: 1,
|
||
dailyStartFromDay: 1,
|
||
|
||
onDemandEnabled: true,
|
||
onDemandPriority: 'normal' as 'high' | 'normal' | 'low',
|
||
|
||
deepCleanEnabled: false,
|
||
deepCleanEveryDays: 7,
|
||
|
||
inspectionAfterClean: true,
|
||
autoAssign: false,
|
||
})
|
||
|
||
const setP = <K extends keyof typeof plans>(k: K, v: typeof plans[K]) =>
|
||
setPlans(prev => ({ ...prev, [k]: v }))
|
||
|
||
const savePlans = () => {
|
||
setPlanSaved(true)
|
||
setTimeout(() => setPlanSaved(false), 2000)
|
||
}
|
||
|
||
const updateStatus = (id: string, status: HousekeepingTask['status']) => {
|
||
setTasks(prev => prev.map(t =>
|
||
t.id === id
|
||
? { ...t, status, completedAt: status === 'done' ? new Date().toISOString() : undefined }
|
||
: t,
|
||
))
|
||
}
|
||
|
||
const addMaintenanceNote = (id: string, note: string) => {
|
||
setTasks(prev => prev.map(t => t.id === id ? { ...t, maintenanceNote: note } : t))
|
||
}
|
||
|
||
const total = tasks.length
|
||
const done = tasks.filter(t => t.status === 'done').length
|
||
|
||
return (
|
||
<div className="p-4 md:p-6 space-y-5">
|
||
{/* Header */}
|
||
<div className="flex items-start justify-between">
|
||
<div className="flex-1">
|
||
<h1 className="text-xl font-bold text-slate-900 dark:text-slate-100">Уборка и обслуживание</h1>
|
||
{activeTab === 'tasks' && (
|
||
<div className="flex items-center gap-3 mt-1.5">
|
||
<div className="flex-1 bg-slate-200 dark:bg-slate-700 rounded-full h-2">
|
||
<div
|
||
className="h-2 rounded-full bg-emerald-500 transition-all duration-500"
|
||
style={{ width: total ? `${(done / total) * 100}%` : '0%' }}
|
||
/>
|
||
</div>
|
||
<span className="text-sm text-slate-600 dark:text-slate-400 shrink-0">
|
||
{done} / {total} завершено
|
||
</span>
|
||
</div>
|
||
)}
|
||
</div>
|
||
</div>
|
||
|
||
{/* Tabs */}
|
||
<div className="flex border-b border-slate-200 dark:border-slate-700">
|
||
{([
|
||
{ id: 'tasks' as const, label: 'Задачи на сегодня', icon: ListChecks },
|
||
{ id: 'plans' as const, label: 'Планы уборки', icon: Settings2 },
|
||
]).map(t => (
|
||
<button
|
||
key={t.id}
|
||
onClick={() => setActiveTab(t.id)}
|
||
className={cn(
|
||
'flex items-center gap-1.5 px-4 py-2.5 text-sm font-medium border-b-2 -mb-px transition-colors',
|
||
activeTab === t.id
|
||
? 'border-brand-600 text-brand-600 dark:text-brand-400 dark:border-brand-400'
|
||
: 'border-transparent text-slate-500 dark:text-slate-400 hover:text-slate-700 dark:hover:text-slate-300',
|
||
)}
|
||
>
|
||
<t.icon size={14} />
|
||
{t.label}
|
||
</button>
|
||
))}
|
||
</div>
|
||
|
||
{/* ── Tasks tab ── */}
|
||
{activeTab === 'tasks' && (
|
||
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
|
||
{COLUMNS.map(col => {
|
||
const colTasks = tasks.filter(t => t.status === col.id)
|
||
const Icon = col.icon
|
||
return (
|
||
<div key={col.id} className="space-y-3">
|
||
<div className="flex items-center gap-2">
|
||
<Icon size={16} className={col.color} />
|
||
<h3 className="font-semibold text-slate-700 dark:text-slate-300">{col.label}</h3>
|
||
<span className="ml-auto text-xs font-bold px-2 py-0.5 rounded-full bg-slate-200 dark:bg-slate-700 text-slate-600 dark:text-slate-400">
|
||
{colTasks.length}
|
||
</span>
|
||
</div>
|
||
<div className="space-y-2.5">
|
||
{colTasks.map(task => (
|
||
<TaskCard key={task.id} task={task} onStatusChange={updateStatus} onMaintenanceNote={addMaintenanceNote} />
|
||
))}
|
||
{colTasks.length === 0 && (
|
||
<div className="rounded-xl border-2 border-dashed border-slate-200 dark:border-slate-700 py-8 text-center">
|
||
<p className="text-sm text-slate-400 dark:text-slate-500">Пусто</p>
|
||
</div>
|
||
)}
|
||
</div>
|
||
</div>
|
||
)
|
||
})}
|
||
</div>
|
||
)}
|
||
|
||
{/* ── Plans tab ── */}
|
||
{activeTab === 'plans' && (
|
||
<div className="max-w-2xl space-y-5">
|
||
|
||
{/* Checkout cleaning */}
|
||
<div className="card p-4 space-y-3">
|
||
<div className="flex items-center justify-between">
|
||
<div>
|
||
<p className="font-semibold text-slate-900 dark:text-slate-100">Уборка при выезде</p>
|
||
<p className="text-xs text-slate-500 dark:text-slate-400 mt-0.5">
|
||
Автоматически создавать задачу на уборку, как только гость освобождает номер
|
||
</p>
|
||
</div>
|
||
<Toggle on={plans.checkoutAuto} onChange={() => setP('checkoutAuto', !plans.checkoutAuto)} />
|
||
</div>
|
||
{plans.checkoutAuto && (
|
||
<div className="pl-1 space-y-3 border-t border-slate-100 dark:border-slate-700 pt-3">
|
||
<div>
|
||
<label className="block text-xs font-medium text-slate-600 dark:text-slate-400 mb-1.5">Приоритет задачи</label>
|
||
<div className="flex gap-2">
|
||
{([['high', 'Срочно'], ['normal', 'Обычный']] as const).map(([v, l]) => (
|
||
<button
|
||
key={v}
|
||
onClick={() => setP('checkoutPriority', v)}
|
||
className={cn(
|
||
'px-3 py-1.5 rounded-lg text-xs font-medium border transition-colors',
|
||
plans.checkoutPriority === v
|
||
? v === 'high' ? 'bg-red-500 border-red-500 text-white' : 'bg-brand-600 border-brand-600 text-white'
|
||
: 'bg-white dark:bg-slate-700 border-slate-200 dark:border-slate-600 text-slate-600 dark:text-slate-300',
|
||
)}
|
||
>
|
||
{l}
|
||
</button>
|
||
))}
|
||
</div>
|
||
</div>
|
||
<div className="flex items-center justify-between">
|
||
<div>
|
||
<p className="text-sm text-slate-700 dark:text-slate-300">Инспекция после уборки</p>
|
||
<p className="text-xs text-slate-500 dark:text-slate-400">Создавать задачу проверки для старшей горничной</p>
|
||
</div>
|
||
<Toggle on={plans.checkoutInspection} onChange={() => setP('checkoutInspection', !plans.checkoutInspection)} />
|
||
</div>
|
||
</div>
|
||
)}
|
||
</div>
|
||
|
||
{/* Daily cleaning */}
|
||
<div className="card p-4 space-y-3">
|
||
<div className="flex items-center justify-between">
|
||
<div>
|
||
<p className="font-semibold text-slate-900 dark:text-slate-100">Ежедневная уборка</p>
|
||
<p className="text-xs text-slate-500 dark:text-slate-400 mt-0.5">
|
||
Регулярная уборка в номерах с проживающими гостями
|
||
</p>
|
||
</div>
|
||
<Toggle on={plans.dailyEnabled} onChange={() => setP('dailyEnabled', !plans.dailyEnabled)} />
|
||
</div>
|
||
{plans.dailyEnabled && (
|
||
<div className="pl-1 space-y-3 border-t border-slate-100 dark:border-slate-700 pt-3">
|
||
<div className="grid grid-cols-2 gap-4">
|
||
<div>
|
||
<label className="block text-xs font-medium text-slate-600 dark:text-slate-400 mb-1.5">
|
||
Каждые N дней
|
||
</label>
|
||
<div className="flex gap-1.5 flex-wrap">
|
||
{[1, 2, 3, 7].map(n => (
|
||
<button
|
||
key={n}
|
||
onClick={() => setP('dailyIntervalDays', n)}
|
||
className={cn(
|
||
'px-3 py-1.5 rounded-lg text-xs font-medium border transition-colors',
|
||
plans.dailyIntervalDays === n
|
||
? 'bg-brand-600 border-brand-600 text-white'
|
||
: 'bg-white dark:bg-slate-700 border-slate-200 dark:border-slate-600 text-slate-600 dark:text-slate-300',
|
||
)}
|
||
>
|
||
{n === 1 ? 'Ежедневно' : `${n} дня`}
|
||
</button>
|
||
))}
|
||
</div>
|
||
</div>
|
||
<div>
|
||
<label className="block text-xs font-medium text-slate-600 dark:text-slate-400 mb-1.5">
|
||
Начинать с дня заезда №
|
||
</label>
|
||
<input
|
||
type="number" min={1} max={10}
|
||
className="input w-20 text-sm"
|
||
value={plans.dailyStartFromDay}
|
||
onChange={e => setP('dailyStartFromDay', Math.max(1, parseInt(e.target.value) || 1))}
|
||
/>
|
||
<p className="text-xs text-slate-400 mt-1">
|
||
Уборка начнётся на {plans.dailyStartFromDay}-й день проживания
|
||
</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
)}
|
||
</div>
|
||
|
||
{/* On-demand cleaning */}
|
||
<div className="card p-4 space-y-3">
|
||
<div className="flex items-center justify-between">
|
||
<div>
|
||
<p className="font-semibold text-slate-900 dark:text-slate-100">Уборка по запросу гостя</p>
|
||
<p className="text-xs text-slate-500 dark:text-slate-400 mt-0.5">
|
||
Гость может запросить уборку через QR-код или мобильное приложение
|
||
</p>
|
||
</div>
|
||
<Toggle on={plans.onDemandEnabled} onChange={() => setP('onDemandEnabled', !plans.onDemandEnabled)} />
|
||
</div>
|
||
{plans.onDemandEnabled && (
|
||
<div className="pl-1 border-t border-slate-100 dark:border-slate-700 pt-3">
|
||
<label className="block text-xs font-medium text-slate-600 dark:text-slate-400 mb-1.5">Приоритет</label>
|
||
<div className="flex gap-2">
|
||
{([['high', 'Срочно'], ['normal', 'Обычный'], ['low', 'Низкий']] as const).map(([v, l]) => (
|
||
<button
|
||
key={v}
|
||
onClick={() => setP('onDemandPriority', v)}
|
||
className={cn(
|
||
'px-3 py-1.5 rounded-lg text-xs font-medium border transition-colors',
|
||
plans.onDemandPriority === v
|
||
? 'bg-brand-600 border-brand-600 text-white'
|
||
: 'bg-white dark:bg-slate-700 border-slate-200 dark:border-slate-600 text-slate-600 dark:text-slate-300',
|
||
)}
|
||
>
|
||
{l}
|
||
</button>
|
||
))}
|
||
</div>
|
||
</div>
|
||
)}
|
||
</div>
|
||
|
||
{/* Deep cleaning */}
|
||
<div className="card p-4 space-y-3">
|
||
<div className="flex items-center justify-between">
|
||
<div>
|
||
<p className="font-semibold text-slate-900 dark:text-slate-100">Генеральная уборка</p>
|
||
<p className="text-xs text-slate-500 dark:text-slate-400 mt-0.5">
|
||
Глубокая уборка с чисткой мебели, мытьём окон и полной сменой постельного белья
|
||
</p>
|
||
</div>
|
||
<Toggle on={plans.deepCleanEnabled} onChange={() => setP('deepCleanEnabled', !plans.deepCleanEnabled)} />
|
||
</div>
|
||
{plans.deepCleanEnabled && (
|
||
<div className="pl-1 border-t border-slate-100 dark:border-slate-700 pt-3 flex items-center gap-3">
|
||
<label className="text-xs font-medium text-slate-600 dark:text-slate-400 shrink-0">Проводить каждые</label>
|
||
<input
|
||
type="number" min={1} max={30}
|
||
className="input w-20 text-sm"
|
||
value={plans.deepCleanEveryDays}
|
||
onChange={e => setP('deepCleanEveryDays', Math.max(1, parseInt(e.target.value) || 7))}
|
||
/>
|
||
<span className="text-xs text-slate-500 dark:text-slate-400">дней</span>
|
||
</div>
|
||
)}
|
||
</div>
|
||
|
||
{/* Inspection after cleaning */}
|
||
<div className="card p-4">
|
||
<div className="flex items-center justify-between">
|
||
<div>
|
||
<p className="font-semibold text-slate-900 dark:text-slate-100">Проверка после уборки</p>
|
||
<p className="text-xs text-slate-500 dark:text-slate-400 mt-0.5">
|
||
После завершения любой уборки создавать задачу инспекции для старшей горничной
|
||
</p>
|
||
</div>
|
||
<Toggle on={plans.inspectionAfterClean} onChange={() => setP('inspectionAfterClean', !plans.inspectionAfterClean)} />
|
||
</div>
|
||
</div>
|
||
|
||
{/* Auto assign */}
|
||
<div className="card p-4">
|
||
<div className="flex items-center justify-between">
|
||
<div>
|
||
<p className="font-semibold text-slate-900 dark:text-slate-100">Автоназначение горничной</p>
|
||
<p className="text-xs text-slate-500 dark:text-slate-400 mt-0.5">
|
||
Автоматически назначать ответственную горничную по расписанию смен (без этой опции — задачи назначаются вручную)
|
||
</p>
|
||
</div>
|
||
<Toggle on={plans.autoAssign} onChange={() => setP('autoAssign', !plans.autoAssign)} />
|
||
</div>
|
||
</div>
|
||
|
||
<div className="flex justify-end">
|
||
<button onClick={savePlans} className="btn-primary">
|
||
<Save size={14} />
|
||
{planSaved ? 'Сохранено!' : 'Сохранить планы'}
|
||
</button>
|
||
</div>
|
||
</div>
|
||
)}
|
||
</div>
|
||
)
|
||
}
|
||
|
||
function TaskCard({ task, onStatusChange, onMaintenanceNote }: {
|
||
task: HousekeepingTask
|
||
onStatusChange: (id: string, status: HousekeepingTask['status']) => void
|
||
onMaintenanceNote: (id: string, note: string) => void
|
||
}) {
|
||
const [reportOpen, setReportOpen] = useState(false)
|
||
const [reportText, setReportText] = useState('')
|
||
|
||
const submitReport = () => {
|
||
if (!reportText.trim()) return
|
||
onMaintenanceNote(task.id, reportText.trim())
|
||
setReportText('')
|
||
setReportOpen(false)
|
||
}
|
||
|
||
return (
|
||
<div className={cn(
|
||
'card p-3.5 space-y-2.5 transition-all',
|
||
task.status === 'done' && 'opacity-70',
|
||
)}>
|
||
<div className="flex items-center justify-between">
|
||
<span className="text-xl font-bold text-slate-900 dark:text-slate-100">
|
||
№{task.roomNumber}
|
||
</span>
|
||
<Badge className={PRIORITY_COLORS[task.priority]}>
|
||
{PRIORITY_LABELS[task.priority]}
|
||
</Badge>
|
||
</div>
|
||
|
||
<div className="flex gap-1.5 flex-wrap">
|
||
<Badge className={TYPE_COLORS[task.type]}>
|
||
{TYPE_LABELS[task.type]}
|
||
</Badge>
|
||
</div>
|
||
|
||
{task.notes && (
|
||
<p className="text-xs text-slate-500 dark:text-slate-400 bg-slate-50 dark:bg-slate-700/40 rounded-lg p-2">
|
||
{task.notes}
|
||
</p>
|
||
)}
|
||
|
||
{task.maintenanceNote && (
|
||
<div className="flex items-start gap-1.5 bg-orange-50 dark:bg-orange-900/20 border border-orange-200 dark:border-orange-800 rounded-lg p-2">
|
||
<Wrench size={11} className="text-orange-500 mt-0.5 shrink-0" />
|
||
<p className="text-xs text-orange-700 dark:text-orange-300">{task.maintenanceNote}</p>
|
||
</div>
|
||
)}
|
||
|
||
{task.assignedToName && (
|
||
<div className="flex items-center gap-1.5 text-xs text-slate-500 dark:text-slate-400">
|
||
<User size={11} />
|
||
{task.assignedToName}
|
||
</div>
|
||
)}
|
||
|
||
{task.completedAt && (
|
||
<p className="text-xs text-emerald-600 dark:text-emerald-400">
|
||
Завершено в {new Date(task.completedAt).toLocaleTimeString('ru-RU', { hour: '2-digit', minute: '2-digit' })}
|
||
</p>
|
||
)}
|
||
|
||
{/* Maintenance report form */}
|
||
{reportOpen && (
|
||
<div className="border-t border-slate-100 dark:border-slate-700 pt-2 space-y-1.5">
|
||
<div className="flex items-center justify-between">
|
||
<p className="text-xs font-medium text-orange-600 dark:text-orange-400 flex items-center gap-1">
|
||
<Wrench size={11} /> Сообщить о поломке
|
||
</p>
|
||
<button onClick={() => setReportOpen(false)} className="text-slate-400 hover:text-slate-600">
|
||
<XIcon size={13} />
|
||
</button>
|
||
</div>
|
||
<textarea
|
||
autoFocus
|
||
className="w-full text-xs border border-slate-200 dark:border-slate-600 rounded-lg p-2 bg-white dark:bg-slate-700 text-slate-700 dark:text-slate-300 resize-none focus:outline-none focus:border-orange-400"
|
||
rows={2}
|
||
placeholder="Опишите неисправность (напр. Не работает кондиционер, сломана ручка двери...)"
|
||
value={reportText}
|
||
onChange={e => setReportText(e.target.value)}
|
||
onKeyDown={e => { if (e.key === 'Enter' && e.ctrlKey) submitReport() }}
|
||
/>
|
||
<button
|
||
onClick={submitReport}
|
||
disabled={!reportText.trim()}
|
||
className="w-full flex items-center justify-center gap-1 text-xs py-1.5 rounded-lg bg-orange-500 text-white font-medium hover:bg-orange-600 disabled:opacity-40 disabled:cursor-not-allowed transition-colors"
|
||
>
|
||
<Send size={11} /> Отправить технической службе
|
||
</button>
|
||
</div>
|
||
)}
|
||
|
||
{/* Actions */}
|
||
<div className="flex gap-1.5 pt-1">
|
||
{task.status === 'pending' && (
|
||
<button
|
||
onClick={() => onStatusChange(task.id, 'in_progress')}
|
||
className="flex-1 text-xs py-1.5 rounded-lg bg-blue-50 dark:bg-blue-900/20 text-blue-700 dark:text-blue-300 font-medium hover:bg-blue-100 dark:hover:bg-blue-900/30 transition-colors"
|
||
>
|
||
Начать
|
||
</button>
|
||
)}
|
||
{task.status === 'in_progress' && (
|
||
<button
|
||
onClick={() => onStatusChange(task.id, 'done')}
|
||
className="flex-1 text-xs py-1.5 rounded-lg bg-emerald-50 dark:bg-emerald-900/20 text-emerald-700 dark:text-emerald-300 font-medium hover:bg-emerald-100 dark:hover:bg-emerald-900/30 transition-colors"
|
||
>
|
||
Завершить
|
||
</button>
|
||
)}
|
||
{task.status === 'done' && (
|
||
<button
|
||
onClick={() => onStatusChange(task.id, 'pending')}
|
||
className="flex-1 text-xs py-1.5 rounded-lg bg-slate-50 dark:bg-slate-700 text-slate-600 dark:text-slate-400 font-medium hover:bg-slate-100 dark:hover:bg-slate-600 transition-colors"
|
||
>
|
||
Вернуть
|
||
</button>
|
||
)}
|
||
{!reportOpen && (
|
||
<button
|
||
onClick={() => setReportOpen(true)}
|
||
title="Сообщить о поломке"
|
||
className={cn(
|
||
'text-xs py-1.5 px-2.5 rounded-lg font-medium transition-colors flex items-center gap-1',
|
||
task.maintenanceNote
|
||
? 'bg-orange-100 dark:bg-orange-900/30 text-orange-600 dark:text-orange-400'
|
||
: 'bg-slate-50 dark:bg-slate-700 text-slate-500 dark:text-slate-400 hover:bg-orange-50 dark:hover:bg-orange-900/20 hover:text-orange-600',
|
||
)}
|
||
>
|
||
<Wrench size={11} />
|
||
</button>
|
||
)}
|
||
</div>
|
||
</div>
|
||
)
|
||
}
|