import { useEffect, useRef, useState } from "react"; import { Button } from "./ui/button"; import { Input } from "./ui/input"; export function EditableText({ value, onSave, className }: { value: string; onSave: (v: string) => void; className?: string }) { const [editing, setEditing] = useState(false); const [draft, setDraft] = useState(value); const inputRef = useRef(null); useEffect(() => { setDraft(value); }, [value]); useEffect(() => { if (editing) inputRef.current?.focus(); }, [editing]); function commit() { setEditing(false); if (draft.trim() && draft !== value) onSave(draft.trim()); else setDraft(value); } if (editing) { return ( setDraft(e.target.value)} onBlur={commit} onKeyDown={(e) => { if (e.key === "Enter") commit(); if (e.key === "Escape") { setDraft(value); setEditing(false); } }} className={`${className} border-accent`} /> ); } return ( setEditing(true)} className={`${className} cursor-pointer hover:border-b hover:border-content-tertiary`}> {value} ); } export function EditableBadge({ value, placeholder, onSave, className, }: { value: string | null; placeholder: string; onSave: (v: string) => void; className: string; }) { const [editing, setEditing] = useState(false); const [draft, setDraft] = useState(value || ""); const ref = useRef(null); useEffect(() => { setDraft(value || ""); }, [value]); useEffect(() => { if (editing) ref.current?.focus(); }, [editing]); function commit() { setEditing(false); if (draft !== (value || "")) onSave(draft); } if (editing) { return ( setDraft(e.target.value)} onBlur={commit} onKeyDown={(e) => { if (e.key === "Enter") commit(); if (e.key === "Escape") { setDraft(value || ""); setEditing(false); } }} placeholder="project name" className="text-[11px] font-mono h-6 w-24" /> ); } if (!value) { return ( ); } return ( setEditing(true)} className={`text-[11px] font-mono px-2 py-0.5 rounded cursor-pointer ${className}`}> {value} ); } export function Field({ label, value }: { label: string; value: React.ReactNode }) { return (
{label}
{value}
); } export function FieldLabel({ children }: { children: React.ReactNode }) { return
{children}
; } export function formatRelative(dateStr: string): string { const diff = Date.now() - new Date(dateStr).getTime(); const mins = Math.floor(diff / 60000); if (mins < 1) return "now"; if (mins < 60) return `${mins}m`; const hrs = Math.floor(mins / 60); if (hrs < 24) return `${hrs}h`; return `${Math.floor(hrs / 24)}d`; }