Skip to content

Commit

Permalink
Merge pull request #90 from jembi/87-ui-show-qr-code
Browse files Browse the repository at this point in the history
Feat: QR code
  • Loading branch information
yassinedorbozgithub authored Sep 25, 2024
2 parents 81439e1 + fc601c8 commit 022e9bb
Show file tree
Hide file tree
Showing 7 changed files with 279 additions and 52 deletions.
8 changes: 8 additions & 0 deletions src/app/components/StyledDialogActions.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { DialogActions, styled } from '@mui/material';

export const StyledDialogActions = styled(DialogActions)(() => ({
paddingTop: '15px',
paddingRight: '25px',
paddingBottom: '15px',
backgroundImage: 'linear-gradient(to top, hsla(0, 0%, 90%, .05), #e6e6e6)',
}));
8 changes: 8 additions & 0 deletions src/app/components/StyledDialogContent.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { styled } from '@mui/material';

export const StyledDialogContent = styled('div')(() => ({
gap: '15px',
margin: '15px',
display: 'flex',
flexDirection: 'column',
}));
5 changes: 5 additions & 0 deletions src/app/components/StyledDialogTitle.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { DialogTitle, styled } from '@mui/material';

export const StyledDialogTitle = styled(DialogTitle)(() => ({
backgroundImage: 'linear-gradient(to bottom, hsla(0, 0%, 90%, .05), #e6e6e6)',
}));
21 changes: 3 additions & 18 deletions src/app/shared-links/Components/AddLinkDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ import {
import { FC, useEffect } from 'react';
import { useForm } from 'react-hook-form';

import { StyledDialogActions } from '@/app/components/StyledDialogActions';
import { StyledDialogContent } from '@/app/components/StyledDialogContent';
import { StyledDialogTitle } from '@/app/components/StyledDialogTitle';
import { useAuth } from '@/app/context/AuthProvider';
import { apiSharedLink } from '@/app/utils/api.class';
import { CreateSHLinkDto } from '@/domain/dtos/shlink';
Expand All @@ -19,24 +22,6 @@ const removeUndefinedValues = <T extends Record<string, unknown>>(
object: T,
): T => JSON.parse(JSON.stringify(object));

const StyledDialogTitle = styled(DialogTitle)(() => ({
backgroundImage: 'linear-gradient(to bottom, hsla(0, 0%, 90%, .05), #e6e6e6)',
}));

const StyledDialogContent = styled('div')(() => ({
gap: '15px',
margin: '15px',
display: 'flex',
flexDirection: 'column',
}));

const StyledDialogActions = styled(DialogActions)(() => ({
paddingTop: '15px',
paddingRight: '25px',
paddingBottom: '15px',
backgroundImage: 'linear-gradient(to top, hsla(0, 0%, 90%, .05), #e6e6e6)',
}));

export type TCreateSHLinkDto = Omit<CreateSHLinkDto, 'configExp'> & {
configExp?: string;
};
Expand Down
95 changes: 61 additions & 34 deletions src/app/shared-links/Components/LinksTable.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
'use client';

import { QrCode } from '@mui/icons-material';
import CalendarTodayIcon from '@mui/icons-material/CalendarToday';
import LinkOffIcon from '@mui/icons-material/LinkOff';
import {
Expand All @@ -14,21 +14,18 @@ import {
TablePagination,
TableRow,
Tooltip,
Dialog,
DialogActions,
DialogContent,
DialogContentText,
DialogTitle,
} from '@mui/material';
import { useEffect, useState } from 'react';
import React from 'react';

import { apiSharedLink } from '@/app/utils/api.class';
import { uuid } from '@/app/utils/helpers';
import { SHLinkMiniDto } from '@/domain/dtos/shlink';

import { AddLinkDialog } from './AddLinkDialog';
import BooleanIcon from './BooleanIcon';
import ConfirmationDialog from './ConfirmationDialog';
import { QRCodeDialog } from './QRCodeDialog';

interface Column {
id: keyof SHLinkMiniDto;
Expand All @@ -40,20 +37,26 @@ interface Column {
) => string | React.JSX.Element;
}

interface IActionColumn extends Omit<Column, 'id' | 'label'> {
interface IActionColumns extends Omit<Column, 'id' | 'label'> {
id: 'action';
label: React.JSX.Element;
action: (id: string) => void;
action: (row: SHLinkMiniDto) => void;
tooltipTitle?: string;
isDisabled?: (row: SHLinkMiniDto) => boolean;
}

const createActionColumn = (
label: React.JSX.Element,
action: (id: string) => void,
): IActionColumn => ({
action: (row: SHLinkMiniDto) => void,
tooltipTitle?: string,
isDisabled?: (row: SHLinkMiniDto) => boolean,
): IActionColumns => ({
id: 'action',
label,
minWidth: 50,
action,
tooltipTitle,
isDisabled,
});

const columns: readonly Column[] = [
Expand Down Expand Up @@ -90,12 +93,19 @@ export default function LinksTable() {
const [confirmDialogOpen, setConfirmDialogOpen] = useState(false);
const [selectedLinkId, setSelectedLinkId] = useState<string | null>(null);

const [qrCodeDialogOpen, setQrCodeDialogOpen] = useState(false);
const [qrCodeData, setQrCodeData] = useState<{
id: string;
managementToken: string;
url: string;
}>();

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

const handleDeactivate = async (id: string) => {
setSelectedLinkId(id);
const handleDeactivate = async (row: SHLinkMiniDto) => {
setSelectedLinkId(row.id);
setConfirmDialogOpen(true);
};

Expand All @@ -110,10 +120,19 @@ export default function LinksTable() {
}
}
};
const handleQrCode = async (row: SHLinkMiniDto) => {
setQrCodeDialogOpen(true);
setQrCodeData({ id: row.id, managementToken: '', url: row.url });
};

const actionColumn: IActionColumn[] = [
createActionColumn(<LinkOffIcon />, handleDeactivate),
// TODO: Other actions will be added
const actionColumns: IActionColumns[] = [
createActionColumn(
<LinkOffIcon />,
handleDeactivate,
'Deactivate',
(row) => row.active,
),
createActionColumn(<QrCode />, handleQrCode, 'Show QR Code'),
];

const fetchLinks = async () => {
Expand All @@ -136,8 +155,6 @@ export default function LinksTable() {
setAddDialog(true);
};

const combinedCols = [...columns, ...actionColumn];

return (
<Paper sx={{ width: '100%', overflow: 'hidden' }}>
<AddLinkDialog
Expand All @@ -150,6 +167,15 @@ export default function LinksTable() {
});
}}
/>
{qrCodeDialogOpen && (
<QRCodeDialog
open={qrCodeDialogOpen}
data={qrCodeData}
onClose={() => {
setQrCodeDialogOpen(false);
}}
/>
)}
<Grid container justifyContent="end">
<Grid item>
<Button variant="contained" onClick={handleCreateLink}>
Expand Down Expand Up @@ -178,32 +204,33 @@ export default function LinksTable() {
.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage)
.map((row) => (
<TableRow hover tabIndex={-1} key={row.id}>
{combinedCols.map((column) => {
{columns.map((column) => {
const value = row[column.id];
return (
<TableCell
key={column.id + row.active}
align={column.align}
>
{column.id === 'action' ? (
<Tooltip title="Deactivate">
<span>
<Button
disabled={!row.active}
onClick={() => column.action(row.id)}
>
{column.label}
</Button>
</span>
</Tooltip>
) : column.format ? (
column.format(value)
) : (
value?.toString()
)}
{column.format
? column.format(value)
: value?.toString()}
</TableCell>
);
})}
<TableCell width={200}>
{actionColumns.map((actionColumn) => (
<Tooltip key={uuid()} title={actionColumn.tooltipTitle}>
<span>
<Button
disabled={actionColumn.isDisabled?.(row)}
onClick={() => actionColumn.action(row)}
>
{actionColumn.label}
</Button>
</span>
</Tooltip>
))}
</TableCell>
</TableRow>
))}
</TableBody>
Expand Down
Loading

0 comments on commit 022e9bb

Please sign in to comment.