import React, { useState } from 'react'; import { useTranslation } from 'react-i18next'; import { useModule, useUserPoints } from '~/lib/react'; import { SortFunction } from '~/lib/types'; import { useAppDispatch } from '~/store'; import { modules, removeRedeem, setUserPoints } from '~/store/api/reducer'; import { LoyaltyRedeem } from '~/store/api/types'; import { DataTable } from '../../components/DataTable'; import DialogContent from '../../components/DialogContent'; import { Button, Dialog, DialogActions, Field, FlexRow, InputBox, Label, NoneText, PageContainer, PageHeader, PageTitle, TabButton, TabContainer, TabContent, TabList, TextBlock, } from '../../theme'; import { TableCell, TableRow } from '../../theme/table'; function RewardQueueRow({ data }: { data: LoyaltyRedeem & { date: Date } }) { const dispatch = useAppDispatch(); const { t } = useTranslation(); return ( {data.date.toLocaleString()} {data.username} {data.reward?.name} {data.request_text} ); } function RewardQueue() { const { t } = useTranslation(); const [queue] = useModule(modules.loyaltyRedeemQueue); // Big hack but this is required or refunds break useUserPoints(); const data = queue?.map((q) => ({ ...q, date: new Date(q.when) })) ?? []; type Redeem = (typeof data)[0]; const sortfn = (key: keyof Redeem) => (a: Redeem, b: Redeem) => { switch (key) { case 'display_name': { return a.display_name?.localeCompare(b.display_name); } case 'when': { return a.date && b.date ? a.date.getTime() - b.date.getTime() : 0; } case 'reward': { return a.reward?.name?.localeCompare(b.reward.name); } default: return 0; } }; return ( <> {(data.length > 0 && ( `${d.when.toString()}/${d.username}`} columns={[ { key: 'when', title: t('pages.loyalty-queue.date'), sortable: true, }, { key: 'username', title: t('pages.loyalty-queue.username'), sortable: true, }, { key: 'reward', title: t('pages.loyalty-queue.reward'), sortable: true, attr: { style: { textTransform: 'capitalize', }, }, }, { key: 'request_text', title: t('pages.loyalty-queue.request'), sortable: false, attr: { style: { width: '100%', textAlign: 'left', }, }, }, { key: 'actions', title: '', sortable: false, }, ]} defaultSort={{ key: 'when', order: 'desc' }} rowComponent={RewardQueueRow} /> )) || {t('pages.loyalty-queue.no-redeems')}} ); } function UserList() { const { t } = useTranslation(); const users = useUserPoints(); const dispatch = useAppDispatch(); const [currentEntry, setCurrentEntry] = useState(null); const [givePointDialog, setGivePointDialog] = useState({ open: false, user: '', points: 0, }); const [config] = useModule(modules.loyaltyConfig); const [usernameFilter, setUsernameFilter] = useState(''); const filtered = Object.entries(users ?? []) .filter(([user]) => user.includes(usernameFilter)) .map(([username, data]) => ({ username, ...data, })); type UserEntry = (typeof filtered)[0]; const sortfn = (key: keyof UserEntry): SortFunction => { switch (key) { case 'username': { return (a, b) => a.username.localeCompare(b.username); } case 'points': { return (a: UserEntry, b: UserEntry) => a.points - b.points; } } }; const UserListRow = ({ data }: { data: UserEntry }) => ( {data.username} {data.points} ); return ( <> setGivePointDialog({ ...givePointDialog, open: state }) } >
{ e.preventDefault(); if ((e.target as HTMLFormElement).checkValidity()) { void dispatch( setUserPoints({ ...givePointDialog, user: givePointDialog.user.toLowerCase(), relative: true, }), ); setGivePointDialog({ ...givePointDialog, open: false }); } }} > setGivePointDialog({ ...givePointDialog, user: e.target.value, }) } /> setGivePointDialog({ ...givePointDialog, points: parseInt(e.target.value, 10), }) } />
setCurrentEntry(state ? currentEntry : null)} >
{ e.preventDefault(); if ((e.target as HTMLFormElement).checkValidity()) { void dispatch( setUserPoints({ user: currentEntry.username.toLowerCase(), points: currentEntry.points, relative: false, }), ); setCurrentEntry(null); } }} > setCurrentEntry({ ...currentEntry, points: parseInt(e.target.value, 10), }) } />
setUsernameFilter(e.target.value)} /> {(filtered.length > 0 && ( entry.username} columns={[ { key: 'username', title: t('pages.loyalty-queue.username'), sortable: true, attr: { style: { width: '100%', textAlign: 'left', }, }, }, { key: 'points', title: config?.currency || t('pages.loyalty-queue.points'), sortable: true, attr: { style: { textTransform: 'capitalize', }, }, }, { key: 'actions', title: '', sortable: false, }, ]} defaultSort={{ key: 'points', order: 'desc' }} rowComponent={UserListRow} /> )) || {t('pages.loyalty-queue.no-users')}} ); } export default function LoyaltyQueuePage(): React.ReactElement { const { t } = useTranslation(); return ( {t('pages.loyalty-queue.title')} {t('pages.loyalty-queue.subtitle')} {t('pages.loyalty-queue.queue-tab')} {t('pages.loyalty-queue.users-tab')} ); }