Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable no-undef */
module.exports = {
root: true,
parser: "@typescript-eslint/parser",
Expand Down
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,5 @@ web-build/
# The following patterns were generated by expo-cli

expo-env.d.ts
# @end expo-cli
# @end expo-cli
.idea/
27 changes: 17 additions & 10 deletions app/(auth)/login.tsx
Original file line number Diff line number Diff line change
@@ -1,30 +1,37 @@
import {View, SafeAreaView, TouchableOpacity, Text} from 'react-native';
import React from "react";

import React, { useState } from "react";
import LoginSignupHeader from "@/components/LoginSignupHeader";
import {CustomInput} from "@/components/elements/CustomInput";
import CustomButton from "@/components/elements/CustomButton";
import { router } from "expo-router"; // Make sure to import the router object
import {router} from "expo-router";
import {LoginSignupFooter} from "@/components/elements/LoginSignupFooter";


export default function Login() {
const [login, setLogin] = useState<string>("");
const [password, setPassword] = useState<string>("");

const handleSignupPress = () => {
router.push("/signup"); // Use the router object to navigate to the "/signup" route
router.push("/(tabs)/signup");
}
const handleFormSubmit = () => {

}

return (
<SafeAreaView className={"flex-1"}>
<LoginSignupHeader/>
<View className={"flex flex-col p-12 flex-1 justify-between"}>
<View>
<CustomInput type={"email"} placeholder={"E-mail"}/>
<CustomInput type={"password"} placeholder={"Hasło"}/>
<CustomInput type={"email"} placeholder={"E-mail"} value={login} onChangeText={setLogin} />
<CustomInput type={"password"} placeholder={"Hasło"} value={password} onChangeText={setPassword} />
<CustomButton title={"Zaloguj"} buttonType={"primary"}/>
<TouchableOpacity onPress={handleSignupPress} className="mt-4">
<Text className="text-text text-center">Nie masz konta? Zarejestruj się!</Text>
</TouchableOpacity>
</View>
<Text className="hover:text-blue-500 hover:underline text-gray-200 text-center">Nie masz konta?
Zarejestruj się!</Text>
</TouchableOpacity></View>
<LoginSignupFooter/>
</View>
</SafeAreaView>
);
}
}
17 changes: 11 additions & 6 deletions app/(auth)/signup.tsx
Original file line number Diff line number Diff line change
@@ -1,27 +1,32 @@
import {View, SafeAreaView, TouchableOpacity, Text} from 'react-native';

import React, { useState } from "react";
import LoginSignupHeader from "@/components/LoginSignupHeader";
import {CustomInput} from "@/components/elements/CustomInput";
import CustomButton from "@/components/elements/CustomButton";
import {router} from "expo-router";
import {router, useNavigation} from "expo-router";
import {LoginSignupFooter} from "@/components/elements/LoginSignupFooter";


