Terminal Management

Monitor and manage your payment terminals

<.link patch={~p"/terminals/new"} class="inline-flex items-center px-4 py-2 bg-blue-600 hover:bg-blue-700 text-white font-medium rounded-lg shadow-sm transition-colors duration-200"> New Terminal

Filters & Search

<.input name="device_sn" value={@filters["device_sn"]} placeholder="Enter device serial" phx-debounce="300" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent" />
<.select name="area" value={@filters["area"]} options={[{"", ""} | @filter_options.areas]} class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent" />
<.select name="vendor" value={@filters["vendor"]} options={[{"", ""} | @filter_options.vendors]} class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent" />
<.select name="group" value={@filters["group"]} options={[{"", ""} | Enum.map(@terminal_groups, &{&1.name, &1.name})]} class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent" />
<.select name="model" value={@filters["model"]} options={[{"", ""} | @filter_options.models]} class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent" />
Showing <%= (@page - 1) * @per_page + 1 %> to <%= min(@page * @per_page, @total) %> of <%= @total %> terminals
<.input type="number" min="1" max={div(@total, @per_page) + 1} value={@page} phx-change="paginate" name="page" class="w-16 px-2 py-1 text-sm border border-gray-300 rounded" /> of <%= div(@total, @per_page) + 1 %>
<%= if @selected_terminal do %> <.slide_over origin="right" title={"Terminal: #{@selected_terminal.serial_number}"}>

Terminal Details

Serial: <%= @selected_terminal.serial_number %>

<%= String.capitalize(@selected_terminal.status || "unknown") %>
<%= if @tab == "details" do %>

Base Information

<%= if assigns[:edit_mode] && @edit_mode do %> <% else %> <% end %>
<%= if assigns[:edit_mode] && @edit_mode do %>
<.select name="terminal_form[area]" value={@terminal_form["area"] || Map.get(@selected_terminal, :area) || ""} options={[{"", ""} | @filter_options.areas]} class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent" />
<.select name="terminal_form[vendor]" value={@terminal_form["vendor"] || Map.get(@selected_terminal, :vendor) || ""} options={[{"", ""} | @filter_options.vendors]} class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent" />
<.select name="terminal_form[model]" value={@terminal_form["model"] || Map.get(@selected_terminal, :model) || ""} options={[{"", ""} | @filter_options.models]} class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent" />
<.select name="terminal_form[group]" value={@terminal_form["group"] || Map.get(@selected_terminal, :group) || ""} options={[{"", ""} | Enum.map(@terminal_groups, &{&1.name, &1.name})]} class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent" />
<% else %>
<%= for {label, value, icon} <- [ {"Device Serial", @selected_terminal.serial_number, "M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707L16.293 6.293A1 1 0 0015.586 6H7a2 2 0 00-2 2v11a2 2 0 002 2z"}, {"OID", @selected_terminal.oid, "M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"}, {"Area", Map.get(@selected_terminal, :area, "-"), "M17.657 16.657L13.414 20.9a1.998 1.998 0 01-2.827 0l-4.244-4.243a8 8 0 1111.314 0z"}, {"Vendor", Map.get(@selected_terminal, :vendor, "-"), "M19 21V5a2 2 0 00-2-2H7a2 2 0 00-2 2v16m14 0h2m-2 0h-5m-9 0H3m2 0h5M9 7h1m-1 4h1m4-4h1m-1 4h1m-5 10v-5a1 1 0 011-1h4a1 1 0 011 1v5m-6 0h6"}, {"Model", Map.get(@selected_terminal, :model, "-"), "M9 3v2m6-2v2M9 19v2m6-2v2M5 9H3m2 6H3m18-6h-2m2 6h-2M7 19h10a2 2 0 002-2V7a2 2 0 00-2-2H7a2 2 0 00-2 2v10a2 2 0 002 2zM9 9h6v6H9V9z"}, {"Status", String.capitalize(@selected_terminal.status || "unknown"), "M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"}, {"Group", Map.get(@selected_terminal, :group, "-"), "M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z"}, {"IMEI", Map.get(@selected_terminal, :imei, "-"), "M12 18h.01M8 21h8a2 2 0 002-2V5a2 2 0 00-2-2H8a2 2 0 00-2 2v14a2 2 0 002 2z"} ] do %>
<%= label %>

