mirror of
https://git.sr.ht/~ashkeel/strimertul
synced 2024-09-18 01:50:50 +00:00
refactor: fix code smells
This commit is contained in:
parent
bc6c76c581
commit
4eac451432
7 changed files with 104 additions and 68 deletions
|
@ -39,8 +39,10 @@ function log(level: string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function start() {
|
function start() {
|
||||||
if (!extFn || !kv || extensionStatus !== ExtensionStatus.Ready)
|
if (!extFn || !kv || extensionStatus !== ExtensionStatus.Ready) {
|
||||||
throw new Error('extension not ready');
|
throw new Error('extension not ready');
|
||||||
|
}
|
||||||
|
|
||||||
void extFn(kv)
|
void extFn(kv)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
setStatus(ExtensionStatus.Finished);
|
setStatus(ExtensionStatus.Finished);
|
||||||
|
@ -51,6 +53,7 @@ function start() {
|
||||||
error,
|
error,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
setStatus(ExtensionStatus.Running);
|
setStatus(ExtensionStatus.Running);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -178,7 +178,9 @@ function RecoveryDialog({ open, onOpenChange }: RecoveryDialogProps) {
|
||||||
defaultOpen={true}
|
defaultOpen={true}
|
||||||
open={open}
|
open={open}
|
||||||
onOpenChange={(state) => {
|
onOpenChange={(state) => {
|
||||||
if (onOpenChange) onOpenChange(state);
|
if (onOpenChange) {
|
||||||
|
onOpenChange(state);
|
||||||
|
}
|
||||||
setRestored('idle');
|
setRestored('idle');
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
@ -188,7 +190,9 @@ function RecoveryDialog({ open, onOpenChange }: RecoveryDialogProps) {
|
||||||
description={t('pages.crash.recovery.restore-succeeded-body')}
|
description={t('pages.crash.recovery.restore-succeeded-body')}
|
||||||
actionText={t('form-actions.ok')}
|
actionText={t('form-actions.ok')}
|
||||||
onAction={() => {
|
onAction={() => {
|
||||||
if (onOpenChange) onOpenChange(false);
|
if (onOpenChange) {
|
||||||
|
onOpenChange(false);
|
||||||
|
}
|
||||||
setRestored('idle');
|
setRestored('idle');
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
@ -202,7 +206,9 @@ function RecoveryDialog({ open, onOpenChange }: RecoveryDialogProps) {
|
||||||
defaultOpen={false}
|
defaultOpen={false}
|
||||||
open={!!restoreError}
|
open={!!restoreError}
|
||||||
onOpenChange={(val: boolean) => {
|
onOpenChange={(val: boolean) => {
|
||||||
if (!val) setRestoreError(null);
|
if (!val) {
|
||||||
|
setRestoreError(null);
|
||||||
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<AlertContent
|
<AlertContent
|
||||||
|
@ -220,7 +226,9 @@ function RecoveryDialog({ open, onOpenChange }: RecoveryDialogProps) {
|
||||||
<Dialog
|
<Dialog
|
||||||
open={open}
|
open={open}
|
||||||
onOpenChange={(state) => {
|
onOpenChange={(state) => {
|
||||||
if (onOpenChange) onOpenChange(state);
|
if (onOpenChange) {
|
||||||
|
onOpenChange(state);
|
||||||
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<DialogContent
|
<DialogContent
|
||||||
|
@ -315,7 +323,9 @@ function ReportDialog({ open, onOpenChange, errorData }: ReportDialogProps) {
|
||||||
<Alert
|
<Alert
|
||||||
open={open}
|
open={open}
|
||||||
onOpenChange={(state) => {
|
onOpenChange={(state) => {
|
||||||
if (onOpenChange) onOpenChange(state);
|
if (onOpenChange) {
|
||||||
|
onOpenChange(state);
|
||||||
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<AlertContent
|
<AlertContent
|
||||||
|
@ -353,7 +363,9 @@ function ReportDialog({ open, onOpenChange, errorData }: ReportDialogProps) {
|
||||||
defaultOpen={false}
|
defaultOpen={false}
|
||||||
open={!!submissionError}
|
open={!!submissionError}
|
||||||
onOpenChange={(val: boolean) => {
|
onOpenChange={(val: boolean) => {
|
||||||
if (!val) setSubmissionError(null);
|
if (!val) {
|
||||||
|
setSubmissionError(null);
|
||||||
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<AlertContent
|
<AlertContent
|
||||||
|
@ -370,7 +382,9 @@ function ReportDialog({ open, onOpenChange, errorData }: ReportDialogProps) {
|
||||||
<Dialog
|
<Dialog
|
||||||
open={open}
|
open={open}
|
||||||
onOpenChange={(state) => {
|
onOpenChange={(state) => {
|
||||||
if (onOpenChange) onOpenChange(state);
|
if (onOpenChange) {
|
||||||
|
onOpenChange(state);
|
||||||
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<DialogContent
|
<DialogContent
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { ChevronDownIcon, ChevronUpIcon } from '@radix-ui/react-icons';
|
import { ChevronDownIcon, ChevronUpIcon } from '@radix-ui/react-icons';
|
||||||
import React, { useState } from 'react';
|
import React, { ReactElement, useState } from 'react';
|
||||||
import { SortFunction } from '~/lib/types';
|
import { SortFunction } from '~/lib/types';
|
||||||
import { styled } from '../theme';
|
import { styled } from '../theme';
|
||||||
import { Table, TableHeader } from '../theme/table';
|
import { Table, TableHeader } from '../theme/table';
|
||||||
|
@ -26,7 +26,7 @@ export interface DataTableProps<T> {
|
||||||
}
|
}
|
||||||
))[];
|
))[];
|
||||||
defaultSort: SortingOrder<T>;
|
defaultSort: SortingOrder<T>;
|
||||||
view: (data: T) => React.ReactNode;
|
rowComponent: (data: { data: T }) => ReactElement;
|
||||||
sort: (key: keyof T) => SortFunction<T>;
|
sort: (key: keyof T) => SortFunction<T>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ export function DataTable<T>({
|
||||||
columns,
|
columns,
|
||||||
defaultSort,
|
defaultSort,
|
||||||
sort,
|
sort,
|
||||||
view,
|
rowComponent,
|
||||||
}: DataTableProps<T>): React.ReactElement {
|
}: DataTableProps<T>): React.ReactElement {
|
||||||
const [entriesPerPage, setEntriesPerPage] = useState(15);
|
const [entriesPerPage, setEntriesPerPage] = useState(15);
|
||||||
const [page, setPage] = useState(0);
|
const [page, setPage] = useState(0);
|
||||||
|
@ -83,6 +83,8 @@ export function DataTable<T>({
|
||||||
const paged = sortedEntries.slice(offset, offset + entriesPerPage);
|
const paged = sortedEntries.slice(offset, offset + entriesPerPage);
|
||||||
const totalPages = Math.floor(sortedEntries.length / entriesPerPage);
|
const totalPages = Math.floor(sortedEntries.length / entriesPerPage);
|
||||||
|
|
||||||
|
const RowComponent = rowComponent;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<PageList
|
<PageList
|
||||||
|
@ -115,7 +117,11 @@ export function DataTable<T>({
|
||||||
))}
|
))}
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>{paged.map(view)}</tbody>
|
<tbody>
|
||||||
|
{paged.map((entry) => (
|
||||||
|
<RowComponent data={entry} />
|
||||||
|
))}
|
||||||
|
</tbody>
|
||||||
</Table>
|
</Table>
|
||||||
<PageList
|
<PageList
|
||||||
current={page + 1}
|
current={page + 1}
|
||||||
|
|
|
@ -277,7 +277,7 @@ export function LogItem({ data, expandDefault }: LogItemProps) {
|
||||||
{details.length > 0 && showDetails ? (
|
{details.length > 0 && showDetails ? (
|
||||||
<LogDetails level={levelStyle}>
|
<LogDetails level={levelStyle}>
|
||||||
{details.map(([key, value]) => (
|
{details.map(([key, value]) => (
|
||||||
<LogDetailItem>
|
<LogDetailItem key={key}>
|
||||||
<LogDetailKey level={levelStyle}>{key}</LogDetailKey>
|
<LogDetailKey level={levelStyle}>{key}</LogDetailKey>
|
||||||
<LogDetailValue>{JSON.stringify(value)}</LogDetailValue>
|
<LogDetailValue>{JSON.stringify(value)}</LogDetailValue>
|
||||||
</LogDetailItem>
|
</LogDetailItem>
|
||||||
|
|
|
@ -16,7 +16,9 @@ const ControlledInput = (
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const input = ref.current;
|
const input = ref.current;
|
||||||
if (input) input.setSelectionRange(cursor, cursor);
|
if (input) {
|
||||||
|
input.setSelectionRange(cursor, cursor);
|
||||||
|
}
|
||||||
}, [ref, cursor, value]);
|
}, [ref, cursor, value]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -25,7 +27,9 @@ const ControlledInput = (
|
||||||
value={value}
|
value={value}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
setCursor(e.target.selectionStart);
|
setCursor(e.target.selectionStart);
|
||||||
if (onChange) onChange(e);
|
if (onChange) {
|
||||||
|
onChange(e);
|
||||||
|
}
|
||||||
}}
|
}}
|
||||||
{...rest}
|
{...rest}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -4,6 +4,7 @@ import { useModule, useUserPoints } from '~/lib/react';
|
||||||
import { SortFunction } from '~/lib/types';
|
import { SortFunction } from '~/lib/types';
|
||||||
import { useAppDispatch } from '~/store';
|
import { useAppDispatch } from '~/store';
|
||||||
import { modules, removeRedeem, setUserPoints } from '~/store/api/reducer';
|
import { modules, removeRedeem, setUserPoints } from '~/store/api/reducer';
|
||||||
|
import { LoyaltyRedeem } from '~/store/api/types';
|
||||||
import { DataTable } from '../components/DataTable';
|
import { DataTable } from '../components/DataTable';
|
||||||
import DialogContent from '../components/DialogContent';
|
import DialogContent from '../components/DialogContent';
|
||||||
import {
|
import {
|
||||||
|
@ -26,10 +27,54 @@ import {
|
||||||
} from '../theme';
|
} from '../theme';
|
||||||
import { TableCell, TableRow } from '../theme/table';
|
import { TableCell, TableRow } from '../theme/table';
|
||||||
|
|
||||||
|
function RewardQueueRow({ data }: { data: LoyaltyRedeem & { date: Date } }) {
|
||||||
|
const dispatch = useAppDispatch();
|
||||||
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<TableRow key={`${data.when.toString()}${data.username}`}>
|
||||||
|
<TableCell css={{ width: '22%', fontSize: '0.8rem' }}>
|
||||||
|
{data.date.toLocaleString()}
|
||||||
|
</TableCell>
|
||||||
|
<TableCell css={{ width: '10%' }}>{data.username}</TableCell>
|
||||||
|
<TableCell css={{ width: '18%' }}>{data.reward?.name}</TableCell>
|
||||||
|
<TableCell css={{ width: '40%' }}>{data.request_text}</TableCell>
|
||||||
|
<TableCell>
|
||||||
|
<FlexRow spacing="1">
|
||||||
|
<Button
|
||||||
|
size="small"
|
||||||
|
onClick={() => {
|
||||||
|
void dispatch(removeRedeem(data));
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{t('pages.loyalty-queue.accept')}
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
size="small"
|
||||||
|
onClick={() => {
|
||||||
|
// Give points back to the viewer
|
||||||
|
void dispatch(
|
||||||
|
setUserPoints({
|
||||||
|
user: data.username,
|
||||||
|
points: data.reward.price,
|
||||||
|
relative: true,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
// Take the redeem off the list
|
||||||
|
void dispatch(removeRedeem(data));
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{t('pages.loyalty-queue.refund')}
|
||||||
|
</Button>
|
||||||
|
</FlexRow>
|
||||||
|
</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
function RewardQueue() {
|
function RewardQueue() {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const [queue] = useModule(modules.loyaltyRedeemQueue);
|
const [queue] = useModule(modules.loyaltyRedeemQueue);
|
||||||
const dispatch = useAppDispatch();
|
|
||||||
|
|
||||||
// Big hack but this is required or refunds break
|
// Big hack but this is required or refunds break
|
||||||
useUserPoints();
|
useUserPoints();
|
||||||
|
@ -98,45 +143,7 @@ function RewardQueue() {
|
||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
defaultSort={{ key: 'when', order: 'desc' }}
|
defaultSort={{ key: 'when', order: 'desc' }}
|
||||||
view={(entry) => (
|
rowComponent={RewardQueueRow}
|
||||||
<TableRow key={`${entry.when.toString()}${entry.username}`}>
|
|
||||||
<TableCell css={{ width: '22%', fontSize: '0.8rem' }}>
|
|
||||||
{entry.date.toLocaleString()}
|
|
||||||
</TableCell>
|
|
||||||
<TableCell css={{ width: '10%' }}>{entry.username}</TableCell>
|
|
||||||
<TableCell css={{ width: '18%' }}>{entry.reward?.name}</TableCell>
|
|
||||||
<TableCell css={{ width: '40%' }}>{entry.request_text}</TableCell>
|
|
||||||
<TableCell>
|
|
||||||
<FlexRow spacing="1">
|
|
||||||
<Button
|
|
||||||
size="small"
|
|
||||||
onClick={() => {
|
|
||||||
void dispatch(removeRedeem(entry));
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{t('pages.loyalty-queue.accept')}
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
size="small"
|
|
||||||
onClick={() => {
|
|
||||||
// Give points back to the viewer
|
|
||||||
void dispatch(
|
|
||||||
setUserPoints({
|
|
||||||
user: entry.username,
|
|
||||||
points: entry.reward.price,
|
|
||||||
relative: true,
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
// Take the redeem off the list
|
|
||||||
void dispatch(removeRedeem(entry));
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{t('pages.loyalty-queue.refund')}
|
|
||||||
</Button>
|
|
||||||
</FlexRow>
|
|
||||||
</TableCell>
|
|
||||||
</TableRow>
|
|
||||||
)}
|
|
||||||
/>
|
/>
|
||||||
)) || <NoneText>{t('pages.loyalty-queue.no-redeems')}</NoneText>}
|
)) || <NoneText>{t('pages.loyalty-queue.no-redeems')}</NoneText>}
|
||||||
</>
|
</>
|
||||||
|
@ -175,6 +182,18 @@ function UserList() {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const UserListRow = ({ data }: { data: UserEntry }) => (
|
||||||
|
<TableRow key={data.username}>
|
||||||
|
<TableCell css={{ width: '100%' }}>{data.username}</TableCell>
|
||||||
|
<TableCell>{data.points}</TableCell>
|
||||||
|
<TableCell>
|
||||||
|
<Button onClick={() => setCurrentEntry(data)} size="small">
|
||||||
|
{t('form-actions.edit')}
|
||||||
|
</Button>
|
||||||
|
</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Dialog
|
<Dialog
|
||||||
|
@ -360,17 +379,7 @@ function UserList() {
|
||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
defaultSort={{ key: 'points', order: 'desc' }}
|
defaultSort={{ key: 'points', order: 'desc' }}
|
||||||
view={(entry) => (
|
rowComponent={UserListRow}
|
||||||
<TableRow key={entry.username}>
|
|
||||||
<TableCell css={{ width: '100%' }}>{entry.username}</TableCell>
|
|
||||||
<TableCell>{entry.points}</TableCell>
|
|
||||||
<TableCell>
|
|
||||||
<Button onClick={() => setCurrentEntry(entry)} size="small">
|
|
||||||
{t('form-actions.edit')}
|
|
||||||
</Button>
|
|
||||||
</TableCell>
|
|
||||||
</TableRow>
|
|
||||||
)}
|
|
||||||
/>
|
/>
|
||||||
)) || <NoneText>{t('pages.loyalty-queue.no-users')}</NoneText>}
|
)) || <NoneText>{t('pages.loyalty-queue.no-users')}</NoneText>}
|
||||||
</>
|
</>
|
||||||
|
|
|
@ -361,7 +361,7 @@ function RewardsPage() {
|
||||||
id:
|
id:
|
||||||
e.target.value
|
e.target.value
|
||||||
?.toLowerCase()
|
?.toLowerCase()
|
||||||
.replace(/[^a-zA-Z0-9]/gi, '-') ?? '',
|
.replace(/[^a-z0-9]/gi, '-') ?? '',
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
if (
|
if (
|
||||||
|
@ -685,7 +685,7 @@ function GoalsPage() {
|
||||||
id:
|
id:
|
||||||
e.target.value
|
e.target.value
|
||||||
?.toLowerCase()
|
?.toLowerCase()
|
||||||
.replace(/[^a-zA-Z0-9]/gi, '-') ?? '',
|
.replace(/[^a-z0-9]/gi, '-') ?? '',
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
if (
|
if (
|
||||||
|
|
Loading…
Reference in a new issue