mirror of
https://github.com/magnum-opus-nn-cp/frontend.git
synced 2024-11-21 17:16:36 +03:00
feat(response): add response page layout
This commit is contained in:
parent
dbfd8e8b4f
commit
b2285e263b
|
@ -1,15 +1,14 @@
|
|||
import React from 'react';
|
||||
import { Helmet } from 'react-helmet';
|
||||
import {AppRoutes} from './routes';
|
||||
import { AppRoutes } from './routes';
|
||||
|
||||
export function App() {
|
||||
return (
|
||||
<>
|
||||
<Helmet title={"Pitch Deck"}>
|
||||
<Helmet title={'Press-release analyzer'}>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" />
|
||||
</Helmet>
|
||||
<AppRoutes />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,8 @@ import { ChatPage } from '../../pages/chat';
|
|||
import { HomePage } from '../../pages/home';
|
||||
import { DefaultLayout } from '../../pages/_layouts/DefaultLayout';
|
||||
import { TextPage } from '../../pages/text';
|
||||
import { CHAT_PAGE_ROUTE, HOME_PAGE_ROUTE, TEXT_PAGE_ROUTE } from './routes';
|
||||
import { ResponsePage } from '../../pages/response';
|
||||
import { CHAT_PAGE_ROUTE, HOME_PAGE_ROUTE, RESPONSE_PAGE_ROUTE, TEXT_PAGE_ROUTE } from './routes';
|
||||
|
||||
export const AppRoutes = () => {
|
||||
return (
|
||||
|
@ -11,6 +12,7 @@ export const AppRoutes = () => {
|
|||
<Route element={<DefaultLayout />}>
|
||||
<Route path={CHAT_PAGE_ROUTE} element={<ChatPage />} />
|
||||
<Route path={HOME_PAGE_ROUTE} element={<HomePage />} />
|
||||
<Route path={RESPONSE_PAGE_ROUTE} element={<ResponsePage />} />
|
||||
<Route path={TEXT_PAGE_ROUTE} element={<TextPage />} />
|
||||
</Route>
|
||||
</Routes>
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
export const CHAT_PAGE_ROUTE = `/chat`;
|
||||
export const HOME_PAGE_ROUTE = `/`;
|
||||
|
||||
export const RESPONSE_PAGE_PARAM = 'processId';
|
||||
export const RESPONSE_PAGE_ROUTE = `/response/:${RESPONSE_PAGE_PARAM}`;
|
||||
|
||||
export const TEXT_PAGE_PARAM = 'textId';
|
||||
export const TEXT_PAGE_ROUTE = `/text/:${TEXT_PAGE_PARAM}`;
|
||||
|
|
|
@ -103,7 +103,7 @@ $line-height-67: 67px;
|
|||
|
||||
@mixin text-body-s-regular {
|
||||
font-family: $font-family-inter, $font-family-default;
|
||||
font-size: $font-size-12;
|
||||
font-size: $font-size-14;
|
||||
font-weight: $font-weight-400;
|
||||
line-height: $line-height-18;
|
||||
}
|
||||
|
|
|
@ -34,3 +34,7 @@ a {
|
|||
text-decoration: none;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.scroll-prevented {
|
||||
overflow: hidden;
|
||||
}
|
67
src/components/Modal/Modal.module.scss
Normal file
67
src/components/Modal/Modal.module.scss
Normal file
|
@ -0,0 +1,67 @@
|
|||
@import 'src/app/styles/vars';
|
||||
|
||||
.Modal {
|
||||
position: fixed;
|
||||
z-index: $z-index-modal;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: $color-text-primary;
|
||||
}
|
||||
|
||||
.Modal__overlay {
|
||||
@include transition(opacity);
|
||||
|
||||
position: fixed;
|
||||
z-index: $z-index-overlay;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: #000;
|
||||
}
|
||||
|
||||
.Modal__content {
|
||||
@include transition(opacity);
|
||||
|
||||
z-index: $z-index-modal;
|
||||
border-radius: $radius-large;
|
||||
background: var(--bg-color);
|
||||
opacity: 0;
|
||||
|
||||
@include media-down(tablet-small) {
|
||||
width: 100%;
|
||||
margin-top: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.Modal_entering,
|
||||
.Modal_entered {
|
||||
.Modal__overlay {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.Modal__content {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.Modal_exiting,
|
||||
.Modal_exited {
|
||||
pointer-events: none;
|
||||
|
||||
.Modal__overlay {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.Modal__content {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
35
src/components/Modal/Modal.tsx
Normal file
35
src/components/Modal/Modal.tsx
Normal file
|
@ -0,0 +1,35 @@
|
|||
import { ReactNode, useRef } from 'react';
|
||||
import { Transition } from 'react-transition-group';
|
||||
import clsx from 'clsx';
|
||||
import { Portal } from '../Portal';
|
||||
import { usePreventWindowScroll } from '../../hooks/usePreventWindowScroll';
|
||||
import s from './Modal.module.scss';
|
||||
|
||||
export interface ModalProps {
|
||||
className?: string;
|
||||
children?: ReactNode;
|
||||
isOpen?: boolean;
|
||||
onClose?: () => void;
|
||||
isClosing?: boolean;
|
||||
preventWindowScroll?: false;
|
||||
}
|
||||
|
||||
export const Modal = (props: ModalProps) => {
|
||||
const { className, children, isOpen, onClose, isClosing, preventWindowScroll } = props;
|
||||
|
||||
const nodeRef = useRef(null);
|
||||
usePreventWindowScroll(preventWindowScroll ?? isOpen);
|
||||
|
||||
return (
|
||||
<Portal>
|
||||
<Transition unmountOnExit nodeRef={nodeRef} timeout={200} in={isOpen && !isClosing}>
|
||||
{(state) => (
|
||||
<div ref={nodeRef} className={clsx(s.Modal, s[`Modal_${state}`], className)}>
|
||||
<div onClick={onClose} className={s.Modal__overlay} />
|
||||
<div className={s.Modal__content}>{isOpen && children}</div>
|
||||
</div>
|
||||
)}
|
||||
</Transition>
|
||||
</Portal>
|
||||
);
|
||||
};
|
11
src/components/Modal/ModalBody/ModalBody.module.scss
Normal file
11
src/components/Modal/ModalBody/ModalBody.module.scss
Normal file
|
@ -0,0 +1,11 @@
|
|||
@import 'src/app/styles/vars';
|
||||
|
||||
.ModalBody {
|
||||
@include scrollbar;
|
||||
|
||||
overflow-y: auto;
|
||||
|
||||
@include media-down(tablet-small) {
|
||||
border-radius: 0 0 $radius-small $radius-small;
|
||||
}
|
||||
}
|
15
src/components/Modal/ModalBody/ModalBody.tsx
Normal file
15
src/components/Modal/ModalBody/ModalBody.tsx
Normal file
|
@ -0,0 +1,15 @@
|
|||
import { memo } from 'react';
|
||||
import clsx from 'clsx';
|
||||
import { ReactFCC } from '../../../utils/ReactFCC';
|
||||
import s from './ModalBody.module.scss';
|
||||
|
||||
export interface ModalBodyProps {
|
||||
className?: string;
|
||||
}
|
||||
|
||||
export const ModalBody: ReactFCC<ModalBodyProps> = memo((props) => {
|
||||
const { children, className } = props;
|
||||
|
||||
return <div className={clsx(s.ModalBody, className)}>{children}</div>;
|
||||
});
|
||||
ModalBody.displayName = 'ModalBody';
|
1
src/components/Modal/ModalBody/index.ts
Normal file
1
src/components/Modal/ModalBody/index.ts
Normal file
|
@ -0,0 +1 @@
|
|||
export * from './ModalBody';
|
|
@ -0,0 +1,32 @@
|
|||
@import 'src/app/styles/vars';
|
||||
|
||||
.ModalContainer {
|
||||
@include media-down(tablet-small) {
|
||||
padding: $spacing-small $spacing-small-x;
|
||||
}
|
||||
}
|
||||
|
||||
.ModalContainer__wrapper {
|
||||
display: flex;
|
||||
width: 600px;
|
||||
max-height: calc(100vh - $spacing-medium-x * 2);
|
||||
background: $color-background-primary;
|
||||
padding: $spacing-small;
|
||||
|
||||
&_borderRadius {
|
||||
border-radius: $radius-medium;
|
||||
}
|
||||
|
||||
@include media-down(tablet-small) {
|
||||
width: 100%;
|
||||
max-height: calc(100vh - $spacing-small * 2);
|
||||
margin-top: auto;
|
||||
background: $color-background-primary;
|
||||
}
|
||||
}
|
||||
|
||||
.ModalContainer__content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
}
|
36
src/components/Modal/ModalContainer/ModalContainer.tsx
Normal file
36
src/components/Modal/ModalContainer/ModalContainer.tsx
Normal file
|
@ -0,0 +1,36 @@
|
|||
import { ReactNode } from 'react';
|
||||
import clsx from 'clsx';
|
||||
import { Modal } from '../Modal';
|
||||
import s from './ModalContainer.module.scss';
|
||||
|
||||
export interface ModalContainerProps {
|
||||
className?: string;
|
||||
children?: ReactNode;
|
||||
onClose?: () => void;
|
||||
isOpen: boolean;
|
||||
isClosing?: boolean;
|
||||
withBorderRadius?: boolean;
|
||||
preventWindowScroll?: false;
|
||||
}
|
||||
|
||||
export const ModalContainer = (props: ModalContainerProps) => {
|
||||
const { isClosing, className, children, isOpen, onClose, withBorderRadius = true, preventWindowScroll } = props;
|
||||
|
||||
return (
|
||||
<Modal
|
||||
className={clsx(s.ModalContainer, {})}
|
||||
onClose={onClose}
|
||||
isClosing={isClosing}
|
||||
isOpen={isOpen}
|
||||
preventWindowScroll={preventWindowScroll}>
|
||||
<div
|
||||
className={clsx(
|
||||
s.ModalContainer__wrapper,
|
||||
{ [s.ModalContainer__wrapper_borderRadius]: withBorderRadius },
|
||||
className
|
||||
)}>
|
||||
<div className={s.ModalContainer__content}>{children}</div>
|
||||
</div>
|
||||
</Modal>
|
||||
);
|
||||
};
|
1
src/components/Modal/ModalContainer/index.ts
Normal file
1
src/components/Modal/ModalContainer/index.ts
Normal file
|
@ -0,0 +1 @@
|
|||
export * from './ModalContainer';
|
5
src/components/Modal/index.ts
Normal file
5
src/components/Modal/index.ts
Normal file
|
@ -0,0 +1,5 @@
|
|||
export * from './Modal';
|
||||
export * from './ModalContainer';
|
||||
export * from './ModalBody';
|
||||
export * from './useModal';
|
||||
// export * from './ModalAlert';
|
72
src/components/Modal/useModal.ts
Normal file
72
src/components/Modal/useModal.ts
Normal file
|
@ -0,0 +1,72 @@
|
|||
import { useCallback, useEffect, useRef, useState } from 'react';
|
||||
|
||||
export interface UseModalProps {
|
||||
onClose?: () => void;
|
||||
isOpen?: boolean;
|
||||
canClose?: boolean;
|
||||
}
|
||||
const ANIMATION_DURATION = 200;
|
||||
|
||||
export function useModal(props: UseModalProps) {
|
||||
const { isOpen, canClose: canCloseProp = true, onClose } = props;
|
||||
|
||||
const [isClosing, setIsClosing] = useState(false);
|
||||
const [modalIsVisible, setModalIsVisible] = useState(false);
|
||||
const [canClose, setCanClose] = useState(false);
|
||||
|
||||
const timerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
|
||||
|
||||
const close = useCallback(() => {
|
||||
if (canClose && canCloseProp && onClose) {
|
||||
onClose();
|
||||
}
|
||||
}, [canClose, canCloseProp, onClose]);
|
||||
|
||||
const onKeyDown = useCallback(
|
||||
(evt: KeyboardEvent) => {
|
||||
if (evt.key === 'Escape') {
|
||||
close();
|
||||
}
|
||||
},
|
||||
[close]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (isOpen) {
|
||||
setModalIsVisible(true);
|
||||
timerRef.current = setTimeout(() => {
|
||||
setCanClose(true);
|
||||
window.addEventListener('keydown', onKeyDown);
|
||||
}, ANIMATION_DURATION);
|
||||
|
||||
return () => {
|
||||
window.removeEventListener('keydown', onKeyDown);
|
||||
if (timerRef.current) {
|
||||
clearTimeout(timerRef.current);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
if (!isOpen) {
|
||||
setIsClosing(true);
|
||||
setCanClose(false);
|
||||
timerRef.current = setTimeout(() => {
|
||||
setModalIsVisible(false);
|
||||
setIsClosing(false);
|
||||
}, ANIMATION_DURATION);
|
||||
|
||||
return () => {
|
||||
if (timerRef.current) {
|
||||
clearTimeout(timerRef.current);
|
||||
}
|
||||
};
|
||||
}
|
||||
}, [isOpen, onKeyDown]);
|
||||
|
||||
return {
|
||||
isClosing,
|
||||
close,
|
||||
modalIsVisible,
|
||||
ANIMATION_DURATION
|
||||
};
|
||||
}
|
16
src/components/Portal/Portal.tsx
Normal file
16
src/components/Portal/Portal.tsx
Normal file
|
@ -0,0 +1,16 @@
|
|||
import { createPortal } from 'react-dom';
|
||||
import { ReactFCC } from '../../utils/ReactFCC';
|
||||
|
||||
interface PortalProps {
|
||||
element?: Element | DocumentFragment | null;
|
||||
}
|
||||
|
||||
export const Portal: ReactFCC<PortalProps> = (props) => {
|
||||
const { children, element = document.body } = props;
|
||||
|
||||
if (!element) {
|
||||
return <>{children}</>;
|
||||
}
|
||||
|
||||
return createPortal(children, element);
|
||||
};
|
1
src/components/Portal/index.ts
Normal file
1
src/components/Portal/index.ts
Normal file
|
@ -0,0 +1 @@
|
|||
export * from './Portal';
|
13
src/hooks/usePreventWindowScroll.ts
Normal file
13
src/hooks/usePreventWindowScroll.ts
Normal file
|
@ -0,0 +1,13 @@
|
|||
import { useCallback, useEffect } from 'react';
|
||||
|
||||
export const usePreventWindowScroll = (isPrevented?: boolean) => {
|
||||
const preventScroll = useCallback((isPrevented: boolean) => {
|
||||
document.body.classList.toggle('scroll-prevented', isPrevented);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
preventScroll(!!isPrevented);
|
||||
}, [isPrevented, preventScroll]);
|
||||
|
||||
return preventScroll;
|
||||
};
|
78
src/pages/response/ResponsePage.module.scss
Normal file
78
src/pages/response/ResponsePage.module.scss
Normal file
|
@ -0,0 +1,78 @@
|
|||
@import 'src/app/styles/vars';
|
||||
|
||||
.ResponsePage {
|
||||
|
||||
}
|
||||
|
||||
.ResponsePage__title {
|
||||
margin-bottom: $spacing-medium;
|
||||
}
|
||||
|
||||
.ResponsePage__container {
|
||||
width: 100%;
|
||||
|
||||
@include mobile-down {
|
||||
@include flex-col;
|
||||
row-gap: $spacing-small-2x;
|
||||
}
|
||||
}
|
||||
|
||||
.ResponsePage__table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
border-radius: $radius-small;
|
||||
border-style: hidden;
|
||||
box-shadow: 0 0 0 1px $color-border-default;
|
||||
|
||||
tbody tr {
|
||||
@include transition(background-color);
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
background-color: $color-background-secondary;
|
||||
|
||||
td {
|
||||
border-color: $color-border-hover;
|
||||
|
||||
&, > span {
|
||||
color: $color-text-brand !important;
|
||||
}
|
||||
}
|
||||
|
||||
.ResponsePage__tableSummary {
|
||||
//opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
&:active {
|
||||
background-color: $color-button-secondary-hover-fill;
|
||||
}
|
||||
}
|
||||
|
||||
th, td {
|
||||
padding: $spacing-small-3x $spacing-small-2x;
|
||||
border: 1px solid $color-border-default;
|
||||
}
|
||||
|
||||
th {
|
||||
text-align: left;
|
||||
font-weight: $font-weight-medium;
|
||||
}
|
||||
|
||||
td {
|
||||
@include transition(border-color, color);
|
||||
|
||||
&.ResponsePage__tableSummary {
|
||||
@include transition(opacity);
|
||||
opacity: 0;
|
||||
|
||||
&:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
> span {
|
||||
@include transition(color);
|
||||
}
|
||||
}
|
||||
}
|
108
src/pages/response/ResponsePage.tsx
Normal file
108
src/pages/response/ResponsePage.tsx
Normal file
|
@ -0,0 +1,108 @@
|
|||
import { FC, useCallback, useState } from 'react';
|
||||
import { Heading, HeadingSize } from '../../components/Heading';
|
||||
import { Link } from '../../components/Link';
|
||||
import { getPercentageColor } from '../../utils/getPercentageColor';
|
||||
import { EMDASH } from '../../utils/chars';
|
||||
import { ModalBody, useModal, ModalContainer } from '../../components/Modal';
|
||||
import { useIsMobile } from '../../hooks/useIsMobile';
|
||||
import { TextItem } from './components';
|
||||
import s from './ResponsePage.module.scss';
|
||||
|
||||
export const ResponsePage: FC = () => {
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
const onClose = useCallback(() => {
|
||||
setIsOpen(false);
|
||||
}, []);
|
||||
const { modalIsVisible, isClosing, close } = useModal({ isOpen, onClose });
|
||||
|
||||
const isMobile = useIsMobile();
|
||||
|
||||
return (
|
||||
<div className={s.ResponsePage}>
|
||||
<Heading size={HeadingSize.H2} className={s.ResponsePage__title}>
|
||||
Результаты по запросу
|
||||
</Heading>
|
||||
|
||||
<div className={s.ResponsePage__container}>
|
||||
{isMobile ? (
|
||||
<>
|
||||
<TextItem onClickSummary={() => setIsOpen(true)} />
|
||||
<TextItem />
|
||||
</>
|
||||
) : (
|
||||
<table className={s.ResponsePage__table}>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>Имя</th>
|
||||
<th>М. н-с.</th>
|
||||
<th>М. стат.</th>
|
||||
<th>М. п.</th>
|
||||
<th>Рез.</th>
|
||||
<th>Крат. сод.</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>1</td>
|
||||
<td>file.txt</td>
|
||||
<td>
|
||||
AA+ | <span style={{ color: getPercentageColor(0.63) }}>0.63</span>
|
||||
</td>
|
||||
<td>
|
||||
AA+ | <span style={{ color: getPercentageColor(0.95) }}>0.95</span>
|
||||
</td>
|
||||
<td>
|
||||
AA+ | <span style={{ color: getPercentageColor(0.95) }}>0.95</span>
|
||||
</td>
|
||||
<td>
|
||||
AA+ | <span style={{ color: getPercentageColor(0.95) }}>0.95</span>
|
||||
</td>
|
||||
<td className={s.ResponsePage__tableSummary}>
|
||||
<Link standalone={false}>Открыть</Link>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>1</td>
|
||||
<td>{EMDASH}</td>
|
||||
<td>
|
||||
AA+ | <span style={{ color: getPercentageColor(0.63) }}>0.63</span>
|
||||
</td>
|
||||
<td>
|
||||
AA+ | <span style={{ color: getPercentageColor(0.95) }}>0.95</span>
|
||||
</td>
|
||||
<td>
|
||||
AA+ | <span style={{ color: getPercentageColor(0.95) }}>0.95</span>
|
||||
</td>
|
||||
<td>
|
||||
AA+ | <span style={{ color: getPercentageColor(0.95) }}>0.95</span>
|
||||
</td>
|
||||
<td className={s.ResponsePage__tableSummary}>
|
||||
<Link
|
||||
component={'button'}
|
||||
standalone={false}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
setIsOpen(true);
|
||||
}}>
|
||||
Открыть
|
||||
</Link>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<ModalContainer isOpen={modalIsVisible} onClose={close} isClosing={isClosing}>
|
||||
<ModalBody>
|
||||
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industrys
|
||||
standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to
|
||||
make a type specimen book.
|
||||
</ModalBody>
|
||||
</ModalContainer>
|
||||
</div>
|
||||
);
|
||||
};
|
33
src/pages/response/components/TextItem/TextItem.module.scss
Normal file
33
src/pages/response/components/TextItem/TextItem.module.scss
Normal file
|
@ -0,0 +1,33 @@
|
|||
@import 'src/app/styles/vars';
|
||||
|
||||
.TextItem {
|
||||
background-color: $color-background-dark-100;
|
||||
border-radius: $radius-medium;
|
||||
padding: $spacing-small-2x;
|
||||
}
|
||||
|
||||
.TextItem__row {
|
||||
margin-bottom: $spacing-small-4x;
|
||||
|
||||
&:not(.TextItem__row_name) {
|
||||
> span {
|
||||
font-size: $font-size-14;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.TextItem__row_name {
|
||||
margin-bottom: $spacing-small-3x;
|
||||
|
||||
}
|
||||
|
||||
.TextItem__name {
|
||||
//font-size: $font-size-18;
|
||||
text-transform: uppercase;
|
||||
font-weight: $font-weight-600;
|
||||
}
|
||||
|
||||
.TextItem__row_link {
|
||||
margin-top: $spacing-small-3x;
|
||||
margin-bottom: 0;
|
||||
}
|
62
src/pages/response/components/TextItem/TextItem.tsx
Normal file
62
src/pages/response/components/TextItem/TextItem.tsx
Normal file
|
@ -0,0 +1,62 @@
|
|||
import clsx from 'clsx';
|
||||
import { ReactFCC } from '../../../../utils/ReactFCC';
|
||||
import { ETextVariants, Text } from '../../../../components/Text';
|
||||
import { getPercentageColor } from '../../../../utils/getPercentageColor';
|
||||
import { Link } from '../../../../components/Link';
|
||||
import s from './TextItem.module.scss';
|
||||
|
||||
export interface TextItemProps {
|
||||
/**
|
||||
* Дополнительный css-класс
|
||||
*/
|
||||
className?: string;
|
||||
|
||||
onClickSummary?: () => void;
|
||||
}
|
||||
|
||||
export const TextItem: ReactFCC<TextItemProps> = (props) => {
|
||||
const { className, onClickSummary } = props;
|
||||
|
||||
return (
|
||||
<div className={clsx(s.TextItem, className)}>
|
||||
<div className={clsx(s.TextItem__row, s.TextItem__row_name)}>
|
||||
{/*<Text component={'span'} variant={ETextVariants.BODY_S_MEDIUM}>*/}
|
||||
{/* Имя:*/}
|
||||
{/*</Text>{' '}*/}
|
||||
<Text className={s.TextItem__name} component={'span'} variant={ETextVariants.PROGRAMMING_CODE_REGULAR}>
|
||||
file.txt #1
|
||||
</Text>
|
||||
{/*{' | '}*/}
|
||||
{/*<Text component={'span'} variant={ETextVariants.BODY_S_REGULAR}>*/}
|
||||
{/* file.txt*/}
|
||||
{/*</Text>*/}
|
||||
</div>
|
||||
|
||||
<div className={s.TextItem__row}>
|
||||
<Text component={'span'} variant={ETextVariants.PROGRAMMING_CODE_REGULAR}>
|
||||
М. н-с: AA+ | <span style={{ color: getPercentageColor(0.63) }}>0.63</span>
|
||||
</Text>{' '}
|
||||
</div>
|
||||
|
||||
<div className={s.TextItem__row}>
|
||||
<Text component={'span'} variant={ETextVariants.PROGRAMMING_CODE_REGULAR}>
|
||||
М. стат: AA+ | <span style={{ color: getPercentageColor(0.63) }}>0.63</span>
|
||||
</Text>{' '}
|
||||
</div>
|
||||
|
||||
<div className={s.TextItem__row}>
|
||||
<Text component={'span'} variant={ETextVariants.PROGRAMMING_CODE_REGULAR}>
|
||||
М. п: AA+ | <span style={{ color: getPercentageColor(0.63) }}>0.63</span>
|
||||
</Text>{' '}
|
||||
</div>
|
||||
|
||||
<div className={clsx(s.TextItem__row, s.TextItem__row_link)}>
|
||||
<Text component={'span'} variant={ETextVariants.BODY_S_REGULAR}>
|
||||
<Link component={'button'} standalone={false} onClick={() => onClickSummary?.()}>
|
||||
Краткое содержание
|
||||
</Link>
|
||||
</Text>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
1
src/pages/response/components/TextItem/index.ts
Normal file
1
src/pages/response/components/TextItem/index.ts
Normal file
|
@ -0,0 +1 @@
|
|||
export * from './TextItem';
|
1
src/pages/response/components/index.ts
Normal file
1
src/pages/response/components/index.ts
Normal file
|
@ -0,0 +1 @@
|
|||
export * from './TextItem';
|
1
src/pages/response/index.ts
Normal file
1
src/pages/response/index.ts
Normal file
|
@ -0,0 +1 @@
|
|||
export * from './ResponsePage';
|
|
@ -42,7 +42,7 @@ export const TextPage: FC = () => {
|
|||
Результат по методу{' '}
|
||||
<Tooltip className={s.TextPage__tooltip} content={'Berd + Annoy'}>
|
||||
<span className={s.TextPage__underline}>похожести</span>
|
||||
</Tooltip>{' '}
|
||||
</Tooltip>
|
||||
: АА+ | Accuracy: <span style={{ color: getPercentageColor(0.63) }}>0.63</span>
|
||||
</Text>
|
||||
</div>
|
||||
|
|
21
src/utils/chars.ts
Normal file
21
src/utils/chars.ts
Normal file
|
@ -0,0 +1,21 @@
|
|||
// eslint-disable
|
||||
export const LAQUO = '\u00AB'; // «
|
||||
export const RAQUO = '\u00BB'; // »
|
||||
export const EMDASH = '\u2014'; // —
|
||||
export const THINSP = '\u2009'; //
|
||||
export const QUARTERSP = '\u2005'; //
|
||||
export const THIRDSP = '\u2004'; //
|
||||
export const ENSP = '\u2002'; //
|
||||
export const EMSP = '\u2001'; //
|
||||
export const NBSP = '\u00A0'; //
|
||||
export const HELLIP = '\u2026'; // …
|
||||
export const LSAQUO = '\u2039'; // ‹
|
||||
export const RSAQUO = '\u203A'; // ›
|
||||
export const RUBLE = '\u20BD'; // ₽
|
||||
export const LEQ = '\u2264'; // ≤
|
||||
export const NEQ = '\u2260'; // ≠
|
||||
export const GEQ = '\u2265'; // ≥
|
||||
export const ARROW_LEFT = '\u2190'; // ←
|
||||
export const ARROW_RIGHT = '\u2192'; // →
|
||||
export const MAC_OPTION = '\u2325'; // ⌥
|
||||
// eslint-enable
|
Loading…
Reference in New Issue
Block a user