diff --git a/mobile/tradeverse/app/(tabs)/create/index.jsx b/mobile/tradeverse/app/(tabs)/create/index.jsx index 02cbe06c..5f4cbc0e 100644 --- a/mobile/tradeverse/app/(tabs)/create/index.jsx +++ b/mobile/tradeverse/app/(tabs)/create/index.jsx @@ -1,9 +1,11 @@ import React from 'react'; import { Text } from 'react-native'; import CreateRootScreen from '../../../screens/create-root'; +import WelcomingScreen from '../../../screens/welcoming'; export default function Create() { return ( - + // + ); } diff --git a/mobile/tradeverse/components/buttons/main-button.jsx b/mobile/tradeverse/components/buttons/main-button.jsx new file mode 100644 index 00000000..8364b579 --- /dev/null +++ b/mobile/tradeverse/components/buttons/main-button.jsx @@ -0,0 +1,83 @@ +import React from 'react'; +import { ActivityIndicator, Alert, Pressable, StyleSheet, Text } from 'react-native'; +import { COLORS, SIZE_CONSTANT } from '../../constants/theme'; + +export default function MainButton({ + onPress=()=>{Alert.alert("Not Implemented")}, + loading, + disabled, + style, + textStyle, + variant = 'primary', + text = 'Press' +}) { + const selectedStyle = styles[variant]; + + return ( + { + e.preventDefault(); + onPress(); + }} + role='button' + disabled={disabled} + style={[ + selectedStyle.container, + style, + { + opacity: disabled ? 0.5 : 1, + pointerEvents: disabled ? 'none' : 'auto' + } + ]} + > + {loading ? ( + + ) : ( + {text} + )} + + ); +} + +const primaryStyle = StyleSheet.create({ + container: { + width: '100%', + backgroundColor: COLORS.primary500, + padding: 10, + height: SIZE_CONSTANT * 4.4, + display: 'flex', + justifyContent: 'center', + alignItems: 'center', + borderRadius: 6 + }, + text: { + color: COLORS.white, + fontSize: SIZE_CONSTANT * 1.4, + fontWeight: '600', + } +}); + +const secondaryStyle = StyleSheet.create({ + container: { + width: '100%', + height: SIZE_CONSTANT * 4.4, + backgroundColor: '#fff', + padding: 10, + display: 'flex', + justifyContent: 'center', + alignItems: 'center', + borderRadius: 6, + borderColor: '#F2F2F2', + borderWidth: 1 + }, + text: { + color: COLORS.primary950, + fontSize: 14, + fontWeight: 'regular' + } +}); + +const styles = { + primary: primaryStyle, + secondary: secondaryStyle +}; \ No newline at end of file diff --git a/mobile/tradeverse/components/images/profile-image.jsx b/mobile/tradeverse/components/images/profile-image.jsx index c24777d7..d5965b36 100644 --- a/mobile/tradeverse/components/images/profile-image.jsx +++ b/mobile/tradeverse/components/images/profile-image.jsx @@ -2,7 +2,10 @@ import React from 'react'; import { Image, StyleSheet } from 'react-native'; import IMAGES from '../../constants/images'; -export default function ProfileImage({ src='', style }) { +export default function ProfileImage({ src='', style, deviceReference=false }) { + if(deviceReference) { + return ; + } return ; } diff --git a/mobile/tradeverse/package-lock.json b/mobile/tradeverse/package-lock.json index e34877e3..db0431f6 100644 --- a/mobile/tradeverse/package-lock.json +++ b/mobile/tradeverse/package-lock.json @@ -13,6 +13,7 @@ "@tabler/icons-react-native": "^3.19.0", "expo": "~51.0.28", "expo-font": "~12.0.9", + "expo-image-picker": "^15.0.7", "expo-linking": "~6.3.1", "expo-router": "~3.5.23", "expo-splash-screen": "~0.27.5", @@ -9372,6 +9373,25 @@ "expo": "*" } }, + "node_modules/expo-image-loader": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/expo-image-loader/-/expo-image-loader-4.7.0.tgz", + "integrity": "sha512-cx+MxxsAMGl9AiWnQUzrkJMJH4eNOGlu7XkLGnAXSJrRoIiciGaKqzeaD326IyCTV+Z1fXvIliSgNW+DscvD8g==", + "peerDependencies": { + "expo": "*" + } + }, + "node_modules/expo-image-picker": { + "version": "15.0.7", + "resolved": "https://registry.npmjs.org/expo-image-picker/-/expo-image-picker-15.0.7.tgz", + "integrity": "sha512-u8qiPZNfDb+ap6PJ8pq2iTO7JKX+ikAUQ0K0c7gXGliKLxoXgDdDmXxz9/6QdICTshJBJlBvI0MwY5NWu7A/uw==", + "dependencies": { + "expo-image-loader": "~4.7.0" + }, + "peerDependencies": { + "expo": "*" + } + }, "node_modules/expo-keep-awake": { "version": "13.0.2", "resolved": "https://registry.npmjs.org/expo-keep-awake/-/expo-keep-awake-13.0.2.tgz", diff --git a/mobile/tradeverse/package.json b/mobile/tradeverse/package.json index 59ce270b..a821de61 100644 --- a/mobile/tradeverse/package.json +++ b/mobile/tradeverse/package.json @@ -18,6 +18,7 @@ "@tabler/icons-react-native": "^3.19.0", "expo": "~51.0.28", "expo-font": "~12.0.9", + "expo-image-picker": "^15.0.7", "expo-linking": "~6.3.1", "expo-router": "~3.5.23", "expo-splash-screen": "~0.27.5", diff --git a/mobile/tradeverse/screens/welcoming/index.jsx b/mobile/tradeverse/screens/welcoming/index.jsx new file mode 100644 index 00000000..218a9eef --- /dev/null +++ b/mobile/tradeverse/screens/welcoming/index.jsx @@ -0,0 +1,234 @@ +import React, { useState } from "react"; +import { + Text, + StyleSheet, + TouchableOpacity, + View, + Pressable, +} from "react-native"; +import { IconArrowRight } from "@tabler/icons-react-native"; +import { + COLORS, + FONT_WEIGHTS, + SIZE_CONSTANT, + SIZES, +} from "../../constants/theme"; +import GlobalScreen from "../../components/ui/global-screen"; +import MainButton from "../../components/buttons/main-button"; +import ProfileImage from "../../components/images/profile-image"; +import { launchImageLibraryAsync } from "expo-image-picker"; + +export default function WelcomingScreen() { + const [currentStep, setCurrentStep] = useState("profile"); // user_tag, profile + const [selectedImage, setSelectedImage] = useState(null); + const [selectedUserTag, setSelectedUserTag] = useState(null); + + const openImageGallery = async () => { + const result = await launchImageLibraryAsync({ + mediaTypes: "Images", + allowsEditing: true, + aspect: [4, 3], + quality: 1, + }); + + if (!result.canceled) { + setSelectedImage(result.assets[0]); + } + }; + + const options = [ + { label: "Beginner", icon: "🏁", value: "beginner" }, + { label: "Day Trader", icon: "📊", value: "day_trader" }, + { label: "Investor", icon: "💼", value: "investor" }, + { label: "Finance Enthusiast", icon: "💸", value: "finance_enthusiast" }, + { label: "Financial Analyst", icon: "📈", value: "finance_analyst" }, + ]; + + const handleNext = () => { + if (currentStep === "profile") { + setCurrentStep("user_tag"); + } + }; + + const ProfileView = () => { + return ( + + + Set a profile picture + + + + + + + + + + + + Skip for now + + + {selectedImage && ( + + )} + + + ); + }; + + const UserTagView = () => { + return ( + + + What is your experience with finance ? + + + {options.map((option, index) => ( + setSelectedUserTag(option.value)} + key={index} + style={styles.optionButton(option.value === selectedUserTag)} + > + + {option.label} + + {option.icon} + + ))} + + + + ); + }; + + return ( + + Welcome Huseyin ! + {currentStep === "user_tag" && } + {currentStep === "profile" && } + + ); +} + +const styles = StyleSheet.create({ + container: { + flex: 1, + backgroundColor: "#FFFFFF", + padding: 20, + }, + gradientText: { + alignSelf: "stretch", + marginTop: 40, + marginBottom: 40, + }, + welcomeText: { + fontSize: SIZE_CONSTANT * 2.4, + fontWeight: FONT_WEIGHTS.bold, + textAlign: "center", + color: COLORS.primary700, + marginBottom: SIZE_CONSTANT * 8, + letterSpacing: -0.03, + }, + + questionText: { + fontSize: SIZE_CONSTANT * 1.6, + color: "#1D1B4B", + marginBottom: 20, + fontWeight: FONT_WEIGHTS.medium, + letterSpacing: -0.3, + }, + + optionButton: (isSelected = false) => { + return { + flexDirection: "row", + justifyContent: "space-between", + alignItems: "center", + backgroundColor: isSelected ? COLORS.primary500 : "#EEF2FF", + padding: 15, + paddingHorizontal: SIZE_CONSTANT * 2, + borderRadius: SIZE_CONSTANT * 0.6, + marginBottom: SIZE_CONSTANT * 1.2, + height: SIZE_CONSTANT * 6, + }; + }, + optionText: (isSelected = false) => { + return { + fontSize: SIZES.medium, + color: isSelected ? COLORS.white : COLORS.primary800, + fontWeight: FONT_WEIGHTS.medium, + }; + }, + + continueButton: { + flexDirection: "row", + justifyContent: "center", + alignItems: "center", + backgroundColor: COLORS.primary500, + padding: 15, + height: SIZE_CONSTANT * 4.4, + borderRadius: SIZE_CONSTANT * 0.4, + marginTop: 20, + }, + + continueText: { + fontSize: SIZES.medium, + fontWeight: FONT_WEIGHTS.medium, + color: COLORS.white, + }, +});