index.tsx 2.6 KB
Newer Older
P
Peter Pan 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
/**
 * Copyright 2020 Baidu Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

17
import React, {FunctionComponent, useEffect, useMemo} from 'react';
18
import {headerHeight, primaryColor, rem, size} from '~/utils/style';
P
Peter Pan 已提交
19
import {useHistory, useLocation} from 'react-router-dom';
20

P
Peter Pan 已提交
21
import Error from '~/components/Error';
P
Peter Pan 已提交
22 23
import HashLoader from 'react-spinners/HashLoader';
import styled from 'styled-components';
24
import useComponents from '~/hooks/useComponents';
25
import {useTranslation} from 'react-i18next';
P
Peter Pan 已提交
26

27 28 29 30 31 32 33 34 35 36 37 38
const flatten = <T extends {children?: T[]}>(routes: T[]) => {
    const result: Omit<T, 'children'>[] = [];
    routes.forEach(route => {
        if (route.children) {
            result.push(...flatten(route.children));
        } else {
            result.push(route);
        }
    });
    return result;
};

P
Peter Pan 已提交
39
const CenterWrapper = styled.div`
P
Peter Pan 已提交
40 41
    ${size(`calc(100vh - ${headerHeight})`, '100vw')}
    overscroll-behavior: none;
P
Peter Pan 已提交
42 43 44
`;

const Loading = styled.div`
45
    font-size: ${rem(16)};
P
Peter Pan 已提交
46
    height: 100%;
47
    line-height: ${rem(60)};
P
Peter Pan 已提交
48 49 50 51
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
P
Peter Pan 已提交
52
`;
53

54
const IndexPage: FunctionComponent = () => {
55
    const [components, loading] = useComponents();
56
    const history = useHistory();
P
Peter Pan 已提交
57

58 59
    const {t} = useTranslation('common');

P
Peter Pan 已提交
60 61
    const location = useLocation();

62 63
    const activeComponents = useMemo(() => flatten(components).filter(c => c.inactive !== true), [components]);

64
    useEffect(() => {
65 66
        if (activeComponents.length) {
            history.replace(activeComponents[0].path + location.search);
P
Peter Pan 已提交
67 68
        } else {
            // TODO: no component available, add a error tip
P
Peter Pan 已提交
69
        }
70
    }, [activeComponents, history, location.search]);
71

P
Peter Pan 已提交
72
    return (
P
Peter Pan 已提交
73
        <CenterWrapper>
74
            {loading ? (
P
Peter Pan 已提交
75 76 77 78 79 80 81 82
                <Loading>
                    <HashLoader size="60px" color={primaryColor} />
                    <span>{t('common:loading')}</span>
                </Loading>
            ) : (
                <Error />
            )}
        </CenterWrapper>
P
Peter Pan 已提交
83
    );
84 85
};

86
export default IndexPage;