feat: redesign bottom navigation with day-picker styling

- Add a compact sky-blue rounded navigation group based on the day picker geometry.
- Use coral for the selected destination and the separate global add button.
- Add a functional global Add Class action that works from every tab.
- Cover the global navigation action with Playwright.
This commit is contained in:
2026-09-05 10:27:35 +05:30
parent 829b3234e5
commit b0bdfd2ca5
5 changed files with 186 additions and 51 deletions

View File

@@ -1,18 +1,23 @@
import { Tabs } from 'expo-router';
import { GlobalAddClassProvider } from '@/components/global-add-class';
import { BottomTabBar } from '@/components/ui/bottom-tab-bar';
export default function TabLayout() {
return <Tabs
tabBar={(props) => <BottomTabBar {...props} />}
screenOptions={{
headerShown: false,
// The visible dock is independently absolute; this removes React Navigation's reserved tab-bar scene area.
tabBarStyle: { position: 'absolute', height: 0, backgroundColor: 'transparent', borderTopWidth: 0, elevation: 0 },
}}>
<Tabs.Screen name="index" options={{ title: 'Today' }} />
<Tabs.Screen name="timetable" options={{ title: 'Timetable' }} />
<Tabs.Screen name="attendance" options={{ title: 'Attendance' }} />
<Tabs.Screen name="settings" options={{ title: 'Settings' }} />
</Tabs>;
return (
<GlobalAddClassProvider>
<Tabs
tabBar={(props) => <BottomTabBar {...props} />}
screenOptions={{
headerShown: false,
// The visible dock is independently absolute; this removes React Navigation's reserved tab-bar scene area.
tabBarStyle: { position: 'absolute', height: 0, backgroundColor: 'transparent', borderTopWidth: 0, elevation: 0 },
}}>
<Tabs.Screen name="index" options={{ title: 'Today' }} />
<Tabs.Screen name="timetable" options={{ title: 'Timetable' }} />
<Tabs.Screen name="attendance" options={{ title: 'Attendance' }} />
<Tabs.Screen name="settings" options={{ title: 'Settings' }} />
</Tabs>
</GlobalAddClassProvider>
);
}

View File

@@ -5,6 +5,7 @@ import { useCallback, useEffect, useMemo, useState } from 'react';
import { ActivityIndicator, Alert, Platform, Pressable, ScrollView, StyleSheet, View } from 'react-native';
import { AddClassModal } from '@/components/add-class-modal';
import { useGlobalAddClass } from '@/components/global-add-class';
import {
AppHeader,
AppText,
@@ -50,6 +51,7 @@ const daysInMonth = (date: Date) => new Date(date.getFullYear(), date.getMonth()
export default function TodayScreen() {
const router = useRouter();
const { revision: globalAddRevision } = useGlobalAddClass();
const [activeDate, setActiveDate] = useState(() => new Date());
const [calendarMonth, setCalendarMonth] = useState(() => startOfMonth(new Date()));
const [classes, setClasses] = useState<Session[]>([]);
@@ -93,6 +95,10 @@ export default function TodayScreen() {
useEffect(() => { loadSchedule(); }, [loadSchedule, refresh]);
useEffect(() => {
if (globalAddRevision > 0) setRefresh((current) => current + 1);
}, [globalAddRevision]);
useEffect(() => {
collegeApi.attendanceSummary().then(({ subjects }) => {
const total = subjects.reduce((value, subject) => value + subject.total, 0);