Implemented a shared mobile shell and navigation aligned to the new architecture, plus refactored the dashboard and
tab flows.
- Added a dynamic MobileShell with sticky header (notification bell with badge, quick QR when an event is
active, event switcher for multi-event users) and stabilized bottom tabs (home, tasks, uploads, profile)
driven by useMobileNav (resources/js/admin/mobile/components/MobileShell.tsx, components/BottomNav.tsx, hooks/
useMobileNav.ts).
- Centralized event handling now supports 0/1/many-event states without auto-selecting in multi-tenant mode and
exposes helper flags/activeSlug for consumers (resources/js/admin/context/EventContext.tsx).
- Rebuilt the mobile dashboard into explicit states: onboarding/no-event, single-event focus, and multi-event picker
with featured/secondary actions, KPI strip, and alerts (resources/js/admin/mobile/DashboardPage.tsx).
- Introduced tab entry points that respect event context and prompt selection when needed (resources/js/admin/
mobile/TasksTabPage.tsx, UploadsTabPage.tsx). Refreshed tasks/uploads detail screens to use the new shell and sync
event selection (resources/js/admin/mobile/EventTasksPage.tsx, EventPhotosPage.tsx).
- Updated mobile routes and existing screens to the new tab keys and header/footer behavior (resources/js/admin/
router.tsx, mobile/* pages, i18n nav/header strings).
This commit is contained in:
@@ -6,9 +6,8 @@ import { YStack, XStack } from '@tamagui/stacks';
|
||||
import { SizableText as Text } from '@tamagui/text';
|
||||
import { ListItem } from '@tamagui/list-item';
|
||||
import { Pressable } from '@tamagui/react-native-web-lite';
|
||||
import { MobileScaffold } from './components/Scaffold';
|
||||
import { MobileShell } from './components/MobileShell';
|
||||
import { MobileCard, CTAButton } from './components/Primitives';
|
||||
import { BottomNav } from './components/BottomNav';
|
||||
import {
|
||||
getEvent,
|
||||
getEventTasks,
|
||||
@@ -33,7 +32,7 @@ import { getApiErrorMessage } from '../lib/apiError';
|
||||
import toast from 'react-hot-toast';
|
||||
import { MobileSheet } from './components/Sheet';
|
||||
import { Tag } from './components/Tag';
|
||||
import { useMobileNav } from './hooks/useMobileNav';
|
||||
import { useEventContext } from '../context/EventContext';
|
||||
|
||||
const inputStyle: React.CSSProperties = {
|
||||
width: '100%',
|
||||
@@ -51,7 +50,8 @@ function InlineSeparator() {
|
||||
|
||||
export default function MobileEventTasksPage() {
|
||||
const { slug: slugParam } = useParams<{ slug?: string }>();
|
||||
const slug = slugParam ?? null;
|
||||
const { activeEvent, selectEvent } = useEventContext();
|
||||
const slug = slugParam ?? activeEvent?.slug ?? null;
|
||||
const navigate = useNavigate();
|
||||
const { t } = useTranslation('management');
|
||||
|
||||
@@ -67,7 +67,6 @@ export default function MobileEventTasksPage() {
|
||||
const [busyId, setBusyId] = React.useState<number | null>(null);
|
||||
const [assigningId, setAssigningId] = React.useState<number | null>(null);
|
||||
const [eventId, setEventId] = React.useState<number | null>(null);
|
||||
const { go } = useMobileNav(slug);
|
||||
const [searchTerm, setSearchTerm] = React.useState('');
|
||||
const [emotionFilter, setEmotionFilter] = React.useState<string>('');
|
||||
const [expandedLibrary, setExpandedLibrary] = React.useState(false);
|
||||
@@ -79,6 +78,11 @@ export default function MobileEventTasksPage() {
|
||||
const [editingEmotion, setEditingEmotion] = React.useState<TenantEmotion | null>(null);
|
||||
const [emotionForm, setEmotionForm] = React.useState({ name: '', color: '#e5e7eb' });
|
||||
const [savingEmotion, setSavingEmotion] = React.useState(false);
|
||||
React.useEffect(() => {
|
||||
if (slugParam && activeEvent?.slug !== slugParam) {
|
||||
selectEvent(slugParam);
|
||||
}
|
||||
}, [slugParam, activeEvent?.slug, selectEvent]);
|
||||
|
||||
const load = React.useCallback(async () => {
|
||||
if (!slug) {
|
||||
@@ -273,10 +277,11 @@ export default function MobileEventTasksPage() {
|
||||
}
|
||||
|
||||
return (
|
||||
<MobileScaffold
|
||||
<MobileShell
|
||||
activeTab="tasks"
|
||||
title={t('events.tasks.title', 'Tasks & Checklists')}
|
||||
onBack={() => navigate(-1)}
|
||||
rightSlot={
|
||||
headerActions={
|
||||
<XStack space="$2">
|
||||
<Pressable onPress={() => load()}>
|
||||
<RefreshCcw size={18} color="#0f172a" />
|
||||
@@ -286,9 +291,6 @@ export default function MobileEventTasksPage() {
|
||||
</Pressable>
|
||||
</XStack>
|
||||
}
|
||||
footer={
|
||||
<BottomNav active="tasks" onNavigate={go} />
|
||||
}
|
||||
>
|
||||
{error ? (
|
||||
<MobileCard>
|
||||
@@ -734,7 +736,7 @@ export default function MobileEventTasksPage() {
|
||||
>
|
||||
<Plus size={20} color="#ffffff" />
|
||||
</Pressable>
|
||||
</MobileScaffold>
|
||||
</MobileShell>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user