Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@ import Spinner from '../../../generic/spinner/Spinner';
import ExistingRecordTable from './ExistingRecordTable';
import useBaseAPIHeaders from '../../../../helpers/hooks/useBaseAPIHeaders';
import useBaseAPIUrl from '../../../../helpers/hooks/useBaseAPIUrl';
import { getFormattedDateFromString } from '../../../../helpers/utils/formatDate';
import {
getFormattedDateFromString,
getFormattedDateTimeFromString,
} from '../../../../helpers/utils/formatDate';
import {
GetDocumentReviewDto,
ReviewDetails,
Expand All @@ -28,6 +31,7 @@ import DocumentUploadLloydGeorgePreview from '../../_documentUpload/documentUplo
import { AxiosError } from 'axios';
import { errorToParams } from '../../../../helpers/utils/errorToParams';
import PatientSummary, { PatientInfo } from '../../../generic/patientSummary/PatientSummary';
import { CreatedByText } from '../../../generic/createdBy/createdBy';

type FileAction = 'add-all' | 'choose-files' | 'duplicate' | 'accept' | 'reject' | '';

Expand Down Expand Up @@ -402,13 +406,19 @@ const ReviewDetailsAssessmentStage = ({
<p>
<strong>You are currently viewing: all files</strong>
</p>

<DocumentUploadLloydGeorgePreview
documents={uploadDocuments.filter((f) => f.file.name.endsWith('.pdf'))}
setMergedPdfBlob={(): void => {}}
stitchedBlobLoaded={(): void => {}}
isReview={true}
documentConfig={reviewConfig}
/>
>
<CreatedByText
odsCode={reviewData.uploader}
dateUploaded={getFormattedDateTimeFromString(reviewData.dateUploaded)}
cssClass="pt-1"
/>
</DocumentUploadLloydGeorgePreview>
</>
)}

Expand Down Expand Up @@ -438,8 +448,17 @@ const ReviewDetailsAssessmentStage = ({
)}
setMergedPdfBlob={(): void => {}}
stitchedBlobLoaded={(): void => {}}
isReview={true}
documentConfig={reviewConfig}
/>
>
<CreatedByText
odsCode={reviewData.uploader}
dateUploaded={getFormattedDateTimeFromString(
reviewData.dateUploaded,
)}
cssClass="pt-1"
/>
</DocumentUploadLloydGeorgePreview>
)}
</section>
)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ const ReviewDetailsDocumentSelectOrderStage = ({
confirmFiles={(): void => {}}
onSuccess={onSuccess}
isReview={true}
reviewData={reviewData}
/>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,9 @@ import { RecordLayout } from '../../../generic/recordCard/RecordCard';
import { RecordLoader, RecordLoaderProps } from '../../../generic/recordLoader/RecordLoader';
import { getConfigForDocType } from '../../../../helpers/utils/documentType';
import { DOWNLOAD_STAGE } from '../../../../types/generic/downloadStage';
import { getFormattedDateFromString } from '../../../../helpers/utils/formatDate';
import { ReviewUploadDocument } from '../../../../types/pages/UploadDocumentsPage/types';
import { getFormattedDateTimeFromString } from '../../../../helpers/utils/formatDate';
import { CreatedByCard } from '../../../generic/createdBy/createdBy';

export const incorrectFormatMessage = "Enter patient's 10 digit NHS number";

Expand Down Expand Up @@ -137,7 +138,6 @@ const ReviewDetailsPatientSearchStage = ({

const recordDetailsProps: RecordLoaderProps = {
downloadStage: DOWNLOAD_STAGE.SUCCEEDED,
lastUpdated: getFormattedDateFromString(reviewData.lastUpdated),
childrenIfFailiure: <p>Failure: failed to load documents</p>,
fileName:
!reviewConfig.multifileReview && reviewData.files?.length === 1
Expand Down Expand Up @@ -236,7 +236,13 @@ const ReviewDetailsPatientSearchStage = ({
setMergedPdfBlob={(): void => {}}
documentConfig={reviewConfig}
isReview={true}
/>
>
<CreatedByCard
odsCode={reviewData.uploader}
dateUploaded={getFormattedDateTimeFromString(reviewData.dateUploaded)}
cssClass="pt-1"
/>
</DocumentUploadLloydGeorgePreview>
</RecordLayout>
</>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import useConfig from '../../../../helpers/hooks/useConfig';
import useRole from '../../../../helpers/hooks/useRole';
import useTitle from '../../../../helpers/hooks/useTitle';
import { getConfigForDocType } from '../../../../helpers/utils/documentType';
import { getFormattedDateFromString } from '../../../../helpers/utils/formatDate';
import { getFormattedDateTimeFromString } from '../../../../helpers/utils/formatDate';
import { setFullScreen } from '../../../../helpers/utils/fullscreen';
import { handleSearch as handlePatientSearch } from '../../../../helpers/utils/handlePatientSearch';
import { usePatientDetailsContext } from '../../../../providers/patientProvider/PatientProvider';
Expand Down Expand Up @@ -35,6 +35,7 @@ import { errorToParams } from '../../../../helpers/utils/errorToParams';
import waitForSeconds from '../../../../helpers/utils/waitForSeconds';
import DocumentUploadLloydGeorgePreview from '../../_documentUpload/documentUploadLloydGeorgePreview/DocumentUploadLloydGeorgePreview';
import { NHS_NUMBER_UNKNOWN } from '../../../../helpers/constants/numbers';
import { CreatedByCard } from '../../../generic/createdBy/createdBy';

export type ReviewsDetailsStageProps = {
reviewData: ReviewDetails;
Expand Down Expand Up @@ -106,9 +107,9 @@ const ReviewsDetailsStage = ({
anchor.remove();
}
};

const recordDetailsProps: RecordLoaderProps = {
downloadStage,
lastUpdated: getFormattedDateFromString(reviewData.lastUpdated),
childrenIfFailiure: <p>Failure: failed to load documents</p>,
fileName:
!reviewConfig.multifileReview && reviewData.files && reviewData.files.length === 1
Expand Down Expand Up @@ -334,7 +335,15 @@ const ReviewsDetailsStage = ({
setMergedPdfBlob={(): void => {}}
documentConfig={reviewConfig}
isReview={true}
/>
>
<CreatedByCard
odsCode={reviewData.uploader}
dateUploaded={getFormattedDateTimeFromString(
reviewData.dateUploaded,
)}
cssClass="pt-1"
/>
</DocumentUploadLloydGeorgePreview>
</RecordLayout>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ import ErrorBox from '../../../layout/errorBox/ErrorBox';
import DocumentUploadLloydGeorgePreview from '../documentUploadLloydGeorgePreview/DocumentUploadLloydGeorgePreview';
import SpinnerButton from '../../../generic/spinnerButton/SpinnerButton';
import { DOCUMENT_TYPE_CONFIG } from '../../../../helpers/utils/documentType';
import { CreatedByText } from '../../../generic/createdBy/createdBy';
import { getFormattedDateTimeFromString } from '../../../../helpers/utils/formatDate';
import { ReviewDetails } from '../../../../types/generic/reviews';

type Props = {
documents: UploadDocument[] | ReviewUploadDocument[];
Expand All @@ -34,6 +37,7 @@ type Props = {
confirmFiles: () => void;
onSuccess?: () => void;
isReview?: boolean;
reviewData?: ReviewDetails;
};

type FormData = {
Expand All @@ -51,6 +55,7 @@ const DocumentSelectOrderStage = ({
confirmFiles,
onSuccess,
isReview = false,
reviewData,
}: Readonly<Props>): JSX.Element => {
const navigate = useEnhancedNavigate();
const journey = getJourney();
Expand Down Expand Up @@ -472,7 +477,18 @@ const DocumentSelectOrderStage = ({
setStitchedBlobLoaded(loaded);
}}
documentConfig={documentConfig}
/>
isReview={isReview}
>
{isReview && reviewData && (
<CreatedByText
odsCode={reviewData.uploader}
dateUploaded={getFormattedDateTimeFromString(
reviewData.dateUploaded,
)}
cssClass="pt-5"
/>
)}
</DocumentUploadLloydGeorgePreview>
</div>
{documents.length > 0 && stitchedBlobLoaded && (
<Button
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ type Props = {
documentConfig: DOCUMENT_TYPE_CONFIG;
isReview?: boolean;
showCurrentlyViewingText?: boolean;
children?: React.ReactNode;
};

const DocumentUploadLloydGeorgePreview = ({
Expand All @@ -21,6 +22,7 @@ const DocumentUploadLloydGeorgePreview = ({
documentConfig,
isReview = false,
showCurrentlyViewingText,
children,
}: Props): JSX.Element => {
const [mergedPdfUrl, setMergedPdfUrl] = useState('');
const journey = getJourney();
Expand Down Expand Up @@ -106,6 +108,7 @@ const DocumentUploadLloydGeorgePreview = ({
)}
</>
)}
{isReview && <>{children}</>}
{documents && mergedPdfUrl && (
<PdfViewer customClasses={['upload-preview']} fileUrl={mergedPdfUrl} />
)}
Expand Down
79 changes: 79 additions & 0 deletions app/src/components/generic/createdBy/createdBy.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import { render, screen } from '@testing-library/react';
import { CreatedByCard, CreatedByText } from './createdBy';

describe('createdBy.tsx', () => {
describe('CreatedByCard', () => {
const defaultProps = {
odsCode: 'Y12345',
dateUploaded: '2024-01-15',
};

it('renders the card with odsCode and dateUploaded', () => {
render(<CreatedByCard {...defaultProps} />);

expect(
screen.getByText(
`Created by practice ${defaultProps.odsCode} on ${defaultProps.dateUploaded}`,
),
).toBeInTheDocument();
});

it('applies custom cssClass when provided', () => {
const customClass = 'custom-test-class';
const { container } = render(
<CreatedByCard {...defaultProps} cssClass={customClass} />,
);

const cardContent = container.querySelector(`.${customClass}`);
expect(cardContent).toBeInTheDocument();
});

it('renders without cssClass when not provided', () => {
const { container } = render(<CreatedByCard {...defaultProps} />);

const cardContent = container.firstChild;
expect(cardContent).not.toHaveClass('custom-test-class');
});
});

describe('CreatedByText', () => {
const defaultProps = {
odsCode: 'A98765',
dateUploaded: '2024-06-20',
};

it('renders the text with odsCode and dateUploaded', () => {
render(<CreatedByText {...defaultProps} />);

expect(
screen.getByText(
`Created by practice ${defaultProps.odsCode} on ${defaultProps.dateUploaded}`,
),
).toBeInTheDocument();
});

it('renders as a paragraph element', () => {
render(<CreatedByText {...defaultProps} />);

const paragraph = screen.getByText(/Created by practice/);
expect(paragraph.tagName).toBe('P');
});

it('applies custom cssClass when provided', () => {
const customClass = 'text-style-class';
const { container } = render(
<CreatedByText {...defaultProps} cssClass={customClass} />,
);

const paragraph = container.querySelector(`.${customClass}`);
expect(paragraph).toBeInTheDocument();
});

it('renders without cssClass when not provided', () => {
const { container } = render(<CreatedByText {...defaultProps} />);

const paragraph = container.firstChild;
expect(paragraph).not.toHaveClass('text-style-class');
});
});
});
20 changes: 20 additions & 0 deletions app/src/components/generic/createdBy/createdBy.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { Card } from 'nhsuk-react-components';
import { JSX } from 'react';

export type CreatedByProps = {
odsCode: string;
dateUploaded: string;
cssClass?: string;
};

export const CreatedByCard = ({ odsCode, dateUploaded, cssClass }: CreatedByProps): JSX.Element => (
<Card.Content className={cssClass}>
Created by practice {odsCode} on {dateUploaded}
</Card.Content>
);

export const CreatedByText = ({ odsCode, dateUploaded, cssClass }: CreatedByProps): JSX.Element => (
<p className={cssClass}>
Created by practice {odsCode} on {dateUploaded}
</p>
);
Original file line number Diff line number Diff line change
Expand Up @@ -343,12 +343,6 @@ describe('RecordDetails', () => {
});

describe('Edge Cases', () => {
it('handles empty string for lastUpdated', () => {
render(<RecordDetails fileName="test-document.pdf" lastUpdated="" />);

expect(screen.getByText('Last updated:')).toBeInTheDocument();
});

it('handles long date strings', () => {
const longDate = 'Wednesday, 25th December 2024 at 12:30:45pm GMT';
render(<RecordDetails fileName="test-document.pdf" lastUpdated={longDate} />);
Expand Down
16 changes: 11 additions & 5 deletions app/src/components/generic/recordLoader/RecordLoader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import ProgressBar from '../progressBar/ProgressBar';

export type RecordLoaderProps = {
downloadStage: DOWNLOAD_STAGE;
lastUpdated: string;
lastUpdated?: string;
childrenIfFailiure: React.JSX.Element;
fileName: string;
downloadAction?: (e: React.MouseEvent<HTMLElement>) => void;
Expand All @@ -23,6 +23,10 @@ export const RecordLoader = ({
fileName,
};

if (!lastUpdated && !fileName) {
return <></>;
}

switch (downloadStage) {
case DOWNLOAD_STAGE.INITIAL:
case DOWNLOAD_STAGE.PENDING:
Expand All @@ -48,7 +52,7 @@ export const RecordLoader = ({
};

export type RecordDetailsProps = {
lastUpdated: string;
lastUpdated?: string;
fileName: string;
downloadAction?: (e: React.MouseEvent<HTMLElement>) => void;
};
Expand All @@ -61,9 +65,11 @@ export const RecordDetails = ({
return (
<div className="lloydgeorge_record-details">
<div className="lloydgeorge_record-details_details">
<div className="lloydgeorge_record-details_details--last-updated">
<p>Last updated: {lastUpdated}</p>
</div>
{lastUpdated && (
<div className="lloydgeorge_record-details_details--last-updated">
<p>Last updated: {lastUpdated}</p>
</div>
)}
{fileName && (
<div className="lloydgeorge_record-details_details--last-updated mt-3">
<p>
Expand Down
Loading
Loading