Skip to content

Commit

Permalink
Create component for collecting user feedback
Browse files Browse the repository at this point in the history
  • Loading branch information
rrachea committed Oct 20, 2024
1 parent 787cfc7 commit 6a36b5f
Show file tree
Hide file tree
Showing 2 changed files with 242 additions and 9 deletions.
28 changes: 19 additions & 9 deletions frontend/iQMA-Skills-Builder/app/screens/Home.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
// screens/HomeScreen.tsx

import * as accountEndpoints from '@/helpers/accountEndpoints';
import * as lessonEndpoints from '@/helpers/lessonEndpoints';
import * as resultEndpoints from '@/helpers/resultEndpoints';
import * as sectionEndpoints from '@/helpers/sectionEndpoints';
import * as unitEndpoints from '@/helpers/unitEndpoints';
import * as accountEndpoints from '@/helpers/accountEndpoints';

import {
NativeScrollEvent,
Expand All @@ -21,6 +21,7 @@ import React, {useEffect, useRef, useState} from 'react';
import AsyncStorage from '@react-native-async-storage/async-storage';
import {AuthContext} from '@/context/AuthContext';
import {Colors} from '@/constants/Colors';
import FeedbackComponent from '@/components/Feedback';
import {Ionicons} from '@expo/vector-icons';
import {LoadingIndicator} from '@/components/LoadingIndicator';
import {SafeAreaView} from 'react-native-safe-area-context';
Expand All @@ -29,7 +30,6 @@ import TopStats from '@/components/TopStats';
import {router} from 'expo-router';
import {useContext} from 'react';


const HomeScreen: React.FC = () => {
const {currentUser, isLoading} = useContext(AuthContext);
const [circularProgress, setCircularProgress] = useState<number>(0);
Expand Down Expand Up @@ -172,7 +172,10 @@ const HomeScreen: React.FC = () => {
// console.log("unitID", unitID)
// console.log("totalLesson", totalLesson)

const getAllLessons = await lessonEndpoints.getAllLesson(sectionID, unitID);
const getAllLessons = await lessonEndpoints.getAllLesson(
sectionID,
unitID
);

if (getAllLessons.length === 0) {
return;
Expand Down Expand Up @@ -225,15 +228,19 @@ const HomeScreen: React.FC = () => {
}
} else {
if (getAllLessons[completedLessons]) {
currentLessonId = getAllLessons[completedLessons].lessonID;
currentLessonId =
getAllLessons[completedLessons].lessonID;
}
currentLessonIdx = completedLessons;
if (completedLessons !== 0) {
routerName = 'Lesson';
currentProgress =
1 +
completedLessons * 2 +
accountEndpoints.calculateKTProgress(getLessonIds, completedLessons);
accountEndpoints.calculateKTProgress(
getLessonIds,
completedLessons
);
// console.log('Current Progress:', currentProgress);
} else if (completedUnits === 0) {
routerName = 'SectionIntroduction';
Expand Down Expand Up @@ -309,8 +316,11 @@ const HomeScreen: React.FC = () => {
useEffect(() => {
(async () => {
try {
const sectionDetails = await sectionEndpoints.getAllSectionDetails();
let currentSection = await resultEndpoints.getCurrentSection(currentUser.sub);
const sectionDetails =
await sectionEndpoints.getAllSectionDetails();
let currentSection = await resultEndpoints.getCurrentSection(
currentUser.sub
);
console.log('Current Section Outside:', currentSection);

if (currentSection > sectionDetails.length) {
Expand Down Expand Up @@ -359,8 +369,7 @@ const HomeScreen: React.FC = () => {
})();
}, [completedFinals, sectionCircularProgress, circularProgress]);

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

const handlePress = (
pathName: string,
Expand Down Expand Up @@ -452,6 +461,7 @@ const HomeScreen: React.FC = () => {
<Ionicons name="arrow-up" size={24} color="#7654F2" />
</TouchableOpacity>
)}
<FeedbackComponent />
</SafeAreaView>
);
};
Expand Down
223 changes: 223 additions & 0 deletions frontend/iQMA-Skills-Builder/components/Feedback.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,223 @@
import {
Modal,
StyleSheet,
Text,
TextInput,
TouchableOpacity,
View,
} from 'react-native';
import React, {useState} from 'react';

import {Colors} from '@/constants/Colors';
import {Picker} from '@react-native-picker/picker';

// Define types for the component
type FeedbackComponentProps = {};

const FeedbackComponent: React.FC<FeedbackComponentProps> = () => {
const [visible, setVisible] = useState<boolean>(false); // To toggle form visibility
const [selectedOption, setSelectedOption] = useState<string>(''); // Dropdown state
const [selectedRating, setSelectedRating] = useState<number | null>(null); // Rating state
const [message, setMessage] = useState<string>(''); // Message based on dropdown

// Messages corresponding to dropdown options
const customMessages: {[key: string]: string} = {
feedback:
"We're here to listen! Are your feedback about gamification techniques or the course content?",
bug: "We're here to help! Are you reporting a bug related to the system functionality or a display issue?",
suggestion:
'We love hearing new ideas! Is your suggestion about improving the course or adding new features?',
};

const onDropdownChange = (itemValue: string) => {
setSelectedOption(itemValue);
setMessage(customMessages[itemValue] || ''); // Set custom message based on dropdown selection
};

const ratingFaces = ['😭', '😐', '😊', '😀'];

return (
<View style={styles.container}>
{/* Floating Button */}
<TouchableOpacity
style={styles.bubble}
onPress={() => setVisible(true)}
>
<Text style={styles.bubbleText}>🗳️</Text>
</TouchableOpacity>

{/* Modal for Form */}
<Modal visible={visible} transparent={true} animationType="slide">
<View style={styles.modalBackground}>
<View style={styles.formContainer}>
<Text style={styles.formTitle}>User Feedback Form</Text>

{/* Dropdown Field */}
<View style={styles.dropdownContainer}>
<Picker
selectedValue={selectedOption}
style={styles.dropdown}
onValueChange={(itemValue: string) =>
onDropdownChange(itemValue)
}
>
<Picker.Item label="Select Type" value="" />
<Picker.Item
label="Feedback"
value="feedback"
/>
<Picker.Item label="Bug Report" value="bug" />
<Picker.Item
label="Suggestion"
value="suggestion"
/>
</Picker>
</View>

{/* Rating Field with Faces */}
<View style={styles.ratingContainer}>
{/* Render the rating faces */}
{ratingFaces.map((emoji, index) => (
<TouchableOpacity
key={index}
onPress={() => setSelectedRating(index)} // Set selected rating
style={[
styles.faceContainer,
selectedRating !== null &&
selectedRating !== index
? styles.grayscale
: {},
]}
>
<Text style={styles.face}>{emoji}</Text>
<Text>{index + 1}</Text>
</TouchableOpacity>
))}
</View>

{/* Custom Message */}
{selectedOption ? (
<Text style={styles.customMessage}>{message}</Text>
) : null}

{/* Text Input Field */}
<TextInput
style={styles.textInput}
placeholder="We value your inputs! Please share your feedback here."
multiline
/>

{/* Close Form Button */}
<TouchableOpacity
style={styles.closeButton}
onPress={() => setVisible(false)}
>
<Text style={styles.closeButtonText}>Close</Text>
</TouchableOpacity>
</View>
</View>
</Modal>
</View>
);
};

// Styles
const styles = StyleSheet.create({
bubble: {
alignItems: 'center',
backgroundColor: Colors.default.purple100,
borderRadius: 30,
bottom: 20,
width: 60,
height: 60,
justifyContent: 'center',
left: 20,
position: 'absolute',
zIndex: 1000,
},
bubbleText: {
color: Colors.chatbot.inputColor,
fontSize: 30,
},
closeButton: {
backgroundColor: '#C3B1FF',
borderRadius: 5,
marginTop: 10,
padding: 10,
},
closeButtonText: {
color: '#7654F2',
},
container: {
flex: 1,
justifyContent: 'flex-end',
alignItems: 'center',
},
customMessage: {
color: Colors.light.text,
fontSize: 16,
marginRight: 10,
paddingLeft: 20,
paddingHorizontal: 10,
paddingVertical: 5,
},
dropdown: {
color: Colors.light.text,
height: 50,
width: 200,
},
dropdownContainer: {
borderWidth: 1, // Border width
borderColor: Colors.default.purple500, // Custom border color
borderRadius: 5, // Rounded corners
overflow: 'hidden', // Ensures content doesn't overflow the border
marginBottom: 10, // Space below the dropdown
},
grayscale: {
// Apply grayscale filter
opacity: 0.3, // Make the unselected emojis look like they are black and white
},
face: {
fontSize: 30,
marginHorizontal: 10,
},
faceContainer: {
padding: 10, // Optional padding around the emoji
},
formContainer: {
alignItems: 'center',
backgroundColor: 'white',
borderRadius: 10,
padding: 20,
margin: 20,
},
formTitle: {
color: Colors.default.purple500,
fontSize: 18,
marginBottom: 10,
},
modalBackground: {
flex: 1,
justifyContent: 'center',
backgroundColor: 'rgba(0,0,0,0.5)',
},
ratingContainer: {
flexDirection: 'row',
justifyContent: 'space-around',
marginVertical: 10,
},
textInput: {
borderColor: 'gray',
borderWidth: 1,
borderRadius: 5,
color: Colors.light.text,
height: 100,
marginVertical: 20,
marginRight: 10,
paddingHorizontal: 10,
paddingLeft: 20,
width: 300,
},
});

export default FeedbackComponent;

0 comments on commit 6a36b5f

Please sign in to comment.