Skip to content

Commit e6c20c4

Browse files
committed
feat: change action pages layout
1 parent 37d5774 commit e6c20c4

10 files changed

Lines changed: 13592 additions & 110 deletions

File tree

src/app/(landing)/[locale]/actions/[slug]/page.tsx

Lines changed: 38 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { ActionTriggerView } from "@/components/ActionTriggerView"
21
import { ActionIcon } from "@/components/ActionIcon"
2+
import { ActionTriggerCard } from "@/components/ActionTriggerCard"
33
import { ActionCard } from "@/components/cards/ActionCard"
44
import { Aurora } from "@/components/ui/Aurora"
55
import { LandingContainer } from "@/components/ui/LandingContainer"
@@ -13,6 +13,7 @@ import type { Media } from "@/payload-types"
1313
import { IconArrowLeft } from "@tabler/icons-react"
1414
import type { Metadata } from "next"
1515
import { notFound } from "next/navigation"
16+
import type { ReactNode } from "react"
1617

1718
export default async function ActionDetailPage({ params }: { params: LocaleSlugPageParams }) {
1819
const { locale, slug } = await getPageLocaleAndSlug(params)
@@ -24,18 +25,12 @@ export default async function ActionDetailPage({ params }: { params: LocaleSlugP
2425
const moduleJson = await fetchMediaJson(module).catch(() => null)
2526
const extractedFlowTypes = extractFlowTypesFromJson(moduleJson)
2627
const extractedFunctionDefinitions = extractFunctionDefinitionsFromJson(moduleJson)
27-
const flowTypeItems = extractedFlowTypes.map((item) => ({
28-
item,
29-
icon: item.displayIcon,
30-
}))
31-
const functionDefinitionItems = extractedFunctionDefinitions.map((item) => ({
32-
item,
33-
icon: item.displayIcon ?? "tabler:IconFunction",
34-
}))
3528
const references = (action.references ?? []).filter((reference): reference is Exclude<typeof reference, number> => typeof reference !== "number")
3629
const tags = (action.tags ?? []).filter((tag): tag is string => Boolean(tag))
3730
const actionsBlock = findPageBlock(actionsPage, "actions")
3831
const referencesLabel = actionsBlock?.referencesLabel ?? (locale === "de" ? "Referenzen" : "References")
32+
const flowTypesLabel = actionsBlock?.flowTypesLabel ?? "FlowTypes"
33+
const functionDefinitionsLabel = actionsBlock?.functionDefinitionsLabel ?? "FunctionDefinitions"
3934
const emptyDefinitionLabels = {
4035
flowTypes: actionsBlock?.noFlowTypesFoundLabel ?? (locale === "de" ? "Keine FlowTypes gefunden." : "No flow types found."),
4136
functionDefinitions: actionsBlock?.noFunctionDefinitionsFoundLabel ?? (locale === "de" ? "Keine FunctionDefinitions gefunden." : "No function definitions found."),
@@ -78,7 +73,27 @@ export default async function ActionDetailPage({ params }: { params: LocaleSlugP
7873
</div>
7974
{action.description && <div className="max-w-3xl whitespace-pre-line text-sm leading-6 text-secondary">{action.description}</div>}
8075

81-
<ActionTriggerView locale={locale} flowTypes={flowTypeItems} functionDefinitions={functionDefinitionItems} emptyLabels={emptyDefinitionLabels} />
76+
{extractedFlowTypes.length > 0 || extractedFunctionDefinitions.length > 0 ? (
77+
<div className="space-y-8">
78+
<ActionDefinitionGroup label={flowTypesLabel}>
79+
{extractedFlowTypes.length > 0 ? (
80+
extractedFlowTypes.map((item) => <ActionTriggerCard key={item.id} type="flowType" item={item} />)
81+
) : (
82+
<p className="px-2 text-sm text-tertiary">{emptyDefinitionLabels.flowTypes}</p>
83+
)}
84+
</ActionDefinitionGroup>
85+
86+
<ActionDefinitionGroup label={functionDefinitionsLabel}>
87+
{extractedFunctionDefinitions.length > 0 ? (
88+
extractedFunctionDefinitions.map((item) => <ActionTriggerCard key={item.id} type="functionDefinition" item={item} />)
89+
) : (
90+
<p className="px-2 text-sm text-tertiary">{emptyDefinitionLabels.functionDefinitions}</p>
91+
)}
92+
</ActionDefinitionGroup>
93+
</div>
94+
) : (
95+
<p className="px-2 text-sm text-tertiary">{emptyDefinitionLabels.both}</p>
96+
)}
8297

8398
{references.length > 0 && (
8499
<div className="space-y-3">
@@ -98,6 +113,19 @@ export default async function ActionDetailPage({ params }: { params: LocaleSlugP
98113
)
99114
}
100115

116+
function ActionDefinitionGroup({ label, children }: { label: string; children: ReactNode }) {
117+
return (
118+
<div className="space-y-4">
119+
<div className="flex items-center gap-3">
120+
<div className="h-px flex-1 bg-white/10" />
121+
<p className="shrink-0 text-xs font-medium tracking-wider text-tertiary">{label}</p>
122+
<div className="h-px flex-1 bg-white/10" />
123+
</div>
124+
<div className="flex flex-col gap-3">{children}</div>
125+
</div>
126+
)
127+
}
128+
101129
export async function generateMetadata({ params }: { params: LocaleSlugPageParams }): Promise<Metadata> {
102130
const { locale, slug } = await params
103131
if (!slug?.trim()) return createMetadata()

src/blocks/ActionBlock.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,20 @@ export const ActionBlock: Block = {
4242
localized: true,
4343
defaultValue: "References",
4444
},
45+
{
46+
name: "flowTypesLabel",
47+
type: "text",
48+
required: true,
49+
localized: true,
50+
defaultValue: "FlowTypes",
51+
},
52+
{
53+
name: "functionDefinitionsLabel",
54+
type: "text",
55+
required: true,
56+
localized: true,
57+
defaultValue: "FunctionDefinitions",
58+
},
4559
{
4660
name: "noFlowTypesFoundLabel",
4761
type: "text",

src/components/ActionTriggerCard.tsx

Lines changed: 27 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,18 @@
11
"use client"
22

3-
import { BaseAccordionItem } from "@/components/ui/Accordion"
43
import type { ExtractedFlowType, ExtractedFunctionDefinition } from "@/lib/actionExtraction"
5-
import { Icon } from "@code0-tech/pictor"
4+
import { IconChevronDown } from "@tabler/icons-react"
65
import { useCallback, useMemo, useState } from "react"
76
import { Card } from "./ui/Card"
87

98
interface ActionTriggerCardProps {
109
type: "flowType" | "functionDefinition"
1110
item: ExtractedFlowType | ExtractedFunctionDefinition
12-
icon?: string
1311
}
1412

15-
export function ActionTriggerCard({ type, item, icon }: ActionTriggerCardProps) {
13+
export function ActionTriggerCard({ type, item }: ActionTriggerCardProps) {
1614
const [openItem, setOpenItem] = useState<number | null>(null)
15+
const open = openItem === 0
1716
const parameters = item.kind === "functionDefinition" ? item.parameters : item.kind === "flowType" ? item.settings : []
1817
const label = type === "flowType" ? "FlowType" : "FunctionDefinition"
1918
const parameterLabel = type === "flowType" ? "Settings" : "Parameters"
@@ -22,50 +21,37 @@ export function ActionTriggerCard({ type, item, icon }: ActionTriggerCardProps)
2221
}, [])
2322
const parameterList = useMemo(
2423
() => (
25-
<div className="flex flex-col gap-2">
26-
{parameters.map((parameter) => (
27-
<div key={parameter.id} className="rounded-md bg-primary/50 p-2">
28-
<div className="text-xs font-medium text-white">{parameter.name || parameter.identifier}</div>
29-
{parameter.description && <div className="mt-1 text-xs leading-5 text-tertiary">{parameter.description}</div>}
24+
<div className="flex flex-col gap-3">
25+
<div className="grid gap-1 text-xs">
26+
<div className="text-tertiary">{label}</div>
27+
<div className="font-medium text-white">{item.identifier}</div>
28+
</div>
29+
30+
{parameters.length > 0 && (
31+
<div className="flex flex-col gap-2">
32+
<div className="text-xs text-tertiary">{parameterLabel}</div>
33+
{parameters.map((parameter) => (
34+
<div key={parameter.id} className="rounded-md bg-primary/50 p-2">
35+
<div className="text-xs font-medium text-white">{parameter.name || parameter.identifier}</div>
36+
{parameter.description && <div className="mt-1 text-xs leading-5 text-tertiary">{parameter.description}</div>}
37+
</div>
38+
))}
3039
</div>
31-
))}
40+
)}
3241
</div>
3342
),
34-
[parameters]
43+
[item.identifier, label, parameterLabel, parameters]
3544
)
3645

3746
return (
38-
<Card size="sm" className="bg-light">
39-
<div className="relative z-10 flex h-full flex-col gap-2">
40-
<div className="flex items-start justify-between gap-3">
41-
<div className="flex min-w-0 items-center gap-2">
42-
<div className="flex size-10 shrink-0 items-center justify-center rounded-lg border border-white/5 bg-light text-brand">
43-
<Icon icon={icon ?? "tabler:IconFunction"} size={24} />
44-
</div>
45-
<div className="min-w-0">
46-
<p className="text-xs tracking-wide text-tertiary">{label}</p>
47-
<h3 className="truncate tracking-wide text-white">{item.name || item.identifier}</h3>
48-
</div>
49-
</div>
50-
<div className="shrink-0 rounded-lg border border-white/5 bg-light px-2 py-1 text-xs text-tertiary">{item.identifier}</div>
51-
</div>
52-
53-
{item.description && <p className="line-clamp-3 text-sm leading-6 text-secondary">{item.description}</p>}
47+
<Card size="sm" className="bg-light p-0!">
48+
<div className="relative z-10">
49+
<button type="button" onClick={() => toggleItem(0)} className="flex w-full items-center justify-between gap-3 p-3 text-left">
50+
<span className="min-w-0 truncate text-sm font-medium text-white">{item.name || item.identifier}</span>
51+
<IconChevronDown size={16} className={`shrink-0 text-tertiary transition-transform ${open ? "rotate-180" : ""}`} />
52+
</button>
5453

55-
{parameters.length > 0 && (
56-
<div className="mt-auto pt-2">
57-
<BaseAccordionItem
58-
index={0}
59-
question={`${parameterLabel} (${parameters.length})`}
60-
isOpen={openItem === 0}
61-
onToggle={toggleItem}
62-
className="rounded-lg before:bg-none"
63-
questionClassname="pl-3 pr-1 py-0 text-sm lg:text-sm"
64-
answerClassname="px-2 pb-2 pt-0"
65-
answer={parameterList}
66-
/>
67-
</div>
68-
)}
54+
{open && <div className="border-t border-white/5 px-3 pb-3 pt-2">{parameterList}</div>}
6955
</div>
7056
</Card>
7157
)

src/components/ActionTriggerView.tsx

Lines changed: 0 additions & 56 deletions
This file was deleted.

src/components/cards/ActionCard.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ export function ActionCard({ action, locale }: { action: ActionItem; locale: App
1313
<div className="relative z-10 flex flex-col gap-4">
1414
<div className="flex items-start gap-2">
1515
{action.icon && (
16-
<div className="flex size-14 shrink-0 items-center justify-center overflow-hidden rounded-2xl border border-white/5 bg-light text-white">
16+
<div className="flex size-14 shrink-0 items-center justify-center overflow-hidden rounded-2xl border border-white/10 bg-primary text-white">
1717
<ActionIcon icon={action.icon} size={28} />
1818
</div>
1919
)}

src/components/sections/ActionSection.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ export function ActionSection({ actions, locale, content }: ActionSectionProps)
9393
})}
9494
</div>
9595
)}
96-
<div className="flex flex-col gap-4">
96+
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
9797
{filteredActions.map((action) => (
9898
<ActionCard key={action.id} action={action} locale={locale} />
9999
))}

0 commit comments

Comments
 (0)