Skip to content

tongexe3-blip/my-data

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 

Repository files navigation

my-data

<title>Student Management System</title> <script src="https://cdn.jsdelivr.net/npm/xlsx@0.18.5/dist/xlsx.full.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/chart.js@3.9.1/dist/chart.min.js"></script> <style> * { margin: 0; padding: 0; box-sizing: border-box; }

body { font-family: 'Arial', 'Khmer OS', sans-serif; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); min-height: 100vh; padding: 20px; }

.container { max-width: 1400px; margin: 0 auto; background: white; border-radius: 10px; padding: 30px; box-shadow: 0 10px 40px rgba(0, 0, 0, 0.2); }

h1 { color: #333; text-align: center; margin-bottom: 10px; }

h2 { color: #666; text-align: center; margin-bottom: 30px; font-size: 18px; }

h3 { color: #333; margin-top: 20px; margin-bottom: 15px; }

.controls { display: flex; gap: 5px; margin-bottom: 10px; flex-wrap: nowrap; justify-content: center; }

.btn { padding: 5px 10px; border: none; border-radius: 5px; cursor: pointer; font-size: 8px; font-weight: bold; transition: all 0.3s ease; text-decoration: none; }

.btn-primary { background-color: #3498db; color: white; }

.btn-primary:hover { background-color: #2980b9; transform: translateY(-2px); box-shadow: 0 5px 15px rgba(52, 152, 219, 0.4); }

.btn-success { background-color: #2ecc71; color: white; }

.btn-success:hover { background-color: #27ae60; transform: translateY(-2px); box-shadow: 0 5px 15px rgba(46, 204, 113, 0.4); }

.btn-info { background-color: #1abc9c; color: white; }

.btn-info:hover { background-color: #16a085; transform: translateY(-2px); box-shadow: 0 5px 15px rgba(26, 188, 156, 0.4); }

.btn-warning { background-color: #f39c12; color: white; }

.btn-warning:hover { background-color: #d68910; transform: translateY(-2px); box-shadow: 0 5px 15px rgba(243, 156, 18, 0.4); }

.btn-danger { background-color: #e74c3c; color: white; }

.btn-danger:hover { background-color: #c0392b; }

#tableContainer { overflow-x: auto; }

table { width: 100%; border-collapse: collapse; margin-top: 10px; font-size: 13px; text-wrap: nowrap; text-content: left;

}

table, th, td { border: 1px solid #ddd; }

th { background-color: #34495e; color: white; padding: 12px 8px; text-align: center; font-weight: bold; }

td { padding: 10px 8px; text-align: left; }

tr:nth-child(even) { background-color: #f9f9f9; }

tr:hover { background-color: #f0f0f0; }

.edit-btn { background-color: #e74c3c; color: white; border: none; padding: 5px 10px; border-radius: 3px; cursor: pointer; font-size: 8px; }

.edit-btn:hover { background-color: #c0392b; }

.delete-btn { background-color: #e74c3c; color: white; border: none; padding: 5px 10px; border-radius: 3px; cursor: pointer; font-size: 8px; }

.delete-btn:hover { background-color: #c0392b; }

/* Modal Styles */ .modal { display: none; position: fixed; z-index: 1000; left: 0; top: 0; width: 100%; height: 100%; background-color: rgba(0, 0, 0, 0.5); overflow-y: auto; }

.modal-content { background-color: white; margin: 5% auto; padding: 30px; border-radius: 10px; width: 90%; max-width: 1200px; box-shadow: 0 10px 40px rgba(0, 0, 0, 0.3); max-height: 90vh; overflow-y: auto; }

.close { color: #aaa; float: right; font-size: 28px; font-weight: bold; cursor: pointer; }

.close:hover, .close:focus { color: #000; }

.report-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(400px, 1fr)); gap: 20px; margin: 20px 0; }

.report-card { background: #f8f9fa; border: 1px solid #dee2e6; border-radius: 8px; padding: 20px; box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); }

.report-card h3 { margin-top: 0; color: #333; border-bottom: 2px solid #3498db; padding-bottom: 10px; }

.report-card canvas { max-height: 300px; }

#statistics { padding: 15px; background: white; border-radius: 5px; line-height: 2; }

.stat-item { display: flex; justify-content: space-between; padding: 8px 0; border-bottom: 1px solid #eee; }

.stat-label { font-weight: bold; color: #333; }

.stat-value { color: #3498db; font-weight: bold; }

#printReportBtn { margin-top: 20px; }

@media print { body { background: white; }

.controls, .close {
    display: none;
}

.report-grid {
    grid-template-columns: repeat(2, 1fr);
}

}

@media (max-width: 768px) { .container { padding: 15px; }

.controls {
    flex-direction: column;
}

.btn {
    width: 100%;
}

table {
    font-size: 11px;
}

.report-grid {
    grid-template-columns: 1fr;
}

} </style>

ប្រព័ន្ធគ្រប់គ្រងព័ត៌មានសិស្ស

Student Management System

    <div class="controls">
        <button id="importBtn" class="btn btn-primary">📥 Import XLSX</button>
        <button id="exportJsonBtn" class="btn btn-success">📤 Export JSON</button>
        <button id="exportExcelBtn" class="btn btn-info">📊 Export Excel</button>
        <button id="reportBtn" class="btn btn-warning">📈 View Report</button>
        <input type="file" id="fileInput" accept=".xlsx,.xls" style="display:none;">
    </div>

    <div id="tableContainer">
        <h3>Student List</h3>
        <table id="studentTable">
            <thead>
                <tr>
                    <th>##</th>
                    <th>Student ID</th>
                    <th>Last Name</th>
                    <th>First Name</th>
                    <th>DOB</th>
                    <th>Age</th>
                    <th>Sex</th>
                    <th>Grade</th>
                    <th>Phone</th>
                    <th>Address</th>
                    <th>Status</th>
                    <th>Action</th>
                </tr>
            </thead>
            <tbody id="studentTableBody">
            </tbody>
        </table>
    </div>
</div>

<!-- Report Modal -->
<div id="reportModal" class="modal">
    <div class="modal-content">
        <span class="close">&times;</span>
        <h2>Student Report</h2>
        
        <div class="report-grid">
            <div class="report-card">
                <h3>Gender Distribution</h3>
                <canvas id="genderChart"></canvas>
            </div>
            
            <div class="report-card">
                <h3>Students by Grade</h3>
                <canvas id="gradeChart"></canvas>
            </div>
            
            <div class="report-card">
                <h3>Students by Age</h3>
                <canvas id="ageChart"></canvas>
            </div>
            
            <div class="report-card">
                <h3>Male/Female by Grade</h3>
                <canvas id="genderGradeChart"></canvas>
            </div>

            <div class="report-card">
                <h3>Male/Female by Age</h3>
                <canvas id="genderAgeChart"></canvas>
            </div>

            <div class="report-card">
                <h3>Statistics</h3>
                <div id="statistics"></div>
            </div>
        </div>

        <button id="printReportBtn" class="btn btn-primary">🖨️ Print Report</button>
    </div>
</div>
<script> class StudentManager { constructor() { this.students = []; this.charts = {}; this.initEventListeners(); this.loadFromLocalStorage(); } initEventListeners() { document.getElementById('importBtn').addEventListener('click', () => { document.getElementById('fileInput').click(); }); document.getElementById('fileInput').addEventListener('change', (e) => { this.importExcel(e); }); document.getElementById('exportJsonBtn').addEventListener('click', () => { this.exportJSON(); }); document.getElementById('exportExcelBtn').addEventListener('click', () => { this.exportExcel(); }); document.getElementById('reportBtn').addEventListener('click', () => { this.showReport(); }); document.querySelector('.close').addEventListener('click', () => { document.getElementById('reportModal').style.display = 'none'; }); window.addEventListener('click', (event) => { const modal = document.getElementById('reportModal'); if (event.target === modal) { modal.style.display = 'none'; } }); document.getElementById('printReportBtn').addEventListener('click', () => { window.print(); }); } importExcel(event) { const file = event.target.files[0]; if (!file) return; const reader = new FileReader(); reader.onload = (e) => { try { const data = new Uint8Array(e.target.result); const workbook = XLSX.read(data, { type: 'array' }); const worksheet = workbook.Sheets[workbook.SheetNames[0]]; const jsonData = XLSX.utils.sheet_to_json(worksheet); this.students = jsonData.map((row, index) => ({ id: index + 1, studentId: row['Student ID'] || row['studentId'] || '', lastName: row['Last Name'] || row['lastName'] || '', firstName: row['First Name'] || row['firstName'] || '', dob: row['DOB'] || row['dob'] || '', age: this.calculateAge(row['DOB'] || row['dob'] || ''), sex: row['Sex'] || row['sex'] || '', grade: row['Grade'] || row['grade'] || '', phone: row['Phone'] || row['phoneNumber'] || '', address: row['Address'] || row['fullAddress'] || '', status: row['Status'] || row['status'] || 'Active' })); this.saveToLocalStorage(); this.renderTable(); alert('✅ Excel file imported successfully!'); } catch (error) { alert('❌ Error importing file: ' + error.message); console.error(error); } }; reader.readAsArrayBuffer(file); } calculateAge(dateString) { if (!dateString) return 0; const today = new Date(); let birthDate = new Date(dateString); let age = today.getFullYear() - birthDate.getFullYear(); const monthDiff = today.getMonth() - birthDate.getMonth(); if (monthDiff < 0 || (monthDiff === 0 && today.getDate() < birthDate.getDate())) { age--; } return age; } renderTable() { const tbody = document.getElementById('studentTableBody'); tbody.innerHTML = ''; this.students.forEach((student, index) => { const row = tbody.insertRow(); row.innerHTML = ` ${index + 1} ${student.studentId} ${student.lastName} ${student.firstName} ${student.dob} ${student.age} ${student.sex} ${student.grade} ${student.phone} ${student.address} ${student.status} Delete Edit `; }); if (this.students.length === 0) { const row = tbody.insertRow(); row.innerHTML = 'No students data. Import Excel file to get started.'; } } // បន្ថែម method editStudent ទៅក្នុង class StudentManager editStudent(id) { // ស្វែងរកនិស្សិតតាម id const student = this.students.find(s => s.id === id); if (!student) return; // បង្ហាញ prompt សម្រាប់កែប្រែទិន្នន័យ (អាចប្តូរជា form modal ក្នុងពេលក្រោយ) const newLastName = prompt("Enter Last Name:", student.lastName); const newFirstName = prompt("Enter First Name:", student.firstName); const newDob = prompt("Enter DOB (YYYY-MM-DD):", student.dob); const newSex = prompt("Enter Sex:", student.sex); const newGrade = prompt("Enter Grade:", student.grade); const newPhone = prompt("Enter Phone:", student.phone); const newAddress = prompt("Enter Address:", student.address); const newStatus = prompt("Enter Status:", student.status); // បន្ទាប់ពីកែប្រែ ប្តូរ data លើ object និស្សិត student.lastName = newLastName || student.lastName; student.firstName = newFirstName || student.firstName; student.dob = newDob || student.dob; student.age = this.calculateAge(newDob) || student.age; student.sex = newSex || student.sex; student.grade = newGrade || student.grade; student.phone = newPhone || student.phone; student.address = newAddress || student.address; student.status = newStatus || student.status; this.saveToLocalStorage(); this.renderTable(); } deleteStudent(id) { if (confirm('Are you sure you want to delete this student?')) { this.students = this.students.filter(s => s.id !== id); this.saveToLocalStorage(); this.renderTable(); } } exportJSON() { const dataStr = JSON.stringify(this.students, null, 2); const dataBlob = new Blob([dataStr], { type: 'application/json' }); const url = URL.createObjectURL(dataBlob); const link = document.createElement('a'); link.href = url; link.download = `students_${new Date().toISOString().split('T')[0]}.json`; link.click(); URL.revokeObjectURL(url); } exportExcel() { const ws = XLSX.utils.json_to_sheet(this.students); const wb = XLSX.utils.book_new(); XLSX.utils.book_append_sheet(wb, ws, 'Students'); XLSX.writeFile(wb, `students_${new Date().toISOString().split('T')[0]}.xlsx`); } showReport() { document.getElementById('reportModal').style.display = 'block'; setTimeout(() => { this.generateReports(); }, 100); } generateReports() { this.createGenderChart(); this.createGradeChart(); this.createAgeChart(); this.createGenderGradeChart(); this.createGenderAgeChart(); this.createStatistics(); } createGenderChart() { const genderData = this.aggregateData('sex'); const ctx = document.getElementById('genderChart').getContext('2d'); if (this.charts.gender) { this.charts.gender.destroy(); } this.charts.gender = new Chart(ctx, { type: 'pie', data: { labels: Object.keys(genderData), datasets: [{ data: Object.values(genderData), backgroundColor: ['#FF6B6B', '#4ECDC4', '#95E1D3'], borderColor: ['#FF5252', '#45B7AA', '#7FD8BE'], borderWidth: 2 }] }, options: { responsive: true, maintainAspectRatio: true, plugins: { legend: { position: 'bottom' } } } }); } createGradeChart() { const gradeData = this.aggregateData('grade'); const ctx = document.getElementById('gradeChart').getContext('2d'); if (this.charts.grade) { this.charts.grade.destroy(); } this.charts.grade = new Chart(ctx, { type: 'pie', data: { labels: Object.keys(gradeData), datasets: [{ data: Object.values(gradeData), backgroundColor: this.getRandomColors(Object.keys(gradeData).length), borderWidth: 2 }] }, options: { responsive: true, maintainAspectRatio: true, plugins: { legend: { position: 'bottom', labels: { font: { size: 10 } } } } } }); } createAgeChart() { const ageData = this.aggregateData('age'); const sortedAges = Object.keys(ageData).sort((a, b) => a - b); const sortedData = sortedAges.map(age => ageData[age]); const ctx = document.getElementById('ageChart').getContext('2d'); if (this.charts.age) { this.charts.age.destroy(); } this.charts.age = new Chart(ctx, { type: 'bar', data: { labels: sortedAges, datasets: [{ label: 'Number of Students', data: sortedData, backgroundColor: '#3498db', borderColor: '#2980b9', borderWidth: 1 }] }, options: { responsive: true, maintainAspectRatio: true, indexAxis: 'x', plugins: { legend: { display: true } }, scales: { y: { beginAtZero: true, ticks: { stepSize: 1 } } } } }); } createGenderGradeChart() { const gradeGenderData = this.createCrossTabulation('grade', 'sex'); const grades = Object.keys(gradeGenderData); const genders = new Set(); grades.forEach(grade => { Object.keys(gradeGenderData[grade]).forEach(gender => { genders.add(gender); }); }); const genderArray = Array.from(genders); const datasets = genderArray.map((gender, index) => ({ label: gender, data: grades.map(grade => gradeGenderData[grade][gender] || 0), backgroundColor: this.getChartColors(index, genderArray.length), borderWidth: 1 })); const ctx = document.getElementById('genderGradeChart').getContext('2d'); if (this.charts.genderGrade) { this.charts.genderGrade.destroy(); } this.charts.genderGrade = new Chart(ctx, { type: 'bar', data: { labels: grades, datasets: datasets }, options: { responsive: true, maintainAspectRatio: true, scales: { x: { stacked: false }, y: { stacked: false, beginAtZero: true, ticks: { stepSize: 1 } } }, plugins: { legend: { position: 'bottom' } } } }); } createGenderAgeChart() { const ageGenderData = this.createCrossTabulation('age', 'sex'); const ages = Object.keys(ageGenderData).sort((a, b) => a - b); const genders = new Set(); ages.forEach(age => { Object.keys(ageGenderData[age]).forEach(gender => { genders.add(gender); }); }); const genderArray = Array.from(genders); const datasets = genderArray.map((gender, index) => ({ label: gender, data: ages.map(age => ageGenderData[age][gender] || 0), backgroundColor: this.getChartColors(index, genderArray.length), borderWidth: 1 })); const ctx = document.getElementById('genderAgeChart').getContext('2d'); if (this.charts.genderAge) { this.charts.genderAge.destroy(); } this.charts.genderAge = new Chart(ctx, { type: 'bar', data: { labels: ages, datasets: datasets }, options: { responsive: true, maintainAspectRatio: true, scales: { x: { stacked: false }, y: { stacked: false, beginAtZero: true, ticks: { stepSize: 1 } } }, plugins: { legend: { position: 'bottom' } } } }); } createStatistics() { const stats = { 'Total Students': this.students.length, 'Males': this.students.filter(s => s.sex && s.sex.toLowerCase().includes('ប្រុស')).length, 'Females': this.students.filter(s => s.sex && s.sex.toLowerCase().includes('ស្រី')).length, 'Average Age': (this.students.reduce((sum, s) => sum + (s.age || 0), 0) / this.students.length).toFixed(1), 'Youngest': Math.min(...this.students.map(s => s.age || 999)), 'Oldest': Math.max(...this.students.map(s => s.age || 0)), 'Grades Count': Object.keys(this.aggregateData('grade')).length, }; const statsDiv = document.getElementById('statistics'); statsDiv.innerHTML = Object.entries(stats).map(([key, value]) => `
${key}: ${value}
`).join(''); } aggregateData(field) { return this.students.reduce((acc, student) => { const value = student[field] || 'Unknown'; acc[value] = (acc[value] || 0) + 1; return acc; }, {}); } createCrossTabulation(field1, field2) { return this.students.reduce((acc, student) => { const val1 = student[field1] || 'Unknown'; const val2 = student[field2] || 'Unknown'; if (!acc[val1]) { acc[val1] = {}; } acc[val1][val2] = (acc[val1][val2] || 0) + 1; return acc; }, {}); } getRandomColors(count) { const colors = [ '#FF6B6B', '#4ECDC4', '#45B7D1', '#FFA07A', '#98D8C8', '#F7DC6F', '#BB8FCE', '#85C1E2', '#F8B88B', '#A8D8EA' ]; const result = []; for (let i = 0; i < count; i++) { result.push(colors[i % colors.length]); } return result; } getChartColors(index, total) { const colors = ['#FF6B6B', '#4ECDC4', '#45B7D1', '#FFA07A', '#98D8C8']; return colors[index % colors.length]; } saveToLocalStorage() { localStorage.setItem('studentData', JSON.stringify(this.students)); } loadFromLocalStorage() { const data = localStorage.getItem('studentData'); if (data) { this.students = JSON.parse(data); this.renderTable(); } } } // Initialize the application const studentManager = new StudentManager(); </script>
<script src="app.js"></script>
<script type="module" crossorigin="" src="/assets/index-B5p-6V1M.js"></script>

បានឃើញ និងឯកភាព

ថ្ងៃព្រហស្បតិ៍ ១១កើត ខែមាឃ ឆ្នាំម្សាញ់ សប្តស័ក ព.ស ២៥៦៩

រោគ ថ្ងៃទី២៩ ខែមករា ឆ្នាំ២០២៦

នាយិកា

ថ្ងៃព្រហស្បតិ៍ ១១កើត ខែមាឃ ឆ្នាំម្សាញ់ សប្តស័ក ព.ស ២៥៦៩

រោគ ថ្ងៃទី២៩ ខែមករា ឆ្នាំ២០២៦

អ្នកធ្វើតារាង





អ៊ុន ប៊ុនទុង

<title>id</title>

id

## Student ID Last Name First Name DOB Age Sex Grade Phone Address Status Extra Action
1 1860987 ក្តាម កន 17/09/2013 12 ប្រុស 6A 097... ភ្នំពេញ Active ក្រ១ Edit Delete
<script> function editRow(button) { const row = button.closest("tr"); const cells = row.querySelectorAll("td"); // Example: replace DOB with date input cells[4].innerHTML = ``; // Age as number cells[5].innerHTML = ``; // Sex dropdown cells[6].innerHTML = ` ប្រុស ស្រី `; // Grade dropdown cells[7].innerHTML = ` 1A 2B 3A 4B 5A 6B HL 1B 2A 3B 4A 5B 6A `; // Phone cells[8].innerHTML = ``; // Address editable cells[9].setAttribute("contenteditable","true"); // Status dropdown cells[10].innerHTML = ` Active Inactive `; // Extra dropdown (example: ក្រ១, ក្រ២, ផ្សេង) cells[11].innerHTML = ` ក្រ១ ក្រ២ ផ្សេងៗ `; // Replace action buttons cells[12].innerHTML = ` Save Cancel `; } function saveRow(button) { const row = button.closest("tr"); const inputs = row.querySelectorAll("input, select"); inputs.forEach(input => { const cell = input.closest("td"); cell.innerText = input.value; }); // Restore action buttons const actionCell = row.querySelectorAll("td")[12]; actionCell.innerHTML = ` Edit Delete `; } function cancelEdit(button) { // For simplicity, just reload page or re-render row from stored data alert("Cancel clicked — restore original values here."); } function deleteRow(button) { const row = button.closest("tr"); row.remove(); } </script>

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published