mirror of
https://git.sr.ht/~ashkeel/strimertul
synced 2024-09-18 01:50:50 +00:00
Add test redeem button
This commit is contained in:
parent
c77d7c7a74
commit
61212f249c
6 changed files with 75 additions and 13 deletions
|
@ -27,8 +27,8 @@
|
|||
],
|
||||
"devDependencies": {
|
||||
"@parcel/transformer-sass": "^2.0.0-beta.2",
|
||||
"@typescript-eslint/eslint-plugin": "^4.6.1",
|
||||
"@typescript-eslint/parser": "^4.6.1",
|
||||
"@typescript-eslint/eslint-plugin": "^4.22.0",
|
||||
"@typescript-eslint/parser": "^4.22.0",
|
||||
"eslint": "^7.12.1",
|
||||
"eslint-config-airbnb-base": "^14.2.0",
|
||||
"eslint-config-prettier": "^6.15.0",
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
export type SubscriptionHandler = (newValue: string) => void;
|
||||
|
||||
export type wsMessage = wsError | wsPush | wsResponse;
|
||||
|
||||
interface wsError {
|
||||
ok: false;
|
||||
error: string;
|
||||
|
@ -21,6 +19,8 @@ interface wsResponse {
|
|||
data?: string;
|
||||
}
|
||||
|
||||
export type wsMessage = wsError | wsPush | wsResponse;
|
||||
|
||||
export default class StrimertulWS {
|
||||
socket: WebSocket;
|
||||
|
||||
|
|
|
@ -245,6 +245,39 @@ 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, dispatch }) => {
|
||||
const { api } = getState() as { api: APIState };
|
||||
return dispatch(
|
||||
modules.loyaltyRedeemQueue.setter([...api.loyalty.redeemQueue, redeem]),
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
const apiReducer = createSlice({
|
||||
name: 'api',
|
||||
initialState,
|
||||
|
|
|
@ -2,7 +2,11 @@ import React, { useState } from 'react';
|
|||
import { useDispatch } from 'react-redux';
|
||||
import { RouteComponentProps } from '@reach/router';
|
||||
import { useModule } from '../../../lib/react-utils';
|
||||
import { LoyaltyRedeem, modules } from '../../../store/api/reducer';
|
||||
import {
|
||||
LoyaltyRedeem,
|
||||
modules,
|
||||
setUserPoints,
|
||||
} from '../../../store/api/reducer';
|
||||
import PageList from '../../components/PageList';
|
||||
|
||||
interface SortingOrder {
|
||||
|
@ -15,7 +19,6 @@ export default function LoyaltyRedeemQueuePage(
|
|||
props: RouteComponentProps<unknown>,
|
||||
): React.ReactElement {
|
||||
const [redemptions, setRedeemQueue] = useModule(modules.loyaltyRedeemQueue);
|
||||
const [points, setPoints] = useModule(modules.loyaltyStorage);
|
||||
|
||||
const [sorting, setSorting] = useState<SortingOrder>({
|
||||
key: 'when',
|
||||
|
@ -86,9 +89,10 @@ export default function LoyaltyRedeemQueuePage(
|
|||
const refundRedeem = (redeem: LoyaltyRedeem) => {
|
||||
// Give points back to the viewer
|
||||
dispatch(
|
||||
setPoints({
|
||||
...points,
|
||||
[redeem.username]: (points[redeem.username] ?? 0) + redeem.reward.price,
|
||||
setUserPoints({
|
||||
user: redeem.username,
|
||||
points: redeem.reward.price,
|
||||
relative: true,
|
||||
}),
|
||||
);
|
||||
// Take the redeem off the list
|
||||
|
@ -157,8 +161,12 @@ export default function LoyaltyRedeemQueuePage(
|
|||
<td>{redemption.reward.name}</td>
|
||||
<td style={{ textAlign: 'right' }}>
|
||||
<a onClick={() => acceptRedeem(redemption)}>Accept</a>
|
||||
{redemption.username !== '@PLATFORM' ? (
|
||||
<>
|
||||
{' 🞄 '}
|
||||
<a onClick={() => refundRedeem(redemption)}>Refund</a>
|
||||
</>
|
||||
) : null}
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
|
|
|
@ -3,7 +3,11 @@ import React, { useState } from 'react';
|
|||
import { useSelector, useDispatch } from 'react-redux';
|
||||
import { useModule } from '../../../lib/react-utils';
|
||||
import { RootState } from '../../../store';
|
||||
import { LoyaltyReward, modules } from '../../../store/api/reducer';
|
||||
import {
|
||||
createRedeem,
|
||||
LoyaltyReward,
|
||||
modules,
|
||||
} from '../../../store/api/reducer';
|
||||
import Modal from '../../components/Modal';
|
||||
|
||||
interface RewardItemProps {
|
||||
|
@ -11,12 +15,14 @@ interface RewardItemProps {
|
|||
onToggleState: () => void;
|
||||
onEdit: () => void;
|
||||
onDelete: () => void;
|
||||
onTest: () => void;
|
||||
}
|
||||
function RewardItem({
|
||||
item,
|
||||
onToggleState,
|
||||
onEdit,
|
||||
onDelete,
|
||||
onTest,
|
||||
}: RewardItemProps) {
|
||||
const currency = useSelector(
|
||||
(state: RootState) =>
|
||||
|
@ -71,6 +77,9 @@ function RewardItem({
|
|||
</>
|
||||
) : null}
|
||||
<div style={{ marginTop: '1rem' }}>
|
||||
<a className="button is-small" onClick={onTest}>
|
||||
Test
|
||||
</a>{' '}
|
||||
<a className="button is-small" onClick={onToggleState}>
|
||||
{item.enabled ? 'Disable' : 'Enable'}
|
||||
</a>{' '}
|
||||
|
@ -358,6 +367,17 @@ export default function LoyaltyRewardsPage(
|
|||
dispatch(setRewards(rewards.filter((entry) => entry.id !== rewardID)));
|
||||
};
|
||||
|
||||
const testRedeem = (reward: LoyaltyReward) => {
|
||||
dispatch(
|
||||
createRedeem({
|
||||
username: '@PLATFORM',
|
||||
display_name: 'me :3',
|
||||
when: new Date(),
|
||||
reward,
|
||||
}),
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<h1 className="title is-4">Loyalty rewards</h1>
|
||||
|
@ -413,6 +433,7 @@ export default function LoyaltyRewardsPage(
|
|||
onDelete={() => deleteReward(reward.id)}
|
||||
onEdit={() => setShowModifyReward(reward)}
|
||||
onToggleState={() => toggleReward(reward.id)}
|
||||
onTest={() => testRedeem(reward)}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
|
|
2
main.go
2
main.go
|
@ -218,6 +218,7 @@ func main() {
|
|||
})
|
||||
if moduleConfig.EnableStaticServer {
|
||||
http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir(httpConfig.Path))))
|
||||
httpLogger(logger.MTNotice, "serving %s", httpConfig.Path)
|
||||
}
|
||||
|
||||
go func() {
|
||||
|
@ -226,7 +227,6 @@ func main() {
|
|||
}()
|
||||
|
||||
// Start HTTP server
|
||||
httpLogger(logger.MTNotice, "serving %s", httpConfig.Path)
|
||||
fatalError(http.ListenAndServe(httpConfig.Bind, nil), "HTTP server died unexepectedly")
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue