Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import { Component, OnInit, OnDestroy } from '@angular/core';
- import { SchoolService } from '../../school/services/school.service';
- import { TeacherService } from '../../school/services/teacher.service';
- import { LoadingController, ToastController } from '@ionic/angular';
- import { ClassroomService } from '../../school/services/classroom.service';
- import { StudentService } from '../../school/services/student.service';
- import { AttendanceService } from '../../attendance/services/attendance.service';
- import { Router } from '@angular/router';
- @Component({
- selector: 'app-syncdata',
- templateUrl: './syncdata.component.html',
- styleUrls: ['./syncdata.component.scss'],
- })
- export class SyncDataComponent implements OnInit, OnDestroy {
- private readonly DB_NAME = 'attendance';
- private readonly DB_VERSION = 1;
- private db: IDBDatabase | undefined;
- constructor(
- private schoolService: SchoolService,
- private teacherService: TeacherService,
- private classroomService: ClassroomService,
- private studentService: StudentService,
- private attendanceService: AttendanceService,
- private loadingController: LoadingController,
- private toastController: ToastController,
- private router: Router
- ) { }
- ngOnInit() { }
- ngOnDestroy() {
- if (this.db) {
- this.db.close();
- this.db = undefined;
- }
- }
- private async closeAllConnections(): Promise<void> {
- return new Promise<void>((resolve) => {
- if (this.db) {
- try {
- // Remove all event listeners
- this.db.onerror = null;
- this.db.onclose = null;
- this.db.onversionchange = null;
- // Close the connection
- this.db.close();
- // Add a delay before setting db to undefined
- setTimeout(() => {
- this.db = undefined;
- resolve();
- }, 500);
- } catch (error) {
- console.warn('Error while closing database:', error);
- this.db = undefined;
- resolve();
- }
- } else {
- resolve();
- }
- });
- }
- private async clearAllStores(): Promise<void> {
- return new Promise(async (resolve, reject) => {
- try {
- if (!this.db) {
- throw new Error('Database not initialized');
- }
- const stores = [
- 'school',
- 'teacher',
- 'classroom',
- 'student',
- 'attendance',
- 'attendanceHistory'
- ];
- const transaction = this.db.transaction(stores, 'readwrite');
- stores.forEach(storeName => {
- const store = transaction.objectStore(storeName);
- const clearRequest = store.clear();
- clearRequest.onerror = () => {
- console.error(`Error clearing ${storeName} store:`, clearRequest.error);
- reject(clearRequest.error);
- };
- });
- transaction.oncomplete = () => {
- console.log('All stores cleared successfully');
- resolve();
- };
- transaction.onerror = () => {
- console.error('Error clearing stores:', transaction.error);
- reject(transaction.error);
- };
- } catch (error) {
- console.error('Error in clearAllStores:', error);
- reject(error);
- }
- });
- }
- private initDatabase(): Promise<void> {
- return new Promise((resolve, reject) => {
- try {
- if (this.db) {
- this.db.close();
- this.db = undefined;
- }
- const request = indexedDB.open(this.DB_NAME, this.DB_VERSION);
- request.onerror = () => {
- console.error('Error opening database:', request.error);
- reject(request.error);
- };
- request.onupgradeneeded = (event) => {
- const db = (event.target as IDBOpenDBRequest).result;
- if (!db.objectStoreNames.contains('school')) {
- db.createObjectStore('school', { keyPath: 'id' });
- }
- if (!db.objectStoreNames.contains('teacher')) {
- db.createObjectStore('teacher', { keyPath: 'id' });
- }
- if (!db.objectStoreNames.contains('classroom')) {
- db.createObjectStore('classroom', { keyPath: 'id' });
- }
- if (!db.objectStoreNames.contains('student')) {
- const studentStore = db.createObjectStore('student', { keyPath: 'id' });
- studentStore.createIndex('classroomId', 'classroomId', { unique: false });
- }
- if (!db.objectStoreNames.contains('attendance')) {
- db.createObjectStore('attendance', { keyPath: 'id' });
- }
- if (!db.objectStoreNames.contains('attendanceHistory')) {
- db.createObjectStore('attendanceHistory', { keyPath: 'id' });
- }
- };
- request.onsuccess = () => {
- this.db = request.result;
- this.db.onerror = (event) => {
- console.error('Database error:', event);
- };
- this.db.onclose = () => {
- console.log('Database connection closed');
- };
- console.log('Database opened successfully');
- resolve();
- };
- } catch (error) {
- console.error('Error in initDatabase:', error);
- reject(error);
- }
- });
- }
- async onDownload() {
- const loading = await this.loadingController.create({
- message: 'Téléchargement en cours...',
- spinner: 'circles'
- });
- try {
- await loading.present();
- // Close any existing connections first
- await this.closeAllConnections();
- // Validate user data
- const userData = JSON.parse(localStorage.getItem('user') || '{}');
- if (!userData.id) {
- throw new Error('User ID not found');
- }
- // Initialize the database if not already initialized
- if (!this.db) {
- try {
- await this.initDatabase();
- console.log('Database initialized');
- } catch (error) {
- console.error('Failed to initialize database:', error);
- throw new Error('Database initialization failed');
- }
- }
- // Clear all stores
- try {
- await this.clearAllStores();
- console.log('All stores cleared');
- } catch (error) {
- console.warn('Store clearing failed, proceeding anyway:', error);
- }
- // Fetch and store teacher data
- try {
- const teacherData = await this.teacherService.getTeacherById(userData.id).toPromise();
- if (!teacherData) {
- throw new Error('No teacher data received');
- }
- await this.storeTeacherData(teacherData);
- console.log('Teacher data stored');
- // Validate school ID
- const schoolId = teacherData.school?.id;
- if (!schoolId) {
- throw new Error('School ID not found in teacher data');
- }
- // Fetch and store school data
- const schoolData = await this.schoolService.getSchoolById(schoolId).toPromise();
- if (!schoolData) {
- throw new Error('No school data received');
- }
- await this.storeSchoolData(schoolData);
- console.log('School data stored');
- // Fetch and store classroom data
- const classroomData = await this.classroomService.getClassroomsBySchoolId(schoolId).toPromise();
- if (!classroomData || !Array.isArray(classroomData)) {
- throw new Error('Invalid classroom data received');
- }
- await this.storeClassroomData(classroomData);
- console.log('Classroom data stored');
- // Fetch and store student data
- try {
- await this.fetchAndStoreStudents(schoolId);
- console.log('Students data stored');
- } catch (error) {
- console.error('Error storing students:', error);
- throw new Error('Failed to store student data');
- }
- // Fetch and store attendance data
- const attendanceData = await this.attendanceService.getAttendanceBySchoolById(schoolId).toPromise();
- if (!attendanceData || !Array.isArray(attendanceData)) {
- throw new Error('Invalid attendance data received');
- }
- await this.storeAttendanceData(attendanceData);
- console.log('Attendance data stored');
- // Fetch and store attendance history data
- const attendanceHistoryData = await this.attendanceService.getAttendanceHistoryBySchoolById(schoolId).toPromise();
- if (!attendanceHistoryData || !Array.isArray(attendanceHistoryData)) {
- throw new Error('Invalid attendance history data received');
- }
- await this.storeAttendanceHistoryData(attendanceHistoryData);
- console.log('Attendance history data stored');
- // Success - show toast and navigate
- await loading.dismiss();
- await this.showToast('Données synchronisées avec succès', 'success');
- this.router.navigate(['/tabs/home']);
- } catch (error) {
- console.error('Error during data synchronization:', error);
- throw new Error('Data synchronization failed');
- }
- } catch (error: unknown) {
- console.error('Sync error:', error);
- await loading.dismiss();
- if (error instanceof Error) {
- await this.showToast(error.message, 'danger');
- } else {
- await this.showToast('Erreur lors de la synchronisation', 'danger');
- }
- } finally {
- try {
- if (loading) {
- await loading.dismiss();
- }
- } catch (cleanupError) {
- console.error('Error in cleanup:', cleanupError);
- }
- }
- }
- private async showToast(message: string, color: string = 'primary') {
- try {
- const toast = await this.toastController.create({
- message,
- duration: 3000,
- color,
- position: 'bottom',
- buttons: [{
- text: 'OK',
- role: 'cancel'
- }]
- });
- await toast.present();
- } catch (error) {
- console.error('Error showing toast:', error);
- }
- }
- private safeParseResponse(response: any, expectedType: string): any {
- if (!response) {
- throw new Error(`No ${expectedType} data received`);
- }
- if (expectedType === 'array' && !Array.isArray(response)) {
- throw new Error(`Invalid ${expectedType} data format`);
- }
- return response;
- }
- private handleApiError(error: any, operation: string): never {
- console.error(`Error during ${operation}:`, error);
- throw new Error(`Failed to ${operation}`);
- }
- private storeSchoolData(data: any): Promise<void> {
- return new Promise((resolve, reject) => {
- try {
- if (!this.db) {
- throw new Error('Database not initialized');
- }
- const transaction = this.db.transaction('school', 'readwrite');
- const store = transaction.objectStore('school');
- const request = store.put({
- ...data,
- sync_status: true,
- last_sync: new Date().toISOString()
- });
- transaction.oncomplete = () => resolve();
- transaction.onerror = () => {
- console.error('Error storing school data:', transaction.error);
- reject(transaction.error);
- };
- } catch (error) {
- console.error('Error in storeSchoolData:', error);
- reject(error);
- }
- });
- }
- private storeTeacherData(data: any): Promise<void> {
- return new Promise((resolve, reject) => {
- try {
- if (!this.db) {
- throw new Error('Database not initialized');
- }
- const transaction = this.db.transaction('teacher', 'readwrite');
- const store = transaction.objectStore('teacher');
- const request = store.put({
- ...data,
- sync_status: true,
- last_sync: new Date().toISOString()
- });
- transaction.oncomplete = () => resolve();
- transaction.onerror = () => {
- console.error('Error storing teacher data:', transaction.error);
- reject(transaction.error);
- };
- } catch (error) {
- console.error('Error in storeTeacherData:', error);
- reject(error);
- }
- });
- }
- private storeClassroomData(classrooms: any[]): Promise<void> {
- return new Promise((resolve, reject) => {
- try {
- if (!this.db) {
- throw new Error('Database not initialized');
- }
- const transaction = this.db.transaction('classroom', 'readwrite');
- const store = transaction.objectStore('classroom');
- classrooms.forEach(classroom => {
- store.put({
- ...classroom,
- sync_status: true,
- last_sync: new Date().toISOString()
- });
- });
- transaction.oncomplete = () => resolve();
- transaction.onerror = () => {
- console.error('Error storing classroom data:', transaction.error);
- reject(transaction.error);
- };
- } catch (error) {
- console.error('Error in storeClassroomData:', error);
- reject(error);
- }
- });
- }
- private async fetchAndStoreStudents(schoolId: number): Promise<void> {
- try {
- const students = await this.studentService.getStudentsBySchoolId(schoolId).toPromise();
- await this.storeStudentData(students);
- console.log(`Students stored for school ${schoolId}`);
- } catch (error) {
- console.error(`Error processing students for school ${schoolId}:`, error);
- throw error;
- }
- }
- private storeStudentData(students: any[]): Promise<void> {
- return new Promise((resolve, reject) => {
- try {
- if (!this.db) {
- throw new Error('Database not initialized');
- }
- const transaction = this.db.transaction('student', 'readwrite');
- const store = transaction.objectStore('student');
- students.forEach(student => {
- store.put({
- ...student,
- sync_status: true,
- last_sync: new Date().toISOString()
- });
- });
- transaction.oncomplete = () => resolve();
- transaction.onerror = () => {
- console.error('Error storing student data:', transaction.error);
- reject(transaction.error);
- };
- } catch (error) {
- console.error('Error in storeStudentData:', error);
- reject(error);
- }
- });
- }
- private storeAttendanceData(attendances: any[]): Promise<void> {
- return new Promise((resolve, reject) => {
- try {
- if (!this.db) {
- throw new Error('Database not initialized');
- }
- const transaction = this.db.transaction('attendance', 'readwrite');
- const store = transaction.objectStore('attendance');
- attendances.forEach(attendance => {
- store.put({
- ...attendance,
- sync_status: true,
- last_sync: new Date().toISOString()
- });
- });
- transaction.oncomplete = () => resolve();
- transaction.onerror = () => {
- console.error('Error storing attendance data:', transaction.error);
- reject(transaction.error);
- };
- } catch (error) {
- console.error('Error in storeAttendanceData:', error);
- reject(error);
- }
- });
- }
- private storeAttendanceHistoryData(attendanceHistories: any[]): Promise<void> {
- return new Promise((resolve, reject) => {
- try {
- if (!this.db) {
- throw new Error('Database not initialized');
- }
- const transaction = this.db.transaction('attendanceHistory', 'readwrite');
- const store = transaction.objectStore('attendanceHistory');
- attendanceHistories.forEach(history => {
- store.put({
- ...history,
- sync_status: true,
- last_sync: new Date().toISOString()
- });
- });
- transaction.oncomplete = () => resolve();
- transaction.onerror = () => {
- console.error('Error storing attendance history data:', transaction.error);
- reject(transaction.error);
- };
- } catch (error) {
- console.error('Error in storeAttendanceHistoryData:', error);
- reject(error);
- }
- });
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement