mirror of
https://git.sr.ht/~ashkeel/strimertul
synced 2024-09-20 02:00:49 +00:00
Update UI to use kilovolt v4 and new loyalty key
This commit is contained in:
parent
70f515dae7
commit
ec7f882beb
5 changed files with 43 additions and 50 deletions
6
frontend/package-lock.json
generated
6
frontend/package-lock.json
generated
|
@ -2274,9 +2274,9 @@
|
|||
}
|
||||
},
|
||||
"@strimertul/kilovolt-client": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@strimertul/kilovolt-client/-/kilovolt-client-3.0.0.tgz",
|
||||
"integrity": "sha512-jzm5gTJsxAJxkkDgpPsCttDwgN1wF3c1pPneE3drFIoI7+oRnXQsiWIsA6VZBYoVamitn4CcQHMK1eKAYGkxrQ==",
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@strimertul/kilovolt-client/-/kilovolt-client-4.1.0.tgz",
|
||||
"integrity": "sha512-krobLL0IsXAm5gIw9uswnBDKX/mV5bpYp8bom4IJCrZLsd8QGUsMB3yd3ukS0Sxm7R5p0oXW91XbrqMixvgUHA==",
|
||||
"requires": {
|
||||
"@billjs/event-emitter": "^1.0.3"
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
"@billjs/event-emitter": "^1.0.3",
|
||||
"@reach/router": "^1.3.4",
|
||||
"@reduxjs/toolkit": "^1.5.1",
|
||||
"@strimertul/kilovolt-client": "^3.0.0",
|
||||
"@strimertul/kilovolt-client": "^4.1.0",
|
||||
"@types/node": "^15.0.2",
|
||||
"@types/reach__router": "^1.3.7",
|
||||
"@types/react": "^17.0.5",
|
||||
|
|
|
@ -29,9 +29,9 @@ export function useModule<T>({
|
|||
const subscriber = (newValue) => {
|
||||
dispatch(asyncSetter(JSON.parse(newValue) as T));
|
||||
};
|
||||
client.subscribe(key, subscriber);
|
||||
client.subscribeKey(key, subscriber);
|
||||
return () => {
|
||||
client.unsubscribe(key, subscriber);
|
||||
client.unsubscribeKey(key, subscriber);
|
||||
};
|
||||
}, []);
|
||||
return [data, setter];
|
||||
|
|
|
@ -17,7 +17,7 @@ const twitchConfigKey = 'twitch/config';
|
|||
const twitchBotConfigKey = 'twitch/bot-config';
|
||||
const stulbeConfigKey = 'stulbe/config';
|
||||
const loyaltyConfigKey = 'loyalty/config';
|
||||
const loyaltyStorageKey = 'loyalty/users';
|
||||
const loyaltyPointsPrefix = 'loyalty/points/';
|
||||
const loyaltyRewardsKey = 'loyalty/rewards';
|
||||
const loyaltyGoalsKey = 'loyalty/goals';
|
||||
const loyaltyRedeemQueueKey = 'loyalty/redeem-queue';
|
||||
|
@ -68,7 +68,11 @@ interface LoyaltyConfig {
|
|||
banlist: string[];
|
||||
}
|
||||
|
||||
export type LoyaltyStorage = Record<string, number>;
|
||||
interface LoyaltyPointsEntry {
|
||||
points: number;
|
||||
}
|
||||
|
||||
export type LoyaltyStorage = Record<string, LoyaltyPointsEntry>;
|
||||
|
||||
export interface LoyaltyReward {
|
||||
enabled: boolean;
|
||||
|
@ -199,6 +203,20 @@ export const createWSClient = createAsyncThunk(
|
|||
},
|
||||
);
|
||||
|
||||
export const getUserPoints = createAsyncThunk(
|
||||
'api/getUserPoints',
|
||||
async (_: void, { getState }) => {
|
||||
const { api } = getState() as { api: APIState };
|
||||
const keys = await api.client.getKeysByPrefix(loyaltyPointsPrefix);
|
||||
console.log(keys);
|
||||
const userpoints: LoyaltyStorage = {};
|
||||
Object.entries(keys).forEach(([k, v]) => {
|
||||
userpoints[k.substr(loyaltyPointsPrefix.length)] = JSON.parse(v);
|
||||
});
|
||||
return userpoints;
|
||||
},
|
||||
);
|
||||
|
||||
export const modules = {
|
||||
moduleConfig: makeModule<ModuleConfig>(
|
||||
moduleConfigKey,
|
||||
|
@ -242,13 +260,6 @@ export const modules = {
|
|||
state.moduleConfigs.loyaltyConfig = payload;
|
||||
},
|
||||
),
|
||||
loyaltyStorage: makeModule<LoyaltyStorage>(
|
||||
loyaltyStorageKey,
|
||||
(state) => state.loyalty.users,
|
||||
(state, { payload }) => {
|
||||
state.loyalty.users = payload;
|
||||
},
|
||||
),
|
||||
loyaltyRewards: makeModule<LoyaltyReward[]>(
|
||||
loyaltyRewardsKey,
|
||||
(state) => state.loyalty.rewards,
|
||||
|
@ -272,29 +283,6 @@ export const modules = {
|
|||
),
|
||||
};
|
||||
|
||||
export const setUserPoints = createAsyncThunk(
|
||||
'api/setUserPoints',
|
||||
async (
|
||||
{
|
||||
user,
|
||||
points,
|
||||
relative,
|
||||
}: { user: string; points: number; relative: boolean },
|
||||
{ getState, dispatch },
|
||||
) => {
|
||||
const { api } = getState() as { api: APIState };
|
||||
const newAmount = relative
|
||||
? (api.loyalty.users[user] ?? 0) + points
|
||||
: points;
|
||||
return dispatch(
|
||||
modules.loyaltyStorage.setter({
|
||||
...api.loyalty.users,
|
||||
[user]: newAmount,
|
||||
}),
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
export const createRedeem = createAsyncThunk(
|
||||
'api/createRedeem',
|
||||
async (redeem: LoyaltyRedeem, { getState }) => {
|
||||
|
@ -339,9 +327,6 @@ const apiReducer = createSlice({
|
|||
loyaltyConfigChanged(state, { payload }: PayloadAction<LoyaltyConfig>) {
|
||||
state.moduleConfigs.loyaltyConfig = payload;
|
||||
},
|
||||
loyaltyStorageChanged(state, { payload }: PayloadAction<LoyaltyStorage>) {
|
||||
state.loyalty.users = payload;
|
||||
},
|
||||
loyaltyRewardsChanged(state, { payload }: PayloadAction<LoyaltyReward[]>) {
|
||||
state.loyalty.rewards = payload;
|
||||
},
|
||||
|
@ -354,6 +339,9 @@ const apiReducer = createSlice({
|
|||
state.client = payload;
|
||||
state.connected = true;
|
||||
});
|
||||
builder.addCase(getUserPoints.fulfilled, (state, { payload }) => {
|
||||
state.loyalty.users = payload;
|
||||
});
|
||||
Object.values(modules).forEach((mod) => {
|
||||
builder.addCase(mod.getter.fulfilled, mod.stateSetter);
|
||||
builder.addCase(mod.asyncSetter, mod.stateSetter);
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
import React, { useState } from 'react';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import { RouteComponentProps } from '@reach/router';
|
||||
import { useModule } from '../../../lib/react-utils';
|
||||
import { modules } from '../../../store/api/reducer';
|
||||
import PageList from '../../components/PageList';
|
||||
import { RootState } from '../../../store';
|
||||
import { getUserPoints } from '../../../store/api/reducer';
|
||||
|
||||
interface SortingOrder {
|
||||
key: 'user' | 'points';
|
||||
|
@ -12,13 +13,17 @@ export default function LoyaltyUserListPage(
|
|||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
props: RouteComponentProps<unknown>,
|
||||
): React.ReactElement {
|
||||
const [users] = useModule(modules.loyaltyStorage);
|
||||
|
||||
const users = useSelector((state: RootState) => state.api.loyalty.users);
|
||||
const dispatch = useDispatch();
|
||||
const [sorting, setSorting] = useState<SortingOrder>({
|
||||
key: 'points',
|
||||
order: 'desc',
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
dispatch(getUserPoints());
|
||||
}, []);
|
||||
|
||||
const [entriesPerPage, setEntriesPerPage] = useState(15);
|
||||
const [page, setPage] = useState(0);
|
||||
const [usernameFilter, setUsernameFilter] = useState('');
|
||||
|
@ -51,10 +56,10 @@ export default function LoyaltyUserListPage(
|
|||
case 'points':
|
||||
if (sorting.order === 'asc') {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
sortedEntries.sort(([_a, pointsA], [_b, pointsB]) => pointsA - pointsB);
|
||||
sortedEntries.sort(([_a, a], [_b, b]) => a.points - b.points);
|
||||
} else {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
sortedEntries.sort(([_a, pointsA], [_b, pointsB]) => pointsB - pointsA);
|
||||
sortedEntries.sort(([_a, a], [_b, b]) => b.points - a.points);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
@ -120,10 +125,10 @@ export default function LoyaltyUserListPage(
|
|||
</thead>
|
||||
|
||||
<tbody>
|
||||
{paged.map(([user, points]) => (
|
||||
{paged.map(([user, p]) => (
|
||||
<tr key={user}>
|
||||
<td>{user}</td>
|
||||
<td>{points}</td>
|
||||
<td>{p.points}</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
))}
|
||||
|
|
Loading…
Reference in a new issue