Files
lms-sb/src/components/admin/homework-editor.tsx
T
admins c94a8dafa9 style(lms): синхронизировать типографику со шкалой ДС-2 (+2px)
Переопределены токены шкалы Tailwind (--text-xs…--text-5xl) на +2px,
базовый размер body 18px, размеры компонентных классов (.btn-aubade,
.tag-aubade, .admin-sidebar-nav-link) и инлайновые fontSize приведены
к канону дизайн-системы ДС-2. Rem-база (html 16px) не тронута —
спейсинг и сетка не затронуты, растёт только текст.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-18 17:14:16 +05:00

95 lines
3.2 KiB
TypeScript
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.
"use client";
import { useState, useTransition } from "react";
import { saveHomework, deleteHomework } from "@/lib/actions/homework-actions";
interface Props {
lessonId: string;
initial: { id: string; description: string } | null;
}
export function HomeworkEditor({ lessonId, initial }: Props) {
const [editing, setEditing] = useState(!initial);
const [text, setText] = useState(initial?.description ?? "");
const [saved, setSaved] = useState(false);
const [pending, startTransition] = useTransition();
const inputStyle = {
border: "2px solid var(--border)",
background: "var(--background)",
outline: "none",
width: "100%",
padding: "0.5rem 0.75rem",
fontSize: "16px",
fontFamily: "inherit",
resize: "vertical" as const,
minHeight: "120px",
};
function handleSave() {
if (!text.trim()) return;
startTransition(async () => {
await saveHomework(lessonId, text.trim());
setSaved(true);
setEditing(false);
setTimeout(() => setSaved(false), 2000);
});
}
function handleDelete() {
if (!confirm("Удалить домашнее задание? Все сданные работы будут удалены.")) return;
startTransition(async () => {
await deleteHomework(lessonId);
setText("");
setEditing(true);
});
}
if (!editing && initial) {
return (
<div className="space-y-3">
<div className="px-4 py-3 text-sm whitespace-pre-wrap" style={{ border: "2px solid var(--border)", background: "var(--color-surface)" }}>
{text || initial.description}
</div>
<div className="flex gap-2">
<button onClick={() => setEditing(true)} className="btn-aubade text-xs px-3 py-1.5">
Редактировать
</button>
<button onClick={handleDelete} disabled={pending} className="text-xs px-3 py-1.5" style={{ color: "oklch(0.577 0.245 27.325)" }}>
Удалить ДЗ
</button>
{saved && <span className="text-xs self-center" style={{ color: "var(--muted-foreground)" }}> Сохранено</span>}
</div>
</div>
);
}
return (
<div className="space-y-3">
<textarea
value={text}
onChange={(e) => setText(e.target.value)}
style={inputStyle}
placeholder="Опишите задание для студентов..."
onFocus={(e) => (e.currentTarget.style.borderColor = "var(--foreground)")}
onBlur={(e) => (e.currentTarget.style.borderColor = "var(--border)")}
/>
<div className="flex items-center gap-2">
<button
onClick={handleSave}
disabled={pending || !text.trim()}
className="btn-aubade btn-aubade-accent text-xs px-4 py-1.5"
style={{ opacity: pending || !text.trim() ? 0.6 : 1 }}
>
{pending ? "Сохранение..." : "Сохранить задание"}
</button>
{initial && (
<button onClick={() => { setEditing(false); setText(initial.description); }} className="text-xs" style={{ color: "var(--muted-foreground)" }}>
Отмена
</button>
)}
</div>
</div>
);
}