<%= value || "-" %>

<% end %> <%= if Map.get(@selected_terminal, :remarks) && Map.get(@selected_terminal, :remarks) != "" do %>
Remarks

<%= Map.get(@selected_terminal, :remarks) %>

<% end %>
<% end %>

Version Information

<%= for {label, value, color} <- [ {"App Version", Map.get(@selected_terminal, :app_version, "-"), "blue"}, {"Data Version", Map.get(@selected_terminal, :data_version, "-"), "purple"}, {"System Version", Map.get(@selected_terminal, :system_version, "-"), "indigo"} ] do %>

<%= label %>

<%= value %>

<% end %>

Latest Status

Heartbeat Interval
<%= Map.get(@selected_terminal, :heart, "-") %> seconds
<% end %> <%= if @tab == "history" do %> <.history_tab history_filters={@history_filters} history_rows={@history_rows} /> <% end %> <%= if @tab == "location" do %> <.location_tab /> <% end %> <%= if @tab == "apk" do %> <.apk_tab /> <% end %> <%= if @tab == "traffic" do %> <.traffic_tab /> <% end %> <%= if @tab == "remote" do %> <.remote_tab selected_terminal={@selected_terminal} remote_connected={@remote_connected} remote_logging={@remote_logging} remote_mode={@remote_mode} remote_logs={@remote_logs} remote_log_count={@remote_log_count} /> <% end %> <%= if @tab == "push_config" do %>

Push Configuration

Configure terminal settings and connection parameters

Connection Settings

Security Settings

System Settings

<% end %> <%= if @tab == "push_package" do %>

Deploy App Package

Install or update application packages on the terminal

Select an application package to deploy to the terminal. The deployment process will be handled in the background.

Override version checks and force installation

Create backup before installing new version

<% end %> <%= if @tab == "push_params" do %>

Push Terminal Parameters

Send configuration parameters to the terminal

Fill in the parameters you want to update. Leave fields empty to keep current values unchanged.

Connection Parameters

Security Parameters

System Parameters

<% end %> <%= if @tab == "file_download" do %>

Send File Download Command

Instruct the terminal to download files from specified URLs

Configure file download parameters. The terminal will download the file to the specified local path.

Enter the complete URL where the file can be downloaded

Name to save the file as

Choose where to save the file on the terminal

Categorize the file type for better organization

Mark as merchant-specific configuration

<% end %>
<.button type="button" label="Close" color="white" phx-click="close_panel" class="inline-flex items-center px-4 py-2 bg-gray-600 hover:bg-gray-700 text-white font-medium rounded-lg shadow-sm transition-colors duration-200" />
<% end %> <%= if assigns[:show_new_terminal] && @show_new_terminal do %> <.slide_over origin="right" title="Create New Terminal">

Essential Information

<%= if @new_terminal_errors["serial_number"] do %>

<%= @new_terminal_errors["serial_number"] %>

<% end %>
<%= if @new_terminal_errors["imei"] do %>

<%= @new_terminal_errors["imei"] %>

<% end %>
<.select name="new_terminal_form[model]" value={@new_terminal_form["model"] || ""} options={[{"", ""} | @filter_options.models]} required class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent" /> <%= if @new_terminal_errors["model"] do %>

<%= @new_terminal_errors["model"] %>

<% end %>
<.select name="new_terminal_form[vendor]" value={@new_terminal_form["vendor"] || ""} options={[{"", ""} | @filter_options.vendors]} required class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent" /> <%= if @new_terminal_errors["vendor"] do %>

<%= @new_terminal_errors["vendor"] %>

<% end %>

Location & Organization

<.select name="new_terminal_form[area]" value={@new_terminal_form["area"] || ""} options={[{"", ""} | @filter_options.areas]} class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent" />
<.select name="new_terminal_form[group]" value={@new_terminal_form["group"] || ""} options={[{"", ""} | Enum.map(@terminal_groups, &{&1.name, &1.name})]} class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent" />

Technical Details

Version Information (Optional)

Additional Notes

<% end %>