feat: env badge in header, inline desc edit, clean up deps

- Header now shows Production/Development with color-coded dot via import.meta.env.PROD
- LinkDashboard: click-to-edit description inline (blur/Enter to save, Escape to cancel)
- LoginPage: fix Azure button label to English
- Remove unused motion and autoprefixer dependencies
This commit is contained in:
Brückner
2026-06-04 13:42:13 +02:00
parent b7a3d2086d
commit 5769b38f74
5 changed files with 39 additions and 136 deletions

View File

@ -63,8 +63,8 @@ export default function Header({
{/* System Indicator */}
<div className="hidden md:flex items-center gap-2 px-3 py-1 bg-slate-800/60 rounded-full border border-slate-700/50 text-xs font-mono text-slate-300">
<span className="w-2 h-2 rounded-full bg-emerald-500 animate-pulse"></span>
<span>System: Online (Simulated)</span>
<span className={`w-2 h-2 rounded-full animate-pulse ${import.meta.env.PROD ? 'bg-emerald-500' : 'bg-amber-400'}`} />
<span>System: {import.meta.env.PROD ? 'Production' : 'Development'}</span>
</div>
{/* Mail Inbox */}

View File

@ -43,6 +43,8 @@ export default function LinkDashboard({ links, currentUser, onAddLink, onUpdateL
const [editingId, setEditingId] = useState<string | null>(null);
const [draft, setDraft] = useState<Draft>(EMPTY_DRAFT);
const [activeCategory, setActiveCategory] = useState<string>('all');
const [editingDescId, setEditingDescId] = useState<string | null>(null);
const [descDraft, setDescDraft] = useState('');
const categories = useMemo(() => {
const set = new Set<string>();
@ -97,6 +99,16 @@ export default function LinkDashboard({ links, currentUser, onAddLink, onUpdateL
setDraft(EMPTY_DRAFT);
};
const startDescEdit = (link: QuickLink) => {
setEditingDescId(link.id);
setDescDraft(link.description);
};
const commitDescEdit = (link: QuickLink) => {
onUpdateLink({ ...link, description: descDraft.trim() });
setEditingDescId(null);
};
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
const title = draft.title.trim();
@ -239,8 +251,28 @@ export default function LinkDashboard({ links, currentUser, onAddLink, onUpdateL
</div>
</div>
{link.description && (
<p className="text-[11px] text-slate-400 leading-relaxed mt-3 line-clamp-2">{link.description}</p>
{editingDescId === link.id ? (
<textarea
autoFocus
rows={2}
value={descDraft}
onChange={(e) => setDescDraft(e.target.value)}
onBlur={() => commitDescEdit(link)}
onKeyDown={(e) => {
if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); commitDescEdit(link); }
if (e.key === 'Escape') { setEditingDescId(null); }
}}
className="w-full mt-3 bg-slate-950 text-slate-200 text-[11px] border border-emerald-600 rounded px-2 py-1 resize-none focus:outline-none leading-relaxed"
placeholder="Add a description"
/>
) : (
<p
onClick={() => startDescEdit(link)}
title="Click to edit description"
className={`text-[11px] leading-relaxed mt-3 line-clamp-2 cursor-text ${link.description ? 'text-slate-400 hover:text-slate-200' : 'text-slate-600 italic hover:text-slate-400'} transition-colors`}
>
{link.description || 'Add a description…'}
</p>
)}
{/* Hover actions */}

View File

@ -165,7 +165,7 @@ export default function LoginPage({ onLogin, onNavigateToRegister, authError }:
<rect x="1" y="11" width="9" height="9" fill="#00A4EF" />
<rect x="11" y="11" width="9" height="9" fill="#FFB900" />
</svg>
Mit Microsoft anmelden
Sign In with Entra ID
</button>
</>
)}