210 lines
8.2 KiB
TypeScript
210 lines
8.2 KiB
TypeScript
"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>
|
||
);
|
||
}
|