parinazAkef's picture
Fresh start: TalimBot project without binary files
2fe573b
// Student Grouping System - Data Management
// This file handles all data operations using Backend API
// Backend API Configuration
// Auto-detects if running on Railway deployment or localhost
function getApiBaseUrl() {
// When deployed to Railway, it will use the same domain
// Railway serves both frontend and backend from the same URL
// So we use relative paths for API calls
if (window.location.hostname !== 'localhost' && window.location.hostname !== '127.0.0.1') {
// PRODUCTION: Running on Railway - use relative paths
return '/api';
}
// DEVELOPMENT: Running locally
return 'http://localhost:8000/api';
}
const API_BASE_URL = getApiBaseUrl();
// Utility function for API calls
async function apiCall(endpoint, options = {}) {
try {
const response = await fetch(`${API_BASE_URL}${endpoint}`, {
...options,
headers: {
'Content-Type': 'application/json',
...options.headers
}
});
if (!response.ok) {
const error = await response.json();
throw new Error(error.detail || 'API request failed');
}
return await response.json();
} catch (error) {
console.error('API Error:', error);
throw error;
}
}
// Get all data (for backward compatibility)
async function getData() {
const students = await getAllStudents();
const status = await getGroupingStats();
return {
students: students,
courseName: status.courseName,
groupingComplete: status.groupingComplete,
resultsVisible: status.resultsVisible,
teacherPassword: 'teacher123'
};
}
// Get student by student number
async function getStudent(studentNumber) {
try {
return await apiCall(`/student/${studentNumber}`);
} catch (error) {
return null;
}
}
// Update student information
async function updateStudent(studentNumber, updates) {
try {
const result = await apiCall(`/student/${studentNumber}`, {
method: 'PUT',
body: JSON.stringify(updates)
});
return result.success;
} catch (error) {
return false;
}
}
// Get all students
async function getAllStudents() {
const result = await apiCall('/students');
return result.students;
}
// Check if a student number exists in the system
async function studentExists(studentNumber) {
const student = await getStudent(studentNumber);
return student !== null;
}
// Get students with complete information (REQUIRED fields only: MBTI and Learning Style)
async function getStudentsWithCompleteInfo() {
const students = await getAllStudents();
return students.filter(s => s.mbti && s.learningStyle);
}
// Check if a student has complete profile (all fields filled)
async function hasCompleteProfile(studentNumber) {
const student = await getStudent(studentNumber);
if (!student) return false;
return !!(student.mbti && student.learningStyle &&
student.ams !== null && student.cooperative !== null);
}
// Get completion percentage for a student
async function getProfileCompletion(studentNumber) {
const student = await getStudent(studentNumber);
if (!student) return 0;
let completed = 0;
const total = 4;
if (student.mbti) completed++;
if (student.learningStyle) completed++;
if (student.ams !== null) completed++;
if (student.cooperative !== null) completed++;
return Math.round((completed / total) * 100);
}
// Get grouping statistics
async function getGroupingStats() {
return await apiCall('/grouping/status');
}
// Check if grouping is complete
async function isGroupingComplete() {
const stats = await getGroupingStats();
return stats.groupingComplete;
}
// Get course name
async function getCourseName() {
const stats = await getGroupingStats();
return stats.courseName;
}
// Check teacher password
async function checkTeacherPassword(password) {
try {
const result = await apiCall('/auth/teacher', {
method: 'POST',
body: JSON.stringify({ password })
});
return result.valid;
} catch (error) {
return false;
}
}
// Get student's group (only if results are visible)
async function getStudentGroup(studentNumber) {
try {
return await apiCall(`/student/${studentNumber}/group`);
} catch (error) {
if (error.message.includes('not yet visible')) {
return { error: 'results_not_visible', message: 'نتایج هنوز توسط معلم نمایش داده نشده است.' };
}
if (error.message.includes('not assigned')) {
return { error: 'not_assigned', message: 'شما هنوز به گروهی اختصاص داده نشده‌اید.' };
}
throw error;
}
}
// Reset grouping only (keep student data)
async function resetGrouping(password) {
return await apiCall('/grouping/reset', {
method: 'POST',
body: JSON.stringify({ password })
});
}
// Reset ALL data (student profiles + grouping)
async function resetAllData(password) {
return await apiCall('/data/reset-all', {
method: 'POST',
body: JSON.stringify({ password })
});
}
// Toggle results visibility
async function toggleResultsVisibility(password) {
return await apiCall('/grouping/toggle-visibility', {
method: 'POST',
body: JSON.stringify({ password })
});
}
// Legacy functions for backward compatibility (these are handled by backend now)
function saveData(data) {
console.warn('saveData is deprecated - data is automatically saved to backend');
}
function initializeData() {
console.log('Data is managed by backend');
return true;
}
function addNewStudent(studentNumber, name, grade = 15) {
console.warn('addNewStudent should be done through admin panel');
return { success: false, message: 'Use backend API for adding students' };
}
function saveStudents(students) {
console.warn('saveStudents is deprecated - use backend API');
}
function deleteStudent(studentNumber) {
console.warn('deleteStudent should be done through admin panel');
return false;
}
function setGroupingComplete(status) {
console.warn('setGroupingComplete is handled by backend');
}
function setCourseName(name) {
console.warn('setCourseName is handled by backend');
}
function resetData() {
console.warn('resetData should be done through teacher dashboard');
}
// Export functions for use in other files
if (typeof module !== 'undefined' && module.exports) {
module.exports = {
getData,
getStudent,
updateStudent,
getAllStudents,
studentExists,
getStudentsWithCompleteInfo,
hasCompleteProfile,
getProfileCompletion,
isGroupingComplete,
getCourseName,
checkTeacherPassword,
getGroupingStats,
getStudentGroup
};
}