LKSBrightSteps

แอปพลิเคชันเก็บบันทึกข้อมูลพฤติกรรมของเด็กที่บกพร่องทางด้านการเรียนรู้

React Native PHP MySQL REST API Linux Server

Overview

LKSBrightSteps เป็น Mobile Application ที่พัฒนาขึ้นเพื่อช่วยครูและผู้ปกครองในการติดตามและบันทึกพฤติกรรมของเด็กที่มีความบกพร่องทางการเรียนรู้ (Learning Disabilities) โดยมีการวิเคราะห์ผลในรูปแบบกราฟและการส่งออกรายงาน เพื่อให้การดูแลและพัฒนาเด็กเป็นไปอย่างมีประสิทธิภาพ

Mobile Application Interface
Login Interface
Data Visualization Dashboard
Software Structure

System Architecture & Logic

ระบบแบ่งการทำงานเป็น 2 ส่วนหลัก คือ Front-end พัฒนาด้วย React Native สำหรับ Mobile App และ Back-end ใช้ PHP ร่วมกับ MySQL บน Linux Server โดยสื่อสารกันผ่าน REST API

# Authentication API & Logic

LoginScreen.js / login-Reporter.php
// React Native: Login Function (Authentication)
const submitLogin = async () => {
  try {
    const response = await axios.post(
      `${API_URL}Login-System/login-Reporter.php`,
      { id: userId, password }
    );
    
    if (response.data.status === "success") {
      setUserId(response.data.id); // Context State Update
      navigation.navigate("Home");
    } else {
      Alert.alert("Error", "ID or Password incorrect");
    }
  } catch (error) {
    console.error(error);
  }
};
// PHP: Verify Password Hash (Backend Logic)
$sql = "SELECT id, password FROM reporteracc WHERE id = ?";
$stmt = $conn->prepare($sql);
$stmt->bind_param("s", $user_id);
$stmt->execute();
$result = $stmt->get_result();

if ($result->num_rows == 1) {
    $row = $result->fetch_assoc();
    // ใช้ password_verify เพื่อความปลอดภัย
    if (password_verify($input_password, $row['password'])) {
        $_SESSION["user_id"] = $user_id;
        echo json_encode(["status" => "success"]);
    }
}

# Data Recording API & Logic

reporting.js / save_student.php
const submitStudentData = async (id, type, level, detail, time, reporter) => {
  try {
    const response = await axios.post(API_URL2, {
      studentId: id,
      type,
      level,
      detail,
      time,
      reporter,
    }, {
      headers: { "Content-Type": "application/json" },
    });

    console.log("Response:", response.data);
    return response.data;
  } catch (error) {
    console.error("Error:", error);
    return { status: "error", message: "Failed to submit data" };
  }
};

const StudentForm = () => {
  const [type, setType] = useState("");
  const [level, setLevel] = useState("");
  const handleLevelPress = (selectedLevel) => {
    if (level === selectedLevel) {
      setLevel(""); 
    } else {
      setLevel(selectedLevel); 
    }
  };
  const [detail, setDetail] = useState("");

  const { studentId } = useStudent();
  const { userId } = useUser();
  const navigation = useNavigation(); 
  const [showAlert, setShowAlert] = useState(false);
  const [isButtonDisabled, setIsButtonDisabled] = useState(false); 
  const fadeAnim = useState(new Animated.Value(0))[0];
$data = json_decode(file_get_contents("php://input"));

if (!isset($data->studentId, $data->type, $data->level, $data->detail, $data->time, $data->reporter)) {
    echo json_encode(["status" => "error", "message" => "ข้อมูลไม่ครบถ้วน"]);
    exit;
}

$studentId = $data->studentId;
$type = $data->type;
$level = $data->level;
$detail = $data->detail;
$time = $data->time;
$reporter = $data->reporter;

$sql = "INSERT IGNORE INTO student (studentId, type, level, detail, time, reporter) VALUES (?, ?, ?, ?, ?, ?)";
$stmt = $conn->prepare($sql);
$stmt->bind_param("ssssss", $studentId, $type, $level, $detail, $time, $reporter);

if ($stmt->execute()) {
    echo json_encode(["status" => "success"]);
} else {
    echo json_encode(["status" => "error", "message" => $stmt->error]);
}

# Get Data API & Logic

student_history.js / student_history.php
useEffect(() => {
    if (!parentId || !studentId) return;

    setLoading(true);

    axios
      .get(
        `${API_URL}Parent-System/student-history.php?parent=${parentId}&student=${studentId}`)
      .then((response) => {
        if (!response.data || response.data.error) {
          setAccessDenied(true);
        } else {
          setHistory(response.data);
        }
      })
      .catch((error) => {
        console.error("Error fetching history:", error);
        Alert.alert("Error", "Could not load data.");
      })
      .finally(() => setLoading(false));
  }, [parentId, studentId]);
// Check parent access permission on the student data
$check_sql = "SELECT * FROM request WHERE parent = ? AND student = ? AND status = 'true'";
$check_stmt = $conn->prepare($check_sql);
$check_stmt->bind_param("ss", $parentId, $studentId);
$check_stmt->execute();
$check_result = $check_stmt->get_result();

if ($check_result->num_rows == 0) {
    die(json_encode(["error" => "Access denied"], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT));
}

// if permission granted, fetch student data
$sql = "SELECT * FROM student WHERE studentId = ?";
$stmt = $conn->prepare($sql);
$stmt->bind_param("s", $studentId);
$stmt->execute();
$result = $stmt->get_result();

$data = [];
while ($row = $result->fetch_assoc()) {
    $data[] = $row;
}
← Back to Portfolio