simpleshop_printify/lib/simpleshop_web/live/debug_live.ex

195 lines
7.4 KiB
Elixir
Raw Permalink Normal View History

2025-11-30 11:05:49 +00:00
defmodule SimpleshopWeb.DebugLive do
use SimpleshopWeb, :live_view
require Logger
@impl true
def mount(_params, _session, socket) do
send(self(), :fetch_shops)
{:ok,
socket
|> assign(:loading, true)
|> assign(:shops, [])
|> assign(:error, nil)
|> assign(:response_details, nil)}
end
@impl true
def handle_info(:fetch_shops, socket) do
config = Application.get_env(:simpleshop, :printify)
token = Keyword.get(config, :access_token)
if token && token != "your_personal_access_token_here" do
url = "https://api.printify.com/v1/shops.json"
# Try without the Content-Type header - some APIs don't like it for GET requests
headers = [
{"Authorization", "Bearer #{token}"},
{"User-Agent", "SimpleshopMVP"}
]
Logger.info("Making request to: #{url}")
Logger.info("Token (first 20 chars): #{String.slice(token, 0, 20)}...")
case Req.get(url, headers: headers) do
{:ok, %{status: 200, body: shops}} ->
Logger.info("Successfully fetched #{length(shops)} shops")
{:noreply,
socket
|> assign(:loading, false)
|> assign(:shops, shops)
|> assign(:error, nil)
|> assign(:response_details, nil)}
{:ok, %{status: status, body: body, headers: resp_headers}} ->
Logger.error("Failed to fetch shops: #{status}")
Logger.error("Response body: #{inspect(body)}")
Logger.error("Response headers: #{inspect(resp_headers)}")
error_msg = case body do
%{"errors" => errors} -> "API Error: #{inspect(errors)}"
%{"message" => message} -> "API Error: #{message}"
_ -> inspect(body)
end
{:noreply,
socket
|> assign(:loading, false)
|> assign(:error, "HTTP #{status}: Authentication failed")
|> assign(:response_details, %{
status: status,
body: body,
error_msg: error_msg
})}
{:error, error} ->
Logger.error("HTTP error fetching shops: #{inspect(error)}")
{:noreply,
socket
|> assign(:loading, false)
|> assign(:error, "Network error: #{inspect(error)}")
|> assign(:response_details, nil)}
end
else
{:noreply,
socket
|> assign(:loading, false)
|> assign(:error, "Access token not configured. Please add it to config/dev.exs")
|> assign(:response_details, nil)}
end
end
@impl true
def render(assigns) do
~H"""
<div class="mx-auto max-w-4xl py-12 px-4">
<h1 class="text-3xl font-bold mb-8">Printify Shop Information</h1>
<%= if @loading do %>
<div class="text-center py-12">
<div class="animate-spin rounded-full h-16 w-16 border-b-2 border-blue-600 mx-auto"></div>
<p class="text-gray-600 mt-4">Fetching your shop information...</p>
</div>
<% else %>
<%= if @error do %>
<div class="bg-red-50 border border-red-200 rounded-lg p-6 mb-6">
<h2 class="text-lg font-semibold text-red-800 mb-2">Error</h2>
<p class="text-red-700 mb-4"><%= @error %></p>
<%= if @response_details do %>
<div class="mt-4 p-4 bg-white rounded border border-red-300">
<p class="text-sm font-semibold text-gray-700 mb-2">Debug Information:</p>
<div class="text-xs text-gray-600 space-y-2">
<p><strong>Status Code:</strong> <%= @response_details.status %></p>
<p><strong>Error Message:</strong> <%= @response_details.error_msg %></p>
<details class="mt-2">
<summary class="cursor-pointer text-gray-700 hover:text-gray-900">Full Response Body</summary>
<pre class="mt-2 bg-gray-100 p-2 rounded overflow-auto text-xs"><%= Jason.encode!(@response_details.body, pretty: true) %></pre>
</details>
</div>
</div>
<div class="mt-4 p-4 bg-yellow-50 rounded border border-yellow-300">
<p class="text-sm font-semibold text-yellow-900 mb-2">Troubleshooting Tips:</p>
<ul class="text-xs text-yellow-800 space-y-1 list-disc list-inside">
<li>Make sure you copied the FULL token (it's very long)</li>
<li>Check that there are no extra spaces before or after the token</li>
<li>The token should start with "eyJ"</li>
<li>Make sure the token hasn't expired</li>
<li>Try creating a new Personal Access Token in Printify</li>
</ul>
</div>
<% end %>
</div>
<% else %>
<%= if @shops == [] do %>
<div class="bg-yellow-50 border border-yellow-200 rounded-lg p-6">
<p class="text-yellow-800">No shops found for this account.</p>
</div>
<% else %>
<div class="space-y-6">
<%= for shop <- @shops do %>
<div class="bg-white border border-gray-200 rounded-lg shadow-sm p-6">
<div class="mb-4 pb-4 border-b">
<h2 class="text-2xl font-bold text-gray-900"><%= shop["title"] %></h2>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<div class="bg-green-50 border border-green-200 rounded-lg p-4">
<p class="text-sm font-semibold text-green-900 mb-2">Shop ID (Use this!)</p>
<p class="text-2xl font-mono font-bold text-green-700">
<%= shop["id"] %>
</p>
</div>
<div class="space-y-2">
<div>
<p class="text-sm font-medium text-gray-600">Sales Channel</p>
<p class="text-gray-900"><%= shop["sales_channel"] || "N/A" %></p>
</div>
</div>
</div>
<div class="mt-6 p-4 bg-blue-50 rounded-lg">
<p class="text-sm text-blue-800">
<strong>Next step:</strong> Copy the Shop ID above and paste it into
<code class="bg-blue-100 px-2 py-1 rounded">config/dev.exs</code>
</p>
<pre class="mt-2 text-xs bg-blue-100 p-2 rounded overflow-x-auto">shop_id: "<%= shop["id"] %>",</pre>
</div>
<details class="mt-4">
<summary class="cursor-pointer text-sm text-gray-600 hover:text-gray-800">
View full shop details (JSON)
</summary>
<pre class="mt-2 bg-gray-100 p-4 rounded-lg overflow-auto text-xs"><%= Jason.encode!(shop, pretty: true) %></pre>
</details>
</div>
<% end %>
</div>
<% end %>
<% end %>
<div class="mt-8 flex gap-4">
<.link
navigate={~p"/"}
class="inline-block bg-gray-600 text-white px-6 py-2 rounded-lg hover:bg-gray-700"
>
Back to Home
</.link>
<.link
navigate={~p"/products"}
class="inline-block bg-blue-600 text-white px-6 py-2 rounded-lg hover:bg-blue-700"
>
View Products
</.link>
</div>
<% end %>
</div>
"""
end
end