Set background
This commit is contained in:
@@ -1,17 +1,26 @@
|
|||||||
|
import Button from "@/components/Button";
|
||||||
import ColorPicker from "@/components/ColorPicker";
|
import ColorPicker from "@/components/ColorPicker";
|
||||||
import Radio from "@/components/Radio";
|
import Radio from "@/components/Radio";
|
||||||
|
import { extractErrorMessage } from "@/config/func";
|
||||||
|
import type { ErrorType } from "@/helpers/types";
|
||||||
import { clx } from "@/helpers/utils";
|
import { clx } from "@/helpers/utils";
|
||||||
import DesignSlider from "@/pages/settings/components/DesignSlider";
|
import DesignSlider from "@/pages/settings/components/DesignSlider";
|
||||||
import { PATTERN_BACKGROUND_OPACITY, useBackgroundPatterns } from "@/pages/settings/hooks/usePatterns";
|
import { PATTERN_BACKGROUND_OPACITY, useBackgroundPatterns } from "@/pages/settings/hooks/usePatterns";
|
||||||
import { DocumentUpload, Gallery, Trash } from "iconsax-react";
|
import { useGetBackgrounds, useSetBackground } from "@/pages/settings/hooks/useSettingData";
|
||||||
import { useCallback, useEffect, useState, type FC } from "react";
|
import type { BackgroundItemType } from "@/pages/settings/types/Types";
|
||||||
|
import { useSingleUpload } from "@/pages/uploader/hooks/useUploaderData";
|
||||||
|
import { DocumentUpload, Gallery, TickCircle, Trash } from "iconsax-react";
|
||||||
|
import { useCallback, useEffect, useMemo, useState, type FC } from "react";
|
||||||
import { useDropzone } from "react-dropzone";
|
import { useDropzone } from "react-dropzone";
|
||||||
|
import { toast } from "react-toastify";
|
||||||
|
|
||||||
const COLOR_APPLY_DELAY_MS = 500;
|
const COLOR_APPLY_DELAY_MS = 500;
|
||||||
type BackgroundType = "pattern" | "custom";
|
type BackgroundType = "pattern" | "custom";
|
||||||
|
|
||||||
const UPLOAD_BOX_CLASS = "w-[200px] h-[362px] rounded-2xl border border-dashed border-description";
|
const UPLOAD_BOX_CLASS = "w-[200px] h-[362px] rounded-2xl border border-dashed border-description";
|
||||||
|
|
||||||
|
const getPatternBgUrl = (item: BackgroundItemType) => item.url ?? item.bgUrl ?? "";
|
||||||
|
|
||||||
const DesignSettings: FC = () => {
|
const DesignSettings: FC = () => {
|
||||||
const [menuColor, setMenuColor] = useState("#000000");
|
const [menuColor, setMenuColor] = useState("#000000");
|
||||||
const [appliedColor, setAppliedColor] = useState("#000000");
|
const [appliedColor, setAppliedColor] = useState("#000000");
|
||||||
@@ -22,7 +31,12 @@ const DesignSettings: FC = () => {
|
|||||||
const [imageOpacity, setImageOpacity] = useState(100);
|
const [imageOpacity, setImageOpacity] = useState(100);
|
||||||
const [imageBlur, setImageBlur] = useState(0);
|
const [imageBlur, setImageBlur] = useState(0);
|
||||||
const [overlayDarkness, setOverlayDarkness] = useState(0);
|
const [overlayDarkness, setOverlayDarkness] = useState(0);
|
||||||
|
const { data: backgrounds } = useGetBackgrounds();
|
||||||
|
const { mutate: setBackground, isPending: isSavingBackground } = useSetBackground();
|
||||||
|
const { mutate: singleUpload, isPending: isUploadingImage } = useSingleUpload();
|
||||||
const { patterns, isLoading: isPatternsLoading, isError: isPatternsError } = useBackgroundPatterns(appliedColor);
|
const { patterns, isLoading: isPatternsLoading, isError: isPatternsError } = useBackgroundPatterns(appliedColor);
|
||||||
|
const backgroundItems = useMemo(() => backgrounds?.data ?? [], [backgrounds]);
|
||||||
|
const isSaving = isSavingBackground || isUploadingImage;
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (patterns[0]?.id) {
|
if (patterns[0]?.id) {
|
||||||
@@ -66,6 +80,65 @@ const DesignSettings: FC = () => {
|
|||||||
setOverlayDarkness(0);
|
setOverlayDarkness(0);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleApplyChanges = () => {
|
||||||
|
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("تنظیمات طراحی با موفقیت ذخیره شد"),
|
||||||
|
onError: (error: unknown) => {
|
||||||
|
toast.error(extractErrorMessage(error as ErrorType, "خطا در ذخیره تنظیمات طراحی"));
|
||||||
|
},
|
||||||
|
},
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!customImage) {
|
||||||
|
toast.error("لطفاً تصویر پسزمینه را آپلود کنید");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
singleUpload(customImage, {
|
||||||
|
onSuccess: (response) => {
|
||||||
|
const bgUrl = response?.data?.url ?? "";
|
||||||
|
|
||||||
|
if (!bgUrl) {
|
||||||
|
toast.error("خطا در آپلود تصویر");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
setBackground(
|
||||||
|
{
|
||||||
|
bgUrl,
|
||||||
|
bgOpacity: imageOpacity,
|
||||||
|
bgBlur: imageBlur,
|
||||||
|
bgOverlay: String(overlayDarkness),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
onSuccess: () => toast.success("تنظیمات طراحی با موفقیت ذخیره شد"),
|
||||||
|
onError: (error: unknown) => {
|
||||||
|
toast.error(extractErrorMessage(error as ErrorType, "خطا در ذخیره تنظیمات طراحی"));
|
||||||
|
},
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
onError: (error: ErrorType) => {
|
||||||
|
toast.error(extractErrorMessage(error, "خطا در آپلود تصویر"));
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const isApplyDisabled = isSaving || (backgroundType === "pattern" ? !selectedPatternId : !customImage);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="bg-white rounded-4xl p-8">
|
<div className="bg-white rounded-4xl p-8">
|
||||||
<div className="text-lg font-light">تنظیمات طراحی</div>
|
<div className="text-lg font-light">تنظیمات طراحی</div>
|
||||||
@@ -82,16 +155,9 @@ const DesignSettings: FC = () => {
|
|||||||
|
|
||||||
{backgroundType === "pattern" && (
|
{backgroundType === "pattern" && (
|
||||||
<div className="mt-2 flex gap-3 flex-wrap">
|
<div className="mt-2 flex gap-3 flex-wrap">
|
||||||
{isPatternsLoading &&
|
{isPatternsLoading && Array.from({ length: 6 }).map((_, index) => <div key={index} className="w-16 h-[139px] rounded-lg bg-secondary animate-pulse" />)}
|
||||||
Array.from({ length: 6 }).map((_, index) => (
|
{!isPatternsLoading && isPatternsError && <div className="text-sm text-description">خطا در بارگذاری پترنها</div>}
|
||||||
<div key={index} className="w-16 h-[139px] rounded-lg bg-secondary animate-pulse" />
|
{!isPatternsLoading && !isPatternsError && patterns.length === 0 && <div className="text-sm text-description">پترنی یافت نشد</div>}
|
||||||
))}
|
|
||||||
{!isPatternsLoading && isPatternsError && (
|
|
||||||
<div className="text-sm text-description">خطا در بارگذاری پترنها</div>
|
|
||||||
)}
|
|
||||||
{!isPatternsLoading && !isPatternsError && patterns.length === 0 && (
|
|
||||||
<div className="text-sm text-description">پترنی یافت نشد</div>
|
|
||||||
)}
|
|
||||||
{patterns.map((pattern) => (
|
{patterns.map((pattern) => (
|
||||||
<button
|
<button
|
||||||
key={pattern.id}
|
key={pattern.id}
|
||||||
@@ -158,6 +224,14 @@ const DesignSettings: FC = () => {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
<div className="mt-8 flex justify-end">
|
||||||
|
<Button type="button" className="w-fit px-6" isloading={isSaving} disabled={isApplyDisabled} onClick={handleApplyChanges}>
|
||||||
|
<div className="flex gap-2 items-center">
|
||||||
|
<TickCircle size={20} color="#fff" />
|
||||||
|
<span>اعمال تغییرات</span>
|
||||||
|
</div>
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user