bài tập

 avatar
unknown
plain_text
23 days ago
8.4 kB
5
Indexable
import React, { useEffect, useState } from "react";
import { View, Text, StyleSheet, TouchableOpacity, ScrollView, Image, Alert } from "react-native";
import { useRouter, useLocalSearchParams } from "expo-router";
import { Icons } from "../../constants/Screen/Icons";
import { LinearGradient } from "expo-linear-gradient";
import { Fonts } from "../../constants/Fonts";
import AsyncStorage from '@react-native-async-storage/async-storage';
import api from "../../constants/API";
import { getByExerciseId } from "../../api/question";

export default function ExerciseScreen() {
  const router = useRouter();
  const { exerciseData, color } = useLocalSearchParams();
  const gradientColors = color ? color.split(",") : ["#FFB6C1", "#FF69B4"];
  const exerciseObject = JSON.parse(exerciseData);
  const [randomizedQuestions, setRandomizedQuestions] = useState([]);
  const [selectedOptions, setSelectedOptions] = useState({});
  const [showSolutions, setShowSolutions] = useState(false);
  const [userInfo, setUserInfo] = useState({});

  const fetchData = async () => {
    try {
      const students = await AsyncStorage.getItem("Student");
      if (students) {
        setUserInfo(JSON.parse(students));
      }
      const storedData = await getByExerciseId(exerciseObject.id);
      const randomized = storedData
        .sort(() => Math.random() - 0.5)
        .slice(0, 10)
        .map((item) => ({
          ...item,
          shuffledOptions: randomizeOptions(item),
        }));
      setRandomizedQuestions(randomized);
    } catch (error) {
      console.error("Error:", error);
    }
  };

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

  const handleOptionSelect = (questionIndex, option) => {
    if (!showSolutions) { // Chỉ cho phép chọn khi chưa nộp bài
      setSelectedOptions((prev) => ({
        ...prev,
        [questionIndex]: option,
      }));
    }
  };
  const calculateScore = async () => {
    setShowSolutions(true); // Hiển thị đáp án sau khi nộp bài
    const correctAnswers = randomizedQuestions.filter(
      (item, index) => selectedOptions[index] === item.answer
    ).length;
    const incorrectAnswers = 10 - correctAnswers;
    Alert.alert("Kết quả bài tập", `Bạn trả lời đúng: ${correctAnswers}/10\nBạn trả lời sai: ${incorrectAnswers}/10`);
    if (correctAnswers >= 8) {
      try {
        await api.post("/ExerciseStatus", {
          studentID: userInfo.id,
          exerciseID: exerciseObject.id,
          point: correctAnswers,
          isComplete: true,
        });
      } catch (error) {
        console.error("API Error:", error);
      }
    } else {
      try {
        await api.post("/ExerciseStatus", {
          studentID: userInfo.id,
          exerciseID: exerciseObject.id,
          point: correctAnswers,
          isComplete: false,
        });
      } catch (error) {
        console.error("API Error:", error);
      }
    }
    setShowSolutions(true);
  };

  const randomizeOptions = (item) => {
    const options = [
      item.answer,
      item.wrongAnswer1,
      item.wrongAnswer2,
      item.wrongAnswer3,
    ];
    return options.sort(() => Math.random() - 0.5);
  };

  return (
    <LinearGradient colors={gradientColors} style={styles.container}>
      <View style={styles.header}>
        <TouchableOpacity
          style={styles.goBackButton}
          onPress={() => router.back()}
        >
          <Image source={Icons.back} style={styles.back} />
        </TouchableOpacity>
        <Text style={styles.title}>{exerciseObject.name || "Không có tiêu đề"}</Text>
      </View>
      <ScrollView contentContainerStyle={styles.content}>
        {randomizedQuestions.length > 0 && (
          <>
            <Text style={styles.sectionTitle}>BÀI TẬP</Text>
            {randomizedQuestions.map((item, index) => {
              const options = item.shuffledOptions;
              const selectedOption = selectedOptions[index];
              return (
                <View key={index} style={styles.questionContainer}>
                  <View style={styles.questionnumber}>
                    <Text style={styles.numberquestion}>{`Câu ${index + 1}`}</Text>
                    <Text style={styles.question}>{item.question}</Text>
                  </View>
                  <View style={styles.optionsContainer}>
                    {options.map((option, optIndex) => {
                      let backgroundColor = "rgba(255, 255, 255, 0.2)";
                      if (showSolutions) {
                        if (option === item.answer) {
                          backgroundColor = "green";
                        } else if (option === selectedOption) {
                          backgroundColor = "red";
                        }
                      } else if (option === selectedOption) {
                        backgroundColor = "#FF1493";
                      }
                      return (
                        <TouchableOpacity
                          key={optIndex}
                          style={[styles.optionItem, { backgroundColor }]}
                          onPress={() => handleOptionSelect(index, option)}
                        >
                          <Text style={styles.option}>{option}</Text>
                        </TouchableOpacity>
                      );
                    })}
                  </View>

                  {showSolutions && (
                    <View style={styles.solutionContainer}>
                      <Text style={styles.solutionText}>{item.solution}</Text>
                    </View>
                  )}
                </View>
              );
            })}
            {!showSolutions && (
              <TouchableOpacity style={styles.solutionButton} onPress={calculateScore}>
                <Text style={styles.solutionButtonText}>Nộp bài</Text>
              </TouchableOpacity>
            )}

          </>
        )}
      </ScrollView>
    </LinearGradient>
  );
}



