feat: sincronización avanzada SIU por código ASIG, perfil con foto/nombre de Moodle y refinamiento visual violeta
This commit is contained in:
@@ -0,0 +1,184 @@
|
||||
import { Component, OnInit, OnDestroy } from '@angular/core';
|
||||
import { ToastController, LoadingController, AlertController, NavController } from '@ionic/angular';
|
||||
import { AuthService, AuthState } from '../services/auth.service';
|
||||
import { SiuService } from '../services/siu-guarani.service';
|
||||
import { CredencialService } from '../services/credencial.service';
|
||||
import { LocalStorageService, AppData } from '../services/local-storage.service';
|
||||
import { Subscription } from 'rxjs';
|
||||
|
||||
@Component({
|
||||
selector: 'app-perfil',
|
||||
templateUrl: './perfil.page.html',
|
||||
styleUrls: ['./perfil.page.scss'],
|
||||
standalone: false
|
||||
})
|
||||
export class PerfilPage implements OnInit, OnDestroy {
|
||||
authState: AuthState | null = null;
|
||||
private authSub: Subscription | null = null;
|
||||
|
||||
// Form states
|
||||
siuDni: string = '';
|
||||
siuPass: string = '';
|
||||
showSiuPass: boolean = false;
|
||||
|
||||
moodleDni: string = '';
|
||||
moodlePass: string = '';
|
||||
showMoodlePass: boolean = false;
|
||||
|
||||
loading: boolean = false;
|
||||
|
||||
constructor(
|
||||
private authService: AuthService,
|
||||
private siuService: SiuService,
|
||||
private credencialService: CredencialService,
|
||||
private localStorageService: LocalStorageService,
|
||||
private toastCtrl: ToastController,
|
||||
private loadingCtrl: LoadingController,
|
||||
private alertCtrl: AlertController,
|
||||
private navCtrl: NavController
|
||||
) { }
|
||||
|
||||
ngOnInit() {
|
||||
this.authSub = this.authService.authState$.subscribe(state => {
|
||||
this.authState = state;
|
||||
// Pre-fill DNI if already connected
|
||||
if (state.siuConnected && !this.siuDni) this.siuDni = state.siuDni || '';
|
||||
if (state.moodleConnected && !this.moodleDni) this.moodleDni = state.moodleDni || '';
|
||||
});
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
if (this.authSub) this.authSub.unsubscribe();
|
||||
}
|
||||
|
||||
async loginSiu() {
|
||||
if (!this.siuDni || !this.siuPass) {
|
||||
this.showToast('Por favor, ingresá DNI y Contraseña', 'warning');
|
||||
return;
|
||||
}
|
||||
|
||||
const loader = await this.loadingCtrl.create({ message: 'Validando con SIU Guaraní...' });
|
||||
await loader.present();
|
||||
|
||||
try {
|
||||
const materias = await this.siuService.getAcademicHistory(this.siuDni, this.siuPass);
|
||||
await this.authService.saveSiuCredentials(this.siuDni, this.siuPass);
|
||||
|
||||
// Persistir datos en LocalStorage para que Home los vea
|
||||
const currentData = await this.localStorageService.loadData() || this.getDefaultData();
|
||||
currentData.siuMaterias = materias;
|
||||
currentData.siuLastSync = new Date().toISOString();
|
||||
|
||||
// Aplicar auto-favoritos (opcional, pero recomendado para consistencia)
|
||||
// Nota: Aquí se podría llamar a una versión compartida de autoCompletarDesdeSiu
|
||||
// Por ahora guardamos para que Home lo procese al volver
|
||||
await this.localStorageService.saveData(currentData);
|
||||
|
||||
this.showToast('¡SIU Guaraní conectado y sincronizado!', 'success');
|
||||
this.siuPass = '';
|
||||
} catch (e: any) {
|
||||
console.error(e);
|
||||
this.authService.setSiuError(e.message || 'Error de conexión');
|
||||
this.showToast('Error al conectar con SIU: ' + (e.message || 'Credenciales inválidas'), 'danger');
|
||||
} finally {
|
||||
await loader.dismiss();
|
||||
}
|
||||
}
|
||||
|
||||
async logoutSiu() {
|
||||
const alert = await this.alertCtrl.create({
|
||||
header: 'Cerrar Sesión en SIU',
|
||||
message: '¿Estás seguro de que deseas desconectar tu cuenta de SIU Guaraní? Se borrarán tus credenciales guardadas.',
|
||||
buttons: [
|
||||
{ text: 'Cancelar', role: 'cancel' },
|
||||
{
|
||||
text: 'Cerrar Sesión',
|
||||
role: 'destructive',
|
||||
handler: () => {
|
||||
this.authService.logoutSiu();
|
||||
this.siuDni = '';
|
||||
this.siuPass = '';
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
await alert.present();
|
||||
}
|
||||
|
||||
async loginMoodle() {
|
||||
if (!this.moodleDni || !this.moodlePass) {
|
||||
this.showToast('Por favor, ingresá DNI y Contraseña (Campus)', 'warning');
|
||||
return;
|
||||
}
|
||||
|
||||
const loader = await this.loadingCtrl.create({ message: 'Validando con Campus UNICABA...' });
|
||||
await loader.present();
|
||||
|
||||
try {
|
||||
// 1. Validar y generar credencial (descarga PDF)
|
||||
await this.credencialService.generateCredential(this.moodleDni, this.moodlePass);
|
||||
|
||||
// 2. Obtener Perfil (Nombre y Foto)
|
||||
const profile = await this.credencialService.getUserProfile(this.moodleDni, this.moodlePass);
|
||||
await this.authService.saveUserProfile(profile.name, profile.photo);
|
||||
|
||||
// 3. Guardar credenciales de acceso
|
||||
await this.authService.saveMoodleCredentials(this.moodleDni, this.moodlePass);
|
||||
|
||||
this.showToast('¡Perfil sincronizado y Campus conectado!', 'success');
|
||||
this.moodlePass = '';
|
||||
} catch (e: any) {
|
||||
console.error(e);
|
||||
this.authService.setMoodleError(e.message || 'Error de conexión');
|
||||
this.showToast('Error al conectar con Campus: ' + (e.message || 'Credenciales inválidas'), 'danger');
|
||||
} finally {
|
||||
await loader.dismiss();
|
||||
}
|
||||
}
|
||||
|
||||
async logoutMoodle() {
|
||||
const alert = await this.alertCtrl.create({
|
||||
header: 'Cerrar Sesión en Campus',
|
||||
message: '¿Estás seguro de que deseas desconectar tu cuenta del Campus? Se borrará tu credencial digital cacheada.',
|
||||
buttons: [
|
||||
{ text: 'Cancelar', role: 'cancel' },
|
||||
{
|
||||
text: 'Cerrar Sesión',
|
||||
role: 'destructive',
|
||||
handler: () => {
|
||||
this.authService.logoutMoodle();
|
||||
this.moodleDni = '';
|
||||
this.moodlePass = '';
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
await alert.present();
|
||||
}
|
||||
|
||||
goBack() {
|
||||
this.navCtrl.back();
|
||||
}
|
||||
|
||||
private async showToast(message: string, color: 'success' | 'warning' | 'danger') {
|
||||
const toast = await this.toastCtrl.create({
|
||||
message,
|
||||
duration: 3000,
|
||||
color,
|
||||
position: 'bottom'
|
||||
});
|
||||
await toast.present();
|
||||
}
|
||||
|
||||
private getDefaultData(): AppData {
|
||||
return {
|
||||
favoritos: [],
|
||||
eventos: [],
|
||||
aprobadas: [],
|
||||
encurso: [],
|
||||
optativas: [],
|
||||
siuMaterias: [],
|
||||
siuLastSync: null
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user