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": {
|
"@strimertul/kilovolt-client": {
|
||||||
"version": "3.0.0",
|
"version": "4.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@strimertul/kilovolt-client/-/kilovolt-client-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/@strimertul/kilovolt-client/-/kilovolt-client-4.1.0.tgz",
|
||||||
"integrity": "sha512-jzm5gTJsxAJxkkDgpPsCttDwgN1wF3c1pPneE3drFIoI7+oRnXQsiWIsA6VZBYoVamitn4CcQHMK1eKAYGkxrQ==",
|
"integrity": "sha512-krobLL0IsXAm5gIw9uswnBDKX/mV5bpYp8bom4IJCrZLsd8QGUsMB3yd3ukS0Sxm7R5p0oXW91XbrqMixvgUHA==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@billjs/event-emitter": "^1.0.3"
|
"@billjs/event-emitter": "^1.0.3"
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
"@billjs/event-emitter": "^1.0.3",
|
"@billjs/event-emitter": "^1.0.3",
|
||||||
"@reach/router": "^1.3.4",
|
"@reach/router": "^1.3.4",
|
||||||
"@reduxjs/toolkit": "^1.5.1",
|
"@reduxjs/toolkit": "^1.5.1",
|
||||||
"@strimertul/kilovolt-client": "^3.0.0",
|
"@strimertul/kilovolt-client": "^4.1.0",
|
||||||
"@types/node": "^15.0.2",
|
"@types/node": "^15.0.2",
|
||||||
"@types/reach__router": "^1.3.7",
|
"@types/reach__router": "^1.3.7",
|
||||||
"@types/react": "^17.0.5",
|
"@types/react": "^17.0.5",
|
||||||
|
|
|
@ -29,9 +29,9 @@ export function useModule<T>({
|
||||||
const subscriber = (newValue) => {
|
const subscriber = (newValue) => {
|
||||||
dispatch(asyncSetter(JSON.parse(newValue) as T));
|
dispatch(asyncSetter(JSON.parse(newValue) as T));
|
||||||
};
|
};
|
||||||
client.subscribe(key, subscriber);
|
client.subscribeKey(key, subscriber);
|
||||||
return () => {
|
return () => {
|
||||||
client.unsubscribe(key, subscriber);
|
client.unsubscribeKey(key, subscriber);
|
||||||
};
|
};
|
||||||
}, []);
|
}, []);
|
||||||
return [data, setter];
|
return [data, setter];
|
||||||
|
|
|
@ -17,7 +17,7 @@ const twitchConfigKey = 'twitch/config';
|
||||||
const twitchBotConfigKey = 'twitch/bot-config';
|
const twitchBotConfigKey = 'twitch/bot-config';
|
||||||
const stulbeConfigKey = 'stulbe/config';
|
const stulbeConfigKey = 'stulbe/config';
|
||||||
const loyaltyConfigKey = 'loyalty/config';
|
const loyaltyConfigKey = 'loyalty/config';
|
||||||
const loyaltyStorageKey = 'loyalty/users';
|
const loyaltyPointsPrefix = 'loyalty/points/';
|
||||||
const loyaltyRewardsKey = 'loyalty/rewards';
|
const loyaltyRewardsKey = 'loyalty/rewards';
|
||||||
const loyaltyGoalsKey = 'loyalty/goals';
|
const loyaltyGoalsKey = 'loyalty/goals';
|
||||||
const loyaltyRedeemQueueKey = 'loyalty/redeem-queue';
|
const loyaltyRedeemQueueKey = 'loyalty/redeem-queue';
|
||||||
|
@ -68,7 +68,11 @@ interface LoyaltyConfig {
|
||||||
banlist: string[];
|
banlist: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export type LoyaltyStorage = Record<string, number>;
|
interface LoyaltyPointsEntry {
|
||||||
|
points: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type LoyaltyStorage = Record<string, LoyaltyPointsEntry>;
|
||||||
|
|
||||||
export interface LoyaltyReward {
|
export interface LoyaltyReward {
|
||||||
enabled: boolean;
|
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 = {
|
export const modules = {
|
||||||
moduleConfig: makeModule<ModuleConfig>(
|
moduleConfig: makeModule<ModuleConfig>(
|
||||||
moduleConfigKey,
|
moduleConfigKey,
|
||||||
|
@ -242,13 +260,6 @@ export const modules = {
|
||||||
state.moduleConfigs.loyaltyConfig = payload;
|
state.moduleConfigs.loyaltyConfig = payload;
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
loyaltyStorage: makeModule<LoyaltyStorage>(
|
|
||||||
loyaltyStorageKey,
|
|
||||||
(state) => state.loyalty.users,
|
|
||||||
(state, { payload }) => {
|
|
||||||
state.loyalty.users = payload;
|
|
||||||
},
|
|
||||||
),
|
|
||||||
loyaltyRewards: makeModule<LoyaltyReward[]>(
|
loyaltyRewards: makeModule<LoyaltyReward[]>(
|
||||||
loyaltyRewardsKey,
|
loyaltyRewardsKey,
|
||||||
(state) => state.loyalty.rewards,
|
(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(
|
export const createRedeem = createAsyncThunk(
|
||||||
'api/createRedeem',
|
'api/createRedeem',
|
||||||
async (redeem: LoyaltyRedeem, { getState }) => {
|
async (redeem: LoyaltyRedeem, { getState }) => {
|
||||||
|
@ -339,9 +327,6 @@ const apiReducer = createSlice({
|
||||||
loyaltyConfigChanged(state, { payload }: PayloadAction<LoyaltyConfig>) {
|
loyaltyConfigChanged(state, { payload }: PayloadAction<LoyaltyConfig>) {
|
||||||
state.moduleConfigs.loyaltyConfig = payload;
|
state.moduleConfigs.loyaltyConfig = payload;
|
||||||
},
|
},
|
||||||
loyaltyStorageChanged(state, { payload }: PayloadAction<LoyaltyStorage>) {
|
|
||||||
state.loyalty.users = payload;
|
|
||||||
},
|
|
||||||
loyaltyRewardsChanged(state, { payload }: PayloadAction<LoyaltyReward[]>) {
|
loyaltyRewardsChanged(state, { payload }: PayloadAction<LoyaltyReward[]>) {
|
||||||
state.loyalty.rewards = payload;
|
state.loyalty.rewards = payload;
|
||||||
},
|
},
|
||||||
|
@ -354,6 +339,9 @@ const apiReducer = createSlice({
|
||||||
state.client = payload;
|
state.client = payload;
|
||||||
state.connected = true;
|
state.connected = true;
|
||||||
});
|
});
|
||||||
|
builder.addCase(getUserPoints.fulfilled, (state, { payload }) => {
|
||||||
|
state.loyalty.users = payload;
|
||||||
|
});
|
||||||
Object.values(modules).forEach((mod) => {
|
Object.values(modules).forEach((mod) => {
|
||||||
builder.addCase(mod.getter.fulfilled, mod.stateSetter);
|
builder.addCase(mod.getter.fulfilled, mod.stateSetter);
|
||||||
builder.addCase(mod.asyncSetter, 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 { RouteComponentProps } from '@reach/router';
|
||||||
import { useModule } from '../../../lib/react-utils';
|
|
||||||
import { modules } from '../../../store/api/reducer';
|
|
||||||
import PageList from '../../components/PageList';
|
import PageList from '../../components/PageList';
|
||||||
|
import { RootState } from '../../../store';
|
||||||
|
import { getUserPoints } from '../../../store/api/reducer';
|
||||||
|
|
||||||
interface SortingOrder {
|
interface SortingOrder {
|
||||||
key: 'user' | 'points';
|
key: 'user' | 'points';
|
||||||
|
@ -12,13 +13,17 @@ export default function LoyaltyUserListPage(
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
props: RouteComponentProps<unknown>,
|
props: RouteComponentProps<unknown>,
|
||||||
): React.ReactElement {
|
): React.ReactElement {
|
||||||
const [users] = useModule(modules.loyaltyStorage);
|
const users = useSelector((state: RootState) => state.api.loyalty.users);
|
||||||
|
const dispatch = useDispatch();
|
||||||
const [sorting, setSorting] = useState<SortingOrder>({
|
const [sorting, setSorting] = useState<SortingOrder>({
|
||||||
key: 'points',
|
key: 'points',
|
||||||
order: 'desc',
|
order: 'desc',
|
||||||
});
|
});
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
dispatch(getUserPoints());
|
||||||
|
}, []);
|
||||||
|
|
||||||
const [entriesPerPage, setEntriesPerPage] = useState(15);
|
const [entriesPerPage, setEntriesPerPage] = useState(15);
|
||||||
const [page, setPage] = useState(0);
|
const [page, setPage] = useState(0);
|
||||||
const [usernameFilter, setUsernameFilter] = useState('');
|
const [usernameFilter, setUsernameFilter] = useState('');
|
||||||
|
@ -51,10 +56,10 @@ export default function LoyaltyUserListPage(
|
||||||
case 'points':
|
case 'points':
|
||||||
if (sorting.order === 'asc') {
|
if (sorting.order === 'asc') {
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
// 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 {
|
} else {
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
// 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;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -120,10 +125,10 @@ export default function LoyaltyUserListPage(
|
||||||
</thead>
|
</thead>
|
||||||
|
|
||||||
<tbody>
|
<tbody>
|
||||||
{paged.map(([user, points]) => (
|
{paged.map(([user, p]) => (
|
||||||
<tr key={user}>
|
<tr key={user}>
|
||||||
<td>{user}</td>
|
<td>{user}</td>
|
||||||
<td>{points}</td>
|
<td>{p.points}</td>
|
||||||
<td></td>
|
<td></td>
|
||||||
</tr>
|
</tr>
|
||||||
))}
|
))}
|
||||||
|
|
Loading…
Reference in a new issue