- Surse complete web (React/Vite) + mobil (React Native/Expo) + extensie (MV3) - Documentație de livrare: ghid utilizare, matrice trasabilitate cerințe, raport testare furnizor - Artefacte binare: imagine Docker didi-frontend:lot3-1.0, APK, extensie v3.2.6 + SHA256SUMS - Configurare adresă platformă externalizată (build args / .env / config.js) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
48 lines
1.4 KiB
TypeScript
48 lines
1.4 KiB
TypeScript
import React from 'react';
|
|
import { useTranslation } from 'react-i18next';
|
|
import styled from '@emotion/styled';
|
|
import { spacing } from '../../../theme';
|
|
|
|
interface Props {
|
|
inputType: string;
|
|
text: string | null | undefined;
|
|
}
|
|
|
|
/** Split raw input into clean paragraphs. Single \n collapses to space; \n\n+ = new paragraph. */
|
|
function toParagraphs(raw: string): string[] {
|
|
return raw.split(/\n{2,}/).map(p => p.replace(/\s*\n\s*/g, ' ').trim()).filter(Boolean);
|
|
}
|
|
|
|
export const InputPreview: React.FC<Props> = ({ inputType, text }) => {
|
|
const { t } = useTranslation();
|
|
if (!text) return null;
|
|
const paragraphs = toParagraphs(text);
|
|
return (
|
|
<Block>
|
|
<Label>{t('history.inputLabel', { type: inputType })}</Label>
|
|
<Body>
|
|
{paragraphs.map((p, i) => <p key={i}>{p}</p>)}
|
|
</Body>
|
|
</Block>
|
|
);
|
|
};
|
|
|
|
const Block = styled.div`
|
|
display: flex; flex-direction: column; gap: 6px;
|
|
padding: 14px 18px;
|
|
background: var(--bg-surface);
|
|
border: 1px solid var(--border-subtle);
|
|
border-radius: 14px;
|
|
margin-bottom: ${spacing.md}px;
|
|
`;
|
|
const Label = styled.div`
|
|
font-size: 10.5px; font-weight: 600; letter-spacing: 0.16em; text-transform: uppercase;
|
|
color: var(--fg-muted);
|
|
`;
|
|
const Body = styled.div`
|
|
font-size: 13px; color: var(--fg-secondary); line-height: 1.6;
|
|
word-break: break-word; overflow-wrap: break-word;
|
|
max-height: 240px; overflow-y: auto;
|
|
display: flex; flex-direction: column; gap: 10px;
|
|
& p { margin: 0; }
|
|
`;
|