fix update settings

This commit is contained in:
hamid zarghami
2026-06-22 10:07:31 +03:30
parent fe78b218cc
commit f8c401f2ed
2 changed files with 129 additions and 67 deletions
+125 -67
View File
@@ -5,8 +5,8 @@ import { extractErrorMessage } from "@/config/func";
import type { ErrorType } from "@/helpers/types";
import { clx } from "@/helpers/utils";
import DesignSlider from "@/pages/settings/components/DesignSlider";
import { PATTERN_BACKGROUND_OPACITY, useBackgroundPatterns } from "@/pages/settings/hooks/usePatterns";
import { useGetBackgrounds, useSetBackground } from "@/pages/settings/hooks/useSettingData";
import { getBackgroundPatternUrl, PATTERN_BACKGROUND_OPACITY, useBackgroundPatterns } from "@/pages/settings/hooks/usePatterns";
import { useGetBackgrounds, useGetRestaurant, useSetBackground, useUpdateRestaurant } from "@/pages/settings/hooks/useSettingData";
import type { BackgroundItemType, SetBackgroundType } from "@/pages/settings/types/Types";
import { useSingleUpload } from "@/pages/uploader/hooks/useUploaderData";
import { DocumentUpload, Gallery, TickCircle, Trash } from "iconsax-react";
@@ -21,6 +21,12 @@ const UPLOAD_BOX_CLASS = "w-[200px] h-[362px] rounded-2xl border border-dashed b
const getPatternBgUrl = (item: BackgroundItemType) => item.url ?? item.bgUrl ?? "";
const normalizeBgUrl = (url: string) => {
if (!url) return "";
if (url.startsWith("http")) return url;
return `${import.meta.env.VITE_BASE_URL}${url.startsWith("/") ? url : `/${url}`}`;
};
const DesignSettings: FC = () => {
const [menuColor, setMenuColor] = useState("#000000");
const [appliedColor, setAppliedColor] = useState("#000000");
@@ -28,21 +34,54 @@ const DesignSettings: FC = () => {
const [backgroundType, setBackgroundType] = useState<BackgroundType>("pattern");
const [customImage, setCustomImage] = useState<File | null>(null);
const [customImagePreview, setCustomImagePreview] = useState<string | null>(null);
const [existingBgUrl, setExistingBgUrl] = useState<string | null>(null);
const [imageOpacity, setImageOpacity] = useState(100);
const [imageBlur, setImageBlur] = useState(0);
const [overlayDarkness, setOverlayDarkness] = useState(0);
const [isInitialized, setIsInitialized] = useState(false);
const { data: backgrounds } = useGetBackgrounds();
const { mutate: setBackground, isPending: isSavingBackground } = useSetBackground();
const { mutate: updateRestaurant, isPending: isUpdatingRestaurant } = useUpdateRestaurant();
const { mutate: singleUpload, isPending: isUploadingImage } = useSingleUpload();
const { patterns, isLoading: isPatternsLoading, isError: isPatternsError } = useBackgroundPatterns(appliedColor);
const { data: restaurant, refetch } = useGetRestaurant();
const backgroundItems = useMemo(() => backgrounds?.data ?? [], [backgrounds]);
const isSaving = isSavingBackground || isUploadingImage;
const isSaving = isSavingBackground || isUploadingImage || isUpdatingRestaurant;
useEffect(() => {
if (patterns[0]?.id) {
setSelectedPatternId((current) => current ?? patterns[0].id);
if (!restaurant?.data || isInitialized) return;
const restaurantData = restaurant.data;
const savedBgUrl = restaurantData.bgUrl;
if (savedBgUrl && backgroundItems.length === 0) return;
const color = restaurantData.menuColor || "#000000";
setMenuColor(color);
setAppliedColor(color);
if (savedBgUrl) {
const matchingPattern = backgroundItems.find(
(item) => getBackgroundPatternUrl(item) === normalizeBgUrl(savedBgUrl) || getPatternBgUrl(item) === savedBgUrl,
);
if (matchingPattern) {
setBackgroundType("pattern");
setSelectedPatternId(matchingPattern.id);
} else {
setBackgroundType("custom");
setExistingBgUrl(savedBgUrl);
setCustomImagePreview(normalizeBgUrl(savedBgUrl));
setImageOpacity(Number(restaurantData.bgOpacity) || 100);
setImageBlur(Number(restaurantData.bgBlur) || 0);
setOverlayDarkness(Number(restaurantData.bgOverlay) || 0);
}
} else if (backgroundItems[0]?.id) {
setSelectedPatternId(backgroundItems[0].id);
}
}, [patterns]);
setIsInitialized(true);
}, [restaurant, backgroundItems, isInitialized]);
useEffect(() => {
const timer = setTimeout(() => setAppliedColor(menuColor), COLOR_APPLY_DELAY_MS);
@@ -50,10 +89,7 @@ const DesignSettings: FC = () => {
}, [menuColor]);
useEffect(() => {
if (!customImage) {
setCustomImagePreview(null);
return;
}
if (!customImage) return;
const previewUrl = URL.createObjectURL(customImage);
setCustomImagePreview(previewUrl);
@@ -75,76 +111,98 @@ const DesignSettings: FC = () => {
const handleRemoveImage = () => {
setCustomImage(null);
setExistingBgUrl(null);
setCustomImagePreview(null);
setImageOpacity(100);
setImageBlur(0);
setOverlayDarkness(0);
};
const handleApplyChanges = () => {
if (backgroundType === "pattern") {
const selectedItem = backgroundItems.find((item) => item.id === selectedPatternId);
const bgUrl = selectedItem ? getPatternBgUrl(selectedItem) : "";
const saveCustomBackground = (bgUrl: string) => {
const backgroundPayload: SetBackgroundType = {
bgUrl,
bgBlur: String(imageBlur ?? 0),
bgOverlay: String(overlayDarkness ?? 0),
};
if (!bgUrl) {
toast.error("لطفاً یک پترن انتخاب کنید");
return;
}
setBackground(
{ bgUrl },
{
onSuccess: () => toast.success("تنظیمات طراحی با موفقیت ذخیره شد"),
onError: (error: unknown) => {
toast.error(extractErrorMessage(error as ErrorType, "خطا در ذخیره تنظیمات طراحی"));
},
},
);
return;
if (imageOpacity) {
backgroundPayload.bgOpacity = String(imageOpacity);
}
if (!customImage) {
toast.error("لطفاً تصویر پس‌زمینه را آپلود کنید");
return;
}
singleUpload(customImage, {
onSuccess: (response) => {
const bgUrl = response?.data?.url ?? "";
if (!bgUrl) {
toast.error("خطا در آپلود تصویر");
return;
}
const backgroundPayload: SetBackgroundType = { bgUrl };
if (imageOpacity) {
backgroundPayload.bgOpacity = String(imageOpacity);
}
if (imageBlur) {
backgroundPayload.bgBlur = String(imageBlur);
}
if (overlayDarkness) {
backgroundPayload.bgOverlay = String(overlayDarkness);
}
setBackground(
backgroundPayload,
{
onSuccess: () => toast.success("تنظیمات طراحی با موفقیت ذخیره شد"),
onError: (error: unknown) => {
toast.error(extractErrorMessage(error as ErrorType, "خطا در ذخیره تنظیمات طراحی"));
},
},
);
setBackground(backgroundPayload, {
onSuccess: () => {
toast.success("تنظیمات طراحی با موفقیت ذخیره شد");
refetch();
},
onError: (error: ErrorType) => {
toast.error(extractErrorMessage(error, "خطا در آپلود تصویر"));
onError: (error: unknown) => {
toast.error(extractErrorMessage(error as ErrorType, "خطا در ذخیره تنظیمات طراحی"));
},
});
};
const isApplyDisabled = isSaving || (backgroundType === "pattern" ? !selectedPatternId : !customImage);
const handleApplyChanges = () => {
updateRestaurant(
{ menuColor },
{
onSuccess: () => {
if (backgroundType === "pattern") {
const selectedItem = backgroundItems.find((item) => item.id === selectedPatternId);
const bgUrl = selectedItem ? getPatternBgUrl(selectedItem) : "";
if (!bgUrl) {
toast.error("لطفاً یک پترن انتخاب کنید");
return;
}
setBackground(
{ bgUrl },
{
onSuccess: () => {
toast.success("تنظیمات طراحی با موفقیت ذخیره شد");
refetch();
},
onError: (error: unknown) => {
toast.error(extractErrorMessage(error as ErrorType, "خطا در ذخیره تنظیمات طراحی"));
},
},
);
return;
}
if (customImage) {
singleUpload(customImage, {
onSuccess: (response) => {
const bgUrl = response?.data?.url ?? "";
if (!bgUrl) {
toast.error("خطا در آپلود تصویر");
return;
}
saveCustomBackground(bgUrl);
},
onError: (error: ErrorType) => {
toast.error(extractErrorMessage(error, "خطا در آپلود تصویر"));
},
});
return;
}
if (existingBgUrl) {
saveCustomBackground(existingBgUrl);
return;
}
toast.error("لطفاً تصویر پس‌زمینه را آپلود کنید");
},
onError: (error: unknown) => {
toast.error(extractErrorMessage(error as ErrorType, "خطا در ذخیره تنظیمات طراحی"));
},
},
);
};
const isApplyDisabled = isSaving || (backgroundType === "pattern" ? !selectedPatternId : !customImage && !existingBgUrl);
return (
<div className="bg-white rounded-4xl p-8">
+4
View File
@@ -40,6 +40,10 @@ export type Restaurant = {
logo: string | null;
address: string | null;
menuColor: string | null;
bgUrl?: string | null;
bgOpacity?: string | null;
bgBlur?: string | null;
bgOverlay?: string | null;
latitude: number | null;
longitude: number | null;
serviceArea: GeoJSONPolygon;