This commit is contained in:
2025-09-16 11:18:37 +05:00
parent bc1b1cac3a
commit f66e35bc7e
5 changed files with 158 additions and 6 deletions
+2 -2
View File
@@ -2,6 +2,6 @@ import AboutMain from "@/components/pages/AboutPage/AboutMain";
import { InProcess } from "@/components/pages/InProcess";
export default function AboutPage() {
return <InProcess />;
// return <AboutMain />;
// return <InProcess />;
return <AboutMain />;
}
+3 -1
View File
@@ -9,6 +9,7 @@ import { FormProvider, SubmitHandler, useForm } from "react-hook-form";
import { ImageUploader } from "../ImageUploader";
import { FormModalHeader } from "./FormModalHeader";
import CloseIcon from "../icons/CloseIcon";
import { ColorPicker } from "@/ui/ColorPicker";
interface ICompanyFormInput {
title: string;
@@ -81,7 +82,8 @@ export function CompanyFormModal<TAction extends "create" | "edit">({
label="Загрузите или перетащите иконку ( в формате svg )"
/>
</div>
<TextInput name="color" label="Цвет" placeholder="#000000" />
{/* <TextInput name="color" label="Цвет" placeholder="#000000" /> */}
<ColorPicker name="color" label="Цвет" />
</FormProvider>
</form>
</div>
+3 -1
View File
@@ -11,6 +11,7 @@ import { TextInput } from "@/ui/TextInput";
import { DatePicker } from "@/ui/DatePicker";
import CloseIcon from "../icons/CloseIcon";
import { useModalStore } from "@/stores/useModalStore";
import { ColorPicker } from "@/ui/ColorPicker";
export interface IEventFormInput {
dates: string[]; // Изменили с Date[] на string[] для корректной сериализации
@@ -76,7 +77,8 @@ function EventFormModal<TAction extends "create" | "edit">({
required
/>
<TextInput name="location" label="Место" placeholder="" />
<TextInput name="color" label="Цвет" placeholder="" />
{/* <TextInput name="color" label="Цвет" placeholder="" /> */}
<ColorPicker name="color" label="Цвет" />
</form>
</FormProvider>
</div>
@@ -46,14 +46,14 @@ export default function AboutEventCard({
style={{ backgroundColor: color }}
className="size-2.5 rounded-full mr-2"
/>
<span>{location}</span>
<span className="font-medium">{location}</span>
</div>
<div
className="py-2.5 px-[0.833vw] rounded-[1.111vw] border border-[#FFFFFF1A]
max-lg:w-max md:max-lg:py-[1.432vw] md:max-lg:px-[2.604vw] md:max-lg:rounded-full
max-md:rounded-[4.444vw] max-md:px-[3.333vw] max-md:py-[1.333vw]"
>
<span>
<span className="font-medium">
{dates
.map((date) => format(date, "d MMMM", { locale: ru }))
.join(" ")}
+148
View File
@@ -0,0 +1,148 @@
import { ChangeEvent, useEffect, useRef, useState } from "react";
import {
FieldValues,
Path,
PathValue,
useFormContext,
useWatch,
} from "react-hook-form";
export function ColorPicker<TFieldValues extends FieldValues>({
label,
name,
required = false,
}: {
label?: string;
name: Path<TFieldValues>;
required?: boolean;
}) {
const { register, setValue, control } = useFormContext<TFieldValues>();
const [hexValue, setHexValue] = useState("");
const isUpdatingRef = useRef(false);
const currentValue = useWatch({ control, name });
// Синхронизируем hex input с текущим значением формы
useEffect(() => {
if (isUpdatingRef.current) return;
if (currentValue) {
const cleanValue = currentValue.replace("#", "");
setHexValue(cleanValue);
} else {
setHexValue("");
}
}, [currentValue]);
// Валидация и форматирование hex кода
const handleHexChange = (e: ChangeEvent<HTMLInputElement>) => {
let value = e.target.value.replace(/[^0-9A-Fa-f]/g, "").toUpperCase();
// Ограничиваем до 6 символов
if (value.length > 6) {
value = value.slice(0, 6);
}
setHexValue(value);
// Устанавливаем флаг обновления
isUpdatingRef.current = true;
// Обновляем значение формы
if (value.length === 6) {
setValue(name, `#${value}` as any);
} else if (value.length === 0) {
setValue(name, "" as any);
}
// Сбрасываем флаг после небольшой задержки
setTimeout(() => {
isUpdatingRef.current = false;
}, 0);
};
// Обработка изменения color picker
const handleColorChange = (e: ChangeEvent<HTMLInputElement>) => {
const colorValue = e.target.value;
// Устанавливаем флаг обновления
isUpdatingRef.current = true;
setValue(name, colorValue as PathValue<TFieldValues, Path<TFieldValues>>);
setHexValue(colorValue.replace("#", ""));
// Сбрасываем флаг после небольшой задержки
setTimeout(() => {
isUpdatingRef.current = false;
}, 0);
};
return (
<div className="flex flex-col gap-4 w-full">
{label && (
<label htmlFor={name + "_" + label} className="heading2 font-medium">
{label}
</label>
)}
<div className="flex gap-3 items-end">
{/* Color Picker */}
<div className="relative flex-shrink-0">
<input
type="color"
className="w-12 h-12 border border-[#37393B] rounded-lg bg-transparent cursor-pointer appearance-none"
id={name + "_" + label}
value={currentValue || "#000000"}
onChange={handleColorChange}
style={{
WebkitAppearance: "none",
MozAppearance: "none",
appearance: "none",
}}
/>
<style jsx>{`
input[type="color"]::-webkit-color-swatch-wrapper {
padding: 0;
border-radius: 0.5rem;
border: none;
}
input[type="color"]::-webkit-color-swatch {
border: none;
border-radius: 0.5rem;
}
input[type="color"]::-moz-color-swatch {
border: none;
border-radius: 0.5rem;
}
`}</style>
</div>
{/* Hex Input */}
<div className="flex-1">
<div className="flex items-center border-b border-[#37393B] pb-1">
<span className="text-[#7A7A7A] font-medium btnl mr-1">#</span>
<input
type="text"
className="flex-1 bg-transparent outline-none btnl font-medium text-white placeholder:text-[#7A7A7A] uppercase"
placeholder="000000"
value={hexValue}
onChange={handleHexChange}
maxLength={6}
/>
</div>
{hexValue.length > 0 && hexValue.length < 6 && (
<p className="text-xs text-[#7A7A7A] mt-1">
Введите 6-значный hex код
</p>
)}
</div>
</div>
{/* Скрытый input для формы */}
<input
type="hidden"
{...register(name, { required })}
value={currentValue || ""}
/>
</div>
);
}