import { ReactNode } from 'react'; import styled from 'styled-components'; import colors from 'styles/colors'; import Heading from 'components/Form/Heading'; export interface RowProps { lbl: string, val: string, // key?: string, children?: ReactNode, rowList?: RowProps[], title?: string, open?: boolean, } export const StyledRow = styled.div` display: flex; justify-content: space-between; padding: 0.25rem; &:not(:last-child) { border-bottom: 1px solid ${colors.primary}; } span.lbl { font-weight: bold; } span.val { max-width: 16rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } `; const StyledExpandableRow = styled(StyledRow).attrs({ as: "summary" })``; const Details = styled.details` transition: all 0.2s ease-in-out; summary { padding-left: 1rem; } summary:before { content: "►"; position: absolute; margin-left: -1rem; color: ${colors.primary}; cursor: pointer; } &[open] summary:before { content: "▼"; } `; const SubRowList = styled.ul` margin: 0; padding: 0.25rem; background: ${colors.primaryTransparent}; `; const SubRow = styled(StyledRow).attrs({ as: "li" })` border-bottom: 1px dashed ${colors.primaryTransparent} !important; `; const isValidDate = (date: any): boolean => { // Checks if a date is within reasonable range const isInRange = (date: Date): boolean => { return date >= new Date('1995-01-01') && date <= new Date('2030-12-31'); }; // Check if input is a timestamp if (typeof date === 'number') { const timestampDate = new Date(date); return !isNaN(timestampDate.getTime()) && isInRange(timestampDate); } // Check if input is a date string if (typeof date === 'string') { const dateStringDate = new Date(date); return !isNaN(dateStringDate.getTime()) && isInRange(dateStringDate); } // Check if input is a Date object if (date instanceof Date) { return !isNaN(date.getTime()) && isInRange(date); } return false; }; const formatDate = (dateString: string): string => { return new Intl.DateTimeFormat('en-GB', { day: 'numeric', month: 'long', year: 'numeric' }).format(new Date(dateString)); } const formatValue = (value: any): string => { if (isValidDate(new Date(value))) return formatDate(value); if (typeof value === 'boolean') return value ? '✅' : '❌'; return value; }; const copyToClipboard = (text: string) => { navigator.clipboard.writeText(text); } export const ExpandableRow = (props: RowProps) => { const { lbl, val, title, rowList, open } = props; return (
{lbl} {val.toString()} { rowList && { rowList?.map((row: RowProps, index: number) => { return ( {row.lbl} copyToClipboard(row.val)}> {formatValue(row.val)} ) })} }
); }; export const ListRow = (props: { list: string[], title: string }) => { const { list, title } = props; return ( <> {title} { list.map((entry: string, index: number) => { return ( { entry } )} )} ); } const Row = (props: RowProps) => { const { lbl, val, title, children } = props; if (children) return {children}; return ( { lbl && {lbl} } copyToClipboard(val)}> {formatValue(val)} ); }; export default Row;