import { createSlice, PayloadAction } from "@reduxjs/toolkit";
import { nanoid } from "@reduxjs/toolkit";
import { arrayMove } from "@dnd-kit/sortable";
import { formsApi } from "../backend/endpoints/forms";
interface FormPlaygroundState {
formElements: FormElementsType[];
}
const initialState: FormPlaygroundState = {
formElements: [],
};
const formPlaygroundSlice = createSlice({
name: "formPlayground",
initialState,
reducers: {
addFormElement(
state,
action: PayloadAction<{ label: string; type: string }>
) {
const { label, type } = action.payload;
state.formElements.push({
id: nanoid(),
label,
type,
required: false,
options: ["checklist", "multi-choice", "dropdown", "combobox"].includes(
type
)
? [
{ label: "Option 1", value: nanoid() },
{ label: "Option 2", value: nanoid() },
]
: undefined,
});
},
moveFormElement(
state,
action: PayloadAction<{ oldIndex: number; newIndex: number }>
) {
const { oldIndex, newIndex } = action.payload;
state.formElements = arrayMove(state.formElements, oldIndex, newIndex);
},
updateLabel(state, action: PayloadAction<{ id: string; label: string }>) {
const { id, label } = action.payload;
const formElement = state.formElements.find((el) => el.id === id);
if (formElement) {
formElement.label = label;
}
},
toggleRequired(state, action: PayloadAction<string>) {
const id = action.payload;
const formElement = state.formElements.find((el) => el.id === id);
if (formElement) {
formElement.required = !formElement.required;
}
},
addOption(state, action: PayloadAction<string>) {
const id = action.payload;
const formElement = state.formElements.find((el) => el.id === id);
if (formElement) {
const optionId = nanoid();
formElement.options?.push({
label: "Option " + (formElement.options.length + 1),
value: optionId,
});
}
},
updateOption(
state,
action: PayloadAction<{ id: string; optionId: string; label: string }>
) {
const { id, optionId, label } = action.payload;
const formElement = state.formElements.find((el) => el.id === id);
if (formElement) {
const option = formElement.options?.find(
(opt) => opt.value === optionId
);
if (option) {
option.label = label;
}
}
},
deleteOption(
state,
action: PayloadAction<{ id: string; optionId: string }>
) {
const { id, optionId } = action.payload;
const formElement = state.formElements.find((el) => el.id === id);
if (formElement && formElement.options) {
formElement.options = formElement.options.filter(
(opt) => opt.value !== optionId
);
}
},
removeFormElement(state, action: PayloadAction<string>) {
const id = action.payload;
state.formElements = state.formElements.filter((el) => el.id !== id);
},
removeAllFormElements(state) {
state.formElements = [];
},
setFormElements(state, action: PayloadAction<FormElementsType[]>) {
state.formElements = action.payload;
},
},
extraReducers: (builder) => {
builder.addMatcher(
formsApi.endpoints.getForm.matchFulfilled,
(state, action) => {
state.formElements = action.payload.data.elements;
}
);
},
});
export const {
addFormElement,
moveFormElement,
updateLabel,
toggleRequired,
addOption,
updateOption,
deleteOption,
removeFormElement,
removeAllFormElements,
setFormElements,
} = formPlaygroundSlice.actions;
export default formPlaygroundSlice.reducer;