Improve FAQ & video rendering, tighten homepage and CSS

This commit is contained in:
Andras Schmelczer 2026-05-04 22:07:30 +01:00
parent 05a1f316e1
commit c69bb0d614
48 changed files with 4689 additions and 1077 deletions

93
video/src/probe.ts Normal file
View file

@ -0,0 +1,93 @@
import { chromium } from 'playwright';
import { APP_URL, AUTH_STATE_PATH, DASHBOARD_PATH, VIEWPORT } from './config.js';
async function main() {
const browser = await chromium.launch({ headless: true });
const context = await browser.newContext({
storageState: AUTH_STATE_PATH,
viewport: VIEWPORT,
});
const page = await context.newPage();
page.on('request', (r) => {
if (r.url().includes('auth-refresh')) {
console.log('REQ', r.method(), r.url(), 'headers:', JSON.stringify(r.headers()));
}
});
page.on('response', async (r) => {
if (r.url().includes('auth-refresh')) {
const body = await r.text().catch(() => '');
console.log('RES', r.status(), r.url(), 'body:', body.slice(0, 200));
}
});
await page.goto(`${APP_URL}${DASHBOARD_PATH}`, { waitUntil: 'networkidle' });
await new Promise((r) => setTimeout(r, 1500));
await page.screenshot({ path: 'output/probe-1-initial.png', fullPage: false });
const ls = await page.evaluate(() => {
const v = localStorage.getItem('pocketbase_auth');
let parsed: unknown = null;
try { parsed = v ? JSON.parse(v) : null; } catch {}
return {
raw: v?.slice(0, 80),
hasToken: !!(parsed as { token?: string })?.token,
hasRecord: !!(parsed as { record?: unknown })?.record,
hasModel: !!(parsed as { model?: unknown })?.model,
};
});
console.log('pb_auth localStorage:', ls);
const refreshTest = await page.evaluate(async () => {
const stored = JSON.parse(localStorage.getItem('pb_auth') ?? '{}');
const r = await fetch('/pb/api/collections/users/auth-refresh', {
method: 'POST',
headers: { Authorization: stored.token },
});
return { status: r.status, body: (await r.text()).slice(0, 200) };
});
console.log('refresh test:', refreshTest);
// Try the SDK path directly. Reach into the Vite-served module graph.
const sdkRefresh = await page.evaluate(async () => {
type W = Window & { pb?: { collection: (n: string) => { authRefresh: () => Promise<unknown> }, authStore: { isValid: boolean, token: string, record: unknown } } };
const w = window as W;
if (!w.pb) return { error: 'window.pb not exposed' };
const before = { isValid: w.pb.authStore.isValid, hasToken: !!w.pb.authStore.token };
try {
const out = await w.pb.collection('users').authRefresh();
return { before, ok: true, out };
} catch (e) {
return { before, ok: false, error: String(e) };
}
});
console.log('SDK refresh:', sdkRefresh);
const aiCount = await page.locator('[data-tutorial="ai-filters"]').count();
const aiVisible = await page.locator('[data-tutorial="ai-filters"]').first().isVisible().catch(() => false);
const aiBtnCount = await page.locator('[data-tutorial="ai-filters"] button').count();
const filterCount = await page.locator('[data-filter-name]').count();
const filterNames = await page.locator('[data-filter-name]').evaluateAll((els) =>
els.map((e) => e.getAttribute('data-filter-name'))
);
const tutorialOverlay = await page.locator('[role="dialog"], [data-tutorial-step], .tutorial-overlay').count();
console.log({ aiCount, aiVisible, aiBtnCount, filterCount, filterNames, tutorialOverlay });
// Try clicking the AI button and check whether textarea appears
const aiBtn = page.locator('[data-tutorial="ai-filters"] button').first();
if (await aiBtn.isVisible()) {
await aiBtn.click();
await new Promise((r) => setTimeout(r, 600));
const taCount = await page.locator('[data-tutorial="ai-filters"] textarea').count();
console.log({ afterClick_taCount: taCount });
await page.screenshot({ path: 'output/probe-2-after-click.png' });
}
await browser.close();
}
main().catch((e) => {
console.error(e);
process.exit(1);
});