supersam/src/components/orders/CalledPanel.jsx

162 lines
5.7 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import React, { useState } from "react";
import { supabase } from "../../supabaseClient";
import { Button } from "../UI/Button";
import { CallDateSelect, CallTimeSelect, toDateInputValue, toTimeInputValue } from "./CallDateTime";
const CalledPanel = ({ order, onUpdate }) => {
const [busy, setBusy] = useState(false);
const [editing, setEditing] = useState(false);
const [comment, setComment] = useState(order?.calledComment || order?.called_comment || "");
const [callDate, setCallDate] = useState("");
const [callTime, setCallTime] = useState("");
const isCalled = !!order?.called;
const formatCalledAt = (ts) => {
if (!ts) return "";
try {
return new Date(ts).toLocaleString("ru-RU", {
day: "2-digit",
month: "2-digit",
year: "numeric",
hour: "2-digit",
minute: "2-digit",
});
} catch {
return "";
}
};
// Open add form with date+time defaulted to NOW for fast entry.
const startAdd = () => {
const now = new Date();
setComment("");
setCallDate(toDateInputValue(now));
setCallTime(toTimeInputValue(now));
setEditing(true);
};
// Open edit form for an existing call, pre-filled from stored values (or now).
const startEdit = () => {
setComment(order?.calledComment || order?.called_comment || "");
if (order?.calledAt || order?.called_at) {
const d = new Date(order.calledAt || order.called_at);
setCallDate(toDateInputValue(d));
setCallTime(toTimeInputValue(d));
} else {
const now = new Date();
setCallDate(toDateInputValue(now));
setCallTime(toTimeInputValue(now));
}
setEditing(true);
};
const save = async (newCalled) => {
if (busy || !order?.id) return;
setBusy(true);
try {
let calledAt = null;
if (newCalled) {
if (callDate && callTime) {
calledAt = new Date(`${callDate}T${callTime}:00`).toISOString();
} else {
calledAt = new Date().toISOString();
}
}
const { error } = await supabase
.from("order_groups")
.update({
called: newCalled,
called_at: calledAt,
called_comment: newCalled ? (comment.trim() || null) : null,
})
.eq("id", order.id);
if (error) {
console.warn("[CalledPanel] update error", error);
} else {
setEditing(false);
if (onUpdate) await onUpdate();
}
} finally {
setBusy(false);
}
};
// Editing form: app-styled date/time pickers + comment + save/reset/cancel.
if (editing) {
return (
<div className="space-y-3">
<div className="flex flex-wrap gap-3">
<CallDateSelect value={callDate} onChange={setCallDate} />
<CallTimeSelect value={callTime} onChange={setCallTime} />
</div>
<div>
<label className="mb-1 block text-xs font-medium text-[var(--color-text-muted)]">Комментарий</label>
<textarea
value={comment}
onChange={(e) => setComment(e.target.value)}
placeholder="Результат звонка..."
rows={2}
className="w-full rounded-2xl border border-[var(--color-border)] bg-[var(--color-surface)] px-4 py-3 text-sm text-[var(--color-text)] placeholder:text-[var(--color-text-muted)] focus:border-[var(--color-accent)] focus:outline-none resize-none"
/>
</div>
<div className="flex flex-wrap gap-2">
<Button variant="primary" size="sm" onClick={() => save(true)} disabled={busy}>
{busy ? "Сохраняем..." : "Сохранить"}
</Button>
{isCalled && (
<Button variant="ghost" size="sm" onClick={() => save(false)} disabled={busy}>
Сбросить
</Button>
)}
<Button variant="secondary" size="sm" onClick={() => setEditing(false)} disabled={busy}>
Отмена
</Button>
</div>
</div>
);
}
return (
<div className="space-y-2">
<div className="flex flex-wrap items-center gap-2">
{isCalled ? (
<>
<Button variant="primary" size="sm" disabled>
📞 Звонили
</Button>
<Button variant="secondary" size="sm" onClick={() => save(false)} disabled={busy}>
Не звонили
</Button>
<Button variant="ghost" size="sm" onClick={startEdit} disabled={busy} title="Изменить дату или комментарий">
✎ Изменить
</Button>
{order?.calledAt || order?.called_at ? (
<span className="text-xs text-[var(--color-text-muted)]">{formatCalledAt(order.calledAt || order.called_at)}</span>
) : null}
{order?.calledComment || order?.called_comment ? (
<span className="text-xs text-[var(--color-text-muted)] italic">«{order.calledComment || order.called_comment}»</span>
) : null}
</>
) : (
<>
<Button variant="primary" size="sm" onClick={() => save(true)} disabled={busy}>
{busy ? "Сохраняем..." : "📞 Звонили"}
</Button>
<Button variant="ghost" size="sm" onClick={startAdd} disabled={busy} title="Записать дату и время звонка">
✎ Дата/комментарий
</Button>
</>
)}
</div>
{!isCalled && (
<p className="text-xs text-[var(--color-text-muted)]">
Нажмите «Звонили», чтобы отметить звонок прямо сейчас.
</p>
)}
</div>
);
};
export { CalledPanel };
export default CalledPanel;