feat(challenges): 新增挑战模块与详情页,优化标签栏布局
- 新增挑战列表页 `app/(tabs)/challenges.tsx`,展示热门挑战卡片 - 新增挑战详情页 `app/challenges/[id].tsx`,支持排行榜、分享与参与 - 在标签栏中新增“挑战”入口,替换原有“发现”与“AI”页 - 调整标签栏间距与圆角,适配新布局 - 新增挑战相关路由常量 `TAB_CHALLENGES` - 迁移 `coach.tsx` 与 `explore.tsx` 至根目录,保持结构清晰
This commit is contained in:
@@ -21,8 +21,8 @@ type TabConfig = {
|
||||
|
||||
const TAB_CONFIGS: Record<string, TabConfig> = {
|
||||
statistics: { icon: 'chart.pie.fill', title: '健康' },
|
||||
// explore: { icon: 'magnifyingglass.circle.fill', title: '发现' },
|
||||
goals: { icon: 'flag.fill', title: '习惯' },
|
||||
challenges: { icon: 'trophy.fill', title: '挑战' },
|
||||
personal: { icon: 'person.fill', title: '个人' },
|
||||
};
|
||||
|
||||
@@ -35,9 +35,10 @@ export default function TabLayout() {
|
||||
// Helper function to determine if a tab is selected
|
||||
const isTabSelected = (routeName: string): boolean => {
|
||||
const routeMap: Record<string, string> = {
|
||||
explore: ROUTES.TAB_EXPLORE,
|
||||
goals: ROUTES.TAB_GOALS,
|
||||
statistics: ROUTES.TAB_STATISTICS,
|
||||
goals: ROUTES.TAB_GOALS,
|
||||
challenges: ROUTES.TAB_CHALLENGES,
|
||||
personal: ROUTES.TAB_PERSONAL,
|
||||
};
|
||||
|
||||
return routeMap[routeName] === pathname || pathname.includes(routeName);
|
||||
@@ -69,11 +70,11 @@ export default function TabLayout() {
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
flexDirection: 'row',
|
||||
marginHorizontal: 6,
|
||||
marginHorizontal: 2,
|
||||
marginVertical: 10,
|
||||
borderRadius: 25,
|
||||
backgroundColor: isSelected ? colorTokens.tabBarActiveBackground : 'transparent',
|
||||
paddingHorizontal: isSelected ? 16 : 10,
|
||||
paddingHorizontal: isSelected ? 8 : 4,
|
||||
paddingVertical: 8,
|
||||
}}
|
||||
>
|
||||
@@ -91,7 +92,7 @@ export default function TabLayout() {
|
||||
fontWeight: '600',
|
||||
marginLeft: 6,
|
||||
}}
|
||||
numberOfLines={0 as any}
|
||||
numberOfLines={1}
|
||||
>
|
||||
{tabConfig.title}
|
||||
</Text>
|
||||
@@ -148,12 +149,12 @@ export default function TabLayout() {
|
||||
shadowOpacity: glassEffectAvailable ? 0.1 : 0.2,
|
||||
shadowRadius: 10,
|
||||
elevation: 5,
|
||||
paddingHorizontal: 10,
|
||||
paddingHorizontal: 6,
|
||||
paddingTop: 0,
|
||||
paddingBottom: 0,
|
||||
marginHorizontal: 20,
|
||||
left: 20,
|
||||
right: 20,
|
||||
marginHorizontal: 16,
|
||||
left: 16,
|
||||
right: 16,
|
||||
alignSelf: 'center',
|
||||
borderWidth: glassEffectAvailable ? 1 : 0,
|
||||
borderColor: glassEffectAvailable ? (theme === 'dark' ? 'rgba(255,255,255,0.1)' : 'rgba(0,0,0,0.1)') : 'transparent',
|
||||
@@ -177,7 +178,11 @@ export default function TabLayout() {
|
||||
</NativeTabs.Trigger>
|
||||
<NativeTabs.Trigger name="goals">
|
||||
<Icon sf="flag.fill" drawable="custom_settings_drawable" />
|
||||
<Label>目标</Label>
|
||||
<Label>习惯</Label>
|
||||
</NativeTabs.Trigger>
|
||||
<NativeTabs.Trigger name="challenges">
|
||||
<Icon sf="trophy.fill" drawable="custom_android_drawable" />
|
||||
<Label>挑战</Label>
|
||||
</NativeTabs.Trigger>
|
||||
<NativeTabs.Trigger name="personal">
|
||||
<Icon sf="person.fill" drawable="custom_settings_drawable" />
|
||||
@@ -193,9 +198,8 @@ export default function TabLayout() {
|
||||
>
|
||||
|
||||
<Tabs.Screen name="statistics" options={{ title: '健康' }} />
|
||||
<Tabs.Screen name="explore" options={{ title: '发现', href: null }} />
|
||||
<Tabs.Screen name="coach" options={{ title: 'AI', href: null }} />
|
||||
<Tabs.Screen name="goals" options={{ title: '习惯' }} />
|
||||
<Tabs.Screen name="challenges" options={{ title: '挑战' }} />
|
||||
<Tabs.Screen name="personal" options={{ title: '个人' }} />
|
||||
</Tabs>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user