const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
  header: {
    paddingVertical: 20,
    paddingHorizontal: 16,
    flexDirection: "row",
    alignItems: "center",
    justifyContent: "center",
    position: "relative",
  },
  goBackButton: {
    position: "absolute",
    left: 10,
    padding: 8,
    borderRadius: 50,
    backgroundColor: "rgba(0, 0, 0, 0.2)",
  },
  back: {
    width: 30,
    height: 30,
  },
  title: {
    fontSize: 24,
    fontFamily: Fonts.NUNITO_BLACK,
    color: "#fff",
  },
  content: {
    flexGrow: 1,
    padding: 20,
  },
  sectionTitle: {
    fontSize: 16,
    fontFamily: Fonts.NUNITO_BLACK,
    color: "#fff",
    marginVertical: 10,
  },
  text: {
    fontSize: 14,
    color: "#333",
    backgroundColor: "#fff",
    fontFamily: Fonts.NUNITO_BLACK,
    padding: 10,
    borderRadius: 5,
  },
  questionContainer: {
    marginBottom: 15,
    backgroundColor: "rgba(255, 255, 255, 0.2)",
    padding: 10,
    borderRadius: 8,
  },
  question: {
    fontSize: 30,
    fontFamily: Fonts.NUNITO_BLACK,
    color: "#fff",
    marginLeft: 60,
  },
  optionsContainer: {
    flexDirection: "row",
    justifyContent: "space-between",
    marginVertical: 20,
  },
  optionItem: {
    backgroundColor: "rgba(255, 0, 230, 0.2)",
    padding: 20,
    borderRadius: 10,
  },
  option: {
    fontSize: 16,
    color: "#fff",
    fontFamily: Fonts.NUNITO_BLACK,
  },
  correctAnswer: {
    backgroundColor: "green",
  },
  wrongAnswer: {
    backgroundColor: "red",
  },
  solutionButton: {
    marginTop: 10,
    padding: 10,
    backgroundColor: "#007AFF",
    borderRadius: 5,
  },
  solutionButtonText: {
    color: "#fff",
    textAlign: "center",
    fontWeight: "bold",
  },
  solutionContainer: {
    marginTop: 10,
    padding: 10,
    backgroundColor: "#fff",
    borderRadius: 5,
  },
  solutionText: {
    fontSize: 14,
    color: "#333",
    fontFamily: Fonts.NUNITO_BLACK,
  },
  questionnumber: {
    flexDirection: 'row',
    justifyContent: 'flex-start',

  },
  numberquestion: {
    fontSize: 20,
    fontFamily: Fonts.NUNITO_BLACK,
    color: "#fff",
  }
});
Editor is loading...
Leave a Comment