1
.playwright-mcp/console-2026-03-11T07-32-37-946Z.log
Normal file
@@ -0,0 +1 @@
|
||||
[ 42ms] [ERROR] Failed to load resource: the server responded with a status of 404 (Not Found) @ http://localhost:3000/favicon.ico:0
|
||||
1
.playwright-mcp/console-2026-03-11T07-40-40-472Z.log
Normal file
@@ -0,0 +1 @@
|
||||
[ 105ms] [ERROR] Failed to load resource: the server responded with a status of 404 (Not Found) @ http://localhost:3000/favicon.ico:0
|
||||
1
.playwright-mcp/console-2026-03-15T16-15-09-664Z.log
Normal file
@@ -0,0 +1 @@
|
||||
[ 314ms] [ERROR] Failed to load resource: the server responded with a status of 404 () @ https://client.dev.forage.sh/favicon.ico:0
|
||||
1
.playwright-mcp/console-2026-03-15T16-15-44-059Z.log
Normal file
@@ -0,0 +1 @@
|
||||
[ 61ms] [ERROR] Failed to load resource: the server responded with a status of 502 () @ chrome-error://chromewebdata/:0
|
||||
BIN
desktop-dashboard-v2.png
Normal file
|
After Width: | Height: | Size: 80 KiB |
BIN
mobile-dashboard-v2.png
Normal file
|
After Width: | Height: | Size: 100 KiB |
BIN
mobile-dashboard.png
Normal file
|
After Width: | Height: | Size: 103 KiB |
BIN
mobile-hamburger-open.png
Normal file
|
After Width: | Height: | Size: 51 KiB |
BIN
mobile-home-v2.png
Normal file
|
After Width: | Height: | Size: 39 KiB |
BIN
mobile-home.png
Normal file
|
After Width: | Height: | Size: 175 KiB |
BIN
mobile-integrations.png
Normal file
|
After Width: | Height: | Size: 89 KiB |
BIN
mobile-login.png
Normal file
|
After Width: | Height: | Size: 34 KiB |
BIN
mobile-marketing-menu-open.png
Normal file
|
After Width: | Height: | Size: 41 KiB |
BIN
mobile-members-v2.png
Normal file
|
After Width: | Height: | Size: 34 KiB |
BIN
mobile-members.png
Normal file
|
After Width: | Height: | Size: 36 KiB |
BIN
mobile-pricing.png
Normal file
|
After Width: | Height: | Size: 130 KiB |
BIN
mobile-projects.png
Normal file
|
After Width: | Height: | Size: 27 KiB |
BIN
mobile-settings.png
Normal file
|
After Width: | Height: | Size: 86 KiB |
BIN
mobile-tokens-v2.png
Normal file
|
After Width: | Height: | Size: 35 KiB |
BIN
mobile-tokens.png
Normal file
|
After Width: | Height: | Size: 38 KiB |
BIN
pipelines-page.png
Normal file
|
After Width: | Height: | Size: 58 KiB |
BIN
release-detail.png
Normal file
|
After Width: | Height: | Size: 80 KiB |
@@ -1,4 +1,28 @@
|
||||
@import "tailwindcss";
|
||||
@source "../../templates";
|
||||
|
||||
/* ── Scrollbar-hidden utility for tab navigation ──────────────────────── */
|
||||
@utility scrollbar-none {
|
||||
-ms-overflow-style: none;
|
||||
scrollbar-width: none;
|
||||
&::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* ── Mobile/Desktop visibility ────────────────────────────────────────── */
|
||||
@utility mobile-only {
|
||||
display: none;
|
||||
@media (max-width: 39.999rem) {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
@utility desktop-only {
|
||||
@media (max-width: 39.999rem) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* ── Dark mode (system preference) ──────────────────────────────────────── */
|
||||
/* Remap Tailwind's color variables so all existing utilities adapt automatically. */
|
||||
|
||||
@@ -33,8 +33,8 @@
|
||||
<a href="/orgs/{{ current_org }}/projects" class="font-medium text-gray-900 hover:text-black">{{ current_org }}</a>
|
||||
{% endif %}
|
||||
{% if projects is defined and projects | length > 0 %}
|
||||
<span class="text-gray-300">/</span>
|
||||
<details class="relative">
|
||||
<span class="text-gray-300 desktop-only">/</span>
|
||||
<details class="relative desktop-only">
|
||||
<summary class="font-medium text-gray-900 hover:text-black cursor-pointer list-none truncate">
|
||||
{% if project_name is defined and project_name %}{{ project_name }}{% else %}Select project{% endif %}
|
||||
<svg class="inline w-3 h-3 ml-0.5 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"/></svg>
|
||||
@@ -46,46 +46,67 @@
|
||||
</div>
|
||||
</details>
|
||||
{% elif project_name is defined and project_name %}
|
||||
<span class="text-gray-300">/</span>
|
||||
<a href="/orgs/{{ current_org }}/projects/{{ project_name }}" class="font-medium text-gray-900 hover:text-black truncate">{{ project_name }}</a>
|
||||
<span class="text-gray-300 desktop-only">/</span>
|
||||
<a href="/orgs/{{ current_org }}/projects/{{ project_name }}" class="font-medium text-gray-900 hover:text-black truncate desktop-only">{{ project_name }}</a>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</div>
|
||||
{# Right-side actions #}
|
||||
<div class="flex items-center gap-3 shrink-0">
|
||||
<a href="/notifications" class="text-gray-400 hover:text-gray-900 relative" title="Notifications">
|
||||
<svg class="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M14.857 17.082a23.848 23.848 0 005.454-1.31A8.967 8.967 0 0118 9.75v-.7V9A6 6 0 006 9v.75a8.967 8.967 0 01-2.312 6.022c1.733.64 3.56 1.085 5.455 1.31m5.714 0a24.255 24.255 0 01-5.714 0m5.714 0a3 3 0 11-5.714 0" />
|
||||
</svg>
|
||||
</a>
|
||||
<a href="/settings/account" class="text-sm text-gray-500 hover:text-gray-900">{{ user.username }}</a>
|
||||
<form method="POST" action="/logout" class="inline">
|
||||
{# Desktop-only: username + sign out #}
|
||||
<a href="/settings/account" class="text-sm text-gray-500 hover:text-gray-900 desktop-only">{{ user.username }}</a>
|
||||
<form method="POST" action="/logout" class="inline desktop-only">
|
||||
<input type="hidden" name="_csrf" value="{{ csrf_token }}">
|
||||
<button type="submit" class="text-sm text-gray-500 hover:text-gray-900">Sign out</button>
|
||||
</form>
|
||||
{# Mobile-only: hamburger #}
|
||||
<button type="button" onclick="document.getElementById('mobile-menu').classList.toggle('hidden')" class="text-gray-500 hover:text-gray-900 p-1 mobile-only">
|
||||
<svg class="w-6 h-6" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M3.75 6.75h16.5M3.75 12h16.5m-16.5 5.25h16.5" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
{# Tab navigation #}
|
||||
{# Mobile dropdown menu #}
|
||||
<div id="mobile-menu" class="hidden border-t border-gray-100 bg-gray-50 px-4 py-3 space-y-2">
|
||||
{% if project_name is defined and project_name %}
|
||||
<div class="text-xs text-gray-500">
|
||||
{% if current_org is defined %}{{ current_org }} /{% endif %} {{ project_name }}
|
||||
</div>
|
||||
{% endif %}
|
||||
<a href="/settings/account" class="block text-sm text-gray-700 hover:text-gray-900 py-1">{{ user.username }}</a>
|
||||
<form method="POST" action="/logout">
|
||||
<input type="hidden" name="_csrf" value="{{ csrf_token }}">
|
||||
<button type="submit" class="text-sm text-gray-500 hover:text-gray-900 py-1">Sign out</button>
|
||||
</form>
|
||||
</div>
|
||||
{# Tab navigation — scrollable on mobile #}
|
||||
<div class="max-w-6xl mx-auto px-4 mt-2">
|
||||
<div class="flex gap-1 -mb-px overflow-x-auto">
|
||||
<div class="flex gap-1 -mb-px overflow-x-auto scrollbar-none">
|
||||
{% if project_name is defined and project_name %}
|
||||
{# ── Project-level tabs ─────────────────────────────── #}
|
||||
<a href="/orgs/{{ current_org }}/projects/{{ project_name }}" class="px-3 py-2 text-sm text-gray-500 hover:text-gray-900 border-b-2 border-transparent hover:border-gray-300{% if active_tab is defined and active_tab == 'project_overview' %} text-gray-900 border-gray-900{% endif %}">Overview</a>
|
||||
<a href="/orgs/{{ current_org }}/projects/{{ project_name }}/releases" class="px-3 py-2 text-sm text-gray-500 hover:text-gray-900 border-b-2 border-transparent hover:border-gray-300{% if active_tab is defined and active_tab == 'project_releases' %} text-gray-900 border-gray-900{% endif %}">Releases</a>
|
||||
<a href="/orgs/{{ current_org }}/projects/{{ project_name }}" class="whitespace-nowrap px-3 py-2 text-sm text-gray-500 hover:text-gray-900 border-b-2 border-transparent hover:border-gray-300{% if active_tab is defined and active_tab == 'project_overview' %} text-gray-900 border-gray-900{% endif %}">Overview</a>
|
||||
<a href="/orgs/{{ current_org }}/projects/{{ project_name }}/releases" class="whitespace-nowrap px-3 py-2 text-sm text-gray-500 hover:text-gray-900 border-b-2 border-transparent hover:border-gray-300{% if active_tab is defined and active_tab == 'project_releases' %} text-gray-900 border-gray-900{% endif %}">Releases</a>
|
||||
{% elif current_org is defined and current_org %}
|
||||
{# ── Org-level tabs ─────────────────────────────────── #}
|
||||
<a href="/dashboard" class="px-3 py-2 text-sm text-gray-500 hover:text-gray-900 border-b-2 border-transparent hover:border-gray-300{% if active_tab is defined and active_tab == 'dashboard' %} text-gray-900 border-gray-900{% endif %}">Overview</a>
|
||||
<a href="/orgs/{{ current_org }}/projects" class="px-3 py-2 text-sm text-gray-500 hover:text-gray-900 border-b-2 border-transparent hover:border-gray-300{% if active_tab is defined and active_tab == 'projects' %} text-gray-900 border-gray-900{% endif %}">Projects</a>
|
||||
<a href="/orgs/{{ current_org }}/settings/members" class="px-3 py-2 text-sm text-gray-500 hover:text-gray-900 border-b-2 border-transparent hover:border-gray-300{% if active_tab is defined and active_tab == 'members' %} text-gray-900 border-gray-900{% endif %}">Members</a>
|
||||
<a href="/orgs/{{ current_org }}/destinations" class="px-3 py-2 text-sm text-gray-500 hover:text-gray-900 border-b-2 border-transparent hover:border-gray-300{% if active_tab is defined and active_tab == 'destinations' %} text-gray-900 border-gray-900{% endif %}">Destinations</a>
|
||||
<a href="/orgs/{{ current_org }}/settings/integrations" class="px-3 py-2 text-sm text-gray-500 hover:text-gray-900 border-b-2 border-transparent hover:border-gray-300{% if active_tab is defined and active_tab == 'integrations' %} text-gray-900 border-gray-900{% endif %}">Integrations</a>
|
||||
<a href="/orgs/{{ current_org }}/usage" class="px-3 py-2 text-sm text-gray-500 hover:text-gray-900 border-b-2 border-transparent hover:border-gray-300{% if active_tab is defined and active_tab == 'usage' %} text-gray-900 border-gray-900{% endif %}">Usage</a>
|
||||
<a href="/settings/tokens" class="px-3 py-2 text-sm text-gray-500 hover:text-gray-900 border-b-2 border-transparent hover:border-gray-300{% if active_tab is defined and active_tab == 'tokens' %} text-gray-900 border-gray-900{% endif %}">Tokens</a>
|
||||
<a href="/settings/account" class="px-3 py-2 text-sm text-gray-500 hover:text-gray-900 border-b-2 border-transparent hover:border-gray-300{% if active_tab is defined and active_tab == 'account' %} text-gray-900 border-gray-900{% endif %}">Settings</a>
|
||||
<a href="/dashboard" class="whitespace-nowrap px-3 py-2 text-sm text-gray-500 hover:text-gray-900 border-b-2 border-transparent hover:border-gray-300{% if active_tab is defined and active_tab == 'dashboard' %} text-gray-900 border-gray-900{% endif %}">Overview</a>
|
||||
<a href="/orgs/{{ current_org }}/projects" class="whitespace-nowrap px-3 py-2 text-sm text-gray-500 hover:text-gray-900 border-b-2 border-transparent hover:border-gray-300{% if active_tab is defined and active_tab == 'projects' %} text-gray-900 border-gray-900{% endif %}">Projects</a>
|
||||
<a href="/orgs/{{ current_org }}/settings/members" class="whitespace-nowrap px-3 py-2 text-sm text-gray-500 hover:text-gray-900 border-b-2 border-transparent hover:border-gray-300{% if active_tab is defined and active_tab == 'members' %} text-gray-900 border-gray-900{% endif %}">Members</a>
|
||||
<a href="/orgs/{{ current_org }}/destinations" class="whitespace-nowrap px-3 py-2 text-sm text-gray-500 hover:text-gray-900 border-b-2 border-transparent hover:border-gray-300{% if active_tab is defined and active_tab == 'destinations' %} text-gray-900 border-gray-900{% endif %}">Destinations</a>
|
||||
<a href="/orgs/{{ current_org }}/settings/integrations" class="whitespace-nowrap px-3 py-2 text-sm text-gray-500 hover:text-gray-900 border-b-2 border-transparent hover:border-gray-300{% if active_tab is defined and active_tab == 'integrations' %} text-gray-900 border-gray-900{% endif %}">Integrations</a>
|
||||
<a href="/orgs/{{ current_org }}/usage" class="whitespace-nowrap px-3 py-2 text-sm text-gray-500 hover:text-gray-900 border-b-2 border-transparent hover:border-gray-300{% if active_tab is defined and active_tab == 'usage' %} text-gray-900 border-gray-900{% endif %}">Usage</a>
|
||||
<a href="/settings/tokens" class="whitespace-nowrap px-3 py-2 text-sm text-gray-500 hover:text-gray-900 border-b-2 border-transparent hover:border-gray-300{% if active_tab is defined and active_tab == 'tokens' %} text-gray-900 border-gray-900{% endif %}">Tokens</a>
|
||||
<a href="/settings/account" class="whitespace-nowrap px-3 py-2 text-sm text-gray-500 hover:text-gray-900 border-b-2 border-transparent hover:border-gray-300{% if active_tab is defined and active_tab == 'account' %} text-gray-900 border-gray-900{% endif %}">Settings</a>
|
||||
{% else %}
|
||||
{# ── Global tabs (no org context) ───────────────────── #}
|
||||
<a href="/dashboard" class="px-3 py-2 text-sm text-gray-500 hover:text-gray-900 border-b-2 border-transparent hover:border-gray-300{% if active_tab is defined and active_tab == 'dashboard' %} text-gray-900 border-gray-900{% endif %}">Overview</a>
|
||||
<a href="/settings/tokens" class="px-3 py-2 text-sm text-gray-500 hover:text-gray-900 border-b-2 border-transparent hover:border-gray-300{% if active_tab is defined and active_tab == 'tokens' %} text-gray-900 border-gray-900{% endif %}">Tokens</a>
|
||||
<a href="/settings/account" class="px-3 py-2 text-sm text-gray-500 hover:text-gray-900 border-b-2 border-transparent hover:border-gray-300{% if active_tab is defined and active_tab == 'account' %} text-gray-900 border-gray-900{% endif %}">Settings</a>
|
||||
<a href="/dashboard" class="whitespace-nowrap px-3 py-2 text-sm text-gray-500 hover:text-gray-900 border-b-2 border-transparent hover:border-gray-300{% if active_tab is defined and active_tab == 'dashboard' %} text-gray-900 border-gray-900{% endif %}">Overview</a>
|
||||
<a href="/settings/tokens" class="whitespace-nowrap px-3 py-2 text-sm text-gray-500 hover:text-gray-900 border-b-2 border-transparent hover:border-gray-300{% if active_tab is defined and active_tab == 'tokens' %} text-gray-900 border-gray-900{% endif %}">Tokens</a>
|
||||
<a href="/settings/account" class="whitespace-nowrap px-3 py-2 text-sm text-gray-500 hover:text-gray-900 border-b-2 border-transparent hover:border-gray-300{% if active_tab is defined and active_tab == 'account' %} text-gray-900 border-gray-900{% endif %}">Settings</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
@@ -96,11 +117,20 @@
|
||||
<div class="max-w-6xl mx-auto px-4 py-4 flex items-center justify-between">
|
||||
<a href="/" class="text-xl font-bold tracking-tight">forage</a>
|
||||
<div class="flex items-center gap-6">
|
||||
<a href="/pricing" class="text-sm text-gray-600 hover:text-gray-900">Pricing</a>
|
||||
<a href="/components" class="text-sm text-gray-600 hover:text-gray-900">Components</a>
|
||||
<a href="/pricing" class="text-sm text-gray-600 hover:text-gray-900 desktop-only">Pricing</a>
|
||||
<a href="/components" class="text-sm text-gray-600 hover:text-gray-900 desktop-only">Components</a>
|
||||
<a href="/login" class="text-sm font-medium px-4 py-2 bg-gray-900 text-white rounded-md hover:bg-gray-800">Sign in</a>
|
||||
<button type="button" onclick="document.getElementById('marketing-mobile-menu').classList.toggle('hidden')" class="text-gray-500 hover:text-gray-900 p-1 mobile-only">
|
||||
<svg class="w-6 h-6" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M3.75 6.75h16.5M3.75 12h16.5m-16.5 5.25h16.5" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div id="marketing-mobile-menu" class="hidden border-t border-gray-100 bg-gray-50 px-4 py-3 space-y-2">
|
||||
<a href="/pricing" class="block text-sm text-gray-600 hover:text-gray-900 py-1">Pricing</a>
|
||||
<a href="/components" class="block text-sm text-gray-600 hover:text-gray-900 py-1">Components</a>
|
||||
</div>
|
||||
</nav>
|
||||
{% endif %}
|
||||
|
||||
|
||||
@@ -34,8 +34,8 @@
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="border border-gray-200 rounded-lg overflow-hidden">
|
||||
<table class="w-full text-sm">
|
||||
<div class="border border-gray-200 rounded-lg overflow-x-auto">
|
||||
<table class="w-full text-sm min-w-full">
|
||||
<thead class="bg-gray-50 border-b border-gray-200">
|
||||
<tr>
|
||||
<th class="text-left px-4 py-3 font-medium text-gray-500">Username</th>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
{% block content %}
|
||||
<section class="max-w-4xl mx-auto px-4 pt-12">
|
||||
<div class="flex items-center justify-between mb-8">
|
||||
<div class="flex flex-col sm:flex-row sm:items-center justify-between gap-2 mb-8">
|
||||
<h1 class="text-2xl font-bold">Personal Access Tokens</h1>
|
||||
<a href="/dashboard" class="text-sm text-gray-600 hover:text-gray-900">← Dashboard</a>
|
||||
</div>
|
||||
|
||||