Fix sticky tasks toolbar layout
This commit is contained in:
@@ -555,6 +555,7 @@ html.guest-theme.dark {
|
|||||||
position: sticky;
|
position: sticky;
|
||||||
top: calc(env(safe-area-inset-top, 0px) + 76px);
|
top: calc(env(safe-area-inset-top, 0px) + 76px);
|
||||||
z-index: 45;
|
z-index: 45;
|
||||||
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (prefers-reduced-motion: reduce) {
|
@media (prefers-reduced-motion: reduce) {
|
||||||
|
|||||||
@@ -618,6 +618,254 @@ export default function MobileEventTasksPage() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const taskPanel = assignedTasks.length === 0 ? (
|
||||||
|
<YStack space="$2">
|
||||||
|
<MobileCard space="$2">
|
||||||
|
<Text fontSize={13} fontWeight="700" color={text}>
|
||||||
|
{t('events.tasks.emptyTitle', 'No photo tasks yet')}
|
||||||
|
</Text>
|
||||||
|
<Text fontSize={12} color={muted}>
|
||||||
|
{t('events.tasks.emptyBody', 'Create photo tasks or import a pack for your event.')}
|
||||||
|
</Text>
|
||||||
|
<XStack space="$2">
|
||||||
|
<CTAButton
|
||||||
|
label={t('events.tasks.emptyActionTask', 'Add photo task')}
|
||||||
|
onPress={() => setShowTaskSheet(true)}
|
||||||
|
fullWidth={false}
|
||||||
|
/>
|
||||||
|
<CTAButton
|
||||||
|
label={t('events.tasks.emptyActionPack', 'Import photo task pack')}
|
||||||
|
tone="ghost"
|
||||||
|
onPress={() => setShowCollectionSheet(true)}
|
||||||
|
fullWidth={false}
|
||||||
|
/>
|
||||||
|
</XStack>
|
||||||
|
</MobileCard>
|
||||||
|
<YGroup {...({ borderWidth: 1, borderColor: border, borderRadius: "$4", overflow: "hidden" } as any)}>
|
||||||
|
<YGroup.Item>
|
||||||
|
<ListItem
|
||||||
|
hoverTheme
|
||||||
|
pressTheme
|
||||||
|
onPress={() => setShowTaskSheet(true)}
|
||||||
|
title={
|
||||||
|
<XStack alignItems="center" space="$2">
|
||||||
|
<YStack
|
||||||
|
width={28}
|
||||||
|
height={28}
|
||||||
|
borderRadius={14}
|
||||||
|
backgroundColor={primary}
|
||||||
|
alignItems="center"
|
||||||
|
justifyContent="center"
|
||||||
|
>
|
||||||
|
<Plus size={14} color={surface} />
|
||||||
|
</YStack>
|
||||||
|
<Text fontSize={12.5} fontWeight="700" color={text}>
|
||||||
|
{t('events.tasks.addTask', 'Fotoaufgabe hinzufügen')}
|
||||||
|
</Text>
|
||||||
|
</XStack>
|
||||||
|
}
|
||||||
|
subTitle={
|
||||||
|
<Text fontSize={11.5} color={muted}>
|
||||||
|
{t('events.tasks.addTaskHint', 'Erstelle eine neue Fotoaufgabe für dieses Event.')}
|
||||||
|
</Text>
|
||||||
|
}
|
||||||
|
paddingVertical="$2"
|
||||||
|
paddingHorizontal="$3"
|
||||||
|
iconAfter={<ChevronRight size={16} color={muted} />}
|
||||||
|
/>
|
||||||
|
</YGroup.Item>
|
||||||
|
<YGroup.Item>
|
||||||
|
<ListItem
|
||||||
|
hoverTheme
|
||||||
|
pressTheme
|
||||||
|
onPress={() => setShowCollectionSheet(true)}
|
||||||
|
title={
|
||||||
|
<XStack alignItems="center" space="$2">
|
||||||
|
<YStack
|
||||||
|
width={28}
|
||||||
|
height={28}
|
||||||
|
borderRadius={14}
|
||||||
|
backgroundColor={primary}
|
||||||
|
alignItems="center"
|
||||||
|
justifyContent="center"
|
||||||
|
>
|
||||||
|
<Plus size={14} color={surface} />
|
||||||
|
</YStack>
|
||||||
|
<Text fontSize={12.5} fontWeight="700" color={text}>
|
||||||
|
{t('events.tasks.import', 'Fotoaufgabenpaket importieren')}
|
||||||
|
</Text>
|
||||||
|
</XStack>
|
||||||
|
}
|
||||||
|
subTitle={
|
||||||
|
<Text fontSize={11.5} color={muted}>
|
||||||
|
{t('events.tasks.importHint', 'Nutze vordefinierte Pakete für deinen Event-Typ.')}
|
||||||
|
</Text>
|
||||||
|
}
|
||||||
|
paddingVertical="$2"
|
||||||
|
paddingHorizontal="$3"
|
||||||
|
iconAfter={<ChevronRight size={16} color={muted} />}
|
||||||
|
/>
|
||||||
|
</YGroup.Item>
|
||||||
|
</YGroup>
|
||||||
|
</YStack>
|
||||||
|
) : (
|
||||||
|
<YStack space="$2">
|
||||||
|
<YStack ref={assignedRef} />
|
||||||
|
<Text fontSize="$sm" color={muted}>
|
||||||
|
{t('events.tasks.count', '{{count}} photo tasks', { count: filteredTasks.length })}
|
||||||
|
</Text>
|
||||||
|
{selectionMode ? (
|
||||||
|
<MobileCard padding="$2.5" space="$2">
|
||||||
|
<Text fontSize={12} fontWeight="700" color={text}>
|
||||||
|
{t('events.tasks.selectionCount', '{{count}} ausgewählt', { count: selectedTaskIds.size })}
|
||||||
|
</Text>
|
||||||
|
<XStack space="$2">
|
||||||
|
<CTAButton
|
||||||
|
label={t('events.tasks.bulkRemove', 'Auswahl löschen')}
|
||||||
|
tone="danger"
|
||||||
|
fullWidth={false}
|
||||||
|
disabled={selectedTaskIds.size === 0 || bulkDeleteBusy}
|
||||||
|
onPress={() => setBulkDeleteOpen(true)}
|
||||||
|
/>
|
||||||
|
<CTAButton
|
||||||
|
label={t('events.tasks.bulkCancel', 'Auswahl beenden')}
|
||||||
|
tone="ghost"
|
||||||
|
fullWidth={false}
|
||||||
|
onPress={() => clearSelection()}
|
||||||
|
/>
|
||||||
|
</XStack>
|
||||||
|
</MobileCard>
|
||||||
|
) : null}
|
||||||
|
<YGroup {...({ borderWidth: 1, borderColor: border, borderRadius: "$4", overflow: "hidden" } as any)}>
|
||||||
|
{filteredTasks.map((task, idx) => (
|
||||||
|
<YGroup.Item key={task.id}>
|
||||||
|
<ListItem
|
||||||
|
hoverTheme
|
||||||
|
pressTheme
|
||||||
|
onPress={() => handleTaskPress(task)}
|
||||||
|
onPointerDown={() => startLongPress(task.id)}
|
||||||
|
onPointerUp={cancelLongPress}
|
||||||
|
onPointerLeave={cancelLongPress}
|
||||||
|
onPointerCancel={cancelLongPress}
|
||||||
|
title={
|
||||||
|
<XStack alignItems="center" space="$2">
|
||||||
|
{selectionMode ? (
|
||||||
|
<Checkbox
|
||||||
|
size="$3"
|
||||||
|
checked={selectedTaskIds.has(task.id)}
|
||||||
|
onCheckedChange={() => toggleSelectedTask(task.id)}
|
||||||
|
onPress={(event: any) => event?.stopPropagation?.()}
|
||||||
|
aria-label={t('events.tasks.select', 'Select photo task')}
|
||||||
|
>
|
||||||
|
<Checkbox.Indicator>
|
||||||
|
<Check size={14} color={text} />
|
||||||
|
</Checkbox.Indicator>
|
||||||
|
</Checkbox>
|
||||||
|
) : null}
|
||||||
|
<Text fontSize={12.5} fontWeight="600" color={text}>
|
||||||
|
{task.title}
|
||||||
|
</Text>
|
||||||
|
</XStack>
|
||||||
|
}
|
||||||
|
subTitle={
|
||||||
|
task.description ? (
|
||||||
|
<Text fontSize={11.5} fontWeight="400" color={subtle}>
|
||||||
|
{task.description}
|
||||||
|
</Text>
|
||||||
|
) : null
|
||||||
|
}
|
||||||
|
iconAfter={
|
||||||
|
selectionMode ? null : (
|
||||||
|
<XStack space="$2" alignItems="center">
|
||||||
|
{task.emotion ? (
|
||||||
|
<Tag label={task.emotion.name ?? ''} color={task.emotion.color ?? text} />
|
||||||
|
) : null}
|
||||||
|
<Button
|
||||||
|
size="$2"
|
||||||
|
circular
|
||||||
|
backgroundColor={dangerBg}
|
||||||
|
borderWidth={1}
|
||||||
|
borderColor={`${danger}33`}
|
||||||
|
icon={<Trash2 size={14} color={dangerText} />}
|
||||||
|
aria-label={t('events.tasks.remove', 'Remove photo task')}
|
||||||
|
disabled={busyId === task.id}
|
||||||
|
onPress={(event: any) => {
|
||||||
|
event?.stopPropagation?.();
|
||||||
|
setDeleteCandidate(task);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<ChevronRight size={14} color={subtle} />
|
||||||
|
</XStack>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
paddingVertical="$2"
|
||||||
|
paddingHorizontal="$3"
|
||||||
|
/>
|
||||||
|
</YGroup.Item>
|
||||||
|
))}
|
||||||
|
</YGroup>
|
||||||
|
<XStack justifyContent="space-between" alignItems="center" marginTop="$2">
|
||||||
|
<YStack ref={libraryRef} />
|
||||||
|
<Text fontSize={12.5} fontWeight="600" color={text}>
|
||||||
|
{t('events.tasks.library', 'Weitere Fotoaufgaben')}
|
||||||
|
</Text>
|
||||||
|
<Pressable onPress={() => setShowCollectionSheet(true)}>
|
||||||
|
<Text fontSize={12} fontWeight="600" color={primary}>
|
||||||
|
{t('events.tasks.import', 'Import photo task pack')}
|
||||||
|
</Text>
|
||||||
|
</Pressable>
|
||||||
|
</XStack>
|
||||||
|
<Pressable onPress={() => setExpandedLibrary((prev) => !prev)}>
|
||||||
|
<Text fontSize={12} fontWeight="600" color={primary}>
|
||||||
|
{expandedLibrary ? t('events.tasks.hideLibrary', 'Hide library') : t('events.tasks.viewAllLibrary', 'View all')}
|
||||||
|
</Text>
|
||||||
|
</Pressable>
|
||||||
|
{library.length === 0 ? (
|
||||||
|
<Text fontSize={12} fontWeight="500" color={subtle}>
|
||||||
|
{t('events.tasks.libraryEmpty', 'Keine weiteren Fotoaufgaben verfügbar.')}
|
||||||
|
</Text>
|
||||||
|
) : (
|
||||||
|
<YGroup {...({ borderWidth: 1, borderColor: border, borderRadius: "$4", overflow: "hidden" } as any)}>
|
||||||
|
{(expandedLibrary ? library : library.slice(0, 6)).map((task, idx, arr) => (
|
||||||
|
<YGroup.Item key={`lib-${task.id}`}>
|
||||||
|
<ListItem
|
||||||
|
hoverTheme
|
||||||
|
pressTheme
|
||||||
|
title={
|
||||||
|
<Text fontSize={12.5} fontWeight="600" color={text}>
|
||||||
|
{task.title}
|
||||||
|
</Text>
|
||||||
|
}
|
||||||
|
subTitle={
|
||||||
|
task.description ? (
|
||||||
|
<Text fontSize={11.5} fontWeight="400" color={subtle}>
|
||||||
|
{task.description}
|
||||||
|
</Text>
|
||||||
|
) : null
|
||||||
|
}
|
||||||
|
iconAfter={
|
||||||
|
<XStack space="$1.5" alignItems="center">
|
||||||
|
<Pressable onPress={() => quickAssign(task.id)}>
|
||||||
|
<XStack alignItems="center" space="$1">
|
||||||
|
<Plus size={14} color={primary} />
|
||||||
|
<Text fontSize={12} fontWeight="600" color={primary}>
|
||||||
|
{assigningId === task.id ? t('common.processing', '...') : t('events.tasks.add', 'Add')}
|
||||||
|
</Text>
|
||||||
|
</XStack>
|
||||||
|
</Pressable>
|
||||||
|
<ChevronRight size={14} color={subtle} />
|
||||||
|
</XStack>
|
||||||
|
}
|
||||||
|
paddingVertical="$2"
|
||||||
|
paddingHorizontal="$3"
|
||||||
|
/>
|
||||||
|
</YGroup.Item>
|
||||||
|
))}
|
||||||
|
</YGroup>
|
||||||
|
)}
|
||||||
|
</YStack>
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<MobileShell
|
<MobileShell
|
||||||
activeTab="tasks"
|
activeTab="tasks"
|
||||||
@@ -715,7 +963,13 @@ export default function MobileEventTasksPage() {
|
|||||||
</MobileCard>
|
</MobileCard>
|
||||||
) : null}
|
) : null}
|
||||||
|
|
||||||
{!loading ? (
|
{loading ? (
|
||||||
|
<YStack space="$2">
|
||||||
|
{Array.from({ length: 4 }).map((_, idx) => (
|
||||||
|
<SkeletonCard key={`tsk-${idx}`} height={70} />
|
||||||
|
))}
|
||||||
|
</YStack>
|
||||||
|
) : (
|
||||||
<YStack space="$2">
|
<YStack space="$2">
|
||||||
<Card
|
<Card
|
||||||
borderRadius={22}
|
borderRadius={22}
|
||||||
@@ -774,7 +1028,7 @@ export default function MobileEventTasksPage() {
|
|||||||
</YStack>
|
</YStack>
|
||||||
</Card>
|
</Card>
|
||||||
|
|
||||||
<YStack className="admin-sticky-toolbar" width="100%">
|
<div className="admin-sticky-toolbar">
|
||||||
<Card
|
<Card
|
||||||
borderRadius={20}
|
borderRadius={20}
|
||||||
borderWidth={2}
|
borderWidth={2}
|
||||||
@@ -820,261 +1074,9 @@ export default function MobileEventTasksPage() {
|
|||||||
</Pressable>
|
</Pressable>
|
||||||
</XStack>
|
</XStack>
|
||||||
</Card>
|
</Card>
|
||||||
</YStack>
|
</div>
|
||||||
</YStack>
|
|
||||||
) : null}
|
|
||||||
|
|
||||||
{loading ? (
|
{taskPanel}
|
||||||
<YStack space="$2">
|
|
||||||
{Array.from({ length: 4 }).map((_, idx) => (
|
|
||||||
<SkeletonCard key={`tsk-${idx}`} height={70} />
|
|
||||||
))}
|
|
||||||
</YStack>
|
|
||||||
) : assignedTasks.length === 0 ? (
|
|
||||||
<YStack space="$2">
|
|
||||||
<MobileCard space="$2">
|
|
||||||
<Text fontSize={13} fontWeight="700" color={text}>
|
|
||||||
{t('events.tasks.emptyTitle', 'No photo tasks yet')}
|
|
||||||
</Text>
|
|
||||||
<Text fontSize={12} color={muted}>
|
|
||||||
{t('events.tasks.emptyBody', 'Create photo tasks or import a pack for your event.')}
|
|
||||||
</Text>
|
|
||||||
<XStack space="$2">
|
|
||||||
<CTAButton
|
|
||||||
label={t('events.tasks.emptyActionTask', 'Add photo task')}
|
|
||||||
onPress={() => setShowTaskSheet(true)}
|
|
||||||
fullWidth={false}
|
|
||||||
/>
|
|
||||||
<CTAButton
|
|
||||||
label={t('events.tasks.emptyActionPack', 'Import photo task pack')}
|
|
||||||
tone="ghost"
|
|
||||||
onPress={() => setShowCollectionSheet(true)}
|
|
||||||
fullWidth={false}
|
|
||||||
/>
|
|
||||||
</XStack>
|
|
||||||
</MobileCard>
|
|
||||||
<YGroup {...({ borderWidth: 1, borderColor: border, borderRadius: "$4", overflow: "hidden" } as any)}>
|
|
||||||
<YGroup.Item>
|
|
||||||
<ListItem
|
|
||||||
hoverTheme
|
|
||||||
pressTheme
|
|
||||||
onPress={() => setShowTaskSheet(true)}
|
|
||||||
title={
|
|
||||||
<XStack alignItems="center" space="$2">
|
|
||||||
<YStack
|
|
||||||
width={28}
|
|
||||||
height={28}
|
|
||||||
borderRadius={14}
|
|
||||||
backgroundColor={primary}
|
|
||||||
alignItems="center"
|
|
||||||
justifyContent="center"
|
|
||||||
>
|
|
||||||
<Plus size={14} color={surface} />
|
|
||||||
</YStack>
|
|
||||||
<Text fontSize={12.5} fontWeight="700" color={text}>
|
|
||||||
{t('events.tasks.addTask', 'Fotoaufgabe hinzufügen')}
|
|
||||||
</Text>
|
|
||||||
</XStack>
|
|
||||||
}
|
|
||||||
subTitle={
|
|
||||||
<Text fontSize={11.5} color={muted}>
|
|
||||||
{t('events.tasks.addTaskHint', 'Erstelle eine neue Fotoaufgabe für dieses Event.')}
|
|
||||||
</Text>
|
|
||||||
}
|
|
||||||
paddingVertical="$2"
|
|
||||||
paddingHorizontal="$3"
|
|
||||||
iconAfter={<ChevronRight size={16} color={muted} />}
|
|
||||||
/>
|
|
||||||
</YGroup.Item>
|
|
||||||
<YGroup.Item>
|
|
||||||
<ListItem
|
|
||||||
hoverTheme
|
|
||||||
pressTheme
|
|
||||||
onPress={() => setShowCollectionSheet(true)}
|
|
||||||
title={
|
|
||||||
<XStack alignItems="center" space="$2">
|
|
||||||
<YStack
|
|
||||||
width={28}
|
|
||||||
height={28}
|
|
||||||
borderRadius={14}
|
|
||||||
backgroundColor={primary}
|
|
||||||
alignItems="center"
|
|
||||||
justifyContent="center"
|
|
||||||
>
|
|
||||||
<Plus size={14} color={surface} />
|
|
||||||
</YStack>
|
|
||||||
<Text fontSize={12.5} fontWeight="700" color={text}>
|
|
||||||
{t('events.tasks.import', 'Fotoaufgabenpaket importieren')}
|
|
||||||
</Text>
|
|
||||||
</XStack>
|
|
||||||
}
|
|
||||||
subTitle={
|
|
||||||
<Text fontSize={11.5} color={muted}>
|
|
||||||
{t('events.tasks.importHint', 'Nutze vordefinierte Pakete für deinen Event-Typ.')}
|
|
||||||
</Text>
|
|
||||||
}
|
|
||||||
paddingVertical="$2"
|
|
||||||
paddingHorizontal="$3"
|
|
||||||
iconAfter={<ChevronRight size={16} color={muted} />}
|
|
||||||
/>
|
|
||||||
</YGroup.Item>
|
|
||||||
</YGroup>
|
|
||||||
</YStack>
|
|
||||||
) : (
|
|
||||||
<YStack space="$2">
|
|
||||||
<YStack ref={assignedRef} />
|
|
||||||
<Text fontSize="$sm" color={muted}>
|
|
||||||
{t('events.tasks.count', '{{count}} photo tasks', { count: filteredTasks.length })}
|
|
||||||
</Text>
|
|
||||||
{selectionMode ? (
|
|
||||||
<MobileCard padding="$2.5" space="$2">
|
|
||||||
<Text fontSize={12} fontWeight="700" color={text}>
|
|
||||||
{t('events.tasks.selectionCount', '{{count}} ausgewählt', { count: selectedTaskIds.size })}
|
|
||||||
</Text>
|
|
||||||
<XStack space="$2">
|
|
||||||
<CTAButton
|
|
||||||
label={t('events.tasks.bulkRemove', 'Auswahl löschen')}
|
|
||||||
tone="danger"
|
|
||||||
fullWidth={false}
|
|
||||||
disabled={selectedTaskIds.size === 0 || bulkDeleteBusy}
|
|
||||||
onPress={() => setBulkDeleteOpen(true)}
|
|
||||||
/>
|
|
||||||
<CTAButton
|
|
||||||
label={t('events.tasks.bulkCancel', 'Auswahl beenden')}
|
|
||||||
tone="ghost"
|
|
||||||
fullWidth={false}
|
|
||||||
onPress={() => clearSelection()}
|
|
||||||
/>
|
|
||||||
</XStack>
|
|
||||||
</MobileCard>
|
|
||||||
) : null}
|
|
||||||
<YGroup {...({ borderWidth: 1, borderColor: border, borderRadius: "$4", overflow: "hidden" } as any)}>
|
|
||||||
{filteredTasks.map((task, idx) => (
|
|
||||||
<YGroup.Item key={task.id}>
|
|
||||||
<ListItem
|
|
||||||
hoverTheme
|
|
||||||
pressTheme
|
|
||||||
onPress={() => handleTaskPress(task)}
|
|
||||||
onPointerDown={() => startLongPress(task.id)}
|
|
||||||
onPointerUp={cancelLongPress}
|
|
||||||
onPointerLeave={cancelLongPress}
|
|
||||||
onPointerCancel={cancelLongPress}
|
|
||||||
title={
|
|
||||||
<XStack alignItems="center" space="$2">
|
|
||||||
{selectionMode ? (
|
|
||||||
<Checkbox
|
|
||||||
size="$3"
|
|
||||||
checked={selectedTaskIds.has(task.id)}
|
|
||||||
onCheckedChange={() => toggleSelectedTask(task.id)}
|
|
||||||
onPress={(event: any) => event?.stopPropagation?.()}
|
|
||||||
aria-label={t('events.tasks.select', 'Select photo task')}
|
|
||||||
>
|
|
||||||
<Checkbox.Indicator>
|
|
||||||
<Check size={14} color={text} />
|
|
||||||
</Checkbox.Indicator>
|
|
||||||
</Checkbox>
|
|
||||||
) : null}
|
|
||||||
<Text fontSize={12.5} fontWeight="600" color={text}>
|
|
||||||
{task.title}
|
|
||||||
</Text>
|
|
||||||
</XStack>
|
|
||||||
}
|
|
||||||
subTitle={
|
|
||||||
task.description ? (
|
|
||||||
<Text fontSize={11.5} fontWeight="400" color={subtle}>
|
|
||||||
{task.description}
|
|
||||||
</Text>
|
|
||||||
) : null
|
|
||||||
}
|
|
||||||
iconAfter={
|
|
||||||
selectionMode ? null : (
|
|
||||||
<XStack space="$2" alignItems="center">
|
|
||||||
{task.emotion ? (
|
|
||||||
<Tag label={task.emotion.name ?? ''} color={task.emotion.color ?? text} />
|
|
||||||
) : null}
|
|
||||||
<Button
|
|
||||||
size="$2"
|
|
||||||
circular
|
|
||||||
backgroundColor={dangerBg}
|
|
||||||
borderWidth={1}
|
|
||||||
borderColor={`${danger}33`}
|
|
||||||
icon={<Trash2 size={14} color={dangerText} />}
|
|
||||||
aria-label={t('events.tasks.remove', 'Remove photo task')}
|
|
||||||
disabled={busyId === task.id}
|
|
||||||
onPress={(event: any) => {
|
|
||||||
event?.stopPropagation?.();
|
|
||||||
setDeleteCandidate(task);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<ChevronRight size={14} color={subtle} />
|
|
||||||
</XStack>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
paddingVertical="$2"
|
|
||||||
paddingHorizontal="$3"
|
|
||||||
/>
|
|
||||||
</YGroup.Item>
|
|
||||||
))}
|
|
||||||
</YGroup>
|
|
||||||
<XStack justifyContent="space-between" alignItems="center" marginTop="$2">
|
|
||||||
<YStack ref={libraryRef} />
|
|
||||||
<Text fontSize={12.5} fontWeight="600" color={text}>
|
|
||||||
{t('events.tasks.library', 'Weitere Fotoaufgaben')}
|
|
||||||
</Text>
|
|
||||||
<Pressable onPress={() => setShowCollectionSheet(true)}>
|
|
||||||
<Text fontSize={12} fontWeight="600" color={primary}>
|
|
||||||
{t('events.tasks.import', 'Import photo task pack')}
|
|
||||||
</Text>
|
|
||||||
</Pressable>
|
|
||||||
</XStack>
|
|
||||||
<Pressable onPress={() => setExpandedLibrary((prev) => !prev)}>
|
|
||||||
<Text fontSize={12} fontWeight="600" color={primary}>
|
|
||||||
{expandedLibrary ? t('events.tasks.hideLibrary', 'Hide library') : t('events.tasks.viewAllLibrary', 'View all')}
|
|
||||||
</Text>
|
|
||||||
</Pressable>
|
|
||||||
{library.length === 0 ? (
|
|
||||||
<Text fontSize={12} fontWeight="500" color={subtle}>
|
|
||||||
{t('events.tasks.libraryEmpty', 'Keine weiteren Fotoaufgaben verfügbar.')}
|
|
||||||
</Text>
|
|
||||||
) : (
|
|
||||||
<YGroup {...({ borderWidth: 1, borderColor: border, borderRadius: "$4", overflow: "hidden" } as any)}>
|
|
||||||
{(expandedLibrary ? library : library.slice(0, 6)).map((task, idx, arr) => (
|
|
||||||
<YGroup.Item key={`lib-${task.id}`}>
|
|
||||||
<ListItem
|
|
||||||
hoverTheme
|
|
||||||
pressTheme
|
|
||||||
title={
|
|
||||||
<Text fontSize={12.5} fontWeight="600" color={text}>
|
|
||||||
{task.title}
|
|
||||||
</Text>
|
|
||||||
}
|
|
||||||
subTitle={
|
|
||||||
task.description ? (
|
|
||||||
<Text fontSize={11.5} fontWeight="400" color={subtle}>
|
|
||||||
{task.description}
|
|
||||||
</Text>
|
|
||||||
) : null
|
|
||||||
}
|
|
||||||
iconAfter={
|
|
||||||
<XStack space="$1.5" alignItems="center">
|
|
||||||
<Pressable onPress={() => quickAssign(task.id)}>
|
|
||||||
<XStack alignItems="center" space="$1">
|
|
||||||
<Plus size={14} color={primary} />
|
|
||||||
<Text fontSize={12} fontWeight="600" color={primary}>
|
|
||||||
{assigningId === task.id ? t('common.processing', '...') : t('events.tasks.add', 'Add')}
|
|
||||||
</Text>
|
|
||||||
</XStack>
|
|
||||||
</Pressable>
|
|
||||||
<ChevronRight size={14} color={subtle} />
|
|
||||||
</XStack>
|
|
||||||
}
|
|
||||||
paddingVertical="$2"
|
|
||||||
paddingHorizontal="$3"
|
|
||||||
/>
|
|
||||||
</YGroup.Item>
|
|
||||||
))}
|
|
||||||
</YGroup>
|
|
||||||
)}
|
|
||||||
</YStack>
|
</YStack>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user