### LiveView Template for Empty State Handling
Source: https://github.com/lalabuy948/phoenixanalytics/blob/master/examples/phoenix_mysql/AGENTS.md
Provides an example of handling empty states in LiveView streams using Tailwind CSS classes. This approach is used when direct counting or empty state checks on the stream are not supported.
```html
```
--------------------------------
### Install Phoenix Analytics dependency
Source: https://github.com/lalabuy948/phoenixanalytics/blob/master/README.md
Add the phoenix_analytics package to your project's mix.exs file to include it as a dependency.
```elixir
def deps do
[
{:phoenix_analytics, "~> 0.4"}
]
end
```
--------------------------------
### Render LiveView Form in Template (HEEx)
Source: https://github.com/lalabuy948/phoenixanalytics/blob/master/examples/phoenix_sqlite/AGENTS.md
Shows how to render a form in a Phoenix LiveView HEEx template using the `<.form>` function component, passing the form assign created with `to_form/1`. It also includes an example of rendering an input field.
```heex
<.form for={@form} id="todo-form" phx-change="validate" phx-submit="save">
<.input field={@form[:field]} type="text" />
```
--------------------------------
### GET /analytics/popular-content
Source: https://context7.com/lalabuy948/phoenixanalytics/llms.txt
Retrieves popular pages, referrers, 404 errors, and device distribution metrics.
```APIDOC
## GET /analytics/popular-content
### Description
Fetches aggregated analytics data for pages, referrers, and device types.
### Method
GET
### Endpoint
/analytics/popular-content
### Parameters
#### Query Parameters
- **from_date** (string) - Required - Start date
- **to_date** (string) - Required - End date
### Response
#### Success Response (200)
- **data** (array) - List of objects containing source and visit counts
#### Response Example
[
{"source": "/", "visits": 500},
{"source": "/products", "visits": 350}
]
```
--------------------------------
### GET /analytics/time-series
Source: https://context7.com/lalabuy948/phoenixanalytics/llms.txt
Retrieves analytics data grouped by time intervals for trend analysis.
```APIDOC
## GET /analytics/time-series
### Description
Returns metrics like visits or requests grouped by hour, day, month, or year.
### Method
GET
### Endpoint
/analytics/time-series
### Parameters
#### Query Parameters
- **interval** (string) - Required - One of: hour, day, month, year
- **from_date** (string) - Required
- **to_date** (string) - Required
### Response
#### Success Response (200)
- **data** (array) - Time-series data points
#### Response Example
[
{"date": "2024-01-01", "visits": 150, "unique_visitors": 100}
]
```
--------------------------------
### Optimize Queries with Cache Service
Source: https://context7.com/lalabuy948/phoenixanalytics/llms.txt
Provides patterns for getting, adding, and fetching analytics data with automatic caching to reduce database load.
```elixir
alias PhoenixAnalytics.Services.Cache
{:ok, value} = Cache.get("analytics:visitors:2024-01")
Cache.add("analytics:visitors:2024-01", 1234)
result = Cache.fetch("analytics:visitors:2024-01", fn ->
repo = MyApp.Repo
query = PhoenixAnalytics.Queries.Analytics.unique_visitors("2024-01-01", "2024-01-31")
repo.one(query)
end)
```
--------------------------------
### GET /analytics/average-views
Source: https://context7.com/lalabuy948/phoenixanalytics/llms.txt
Retrieves the average number of page views per visit within a specified date range.
```APIDOC
## GET /analytics/average-views
### Description
Calculates the average views per visit for the given timeframe.
### Method
GET
### Endpoint
/analytics/average-views
### Parameters
#### Query Parameters
- **from_date** (string) - Required - Start date in YYYY-MM-DD HH:MM:SS format
- **to_date** (string) - Required - End date in YYYY-MM-DD HH:MM:SS format
### Response
#### Success Response (200)
- **avg_views** (float) - The calculated average views per visit
#### Response Example
{
"avg_views": 3.5
}
```
--------------------------------
### Creating Forms from Params
Source: https://github.com/lalabuy948/phoenixanalytics/blob/master/examples/phoenix_sqlite/AGENTS.md
Illustrates how to initialize a form from event parameters, optionally nesting them under a specific name.
```elixir
def handle_event("submitted", params, socket) do
{:noreply, assign(socket, form: to_form(params))}
end
def handle_event("submitted", %{"user" => user_params}, socket) do
{:noreply, assign(socket, form: to_form(user_params, as: :user))}
end
```
--------------------------------
### Managing LiveView Streams
Source: https://github.com/lalabuy948/phoenixanalytics/blob/master/examples/phoenix_sqlite/AGENTS.md
Demonstrates how to implement LiveView streams for efficient list rendering, including appending, resetting, and handling empty states in templates.
```elixir
stream(socket, :messages, [new_msg])
stream(socket, :messages, [new_msg], reset: true)
stream(socket, :messages, [new_msg], at: -1)
stream_delete(socket, :messages, msg)
```
```heex
```
--------------------------------
### Create a form from a changeset
Source: https://github.com/lalabuy948/phoenixanalytics/blob/master/examples/phoenix_mysql/AGENTS.md
Demonstrates how to initialize a form assign in a LiveView module using an Ecto changeset. This process automatically handles data, parameters, and error mapping for the form.
```elixir
%MyApp.Users.User{} |> Ecto.Changeset.change() |> to_form()
```
--------------------------------
### Configure Phoenix Analytics
Source: https://github.com/lalabuy948/phoenixanalytics/blob/master/README.md
Set up the repository and application domain in your environment configuration file.
```elixir
config :phoenix_analytics,
repo: MyApp.Repo,
app_domain: System.get_env("PHX_HOST") || "example.com",
cache_ttl: System.get_env("CACHE_TTL") || 60
```
--------------------------------
### Run database migrations
Source: https://github.com/lalabuy948/phoenixanalytics/blob/master/README.md
Generate and execute migrations to create the necessary analytics tables in your database.
```shell
mix ecto.gen.migration add_phoenix_analytics
```
```elixir
defmodule MyApp.Repo.Migrations.AddPhoenixAnalytics do
use Ecto.Migration
def up, do: PhoenixAnalytics.Migration.up()
def down, do: PhoenixAnalytics.Migration.down()
end
```
```shell
mix ecto.migrate
```
--------------------------------
### Creating LiveView Form from Event Params
Source: https://github.com/lalabuy948/phoenixanalytics/blob/master/examples/phoenix_mysql/AGENTS.md
Shows how to create a form assignable within a LiveView from parameters received in an `handle_event`. The `to_form/1` function is used, expecting string keys in the map.
```elixir
def handle_event("submitted", params, socket) do
{:noreply, assign(socket, form: to_form(params))}
end
```
--------------------------------
### Run Database Migrations
Source: https://context7.com/lalabuy948/phoenixanalytics/llms.txt
Define and execute Ecto migrations to create the necessary analytics tables and indexes in your database.
```elixir
defmodule MyApp.Repo.Migrations.AddPhoenixAnalytics do
use Ecto.Migration
def up, do: PhoenixAnalytics.Migration.up()
def down, do: PhoenixAnalytics.Migration.down()
end
defmodule MyApp.Repo.Migrations.AddPhoenixAnalyticsIndexes do
use Ecto.Migration
def change do
PhoenixAnalytics.Migration.add_indexes()
end
end
```
--------------------------------
### Phoenix LiveView Navigation with `<.link>`
Source: https://github.com/lalabuy948/phoenixanalytics/blob/master/examples/phoenix_sqlite/AGENTS.md
Demonstrates the modern approach to navigation in Phoenix LiveView using the `<.link>` component for `navigate` and `patch` actions. It replaces deprecated functions like `live_redirect` and `live_patch`.
```heex
<.link navigate={@href}>Navigate
<.link patch={@href}>Patch
```
--------------------------------
### Implement Distributed Analytics with PubSub
Source: https://context7.com/lalabuy948/phoenixanalytics/llms.txt
Demonstrates how to subscribe to request events and broadcast logs across multiple nodes for real-time dashboards.
```elixir
alias PhoenixAnalytics.Services.PubSub
PubSub.subscribe()
request_log = %RequestLog{...}
PubSub.broadcast(request_log)
receive do
{:request_sent, request_log} -> IO.inspect(request_log)
end
```
--------------------------------
### Correct Form and Input Usage in LiveView Template (HEEx)
Source: https://github.com/lalabuy948/phoenixanalytics/blob/master/examples/phoenix_sqlite/AGENTS.md
Illustrates the correct way to use the `<.form>` and `<.input>` components in a LiveView template by always referencing the form assign (`@form`). It contrasts this with the incorrect method of directly accessing the changeset.
```heex
<%!-- ALWAYS do this (valid) --%>
<.form for={@form} id="my-form">
<.input field={@form[:field]} type="text" />
<%!-- NEVER do this (invalid) --%>
<%!--
<.form for={@changeset} id="my-form">
<.input field={@changeset[:field]} type="text" />
--%>
```
--------------------------------
### HEEx List Comprehension for Template Content
Source: https://github.com/lalabuy948/phoenixanalytics/blob/master/examples/phoenix_postgres/AGENTS.md
Demonstrates the correct way to generate template content using comprehensions in HEEx. It emphasizes using `<%= for ... %>` for iterating over collections and generating HTML, avoiding non-for comprehensions.
```heex
<%= for item <- @collection do %>
... item ...
<% end %>
```
--------------------------------
### LiveView Stream Operations for Collections
Source: https://github.com/lalabuy948/phoenixanalytics/blob/master/examples/phoenix_mysql/AGENTS.md
Demonstrates essential operations for managing collections using LiveView streams, including appending, resetting, prepending, and deleting items. These methods are crucial for efficient handling of dynamic data to prevent memory issues.
```elixir
stream(socket, :messages, [new_msg])
stream(socket, :messages, [new_msg], reset: true)
stream(socket, :messages, [new_msg], at: -1)
stream_delete(socket, :messages, msg)
```
--------------------------------
### LiveView Stream Operations
Source: https://github.com/lalabuy948/phoenixanalytics/blob/master/examples/phoenix_postgres/AGENTS.md
Demonstrates essential operations for managing collections using LiveView streams, including appending, resetting, prepending, and deleting items. It emphasizes avoiding memory issues and runtime errors with large collections.
```elixir
socket |> stream(:messages, [new_msg])
socket |> stream(:messages, [new_msg], reset: true)
socket |> stream(:messages, [new_msg], at: -1)
stream_delete(socket, :messages, msg)
```
--------------------------------
### Retrieve Analytics Metrics in Elixir
Source: https://context7.com/lalabuy948/phoenixanalytics/llms.txt
Demonstrates how to query average views per visit, popular pages, referrers, 404 errors, and device distributions using the PhoenixAnalytics query module.
```elixir
from_date = "2024-01-01 00:00:00"
to_date = "2024-01-31 23:59:59"
repo = MyApp.Repo
query = PhoenixAnalytics.Queries.Analytics.average_views_per_visit(from_date, to_date)
avg_views = repo.one(query)
query = PhoenixAnalytics.Queries.Analytics.popular_pages(from_date, to_date)
popular = repo.all(query)
query = PhoenixAnalytics.Queries.Analytics.popular_referer(from_date, to_date)
referrers = repo.all(query)
query = PhoenixAnalytics.Queries.Analytics.popular_not_found(from_date, to_date)
not_found = repo.all(query)
query = PhoenixAnalytics.Queries.Analytics.popular_device_types(from_date, to_date)
devices = repo.all(query)
```
--------------------------------
### Create LiveView Form from Changeset (Elixir)
Source: https://github.com/lalabuy948/phoenixanalytics/blob/master/examples/phoenix_sqlite/AGENTS.md
Demonstrates how to create a form assign from an Ecto changeset in a LiveView module. This form assign is then used to render the form in the template. The `:as` option is automatically computed.
```elixir
defmodule MyApp.Users.User do
use Ecto.Schema
...
end
# In LiveView module:
# Assuming you have a changeset available as @changeset
{:ok, socket} = assign(socket, :form, to_form(changeset))
# Or directly from a new changeset:
changeset = %MyApp.Users.User{} |> Ecto.Changeset.change()
{:ok, socket} = assign(socket, :form, to_form(changeset))
```
--------------------------------
### Phoenix HEEx Form Handling with Components
Source: https://github.com/lalabuy948/phoenixanalytics/blob/master/examples/phoenix_sqlite/AGENTS.md
Demonstrates the correct way to build forms in Phoenix using HEEx components. It emphasizes using `Phoenix.Component.form/1` and `Phoenix.Component.inputs_for/1`, and accessing form data via `@form[:field]`. Avoids deprecated functions like `Phoenix.HTML.form_for`.
```heex
<.form for={@form} id="msg-form">
... access fields like @form[:field] ...
```
--------------------------------
### Manage Request Logs with Batcher Service
Source: https://context7.com/lalabuy948/phoenixanalytics/llms.txt
Explains the automatic batching mechanism for request logs and how to manually insert logs into the system.
```elixir
alias PhoenixAnalytics.Services.Batcher
alias PhoenixAnalytics.Entities.RequestLog
request_log = %RequestLog{
request_id: Ecto.UUID.generate(),
method: "GET",
path: "/api/users",
status_code: 200,
duration_ms: 45
}
Batcher.insert(request_log)
```
--------------------------------
### LiveView Template for Stream Consumption
Source: https://github.com/lalabuy948/phoenixanalytics/blob/master/examples/phoenix_mysql/AGENTS.md
Illustrates the required structure for a LiveView template to consume and display data from a stream. It emphasizes setting `phx-update="stream"` on the parent element and using the stream name as the DOM ID for child elements.
```html
```
--------------------------------
### Filtering Data with LiveView Streams
Source: https://github.com/lalabuy948/phoenixanalytics/blob/master/examples/phoenix_sqlite/AGENTS.md
Shows how to filter data by refetching and re-streaming the collection with the reset option, as streams are not enumerable.
```elixir
def handle_event("filter", %{"filter" => filter}, socket) do
messages = list_messages(filter)
{:noreply,
socket
|> assign(:messages_empty?, messages == [])
|> stream(:messages, messages, reset: true)}
end
```
--------------------------------
### LiveViewTest Element Assertions
Source: https://github.com/lalabuy948/phoenixanalytics/blob/master/examples/phoenix_mysql/AGENTS.md
Demonstrates how to use `Phoenix.LiveViewTest` and `LazyHTML` for writing robust tests. It emphasizes referencing element IDs from templates and avoiding raw HTML testing in favor of element presence checks.
```elixir
assert has_element?(view, "#my-form")
```
--------------------------------
### HEEx List Comprehensions for Template Content
Source: https://github.com/lalabuy948/phoenixanalytics/blob/master/examples/phoenix_mysql/AGENTS.md
Shows the correct syntax for generating template content using list comprehensions in HEEx. It mandates the use of `<%= for ... %>` for iterating over collections, discouraging the use of `<% Enum.each %>`.
```HEEx
<%= for item <- @collection do %>
<%= item %>
<% end %>
```
--------------------------------
### HEEx List Comprehension for Template Content
Source: https://github.com/lalabuy948/phoenixanalytics/blob/master/examples/phoenix_sqlite/AGENTS.md
Illustrates the correct way to generate lists of elements within HEEx templates using `Enum.each` is discouraged. Instead, use the `<%= for ... %>` syntax for comprehensions to render collections.
```heex
<%= for item <- @collection do %>
... render item ...
<% end %>
```
--------------------------------
### Refetching and Resetting LiveView Streams
Source: https://github.com/lalabuy948/phoenixanalytics/blob/master/examples/phoenix_mysql/AGENTS.md
Shows how to refetch data and reset an entire stream collection with `reset: true` when filtering or updating items. This is the recommended approach as LiveView streams are not enumerable.
```elixir
def handle_event("filter", %{"filter" => filter}, socket) do
# re-fetch the messages based on the filter
messages = list_messages(filter)
{:noreply,
socket
|> assign(:messages_empty?, messages == [])
# reset the stream with the new messages
|> stream(:messages, messages, reset: true)}
end
```
--------------------------------
### Enable tracking and dashboard
Source: https://github.com/lalabuy948/phoenixanalytics/blob/master/README.md
Register the request tracker plug in your endpoint and define the dashboard route in your router.
```elixir
plug PhoenixAnalytics.Plugs.RequestTracker
```
```elixir
use PhoenixAnalytics.Web, :router
phoenix_analytics_dashboard "/analytics"
```
--------------------------------
### Creating Nested LiveView Form from Event Params
Source: https://github.com/lalabuy948/phoenixanalytics/blob/master/examples/phoenix_mysql/AGENTS.md
Demonstrates how to create a nested form assignable within a LiveView from event parameters. The `to_form/2` function with the `as:` option is used to specify the parameter nesting.
```elixir
def handle_event("submitted", %{"user" => user_params}, socket) do
{:noreply, assign(socket, form: to_form(user_params, as: :user))}
end
```
--------------------------------
### Create LiveView Form from Changeset in Elixir
Source: https://github.com/lalabuy948/phoenixanalytics/blob/master/examples/phoenix_postgres/AGENTS.md
Demonstrates how to create a form assignable for LiveView templates by converting an Ecto changeset. This process involves piping the changeset through `Ecto.Changeset.change/1` and then `to_form/1`. The resulting form assign can be passed to the `<.form>` component in the template.
```elixir
defmodule MyApp.Users.User do
use Ecto.Schema
...
end
# In LiveView module:
# Assuming you have a changeset named `changeset`
form_assign =
%MyApp.Users.User{}
|> Ecto.Changeset.change()
|> to_form()
```
--------------------------------
### HEEx Conditional Class Attributes
Source: https://github.com/lalabuy948/phoenixanalytics/blob/master/examples/phoenix_sqlite/AGENTS.md
Demonstrates the correct syntax for applying conditional CSS classes in HEEx templates using list syntax `[...]`. It shows how to combine static classes with dynamically added ones based on conditions, including nested `if` expressions.
```heex
Text
```
--------------------------------
### HEEx Class Attribute List Syntax for Conditional Classes
Source: https://github.com/lalabuy948/phoenixanalytics/blob/master/examples/phoenix_mysql/AGENTS.md
Demonstrates the correct way to use the class attribute in HEEx templates when dealing with multiple or conditional classes. It requires using the list `[...]` syntax and wrapping `if` expressions within `{...}` with parentheses.
```HEEx
Text
```
--------------------------------
### Elixir Conditional Logic with `cond`
Source: https://github.com/lalabuy948/phoenixanalytics/blob/master/examples/phoenix_sqlite/AGENTS.md
Illustrates the correct way to handle multiple conditional statements in Elixir HEEx templates. It shows how to use the `cond` block, which is preferred over `if/else if` or `if/elsif` for clarity and correctness.
```elixir
<%= cond do %>
<% condition -> %>
...
<% condition2 -> %>
...
<% true -> %>
...
<% end %>
```
--------------------------------
### Utilize Phoenix Analytics Utility Functions
Source: https://context7.com/lalabuy948/phoenixanalytics/llms.txt
Provides helper functions for identifying device types from user agents, generating database-compatible timestamps, creating UUIDs, and detecting the active database type.
```elixir
alias PhoenixAnalytics.Services.Utility
# Get device type from user agent string
Utility.get_device_type("Mozilla/5.0 (iPhone; CPU iPhone OS 14_4 like Mac OS X)...")
# => "mobile"
Utility.get_device_type("Mozilla/5.0 (iPad; CPU OS 14_4 like Mac OS X)...")
# => "tablet"
Utility.get_device_type("Mozilla/5.0 (Windows NT 10.0; Win64; x64)...")
# => "desktop"
# Get current timestamp in database-compatible format
Utility.inserted_at()
# => "2024-01-15 14:30:45.123"
# Generate UUID
Utility.uuid()
# => "550e8400-e29b-41d4-a716-446655440000"
# Detect configured database type
Utility.database_type()
# => :postgres | :sqlite | :mysql
```
--------------------------------
### POST /batcher/insert
Source: https://context7.com/lalabuy948/phoenixanalytics/llms.txt
Manually insert a request log into the batching service.
```APIDOC
## POST /batcher/insert
### Description
Adds a request log to the batcher for bulk insertion into the database.
### Method
POST
### Endpoint
/batcher/insert
### Request Body
- **request_id** (string) - Required
- **method** (string) - Required
- **path** (string) - Required
- **status_code** (integer) - Required
### Response
#### Success Response (200)
- **status** (string) - Confirmation of insertion
```
--------------------------------
### Phoenix LiveView Testing with LazyHTML
Source: https://github.com/lalabuy948/phoenixanalytics/blob/master/examples/phoenix_postgres/AGENTS.md
Details the use of `Phoenix.LiveViewTest` and `LazyHTML` for writing assertions in LiveView tests. It emphasizes referencing element IDs, testing outcomes, and avoiding raw HTML testing.
```elixir
assert has_element?(view, "#my-form")
html = render(view)
document = LazyHTML.from_fragment(html)
matches = LazyHTML.filter(document, "your-complex-selector")
IO.inspect(matches, label: "Matches")
```
--------------------------------
### Ecto Association Preloading
Source: https://github.com/lalabuy948/phoenixanalytics/blob/master/examples/phoenix_mysql/AGENTS.md
Illustrates the importance of preloading Ecto associations when they will be accessed in templates to avoid N+1 query problems. This ensures that related data is fetched efficiently.
```elixir
# Example of preloading an association
query = from u in User, preload: [:posts]
Repo.all(query)
```
--------------------------------
### Ecto Changeset Programmatic Field Setting
Source: https://github.com/lalabuy948/phoenixanalytics/blob/master/examples/phoenix_mysql/AGENTS.md
Explains how to handle fields that are set programmatically (e.g., `user_id`) by not including them in `cast` calls and instead setting them directly when creating the struct. This is a security best practice.
```elixir
# Incorrect: Including user_id in cast
# changeset = cast(struct, params, ~w(name email user_id))
# Correct: Setting user_id programmatically
changeset = cast(struct, params, ~w(name email))
|> put_assoc(:user, user_struct) # or similar direct assignment
```
--------------------------------
### Define Phoenix Scoped Routes
Source: https://github.com/lalabuy948/phoenixanalytics/blob/master/examples/phoenix_sqlite/AGENTS.md
Demonstrates how to use scope blocks in Phoenix to automatically alias controller or live view modules. This prevents redundant module prefixes in route definitions.
```elixir
scope "/admin", AppWeb.Admin do
pipe_through :browser
live "/users", UserLive, :index
end
```
--------------------------------
### Integrate Request Tracker Plug
Source: https://context7.com/lalabuy948/phoenixanalytics/llms.txt
Add the RequestTracker plug to your endpoint or router to begin capturing HTTP request metrics.
```elixir
plug PhoenixAnalytics.Plugs.RequestTracker
```
--------------------------------
### Query Time-Series Analytics in Elixir
Source: https://context7.com/lalabuy948/phoenixanalytics/llms.txt
Shows how to fetch time-series data grouped by intervals like 'day' or 'hour' for trend analysis and performance monitoring.
```elixir
from_date = "2024-01-01 00:00:00"
to_date = "2024-01-31 23:59:59"
repo = MyApp.Repo
query = PhoenixAnalytics.Queries.Analytics.visits_per_period(from_date, to_date, "day")
daily_visits = repo.all(query)
query = PhoenixAnalytics.Queries.Analytics.slowest_pages(from_date, to_date)
slow_pages = repo.all(query)
```
--------------------------------
### Accessing List Elements in Elixir
Source: https://github.com/lalabuy948/phoenixanalytics/blob/master/examples/phoenix_sqlite/AGENTS.md
Demonstrates the correct way to access elements in an Elixir list by index. Since Elixir lists do not support index-based access syntax, developers must use Enum.at/2 or pattern matching.
```elixir
i = 0
mylist = ["blue", "green"]
# Correct way to access by index
value = Enum.at(mylist, i)
```
--------------------------------
### Debugging LiveView Tests
Source: https://github.com/lalabuy948/phoenixanalytics/blob/master/examples/phoenix_sqlite/AGENTS.md
Provides a pattern for debugging failed test selectors by inspecting the rendered HTML fragment using LazyHTML.
```elixir
html = render(view)
document = LazyHTML.from_fragment(html)
matches = LazyHTML.filter(document, "your-complex-selector")
IO.inspect(matches, label: "Matches")
```
--------------------------------
### HEEx Interpolation within Tags and Attributes
Source: https://github.com/lalabuy948/phoenixanalytics/blob/master/examples/phoenix_sqlite/AGENTS.md
Explains the correct usage of interpolation in HEEx templates. It highlights that `{...}` should be used for attribute interpolation and within tag bodies, while `<%= ... %>` is for block constructs (if, cond, case, for) within tag bodies.
```heex
{@my_assign}
<%= if @some_block_condition do %>
{@another_assign}
<% end %>
```
--------------------------------
### Binding Expressions in Elixir
Source: https://github.com/lalabuy948/phoenixanalytics/blob/master/examples/phoenix_sqlite/AGENTS.md
Illustrates the correct approach to binding results from conditional expressions in Elixir. Because variables are immutable, results must be assigned to a variable rather than attempting to rebind inside a block.
```elixir
socket =
if connected?(socket) do
assign(socket, :val, val)
else
socket
end
```
--------------------------------
### Configure Dashboard Routes
Source: https://context7.com/lalabuy948/phoenixanalytics/llms.txt
Expose the built-in analytics dashboard by adding the dashboard route macro to your Phoenix router.
```elixir
use PhoenixAnalytics.Web, :router
phoenix_analytics_dashboard "/analytics"
phoenix_analytics_dashboard "/admin/analytics",
as: :admin_analytics_dashboard,
on_mount: [MyAppWeb.AuthHook],
root_layout: {MyAppWeb.Layouts, :admin_root}
```
--------------------------------
### HEEx HTML Comment Syntax
Source: https://github.com/lalabuy948/phoenixanalytics/blob/master/examples/phoenix_sqlite/AGENTS.md
Specifies the correct syntax for creating HTML comments within HEEx templates. It uses the `<%!-- comment --%>` syntax, ensuring comments are properly processed by the HEEx engine.
```heex
<%!-- This is a HEEx HTML comment --%>
```
--------------------------------
### Ecto Changeset Field Access
Source: https://github.com/lalabuy948/phoenixanalytics/blob/master/examples/phoenix_mysql/AGENTS.md
Demonstrates the correct method for accessing fields within an Ecto.Changeset using `Ecto.Changeset.get_field/3`. This is the recommended way to retrieve field values from a changeset.
```elixir
changeset = %YourSchema.Changeset{}
field_value = Ecto.Changeset.get_field(changeset, :your_field_name)
```
--------------------------------
### Correct vs Incorrect form access
Source: https://github.com/lalabuy948/phoenixanalytics/blob/master/examples/phoenix_mysql/AGENTS.md
Highlights the mandatory pattern of accessing form fields via the form assign rather than the changeset directly. Direct changeset access in templates is unsupported and causes runtime errors.
```html+heex
<%!-- Valid pattern --%>
<.form for={@form} id="my-form">
<.input field={@form[:field]} type="text" />
<%!-- Invalid pattern --%>
<.form for={@changeset} id="my-form">
<.input field={@changeset[:field]} type="text" />
```
--------------------------------
### Ecto Schema Field Definition
Source: https://github.com/lalabuy948/phoenixanalytics/blob/master/examples/phoenix_mysql/AGENTS.md
Shows the convention of using the `:string` type for all Ecto.Schema fields, including those that map to `:text` columns in the database. This ensures consistency in schema definitions.
```elixir
defmodule MyApp.User do
use Ecto.Schema
schema "users" do
field :name, :string
field :email, :string
# ... other fields
timestamps()
end
end
```
--------------------------------
### Query Analytics Data
Source: https://context7.com/lalabuy948/phoenixanalytics/llms.txt
Use the provided query modules to programmatically retrieve metrics like unique visitors, pageviews, and response times.
```elixir
query = PhoenixAnalytics.Queries.Analytics.unique_visitors(from_date, to_date)
repo.one(query)
query = PhoenixAnalytics.Queries.Analytics.total_pageviews(from_date, to_date)
repo.one(query)
query = PhoenixAnalytics.Queries.Analytics.average_response_time(from_date, to_date)
repo.one(query)
```
--------------------------------
### Incorrect Usage of LiveView Form Components in HEEx
Source: https://github.com/lalabuy948/phoenixanalytics/blob/master/examples/phoenix_postgres/AGENTS.md
Highlights an anti-pattern in Phoenix LiveView HEEx templates where a changeset is directly passed to the `<.form>` component or its fields are accessed directly from the changeset. This is explicitly forbidden and will lead to errors. Always use a form assign derived from `to_form/2`.
```heex
<%!-- NEVER do this (invalid) --%>
<.form for={@changeset} id="my-form">
<.input field={@changeset[:field]} type="text" />
```
--------------------------------
### Phoenix LiveView JS Hook with `phx-update="ignore"`
Source: https://github.com/lalabuy948/phoenixanalytics/blob/master/examples/phoenix_sqlite/AGENTS.md
Explains the requirement to use `phx-update="ignore"` when a JS hook manages its own DOM manipulation. This prevents LiveView from attempting to reconcile changes that the hook has already handled.
```heex
```
--------------------------------
### HEEx Literal Curly Brace Interpolation
Source: https://github.com/lalabuy948/phoenixanalytics/blob/master/examples/phoenix_sqlite/AGENTS.md
Shows how to display literal curly braces `{` and `}` within HEEx templates, particularly in code blocks like `` or ``. The `phx-no-curly-interpolation` attribute is used to disable automatic interpolation.
```heex
let obj = {key: "val"}
```
--------------------------------
### Binding Results of Conditional Expressions in Elixir
Source: https://github.com/lalabuy948/phoenixanalytics/blob/master/examples/phoenix_mysql/AGENTS.md
Elixir variables are immutable. This snippet shows how to correctly bind the result of a conditional expression to a variable instead of attempting to rebind inside the block.
```elixir
socket =
if connected?(socket) do
assign(socket, :val, val)
end
```
=== COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.