feat(theme): implement single-file CSS theming engine with dark, light, high-contrast, and soft themes
MindSift CI & Docker Release / Build, Test in Container & Push (push) Failing after 16s
MindSift CI & Docker Release / Build, Test in Container & Push (push) Failing after 16s
This commit is contained in:
1 parent
0f24cbdbf4
commit
b3e651b3b9
18 files changed
+1455
-804
No files matched your search
@@ -6,16 +6,12 @@ import {
|
||||
Trash2,
|
||||
RotateCcw,
|
||||
FileText,
|
||||
Tag,
|
||||
LayoutList,
|
||||
Columns,
|
||||
ArrowRight,
|
||||
ArrowLeft,
|
||||
ChevronRight,
|
||||
ChevronDown,
|
||||
Edit3,
|
||||
X,
|
||||
Clock,
|
||||
Layers,
|
||||
Share2,
|
||||
} from 'lucide-react';
|
||||
@@ -85,7 +81,9 @@ export const TasksView: React.FC<TasksViewProps> = ({
|
||||
const nextState = !task.isCompleted;
|
||||
const nextKanban = nextState ? 'done' : 'todo';
|
||||
setTasks((prev) =>
|
||||
prev.map((t) => (t.id === task.id ? { ...t, isCompleted: nextState, kanbanStatus: nextKanban } : t))
|
||||
prev.map((t) =>
|
||||
t.id === task.id ? { ...t, isCompleted: nextState, kanbanStatus: nextKanban } : t
|
||||
)
|
||||
);
|
||||
await api.updateThought(task.id, { isCompleted: nextState, kanbanStatus: nextKanban });
|
||||
onRefreshStats();
|
||||
@@ -182,7 +180,12 @@ export const TasksView: React.FC<TasksViewProps> = ({
|
||||
};
|
||||
|
||||
const handleDeleteTaskList = async (listId: string) => {
|
||||
if (!window.confirm('Möchten Sie diese Aufgabenliste wirklich löschen? Die enthaltenen Aufgaben bleiben erhalten.')) return;
|
||||
if (
|
||||
!window.confirm(
|
||||
'Möchten Sie diese Aufgabenliste wirklich löschen? Die enthaltenen Aufgaben bleiben erhalten.'
|
||||
)
|
||||
)
|
||||
return;
|
||||
try {
|
||||
await api.deleteTaskList(listId);
|
||||
setTaskLists((prev) => prev.filter((l) => l.id !== listId));
|
||||
@@ -194,12 +197,18 @@ export const TasksView: React.FC<TasksViewProps> = ({
|
||||
|
||||
const safeTasks = Array.isArray(tasks) ? tasks : [];
|
||||
const safeTaskLists = Array.isArray(taskLists) ? taskLists : [];
|
||||
const safeSpaces = Array.isArray(spaces) ? spaces : [];
|
||||
const safeDiscarded = Array.isArray(discarded) ? discarded : [];
|
||||
|
||||
const openTasks = safeTasks.filter((t) => !t.isCompleted);
|
||||
const doneTasks = safeTasks.filter((t) => t.isCompleted);
|
||||
|
||||
const todoKanban = safeTasks.filter((t) => (!t.kanbanStatus || t.kanbanStatus === 'todo') && !t.isCompleted);
|
||||
const inProgressKanban = safeTasks.filter((t) => t.kanbanStatus === 'in_progress' && !t.isCompleted);
|
||||
const todoKanban = safeTasks.filter(
|
||||
(t) => (!t.kanbanStatus || t.kanbanStatus === 'todo') && !t.isCompleted
|
||||
);
|
||||
const inProgressKanban = safeTasks.filter(
|
||||
(t) => t.kanbanStatus === 'in_progress' && !t.isCompleted
|
||||
);
|
||||
const doneKanban = safeTasks.filter((t) => t.kanbanStatus === 'done' || t.isCompleted);
|
||||
|
||||
const currentSelectedList = safeTaskLists.find((l) => l.id === selectedListId);
|
||||
@@ -212,10 +221,10 @@ export const TasksView: React.FC<TasksViewProps> = ({
|
||||
<div className="flex flex-wrap items-center gap-1">
|
||||
<button
|
||||
onClick={() => setSelectedListId('all')}
|
||||
className={`h-8 px-3 text-xs font-medium border transition-colors ${
|
||||
className={`h-8 px-3 text-xs font-medium border rounded-btn transition-colors ${
|
||||
selectedListId === 'all'
|
||||
? 'bg-panel border-accent text-white'
|
||||
: 'bg-canvas border-border text-zinc-400 hover:text-white'
|
||||
? 'bg-panel border-accent text-main'
|
||||
: 'bg-canvas border-border text-muted hover:text-main'
|
||||
}`}
|
||||
>
|
||||
Alle Aufgaben
|
||||
@@ -225,18 +234,16 @@ export const TasksView: React.FC<TasksViewProps> = ({
|
||||
<div key={tl.id} className="relative group flex items-center">
|
||||
<button
|
||||
onClick={() => setSelectedListId(tl.id)}
|
||||
className={`h-8 px-3 text-xs font-medium border flex items-center gap-1.5 transition-colors ${
|
||||
className={`h-8 px-3 text-xs font-medium border rounded-btn flex items-center gap-1.5 transition-colors ${
|
||||
selectedListId === tl.id
|
||||
? 'bg-panel border-accent text-white'
|
||||
: 'bg-canvas border-border text-zinc-400 hover:text-white'
|
||||
? 'bg-panel border-accent text-main'
|
||||
: 'bg-canvas border-border text-muted hover:text-main'
|
||||
}`}
|
||||
>
|
||||
<span>{tl.icon}</span>
|
||||
<span>{tl.title}</span>
|
||||
{tl.tasksCount !== undefined && tl.tasksCount > 0 && (
|
||||
<span className="ml-1 px-1.5 py-0.2 bg-zinc-800 text-[10px] text-zinc-300">
|
||||
{tl.tasksCount}
|
||||
</span>
|
||||
<span className="ml-1 badge-neutral">{tl.tasksCount}</span>
|
||||
)}
|
||||
{tl.spaceId && (
|
||||
<span title="Geteilt mit Team/Space">
|
||||
@@ -248,7 +255,7 @@ export const TasksView: React.FC<TasksViewProps> = ({
|
||||
<button
|
||||
onClick={() => handleDeleteTaskList(tl.id)}
|
||||
title="Liste löschen"
|
||||
className="h-8 px-1.5 bg-panel border-y border-r border-accent text-zinc-500 hover:text-red-400"
|
||||
className="h-8 px-1.5 bg-panel border-y border-r border-accent text-faint hover:text-status-err"
|
||||
>
|
||||
<X className="w-3 h-3" />
|
||||
</button>
|
||||
@@ -258,7 +265,7 @@ export const TasksView: React.FC<TasksViewProps> = ({
|
||||
|
||||
<button
|
||||
onClick={() => setShowNewListModal(true)}
|
||||
className="h-8 px-2.5 bg-canvas hover:bg-panel border border-border border-dashed text-xs text-zinc-400 hover:text-white flex items-center gap-1 transition-colors"
|
||||
className="h-8 px-2.5 bg-canvas hover:bg-panel border border-border border-dashed rounded-btn text-xs text-muted hover:text-main flex items-center gap-1 transition-colors"
|
||||
title="Neue Aufgabenliste anlegen"
|
||||
>
|
||||
<Plus className="w-3.5 h-3.5" />
|
||||
@@ -268,11 +275,11 @@ export const TasksView: React.FC<TasksViewProps> = ({
|
||||
|
||||
{/* View Switcher: List vs Kanban */}
|
||||
<div className="flex items-center gap-1">
|
||||
<div className="flex border border-border bg-canvas">
|
||||
<div className="flex border border-border rounded-btn bg-canvas overflow-hidden">
|
||||
<button
|
||||
onClick={() => setViewMode('list')}
|
||||
className={`h-8 px-2.5 flex items-center gap-1.5 text-xs transition-colors border-r border-border ${
|
||||
viewMode === 'list' ? 'bg-panel text-white' : 'text-zinc-400 hover:text-white'
|
||||
viewMode === 'list' ? 'bg-panel text-main font-medium' : 'text-muted hover:text-main'
|
||||
}`}
|
||||
title="Listenansicht"
|
||||
>
|
||||
@@ -282,7 +289,9 @@ export const TasksView: React.FC<TasksViewProps> = ({
|
||||
<button
|
||||
onClick={() => setViewMode('kanban')}
|
||||
className={`h-8 px-2.5 flex items-center gap-1.5 text-xs transition-colors ${
|
||||
viewMode === 'kanban' ? 'bg-panel text-white' : 'text-zinc-400 hover:text-white'
|
||||
viewMode === 'kanban'
|
||||
? 'bg-panel text-main font-medium'
|
||||
: 'text-muted hover:text-main'
|
||||
}`}
|
||||
title="Kanban-Board"
|
||||
>
|
||||
@@ -294,7 +303,10 @@ export const TasksView: React.FC<TasksViewProps> = ({
|
||||
</div>
|
||||
|
||||
{/* Quick Add Task Input in active list */}
|
||||
<form onSubmit={handleQuickAddTask} className="flex items-center gap-1.5 bg-panel border border-border p-1.5">
|
||||
<form
|
||||
onSubmit={handleQuickAddTask}
|
||||
className="flex items-center gap-1.5 panel-surface p-1.5"
|
||||
>
|
||||
<Plus className="w-4 h-4 text-accent ml-1 flex-shrink-0" />
|
||||
<input
|
||||
type="text"
|
||||
@@ -305,14 +317,14 @@ export const TasksView: React.FC<TasksViewProps> = ({
|
||||
? `Aufgabe zu "${currentSelectedList.title}" hinzufügen… (Enter)`
|
||||
: 'Neue Aufgabe anlegen… (Enter)'
|
||||
}
|
||||
className="flex-1 bg-transparent px-2 py-1 text-sm text-white placeholder-zinc-500 focus:outline-none"
|
||||
className="flex-1 bg-transparent px-2 py-1 text-sm text-main placeholder-faint focus:outline-none"
|
||||
/>
|
||||
<div className="flex items-center gap-1">
|
||||
<input
|
||||
type="date"
|
||||
value={quickDueDate}
|
||||
onChange={(e) => setQuickDueDate(e.target.value)}
|
||||
className="h-7 px-2 bg-canvas border border-border text-xs text-zinc-300 focus:outline-none"
|
||||
className="h-7 px-2 input-field text-xs"
|
||||
title="Fälligkeitsdatum"
|
||||
/>
|
||||
<button
|
||||
@@ -327,21 +339,24 @@ export const TasksView: React.FC<TasksViewProps> = ({
|
||||
|
||||
{/* NEW LIST MODAL */}
|
||||
{showNewListModal && (
|
||||
<div className="fixed inset-0 bg-black/60 backdrop-blur-sm z-50 flex items-center justify-center p-4">
|
||||
<div className="w-full max-w-sm bg-panel border border-border p-4 space-y-3">
|
||||
<div className="fixed inset-0 modal-overlay z-50 flex items-center justify-center p-4">
|
||||
<div className="w-full max-w-sm panel-surface shadow-panel p-4 space-y-3">
|
||||
<div className="flex items-center justify-between border-b border-border pb-2">
|
||||
<h3 className="text-sm font-semibold text-white flex items-center gap-1.5">
|
||||
<h3 className="text-sm font-semibold text-main flex items-center gap-1.5">
|
||||
<Layers className="w-4 h-4 text-accent" />
|
||||
<span>Neue Aufgabenliste erstellen</span>
|
||||
</h3>
|
||||
<button onClick={() => setShowNewListModal(false)} className="text-zinc-400 hover:text-white">
|
||||
<button
|
||||
onClick={() => setShowNewListModal(false)}
|
||||
className="text-muted hover:text-main"
|
||||
>
|
||||
<X className="w-4 h-4" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<form onSubmit={handleCreateTaskList} className="space-y-3">
|
||||
<div>
|
||||
<label className="block text-xs text-zinc-400 mb-1">Titel der Liste</label>
|
||||
<label className="block text-xs text-muted mb-1">Titel der Liste</label>
|
||||
<div className="flex items-center gap-1.5">
|
||||
<input
|
||||
type="text"
|
||||
@@ -358,21 +373,23 @@ export const TasksView: React.FC<TasksViewProps> = ({
|
||||
placeholder="z.B. Homelab, Einkäufe, Steuern"
|
||||
autoFocus
|
||||
required
|
||||
className="flex-1 h-8 input-field px-2.5 text-xs text-white"
|
||||
className="flex-1 h-8 input-field px-2.5 text-xs"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{spaces.length > 0 && (
|
||||
{safeSpaces.length > 0 && (
|
||||
<div>
|
||||
<label className="block text-xs text-zinc-400 mb-1">Geteilt mit Space (optional)</label>
|
||||
<label className="block text-xs text-muted mb-1">
|
||||
Geteilt mit Space (optional)
|
||||
</label>
|
||||
<select
|
||||
value={newListSpaceId}
|
||||
onChange={(e) => setNewListSpaceId(e.target.value)}
|
||||
className="w-full h-8 input-field px-2 text-xs text-white bg-canvas"
|
||||
className="w-full h-8 input-field px-2 text-xs"
|
||||
>
|
||||
<option value="">Privat (nur ich)</option>
|
||||
{spaces.map((sp) => (
|
||||
{safeSpaces.map((sp) => (
|
||||
<option key={sp.id} value={sp.id}>
|
||||
{sp.icon} {sp.name}
|
||||
</option>
|
||||
@@ -405,29 +422,27 @@ export const TasksView: React.FC<TasksViewProps> = ({
|
||||
{/* COLUMN 1: TODO */}
|
||||
<div className="bg-canvas border border-border flex flex-col">
|
||||
<div className="px-3 py-2 bg-panel border-b border-border flex items-center justify-between">
|
||||
<span className="text-xs font-semibold text-zinc-300 flex items-center gap-1.5">
|
||||
<span className="w-2 h-2 bg-zinc-500 inline-block" />
|
||||
<span className="text-xs font-semibold text-main flex items-center gap-1.5">
|
||||
<span className="w-2 h-2 bg-faint inline-block" />
|
||||
<span>Zu erledigen</span>
|
||||
</span>
|
||||
<span className="px-1.5 py-0.2 bg-canvas border border-border text-[10px] text-zinc-400 font-mono">
|
||||
{todoKanban.length}
|
||||
</span>
|
||||
<span className="badge-neutral font-mono">{todoKanban.length}</span>
|
||||
</div>
|
||||
|
||||
<div className="p-2 space-y-2 min-h-[360px] flex-1 overflow-y-auto">
|
||||
{todoKanban.map((task) => (
|
||||
<div
|
||||
key={task.id}
|
||||
className="bg-panel border border-border p-2.5 space-y-2 hover:border-zinc-500 transition-colors"
|
||||
className="panel-surface p-2.5 space-y-2 hover:border-strong transition-colors"
|
||||
>
|
||||
<div className="flex items-start justify-between gap-2">
|
||||
<p className="text-xs font-medium text-white break-words flex-1 leading-snug">
|
||||
<p className="text-xs font-medium text-main break-words flex-1 leading-snug">
|
||||
{task.content}
|
||||
</p>
|
||||
<button
|
||||
onClick={() => handleConvertToDoc(task)}
|
||||
title="Als Notiz vertiefen"
|
||||
className="text-zinc-500 hover:text-accent flex-shrink-0"
|
||||
className="text-faint hover:text-accent flex-shrink-0"
|
||||
>
|
||||
<FileText className="w-3.5 h-3.5" />
|
||||
</button>
|
||||
@@ -441,7 +456,7 @@ export const TasksView: React.FC<TasksViewProps> = ({
|
||||
onChange={(e) => setNotesDraft(e.target.value)}
|
||||
placeholder="Detailnotizen eingeben…"
|
||||
rows={2}
|
||||
className="w-full input-field p-1.5 text-xs text-white resize-none"
|
||||
className="w-full input-field p-1.5 text-xs resize-none"
|
||||
/>
|
||||
<div className="flex justify-end gap-1">
|
||||
<button
|
||||
@@ -464,7 +479,7 @@ export const TasksView: React.FC<TasksViewProps> = ({
|
||||
setActiveNotesTaskId(task.id);
|
||||
setNotesDraft(task.notes || '');
|
||||
}}
|
||||
className="p-1.5 bg-canvas border border-border text-[11px] text-zinc-400 break-words cursor-pointer hover:border-zinc-500"
|
||||
className="p-1.5 bg-canvas border border-border text-[11px] text-muted break-words cursor-pointer hover:border-strong"
|
||||
title="Klicken zum Bearbeiten der Notizen"
|
||||
>
|
||||
{task.notes}
|
||||
@@ -472,10 +487,10 @@ export const TasksView: React.FC<TasksViewProps> = ({
|
||||
) : null}
|
||||
|
||||
{/* Footer & Movement Controls */}
|
||||
<div className="flex items-center justify-between gap-1 pt-1 border-t border-white/[0.05] text-[11px]">
|
||||
<div className="flex items-center gap-1.5 text-zinc-400">
|
||||
<div className="flex items-center justify-between gap-1 pt-1 border-t border-subtle text-[11px]">
|
||||
<div className="flex items-center gap-1.5 text-muted">
|
||||
{task.dueDate && (
|
||||
<span className="flex items-center gap-1 text-[10px] text-zinc-300">
|
||||
<span className="flex items-center gap-1 text-[10px] text-muted">
|
||||
<Calendar className="w-2.5 h-2.5" /> {task.dueDate}
|
||||
</span>
|
||||
)}
|
||||
@@ -485,7 +500,7 @@ export const TasksView: React.FC<TasksViewProps> = ({
|
||||
setActiveNotesTaskId(task.id);
|
||||
setNotesDraft('');
|
||||
}}
|
||||
className="text-[10px] text-zinc-500 hover:text-zinc-300"
|
||||
className="text-[10px] text-faint hover:text-main"
|
||||
>
|
||||
+ Notiz
|
||||
</button>
|
||||
@@ -506,7 +521,7 @@ export const TasksView: React.FC<TasksViewProps> = ({
|
||||
</div>
|
||||
))}
|
||||
{todoKanban.length === 0 && (
|
||||
<div className="p-4 text-center text-zinc-600 text-xs">Keine Aufgaben offen</div>
|
||||
<div className="p-4 text-center text-faint text-xs">Keine Aufgaben offen</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
@@ -518,25 +533,23 @@ export const TasksView: React.FC<TasksViewProps> = ({
|
||||
<span className="w-2 h-2 bg-accent inline-block" />
|
||||
<span>In Bearbeitung</span>
|
||||
</span>
|
||||
<span className="px-1.5 py-0.2 bg-canvas border border-border text-[10px] text-zinc-400 font-mono">
|
||||
{inProgressKanban.length}
|
||||
</span>
|
||||
<span className="badge-neutral font-mono">{inProgressKanban.length}</span>
|
||||
</div>
|
||||
|
||||
<div className="p-2 space-y-2 min-h-[360px] flex-1 overflow-y-auto">
|
||||
{inProgressKanban.map((task) => (
|
||||
<div
|
||||
key={task.id}
|
||||
className="bg-panel border border-accent/40 p-2.5 space-y-2 hover:border-accent transition-colors"
|
||||
className="bg-panel border border-accent-border p-2.5 space-y-2 hover:border-accent transition-colors"
|
||||
>
|
||||
<div className="flex items-start justify-between gap-2">
|
||||
<p className="text-xs font-medium text-white break-words flex-1 leading-snug">
|
||||
<p className="text-xs font-medium text-main break-words flex-1 leading-snug">
|
||||
{task.content}
|
||||
</p>
|
||||
<button
|
||||
onClick={() => handleConvertToDoc(task)}
|
||||
title="Als Notiz vertiefen"
|
||||
className="text-zinc-500 hover:text-accent flex-shrink-0"
|
||||
className="text-faint hover:text-accent flex-shrink-0"
|
||||
>
|
||||
<FileText className="w-3.5 h-3.5" />
|
||||
</button>
|
||||
@@ -550,7 +563,7 @@ export const TasksView: React.FC<TasksViewProps> = ({
|
||||
onChange={(e) => setNotesDraft(e.target.value)}
|
||||
placeholder="Detailnotizen eingeben…"
|
||||
rows={2}
|
||||
className="w-full input-field p-1.5 text-xs text-white resize-none"
|
||||
className="w-full input-field p-1.5 text-xs resize-none"
|
||||
/>
|
||||
<div className="flex justify-end gap-1">
|
||||
<button
|
||||
@@ -573,20 +586,20 @@ export const TasksView: React.FC<TasksViewProps> = ({
|
||||
setActiveNotesTaskId(task.id);
|
||||
setNotesDraft(task.notes || '');
|
||||
}}
|
||||
className="p-1.5 bg-canvas border border-border text-[11px] text-zinc-400 break-words cursor-pointer hover:border-zinc-500"
|
||||
className="p-1.5 bg-canvas border border-border text-[11px] text-muted break-words cursor-pointer hover:border-strong"
|
||||
>
|
||||
{task.notes}
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
{/* Movement Controls */}
|
||||
<div className="flex items-center justify-between gap-1 pt-1 border-t border-white/[0.05] text-[11px]">
|
||||
<div className="flex items-center justify-between gap-1 pt-1 border-t border-subtle text-[11px]">
|
||||
<button
|
||||
onClick={() => handleKanbanMove(task, 'todo')}
|
||||
className="btn-action h-6 px-1.5 text-[10px] flex items-center gap-1"
|
||||
title="Zurück zu 'Zu erledigen'"
|
||||
>
|
||||
<ArrowLeft className="w-3 h-3 text-zinc-400" />
|
||||
<ArrowLeft className="w-3 h-3 text-muted" />
|
||||
<span>Zurück</span>
|
||||
</button>
|
||||
|
||||
@@ -602,7 +615,7 @@ export const TasksView: React.FC<TasksViewProps> = ({
|
||||
</div>
|
||||
))}
|
||||
{inProgressKanban.length === 0 && (
|
||||
<div className="p-4 text-center text-zinc-600 text-xs">Keine aktiven Aufgaben</div>
|
||||
<div className="p-4 text-center text-faint text-xs">Keine aktiven Aufgaben</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
@@ -610,26 +623,24 @@ export const TasksView: React.FC<TasksViewProps> = ({
|
||||
{/* COLUMN 3: DONE */}
|
||||
<div className="bg-canvas border border-border flex flex-col">
|
||||
<div className="px-3 py-2 bg-panel border-b border-border flex items-center justify-between">
|
||||
<span className="text-xs font-semibold text-emerald-400 flex items-center gap-1.5">
|
||||
<span className="w-2 h-2 bg-emerald-500 inline-block" />
|
||||
<span className="text-xs font-semibold text-status-ok flex items-center gap-1.5">
|
||||
<span className="w-2 h-2 bg-status-ok inline-block" />
|
||||
<span>Erledigt</span>
|
||||
</span>
|
||||
<span className="px-1.5 py-0.2 bg-canvas border border-border text-[10px] text-zinc-400 font-mono">
|
||||
{doneKanban.length}
|
||||
</span>
|
||||
<span className="badge-neutral font-mono">{doneKanban.length}</span>
|
||||
</div>
|
||||
|
||||
<div className="p-2 space-y-2 min-h-[360px] flex-1 overflow-y-auto">
|
||||
{doneKanban.map((task) => (
|
||||
<div
|
||||
key={task.id}
|
||||
className="bg-panel border border-border p-2.5 space-y-2 opacity-70 hover:opacity-100 transition-opacity"
|
||||
className="panel-surface p-2.5 space-y-2 opacity-70 hover:opacity-100 transition-opacity"
|
||||
>
|
||||
<p className="text-xs font-medium text-zinc-400 line-through break-words leading-snug">
|
||||
<p className="text-xs font-medium text-muted line-through break-words leading-snug">
|
||||
{task.content}
|
||||
</p>
|
||||
|
||||
<div className="flex items-center justify-between gap-1 pt-1 border-t border-white/[0.05] text-[11px]">
|
||||
<div className="flex items-center justify-between gap-1 pt-1 border-t border-subtle text-[11px]">
|
||||
<button
|
||||
onClick={() => handleKanbanMove(task, 'todo')}
|
||||
className="btn-action h-6 px-1.5 text-[10px] flex items-center gap-1"
|
||||
@@ -640,7 +651,7 @@ export const TasksView: React.FC<TasksViewProps> = ({
|
||||
</button>
|
||||
<button
|
||||
onClick={() => handleDeletePermanent(task.id)}
|
||||
className="text-zinc-500 hover:text-red-400 p-1"
|
||||
className="text-faint hover:text-status-err p-1"
|
||||
title="Löschen"
|
||||
>
|
||||
<Trash2 className="w-3 h-3" />
|
||||
@@ -649,7 +660,9 @@ export const TasksView: React.FC<TasksViewProps> = ({
|
||||
</div>
|
||||
))}
|
||||
{doneKanban.length === 0 && (
|
||||
<div className="p-4 text-center text-zinc-600 text-xs">Noch keine erledigten Aufgaben</div>
|
||||
<div className="p-4 text-center text-faint text-xs">
|
||||
Noch keine erledigten Aufgaben
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
@@ -659,11 +672,11 @@ export const TasksView: React.FC<TasksViewProps> = ({
|
||||
<div className="space-y-2">
|
||||
{/* Subfilter tabs for List View */}
|
||||
<div className="flex items-center justify-between gap-2">
|
||||
<div className="flex items-center border border-border bg-canvas">
|
||||
<div className="flex items-center border border-border rounded-btn bg-canvas overflow-hidden">
|
||||
<button
|
||||
onClick={() => setFilter('open')}
|
||||
className={`h-8 px-3.5 text-xs font-medium border-r border-border transition-colors ${
|
||||
filter === 'open' ? 'bg-panel text-white' : 'text-zinc-400 hover:text-white'
|
||||
filter === 'open' ? 'bg-panel text-main' : 'text-muted hover:text-main'
|
||||
}`}
|
||||
>
|
||||
Offen ({openTasks.length})
|
||||
@@ -672,7 +685,7 @@ export const TasksView: React.FC<TasksViewProps> = ({
|
||||
<button
|
||||
onClick={() => setFilter('done')}
|
||||
className={`h-8 px-3.5 text-xs font-medium border-r border-border transition-colors ${
|
||||
filter === 'done' ? 'bg-panel text-white' : 'text-zinc-400 hover:text-white'
|
||||
filter === 'done' ? 'bg-panel text-main' : 'text-muted hover:text-main'
|
||||
}`}
|
||||
>
|
||||
Erledigt ({doneTasks.length})
|
||||
@@ -681,14 +694,14 @@ export const TasksView: React.FC<TasksViewProps> = ({
|
||||
<button
|
||||
onClick={() => setFilter('discarded')}
|
||||
className={`h-8 px-3.5 text-xs font-medium transition-colors ${
|
||||
filter === 'discarded' ? 'bg-panel text-white' : 'text-zinc-400 hover:text-white'
|
||||
filter === 'discarded' ? 'bg-panel text-main' : 'text-muted hover:text-main'
|
||||
}`}
|
||||
>
|
||||
Papierkorb ({discarded.length})
|
||||
Papierkorb ({safeDiscarded.length})
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{filter === 'discarded' && discarded.length > 0 && (
|
||||
{filter === 'discarded' && safeDiscarded.length > 0 && (
|
||||
<button onClick={handlePurgeAllDiscarded} className="btn-action">
|
||||
<Trash2 className="w-3.5 h-3.5" />
|
||||
Papierkorb leeren
|
||||
@@ -697,22 +710,22 @@ export const TasksView: React.FC<TasksViewProps> = ({
|
||||
</div>
|
||||
|
||||
{loading ? (
|
||||
<div className="p-6 text-center text-zinc-500 text-sm">Lade Aufgaben…</div>
|
||||
<div className="p-6 text-center text-faint text-sm">Lade Aufgaben…</div>
|
||||
) : filter === 'discarded' ? (
|
||||
<div className="panel-surface divide-y divide-border">
|
||||
{discarded.length === 0 ? (
|
||||
<div className="px-4 py-6 text-center text-zinc-400 text-sm">
|
||||
{safeDiscarded.length === 0 ? (
|
||||
<div className="px-4 py-6 text-center text-muted text-sm">
|
||||
Keine verworfenen Gedanken im Papierkorb.
|
||||
</div>
|
||||
) : (
|
||||
discarded.map((item) => (
|
||||
safeDiscarded.map((item) => (
|
||||
<div
|
||||
key={item.id}
|
||||
className="px-3 py-2 flex items-center justify-between gap-3 hover:bg-white/[0.02]"
|
||||
className="px-3 py-2 flex items-center justify-between gap-3 hover:bg-panel-hover"
|
||||
>
|
||||
<div className="flex items-center gap-2.5 min-w-0 flex-1">
|
||||
<Trash2 className="w-4 h-4 text-zinc-500 flex-shrink-0" />
|
||||
<p className="text-sm text-zinc-400 line-through truncate">{item.content}</p>
|
||||
<Trash2 className="w-4 h-4 text-faint flex-shrink-0" />
|
||||
<p className="text-sm text-muted line-through truncate">{item.content}</p>
|
||||
</div>
|
||||
<div className="flex items-center gap-2 flex-shrink-0">
|
||||
<button onClick={() => handleRestore(item)} className="btn-action">
|
||||
@@ -733,7 +746,7 @@ export const TasksView: React.FC<TasksViewProps> = ({
|
||||
) : (
|
||||
<div className="panel-surface divide-y divide-border">
|
||||
{(filter === 'open' ? openTasks : doneTasks).length === 0 ? (
|
||||
<div className="px-4 py-6 text-center text-zinc-400 text-sm">
|
||||
<div className="px-4 py-6 text-center text-muted text-sm">
|
||||
{filter === 'open'
|
||||
? 'Keine offenen Aufgaben vorhanden.'
|
||||
: 'Noch keine erledigten Aufgaben.'}
|
||||
@@ -742,18 +755,18 @@ export const TasksView: React.FC<TasksViewProps> = ({
|
||||
(filter === 'open' ? openTasks : doneTasks).map((task) => (
|
||||
<div
|
||||
key={task.id}
|
||||
className={`px-3 py-2.5 flex flex-col sm:flex-row sm:items-center justify-between gap-2.5 transition-colors hover:bg-white/[0.02] ${
|
||||
className={`px-3 py-2.5 flex flex-col sm:flex-row sm:items-center justify-between gap-2.5 transition-colors hover:bg-panel-hover ${
|
||||
task.isCompleted ? 'opacity-65' : ''
|
||||
}`}
|
||||
>
|
||||
<div className="flex items-start gap-3 min-w-0 flex-1">
|
||||
{/* Square minimalist checkbox */}
|
||||
{/* Theme-controlled checkbox (--radius-checkbox) */}
|
||||
<button
|
||||
onClick={() => handleToggleDone(task)}
|
||||
className={`w-4 h-4 mt-0.5 flex items-center justify-center flex-shrink-0 transition-colors border ${
|
||||
className={`w-4 h-4 mt-0.5 checkbox-square flex items-center justify-center flex-shrink-0 transition-colors border ${
|
||||
task.isCompleted
|
||||
? 'bg-accent border-accent text-white'
|
||||
: 'border-zinc-500 hover:border-accent text-transparent'
|
||||
? 'bg-accent border-accent text-on-accent'
|
||||
: 'border-strong hover:border-accent text-transparent'
|
||||
}`}
|
||||
title={task.isCompleted ? 'Als offen markieren' : 'Als erledigt abhaken'}
|
||||
>
|
||||
@@ -763,7 +776,7 @@ export const TasksView: React.FC<TasksViewProps> = ({
|
||||
<div className="min-w-0 flex-1 space-y-1">
|
||||
<p
|
||||
className={`text-sm break-words leading-tight ${
|
||||
task.isCompleted ? 'line-through text-zinc-500' : 'text-white'
|
||||
task.isCompleted ? 'line-through text-faint' : 'text-main'
|
||||
}`}
|
||||
>
|
||||
{task.content}
|
||||
@@ -777,7 +790,7 @@ export const TasksView: React.FC<TasksViewProps> = ({
|
||||
onChange={(e) => setNotesDraft(e.target.value)}
|
||||
placeholder="Detailnotizen eingeben…"
|
||||
rows={2}
|
||||
className="w-full input-field p-2 text-xs text-white resize-none"
|
||||
className="w-full input-field p-2 text-xs resize-none"
|
||||
/>
|
||||
<div className="flex justify-end gap-1.5">
|
||||
<button
|
||||
@@ -800,7 +813,7 @@ export const TasksView: React.FC<TasksViewProps> = ({
|
||||
setActiveNotesTaskId(task.id);
|
||||
setNotesDraft(task.notes || '');
|
||||
}}
|
||||
className="text-xs text-zinc-400 bg-canvas p-1.5 border border-border cursor-pointer hover:border-zinc-500"
|
||||
className="text-xs text-muted bg-canvas p-1.5 border border-border cursor-pointer hover:border-strong"
|
||||
title="Klicken zum Bearbeiten"
|
||||
>
|
||||
{task.notes}
|
||||
@@ -812,20 +825,15 @@ export const TasksView: React.FC<TasksViewProps> = ({
|
||||
<span className="badge-accent">Dringend</span>
|
||||
)}
|
||||
{task.priority === 'high' && (
|
||||
<span className="px-1.5 py-0.2 border border-white/20 text-zinc-300 text-[10px] font-medium">
|
||||
<span className="px-1.5 py-0.5 border border-strong rounded-btn text-main text-[10px] font-medium">
|
||||
Wichtig
|
||||
</span>
|
||||
)}
|
||||
{task.kanbanStatus === 'in_progress' && (
|
||||
<span className="px-1.5 py-0.2 bg-blue-900/40 border border-blue-500/40 text-blue-300 text-[10px]">
|
||||
⚡ In Bearbeitung
|
||||
</span>
|
||||
<span className="badge-accent">⚡ In Bearbeitung</span>
|
||||
)}
|
||||
{task.tags?.map((tag) => (
|
||||
<span
|
||||
key={tag}
|
||||
className="px-1.5 py-0.2 bg-canvas text-zinc-400 text-[10px]"
|
||||
>
|
||||
<span key={tag} className="badge-neutral">
|
||||
#{tag}
|
||||
</span>
|
||||
))}
|
||||
@@ -850,7 +858,7 @@ export const TasksView: React.FC<TasksViewProps> = ({
|
||||
)}
|
||||
|
||||
<div className="relative flex items-center">
|
||||
<Calendar className="w-3 h-3 text-zinc-400 absolute left-2 pointer-events-none" />
|
||||
<Calendar className="w-3 h-3 text-muted absolute left-2 pointer-events-none" />
|
||||
<input
|
||||
type="date"
|
||||
value={task.dueDate || ''}
|
||||
|
||||
@@ -193,19 +193,19 @@ export const TriageDeck: React.FC<TriageDeckProps> = ({
|
||||
switch (priority) {
|
||||
case 'urgent':
|
||||
return (
|
||||
<span className="px-2 py-0.5 text-[11px] font-semibold border border-accent text-accent">
|
||||
<span className="px-2 py-0.5 text-[11px] font-semibold border border-accent rounded-btn text-accent">
|
||||
Dringend
|
||||
</span>
|
||||
);
|
||||
case 'high':
|
||||
return (
|
||||
<span className="px-2 py-0.5 text-[11px] font-medium border border-white/20 text-zinc-200">
|
||||
<span className="px-2 py-0.5 text-[11px] font-medium border border-strong rounded-btn text-main">
|
||||
Wichtig
|
||||
</span>
|
||||
);
|
||||
default:
|
||||
return (
|
||||
<span className="px-2 py-0.5 text-[11px] font-medium bg-panel-elevated text-zinc-400 border border-border">
|
||||
<span className="px-2 py-0.5 text-[11px] font-medium bg-panel-elevated text-muted border border-border rounded-btn">
|
||||
Quick Dump
|
||||
</span>
|
||||
);
|
||||
@@ -215,14 +215,14 @@ export const TriageDeck: React.FC<TriageDeckProps> = ({
|
||||
const sourceBadge = (source: string) => {
|
||||
if (source === 'voice') {
|
||||
return (
|
||||
<span className="px-2 py-0.5 text-[11px] bg-canvas text-accent border border-border flex items-center gap-1">
|
||||
<span className="px-2 py-0.5 text-[11px] bg-canvas text-accent border border-border rounded-btn flex items-center gap-1">
|
||||
<Mic className="w-3 h-3" /> Diktat
|
||||
</span>
|
||||
);
|
||||
}
|
||||
if (source === 'webhook') {
|
||||
return (
|
||||
<span className="px-2 py-0.5 text-[11px] bg-canvas text-zinc-300 border border-border flex items-center gap-1">
|
||||
<span className="px-2 py-0.5 text-[11px] bg-canvas text-muted border border-border rounded-btn flex items-center gap-1">
|
||||
<Webhook className="w-3 h-3 text-accent" /> Webhook
|
||||
</span>
|
||||
);
|
||||
@@ -232,13 +232,15 @@ export const TriageDeck: React.FC<TriageDeckProps> = ({
|
||||
|
||||
if (!activeCard) {
|
||||
return (
|
||||
<div className="max-w-xl mx-auto mt-2 p-6 bg-panel border border-border text-center">
|
||||
<div className="w-11 h-11 bg-accent text-white flex items-center justify-center mx-auto mb-3 shadow-sm">
|
||||
<div className="max-w-xl mx-auto mt-2 p-6 panel-surface text-center">
|
||||
<div className="w-11 h-11 bg-accent text-on-accent rounded-btn flex items-center justify-center mx-auto mb-3 shadow-sm">
|
||||
<Sparkles className="w-5 h-5" />
|
||||
</div>
|
||||
<h2 className="text-lg font-bold text-white mb-1">Triage-Deck ist leer</h2>
|
||||
<p className="text-zinc-400 text-xs sm:text-sm max-w-md mx-auto mb-4">
|
||||
Alle Quick Dump Notizen sind einsortiert oder verworfen. Tippe oben in die Leiste (Taste <kbd className="px-1.5 py-0.5 bg-canvas border border-border text-zinc-300">C</kbd>), um neue Gedanken reinzurotzen.
|
||||
<h2 className="text-lg font-bold text-main mb-1">Triage-Deck ist leer</h2>
|
||||
<p className="text-muted text-xs sm:text-sm max-w-md mx-auto mb-4">
|
||||
Alle Quick Dump Notizen sind einsortiert oder verworfen. Tippe oben in die Leiste (Taste{' '}
|
||||
<kbd className="px-1.5 py-0.5 bg-canvas border border-border rounded-btn text-main">C</kbd>
|
||||
), um neue Gedanken reinzurotzen.
|
||||
</p>
|
||||
|
||||
<div className="flex flex-wrap items-center justify-center gap-2">
|
||||
@@ -271,8 +273,8 @@ export const TriageDeck: React.FC<TriageDeckProps> = ({
|
||||
<span className="badge-accent">
|
||||
{cards.length} {cards.length === 1 ? 'Quick Dump' : 'Quick Dumps'} offen
|
||||
</span>
|
||||
<span className="hidden sm:inline text-xs text-zinc-600">•</span>
|
||||
<span className="hidden sm:flex items-center gap-1 text-xs text-zinc-400">
|
||||
<span className="hidden sm:inline text-xs text-faint">•</span>
|
||||
<span className="hidden sm:flex items-center gap-1 text-xs text-muted">
|
||||
<Keyboard className="w-3 h-3" /> ← Wegwerfen • → Aufgabe • D Notiz • Leertaste Später
|
||||
</span>
|
||||
</div>
|
||||
@@ -294,11 +296,11 @@ export const TriageDeck: React.FC<TriageDeckProps> = ({
|
||||
{nextCard && (
|
||||
<div
|
||||
key={nextCard.id + '-preview'}
|
||||
className="absolute inset-x-3 top-3 bottom-0 bg-panel/60 border border-border p-4 opacity-40 scale-[0.97] pointer-events-none flex flex-col justify-between"
|
||||
className="absolute inset-x-3 top-3 bottom-0 panel-surface p-4 opacity-40 scale-[0.97] pointer-events-none flex flex-col justify-between"
|
||||
>
|
||||
<div className="flex items-center gap-2">{priorityBadge(nextCard.priority)}</div>
|
||||
<p className="text-sm text-zinc-400 line-clamp-2">{nextCard.content}</p>
|
||||
<div className="text-[11px] text-zinc-500">Nächster Quick Dump…</div>
|
||||
<p className="text-sm text-muted line-clamp-2">{nextCard.content}</p>
|
||||
<div className="text-[11px] text-faint">Nächster Quick Dump…</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -321,19 +323,19 @@ export const TriageDeck: React.FC<TriageDeckProps> = ({
|
||||
initial={{ scale: 0.97, opacity: 0, y: 10 }}
|
||||
animate={{ scale: 1, opacity: 1, y: 0 }}
|
||||
exit={{ scale: 0.93, opacity: 0 }}
|
||||
className="relative w-full h-full bg-panel border border-border p-4 sm:p-5 cursor-grab active:cursor-grabbing flex flex-col justify-between overflow-hidden"
|
||||
className="relative w-full h-full panel-surface p-4 sm:p-5 cursor-grab active:cursor-grabbing flex flex-col justify-between overflow-hidden"
|
||||
>
|
||||
{/* Dynamic Swipe Overlays */}
|
||||
<motion.div
|
||||
style={{ opacity: keepOpacity }}
|
||||
className="pointer-events-none absolute top-3.5 right-3.5 px-2.5 py-1 bg-accent/20 border border-accent text-accent font-semibold text-xs tracking-wide uppercase"
|
||||
className="pointer-events-none absolute top-3.5 right-3.5 px-2.5 py-1 bg-accent-dim border border-accent rounded-btn text-accent font-semibold text-xs tracking-wide uppercase"
|
||||
>
|
||||
Als Aufgabe 👉
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
style={{ opacity: discardOpacity }}
|
||||
className="pointer-events-none absolute top-3.5 left-3.5 px-2.5 py-1 bg-white/10 border border-white/30 text-zinc-200 font-semibold text-xs tracking-wide uppercase"
|
||||
className="pointer-events-none absolute top-3.5 left-3.5 px-2.5 py-1 bg-panel-elevated border border-strong rounded-btn text-main font-semibold text-xs tracking-wide uppercase"
|
||||
>
|
||||
👈 Wegwerfen
|
||||
</motion.div>
|
||||
@@ -352,12 +354,12 @@ export const TriageDeck: React.FC<TriageDeckProps> = ({
|
||||
setIsEditingCard((prev) => !prev);
|
||||
}}
|
||||
title="Quick Dump Text vor dem Zuordnen anpassen"
|
||||
className="h-6 px-2 bg-canvas hover:bg-panel-hover border border-border text-[11px] text-zinc-400 hover:text-white flex items-center gap-1"
|
||||
className="h-6 px-2 bg-canvas hover:bg-panel-hover border border-border rounded-btn text-[11px] text-muted hover:text-main flex items-center gap-1"
|
||||
>
|
||||
<Edit3 className="w-3 h-3" />
|
||||
<span>Bearbeiten</span>
|
||||
</button>
|
||||
<span className="text-xs text-zinc-400 flex items-center gap-1">
|
||||
<span className="text-xs text-muted flex items-center gap-1">
|
||||
<Clock className="w-3 h-3" />
|
||||
{new Date(activeCard.createdAt).toLocaleString('de-DE', {
|
||||
day: '2-digit',
|
||||
@@ -378,7 +380,7 @@ export const TriageDeck: React.FC<TriageDeckProps> = ({
|
||||
onChange={(e) => setEditDraft(e.target.value)}
|
||||
rows={3}
|
||||
autoFocus
|
||||
className="w-full input-field p-2 text-sm text-white resize-none"
|
||||
className="w-full input-field p-2 text-sm resize-none"
|
||||
/>
|
||||
<div className="flex items-center justify-end gap-1.5">
|
||||
<button
|
||||
@@ -398,7 +400,7 @@ export const TriageDeck: React.FC<TriageDeckProps> = ({
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<p className="text-base sm:text-xl font-medium text-white leading-relaxed break-words">
|
||||
<p className="text-base sm:text-xl font-medium text-main leading-relaxed break-words">
|
||||
{activeCard.content}
|
||||
</p>
|
||||
)}
|
||||
@@ -414,14 +416,14 @@ export const TriageDeck: React.FC<TriageDeckProps> = ({
|
||||
</span>
|
||||
))
|
||||
) : (
|
||||
<span className="text-xs text-zinc-500">
|
||||
<span className="text-xs text-faint">
|
||||
Links wischen = Wegwerfen • Rechts wischen = Als Aufgabe sichern
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{activeCard.dueDate && (
|
||||
<span className="px-2 py-0.5 bg-canvas text-zinc-300 border border-border text-xs">
|
||||
<span className="px-2 py-0.5 bg-canvas text-muted border border-border rounded-btn text-xs">
|
||||
📅 {activeCard.dueDate}
|
||||
</span>
|
||||
)}
|
||||
@@ -432,8 +434,8 @@ export const TriageDeck: React.FC<TriageDeckProps> = ({
|
||||
|
||||
{/* Convert to Task with Due Date Popover */}
|
||||
{showDateModal && (
|
||||
<div className="p-3 bg-panel border border-border flex flex-wrap items-center justify-between gap-3">
|
||||
<div className="flex items-center gap-2 text-xs text-zinc-300">
|
||||
<div className="p-3 panel-surface flex flex-wrap items-center justify-between gap-3">
|
||||
<div className="flex items-center gap-2 text-xs text-muted">
|
||||
<Calendar className="w-4 h-4 text-accent" />
|
||||
<span>Aufgabe mit Fälligkeitsdatum anlegen:</span>
|
||||
</div>
|
||||
@@ -456,8 +458,8 @@ export const TriageDeck: React.FC<TriageDeckProps> = ({
|
||||
|
||||
{/* Convert to Shared List Item Popover */}
|
||||
{showListSelector && (
|
||||
<div className="p-3 bg-panel border border-border">
|
||||
<p className="text-xs text-zinc-400 mb-2">
|
||||
<div className="p-3 panel-surface">
|
||||
<p className="text-xs text-muted mb-2">
|
||||
Quick Dump direkt einer Liste zuordnen:
|
||||
</p>
|
||||
<div className="flex flex-wrap gap-1.5">
|
||||
@@ -475,7 +477,7 @@ export const TriageDeck: React.FC<TriageDeckProps> = ({
|
||||
</button>
|
||||
))
|
||||
) : (
|
||||
<span className="text-xs text-zinc-400">Keine Listen vorhanden.</span>
|
||||
<span className="text-xs text-muted">Keine Listen vorhanden.</span>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
@@ -489,7 +491,7 @@ export const TriageDeck: React.FC<TriageDeckProps> = ({
|
||||
title="Wegwerfen (Taste H oder Pfeil links)"
|
||||
className="btn-action h-8 px-2.5 justify-center"
|
||||
>
|
||||
<X className="w-3.5 h-3.5 text-zinc-400" />
|
||||
<X className="w-3.5 h-3.5 text-muted" />
|
||||
<span>Wegwerfen</span>
|
||||
</button>
|
||||
|
||||
@@ -502,7 +504,7 @@ export const TriageDeck: React.FC<TriageDeckProps> = ({
|
||||
cards.length <= 1 ? 'opacity-40 cursor-not-allowed' : ''
|
||||
}`}
|
||||
>
|
||||
<SkipForward className="w-3.5 h-3.5 text-zinc-400" />
|
||||
<SkipForward className="w-3.5 h-3.5 text-muted" />
|
||||
<span>Später</span>
|
||||
</button>
|
||||
|
||||
@@ -514,7 +516,7 @@ export const TriageDeck: React.FC<TriageDeckProps> = ({
|
||||
}}
|
||||
title="Auf eine geteilte Liste setzen"
|
||||
className={`btn-action h-8 px-2.5 justify-center ${
|
||||
showListSelector ? 'border-accent text-accent bg-accent/20' : ''
|
||||
showListSelector ? 'border-accent text-accent bg-accent-dim' : ''
|
||||
}`}
|
||||
>
|
||||
<ShoppingCart className="w-3.5 h-3.5 text-accent" />
|
||||
@@ -539,7 +541,7 @@ export const TriageDeck: React.FC<TriageDeckProps> = ({
|
||||
}}
|
||||
title="Als Aufgabe mit Fälligkeitsdatum (Taste T)"
|
||||
className={`btn-action h-8 px-2.5 justify-center ${
|
||||
showDateModal ? 'border-accent text-accent bg-accent/20' : ''
|
||||
showDateModal ? 'border-accent text-accent bg-accent-dim' : ''
|
||||
}`}
|
||||
>
|
||||
<Calendar className="w-3.5 h-3.5 text-accent" />
|
||||
@@ -561,16 +563,16 @@ export const TriageDeck: React.FC<TriageDeckProps> = ({
|
||||
{cards.length > 1 && (
|
||||
<div className="pt-2">
|
||||
<div className="flex items-center justify-between mb-1.5 px-0.5">
|
||||
<span className="text-xs font-semibold uppercase tracking-wider text-zinc-400 flex items-center gap-1.5">
|
||||
<span className="text-xs font-semibold uppercase tracking-wider text-muted flex items-center gap-1.5">
|
||||
<Layers className="w-3.5 h-3.5 text-accent" />
|
||||
Warteschlange ({cards.length - 1} weitere Quick Dumps)
|
||||
</span>
|
||||
<span className="text-[11px] text-zinc-500">
|
||||
<span className="text-[11px] text-faint">
|
||||
Klicken zum Vorholen oder direkt zuordnen
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div className="bg-panel border border-border divide-y divide-border max-h-60 overflow-y-auto">
|
||||
<div className="panel-surface divide-y divide-border max-h-60 overflow-y-auto">
|
||||
{cards.slice(1).map((item) => (
|
||||
<div
|
||||
key={item.id}
|
||||
@@ -581,7 +583,7 @@ export const TriageDeck: React.FC<TriageDeckProps> = ({
|
||||
className="flex-1 min-w-0 cursor-pointer flex items-center gap-2"
|
||||
>
|
||||
<span className="w-1.5 h-1.5 bg-accent flex-shrink-0" />
|
||||
<span className="text-xs text-zinc-200 truncate group-hover:text-white">
|
||||
<span className="text-xs text-muted truncate group-hover:text-main">
|
||||
{item.content}
|
||||
</span>
|
||||
</div>
|
||||
@@ -593,7 +595,7 @@ export const TriageDeck: React.FC<TriageDeckProps> = ({
|
||||
handleAction('keep', { convertTo: 'task', thoughtOverride: item })
|
||||
}
|
||||
title="Direkt zur Aufgabe machen"
|
||||
className="h-6 px-2 bg-canvas hover:bg-accent hover:text-white border border-border text-[11px] text-zinc-300 flex items-center gap-1 transition-colors"
|
||||
className="h-6 px-2 bg-canvas hover:bg-accent hover:text-on-accent border border-border rounded-btn text-[11px] text-muted flex items-center gap-1 transition-colors"
|
||||
>
|
||||
<Check className="w-3 h-3" />
|
||||
<span className="hidden sm:inline">Aufgabe</span>
|
||||
@@ -605,7 +607,7 @@ export const TriageDeck: React.FC<TriageDeckProps> = ({
|
||||
handleAction('keep', { convertTo: 'document', thoughtOverride: item })
|
||||
}
|
||||
title="Direkt als Workspace-Notiz anlegen"
|
||||
className="h-6 px-2 bg-canvas hover:bg-panel-elevated border border-border text-[11px] text-zinc-300 flex items-center gap-1 transition-colors"
|
||||
className="h-6 px-2 bg-canvas hover:bg-panel-elevated border border-border rounded-btn text-[11px] text-muted hover:text-main flex items-center gap-1 transition-colors"
|
||||
>
|
||||
<FileText className="w-3 h-3 text-accent" />
|
||||
<span className="hidden sm:inline">Notiz</span>
|
||||
@@ -622,7 +624,7 @@ export const TriageDeck: React.FC<TriageDeckProps> = ({
|
||||
})
|
||||
}
|
||||
title={`Direkt auf Liste "${lists[0].title}" setzen`}
|
||||
className="h-6 px-2 bg-canvas hover:bg-panel-elevated border border-border text-[11px] text-zinc-300 flex items-center gap-1 transition-colors"
|
||||
className="h-6 px-2 bg-canvas hover:bg-panel-elevated border border-border rounded-btn text-[11px] text-muted hover:text-main flex items-center gap-1 transition-colors"
|
||||
>
|
||||
<ShoppingCart className="w-3 h-3 text-accent" />
|
||||
<span className="hidden md:inline">{lists[0].title}</span>
|
||||
@@ -633,7 +635,7 @@ export const TriageDeck: React.FC<TriageDeckProps> = ({
|
||||
type="button"
|
||||
onClick={() => handleAction('discard', { thoughtOverride: item })}
|
||||
title="Wegwerfen"
|
||||
className="h-6 w-6 bg-canvas hover:bg-panel-elevated border border-border text-zinc-400 hover:text-white flex items-center justify-center transition-colors"
|
||||
className="h-6 w-6 bg-canvas hover:bg-panel-elevated border border-border rounded-btn text-muted hover:text-main flex items-center justify-center transition-colors"
|
||||
>
|
||||
<X className="w-3 h-3" />
|
||||
</button>
|
||||
|
||||
Reference in new issue
Block a user