design setting part pattern

This commit is contained in:
hamid zarghami
2026-06-08 16:06:32 +03:30
parent c404ac14be
commit ad06b0c8fe
12 changed files with 1369 additions and 52 deletions
+50 -50
View File
@@ -1,56 +1,56 @@
import Tabs from '@/components/Tabs'
import { Money2, NotificationStatus, Setting4 } from 'iconsax-react'
import { useState, type FC } from 'react'
import { SettingTabEnum } from './enum/Enum'
import GeneralSettings from './GeneralSettings'
import ScoreSetting from './components/ScoreSetting'
import NotificationsList from '../notifications/List'
import Tabs from "@/components/Tabs";
import { Brush2, Money2, NotificationStatus, Setting4 } from "iconsax-react";
import { useState, type FC } from "react";
import NotificationsList from "../notifications/List";
import DesignSettings from "./components/DesignSettings";
import ScoreSetting from "./components/ScoreSetting";
import { SettingTabEnum } from "./enum/Enum";
import GeneralSettings from "./GeneralSettings";
const Setting: FC = () => {
const [activeTab, setActiveTab] = useState<SettingTabEnum>(SettingTabEnum.GENERAL);
const [activeTab, setActiveTab] = useState<SettingTabEnum>(SettingTabEnum.GENERAL)
return (
<div className="mt-5">
<h1 className="text-lg font-light">تنظیمات</h1>
return (
<div className='mt-5'>
<h1 className='text-lg font-light'>تنظیمات</h1>
<div className="mt-8">
<Tabs
items={[
{
icon: <Setting4 color={activeTab === SettingTabEnum.GENERAL ? "black" : "#8C90A3"} size={24} />,
label: "عمومی",
value: SettingTabEnum.GENERAL,
},
{
icon: <Money2 color={activeTab === SettingTabEnum.FINANCIAL ? "black" : "#8C90A3"} size={24} />,
label: "تنظیمات امتیاز",
value: SettingTabEnum.FINANCIAL,
},
{
icon: <NotificationStatus color={activeTab === SettingTabEnum.NOTIFICATION ? "black" : "#8C90A3"} size={24} />,
label: "تنظیمات اعلان",
value: SettingTabEnum.NOTIFICATION,
},
{
icon: <Brush2 color={activeTab === SettingTabEnum.DESIGN ? "black" : "#8C90A3"} size={24} />,
label: "تنظیمات طراحی",
value: SettingTabEnum.DESIGN,
},
]}
onChange={(value: string) => setActiveTab(value as SettingTabEnum)}
active={activeTab}
/>
</div>
<div className='mt-8'>
<Tabs
items={[
{
icon: <Setting4 color={activeTab === SettingTabEnum.GENERAL ? 'black' : '#8C90A3'} size={24} />,
label: 'عمومی',
value: SettingTabEnum.GENERAL,
},
{
icon: <Money2 color={activeTab === SettingTabEnum.FINANCIAL ? 'black' : '#8C90A3'} size={24} />,
label: 'تنظیمات امتیاز',
value: SettingTabEnum.FINANCIAL,
},
{
icon: <NotificationStatus color={activeTab === SettingTabEnum.NOTIFICATION ? 'black' : '#8C90A3'} size={24} />,
label: 'تنظیمات اعلان',
value: SettingTabEnum.NOTIFICATION,
},
]}
onChange={(value: string) => setActiveTab(value as SettingTabEnum)}
active={activeTab}
/>
</div>
<div className="mt-8">
{activeTab === SettingTabEnum.GENERAL && <GeneralSettings />}
{activeTab === SettingTabEnum.FINANCIAL && <ScoreSetting />}
{activeTab === SettingTabEnum.NOTIFICATION && <NotificationsList />}
{activeTab === SettingTabEnum.DESIGN && <DesignSettings />}
</div>
</div>
);
};
<div className='mt-8'>
{
activeTab === SettingTabEnum.GENERAL && <GeneralSettings />
}
{
activeTab === SettingTabEnum.FINANCIAL && <ScoreSetting />
}
{
activeTab === SettingTabEnum.NOTIFICATION && <NotificationsList />
}
</div>
</div>
)
}
export default Setting
export default Setting;
@@ -0,0 +1,54 @@
import ColorPicker from "@/components/ColorPicker";
import Radio from "@/components/Radio";
import { clx } from "@/helpers/utils";
import { PATTERN_BACKGROUND_OPACITY, usePatterns } from "@/pages/settings/hooks/usePatterns";
import { useEffect, useState, type FC } from "react";
const COLOR_APPLY_DELAY_MS = 500;
const DesignSettings: FC = () => {
const [menuColor, setMenuColor] = useState("#000000");
const [appliedColor, setAppliedColor] = useState("#000000");
const [selectedPatternId, setSelectedPatternId] = useState(1);
const patterns = usePatterns(appliedColor);
useEffect(() => {
const timer = setTimeout(() => setAppliedColor(menuColor), COLOR_APPLY_DELAY_MS);
return () => clearTimeout(timer);
}, [menuColor]);
return (
<div className="bg-white rounded-4xl p-8">
<div className="text-lg font-light">تنظیمات طراحی</div>
<div className="flex mt-5">
<div className="max-w-[506px] w-full">
<ColorPicker label="رنگ منو" value={menuColor} onChange={setMenuColor} />
<div className="mt-7">
<div className="flex gap-2 items-center">
<Radio isActive={true} value="light" onChange={() => {}} />
<div className="text-sm">انتخاب پس زمینه</div>
</div>
<div className="mt-2 flex gap-3 flex-wrap">
{patterns.map((pattern) => (
<button
key={pattern.id}
type="button"
onClick={() => setSelectedPatternId(pattern.id)}
className={clx("relative w-16 h-[139px] rounded-lg bg-white border overflow-hidden", selectedPatternId === pattern.id ? "border-black" : "border-border")}
>
<div className="absolute inset-0" style={{ backgroundColor: appliedColor, opacity: PATTERN_BACKGROUND_OPACITY }} />
<img src={pattern.image} alt={pattern.name} className="relative scale-200 w-full h-full object-cover" />
</button>
))}
</div>
</div>
</div>
</div>
</div>
);
};
export default DesignSettings;
+1
View File
@@ -4,4 +4,5 @@ export const enum SettingTabEnum {
FINANCIAL = "financial",
DELIVERY = "delivery",
NOTIFICATION = "notification",
DESIGN = "design",
}
+45
View File
@@ -0,0 +1,45 @@
import { useMemo } from "react";
import firstPattern from "@/assets/images/pattern/1.svg?raw";
import secondPattern from "@/assets/images/pattern/2.svg?raw";
import thirdPattern from "@/assets/images/pattern/3.svg?raw";
import fourthPattern from "@/assets/images/pattern/4.svg?raw";
import fifthPattern from "@/assets/images/pattern/5.svg?raw";
import sixthPattern from "@/assets/images/pattern/6.svg?raw";
const PATTERNS = [
{ id: 1, name: "طرح 1", svg: firstPattern },
{ id: 2, name: "طرح 2", svg: secondPattern },
{ id: 3, name: "طرح 3", svg: thirdPattern },
{ id: 4, name: "طرح 4", svg: fourthPattern },
{ id: 5, name: "طرح 5", svg: fifthPattern },
{ id: 6, name: "طرح 6", svg: sixthPattern },
];
export const PATTERN_BACKGROUND_OPACITY = 0.05;
export const PATTERN_VECTOR_OPACITY = 0.1;
const colorizeSvg = (svg: string, color: string) => {
let result = svg.replace(/fill="(?!black|none)[^"]+"/g, `fill="${color}"`);
result = result.replace(/fill-opacity="[^"]+"/g, `fill-opacity="${PATTERN_VECTOR_OPACITY}"`);
result = result.replace(
/(<(?:path|circle|rect|ellipse|polygon)[^>]*fill="(?!black|none)[^"]+")(?![^>]*fill-opacity)/g,
`$1 fill-opacity="${PATTERN_VECTOR_OPACITY}"`,
);
return result;
};
const svgToDataUrl = (svg: string) =>
`data:image/svg+xml;charset=utf-8,${encodeURIComponent(svg)}`;
export const usePatterns = (color: string) => {
return useMemo(
() =>
PATTERNS.map((pattern) => ({
id: pattern.id,
name: pattern.name,
image: svgToDataUrl(colorizeSvg(pattern.svg, color)),
})),
[color],
);
};