diff options
Diffstat (limited to 'src/components/profile')
-rw-r--r-- | src/components/profile/ProfileBadges.tsx | 148 | ||||
-rw-r--r-- | src/components/profile/ProfileBody.tsx | 3 | ||||
-rw-r--r-- | src/components/profile/index.ts | 1 |
3 files changed, 151 insertions, 1 deletions
diff --git a/src/components/profile/ProfileBadges.tsx b/src/components/profile/ProfileBadges.tsx new file mode 100644 index 00000000..8e68dc46 --- /dev/null +++ b/src/components/profile/ProfileBadges.tsx @@ -0,0 +1,148 @@ +import {useNavigation} from '@react-navigation/core'; +import React, {FC, useEffect, useState} from 'react'; +import {StyleSheet, Text, View} from 'react-native'; +import {ScrollView, TouchableOpacity} from 'react-native-gesture-handler'; +import {useSelector} from 'react-redux'; +import {BadgeIcon} from '..'; +import PlusIconImage from '../../assets/icons/plus-icon-thin.svg'; +import {BADGE_LIMIT} from '../../constants'; +import {RootState} from '../../store/rootReducer'; +import {ScreenType, UniversityBadgeDisplayType} from '../../types'; +import {badgesToDisplayBadges, normalize} from '../../utils'; +import BadgeDetailView from '../common/BadgeDetailView'; + +interface ProfileBadgesProps { + userXId: string | undefined; + screenType: ScreenType; +} + +const ProfileBadges: React.FC<ProfileBadgesProps> = ({userXId, screenType}) => { + const navigation = useNavigation(); + const {badges, name, university} = useSelector((state: RootState) => + userXId ? state.userX[screenType][userXId].profile : state.user.profile, + ); + const [displayBadges, setDisplayBadges] = useState< + UniversityBadgeDisplayType[] + >([]); + const [isEditBadgeModalVisible, setIsEditBadgeModalVisible] = useState(false); + const isOwnProfile = userXId === undefined; + + useEffect(() => { + setDisplayBadges(badgesToDisplayBadges(badges, university)); + }, [badges]); + + const PlusIcon: FC = () => ( + <TouchableOpacity + onPress={() => navigation.navigate('BadgeSelection', {editing: true})}> + <PlusIconImage style={styles.plus} /> + </TouchableOpacity> + ); + + const CloseIcon: FC = () => ( + <TouchableOpacity onPress={() => setIsEditBadgeModalVisible(true)}> + <PlusIconImage style={styles.close} /> + </TouchableOpacity> + ); + + return ( + <> + {/* Tutorial text */} + {displayBadges.length === 0 && isOwnProfile && ( + <> + <Text style={styles.title}>Badges</Text> + <Text style={styles.body}> + Proudly represent your team, club, or organization! + </Text> + </> + )} + {displayBadges.length === 0 && isOwnProfile && ( + // Grey circle placeholders + <ScrollView + contentContainerStyle={styles.badgeContainer} + scrollEnabled={false} + horizontal> + <PlusIcon /> + {Array(BADGE_LIMIT) + .fill(0) + .map(() => ( + <View style={[styles.grey, styles.circle]} /> + ))} + </ScrollView> + )} + {displayBadges.length !== 0 && ( + // Populating actual badges + <ScrollView + contentContainerStyle={styles.badgeContainer} + scrollEnabled={false} + horizontal> + {/* Actual badges */} + {displayBadges.map((displayBadge) => ( + <BadgeIcon key={displayBadge.id} badge={displayBadge} /> + ))} + {/* Plus icon */} + {displayBadges.length < BADGE_LIMIT && isOwnProfile && <PlusIcon />} + {/* Empty placeholders for space-between styling */} + {Array(BADGE_LIMIT + 1) + .fill(0) + .splice(displayBadges.length + 1, BADGE_LIMIT) + .map(() => ( + <View style={styles.circle} /> + ))} + {/* X button */} + {displayBadges.length === BADGE_LIMIT && isOwnProfile && ( + <CloseIcon /> + )} + </ScrollView> + )} + {isEditBadgeModalVisible && ( + <BadgeDetailView + userXId={userXId} + screenType={screenType} + isEditable={isOwnProfile} + userFullName={name} + setBadgeViewVisible={setIsEditBadgeModalVisible} + /> + )} + </> + ); +}; + +const styles = StyleSheet.create({ + title: { + fontWeight: '600', + fontSize: normalize(13.5), + lineHeight: normalize(18), + }, + body: { + fontSize: normalize(13.5), + lineHeight: normalize(17), + marginBottom: 10, + }, + badgeContainer: { + width: '100%', + justifyContent: 'space-between', + marginTop: 10, + marginBottom: 15, + }, + circle: { + width: normalize(31), + height: normalize(31), + borderRadius: normalize(31) / 2, + }, + grey: { + backgroundColor: '#c4c4c4', + }, + plus: { + width: normalize(31), + height: normalize(31), + color: 'black', + }, + close: { + width: normalize(31), + height: normalize(31), + color: 'grey', + transform: [{rotate: '45deg'}], + }, +}); + +export default ProfileBadges; diff --git a/src/components/profile/ProfileBody.tsx b/src/components/profile/ProfileBody.tsx index 8743acfb..c0ee508a 100644 --- a/src/components/profile/ProfileBody.tsx +++ b/src/components/profile/ProfileBody.tsx @@ -20,6 +20,7 @@ import { import {canViewProfile} from '../../utils/users'; import {FriendsButton} from '../common'; import {MessageButton} from '../messages'; +import ProfileBadges from './ProfileBadges'; import ToggleButton from './ToggleButton'; interface ProfileBodyProps { @@ -65,6 +66,7 @@ const ProfileBody: React.FC<ProfileBodyProps> = ({ return ( <View onLayout={onLayout} style={styles.container}> + <ProfileBadges {...{userXId, screenType}} /> <Text style={styles.username}>{`@${username}`}</Text> {biography.length > 0 && ( <Text style={styles.biography}>{`${biography}`}</Text> @@ -137,7 +139,6 @@ const styles = StyleSheet.create({ justifyContent: 'space-between', }, container: { - paddingVertical: '1%', paddingHorizontal: 18, backgroundColor: 'white', }, diff --git a/src/components/profile/index.ts b/src/components/profile/index.ts index c544c3f2..faf273d9 100644 --- a/src/components/profile/index.ts +++ b/src/components/profile/index.ts @@ -9,3 +9,4 @@ export {default as ProfileMoreInfoDrawer} from './ProfileMoreInfoDrawer'; export {default as MomentMoreInfoDrawer} from './MomentMoreInfoDrawer'; export {default as UniversityIcon} from './UniversityIcon'; export {default as TaggAvatar} from './TaggAvatar'; +export {default as ProfileBadges} from './ProfileBadges'; |