diff --git a/.gitignore b/.gitignore index e5ee6e8..67f991c 100644 --- a/.gitignore +++ b/.gitignore @@ -14,4 +14,6 @@ web-build/ .DS_Store firebase-config.json -facebook-config.json \ No newline at end of file +facebook-config.json +geminiconfig.json +geminiconfig.json diff --git a/app/screens/Items.tsx b/app/screens/Account.tsx similarity index 56% rename from app/screens/Items.tsx rename to app/screens/Account.tsx index 73bd549..f534414 100644 --- a/app/screens/Items.tsx +++ b/app/screens/Account.tsx @@ -2,15 +2,18 @@ import React from "react"; import { createNativeStackNavigator } from "@react-navigation/native-stack"; import ItemEditScreen from "./ItemEdit"; import ItemListScreen from "./ItemList"; +import MainLayout from "./Layout"; +import { Paragraph } from "react-native-paper"; //https://reactnavigation.org/docs/hello-react-navigation const ItemStack = createNativeStackNavigator(); const ItemScreen = () => { - return - - - + return ( + + da + + ); } export default ItemScreen; \ No newline at end of file diff --git a/app/screens/ChatAI.tsx b/app/screens/ChatAI.tsx new file mode 100644 index 0000000..a3147a9 --- /dev/null +++ b/app/screens/ChatAI.tsx @@ -0,0 +1,94 @@ +import React, { useState } from "react"; +import { View, TextInput, Button, ScrollView, StyleSheet, ActivityIndicator, Text } from "react-native"; +import { Paragraph } from "react-native-paper"; +import MainLayout from "./Layout"; +import { fetchGeminiResponse } from "../../utils/geminiApi"; + +const ChatScreen = () => { + const [messages, setMessages] = useState([{ sender: "user", text: "" }]); + const [input, setInput] = useState(""); + const [loading, setLoading] = useState(false); + + const sendMessage = async () => { + if (!input.trim()) return; + + const userMessage = { sender: "user", text: input }; + setMessages((prev: any) => [...prev, userMessage]); + setInput(""); + setLoading(true); + + const aiText = await fetchGeminiResponse(input); + const aiMessage = { sender: "ai", text: aiText }; + + setMessages((prev) => [...prev, aiMessage]); + setLoading(false); + }; + + return ( + + + {messages.map((msg, index) => ( + + {msg.text} + + ))} + {loading && } + + + + + diff --git a/app/screens/ItemList.tsx b/app/screens/ItemList.tsx index 7294b2c..e3c3915 100644 --- a/app/screens/ItemList.tsx +++ b/app/screens/ItemList.tsx @@ -1,22 +1,15 @@ import React, { useEffect, useState } from "react"; import MainLayout from "./Layout"; -import { getFirestore, onSnapshot, collection } from 'firebase/firestore'; import { Button, DataTable } from "react-native-paper"; -const db = getFirestore(); - const ItemListScreen = ({ navigation }: any) => { - const [data, setData] = useState<{ id?: string, label: string, quantity: number }[]>([]); + const [data, setData] = useState<{ id?: string, label: string, quantity: number }[]>([ + { id: '1', label: 'Apples', quantity: 5 }, + { id: '2', label: 'Bananas', quantity: 3 }, + { id: '3', label: 'Oranges', quantity: 7 } + ]); - useEffect(() => { - const unsubscribe = onSnapshot( - collection(db, 'items'), - snapshot => { - setData(snapshot.docs.map(d => ({ ...d.data() as any, id: d.id }))) - }); - return () => unsubscribe(); - }, [data]); /** https://callstack.github.io/react-native-paper/data-table.html */ diff --git a/app/screens/Layout.tsx b/app/screens/Layout.tsx index 345121f..766be72 100644 --- a/app/screens/Layout.tsx +++ b/app/screens/Layout.tsx @@ -1,42 +1,22 @@ import React, { useEffect, useState } from "react"; -import AsyncStorage from '@react-native-async-storage/async-storage'; import { SafeAreaView } from "react-native-safe-area-context"; import { Appbar } from "react-native-paper"; import { ActivityIndicator, View } from "react-native"; -import { - getAuth, - signOut -} from 'firebase/auth'; -import { initializeApp } from "firebase/app"; -import firebaseConfig from "../../firebase-config.json"; import { useNavigation } from "@react-navigation/native"; -const app = initializeApp(firebaseConfig); -const auth = getAuth(app); - const MainLayout = ({ children }: any) => { - const [user, setUser] = useState<{ displayName: string, email: string }>(); + const [user, setUser] = useState<{ displayName: string, email: string }>({displayName: 'Jane', email: 'jane@somewhere.com'}); const navigation = useNavigation() as any; - useEffect(() => { - const fetchUser = async () => { - const storedUser = await AsyncStorage.getItem('@user'); - if (!!storedUser) { - setUser(JSON.parse(storedUser)); - } - } - fetchUser(); - }, []) return ( user ? - - { await signOut(auth); navigation.navigate('Login') }} /> + { navigation.navigate('Login') }} /> - {children} + {children} : diff --git a/app/screens/Login.tsx b/app/screens/Login.tsx index 8fa13ff..0c74416 100644 --- a/app/screens/Login.tsx +++ b/app/screens/Login.tsx @@ -1,34 +1,10 @@ import React, { useState } from "react"; -import { initializeApp } from "firebase/app"; -import firebaseConfig from "../../firebase-config.json"; -import AsyncStorage from '@react-native-async-storage/async-storage'; -import { - getAuth, - initializeAuth, - onAuthStateChanged, - signInWithEmailAndPassword, - // @ts-ignore - getReactNativePersistence -} from 'firebase/auth'; -//@ts-ignore -import ReactNativeAsyncStorage from '@react-native-async-storage/async-storage'; import { StyleProp, View, ViewStyle } from "react-native"; import { Button, TextInput } from "react-native-paper"; -const app = initializeApp(firebaseConfig); -const auth = getAuth(app); -auth.setPersistence(getReactNativePersistence(ReactNativeAsyncStorage)); -const LoginScreen = ({ navigation }: any) => { - onAuthStateChanged(auth, user => { - if (user != null) { - AsyncStorage.setItem('@user', JSON.stringify(user)) - .then(() => navigation.navigate('Main')); - } else { - console.log('User is signed out'); - } - }); +const LoginScreen = ({ navigation }: any) => { const [email, setEmail] = useState(''); const [password, setPassword] = useState(''); @@ -40,12 +16,7 @@ const LoginScreen = ({ navigation }: any) => { }; const signIn = async () => { - try{ - const signInResult = await signInWithEmailAndPassword(auth, email, password); - console.log('User signed in: ', signInResult) - } catch (error) { - console.log('Error signing in: ', error); - } + navigation.navigate('Main') } return ( diff --git a/app/screens/Main.tsx b/app/screens/Main.tsx index f3b04cf..bcc9556 100644 --- a/app/screens/Main.tsx +++ b/app/screens/Main.tsx @@ -1,9 +1,16 @@ import React from "react"; import Icon from "@expo/vector-icons/MaterialCommunityIcons"; import { createBottomTabNavigator } from '@react-navigation/bottom-tabs'; -import HomeScreen from "./Home"; -import ItemScreen from "./Items"; - +import ChatScreen from "./ChatAI"; +import SearchScreen from "./Search"; +import { Colors } from "react-native/Libraries/NewAppScreen"; +import Entypo from '@expo/vector-icons/Entypo'; +import FontAwesome from '@expo/vector-icons/FontAwesome'; +import MaterialIcons from '@expo/vector-icons/MaterialIcons'; +import AccountScreen from "./Account"; +import FeedScreen from "./Feed"; +import HomeScreen from "./Home" +import Entypo1 from '@expo/vector-icons/Entypo'; //https://reactnavigation.org/docs/tab-based-navigation const Tab = createBottomTabNavigator(); @@ -17,21 +24,54 @@ const MainNavigator = () => ( headerShown: false, tabBarLabel: 'Home', tabBarIcon: ({ color }) => ( - + + ), + }} + /> + ( + + ), + }} + /> + ( + ), }} /> ( + + ), + }} + /> + ( - + ), }} - /> + /> ); diff --git a/app/screens/Search.tsx b/app/screens/Search.tsx new file mode 100644 index 0000000..96fca12 --- /dev/null +++ b/app/screens/Search.tsx @@ -0,0 +1,36 @@ + +import React from "react"; +import { createNativeStackNavigator } from "@react-navigation/native-stack"; +import ItemEditScreen from "./ItemEdit"; +import ItemListScreen from "./ItemList"; +import { Searchbar } from 'react-native-paper'; +import { StyleSheet } from 'react-native'; + +//https://reactnavigation.org/docs/hello-react-navigation +const Search = () => { + const [searchQuery, setSearchQuery] = React.useState(''); + const stil = StyleSheet.create({ + Searchbar: { + position: "absolute", + top: 45, + left: 5, + right: 5, + zIndex: 100, + borderColor: "red", + borderStyle: "solid", + borderWidth: 2, + marginTop: 5, + display: "flex", + flexDirection: "row", + }, + }) + return ( + + ); + }; + + export default Search; \ No newline at end of file diff --git a/geminiconfig.json b/geminiconfig.json new file mode 100644 index 0000000..09d2635 --- /dev/null +++ b/geminiconfig.json @@ -0,0 +1,3 @@ +{ + "api_key":"AIzaSyAXaLllif_4bHHF21oUpX8M5btwMHYPj2A" +} \ No newline at end of file diff --git a/react-native-firebase-seed b/react-native-firebase-seed new file mode 160000 index 0000000..4384690 --- /dev/null +++ b/react-native-firebase-seed @@ -0,0 +1 @@ +Subproject commit 43846900cea2efe44759c0a8c853b04f45bf7252 diff --git a/utils/geminiApi.ts b/utils/geminiApi.ts new file mode 100644 index 0000000..380cc04 --- /dev/null +++ b/utils/geminiApi.ts @@ -0,0 +1,29 @@ +export async function fetchGeminiResponse(prompt: any) { + const key = geminiconfig.api_key; + + const body = { + contents: [ + { + parts: [ + { text: prompt } + ] + } + ] + }; + + try { + const response = await fetch(`https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=${API_KEY}`, { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify(body), + }); + + const data = await response.json(); + return data.candidates[0].content.parts[0].text.trim(); + } catch (error) { + console.error("Eroare Gemini:", error); + return "A apărut o eroare."; +  } +}