bed230f045
Project picker, section cards and the period Excel export now live on the app's home page. The selected project is shared app state, so the sidebar hides sections with the same rules main used to disable its cards (archived, finished, no edit0 right). Queries are 1:1 with stroy-bot-main and covered by tests against a fake HTTP client. Behaviour differences are listed in the migration checklist. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
48 lines
1.5 KiB
TypeScript
48 lines
1.5 KiB
TypeScript
import * as React from 'react';
|
|
import { Icon } from '@tnsu/ui-kit';
|
|
import { RouteLink } from '../../app/routing/RouteLink';
|
|
import { IHubCard } from './hubCards';
|
|
import styles from './HubPage.module.scss';
|
|
|
|
interface Props {
|
|
card: IHubCard;
|
|
projectId: string | undefined;
|
|
}
|
|
|
|
/** Карточка раздела. Внутренние разделы — переход в приложении, архив — внешняя ссылка в новой вкладке. */
|
|
export const HubCard: React.FC<Props> = ({ card, projectId }) => {
|
|
const className = card.isEnabled ? styles.card : `${styles.card} ${styles.cardDisabled}`;
|
|
const content = (
|
|
<>
|
|
<span className={styles.cardIcon} aria-hidden="true">
|
|
<Icon name={card.icon} />
|
|
</span>
|
|
<span className={styles.cardBody}>
|
|
<span className={styles.cardTitle}>{card.title}</span>
|
|
<span className={styles.cardSubtitle}>{card.subtitle}</span>
|
|
</span>
|
|
<span className={styles.cardArrow} aria-hidden="true">
|
|
<Icon name="chevron-right" size="sm" />
|
|
</span>
|
|
</>
|
|
);
|
|
|
|
if (card.target.kind === 'external') {
|
|
return card.isEnabled ? (
|
|
<a className={className} href={card.target.url} target="_blank" rel="noopener noreferrer">
|
|
{content}
|
|
</a>
|
|
) : (
|
|
<a className={className} aria-disabled="true">
|
|
{content}
|
|
</a>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<RouteLink className={className} to={{ page: card.target.page, projectId }} disabled={!card.isEnabled}>
|
|
{content}
|
|
</RouteLink>
|
|
);
|
|
};
|