Files
marketplaces/src/app/components/telegram-login/telegram-login.component.ts
sdarbinyan 325dc17911 feat(admin): sprint 19 admin dashboard, routing, i18n
- Add admin dashboard feature (models/gateway/facade/components/page)
- Wire admin/products routes and backoffice coming-soon placeholders
- Add lastPublishedAt to ProjectEditorFacade/state
- Add dashboard i18n keys (en/ru/hy) and docs/ADMIN.md

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-14 12:21:33 +04:00

95 lines
3.7 KiB
TypeScript

import { Component, ChangeDetectionStrategy, Input, Injector, Signal, inject, effect, OnDestroy, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { AuthService } from '../../services/auth.service';
import { AdminAuthService } from '../../core/admin-auth/admin-auth.service';
import { LanguageService } from '../../services/language.service';
import { TranslatePipe } from '../../i18n/translate.pipe';
import { QrLoginEngine } from '../../shared/qr-login/qr-login.engine';
import { QrLoginAdapter, QrLoginStatus } from '../../shared/qr-login/qr-login.model';
import { AuthSession } from '../../models/auth.model';
/**
* The one QR-login dialog, reused as-is for both customer and admin login.
* `mode` only decides which session service/storage backs it (AuthService's
* customer session vs AdminAuthService's admin session) - the QR creation,
* polling, expiry, and "return from Telegram app" logic (QrLoginEngine) and
* the API call underneath it (TelegramSessionApiService) are identical for
* both, by design: there is one Telegram QR/session backend, not two.
*/
@Component({
selector: 'app-telegram-login',
imports: [TranslatePipe],
templateUrl: './telegram-login.component.html',
styleUrls: ['./telegram-login.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class TelegramLoginComponent implements OnInit, OnDestroy {
@Input() mode: 'customer' | 'admin' = 'customer';
private readonly customerAuth = inject(AuthService);
private readonly adminAuth = inject(AdminAuthService);
private readonly injector = inject(Injector);
private readonly router = inject(Router);
private readonly languageService = inject(LanguageService);
private engine!: QrLoginEngine<AuthSession>;
showDialog = this.customerAuth.showLoginDialog;
status = this.customerAuth.status;
loginUrl!: Signal<string>;
webSessionID!: Signal<string>;
qrStatus!: Signal<QrLoginStatus>;
encodedQrUrl!: Signal<string>;
ngOnInit(): void {
const service = this.mode === 'admin' ? this.adminAuth : this.customerAuth;
this.showDialog = service.showLoginDialog;
this.status = service.status;
const adapter: QrLoginAdapter<AuthSession> = this.mode === 'admin'
? {
createSession: () => this.adminAuth.createWebSession(),
checkSessionOnce: id => this.adminAuth.checkSessionOnce(id),
isSessionActive: session => !!session?.active,
getAppLoginUrl: id => this.adminAuth.getAdminAppLoginUrl(id),
onLoginComplete: () => {
this.adminAuth.onLoginComplete();
void this.router.navigate([this.languageService.currentLanguage(), 'backoffice', 'dashboard']);
},
}
: {
createSession: () => this.customerAuth.createWebSession(),
checkSessionOnce: id => this.customerAuth.checkSessionOnce(id),
isSessionActive: session => !!session?.active,
getAppLoginUrl: id => this.customerAuth.getTelegramAppLoginUrl(id),
onLoginComplete: () => this.customerAuth.onTelegramLoginComplete(),
};
this.engine = new QrLoginEngine<AuthSession>(adapter);
this.loginUrl = this.engine.loginUrl;
this.webSessionID = this.engine.webSessionID;
this.qrStatus = this.engine.qrStatus;
this.encodedQrUrl = this.engine.encodedQrUrl;
effect(() => this.engine.setActive(this.showDialog()), { injector: this.injector });
}
ngOnDestroy(): void {
this.engine?.destroy();
}
close(): void {
this.engine.setActive(false);
(this.mode === 'admin' ? this.adminAuth : this.customerAuth).hideLogin();
}
openTelegramLogin(): void {
this.engine.openAppLogin();
}
refreshQr(): void {
this.engine.refresh();
}
}