export default function Signup() {
const [login, setLogin] = useState<string>("");
const [password, setPassword] = useState<string>("");
const [confirmPassword, setConfirmPassword] = useState<string>("");
const handleSignupPress = () => {
router.push("/login")
router.push("/(tabs)/login");
}
return (
<SafeAreaView className={"flex-1"}>
<LoginSignupHeader/>
<View className={"flex flex-col p-12 flex-1 justify-between"}>
<View>
<CustomInput type={"email"} placeholder={"E-mail"}/>
<CustomInput type={"password"} placeholder={"Hasło"}/>
<CustomInput type={"password"} placeholder={"Powtórz hasło"}/>
<CustomInput type={"email"} placeholder={"E-mail"} value={login} onChangeText={setLogin} />
<CustomInput type={"password"} placeholder={"Hasło"} value={password} onChangeText={setPassword}/>
<CustomInput type={"password"} placeholder={"Powtórz hasło"} value={confirmPassword} onChangeText={setConfirmPassword}/>
<CustomButton title={"Zarejestruj"} buttonType={"primary"}/>
<TouchableOpacity onPress={handleSignupPress} className="mt-4">
<Text className="text-text text-center">Posiadasz konto? Zaloguj się!</Text>
<Text className="hover:text-blue-500 hover:underline text-gray-200 text-center">Posiadasz konto?
Zaloguj się!</Text>
</TouchableOpacity>
</View>
<LoginSignupFooter/>
Expand Down
8 changes: 5 additions & 3 deletions app/(tabs)/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React, { useEffect, useRef, useState } from 'react';
/* eslint-disable @typescript-eslint/no-require-imports */
import React, { useEffect, useState } from 'react';
import { TextInput, ScrollView, Text, View, ImageBackground, Image } from 'react-native';
import { collection, getDocs, orderBy, query, where } from "firebase/firestore"
import { FIREBASE_DB } from '@/firebase.config';
Expand All @@ -7,6 +8,7 @@ import SectionText from '@/components/HomePage/SectionText';
import ScrollCard from '@/components/HomePage/ScrollCard';
import { Ionicons } from '@expo/vector-icons';
import { router } from 'expo-router';
import { ThemedView } from '@/components/ThemedView';

const HomeScreen = () => {
const [allTips, setAllTips] = useState<TipFields[]>([]);
Expand Down Expand Up @@ -88,7 +90,7 @@ const HomeScreen = () => {
}

return (
<View className="flex-1 bg-background">
<ThemedView className="flex-1 bg-background">
<ScrollView bounces={true} showsVerticalScrollIndicator={false}>
{/* Header Section */}
<View style={{ overflow: 'hidden', borderBottomLeftRadius: 35, borderBottomRightRadius: 35 }}>
Expand Down Expand Up @@ -155,7 +157,7 @@ const HomeScreen = () => {
</View>

</ScrollView>
</View>
</ThemedView>
);
};

Expand Down
35 changes: 26 additions & 9 deletions app/(tabs)/settings.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,42 @@
/* eslint-disable @typescript-eslint/no-require-imports */
import {SafeAreaView, Switch, Text, View, TouchableHighlight, Appearance, Image} from 'react-native';
import React, {useEffect, useState} from "react";
import {ThemedText} from '@/components/ThemedText';
import {THEME_PREFERENCE_KEY} from "@/hooks/useColorScheme";
import AsyncStorage from "@react-native-async-storage/async-storage";
import CustomButton from '@/components/elements/CustomButton';
import { router } from 'expo-router';

export default function Settings() {
const [darkTheme, changeDarkToggle] = useState<boolean>(false);
const canChangeTheme = typeof (Appearance.setColorScheme) === "function";
const [darkTheme, setDarkTheme] = useState<boolean>(false);

const canChangeTheme = typeof Appearance.setColorScheme === "function";

useEffect(() => {
const fetchThemePreference = async () => {
try {
const storedTheme = await AsyncStorage.getItem(THEME_PREFERENCE_KEY);
if (storedTheme) {
setDarkTheme(storedTheme === 'dark');
}
} catch (error) {
console.error("Failed to fetch theme preference:", error);
}
};

fetchThemePreference();
}, []);

useEffect(() => {
if (canChangeTheme) Appearance.setColorScheme(darkTheme ? "dark" : "light");
if (canChangeTheme) {
Appearance.setColorScheme(darkTheme ? "dark" : "light");
}
AsyncStorage.setItem(THEME_PREFERENCE_KEY, darkTheme ? "dark" : "light");
}, [darkTheme]);

return (
<SafeAreaView className={"flex-1 p-12 mt-10"}>
<View>
<Image source={require('../../assets/images/logo-icon.png')} className={"w-full h-28 object-contain"} style={{ width: '100%', height: 112, resizeMode: 'contain' }}/>
<ThemedText type='title'>Ustawienia</ThemedText>
<ThemedText type='title' className='px-8'>Ustawienia</ThemedText>
<TouchableHighlight className={"mt-10 border-t border-primary border-b border-solid p-4"}>
<View style={{ flexDirection: "row", alignItems: "center", justifyContent: "space-between" }}>
<Text className={`text-xl p-3 ${(darkTheme ? "text-white" : "text-text")}`}>Użyj ciemny motyw</Text>
Expand All @@ -34,7 +53,7 @@ export default function Settings() {
<Switch
disabled={!canChangeTheme}
value={darkTheme}
onValueChange={changeDarkToggle}
onValueChange={setDarkTheme}
thumbColor={darkTheme ? "#ffffff" : "#f4f4f4"}
trackColor={{
false: "#d3d3d3",
Expand All @@ -47,8 +66,6 @@ export default function Settings() {
/>

</View>
<CustomButton title='login' buttonType='primary' handlePress={() => router.push('/login')}/>
<CustomButton title='signup' buttonType='primary' handlePress={() => router.push('/signup')}/>
</View>
</TouchableHighlight>
</View>
Expand Down
64 changes: 56 additions & 8 deletions app/(tabs)/shop.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,58 @@
import { SafeAreaView, Text, View } from "react-native";

function Shop() {
return <SafeAreaView>
<View>
<Text>Shop</Text>
</View>
</SafeAreaView>
import {ImageBackground, ScrollView, Text, TextInput, View} from "react-native";
import SectionText from "@/components/HomePage/SectionText";
import ScrollCard from "@/components/HomePage/ScrollCard";
import React, {useEffect, useState} from "react";
import {collection, getDocs, query} from "firebase/firestore";
import {FIREBASE_DB} from "@/firebase.config";
import {shuffleArray} from "@/functions/shuffleArray";
import {Ionicons} from "@expo/vector-icons";

const Shop = () => {
const [shopItems, setShopItems] = useState<ShopItem[]>([]);
useEffect(() => {

const fetchItems = async () => {
const shopCollectionReference = collection(FIREBASE_DB, "shop");
const shopQuery = query(shopCollectionReference);
const querySnapshot = await getDocs(shopQuery);

const fetchedTips: ShopItem[] = querySnapshot.docs.map((doc) => ({
id: doc.id,
...doc.data() as ShopItemData
}));

setShopItems(fetchedTips);
}
fetchItems();
}, []);
return <View className="mt-8">
<ScrollView bounces={true} showsVerticalScrollIndicator={false}>
<View style={{ overflow: 'hidden', borderBottomLeftRadius: 35, borderBottomRightRadius: 35 }}>
<ImageBackground
source={require('@/assets/images/banner-image.png')}
className="bg-[#63784f] pt-[85px] pb-14 px-8 flex gap-2"
style={{ borderBottomLeftRadius: 35, borderBottomRightRadius: 35 }}
>
<Text className="text-4xl tracking-widest font-bold text-secondary">
Treebie
</Text>
<Text className="text-3xl tracking-widest font-bold text-secondary">
Ucz się, działaj, zgarniaj
</Text>

</ImageBackground>
</View>
<SectionText title='Sklep' containerStyles='px-8'/>

<ScrollView className="flex-row pl-8" horizontal showsHorizontalScrollIndicator={false} decelerationRate={0}
snapToInterval={200} snapToAlignment={"start"} contentContainerClassName='pr-8'>
{shopItems.slice(0, 5).map((item) => {
return <ScrollCard key={`all-${item.id}`} id={item.id} imageName='logo-icon-new.png'
title={item.name} containerStyle='mr-4' routeBase={"shop"} />
})}
</ScrollView>
</ScrollView>
</View>;
}

export default Shop;
21 changes: 21 additions & 0 deletions app/(tabs)/tree.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { Feather } from '@expo/vector-icons'
import React from 'react'
import { SafeAreaView, Text, TouchableOpacity, View } from 'react-native'

const tree = () => {
return (
<SafeAreaView>
<View className='flex flex-row justify-between px-8'>
<TouchableOpacity>
<Feather name="shopping-bag" size={24} color="black" />
</TouchableOpacity>

<TouchableOpacity>
<Feather name="camera" size={24} color="black" />
</TouchableOpacity>
</View>
</SafeAreaView>
)
}

export default tree
18 changes: 18 additions & 0 deletions app/(tabs)/welcome.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import {ThemedText} from "@/components/ThemedText";
import {SafeAreaView} from "react-native-safe-area-context";
import React from "react";
import {ImageBackground} from "react-native";

export default function Welcome(props: {}) {
return <SafeAreaView
className={""}>
<ImageBackground
source={require('@/assets/images/banner-image.png')}
className="bg-[#63784f] pt-[85px] pb-14 px-8 flex gap-2 items-center justify-center h-full bg-center bg-contain bg-repeat"
style={{borderBottomLeftRadius: 35, borderBottomRightRadius: 35}}
>
<ThemedText type={"title"} style={{ fontSize: 80, lineHeight: 85, fontWeight: 'bold' }}>Save</ThemedText>
<ThemedText type={"title"} style={{ fontSize: 80, lineHeight: 85, fontWeight: 'bold' }}>The</ThemedText>
<ThemedText type={"title"} style={{ fontSize: 80, lineHeight: 85, fontWeight: 'bold' }}>Planet</ThemedText></ImageBackground>
</SafeAreaView>;
}
1 change: 1 addition & 0 deletions app/+not-found.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { StyleSheet } from 'react-native';

import { ThemedText } from '@/components/ThemedText';
import { ThemedView } from '@/components/ThemedView';
import React from 'react';

export default function NotFoundScreen() {
return (
Expand Down
1 change: 1 addition & 0 deletions app/_layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ export default function RootLayout() {
<Stack>
<Stack.Screen name="(tabs)" options={{ headerShown: false }} />
<Stack.Screen name="tip/[id]/index" options={{ headerShown: false }} />
<Stack.Screen name="shop/[id]/index" options={{ headerShown: false }} />
<Stack.Screen name="(auth)/login" options={{ headerShown: false }} />
<Stack.Screen name="(auth)/signup" options={{ headerShown: false }} />
<Stack.Screen name="ai/index" options={{ headerShown: false }} />
Expand Down
17 changes: 10 additions & 7 deletions app/ai/index.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import Message from '@/components/Ai/Message';
import SkeletonMessage from '@/components/Ai/SkeletonMessage';
import { ThemedText } from '@/components/ThemedText';
import { useThemeColor } from '@/hooks/useThemeColor';
import { Feather, Ionicons } from '@expo/vector-icons';
import { router, useLocalSearchParams } from 'expo-router';
import React, { useEffect, useState } from 'react';
import { KeyboardAvoidingView, Platform, SafeAreaView, ScrollView, Text, TextInput, TouchableOpacity, View } from 'react-native';
import { KeyboardAvoidingView, Platform, SafeAreaView, ScrollView, TextInput, TouchableOpacity, View } from 'react-native';

const Index = () => {
const userMessageParam = (useLocalSearchParams().text as string) || null;
Expand Down Expand Up @@ -78,8 +80,9 @@ const Index = () => {
}
}, [userMessageParam]);

const backgroundColor = useThemeColor({ light: "", dark: ""}, 'background');
return (
<SafeAreaView className="flex-1 bg-background">
<SafeAreaView className="flex-1" style={[{ backgroundColor }]}>
{/* Header */}
<View className="flex-row items-center px-8 mt-2">
<TouchableOpacity
Expand All @@ -88,9 +91,9 @@ const Index = () => {
>
<Ionicons name="chevron-back-outline" size={18} color="white" />
</TouchableOpacity>
<Text className="text-4xl font-semibold text-gray-800">
<ThemedText className="text-4xl font-semibold text-gray-800">
Eco Chat
</Text>
</ThemedText>
</View>

{/* Scrollable Content */}
Expand All @@ -106,8 +109,8 @@ const Index = () => {
keyboardVerticalOffset={Platform.OS === 'ios' ? -20 : 0}
style={{ position: 'absolute', bottom: 0, width: '100%' }}
>
<View className="pt-2 pb-6 border-t border-[#e0e0e0] bg-white">
<View className="flex-row items-center bg-white rounded-lg p-4">
<View className="pt-2 pb-6 border-t border-[#e0e0e0]" style={[{ backgroundColor }]}>
<View className="flex-row items-center rounded-lg p-4" style={[{ backgroundColor }]}>
<TextInput
className="flex-1 mx-2 text-gray-700"
placeholder="Zadaj pytanie ECO asystentowi"
Expand All @@ -117,7 +120,7 @@ const Index = () => {
onChangeText={text => setInputValue(text)}
editable={!isFetching}
/>
<Feather name="send" size={24} color="black" className="mr-2" onPress={() => handleSend()} />
<Feather name="send" size={24} color="#202f11" className="mr-2" onPress={() => handleSend()} />
</View>
</View>
</KeyboardAvoidingView>
Expand Down
Loading