UI: restyle task detail onto the new tokens
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -4,11 +4,11 @@ import { Pressable, ScrollView, StyleSheet, Text, View } from "react-native";
|
||||
import DateField from "../../components/DateField";
|
||||
import EstimateChips from "../../components/EstimateChips";
|
||||
import PriorityChips from "../../components/PriorityChips";
|
||||
import { Button, Chips, Field } from "../../components/ui";
|
||||
import { Button, Chips, Empty, Field } from "../../components/ui";
|
||||
import { haptic } from "../../lib/haptics";
|
||||
import { REPEAT_LABEL, REPEATS } from "../../lib/repeat";
|
||||
import { activeProjects, knownContexts, trashTask, updateTask } from "../../lib/store";
|
||||
import { C } from "../../lib/theme";
|
||||
import { C, radius, space, type } from "../../lib/theme";
|
||||
import { useStore } from "../../lib/useStore";
|
||||
import type { Repeat, Task, TaskStatus } from "../../lib/types";
|
||||
|
||||
@@ -22,7 +22,7 @@ export default function TaskDetail() {
|
||||
// Draft is local to the screen; nothing is written until Save.
|
||||
const [draft, setDraft] = useState<Task | null>(original ?? null);
|
||||
|
||||
if (!draft) return <Text style={{ color: C.muted, margin: 16 }}>Task not found.</Text>;
|
||||
if (!draft) return <Empty>Task not found.</Empty>;
|
||||
|
||||
const set = (patch: Partial<Task>) => setDraft({ ...draft, ...patch });
|
||||
|
||||
@@ -50,7 +50,7 @@ export default function TaskDetail() {
|
||||
|
||||
if (draft.status === "trashed") {
|
||||
return (
|
||||
<ScrollView style={{ flex: 1, backgroundColor: C.bg }} contentContainerStyle={{ padding: 16 }}>
|
||||
<ScrollView style={{ flex: 1, backgroundColor: C.bg }} contentContainerStyle={s.content}>
|
||||
<Text style={s.trashedTitle}>{draft.title}</Text>
|
||||
<Text style={s.trashedMeta}>In the trash.</Text>
|
||||
<Button
|
||||
@@ -66,7 +66,12 @@ export default function TaskDetail() {
|
||||
}
|
||||
|
||||
return (
|
||||
<ScrollView style={{ flex: 1, backgroundColor: C.bg }} contentContainerStyle={{ padding: 16 }}>
|
||||
<ScrollView
|
||||
style={{ flex: 1, backgroundColor: C.bg }}
|
||||
contentContainerStyle={s.content}
|
||||
keyboardShouldPersistTaps="handled"
|
||||
showsVerticalScrollIndicator={false}
|
||||
>
|
||||
<Field label="Title" value={draft.title} onChangeText={(v) => set({ title: v })} />
|
||||
<PriorityChips value={draft.priority} onChange={(priority) => set({ priority })} />
|
||||
<EstimateChips value={draft.estimate_min} onChange={(estimate_min) => set({ estimate_min })} />
|
||||
@@ -87,18 +92,25 @@ export default function TaskDetail() {
|
||||
/>
|
||||
{contexts.length > 0 && (
|
||||
<View style={s.contextRow}>
|
||||
{contexts.map((c) => (
|
||||
<Pressable
|
||||
key={c}
|
||||
style={[s.contextChip, draft.context === c && s.contextChipActive]}
|
||||
onPress={() => {
|
||||
haptic.select();
|
||||
set({ context: draft.context === c ? null : c });
|
||||
}}
|
||||
>
|
||||
<Text style={[s.contextText, draft.context === c && { color: C.text }]}>{c}</Text>
|
||||
</Pressable>
|
||||
))}
|
||||
{contexts.map((c) => {
|
||||
const active = draft.context === c;
|
||||
return (
|
||||
<Pressable
|
||||
key={c}
|
||||
style={({ pressed }) => [
|
||||
s.contextChip,
|
||||
active && s.contextChipActive,
|
||||
pressed && !active && { backgroundColor: C.surface2 },
|
||||
]}
|
||||
onPress={() => {
|
||||
haptic.select();
|
||||
set({ context: active ? null : c });
|
||||
}}
|
||||
>
|
||||
<Text style={[s.contextText, active && s.contextTextActive]}>{c}</Text>
|
||||
</Pressable>
|
||||
);
|
||||
})}
|
||||
</View>
|
||||
)}
|
||||
{draft.status === "waiting" && (
|
||||
@@ -126,7 +138,7 @@ export default function TaskDetail() {
|
||||
value={draft.notes}
|
||||
onChangeText={(v) => set({ notes: v })}
|
||||
multiline
|
||||
style={{ minHeight: 80, textAlignVertical: "top" }}
|
||||
style={{ minHeight: 96, textAlignVertical: "top" }}
|
||||
/>
|
||||
<Button title="Save" onPress={save} />
|
||||
<Button
|
||||
@@ -142,18 +154,26 @@ export default function TaskDetail() {
|
||||
}
|
||||
|
||||
const s = StyleSheet.create({
|
||||
trashedTitle: { color: C.text, fontSize: 18, marginBottom: 6 },
|
||||
trashedMeta: { color: C.muted, fontSize: 14, marginBottom: 18 },
|
||||
contextRow: { flexDirection: "row", flexWrap: "wrap", gap: 8, marginTop: -6, marginBottom: 14 },
|
||||
content: { padding: space.lg, paddingBottom: space.xxl },
|
||||
trashedTitle: { ...type.title, fontSize: 22, color: C.text, marginBottom: space.xs },
|
||||
trashedMeta: { ...type.body, color: C.muted, marginBottom: space.xl },
|
||||
contextRow: {
|
||||
flexDirection: "row",
|
||||
flexWrap: "wrap",
|
||||
gap: space.sm,
|
||||
marginTop: -space.sm,
|
||||
marginBottom: space.lg,
|
||||
},
|
||||
contextChip: {
|
||||
paddingVertical: 6,
|
||||
paddingHorizontal: 12,
|
||||
borderRadius: 16,
|
||||
paddingVertical: 7,
|
||||
paddingHorizontal: space.md + 1,
|
||||
borderRadius: radius.pill,
|
||||
backgroundColor: C.surface,
|
||||
borderWidth: 1,
|
||||
borderWidth: StyleSheet.hairlineWidth,
|
||||
borderColor: C.border,
|
||||
},
|
||||
contextChipActive: { backgroundColor: C.surface2, borderColor: C.accent },
|
||||
contextText: { color: C.muted, fontSize: 13 },
|
||||
deferHint: { color: C.muted, fontSize: 13, marginTop: -8, marginBottom: 12 },
|
||||
contextChipActive: { backgroundColor: C.accentSoft, borderColor: C.accent },
|
||||
contextText: { ...type.meta, color: C.textSecondary },
|
||||
contextTextActive: { color: C.accent, fontWeight: "600" },
|
||||
deferHint: { ...type.meta, color: C.muted, marginTop: -space.sm, marginBottom: space.md },
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user