feat(cms): "View site" link in admin header (MITHOME-97 follow-up)
CI Pipeline with Test Management / 🧪 Run Tests & Generate Reports (push) Canceled after 0s
Test Reporting & Gherkin Analysis / 🧪 Run Tests & Generate Reports (push) Canceled after 0s
CI Pipeline with Test Management / 🐳 Docker Integration Tests (push) Canceled after 0s
CI Pipeline with Test Management / 🏗️ Build Docker Image (push) Canceled after 0s
CI Pipeline with Test Management / 📊 Generate Test Summary (push) Canceled after 0s
Test Reporting & Gherkin Analysis / 📊 Analyze Test Coverage (push) Canceled after 0s
Test Reporting & Gherkin Analysis / 🔄 Sync with Linear (push) Canceled after 0s
Test Reporting & Gherkin Analysis / ⚡ Performance Monitoring (push) Canceled after 0s

User request: there was no way to get from the Payload admin back to
the public website — confirmed live (read_page on the admin nav showed
only internal links: collections, globals, account, logout).

Added a "🌐 Honlap megnyitása" link next to the QuickSearch box
(src/components/admin/QuickSearch.tsx — same header slot, no new
admin.components entry or importmap regen needed since the export name
didn't change). Opens in a new tab, points at siteConfig.general.url
(NEXT_PUBLIC_SITE_URL), so it resolves to the correct site per
environment automatically — stage.mozdit.hu on staging, the production
domain once that's live.

Verified live in the browser: link renders next to the search box,
resolves to the expected URL (find() confirmed the href), zero new
console errors in a fresh tab. Gate: tsc, lint, unit tests (51 passed),
production build all green.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Do Siki
2026-09-12 00:59:55 +02:00
co-authored by Claude Sonnet 5
parent c07ec2298c
commit 314b129259
+91 -63
View File
@@ -2,6 +2,7 @@
import { useCallback, useEffect, useRef, useState } from 'react'
import Link from 'next/link'
import { siteConfig } from '@/config/site'
/**
* MITHOME-120 — teljes szöveges gyorskeresés a Payload admin tetején.
@@ -18,6 +19,12 @@ import Link from 'next/link'
* Regisztrálva: payload.config.ts `admin.components.header` — minden admin
* oldalon megjelenik. Az importMap.js-t a `payload generate:importmap`
* generálja újra, ha ez a fájl elmozdul/átnevezik.
*
* A keresés mellett egy "Honlap megnyitása" link is itt kapott helyet
* (felhasználói kérés) — korábban semmilyen link nem vezetett az admin
* felületről a publikus oldalra. `siteConfig.general.url` a
* NEXT_PUBLIC_SITE_URL-ből jön, tehát környezetenként (dev/staging/prod)
* automatikusan a helyes címre mutat.
*/
type Locale = 'hu' | 'en'
@@ -199,80 +206,101 @@ export function QuickSearch() {
<div
ref={containerRef}
style={{
position: 'relative',
maxWidth: 480,
display: 'flex',
alignItems: 'center',
gap: 12,
maxWidth: 620,
margin: '0 auto',
padding: '10px 16px',
}}
>
<input
type="search"
value={query}
placeholder="🔍 Keresés a teljes tartalomban… (min. 2 karakter)"
onFocus={() => {
setOpen(true)
void ensureIndex()
}}
onChange={(e) => {
setQuery(e.target.value)
setOpen(true)
void ensureIndex()
}}
<div style={{ position: 'relative', flex: 1 }}>
<input
type="search"
value={query}
placeholder="🔍 Keresés a teljes tartalomban… (min. 2 karakter)"
onFocus={() => {
setOpen(true)
void ensureIndex()
}}
onChange={(e) => {
setQuery(e.target.value)
setOpen(true)
void ensureIndex()
}}
style={{
width: '100%',
boxSizing: 'border-box',
padding: '8px 12px',
fontSize: 14,
borderRadius: 4,
border: '1px solid var(--theme-elevation-150, #ccc)',
background: 'var(--theme-input-bg, #fff)',
color: 'var(--theme-text, #000)',
}}
/>
{open && query.trim().length >= 2 && (
<div
style={{
position: 'absolute',
top: '100%',
left: 0,
right: 0,
marginTop: 4,
maxHeight: 420,
overflowY: 'auto',
background: 'var(--theme-elevation-0, #fff)',
border: '1px solid var(--theme-elevation-150, #ccc)',
borderRadius: 4,
boxShadow: '0 4px 16px rgba(0,0,0,0.15)',
zIndex: 100,
}}
>
{loading && !index && (
<div style={{ padding: 12, fontSize: 13, opacity: 0.7 }}>Tartalom betöltése</div>
)}
{index && results.length === 0 && (
<div style={{ padding: 12, fontSize: 13, opacity: 0.7 }}>Nincs találat.</div>
)}
{results.map((r) => (
<Link
key={r.key}
href={r.editHref}
onClick={() => setOpen(false)}
style={{
display: 'block',
padding: '8px 12px',
borderBottom: '1px solid var(--theme-elevation-100, #eee)',
textDecoration: 'none',
color: 'inherit',
}}
>
<div style={{ fontSize: 12, opacity: 0.65 }}>
{r.source} · {r.fieldPath} · {r.locale}
</div>
<div style={{ fontSize: 14 }}>{snippetAround(r.value, query)}</div>
</Link>
))}
</div>
)}
</div>
<a
href={siteConfig.general.url}
target="_blank"
rel="noopener noreferrer"
style={{
width: '100%',
boxSizing: 'border-box',
flexShrink: 0,
padding: '8px 12px',
fontSize: 14,
borderRadius: 4,
border: '1px solid var(--theme-elevation-150, #ccc)',
background: 'var(--theme-input-bg, #fff)',
color: 'var(--theme-text, #000)',
textDecoration: 'none',
whiteSpace: 'nowrap',
}}
/>
{open && query.trim().length >= 2 && (
<div
style={{
position: 'absolute',
top: '100%',
left: 16,
right: 16,
marginTop: 4,
maxHeight: 420,
overflowY: 'auto',
background: 'var(--theme-elevation-0, #fff)',
border: '1px solid var(--theme-elevation-150, #ccc)',
borderRadius: 4,
boxShadow: '0 4px 16px rgba(0,0,0,0.15)',
zIndex: 100,
}}
>
{loading && !index && (
<div style={{ padding: 12, fontSize: 13, opacity: 0.7 }}>Tartalom betöltése</div>
)}
{index && results.length === 0 && (
<div style={{ padding: 12, fontSize: 13, opacity: 0.7 }}>Nincs találat.</div>
)}
{results.map((r) => (
<Link
key={r.key}
href={r.editHref}
onClick={() => setOpen(false)}
style={{
display: 'block',
padding: '8px 12px',
borderBottom: '1px solid var(--theme-elevation-100, #eee)',
textDecoration: 'none',
color: 'inherit',
}}
>
<div style={{ fontSize: 12, opacity: 0.65 }}>
{r.source} · {r.fieldPath} · {r.locale}
</div>
<div style={{ fontSize: 14 }}>{snippetAround(r.value, query)}</div>
</Link>
))}
</div>
)}
>
🌐 Honlap megnyitása
</a>
</div>
)
}