aboutsummaryrefslogtreecommitdiffstats
path: root/src/slices/votes.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/slices/votes.ts')
-rw-r--r--src/slices/votes.ts73
1 files changed, 73 insertions, 0 deletions
diff --git a/src/slices/votes.ts b/src/slices/votes.ts
new file mode 100644
index 0000000..87d84e8
--- /dev/null
+++ b/src/slices/votes.ts
@@ -0,0 +1,73 @@
+import { createSlice, PayloadAction } from "@reduxjs/toolkit";
+
+export interface VoteSliceState {
+ votes: Record<string, Record<string, number | null>>;
+}
+
+interface VoteChange {
+ questionId: string;
+ optionId: string;
+ change: 1 | -1;
+}
+
+interface VoteRegister {
+ questionId: string;
+ questionSlugs: string[];
+}
+
+const voteSlice = createSlice({
+ name: "vote",
+ initialState: {
+ votes: {},
+ },
+ reducers: {
+ registerVote: (
+ state: VoteSliceState,
+ action: PayloadAction<VoteRegister>,
+ ) => {
+ state.votes[action.payload.questionId] = {};
+ action.payload.questionSlugs.forEach((value) => {
+ state.votes[action.payload.questionId][value] = null;
+ });
+ },
+ changeVote: (
+ state: VoteSliceState,
+ action: PayloadAction<VoteChange>,
+ ) => {
+ const foundVote =
+ state.votes[action.payload.questionId][action.payload.optionId];
+
+ if (foundVote !== null) {
+ if (foundVote === 1 && action.payload.change <= 0) {
+ return;
+ }
+ if (
+ foundVote >=
+ Object.keys(state.votes[action.payload.questionId])
+ .length &&
+ action.payload.change >= 0
+ ) {
+ state.votes[action.payload.questionId][
+ action.payload.optionId
+ ] = null;
+ return;
+ }
+ state.votes[action.payload.questionId][
+ action.payload.optionId
+ ] += action.payload.change;
+ } else {
+ if (action.payload.change <= 0) {
+ state.votes[action.payload.questionId][
+ action.payload.optionId
+ ] = Object.keys(
+ state.votes[action.payload.questionId],
+ ).length;
+ }
+ }
+ },
+ },
+});
+
+export const { registerVote, changeVote } = voteSlice.actions;
+
+export default voteSlice.reducer;