Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SCRUM-170 Create frontend for all badges #97

Merged
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
202 changes: 202 additions & 0 deletions frontend/iQMA-Skills-Builder/app/Achievements.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
import {
Text,
View,
TextInput,
TouchableOpacity,
StyleSheet,
ScrollView,
Image,
} from 'react-native';
import {useState, useContext, useEffect} from 'react';
import {AuthContext} from '@/context/AuthContext';
import {LoadingIndicator} from '@/components/LoadingIndicator';
import * as gamificationEndpoints from '@/helpers/gamificationEndpoints';
import {Colors} from '@/constants/Colors';
import { formatSection } from '@/helpers/formatSectionID';

export default function Achievements() {
const {currentUser} = useContext(AuthContext);
const [badges, setBadges] = useState<any[]>([]);
const [loading, setLoading] = useState<boolean>(true);

const mock = [
{
sectionID: 'SEC0001',
badges: [
{
unitName: 'Foundations of Communication',
badgeUrl:
'https://lugppkebziopzwushqcg.supabase.co/storage/v1/object/public/badges/placeholder.png',
},
{
unitName: 'Written Communication Proficiency',
badgeUrl:
'https://lugppkebziopzwushqcg.supabase.co/storage/v1/object/public/badges/placeholder.png',
},
{
unitName: 'Visual Communication Strategies',
badgeUrl:
'https://lugppkebziopzwushqcg.supabase.co/storage/v1/object/public/badges/placeholder.png',
},
{
unitName: 'Stakeholder Analysis and Audience Engagement',
badgeUrl:
'https://lugppkebziopzwushqcg.supabase.co/storage/v1/object/public/badges/placeholder.png',
},
{
unitName: 'Interpersonal Communication Excellence',
badgeUrl:
'https://lugppkebziopzwushqcg.supabase.co/storage/v1/object/public/badges/SEC0001/unit3.png',
},
{
unitName: 'Mastering Two-Way Communication',
badgeUrl:
'https://lugppkebziopzwushqcg.supabase.co/storage/v1/object/public/badges/SEC0001/unit2.png',
},
{
unitName: 'The Art of Persuasion',
badgeUrl:
"https://lugppkebziopzwushqcg.supabase.co/storage/v1/object/public/badges/locked.png",
},
],
},
{
sectionID: 'SEC0002',
badges: [
{
unitName: 'Foundations of Communication',
badgeUrl:
'https://lugppkebziopzwushqcg.supabase.co/storage/v1/object/public/badges/placeholder.png',
},
{
unitName: 'Written Communication Proficiency',
badgeUrl:
"https://lugppkebziopzwushqcg.supabase.co/storage/v1/object/public/badges/locked.png",
},
{
unitName: 'Visual Communication Strategies',
badgeUrl:
"https://lugppkebziopzwushqcg.supabase.co/storage/v1/object/public/badges/locked.png",
},
],
},
];

const fetchAchievements = async () => {
try {
const badges = await gamificationEndpoints.getBadges(
currentUser.sub
);

setBadges(badges);

console.log(badges);
} catch (error) {
console.error('Error fetching achievements', error);
} finally {
setLoading(false);
}
};

useEffect(() => {
fetchAchievements();
}, []);

if (loading) {
return <LoadingIndicator />;
}

return (
<ScrollView style={styles.container}>
<View>
{badges.map((section) => (
<>
<View style={styles.sectionContainer}>
<Text style={styles.sectionHeading}>
{/* {section.sectionID} */}
Section {formatSection(section.sectionID)}
</Text>
<View
key={section.sectionID}
style={styles.badgeOuterContainer}
>
{section.badges.map(
(badge: {
badgeUrl: string;
unitName: string;
}) => (
<View style={styles.badgeContainer}>
<Image
source={{uri: badge.badgeUrl}}
style={styles.badgeImage}
/>
{/* <Text style={styles.unlockedBadgeText}> */}
<Text
style={
badge.badgeUrl.endsWith(
'locked.png'
)
? styles.lockedBadgeText
: styles.unlockedBadgeText
}
>
{badge.unitName}
</Text>
</View>
)
)}
</View>
</View>
</>
))}
</View>
</ScrollView>
);
}

