Switch tasks quick nav to tabs
Some checks failed
linter / quality (push) Has been cancelled
tests / ci (push) Has been cancelled
tests / ui (push) Has been cancelled

This commit is contained in:
Codex Agent
2026-01-22 19:48:22 +01:00
parent cebc1d1ec5
commit fba9714ede
2 changed files with 55 additions and 71 deletions

View File

@@ -11,9 +11,9 @@ import { Pressable } from '@tamagui/react-native-web-lite';
import { Button } from '@tamagui/button'; import { Button } from '@tamagui/button';
import { AlertDialog } from '@tamagui/alert-dialog'; import { AlertDialog } from '@tamagui/alert-dialog';
import { ScrollView } from '@tamagui/scroll-view'; import { ScrollView } from '@tamagui/scroll-view';
import { ToggleGroup } from '@tamagui/toggle-group';
import { Switch } from '@tamagui/switch'; import { Switch } from '@tamagui/switch';
import { Checkbox } from '@tamagui/checkbox'; import { Checkbox } from '@tamagui/checkbox';
import { Tabs } from 'tamagui';
import { MobileShell, HeaderActionButton } from './components/MobileShell'; import { MobileShell, HeaderActionButton } from './components/MobileShell';
import { MobileCard, CTAButton, SkeletonCard, FloatingActionButton, PillBadge } from './components/Primitives'; import { MobileCard, CTAButton, SkeletonCard, FloatingActionButton, PillBadge } from './components/Primitives';
import { MobileField, MobileInput, MobileSelect, MobileTextArea } from './components/FormControls'; import { MobileField, MobileInput, MobileSelect, MobileTextArea } from './components/FormControls';
@@ -65,55 +65,6 @@ function allowPermission(permissions: string[], permission: string): boolean {
return false; return false;
} }
function QuickNavChip({
value,
label,
count,
onPress,
isActive = false,
}: {
value: TaskSectionKey;
label: string;
count: number;
onPress: () => void;
isActive?: boolean;
}) {
const { textStrong, border, surface, surfaceMuted, primary } = useAdminTheme();
const activeBorder = withAlpha(primary, 0.45);
const activeBackground = withAlpha(primary, 0.16);
return (
<ToggleGroup.Item
value={value}
onPress={onPress}
borderRadius={999}
borderWidth={1}
borderColor={isActive ? activeBorder : border}
backgroundColor={isActive ? activeBackground : surface}
paddingHorizontal="$3"
paddingVertical="$2"
height={36}
>
<XStack alignItems="center" space="$1.5">
<Text fontSize="$xs" fontWeight="700" color={textStrong}>
{label}
</Text>
<XStack
paddingHorizontal="$2"
paddingVertical="$0.5"
borderRadius={999}
borderWidth={1}
borderColor={isActive ? activeBorder : border}
backgroundColor={surfaceMuted}
>
<Text fontSize={10} fontWeight="800" color={textStrong}>
{count}
</Text>
</XStack>
</XStack>
</ToggleGroup.Item>
);
}
export default function MobileEventTasksPage() { export default function MobileEventTasksPage() {
const { slug: slugParam } = useParams<{ slug?: string }>(); const { slug: slugParam } = useParams<{ slug?: string }>();
const { activeEvent, selectEvent } = useEventContext(); const { activeEvent, selectEvent } = useEventContext();
@@ -258,6 +209,12 @@ export default function MobileEventTasksPage() {
setShowEmotionSheet(true); setShowEmotionSheet(true);
}; };
const handleQuickNavPress = (key: TaskSectionKey) => {
if (quickNavSelection === key) {
handleQuickNav(key);
}
};
const load = React.useCallback(async () => { const load = React.useCallback(async () => {
if (!slug) { if (!slug) {
try { try {
@@ -1093,8 +1050,7 @@ export default function MobileEventTasksPage() {
</XStack> </XStack>
<ScrollView horizontal showsHorizontalScrollIndicator={false}> <ScrollView horizontal showsHorizontalScrollIndicator={false}>
<ToggleGroup <Tabs
type="single"
value={quickNavSelection} value={quickNavSelection}
onValueChange={(next) => { onValueChange={(next) => {
const key = next as TaskSectionKey | ''; const key = next as TaskSectionKey | '';
@@ -1104,23 +1060,50 @@ export default function MobileEventTasksPage() {
setQuickNavSelection(key); setQuickNavSelection(key);
handleQuickNav(key); handleQuickNav(key);
}} }}
orientation="horizontal"
> >
<XStack space="$2" paddingVertical="$1"> <Tabs.List backgroundColor="transparent" borderWidth={0} paddingVertical="$1" gap="$2">
{sectionCounts.map((section) => ( {sectionCounts.map((section) => {
<QuickNavChip const isActive = quickNavSelection === section.key;
key={section.key} const activeBorder = withAlpha(primary, 0.45);
value={section.key} const activeBackground = withAlpha(primary, 0.16);
label={t(`events.tasks.sections.${section.key}`, section.key)} return (
count={section.count} <Tabs.Tab
onPress={() => { key={section.key}
setQuickNavSelection(section.key); value={section.key}
handleQuickNav(section.key); unstyled
}} onPress={() => handleQuickNavPress(section.key)}
isActive={quickNavSelection === section.key} borderRadius={999}
/> borderWidth={1}
))} borderColor={isActive ? activeBorder : border}
</XStack> backgroundColor={isActive ? activeBackground : surface}
</ToggleGroup> paddingHorizontal="$3"
paddingVertical="$2"
height={36}
pressStyle={{ backgroundColor: isActive ? activeBackground : surfaceMuted }}
>
<XStack alignItems="center" space="$1.5">
<Text fontSize="$xs" fontWeight="700" color={textStrong}>
{t(`events.tasks.sections.${section.key}`, section.key)}
</Text>
<XStack
paddingHorizontal="$2"
paddingVertical="$0.5"
borderRadius={999}
borderWidth={1}
borderColor={isActive ? activeBorder : border}
backgroundColor={surfaceMuted}
>
<Text fontSize={10} fontWeight="800" color={textStrong}>
{section.count}
</Text>
</XStack>
</XStack>
</Tabs.Tab>
);
})}
</Tabs.List>
</Tabs>
</ScrollView> </ScrollView>
</YStack> </YStack>
</Card> </Card>

View File

@@ -108,9 +108,10 @@ vi.mock('@tamagui/scroll-view', () => ({
ScrollView: ({ children }: { children: React.ReactNode }) => <div>{children}</div>, ScrollView: ({ children }: { children: React.ReactNode }) => <div>{children}</div>,
})); }));
vi.mock('@tamagui/toggle-group', () => ({ vi.mock('tamagui', () => ({
ToggleGroup: Object.assign(({ children }: { children: React.ReactNode }) => <div>{children}</div>, { Tabs: Object.assign(({ children }: { children: React.ReactNode }) => <div>{children}</div>, {
Item: ({ children }: { children: React.ReactNode }) => <div>{children}</div>, List: ({ children }: { children: React.ReactNode }) => <div>{children}</div>,
Tab: ({ children }: { children: React.ReactNode }) => <button type="button">{children}</button>,
}), }),
})); }));