design setting part pattern
This commit is contained in:
@@ -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;
|
||||
@@ -4,4 +4,5 @@ export const enum SettingTabEnum {
|
||||
FINANCIAL = "financial",
|
||||
DELIVERY = "delivery",
|
||||
NOTIFICATION = "notification",
|
||||
DESIGN = "design",
|
||||
}
|
||||
|
||||
@@ -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],
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user