w-funnel/src/components/admin/builder/templates/DateScreenConfig.tsx
dev.daminik00 e98b1bfc05 fix
2025-09-28 15:59:45 +02:00

210 lines
8.2 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"use client";
import { TextInput } from "@/components/ui/TextInput/TextInput";
import type { DateScreenDefinition } from "@/lib/funnel/types";
import type { BuilderScreen } from "@/lib/admin/builder/types";
interface DateScreenConfigProps {
screen: BuilderScreen & { template: "date" };
onUpdate: (updates: Partial<DateScreenDefinition>) => void;
}
export function DateScreenConfig({ screen, onUpdate }: DateScreenConfigProps) {
const dateScreen = screen as DateScreenDefinition;
const handleDateInputChange = <T extends keyof DateScreenDefinition["dateInput"]>(
field: T,
value: DateScreenDefinition["dateInput"][T]
) => {
onUpdate({
dateInput: {
...dateScreen.dateInput,
[field]: value,
},
});
};
const handleZodiacSettingsChange = (
updates: Partial<NonNullable<DateScreenDefinition["dateInput"]["zodiac"]>>
) => {
const currentZodiac = dateScreen.dateInput?.zodiac ?? {
enabled: false,
storageKey: "",
};
const nextZodiac = {
...currentZodiac,
...updates,
};
const shouldRemove =
(nextZodiac.enabled ?? false) === false && (nextZodiac.storageKey ?? "") === "";
onUpdate({
dateInput: {
...dateScreen.dateInput,
zodiac: shouldRemove ? undefined : nextZodiac,
},
});
};
const handleInfoMessageChange = (field: "text" | "icon", value: string) => {
const baseInfo = dateScreen.infoMessage ?? { text: "", icon: "" };
const nextInfo = { ...baseInfo, [field]: value };
if (!nextInfo.text) {
onUpdate({ infoMessage: undefined });
return;
}
onUpdate({ infoMessage: nextInfo });
};
return (
<div className="space-y-6 rounded-2xl border border-border/70 bg-background/80 p-5 shadow-sm">
<div className="space-y-3">
<h3 className="text-sm font-semibold uppercase tracking-wide text-muted-foreground">
Поля ввода даты
</h3>
<div className="grid grid-cols-3 gap-3 text-xs">
<label className="flex flex-col gap-1 text-muted-foreground">
Подпись месяца
<TextInput
value={dateScreen.dateInput?.monthLabel ?? ""}
onChange={(event) => handleDateInputChange("monthLabel", event.target.value)}
/>
</label>
<label className="flex flex-col gap-1 text-muted-foreground">
Подпись дня
<TextInput
value={dateScreen.dateInput?.dayLabel ?? ""}
onChange={(event) => handleDateInputChange("dayLabel", event.target.value)}
/>
</label>
<label className="flex flex-col gap-1 text-muted-foreground">
Подпись года
<TextInput
value={dateScreen.dateInput?.yearLabel ?? ""}
onChange={(event) => handleDateInputChange("yearLabel", event.target.value)}
/>
</label>
</div>
<div className="grid grid-cols-3 gap-3 text-xs">
<label className="flex flex-col gap-1 text-muted-foreground">
Placeholder месяца
<TextInput
value={dateScreen.dateInput?.monthPlaceholder ?? ""}
onChange={(event) => handleDateInputChange("monthPlaceholder", event.target.value)}
/>
</label>
<label className="flex flex-col gap-1 text-muted-foreground">
Placeholder дня
<TextInput
value={dateScreen.dateInput?.dayPlaceholder ?? ""}
onChange={(event) => handleDateInputChange("dayPlaceholder", event.target.value)}
/>
</label>
<label className="flex flex-col gap-1 text-muted-foreground">
Placeholder года
<TextInput
value={dateScreen.dateInput?.yearPlaceholder ?? ""}
onChange={(event) => handleDateInputChange("yearPlaceholder", event.target.value)}
/>
</label>
</div>
</div>
<div className="space-y-3">
<h4 className="text-sm font-semibold text-foreground">Поведение поля</h4>
<label className="flex items-center gap-2 text-sm text-muted-foreground">
<input
type="checkbox"
checked={dateScreen.dateInput?.showSelectedDate === true}
onChange={(event) => handleDateInputChange("showSelectedDate", event.target.checked)}
/>
Показывать выбранную дату под полем
</label>
<div className="rounded-xl border border-border/60 p-4">
<div className="flex items-center gap-2 text-sm font-medium text-foreground">
<input
type="checkbox"
checked={dateScreen.dateInput?.zodiac?.enabled === true}
onChange={(event) =>
handleZodiacSettingsChange({ enabled: event.target.checked })
}
/>
Автоматически определять знак зодиака
</div>
<p className="mt-2 text-xs text-muted-foreground">
Если включено, система вычислит знак зодиака по выбранной дате и сохранит его по
указанному ключу. Значение можно использовать в правилах навигации и вариативности.
</p>
{dateScreen.dateInput?.zodiac?.enabled && (
<label className="mt-3 flex flex-col gap-1 text-xs text-muted-foreground">
Ключ для сохранения знака зодиака
<TextInput
placeholder="Например, userZodiac"
value={dateScreen.dateInput?.zodiac?.storageKey ?? ""}
onChange={(event) =>
handleZodiacSettingsChange({ storageKey: event.target.value.trim() })
}
/>
</label>
)}
</div>
<div className="grid grid-cols-2 gap-3 text-xs">
<label className="flex flex-col gap-1 text-muted-foreground">
Подпись выбранной даты
<TextInput
value={dateScreen.dateInput?.selectedDateLabel ?? ""}
onChange={(event) => handleDateInputChange("selectedDateLabel", event.target.value)}
/>
</label>
<label className="flex flex-col gap-1 text-muted-foreground">
Формат отображения (date-fns)
<TextInput
placeholder="MMMM d, yyyy"
value={dateScreen.dateInput?.selectedDateFormat ?? ""}
onChange={(event) => handleDateInputChange("selectedDateFormat", event.target.value)}
/>
</label>
</div>
<label className="flex flex-col gap-1 text-xs text-muted-foreground">
Текст ошибки валидации
<TextInput
placeholder="Пожалуйста, укажите корректную дату"
value={dateScreen.dateInput?.validationMessage ?? ""}
onChange={(event) => handleDateInputChange("validationMessage", event.target.value)}
/>
</label>
</div>
<div className="space-y-3">
<h4 className="text-sm font-semibold text-foreground">Информационный блок</h4>
<label className="flex flex-col gap-2 text-sm">
<span className="text-xs font-medium text-muted-foreground">Сообщение (оставьте пустым, чтобы скрыть)</span>
<TextInput
value={dateScreen.infoMessage?.text ?? ""}
onChange={(event) => handleInfoMessageChange("text", event.target.value)}
/>
</label>
{dateScreen.infoMessage && (
<label className="flex flex-col gap-2 text-sm">
<span className="text-xs font-medium text-muted-foreground">Emoji/иконка для сообщения</span>
<TextInput
value={dateScreen.infoMessage.icon ?? ""}
onChange={(event) => handleInfoMessageChange("icon", event.target.value)}
/>
</label>
)}
</div>
</div>
);
}