import { Component } from 'react'; import Box from '@mui/material/Box'; import CircularProgress from '@mui/material/CircularProgress'; import { StorageManagerContext } from '../../api/storageManagerContext'; import BackendError from '../../components/BackendError'; import { ArticleView } from '../../components/article'; import { artikelAutomat, createArticleSelector, getArticle, setLastArticleSku, } from '../../automats'; import withSkuRoute from '../../components/article/withSkuRoute'; /** Full-screen loading state while the shared article cache resolves. */ function ArticleLoading() { return ( ); } class ArtikelSkuPage extends Component { static contextType = StorageManagerContext; constructor(props, context) { super(props, context); this.state = { article: getArticle(props.sku), ready: context.getCategoryState() != null, error: null, }; } componentDidMount() { this._mounted = true; this.installEscape(); setLastArticleSku(this.props.sku); this.unsub = artikelAutomat.subscribe(this, (state) => ({ article: createArticleSelector(this.props.sku)(state), })); void this.ensureArticle(); } componentDidUpdate(prevProps) { if (prevProps.sku !== this.props.sku) { setLastArticleSku(this.props.sku); this.setState({ article: getArticle(this.props.sku), error: null }); this.unsub?.(); this.unsub = artikelAutomat.subscribe(this, (state) => ({ article: createArticleSelector(this.props.sku)(state), })); void this.ensureArticle(); } } componentWillUnmount() { this._mounted = false; this.removeEscape(); this.unsub?.(); this.unsub = null; } /** * Delegates the article fetch to the shared artikelAutomat cache; also waits * for the category tree/company/session the view tiles depend on. */ async ensureArticle() { const sku = this.props.sku; if (!sku) return; try { await Promise.all([ artikelAutomat.actions.loadArticle(sku), this.context.categoryTreePromise, this.context.companyPromise, this.context.authMePromise, ]); if (this._mounted) this.setState({ ready: true }); } catch (error) { if (this._mounted) this.setState({ error }); } } handleRetry = () => { this.setState({ error: null }); void this.ensureArticle(); }; installEscape() { this._onKeyDown = (e) => { if (e.key !== 'Escape') return; e.preventDefault(); this.props.navigate(-1); }; document.addEventListener('keydown', this._onKeyDown); } removeEscape() { if (this._onKeyDown) { document.removeEventListener('keydown', this._onKeyDown); this._onKeyDown = null; } } render() { const { sku } = this.props; const { article, ready, error } = this.state; if (error) { return ; } if (!article || !ready) return ; return ; } } export default withSkuRoute(ArtikelSkuPage);