hermes-web/app/(protected)/settings/redemptions/page.tsx

174 lines
6.8 KiB
TypeScript

"use client";
import axios from "axios";
import * as React from 'react';
import { useEffect, useState } from "react";
import { useSession } from "next-auth/react";
import RedeemptionAction from "@/components/elements/redeemable-action";
import OBSRedemption from "@/components/elements/redemption";
import { ActionType } from "@prisma/client";
import InfoNotice from "@/components/elements/info-notice";
const obsTransformations = [
{ label: "scene_name", description: "", placeholder: "Name of the OBS scene" },
{ label: "scene_item_name", description: "", placeholder: "Name of the OBS scene item / source" },
{ label: "rotation", description: "", placeholder: "An expression using x as the previous value" },
{ label: "position_x", description: "", placeholder: "An expression using x as the previous value" },
{ label: "position_y", description: "", placeholder: "An expression using x as the previous value" },
]
const customTwitchRedemptions = [
{
id: 'adbreak',
title: 'Adbreak (TTS redemption)'
},
{
id: 'follow',
title: 'New Follower (TTS redemption)'
},
{
id: 'subscription',
title: 'Subscription (TTS redemption)'
},
{
id: 'subscription.gift',
title: 'Subscription Gifted (TTS redemption)'
},
]
const RedemptionsPage = () => {
const { data: session, status } = useSession();
const [actions, setActions] = useState<{ name: string, type: string, data: any }[]>([])
const [twitchRedemptions, setTwitchRedemptions] = useState<{ id: string, title: string }[]>([])
const [connections, setConnections] = useState<{ name: string, clientId: string, type: string, scope: string, expiresAt: Date }[]>([])
const [redemptions, setRedemptions] = useState<{ id: string, redemptionId: string, actionName: string, order: number }[]>([])
function addAction(name: string, type: ActionType, data: { [key: string]: string }) {
setActions([...actions, { name, type, data }])
}
function removeAction(action: { name: string, type: string, data: any }) {
setActions(actions.filter(a => a.name != action.name))
}
function addRedemption(id: string, actionName: string, redemptionId: string, order: number) {
setRedemptions([...redemptions, { id, redemptionId, actionName, order }])
}
function removeRedemption(redemption: { id: string, redemptionId: string, actionName: string, order: number }) {
setRedemptions(redemptions.filter(r => r.id != redemption.id))
}
useEffect(() => {
if (status !== "authenticated")
return
axios.get('/api/connection')
.then(d => {
setConnections(d.data.data)
})
axios.get("/api/settings/redemptions/actions")
.then(d => {
setActions(d.data)
})
axios.get("/api/account/redemptions")
.then(d => {
let res : { id: string, title: string }[] = d.data?.data ?? []
res = [ ...res, ...customTwitchRedemptions ]
setTwitchRedemptions(res.sort((a, b) => {
if (a.title < b.title)
return -1
else if (a.title > b.title)
return 1
return 0
}))
axios.get("/api/settings/redemptions")
.then(d => {
setRedemptions(d.data)
})
})
}, [session])
return (
<div>
<div className="text-2xl text-center pt-[50px]">Redemption Actions</div>
<InfoNotice
message="Redemption actions are activated when specific Twitch channel point redeems have been activated. Aforementioned redeem need to be linked in the redemption part, together with the action, for the action to activate."
hidden={false} />
{actions.map(action =>
<div
className="px-10 py-3 w-full h-full flex-grow inset-y-1/2"
key={action.name}>
<RedeemptionAction
name={action.name}
type={action.type}
data={action.data}
edit={false}
showEdit={true}
isNew={false}
obsTransformations={obsTransformations}
connections={connections}
adder={addAction}
remover={removeAction} />
</div>
)}
<div
className="px-10 py-3 w-full h-full flex-grow inset-y-1/2">
<RedeemptionAction
name=""
type={undefined}
data={{}}
edit={true}
showEdit={false}
isNew={true}
obsTransformations={obsTransformations}
connections={connections}
adder={addAction}
remover={removeAction} />
</div>
<div className="text-2xl text-center pt-[50px]">Redemptions</div>
<InfoNotice
message="Redemptions are just a way to link specific actions to actual Twitch channel point redeems."
hidden={false} />
{redemptions.map(redemption =>
<div
className="px-10 py-3 w-full h-full flex-grow inset-y-1/2"
key={redemption.id}>
<OBSRedemption
id={redemption.id}
redemptionId={redemption.redemptionId}
actionName={redemption.actionName}
numbering={redemption.order}
edit={false}
showEdit={true}
isNew={false}
actions={actions.map(a => a.name)}
twitchRedemptions={twitchRedemptions}
adder={addRedemption}
remover={removeRedemption} />
</div>
)}
<div
className="px-10 py-3 w-full h-full flex-grow inset-y-1/2">
<OBSRedemption
id={undefined}
redemptionId={undefined}
actionName=""
numbering={0}
edit={true}
showEdit={false}
isNew={true}
actions={actions.map(a => a.name)}
twitchRedemptions={twitchRedemptions}
adder={addRedemption}
remover={removeRedemption} />
</div>
</div>
);
}
export default RedemptionsPage;