import * as React from 'react'; import styles from './ApprovalAdmin.module.scss'; import type { IApprovalAdminProps } from './IApprovalAdminProps'; import { AdminApp } from './app/AdminApp'; import { ApprovalRouteApi } from '../services/api'; import { AadApiHttpClient, DevApiHttpClient, IHttpClient } from '../services/httpClient'; import { PortalDictionaryClient } from '../services/portalDictionary'; import { texts } from '../texts'; const FONTS_LINK_ID = 'tnsu-approval-admin-fonts'; function ensureFontsLoaded(): void { if (typeof document === 'undefined' || document.getElementById(FONTS_LINK_ID)) return; const link = document.createElement('link'); link.id = FONTS_LINK_ID; link.rel = 'stylesheet'; link.href = 'https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Lora:wght@500;600;700&display=swap'; document.head.appendChild(link); } async function createHttpClient(props: IApprovalAdminProps): Promise { if (props.useDevAuth) { return new DevApiHttpClient(props.apiBaseUrl, props.devUserEmail || 'dev@tnsu.kz'); } const aadClient = await props.context.aadHttpClientFactory.getClient(props.aadResourceId); return new AadApiHttpClient(aadClient, props.apiBaseUrl); } const ApprovalAdmin: React.FC = props => { const [api, setApi] = React.useState(); const [dictionary, setDictionary] = React.useState(); const [error, setError] = React.useState(); React.useEffect(() => { ensureFontsLoaded(); }, []); React.useEffect(() => { let cancelled = false; setApi(undefined); setError(undefined); createHttpClient(props) .then(client => { if (!cancelled) setApi(new ApprovalRouteApi(client)); }) .catch((e: Error) => { if (!cancelled) setError(e.message); }); return () => { cancelled = true; }; // eslint-disable-next-line react-hooks/exhaustive-deps }, [props.useDevAuth, props.apiBaseUrl, props.devUserEmail, props.aadResourceId]); // Справочники всегда идут через AAD, независимо от Dev-режима нашего API: // api.tnsu.kz принимает только настоящий токен, заголовок X-Dev-User-Email // ему ничего не говорит. React.useEffect(() => { let cancelled = false; setDictionary(undefined); props.context.aadHttpClientFactory .getClient(props.aadResourceId) .then(client => { if (!cancelled) setDictionary(new PortalDictionaryClient(client, props.portalBaseUrl)); }) .catch(() => { /* экран маршрутов покажет ошибку загрузки справочника */ }); return () => { cancelled = true; }; // eslint-disable-next-line react-hooks/exhaustive-deps }, [props.aadResourceId, props.portalBaseUrl]); return (
{error && (
{texts.app.connectFailed(error)}
{texts.app.connectHint}
)} {!error && !api &&
{texts.app.connecting}
} {api && ( )}
); }; export default ApprovalAdmin;