diff --git a/assets/down.png b/assets/down.png new file mode 100644 index 00000000..63ac7887 Binary files /dev/null and b/assets/down.png differ diff --git a/assets/github_logo.png.png b/assets/github_logo.png.png new file mode 100644 index 00000000..33479614 Binary files /dev/null and b/assets/github_logo.png.png differ diff --git a/assets/linkedIn_logo.png b/assets/linkedIn_logo.png new file mode 100644 index 00000000..e7929255 Binary files /dev/null and b/assets/linkedIn_logo.png differ diff --git a/assets/right.png b/assets/right.png new file mode 100644 index 00000000..02d9e04e Binary files /dev/null and b/assets/right.png differ diff --git a/assets/twitter_logo.png b/assets/twitter_logo.png new file mode 100644 index 00000000..a9e3361c Binary files /dev/null and b/assets/twitter_logo.png differ diff --git a/src/screens/ProfileScreen/ProfileScreen.tsx b/src/screens/ProfileScreen/ProfileScreen.tsx index e3ecae3c..575e9cb7 100644 --- a/src/screens/ProfileScreen/ProfileScreen.tsx +++ b/src/screens/ProfileScreen/ProfileScreen.tsx @@ -1,7 +1,15 @@ // TODO: we wil remove this once we start using userData and contributionData /* eslint-disable @typescript-eslint/no-unused-vars */ import React, { useState, useCallback, useContext } from 'react'; -import { View, Text, Pressable } from 'react-native'; +import { + View, + Text, + Pressable, + FlatList, + StyleSheet, + SafeAreaView, + ScrollView, +} from 'react-native'; import { ScreenViewContainer } from '../../styles/GlobalStyle'; import { profileScreenStyles } from './styles'; import withHeader from '../../helpers/withHeader'; @@ -13,20 +21,18 @@ import { ImagePickerResponse } from 'react-native-image-picker'; import Strings from '../../i18n/en'; import { fetchContribution } from '../AuthScreen/Util'; import { useFocusEffect } from '@react-navigation/native'; - import { useSelector } from 'react-redux'; +import AllContributionsDropdown from './User Data/UserContributions/AllContributions'; +import NoteworthyContributionsDropdown from './User Data/UserContributions/NoteWorthyContributions'; +import ActiveTaskDropDown from './User Data/UserContributions/ActiveTask'; +import UserData from './User Data/UserData'; const ProfileScreen = () => { const { data: userData } = useSelector((store) => store.user); const [response, setResponse] = useState({}); const [modalVisible, setModalVisible] = useState(false); - const [contributionData, setContributionData] = useState({ - allData: [], - noteworthy: [], - }); + const [contributionData, setContributionData] = useState([]); const { loggedInUserData, setLoggedInUserData } = useContext(AuthContext); - console.log('loggedIn', loggedInUserData); - const openModal = useCallback(() => { setModalVisible(true); }, []); @@ -52,22 +58,13 @@ const ProfileScreen = () => { (async () => { const userName = 'ankush'; const contributionResponse = await fetchContribution(userName); - setContributionData(contributionResponse); + setContributionData(contributionResponse.noteworthy); })(); }, []), ); return ( - - { - setLoggedInUserData(null); - }} - > - {Strings.LOGOUT} - - + { )} - {loggedInUserData?.name} + {/* {loggedInUserData?.name} */} + + + + + + { + setLoggedInUserData(null); + }} + > + {Strings.LOGOUT} + + - + ); }; +const styles = StyleSheet.create({ + container: { + marginBottom: 10, + paddingBottom: 30, + }, + container2: { + borderWidth: 2, + }, +}); export default withHeader(ProfileScreen); diff --git a/src/screens/ProfileScreen/User Data/UserContributions/ActiveTask.tsx b/src/screens/ProfileScreen/User Data/UserContributions/ActiveTask.tsx new file mode 100644 index 00000000..71c0c85a --- /dev/null +++ b/src/screens/ProfileScreen/User Data/UserContributions/ActiveTask.tsx @@ -0,0 +1,60 @@ +import React, { useState } from 'react'; +import { View, StyleSheet, Text, TouchableOpacity, Image } from 'react-native'; + +const ActiveTaskDropDown = () => { + const [clicked, setClicked] = useState(false); + return ( + + setClicked(!clicked)} + style={styles.DropDownButton} + > + Active tasks + {clicked ? ( + + ) : ( + + )} + + + ); +}; + +const styles = StyleSheet.create({ + DropDownButton: { + width: '100%', + height: 80, + elevation: 5, + borderRadius: 10, + backgroundColor: 'white', + alignSelf: 'center', + flexDirection: 'row', + justifyContent: 'space-evenly', + alignItems: 'center', + paddingLeft: 35, + }, + DropDownTitle: { + fontWeight: '600', + fontSize: 20, + color: 'black', + }, + DropDownElement: { + color: 'black', + width: '100%', + alignSelf: 'center', + height: 50, + borderBottomWidth: 0.5, + }, + ImageDimensions: { + height: 100, + width: 100, + }, +}); + +export default ActiveTaskDropDown; diff --git a/src/screens/ProfileScreen/User Data/UserContributions/AllContributions.tsx b/src/screens/ProfileScreen/User Data/UserContributions/AllContributions.tsx new file mode 100644 index 00000000..23d19bd8 --- /dev/null +++ b/src/screens/ProfileScreen/User Data/UserContributions/AllContributions.tsx @@ -0,0 +1,285 @@ +import React, { useState, useCallback } from 'react'; +import { + View, + StyleSheet, + Text, + TouchableOpacity, + Linking, + Image, +} from 'react-native'; +import { fetchContribution } from '../../../AuthScreen/Util'; +import { useFocusEffect } from '@react-navigation/native'; + +const AllContributionsDropdown = () => { + const [clicked, setClicked] = useState(false); + const [allContributionsData, setAllContributionData] = useState([]); + + useFocusEffect( + useCallback(() => { + (async () => { + const userName = 'ankush'; + const contributionResponse = await fetchContribution(userName); + setAllContributionData(contributionResponse.all); + })(); + }, []), + ); + + const convertTimestampToReadableDate = (timestamp) => { + return new Date(timestamp * 1000); + }; + const calculateTimeDifference = (startDate, endDate) => { + const timeDifference = endDate - startDate; + const secondsInMillisecond = 1000; + const minutesInMillisecond = 60 * secondsInMillisecond; + const hoursInMillisecond = 60 * minutesInMillisecond; + const daysInMillisecond = 24 * hoursInMillisecond; + const weeksInMillisecond = 7 * daysInMillisecond; + const monthsInMillisecond = 30.44 * daysInMillisecond; // Average month length + const yearsInMillisecond = 365 * daysInMillisecond; + + if (timeDifference < minutesInMillisecond) { + return `${Math.floor(timeDifference / secondsInMillisecond)} seconds`; + } else if (timeDifference < hoursInMillisecond) { + return `${Math.floor(timeDifference / minutesInMillisecond)} minutes`; + } else if (timeDifference < daysInMillisecond) { + return `${Math.floor(timeDifference / hoursInMillisecond)} hours`; + } else if (timeDifference < weeksInMillisecond) { + return `${Math.floor(timeDifference / daysInMillisecond)} days`; + } else if (timeDifference < monthsInMillisecond) { + return `${Math.floor(timeDifference / weeksInMillisecond)} weeks`; + } else if (timeDifference < yearsInMillisecond) { + return `${Math.floor(timeDifference / monthsInMillisecond)} months`; + } else { + return `${Math.floor(timeDifference / yearsInMillisecond)} years`; + } + }; + + const calculateISODateFormat = (isoDateString) => { + const date = new Date(isoDateString); + const formatDate = (dateVar) => { + const months = [ + 'January', + 'February', + 'March', + 'April', + 'May', + 'June', + 'July', + 'August', + 'September', + 'October', + 'November', + 'December', + ]; + + const day = dateVar.getDate(); + const monthIndex = dateVar.getMonth(); + const year = dateVar.getFullYear(); + + return `${day} ${months[monthIndex]}, ${year}`; + }; + const formattedDate = formatDate(date); + return formattedDate; + }; + + const parseISODate = (isoDateString) => { + return new Date(isoDateString); + }; + + return ( + + setClicked(!clicked)} + style={styles.DropDownButton} + > + All Contributions + {clicked ? ( + + ) : ( + + )} + + {clicked + ? allContributionsData.map((item, index) => ( + + + {item.task.id ? ( + Linking.openURL(item.task.featureUrl) + : null + } + > + + + {item.task.title} + + + {item.task.purpose} + + <> + {item.task.featureUrl ? ( + + Estimated completion:{' '} + {calculateTimeDifference( + convertTimestampToReadableDate( + item.task.startedOn, + ), + convertTimestampToReadableDate(item.task.endsOn), + )} + + ) : ( + + Estimated completion:{' '} + {calculateTimeDifference( + convertTimestampToReadableDate( + item.task.startedOn, + ), + convertTimestampToReadableDate(item.task.endsOn), + )} + + )} + + <> + {item.task.featureUrl ? ( + + Checkout this feature in action + + ) : null} + + + + ) : ( + Linking.openURL(item.prList[0].url) + : null + } + > + + {item.prList.length > 0 && ( + + + {item.prList[0].title} + + + Completed in:{' '} + {calculateTimeDifference( + parseISODate(item.prList[0].createdAt), + parseISODate(item.prList[0].updatedAt), + )} + + + Feature live on:{' '} + {calculateISODateFormat(item.prList[0].updatedAt)} + + <> + {item.prList[0].url ? ( + + Checkout this feature in action + + ) : null} + + + )} + + + )} + {/* */} + {item.prList.title} + + + )) + : null} + + ); +}; + +const styles = StyleSheet.create({ + DropDownButton: { + width: '100%', + height: 80, + elevation: 5, + borderRadius: 10, + backgroundColor: 'white', + alignSelf: 'center', + flexDirection: 'row', + justifyContent: 'space-evenly', + alignItems: 'center', + paddingLeft: 35, + }, + DropDownTitle: { + fontWeight: '600', + fontSize: 20, + color: 'black', + }, + DropDownElement: { + color: 'black', + width: '100%', + alignSelf: 'center', + height: 'auto', + }, + DropDownbackground: { + padding: 10, + marginTop: 5, + height: 'auto', + alignSelf: 'center', + width: '90%', + backgroundColor: '#fff', + borderRadius: 5, + }, + ImageDimensions: { + height: 100, + width: 100, + }, + EstimatedTimeChoice1: { + color: 'black', + fontSize: 15, + fontWeight: 'bold', + borderBottomColor: 'grey', + borderBottomWidth: 1, + marginTop: 5, + }, + EstimatedTimeChoice2: { + color: 'black', + fontWeight: 'bold', + fontSize: 15, + marginTop: 5, + }, + FeatureDate: { + color: 'black', + fontWeight: 'bold', + fontSize: 15, + borderBottomColor: 'grey', + borderBottomWidth: 1, + marginTop: 5, + }, + CheckoutLive: { + color: 'grey', + textAlign: 'center', + }, + ItemTaskTitle: { + color: 'blue', + fontSize: 18, + }, + ItemTaskPurpose: { + color: 'black', + marginTop: 5, + }, + CompletedIn: { + color: 'grey', + marginTop: 5, + }, +}); + +export default AllContributionsDropdown; diff --git a/src/screens/ProfileScreen/User Data/UserContributions/NoteWorthyContributions.tsx b/src/screens/ProfileScreen/User Data/UserContributions/NoteWorthyContributions.tsx new file mode 100644 index 00000000..8aa75561 --- /dev/null +++ b/src/screens/ProfileScreen/User Data/UserContributions/NoteWorthyContributions.tsx @@ -0,0 +1,193 @@ +import React, { useCallback, useState } from 'react'; +import { + View, + StyleSheet, + Text, + TouchableOpacity, + Linking, + Image, +} from 'react-native'; +import { fetchContribution } from '../../../AuthScreen/Util'; +import { useFocusEffect } from '@react-navigation/native'; + +const NoteworthyContributionsDropdown = () => { + const [clicked, setClicked] = useState(false); + const [userContributionData, setUserContributionData] = useState([]); + + useFocusEffect( + useCallback(() => { + (async () => { + const userName = 'ankush'; + const contributionResponse = await fetchContribution(userName); + setUserContributionData(contributionResponse.noteworthy); + })(); + }, []), + ); + + const convertTimestampToReadableDate = (timestamp) => { + return new Date(timestamp * 1000); + }; + const calculateTimeDifference = (startDate, endDate) => { + const timeDifference = endDate - startDate; + const secondsInMillisecond = 1000; + const minutesInMillisecond = 60 * secondsInMillisecond; + const hoursInMillisecond = 60 * minutesInMillisecond; + const daysInMillisecond = 24 * hoursInMillisecond; + const weeksInMillisecond = 7 * daysInMillisecond; + const monthsInMillisecond = 30.44 * daysInMillisecond; // Average month length + const yearsInMillisecond = 365 * daysInMillisecond; + + if (timeDifference < minutesInMillisecond) { + return `${Math.floor(timeDifference / secondsInMillisecond)} seconds`; + } else if (timeDifference < hoursInMillisecond) { + return `${Math.floor(timeDifference / minutesInMillisecond)} minutes`; + } else if (timeDifference < daysInMillisecond) { + return `${Math.floor(timeDifference / hoursInMillisecond)} hours`; + } else if (timeDifference < weeksInMillisecond) { + return `${Math.floor(timeDifference / daysInMillisecond)} days`; + } else if (timeDifference < monthsInMillisecond) { + return `${Math.floor(timeDifference / weeksInMillisecond)} weeks`; + } else if (timeDifference < yearsInMillisecond) { + return `${Math.floor(timeDifference / monthsInMillisecond)} months`; + } else { + return `${Math.floor(timeDifference / yearsInMillisecond)} years`; + } + }; + + return ( + + setClicked(!clicked)} + style={styles.DropDownButton} + > + Noteworthy Contributions + {clicked ? ( + + ) : ( + + )} + + {clicked + ? userContributionData.map((item, index) => ( + + Linking.openURL(item.task.featureUrl) + : null + } + > + {item.task.title} + <> + {item.task.purpose ? ( + + {item.task.purpose} + + ) : null} + + <> + {item.task.featureUrl ? ( + + Estimated completion:{' '} + {calculateTimeDifference( + convertTimestampToReadableDate(item.task.startedOn), + convertTimestampToReadableDate(item.task.endsOn), + )} + + ) : ( + + Estimated completion:{' '} + {calculateTimeDifference( + convertTimestampToReadableDate(item.task.startedOn), + convertTimestampToReadableDate(item.task.endsOn), + )} + + )} + + <> + {item.task.featureUrl ? ( + + Checkout this feature in action + + ) : null} + + + + )) + : null} + + ); +}; + +const styles = StyleSheet.create({ + DropDownButton: { + width: '100%', + height: 80, + elevation: 5, + borderRadius: 10, + backgroundColor: 'white', + alignSelf: 'center', + flexDirection: 'row', + justifyContent: 'space-evenly', + alignItems: 'center', + paddingLeft: 35, + }, + DropDownTitle: { + fontWeight: '600', + fontSize: 20, + color: 'black', + }, + DropDownElement: { + color: 'black', + width: '100%', + alignSelf: 'center', + height: 'auto', + }, + DropDownbackground: { + padding: 10, + marginTop: 5, + alignSelf: 'center', + width: '90%', + backgroundColor: '#fff', + borderRadius: 5, + }, + ImageDimensions: { + height: 100, + width: 100, + }, + EstimatedTimeChoice1: { + color: 'black', + fontSize: 15, + fontWeight: 'bold', + borderBottomColor: 'grey', + borderBottomWidth: 1, + marginTop: 5, + }, + EstimatedTimeChoice2: { + color: 'black', + fontWeight: 'bold', + fontSize: 13, + marginTop: 5, + }, + CheckoutLive: { + color: 'grey', + textAlign: 'center', + }, + ItemTaskTitle: { + color: 'blue', + fontSize: 18, + }, + ItemTaskPurpose: { + color: 'black', + marginTop: 5, + }, +}); + +export default NoteworthyContributionsDropdown; diff --git a/src/screens/ProfileScreen/User Data/UserData.tsx b/src/screens/ProfileScreen/User Data/UserData.tsx new file mode 100644 index 00000000..88afda60 --- /dev/null +++ b/src/screens/ProfileScreen/User Data/UserData.tsx @@ -0,0 +1,80 @@ +import React from 'react'; +import { + StyleSheet, + View, + Text, + Image, + Linking, + TouchableOpacity, +} from 'react-native'; + +const UserData = ({ userData }) => { + return ( + + {userData.name} + {'@' + userData.userName} + {userData.designation} + {userData.company} + + <> + Linking.openURL('https://twitter.com/_bhaaratii')} + > + + + + + Linking.openURL( + 'https://www.linkedin.com/in/bharati-subramanian-29734b152/', + ) + } + > + + + + Linking.openURL('https://github.com/bharati-21')} + > + + + + + + ); +}; + +const styles = StyleSheet.create({ + Name: { + fontSize: 20, + fontWeight: 'bold', + color: 'black', + }, + userName: { + fontSize: 13, + textAlign: 'center', + color: 'grey', + }, + designation: { + fontSize: 15, + color: 'black', + textAlign: 'center', + }, + company: { + fontSize: 13, + fontWeight: 'bold', + color: 'grey', + textAlign: 'center', + }, +}); + +export default UserData; diff --git a/src/screens/ProfileScreen/styles.ts b/src/screens/ProfileScreen/styles.ts index 684735e7..07fe65c6 100644 --- a/src/screens/ProfileScreen/styles.ts +++ b/src/screens/ProfileScreen/styles.ts @@ -83,9 +83,22 @@ export const profileScreenStyles = StyleSheet.create({ elevation: 2, width: '40%', alignItems: 'center', - position: 'absolute', - bottom: 20, + position: 'relative', + // bottom: 10, + margin: 10, + alignSelf: 'center', color: 'white', + + // paddingHorizontal: 8, + // paddingVertical: 6, + // borderRadius: 20, + // elevation: 2, + // top: 10, + // backgroundColor: '#E20062', + // alignSelf: 'flex-end', + // margin: 5, + // width: '40%', + // textAlign: 'center', }, logoutText: { color: 'white',