frontend: add a settings tab and do some light linting
Parents:
5d3a9484 file(s) changed
- frontend/app/(tabs)/_layout.tsx +10 -0
- frontend/app/(tabs)/settings.tsx +49 -0
- frontend/components/ui/icon-symbol.tsx +1 -0
- frontend/context/AuthContext.tsx +7 -5
frontend/app/(tabs)/_layout.tsx
@@ -37,6 +37,7 @@ tabBarActiveTintColor: Colors[colorScheme ?? 'light'].tint,
37 37 headerShown: false,
38 38 tabBarButton: HapticTab,
39 39 }}>
40 +
40 41 <Tabs.Screen
41 42 name="index"
42 43 options={{
@@ -44,11 +45,20 @@ title: 'Home',
44 45 tabBarIcon: ({ color }) => <IconSymbol size={28} name="house.fill" color={color} />,
45 46 }}
46 47 />
48 +
47 49 <Tabs.Screen
48 50 name="explore"
49 51 options={{
50 52 title: 'Explore',
51 53 tabBarIcon: ({ color }) => <IconSymbol size={28} name="paperplane.fill" color={color} />,
54 + }}
55 + />
56 +
57 + <Tabs.Screen
58 + name="settings"
59 + options={{
60 + title: 'Configurações',
61 + tabBarIcon: ({ color }) => <IconSymbol size={28} name="settings.fill" color={color} />,
52 62 }}
53 63 />
54 64 </Tabs>
frontend/app/(tabs)/settings.tsx
@@ -0,0 +1,49 @@
1 + import { StyleSheet } from 'react-native';
2 + import ParallaxScrollView from '@/components/misc/parallax-scroll-view';
3 +
4 + import { ThemedText } from '@/components/misc/themed-text';
5 + import { ThemedView } from '@/components/misc/themed-view';
6 + import { IconSymbol } from '@/components/ui/icon-symbol';
7 + import { Fonts } from '@/constants/theme';
8 +
9 + export default function Settings() {
10 + return (
11 + <ParallaxScrollView
12 + headerBackgroundColor={{ light: '#D0D0D0', dark: '#353636' }}
13 + headerImage={
14 + <IconSymbol
15 + size={310}
16 + color="#808080"
17 + name="chevron.left.forwardslash.chevron.right"
18 + style={styles.headerImage}
19 + />
20 + }>
21 + <ThemedView style={styles.titleContainer}>
22 + <ThemedText
23 + type="title"
24 + style={{
25 + fontFamily: Fonts.rounded,
26 + }}>
27 + Explore
28 + </ThemedText>
29 + </ThemedView>
30 + <ThemedText>
31 + This app includes example code to help you get started.
32 + </ThemedText>
33 + </ParallaxScrollView>
34 + )
35 + }
36 +
37 +
38 + const styles = StyleSheet.create({
39 + headerImage: {
40 + color: '#808080',
41 + bottom: -90,
42 + left: -35,
43 + position: 'absolute',
44 + },
45 + titleContainer: {
46 + flexDirection: 'row',
47 + gap: 8,
48 + },
49 + });
frontend/components/ui/icon-symbol.tsx
@@ -18,6 +18,7 @@ 'house.fill': 'home',
18 18 'paperplane.fill': 'send',
19 19 'chevron.left.forwardslash.chevron.right': 'code',
20 20 'chevron.right': 'chevron-right',
21 + 'settings.fill': 'settings'
21 22 } as IconMapping;
22 23
23 24 /**
frontend/context/AuthContext.tsx
@@ -1,6 +1,10 @@
1 1 import React, { createContext, useContext, useEffect, useState } from 'react';
2 2 import { apiClient, User } from '@/lib/api';
3 3
4 + interface AuthProviderProps {
5 + children: React.ReactNode;
6 + }
7 +
4 8 interface AuthContextType {
5 9 user: User | null;
6 10 isLoading: boolean;
@@ -24,14 +28,11 @@ const context = useContext(AuthContext);
24 28 if (!context) {
25 29 throw new Error('useAuth must be used within an AuthProvider');
26 30 }
31 +
27 32 return context;
28 33 }
29 34
30 - interface AuthProviderProps {
31 - children: React.ReactNode;
32 - }
33 -
34 - export function AuthProvider({ children }: AuthProviderProps) {
35 + export const AuthProvider = ({ children }: AuthProviderProps) => {
35 36 const [user, setUser] = useState<User | null>(null);
36 37 const [isLoading, setIsLoading] = useState(true);
37 38
@@ -70,6 +71,7 @@ };
70 71
71 72 const login = async (email: string, password: string) => {
72 73 setIsLoading(true);
74 +
73 75 try {
74 76 const response = await apiClient.login(email, password);
75 77 setUser(response.user);