Packages
phoenix_kit
1.7.21
1.7.208
1.7.207
1.7.206
1.7.205
1.7.204
1.7.203
1.7.202
1.7.201
1.7.200
1.7.199
1.7.198
1.7.197
1.7.196
1.7.194
1.7.193
1.7.192
1.7.191
1.7.190
1.7.189
1.7.187
1.7.186
1.7.185
1.7.184
1.7.183
1.7.182
1.7.181
1.7.180
1.7.179
1.7.178
1.7.177
1.7.176
1.7.175
1.7.174
1.7.173
1.7.172
1.7.171
1.7.170
1.7.169
1.7.168
1.7.167
1.7.166
1.7.165
1.7.164
1.7.162
1.7.161
1.7.160
1.7.159
1.7.157
1.7.156
1.7.155
1.7.154
1.7.153
1.7.152
1.7.151
1.7.150
1.7.149
1.7.146
1.7.145
1.7.144
1.7.143
1.7.138
1.7.133
1.7.132
1.7.131
1.7.130
1.7.128
1.7.126
1.7.125
1.7.121
1.7.120
1.7.119
1.7.118
1.7.117
1.7.116
1.7.115
1.7.114
1.7.113
1.7.112
1.7.111
1.7.110
1.7.109
1.7.108
1.7.107
1.7.106
1.7.105
1.7.104
1.7.103
1.7.102
1.7.101
1.7.100
1.7.99
1.7.98
1.7.97
1.7.96
1.7.95
1.7.94
1.7.93
1.7.92
1.7.91
1.7.90
1.7.89
1.7.88
1.7.87
1.7.86
1.7.85
1.7.84
1.7.83
1.7.82
1.7.81
1.7.80
1.7.79
1.7.78
1.7.77
1.7.76
1.7.75
1.7.74
1.7.71
1.7.70
1.7.69
1.7.66
1.7.65
1.7.64
1.7.63
1.7.62
1.7.61
1.7.59
1.7.58
1.7.57
1.7.56
1.7.55
1.7.54
1.7.53
1.7.52
1.7.51
1.7.49
1.7.44
1.7.43
1.7.42
1.7.41
1.7.39
1.7.38
1.7.37
1.7.36
1.7.34
1.7.33
1.7.31
1.7.30
1.7.29
1.7.28
1.7.27
1.7.26
1.7.25
1.7.24
1.7.23
1.7.22
1.7.21
1.7.20
1.7.19
1.7.18
1.7.17
1.7.16
1.7.15
1.7.14
1.7.13
1.7.12
1.7.11
1.7.10
1.7.9
1.7.8
1.7.7
1.7.6
1.7.5
1.7.4
1.7.3
1.7.2
1.7.1
1.7.0
1.6.20
1.6.19
1.6.18
1.6.17
1.6.16
1.6.15
1.6.14
1.6.13
1.6.12
1.6.11
1.6.10
1.6.9
1.6.8
1.6.7
1.6.6
1.6.5
1.6.4
1.6.3
1.5.2
1.5.1
1.5.0
1.4.9
1.4.8
1.4.7
1.4.6
1.4.5
1.4.4
1.4.3
1.4.2
1.4.1
1.4.0
1.3.2
1.3.1
1.3.0
1.2.10
1.2.9
1.2.8
1.2.7
1.2.5
1.2.4
1.2.2
1.2.1
1.2.0
1.1.0
1.0.0
A foundation for building Elixir Phoenix apps — SaaS, social networks, ERP systems, marketplaces, and more
Current section
Files
Jump to
Current section
Files
lib/modules/ai/web/prompt_form.html.heex
<PhoenixKitWeb.Components.LayoutWrapper.app_layout
flash={@flash}
page_title={@page_title}
current_path={@current_path}
project_title={@project_title}
phoenix_kit_current_scope={@phoenix_kit_current_scope}
current_locale={assigns[:current_locale]}
>
<div class="container flex-col mx-auto px-4 py-6">
<%!-- Header Section --%>
<header class="w-full relative mb-6">
<%!-- Back Button (Left aligned) --%>
<.link
navigate={PhoenixKit.Utils.Routes.ai_path() <> "/prompts"}
class="btn btn-outline btn-primary btn-sm absolute left-0 top-0 -mb-12"
>
<.icon name="hero-arrow-left" class="w-4 h-4 mr-2" /> Back to Prompts
</.link>
<%!-- Title Section --%>
<div class="text-center">
<h1 class="text-4xl font-bold text-base-content mb-3">{@page_title}</h1>
<p class="text-lg text-base-content">
Create reusable prompts with variable substitution
</p>
</div>
</header>
<%!-- Form Content (constrained width) --%>
<div class="max-w-4xl mx-auto">
<%!-- Form --%>
<div class="card bg-base-200">
<div class="card-body">
<.form for={@form} phx-change="validate" phx-submit="save" class="space-y-5">
<%!-- Name --%>
<div>
<label class="block text-sm font-medium mb-2">
Name <span class="text-error">*</span>
</label>
<input
type="text"
name="prompt[name]"
value={@form[:name].value || ""}
class={"input input-bordered w-full #{if @form.errors[:name], do: "input-error"}"}
placeholder="e.g., Translator, Code Reviewer"
phx-debounce="1000"
required
/>
<%= if @form.errors[:name] do %>
<p class="text-error text-sm mt-1">{elem(@form.errors[:name], 0)}</p>
<% end %>
</div>
<%!-- Slug --%>
<div>
<label class="block text-sm font-medium mb-2">
Slug
<span class="text-base-content/60 font-normal ml-2">
Auto-generated from name
</span>
</label>
<input
type="text"
name="prompt[slug]"
value={@form[:slug].value || ""}
class="input input-bordered w-full font-mono text-sm bg-base-300"
placeholder="auto-generated-slug"
readonly
/>
</div>
<%!-- Description --%>
<div>
<label class="block text-sm font-medium mb-2">
Description <span class="text-base-content/60 font-normal ml-2">Optional</span>
</label>
<textarea
name="prompt[description]"
class="textarea textarea-bordered w-full"
rows="2"
placeholder="Brief description of what this prompt does..."
>{@form[:description].value || ""}</textarea>
</div>
<%!-- Content --%>
<div>
<label class="block text-sm font-medium mb-2">
Content <span class="text-error">*</span>
</label>
<textarea
name="prompt[content]"
class={"textarea textarea-bordered w-full font-mono text-sm #{if @form.errors[:content], do: "textarea-error"}"}
rows="8"
placeholder="Enter your prompt template...
Use {{VariableName}} for dynamic content.
Example:
Translate the following text to {{Language}}:
{{Text}}"
required
>{@form[:content].value || ""}</textarea>
<%= if @form.errors[:content] do %>
<p class="text-error text-sm mt-1">{elem(@form.errors[:content], 0)}</p>
<% end %>
</div>
<%!-- Extracted Variables Preview --%>
<%= if length(@extracted_variables) > 0 do %>
<div class="alert">
<.icon name="hero-variable" class="w-5 h-5" />
<div>
<div class="font-medium">Detected Variables</div>
<div class="flex flex-wrap gap-2 mt-1">
<%= for var <- @extracted_variables do %>
<span class="badge badge-primary badge-outline font-mono">
{"{{#{var}}}"}
</span>
<% end %>
</div>
</div>
</div>
<% end %>
<%!-- Enabled Toggle --%>
<div>
<label class="flex items-center gap-3 cursor-pointer">
<input
type="checkbox"
name="prompt[enabled]"
value="true"
checked={@form[:enabled].value != false}
class="checkbox checkbox-primary"
/>
<span class="font-medium">Enabled</span>
</label>
<p class="text-sm text-base-content/60 mt-1 ml-8">
Disabled prompts cannot be used via the API
</p>
</div>
<%!-- Actions --%>
<div class="flex justify-end gap-2 pt-4">
<.link
navigate={PhoenixKit.Utils.Routes.ai_path() <> "/prompts"}
class="btn btn-ghost"
>
Cancel
</.link>
<button type="submit" class="btn btn-primary">
<.icon name="hero-check" class="w-4 h-4 mr-2" />
{if @prompt, do: "Update Prompt", else: "Create Prompt"}
</button>
</div>
</.form>
</div>
</div>
<%!-- Help Section --%>
<div class="card bg-base-200 mt-6">
<div class="card-body">
<h3 class="card-title text-lg">
<.icon name="hero-question-mark-circle" class="w-5 h-5" /> Variable Syntax
</h3>
<div class="text-sm space-y-4">
<div>
<p class="mb-2">Use double curly braces for variables:</p>
<div class="bg-base-300 p-3 rounded font-mono text-xs">
Translate to {"{{Language}}"}:<br />
{"{{Text}}"}
</div>
</div>
<div>
<p class="font-medium mb-1">Naming rules:</p>
<ul class="list-disc list-inside text-base-content/70 space-y-1">
<li>
Use letters, numbers, and underscores only —
<span class="text-error">no spaces</span>
</li>
<li>
<code class="bg-base-300 px-1 rounded">{"{{UserLanguage}}"}</code>
or <code class="bg-base-300 px-1 rounded">{"{{user_language}}"}</code>
— both work
</li>
<li>
<code class="bg-base-300 px-1 rounded">{"{{User Language}}"}</code>
— won't be detected as a variable
</li>
</ul>
</div>
<div>
<p class="font-medium mb-1">Missing variables:</p>
<p class="text-base-content/70">
If a variable isn't provided when the prompt is used, it stays as-is in the output
(e.g., <code class="bg-base-300 px-1 rounded">{"{{Language}}"}</code>
remains unchanged).
</p>
</div>
</div>
</div>
</div>
</div>
</div>
</PhoenixKitWeb.Components.LayoutWrapper.app_layout>