CI: sync from GitHub
Browse files- frontend/src/useStore.js +95 -24
frontend/src/useStore.js
CHANGED
|
@@ -20,14 +20,22 @@ const postFile = async (url, file) => {
|
|
| 20 |
return res.json();
|
| 21 |
};
|
| 22 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 23 |
const useStore = create((set, get) => ({
|
| 24 |
// состояние
|
| 25 |
model: "MT",
|
| 26 |
-
|
| 27 |
-
|
| 28 |
-
|
| 29 |
-
|
| 30 |
-
|
|
|
|
|
|
|
| 31 |
uploadedPath: null,
|
| 32 |
busy: false,
|
| 33 |
lastPreviewUrls: null,
|
|
@@ -35,11 +43,58 @@ const useStore = create((set, get) => ({
|
|
| 35 |
|
| 36 |
// сеттеры
|
| 37 |
setModel: (model) => set({ model }),
|
| 38 |
-
|
| 39 |
-
|
| 40 |
-
|
| 41 |
-
|
| 42 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 43 |
|
| 44 |
// 1) загрузка принта
|
| 45 |
async upload(file) {
|
|
@@ -55,27 +110,42 @@ const useStore = create((set, get) => ({
|
|
| 55 |
|
| 56 |
// 2) построение превью из текущих контролов
|
| 57 |
async spread() {
|
| 58 |
-
const { model,
|
|
|
|
| 59 |
if (!uploadedPath) throw new Error("Сначала загрузите принт");
|
| 60 |
|
| 61 |
set({ busy: true });
|
| 62 |
try {
|
| 63 |
const payload = {
|
| 64 |
model,
|
| 65 |
-
view,
|
| 66 |
details: {
|
| 67 |
print_path: uploadedPath,
|
| 68 |
-
tile,
|
| 69 |
-
offset_x:
|
| 70 |
-
offset_y:
|
| 71 |
-
scale,
|
| 72 |
},
|
| 73 |
};
|
| 74 |
const data = await postJSON("/api/preview", payload);
|
| 75 |
const urls =
|
| 76 |
data.previews ||
|
| 77 |
-
(data.preview_url ? { [
|
| 78 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 79 |
return data;
|
| 80 |
} finally {
|
| 81 |
set({ busy: false });
|
|
@@ -90,20 +160,21 @@ const useStore = create((set, get) => ({
|
|
| 90 |
|
| 91 |
// 3) создание заказа
|
| 92 |
async startOrder() {
|
| 93 |
-
const { model,
|
|
|
|
| 94 |
if (!uploadedPath) throw new Error("Сначала загрузите принт");
|
| 95 |
|
| 96 |
set({ busy: true });
|
| 97 |
try {
|
| 98 |
const payload = {
|
| 99 |
model,
|
| 100 |
-
view,
|
| 101 |
details: {
|
| 102 |
print_path: uploadedPath,
|
| 103 |
-
tile,
|
| 104 |
-
offset_x:
|
| 105 |
-
offset_y:
|
| 106 |
-
scale,
|
| 107 |
},
|
| 108 |
};
|
| 109 |
const data = await postJSON("/api/order", payload);
|
|
|
|
| 20 |
return res.json();
|
| 21 |
};
|
| 22 |
|
| 23 |
+
const createInitialDetail = () => ({
|
| 24 |
+
previewUrl: null,
|
| 25 |
+
transform: { scale: 1, tx: 0, ty: 0 },
|
| 26 |
+
tile: { enabled: false },
|
| 27 |
+
});
|
| 28 |
+
|
| 29 |
const useStore = create((set, get) => ({
|
| 30 |
// состояние
|
| 31 |
model: "MT",
|
| 32 |
+
active: "front",
|
| 33 |
+
details: {
|
| 34 |
+
front: createInitialDetail(),
|
| 35 |
+
sleeveL: createInitialDetail(),
|
| 36 |
+
back: createInitialDetail(),
|
| 37 |
+
sleeveR: createInitialDetail(),
|
| 38 |
+
},
|
| 39 |
uploadedPath: null,
|
| 40 |
busy: false,
|
| 41 |
lastPreviewUrls: null,
|
|
|
|
| 43 |
|
| 44 |
// сеттеры
|
| 45 |
setModel: (model) => set({ model }),
|
| 46 |
+
setActive: (active) => set({ active }),
|
| 47 |
+
setScale: (scale) =>
|
| 48 |
+
set((state) => ({
|
| 49 |
+
details: {
|
| 50 |
+
...state.details,
|
| 51 |
+
[state.active]: {
|
| 52 |
+
...state.details[state.active],
|
| 53 |
+
transform: {
|
| 54 |
+
...state.details[state.active].transform,
|
| 55 |
+
scale,
|
| 56 |
+
},
|
| 57 |
+
},
|
| 58 |
+
},
|
| 59 |
+
})),
|
| 60 |
+
setTx: (tx) =>
|
| 61 |
+
set((state) => ({
|
| 62 |
+
details: {
|
| 63 |
+
...state.details,
|
| 64 |
+
[state.active]: {
|
| 65 |
+
...state.details[state.active],
|
| 66 |
+
transform: {
|
| 67 |
+
...state.details[state.active].transform,
|
| 68 |
+
tx,
|
| 69 |
+
},
|
| 70 |
+
},
|
| 71 |
+
},
|
| 72 |
+
})),
|
| 73 |
+
setTy: (ty) =>
|
| 74 |
+
set((state) => ({
|
| 75 |
+
details: {
|
| 76 |
+
...state.details,
|
| 77 |
+
[state.active]: {
|
| 78 |
+
...state.details[state.active],
|
| 79 |
+
transform: {
|
| 80 |
+
...state.details[state.active].transform,
|
| 81 |
+
ty,
|
| 82 |
+
},
|
| 83 |
+
},
|
| 84 |
+
},
|
| 85 |
+
})),
|
| 86 |
+
toggleTile: () =>
|
| 87 |
+
set((state) => ({
|
| 88 |
+
details: {
|
| 89 |
+
...state.details,
|
| 90 |
+
[state.active]: {
|
| 91 |
+
...state.details[state.active],
|
| 92 |
+
tile: {
|
| 93 |
+
enabled: !state.details[state.active].tile.enabled,
|
| 94 |
+
},
|
| 95 |
+
},
|
| 96 |
+
},
|
| 97 |
+
})),
|
| 98 |
|
| 99 |
// 1) загрузка принта
|
| 100 |
async upload(file) {
|
|
|
|
| 110 |
|
| 111 |
// 2) построение превью из текущих контролов
|
| 112 |
async spread() {
|
| 113 |
+
const { model, active, details, uploadedPath } = get();
|
| 114 |
+
const detail = details[active];
|
| 115 |
if (!uploadedPath) throw new Error("Сначала загрузите принт");
|
| 116 |
|
| 117 |
set({ busy: true });
|
| 118 |
try {
|
| 119 |
const payload = {
|
| 120 |
model,
|
| 121 |
+
view: active,
|
| 122 |
details: {
|
| 123 |
print_path: uploadedPath,
|
| 124 |
+
tile: detail.tile.enabled,
|
| 125 |
+
offset_x: detail.transform.tx,
|
| 126 |
+
offset_y: detail.transform.ty,
|
| 127 |
+
scale: detail.transform.scale,
|
| 128 |
},
|
| 129 |
};
|
| 130 |
const data = await postJSON("/api/preview", payload);
|
| 131 |
const urls =
|
| 132 |
data.previews ||
|
| 133 |
+
(data.preview_url ? { [active]: data.preview_url } : null);
|
| 134 |
+
if (urls) {
|
| 135 |
+
set((state) => {
|
| 136 |
+
const updatedDetails = { ...state.details };
|
| 137 |
+
for (const [key, url] of Object.entries(urls)) {
|
| 138 |
+
if (!updatedDetails[key]) continue;
|
| 139 |
+
updatedDetails[key] = {
|
| 140 |
+
...updatedDetails[key],
|
| 141 |
+
previewUrl: url,
|
| 142 |
+
};
|
| 143 |
+
}
|
| 144 |
+
return { details: updatedDetails, lastPreviewUrls: urls };
|
| 145 |
+
});
|
| 146 |
+
} else {
|
| 147 |
+
set({ lastPreviewUrls: urls });
|
| 148 |
+
}
|
| 149 |
return data;
|
| 150 |
} finally {
|
| 151 |
set({ busy: false });
|
|
|
|
| 160 |
|
| 161 |
// 3) создание заказа
|
| 162 |
async startOrder() {
|
| 163 |
+
const { model, active, details, uploadedPath } = get();
|
| 164 |
+
const detail = details[active];
|
| 165 |
if (!uploadedPath) throw new Error("Сначала загрузите принт");
|
| 166 |
|
| 167 |
set({ busy: true });
|
| 168 |
try {
|
| 169 |
const payload = {
|
| 170 |
model,
|
| 171 |
+
view: active,
|
| 172 |
details: {
|
| 173 |
print_path: uploadedPath,
|
| 174 |
+
tile: detail.tile.enabled,
|
| 175 |
+
offset_x: detail.transform.tx,
|
| 176 |
+
offset_y: detail.transform.ty,
|
| 177 |
+
scale: detail.transform.scale,
|
| 178 |
},
|
| 179 |
};
|
| 180 |
const data = await postJSON("/api/order", payload);
|