const styles = StyleSheet.create({
container: {
// flex: 1,
// padding: 20,
paddingHorizontal: 20,
},
sectionContainer: {
marginTop: 20,
},
sectionHeading: {
color: Colors.light.color,
fontWeight: 'bold',
fontSize: 16,
textAlign: "center"
},
badgeOuterContainer: {
flexDirection: 'row',
flexWrap: 'wrap',
justifyContent: 'space-between',
marginTop: 10,
// backgroundColor: 'red',
},
badgeImage: {
width: '100%',
aspectRatio: 1,
resizeMode: 'contain',
},
badgeContainer: {
width: '30%',
marginBottom: 20,
alignItems: 'center',
},
unlockedBadgeText: {
marginTop: 10,
textAlign: 'center',
// color: Colors.light.text,
color: Colors.default.purple500,
fontWeight: 'bold',
},
lockedBadgeText: {
marginTop: 10,
textAlign: 'center',
color: Colors.light.text,
fontWeight: 'bold',
},
});
10 changes: 10 additions & 0 deletions frontend/iQMA-Skills-Builder/app/_layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,16 @@ export default function RootLayout() {
headerTintColor: Colors.light.background
}}
/>
<Stack.Screen
name="Achievements"
options={{
headerTitle: "Achievements",
headerStyle: {
backgroundColor: Colors.default.purple100,
},
headerTintColor: Colors.light.background
}}
/>
</Stack>
</AuthProvider>
</Auth0Provider>
Expand Down
43 changes: 34 additions & 9 deletions frontend/iQMA-Skills-Builder/components/Achievement.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,14 @@ import {
FlatList,
} from 'react-native';
import {OverviewCard} from '@/components/OverviewCard';
import {router} from 'expo-router';

interface AchievementsProps {
achievements: any[];
}

export const Achievements: React.FC<AchievementsProps> = ({achievements}) => {
// console.log('achievements:', achievements);
console.log('achievements:', achievements);

let topThreeAchievements: any[] = [];

Expand All @@ -26,18 +27,37 @@ export const Achievements: React.FC<AchievementsProps> = ({achievements}) => {
);
}

const handlePress = () => {
router.push("Achievements");
};

// console.log('topThreeAchievements:', topThreeAchievements);
return (
<View style={styles.outerContainer}>
<Text
style={[
styles.achievementsHeader,
topThreeAchievements.length === 0 &&
styles.achievementsError,
]}
<View
style={{flexDirection: 'row', justifyContent: 'space-between'}}
>
Achievements
</Text>
<Text
style={[
styles.achievementsHeader,
topThreeAchievements.length === 0 &&
styles.achievementsError,
]}
>
Achievements
</Text>
<TouchableOpacity onPress={handlePress}>
<Text
style={{
textDecorationLine: 'underline',
textDecorationColor: '#5C5776',
fontWeight: 'bold',
}}
>
View all
</Text>
</TouchableOpacity>
</View>
{topThreeAchievements.length === 0 && (
<OverviewCard
text="Sorry, our system is currently under maintenance."
Expand Down Expand Up @@ -74,6 +94,11 @@ const styles = StyleSheet.create({
paddingHorizontal: 20,
marginTop: 20,
},
header: {
fontSize: 16,
fontWeight: 'bold',
color: '#18113C',
},
achievementsHeader: {
fontSize: 16,
fontWeight: 'bold',
Expand Down
2 changes: 1 addition & 1 deletion frontend/iQMA-Skills-Builder/context/AuthContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export const AuthProvider = ({children}: {children: React.ReactNode}) => {
} else {
// await AsyncStorage.removeItem('userID');
await AsyncStorage.clear();
setIsLoading(false);
// setIsLoading(false);
}
setIsLoading(false);
};
Expand Down