add screen to funnel soulmate

This commit is contained in:
dev.daminik00 2025-10-09 00:45:32 +02:00
parent fc003e6ada
commit 2c5c525c99
4 changed files with 139 additions and 19 deletions

View File

@ -124,7 +124,7 @@
},
"navigation": {
"rules": [],
"defaultNextScreenId": "relationship-status",
"defaultNextScreenId": "partner-gender",
"isEndScreen": false
},
"list": {
@ -147,6 +147,50 @@
},
"variants": []
},
{
"id": "partner-gender",
"template": "list",
"header": {
"showBackButton": true,
"show": true
},
"title": {
"text": "Кто вас интересует?",
"show": true,
"font": "manrope",
"weight": "bold",
"size": "2xl",
"align": "left",
"color": "default"
},
"bottomActionButton": {
"show": false,
"cornerRadius": "3xl",
"showPrivacyTermsConsent": false
},
"navigation": {
"rules": [],
"defaultNextScreenId": "relationship-status",
"isEndScreen": false
},
"list": {
"selectionType": "single",
"options": [
{
"id": "male",
"label": "Male",
"disabled": false
},
{
"id": "female",
"label": "Female",
"disabled": false
}
],
"registrationFieldKey": "partner.gender"
},
"variants": []
},
{
"id": "relationship-status",
"template": "list",
@ -2268,10 +2312,6 @@
"cornerRadius": "3xl",
"showPrivacyTermsConsent": false
},
"navigation": {
"rules": [],
"isEndScreen": false
},
"variants": [],
"headerBlock": {
"text": {

View File

@ -28,7 +28,7 @@ export function BuilderSidebar() {
const dispatch = useBuilderDispatch();
const selectedScreen = useBuilderSelectedScreen();
const [activeTab, setActiveTab] = useState<"funnel" | "screen">(
const [activeTab, setActiveTab] = useState<"funnel" | "screen" | "data">(
selectedScreen ? "screen" : "funnel"
);
const selectedScreenId = selectedScreen?.id ?? null;
@ -360,6 +360,18 @@ export function BuilderSidebar() {
>
Экран
</button>
<button
type="button"
className={cn(
"flex-1 rounded-md px-3 py-1.5 transition",
activeTab === "data"
? "bg-background text-foreground shadow"
: "text-muted-foreground hover:text-foreground"
)}
onClick={() => setActiveTab("data")}
>
Данные
</button>
</div>
</div>
@ -478,6 +490,40 @@ export function BuilderSidebar() {
</div>
</Section>
</div>
) : activeTab === "data" ? (
<div className="flex flex-col gap-4">
<Section title="List экраны и опции" alwaysExpanded>
{state.screens
.filter((screen) => screen.template === "list")
.map((screen) => (
<div
key={screen.id}
className="flex flex-col gap-1.5 rounded-lg border border-border/60 bg-muted/20 p-2.5 text-xs"
>
<div className="font-semibold text-foreground">
{screen.id}
</div>
<div className="flex flex-wrap gap-1">
{isListScreen(screen) &&
screen.list.options.map((option) => (
<code
key={option.id}
className="rounded bg-primary/10 px-1.5 py-0.5 text-[10px] text-primary font-mono"
>
{option.id}
</code>
))}
</div>
</div>
))}
{state.screens.filter((screen) => screen.template === "list")
.length === 0 && (
<div className="rounded-lg border border-border/60 bg-muted/30 p-3 text-center text-xs text-muted-foreground">
Нет list экранов
</div>
)}
</Section>
</div>
) : selectedScreen ? (
<div className="flex flex-col gap-4">
{/* Валидация всегда вверху, без заголовка */}

View File

@ -67,13 +67,6 @@ export function ListTemplate({
? buttons.filter((button) => selectionSet.has(String(button.id)))
: null;
const handleRadioChange: RadioAnswersListProps["onChangeSelectedAnswer"] = (
answer
) => {
const id = stringId(answer?.id);
onSelectionChange(id ? [id] : []);
};
const handleRadioAnswerClick: RadioAnswersListProps["onAnswerClick"] = (
answer
) => {
@ -93,7 +86,8 @@ export function ListTemplate({
const radioContent: RadioAnswersListProps = {
answers: buttons,
activeAnswer,
onChangeSelectedAnswer: handleRadioChange,
// Не передаем onChangeSelectedAnswer чтобы избежать двойного вызова при клике
// onAnswerClick достаточно для обработки выбора
onAnswerClick: handleRadioAnswerClick,
};

View File

@ -433,7 +433,7 @@ export const BAKED_FUNNELS: Record<string, FunnelDefinition> = {
},
"navigation": {
"rules": [],
"defaultNextScreenId": "relationship-status",
"defaultNextScreenId": "partner-gender",
"isEndScreen": false
},
"list": {
@ -456,6 +456,50 @@ export const BAKED_FUNNELS: Record<string, FunnelDefinition> = {
},
"variants": []
},
{
"id": "partner-gender",
"template": "list",
"header": {
"showBackButton": true,
"show": true
},
"title": {
"text": "Кто вас интересует?",
"show": true,
"font": "manrope",
"weight": "bold",
"size": "2xl",
"align": "left",
"color": "default"
},
"bottomActionButton": {
"show": false,
"cornerRadius": "3xl",
"showPrivacyTermsConsent": false
},
"navigation": {
"rules": [],
"defaultNextScreenId": "relationship-status",
"isEndScreen": false
},
"list": {
"selectionType": "single",
"options": [
{
"id": "male",
"label": "Male",
"disabled": false
},
{
"id": "female",
"label": "Female",
"disabled": false
}
],
"registrationFieldKey": "partner.gender"
},
"variants": []
},
{
"id": "relationship-status",
"template": "list",
@ -2577,10 +2621,6 @@ export const BAKED_FUNNELS: Record<string, FunnelDefinition> = {
"cornerRadius": "3xl",
"showPrivacyTermsConsent": false
},
"navigation": {
"rules": [],
"isEndScreen": false
},
"variants": [],
"headerBlock": {
"text": {