577 lines
14 KiB
TypeScript
577 lines
14 KiB
TypeScript
import { create } from "zustand";
|
|
import { v4 as uuidv4 } from "uuid";
|
|
import {
|
|
PersonalityStore,
|
|
PersonalityDataType,
|
|
SectionItemType,
|
|
TextType,
|
|
ButtonType,
|
|
ImageType,
|
|
SocialType,
|
|
SectionName,
|
|
HorizontalAlignment,
|
|
VerticalAlignment,
|
|
SelectedElement,
|
|
} from "../types/Types";
|
|
|
|
export const usePersonalityStore = create<PersonalityStore>((set) => ({
|
|
data: {
|
|
header: { columnsCount: 0, items: [] },
|
|
content: { columnsCount: 0, items: [] },
|
|
footer: { columnsCount: 0, items: [] },
|
|
},
|
|
|
|
activeSection: "",
|
|
activeItemIndex: 0,
|
|
selectedElement: null,
|
|
isEditMode: false,
|
|
|
|
setData: (data: PersonalityDataType) =>
|
|
set(() => ({
|
|
data,
|
|
})),
|
|
|
|
setActiveSection: (section: SectionName) =>
|
|
set(() => {
|
|
return {
|
|
activeSection: section,
|
|
activeItemIndex: 0,
|
|
selectedElement: null,
|
|
isEditMode: false,
|
|
};
|
|
}),
|
|
|
|
setActiveItemIndex: (index: number) =>
|
|
set(() => {
|
|
return {
|
|
activeItemIndex: index,
|
|
selectedElement: null,
|
|
isEditMode: false,
|
|
};
|
|
}),
|
|
|
|
setSelectedElement: (element: SelectedElement) =>
|
|
set({ selectedElement: element, isEditMode: !!element }),
|
|
|
|
setEditMode: (isEdit: boolean) => set({ isEditMode: isEdit }),
|
|
|
|
setColumnsCount: (
|
|
sectionKey: keyof PersonalityDataType,
|
|
columnsCount: number
|
|
) =>
|
|
set((state) => {
|
|
const currentItems = state.data[sectionKey].items;
|
|
const newItems = Array.from(
|
|
{ length: columnsCount },
|
|
(_, index) =>
|
|
currentItems[index] || {
|
|
id: uuidv4(),
|
|
backgroundColor: "#ffffff",
|
|
texts: [],
|
|
buttons: [],
|
|
images: [],
|
|
socials: [],
|
|
alignment: HorizontalAlignment.CENTER,
|
|
verticalAlignment: VerticalAlignment.MIDDLE,
|
|
}
|
|
);
|
|
|
|
return {
|
|
data: {
|
|
...state.data,
|
|
[sectionKey]: {
|
|
columnsCount,
|
|
items: newItems,
|
|
},
|
|
},
|
|
activeItemIndex: 0,
|
|
};
|
|
}),
|
|
|
|
setItems: (sectionKey: keyof PersonalityDataType, items: SectionItemType[]) =>
|
|
set((state) => ({
|
|
data: {
|
|
...state.data,
|
|
[sectionKey]: {
|
|
...state.data[sectionKey],
|
|
items,
|
|
},
|
|
},
|
|
})),
|
|
|
|
addItem: (
|
|
sectionKey: keyof PersonalityDataType,
|
|
item: Omit<SectionItemType, "id">
|
|
) =>
|
|
set((state) => ({
|
|
data: {
|
|
...state.data,
|
|
[sectionKey]: {
|
|
...state.data[sectionKey],
|
|
items: [...state.data[sectionKey].items, { ...item, id: uuidv4() }],
|
|
},
|
|
},
|
|
})),
|
|
|
|
updateActiveItem: (updates: Partial<SectionItemType>) =>
|
|
set((state) => {
|
|
if (!state.activeSection) return state;
|
|
|
|
const sectionKey = state.activeSection as keyof PersonalityDataType;
|
|
const items = state.data[sectionKey].items;
|
|
const activeIndex = state.activeItemIndex;
|
|
|
|
if (activeIndex >= items.length) return state;
|
|
|
|
const updatedItems = items.map((item, index) =>
|
|
index === activeIndex ? { ...item, ...updates } : item
|
|
);
|
|
|
|
return {
|
|
data: {
|
|
...state.data,
|
|
[sectionKey]: {
|
|
...state.data[sectionKey],
|
|
items: updatedItems,
|
|
},
|
|
},
|
|
};
|
|
}),
|
|
|
|
updateItem: (
|
|
sectionKey: keyof PersonalityDataType,
|
|
id: string,
|
|
updates: Partial<SectionItemType>
|
|
) =>
|
|
set((state) => ({
|
|
data: {
|
|
...state.data,
|
|
[sectionKey]: {
|
|
...state.data[sectionKey],
|
|
items: state.data[sectionKey].items.map((item) =>
|
|
item.id === id ? { ...item, ...updates } : item
|
|
),
|
|
},
|
|
},
|
|
})),
|
|
|
|
removeItem: (sectionKey: keyof PersonalityDataType, id: string) =>
|
|
set((state) => ({
|
|
data: {
|
|
...state.data,
|
|
[sectionKey]: {
|
|
...state.data[sectionKey],
|
|
items: state.data[sectionKey].items.filter((item) => item.id !== id),
|
|
},
|
|
},
|
|
})),
|
|
|
|
addText: (
|
|
sectionKey: keyof PersonalityDataType,
|
|
itemId: string,
|
|
text: Omit<TextType, "id">
|
|
) =>
|
|
set((state) => ({
|
|
data: {
|
|
...state.data,
|
|
[sectionKey]: {
|
|
...state.data[sectionKey],
|
|
items: state.data[sectionKey].items.map((item) =>
|
|
item.id === itemId
|
|
? {
|
|
...item,
|
|
texts: [...item.texts, { ...text, id: uuidv4() }],
|
|
}
|
|
: item
|
|
),
|
|
},
|
|
},
|
|
})),
|
|
|
|
addTextToActiveItem: (text: Omit<TextType, "id">) =>
|
|
set((state) => {
|
|
if (!state.activeSection) return state;
|
|
|
|
const sectionKey = state.activeSection as keyof PersonalityDataType;
|
|
const items = state.data[sectionKey].items;
|
|
const activeIndex = state.activeItemIndex;
|
|
|
|
if (activeIndex >= items.length) return state;
|
|
|
|
const updatedItems = items.map((item, index) =>
|
|
index === activeIndex
|
|
? {
|
|
...item,
|
|
texts: [...item.texts, { ...text, id: uuidv4() }],
|
|
}
|
|
: item
|
|
);
|
|
|
|
return {
|
|
data: {
|
|
...state.data,
|
|
[sectionKey]: {
|
|
...state.data[sectionKey],
|
|
items: updatedItems,
|
|
},
|
|
},
|
|
};
|
|
}),
|
|
|
|
addButton: (
|
|
sectionKey: keyof PersonalityDataType,
|
|
itemId: string,
|
|
button: Omit<ButtonType, "id">
|
|
) =>
|
|
set((state) => ({
|
|
data: {
|
|
...state.data,
|
|
[sectionKey]: {
|
|
...state.data[sectionKey],
|
|
items: state.data[sectionKey].items.map((item) =>
|
|
item.id === itemId
|
|
? {
|
|
...item,
|
|
buttons: [...item.buttons, { ...button, id: uuidv4() }],
|
|
}
|
|
: item
|
|
),
|
|
},
|
|
},
|
|
})),
|
|
|
|
addButtonToActiveItem: (button: Omit<ButtonType, "id">) =>
|
|
set((state) => {
|
|
if (!state.activeSection) return state;
|
|
|
|
const sectionKey = state.activeSection as keyof PersonalityDataType;
|
|
const items = state.data[sectionKey].items;
|
|
const activeIndex = state.activeItemIndex;
|
|
|
|
if (activeIndex >= items.length) return state;
|
|
|
|
const updatedItems = items.map((item, index) =>
|
|
index === activeIndex
|
|
? {
|
|
...item,
|
|
buttons: [...item.buttons, { ...button, id: uuidv4() }],
|
|
}
|
|
: item
|
|
);
|
|
|
|
return {
|
|
data: {
|
|
...state.data,
|
|
[sectionKey]: {
|
|
...state.data[sectionKey],
|
|
items: updatedItems,
|
|
},
|
|
},
|
|
};
|
|
}),
|
|
|
|
updateText: (
|
|
sectionKey: keyof PersonalityDataType,
|
|
itemId: string,
|
|
textId: string,
|
|
updates: Partial<TextType>
|
|
) =>
|
|
set((state) => ({
|
|
data: {
|
|
...state.data,
|
|
[sectionKey]: {
|
|
...state.data[sectionKey],
|
|
items: state.data[sectionKey].items.map((item) =>
|
|
item.id === itemId
|
|
? {
|
|
...item,
|
|
texts: item.texts.map((text) =>
|
|
text.id === textId ? { ...text, ...updates } : text
|
|
),
|
|
}
|
|
: item
|
|
),
|
|
},
|
|
},
|
|
})),
|
|
|
|
updateButton: (
|
|
sectionKey: keyof PersonalityDataType,
|
|
itemId: string,
|
|
buttonId: string,
|
|
updates: Partial<ButtonType>
|
|
) =>
|
|
set((state) => ({
|
|
data: {
|
|
...state.data,
|
|
[sectionKey]: {
|
|
...state.data[sectionKey],
|
|
items: state.data[sectionKey].items.map((item) =>
|
|
item.id === itemId
|
|
? {
|
|
...item,
|
|
buttons: item.buttons.map((button) =>
|
|
button.id === buttonId ? { ...button, ...updates } : button
|
|
),
|
|
}
|
|
: item
|
|
),
|
|
},
|
|
},
|
|
})),
|
|
|
|
addImage: (
|
|
sectionKey: keyof PersonalityDataType,
|
|
itemId: string,
|
|
image: Omit<ImageType, "id">
|
|
) =>
|
|
set((state) => ({
|
|
data: {
|
|
...state.data,
|
|
[sectionKey]: {
|
|
...state.data[sectionKey],
|
|
items: state.data[sectionKey].items.map((item) =>
|
|
item.id === itemId
|
|
? {
|
|
...item,
|
|
images: [...item.images, { ...image, id: uuidv4() }],
|
|
}
|
|
: item
|
|
),
|
|
},
|
|
},
|
|
})),
|
|
|
|
addImageToActiveItem: (image: Omit<ImageType, "id">) =>
|
|
set((state) => {
|
|
if (!state.activeSection) return state;
|
|
|
|
const sectionKey = state.activeSection as keyof PersonalityDataType;
|
|
const items = state.data[sectionKey].items;
|
|
const activeIndex = state.activeItemIndex;
|
|
|
|
if (activeIndex >= items.length) return state;
|
|
|
|
const updatedItems = items.map((item, index) =>
|
|
index === activeIndex
|
|
? {
|
|
...item,
|
|
images: [...item.images, { ...image, id: uuidv4() }],
|
|
}
|
|
: item
|
|
);
|
|
|
|
return {
|
|
data: {
|
|
...state.data,
|
|
[sectionKey]: {
|
|
...state.data[sectionKey],
|
|
items: updatedItems,
|
|
},
|
|
},
|
|
};
|
|
}),
|
|
|
|
updateImage: (
|
|
sectionKey: keyof PersonalityDataType,
|
|
itemId: string,
|
|
imageId: string,
|
|
updates: Partial<ImageType>
|
|
) =>
|
|
set((state) => ({
|
|
data: {
|
|
...state.data,
|
|
[sectionKey]: {
|
|
...state.data[sectionKey],
|
|
items: state.data[sectionKey].items.map((item) =>
|
|
item.id === itemId
|
|
? {
|
|
...item,
|
|
images: item.images.map((image) =>
|
|
image.id === imageId ? { ...image, ...updates } : image
|
|
),
|
|
}
|
|
: item
|
|
),
|
|
},
|
|
},
|
|
})),
|
|
|
|
deleteText: (
|
|
sectionKey: keyof PersonalityDataType,
|
|
itemId: string,
|
|
textId: string
|
|
) =>
|
|
set((state) => ({
|
|
data: {
|
|
...state.data,
|
|
[sectionKey]: {
|
|
...state.data[sectionKey],
|
|
items: state.data[sectionKey].items.map((item) =>
|
|
item.id === itemId
|
|
? {
|
|
...item,
|
|
texts: item.texts.filter((text) => text.id !== textId),
|
|
}
|
|
: item
|
|
),
|
|
},
|
|
},
|
|
selectedElement: null,
|
|
isEditMode: false,
|
|
})),
|
|
|
|
deleteButton: (
|
|
sectionKey: keyof PersonalityDataType,
|
|
itemId: string,
|
|
buttonId: string
|
|
) =>
|
|
set((state) => ({
|
|
data: {
|
|
...state.data,
|
|
[sectionKey]: {
|
|
...state.data[sectionKey],
|
|
items: state.data[sectionKey].items.map((item) =>
|
|
item.id === itemId
|
|
? {
|
|
...item,
|
|
buttons: item.buttons.filter(
|
|
(button) => button.id !== buttonId
|
|
),
|
|
}
|
|
: item
|
|
),
|
|
},
|
|
},
|
|
selectedElement: null,
|
|
isEditMode: false,
|
|
})),
|
|
|
|
deleteImage: (
|
|
sectionKey: keyof PersonalityDataType,
|
|
itemId: string,
|
|
imageId: string
|
|
) =>
|
|
set((state) => ({
|
|
data: {
|
|
...state.data,
|
|
[sectionKey]: {
|
|
...state.data[sectionKey],
|
|
items: state.data[sectionKey].items.map((item) =>
|
|
item.id === itemId
|
|
? {
|
|
...item,
|
|
images: item.images.filter((image) => image.id !== imageId),
|
|
}
|
|
: item
|
|
),
|
|
},
|
|
},
|
|
selectedElement: null,
|
|
isEditMode: false,
|
|
})),
|
|
|
|
addSocial: (
|
|
sectionKey: keyof PersonalityDataType,
|
|
itemId: string,
|
|
social: Omit<SocialType, "id">
|
|
) =>
|
|
set((state) => ({
|
|
data: {
|
|
...state.data,
|
|
[sectionKey]: {
|
|
...state.data[sectionKey],
|
|
items: state.data[sectionKey].items.map((item) =>
|
|
item.id === itemId
|
|
? {
|
|
...item,
|
|
socials: [...item.socials, { ...social, id: uuidv4() }],
|
|
}
|
|
: item
|
|
),
|
|
},
|
|
},
|
|
})),
|
|
|
|
addSocialToActiveItem: (social: Omit<SocialType, "id">) =>
|
|
set((state) => {
|
|
if (!state.activeSection) return state;
|
|
|
|
const sectionKey = state.activeSection as keyof PersonalityDataType;
|
|
const items = state.data[sectionKey].items;
|
|
const activeIndex = state.activeItemIndex;
|
|
|
|
if (activeIndex >= items.length) return state;
|
|
|
|
const updatedItems = items.map((item, index) =>
|
|
index === activeIndex
|
|
? {
|
|
...item,
|
|
socials: [...item.socials, { ...social, id: uuidv4() }],
|
|
}
|
|
: item
|
|
);
|
|
|
|
return {
|
|
data: {
|
|
...state.data,
|
|
[sectionKey]: {
|
|
...state.data[sectionKey],
|
|
items: updatedItems,
|
|
},
|
|
},
|
|
};
|
|
}),
|
|
|
|
updateSocial: (
|
|
sectionKey: keyof PersonalityDataType,
|
|
itemId: string,
|
|
socialId: string,
|
|
updates: Partial<SocialType>
|
|
) =>
|
|
set((state) => ({
|
|
data: {
|
|
...state.data,
|
|
[sectionKey]: {
|
|
...state.data[sectionKey],
|
|
items: state.data[sectionKey].items.map((item) =>
|
|
item.id === itemId
|
|
? {
|
|
...item,
|
|
socials: item.socials.map((social) =>
|
|
social.id === socialId ? { ...social, ...updates } : social
|
|
),
|
|
}
|
|
: item
|
|
),
|
|
},
|
|
},
|
|
})),
|
|
|
|
deleteSocial: (
|
|
sectionKey: keyof PersonalityDataType,
|
|
itemId: string,
|
|
socialId: string
|
|
) =>
|
|
set((state) => ({
|
|
data: {
|
|
...state.data,
|
|
[sectionKey]: {
|
|
...state.data[sectionKey],
|
|
items: state.data[sectionKey].items.map((item) =>
|
|
item.id === itemId
|
|
? {
|
|
...item,
|
|
socials: item.socials.filter(
|
|
(social) => social.id !== socialId
|
|
),
|
|
}
|
|
: item
|
|
),
|
|
},
|
|
},
|
|
selectedElement: null,
|
|
isEditMode: false,
|
|
})),
|
|
}));
|