From fc5bd12f265526f1e465d049fef8fc2aed72e758 Mon Sep 17 00:00:00 2001 From: anurag629 Date: Sat, 28 Feb 2026 11:16:43 +0530 Subject: [PATCH 01/10] fix: improve mobile UI/UX across editor, navbar, API docs, and preview pages - Redesign API docs page with mobile-first layout: div-based params instead of tables, horizontal sticky tab nav, contained code blocks - Fix hamburger menu broken after View Transitions by removing transition:persist from Header and moving mobile menu inside
- Improve editor mobile layout: single scroll column, proper touch targets, auto-switch to customize tab on template select - Add safe-area and viewport-fit handling for notched devices - Improve preview page mobile: stacked URL input, larger buttons - Adjust responsive nav-height and global spacing for small screens Made-with: Cursor --- src/components/Header.astro | 263 ++++++++++++--- src/components/editor/EditorApp.tsx | 4 + src/layouts/Layout.astro | 4 +- src/layouts/ToolLayout.astro | 9 +- src/pages/api-docs.astro | 268 ++++++++-------- src/styles/api-docs.css | 480 +++++++++++++++++----------- src/styles/editor.css | 144 ++++++++- src/styles/global.css | 3 +- src/styles/preview.css | 92 +++++- 9 files changed, 873 insertions(+), 394 deletions(-) diff --git a/src/components/Header.astro b/src/components/Header.astro index 086b61a..7ae7f71 100644 --- a/src/components/Header.astro +++ b/src/components/Header.astro @@ -36,41 +36,82 @@ const navItems = [ - -
- -
- + diff --git a/src/components/editor/EditorApp.tsx b/src/components/editor/EditorApp.tsx index e8f9035..b86b944 100644 --- a/src/components/editor/EditorApp.tsx +++ b/src/components/editor/EditorApp.tsx @@ -59,6 +59,10 @@ export function EditorApp({ initialCategory }: EditorAppProps) { const handleTemplateSelect = useCallback( (template: TemplateDefinition) => { setTemplate(template); + // On mobile, switch to Customize tab so user sees the canvas and form + if (typeof window !== 'undefined' && window.innerWidth <= 768) { + setMobileTab('customize'); + } }, [setTemplate] ); diff --git a/src/layouts/Layout.astro b/src/layouts/Layout.astro index 0cb1229..1d0ce60 100644 --- a/src/layouts/Layout.astro +++ b/src/layouts/Layout.astro @@ -31,7 +31,7 @@ const fullTitle = title === 'OGCOPS' ? title : `${title} | ${siteName}`; - + {noindex && } @@ -106,7 +106,7 @@ const fullTitle = title === 'OGCOPS' ? title : `${title} | ${siteName}`; -
+
diff --git a/src/layouts/ToolLayout.astro b/src/layouts/ToolLayout.astro index 1c21182..37acc6d 100644 --- a/src/layouts/ToolLayout.astro +++ b/src/layouts/ToolLayout.astro @@ -19,7 +19,7 @@ const fullTitle = `${title} | ${siteName}`; - + @@ -61,7 +61,14 @@ const fullTitle = `${title} | ${siteName}`; body { display: flex; flex-direction: column; + min-height: 100vh; + min-height: 100dvh; height: 100vh; + height: 100dvh; overflow: hidden; + padding-top: env(safe-area-inset-top); + padding-left: env(safe-area-inset-left); + padding-right: env(safe-area-inset-right); + padding-bottom: env(safe-area-inset-bottom); } diff --git a/src/pages/api-docs.astro b/src/pages/api-docs.astro index 9c56591..591db5b 100644 --- a/src/pages/api-docs.astro +++ b/src/pages/api-docs.astro @@ -5,24 +5,29 @@ import '@/styles/api-docs.css';
- + +
+

API Documentation

+

+ Generate OG images, check URL meta tags, and list templates with our free REST API. + No API key required. CORS-enabled for browser use. +

+
+ +
diff --git a/src/components/Header.astro b/src/components/Header.astro index 086b61a..7ae7f71 100644 --- a/src/components/Header.astro +++ b/src/components/Header.astro @@ -36,41 +36,82 @@ const navItems = [
- - - -
- + diff --git a/src/components/editor/EditorApp.tsx b/src/components/editor/EditorApp.tsx index e8f9035..b992b98 100644 --- a/src/components/editor/EditorApp.tsx +++ b/src/components/editor/EditorApp.tsx @@ -31,6 +31,17 @@ export function EditorApp({ initialCategory }: EditorAppProps) { const { svg, loading, error, render } = useSatoriRenderer(); const [mobileTab, setMobileTab] = useState<'templates' | 'customize' | 'export'>('customize'); + const [isMobile, setIsMobile] = useState(() => + typeof window !== 'undefined' ? window.innerWidth <= 768 : false + ); + + useEffect(() => { + const mq = window.matchMedia('(max-width: 768px)'); + const handler = (e: MediaQueryListEvent) => setIsMobile(e.matches); + mq.addEventListener('change', handler); + setIsMobile(mq.matches); + return () => mq.removeEventListener('change', handler); + }, []); // Find current template definition (use registry lookup to ensure render function is present) const currentTemplate = useMemo( @@ -59,8 +70,11 @@ export function EditorApp({ initialCategory }: EditorAppProps) { const handleTemplateSelect = useCallback( (template: TemplateDefinition) => { setTemplate(template); + if (isMobile) { + setMobileTab('customize'); + } }, - [setTemplate] + [setTemplate, isMobile] ); const handleReset = useCallback(() => { @@ -114,11 +128,20 @@ export function EditorApp({ initialCategory }: EditorAppProps) { />
- {/* Right: Customize */} + {/* Right: Customize / Export */}
{mobileTab === 'export' ? (
+
+ +
+
) : ( copyToClipboard(apiUrl, 'url')} > - {copied === 'url' ? 'Copied!' : 'Copy URL'} + + {copied === 'url' ? 'Copied!' : 'Copy Image URL'}
diff --git a/src/layouts/Layout.astro b/src/layouts/Layout.astro index 0cb1229..1d0ce60 100644 --- a/src/layouts/Layout.astro +++ b/src/layouts/Layout.astro @@ -31,7 +31,7 @@ const fullTitle = title === 'OGCOPS' ? title : `${title} | ${siteName}`; - + {noindex && } @@ -106,7 +106,7 @@ const fullTitle = title === 'OGCOPS' ? title : `${title} | ${siteName}`; -
+
diff --git a/src/layouts/ToolLayout.astro b/src/layouts/ToolLayout.astro index 1c21182..37acc6d 100644 --- a/src/layouts/ToolLayout.astro +++ b/src/layouts/ToolLayout.astro @@ -19,7 +19,7 @@ const fullTitle = `${title} | ${siteName}`; - + @@ -61,7 +61,14 @@ const fullTitle = `${title} | ${siteName}`; body { display: flex; flex-direction: column; + min-height: 100vh; + min-height: 100dvh; height: 100vh; + height: 100dvh; overflow: hidden; + padding-top: env(safe-area-inset-top); + padding-left: env(safe-area-inset-left); + padding-right: env(safe-area-inset-right); + padding-bottom: env(safe-area-inset-bottom); } diff --git a/src/pages/api-docs.astro b/src/pages/api-docs.astro index 9c56591..591db5b 100644 --- a/src/pages/api-docs.astro +++ b/src/pages/api-docs.astro @@ -5,24 +5,29 @@ import '@/styles/api-docs.css';
- + +
+

API Documentation

+

+ Generate OG images, check URL meta tags, and list templates with our free REST API. + No API key required. CORS-enabled for browser use. +

+
+ +
+ + {/* AI Settings Modal */} + ); } diff --git a/src/components/editor/TemplatePanel.tsx b/src/components/editor/TemplatePanel.tsx index d483ef8..c027cb0 100644 --- a/src/components/editor/TemplatePanel.tsx +++ b/src/components/editor/TemplatePanel.tsx @@ -2,6 +2,7 @@ import { useMemo } from 'react'; import type { TemplateDefinition, TemplateCategory } from '@/templates/types'; import { CATEGORY_META, ALL_CATEGORIES } from '@/templates/types'; import { TemplateThumbnail } from './TemplateThumbnail'; +import { AITemplateSearch } from './AITemplateSearch'; interface TemplatePanelProps { templates: TemplateDefinition[]; @@ -49,6 +50,7 @@ export function TemplatePanel({ value={searchQuery} onChange={(e) => onSearchChange(e.target.value)} /> +