Skip to content

Commit

Permalink
Merge pull request #299 from bounswe/mobile/feature/welcoming-screen
Browse files Browse the repository at this point in the history
Add welcoming screen views
  • Loading branch information
gulsensabak authored Oct 20, 2024
2 parents 62231da + 9e57848 commit a82a8a9
Show file tree
Hide file tree
Showing 6 changed files with 345 additions and 2 deletions.
4 changes: 3 additions & 1 deletion mobile/tradeverse/app/(tabs)/create/index.jsx
Original file line number Diff line number Diff line change
@@ -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 (
<CreateRootScreen/>
// <CreateRootScreen/>
<WelcomingScreen/>
);
}
83 changes: 83 additions & 0 deletions mobile/tradeverse/components/buttons/main-button.jsx
Original file line number Diff line number Diff line change
@@ -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 (
<Pressable
onPress={(e) => {
e.preventDefault();
onPress();
}}
role='button'
disabled={disabled}
style={[
selectedStyle.container,
style,
{
opacity: disabled ? 0.5 : 1,
pointerEvents: disabled ? 'none' : 'auto'
}
]}
>
{loading ? (
<ActivityIndicator color={selectedStyle.text.color} />
) : (
<Text style={[selectedStyle.text, textStyle]}>{text}</Text>
)}
</Pressable>
);
}

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
};
5 changes: 4 additions & 1 deletion mobile/tradeverse/components/images/profile-image.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 <Image source={src ? src : IMAGES.NO_PROFILE_IMG} style={[styles.image, style]} />;
}
return <Image source={src ? {uri:src} : IMAGES.NO_PROFILE_IMG} style={[styles.image, style]} />;
}

Expand Down
20 changes: 20 additions & 0 deletions mobile/tradeverse/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions mobile/tradeverse/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
234 changes: 234 additions & 0 deletions mobile/tradeverse/screens/welcoming/index.jsx
Original file line number Diff line number Diff line change
@@ -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 (
<View>
<Text
style={{
fontSize: SIZE_CONSTANT * 1.6,
textAlign: "center",
color: COLORS.primary900,
fontWeight: FONT_WEIGHTS.medium,
letterSpacing: -0.2,
}}
>
Set a profile picture
</Text>
<View
style={{
marginTop: SIZE_CONSTANT * 5,
}}
>
<View
style={{
display: "flex",
alignItems: "center",
justifyContent: "center",
}}
>
<Pressable onPress={openImageGallery}>
<ProfileImage
deviceReference
src={selectedImage}
style={{
borderWidth: 2,
borderColor: COLORS.primary50,
width: SIZE_CONSTANT * 14,
height: SIZE_CONSTANT * 14,
borderRadius: SIZE_CONSTANT * 7,
}}
/>
</Pressable>
</View>
<MainButton
style={{
marginTop: SIZE_CONSTANT * 4,
backgroundColor: COLORS.primary50,
}}
textStyle={{ color: COLORS.primary900 }}
text={selectedImage ? "Modify Image" : "Upload Image"}
onPress={openImageGallery}
/>

<TouchableOpacity
onPress={handleNext}
style={{
marginTop: SIZE_CONSTANT * 3,
}}
>
<Text
style={{
textAlign: "center",
color: COLORS.primary300,
letterSpacing: -0.2,
}}
>
Skip for now
</Text>
</TouchableOpacity>
{selectedImage && (
<MainButton
onPress={handleNext}
style={{ marginTop: SIZE_CONSTANT * 7 }}
text="Continue"
/>
)}
</View>
</View>
);
};

const UserTagView = () => {
return (
<View>
<Text style={styles.questionText}>
What is your experience with finance ?
</Text>

{options.map((option, index) => (
<TouchableOpacity
onPress={() => setSelectedUserTag(option.value)}
key={index}
style={styles.optionButton(option.value === selectedUserTag)}
>
<Text style={styles.optionText(option.value === selectedUserTag)}>
{option.label}
</Text>
<Text style={styles.optionText}>{option.icon}</Text>
</TouchableOpacity>
))}

<MainButton
style={{ marginTop: SIZE_CONSTANT * 2 }}
text="Continue"
disabled={!selectedUserTag}
/>
</View>
);
};

return (
<GlobalScreen>
<Text style={styles.welcomeText}>Welcome Huseyin !</Text>
{currentStep === "user_tag" && <UserTagView />}
{currentStep === "profile" && <ProfileView />}
</GlobalScreen>
);
}

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,
},
});

0 comments on commit a82a8a9

Please sign in to comment.