Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Display user's shared links table + Add new links #64

Merged
Merged
Show file tree
Hide file tree
Changes from 4 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
3 changes: 3 additions & 0 deletions src/app/components/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ export default async function Header() {
>
Patient Summary View
</MenuItem>
<MenuItem key="dashboard" component={NextLink} href="/shared-links">
Dashboard
</MenuItem>
<Box sx={{ width: '100%', textAlign: 'right' }}>{AuthButton}</Box>
</Toolbar>
</AppBar>
Expand Down
15 changes: 15 additions & 0 deletions src/app/shared-links/Components/BooleanIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import CancelIcon from '@mui/icons-material/Cancel';
import CheckCircleIcon from '@mui/icons-material/CheckCircle';
import { green, red } from '@mui/material/colors';

export default function BooleanIcon({
status,
}: {
status: boolean;
}): JSX.Element {
return status ? (
<CheckCircleIcon style={{ color: green[500] }} />
) : (
<CancelIcon style={{ color: red[500] }} />
);
}
157 changes: 157 additions & 0 deletions src/app/shared-links/Components/LinksTable.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
'use client';
import CalendarTodayIcon from '@mui/icons-material/CalendarToday';
import {
Paper,
Table,
TableBody,
TableCell,
TableContainer,
TableHead,
TablePagination,
TableRow,
} from '@mui/material';
import React from 'react';

import { SHLinkMiniDto } from '@/domain/dtos/shlink';

import BooleanIcon from './BooleanIcon';

interface Column {
id: keyof SHLinkMiniDto;
label: string;
minWidth?: number;
align?: 'right' | 'left' | 'center';
// string | boolean | Date | SHLinkFileDto[]
format?: (
value: SHLinkMiniDto[keyof SHLinkMiniDto],
) => string | React.JSX.Element;
}

const columns: readonly Column[] = [
{ id: 'name', label: 'Name', minWidth: 100 },
{
id: 'expiryDate',
label: 'Expiry Date',
minWidth: 80,
format: (value?: Date) =>
value?.toLocaleDateString() || (
<span
style={{ display: 'flex', alignItems: 'center', color: '#9e9e9e' }}
>
<CalendarTodayIcon fontSize="small" style={{ marginRight: '4px' }} />
Not Defined
</span>
),
},
{
id: 'passwordRequired',
label: 'Passcode enabled',
minWidth: 50,
format: (value?: boolean) => <BooleanIcon status={!!value} />,
},
];

function createData(data: SHLinkMiniDto): SHLinkMiniDto {
return { ...data };
}

const apiDataMock: SHLinkMiniDto[] = [
{
name: 'Lab Results',
id: 'A9876',
managementToken: 'token-health1234abcd5678',
url: 'https://healthportal.com/share/johndoe/lab-results',
expiryDate: new Date('2024-11-01T09:30:00Z'),
passwordRequired: true,
},
{
name: 'MRI Report',
id: 'B6543',
managementToken: 'token-mri5678wxyz9012',
url: 'https://healthportal.com/share/janesmith/mri-report',
passwordRequired: false,
},
{
name: 'Prescription',
id: 'C3210',
managementToken: 'token-prescript123uvwx4567',
url: 'https://healthportal.com/share/patient/prescription-link',
expiryDate: new Date('2025-01-15T12:00:00Z'),
passwordRequired: true,
},
{
name: 'Surgery Notes',
id: 'D7891',
managementToken: 'token-surgery789abcd0123',
url: 'https://healthportal.com/share/emilybrown/surgery-notes',
expiryDate: new Date('2024-09-30T15:00:00Z'),
passwordRequired: false,
},
];

const rows = apiDataMock.map(createData);

export default function LinksTable() {
const [page, setPage] = React.useState(0);
const [rowsPerPage, setRowsPerPage] = React.useState(10);

const handleChangePage = (_event: unknown, newPage: number) => {
setPage(newPage);
};

const handleChangeRowsPerPage = (
event: React.ChangeEvent<HTMLInputElement>,
) => {
setRowsPerPage(Number(event.target.value));
setPage(0);
};

return (
<Paper sx={{ width: '100%', overflow: 'hidden' }}>
<TableContainer sx={{ maxHeight: '50vh' }}>
<Table stickyHeader aria-label="sticky table">
<TableHead>
<TableRow>
{columns.map((column) => (
<TableCell
key={column.id}
align={column.align}
style={{ minWidth: column.minWidth }}
>
{column.label}
</TableCell>
))}
</TableRow>
</TableHead>
<TableBody>
{rows
.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage)
.map((row) => (
<TableRow hover tabIndex={-1} key={row.id}>
{columns.map((column) => {
const value = row[column.id];
return (
<TableCell key={column.id} align={column.align}>
{column.format
? column.format(value)
: value.toString()}
</TableCell>
);
})}
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
<TablePagination
rowsPerPageOptions={[10, 25, 100]}
component="div"
count={rows.length}
rowsPerPage={rowsPerPage}
page={page}
onPageChange={handleChangePage}
onRowsPerPageChange={handleChangeRowsPerPage}
/>
</Paper>
);
}
amalessid marked this conversation as resolved.
Show resolved Hide resolved
151 changes: 151 additions & 0 deletions src/app/shared-links/LinksTable.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
'use client';
import {
Paper,
Table,
TableBody,
TableCell,
TableContainer,
TableHead,
TablePagination,
TableRow,
} from '@mui/material';
import React from 'react';

import { SHLinkMiniDto } from '@/domain/dtos/shlink';

interface Column {
id: keyof SHLinkMiniDto;
label: string;
minWidth?: number;
align?: 'right' | 'left' | 'center';
// string | boolean | Date | SHLinkFileDto[]
format?: (value: SHLinkMiniDto[keyof SHLinkMiniDto]) => string;
}

const columns: readonly Column[] = [
{ id: 'id', label: 'Id', minWidth: 100 },
{ id: 'name', label: 'Name', minWidth: 100 },
{ id: 'url', label: 'Url', minWidth: 100 },
{ id: 'managementToken', label: 'Management Token', minWidth: 100 },
{
id: 'expiryDate',
label: 'Expiry Date',
minWidth: 80,
format: (value: Date) => value.toLocaleDateString(),
},
{
id: 'passwordRequired',
label: 'Password',
minWidth: 80,
// format: (value: boolean) => (!value?`Not`:`` value),
format: (value: boolean) => `${!value ? 'Not' : ''} Required`,
},
];

function createData(data: SHLinkMiniDto): SHLinkMiniDto {
return { ...data };
}

const apiDataMock: SHLinkMiniDto[] = [
amalessid marked this conversation as resolved.
Show resolved Hide resolved
{
name: 'Lab Results',
id: 'A9876',
managementToken: 'token-health1234abcd5678',
url: 'https://healthportal.com/share/johndoe/lab-results',
expiryDate: new Date('2024-11-01T09:30:00Z'),
passwordRequired: true,
},
{
name: 'MRI Report',
id: 'B6543',
managementToken: 'token-mri5678wxyz9012',
url: 'https://healthportal.com/share/janesmith/mri-report',
expiryDate: new Date('2024-12-20T17:45:00Z'),
passwordRequired: false,
},
{
name: 'Prescription',
id: 'C3210',
managementToken: 'token-prescript123uvwx4567',
url: 'https://healthportal.com/share/patient/prescription-link',
expiryDate: new Date('2025-01-15T12:00:00Z'),
passwordRequired: true,
},
{
name: 'Surgery Notes',
id: 'D7891',
managementToken: 'token-surgery789abcd0123',
url: 'https://healthportal.com/share/emilybrown/surgery-notes',
expiryDate: new Date('2024-09-30T15:00:00Z'),
passwordRequired: false,
},
];

const rows = apiDataMock.map(createData);

export default function LinksTable() {
const [page, setPage] = React.useState(0);
const [rowsPerPage, setRowsPerPage] = React.useState(10);

const handleChangePage = (_event: unknown, newPage: number) => {
setPage(newPage);
};

const handleChangeRowsPerPage = (
event: React.ChangeEvent<HTMLInputElement>,
) => {
setRowsPerPage(Number(event.target.value));
setPage(0);
};

return (
<Paper sx={{ width: '100%', overflow: 'hidden' }}>
<TableContainer sx={{ maxHeight: '50vh' }}>
<Table stickyHeader aria-label="sticky table">
<TableHead>
<TableRow>
{columns.map((column) => (
<TableCell
key={column.id}
align={column.align}
style={{ minWidth: column.minWidth }}
>
{column.label}
</TableCell>
))}
</TableRow>
</TableHead>
<TableBody>
{rows
.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage)
.map((row) => (
<TableRow hover tabIndex={-1} key={row.id}>
{columns.map((column) => {
const value = row[column.id];
return (
<TableCell key={column.id} align={column.align}>
{column.format
? column.format(value)
: value
? value.toString()
: ''}
</TableCell>
);
})}
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
<TablePagination
rowsPerPageOptions={[10, 25, 100]}
component="div"
count={rows.length}
rowsPerPage={rowsPerPage}
page={page}
onPageChange={handleChangePage}
onRowsPerPageChange={handleChangeRowsPerPage}
/>
</Paper>
);
}
19 changes: 19 additions & 0 deletions src/app/shared-links/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { Box, Container } from '@mui/material';

import LinksTable from './Components/LinksTable';

export default function SharedLinksPage() {
return (
<Container maxWidth={false}>
<Box
display="flex"
flexDirection="column"
alignItems="center"
justifyContent="center"
paddingTop={8}
paddingBottom={8}
></Box>
amalessid marked this conversation as resolved.
Show resolved Hide resolved
<LinksTable />
</Container>
);
}