fix: Aptly z Adobe Fonts na celej stranke, pad pri vlozeni odkazu na CSS

- web projekt Adobe Fonts xrv1cuz sa nacitava vzdy (dá sa zmenit cez
  NEXT_PUBLIC_ADOBE_FONTS_URL), Aptly uz nezavisi od Creative Cloud v pocitaci
- vlozeny odkaz s uvodzovkami alebo cely <link>/@import sa ocisti na URL;
  hladanie uz nacitanych odkazov neskladá CSS selektor z textu

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Jakub_HostacnyandClaude Opus 5.5 committed 2026-10-22 09:06:32 +02:00
1 parent d6465dc7b1
commit 22103072b7
3 files changed
+22 -8

No files matched your search

+1 -1
View File
@@ -9,7 +9,7 @@ SUPABASE_SERVICE_ROLE_KEY=
# Adobe Fonts (voliteľné): odkaz na CSS web projektu z fonts.adobe.com (Web Projects → Embed),
# napr. https://use.typekit.net/abc1234.css – načíta písma ako Aptly pre cenovky a štítky.
# V Adobe projekte treba povoliť domény (localhost aj produkčnú).
NEXT_PUBLIC_ADOBE_FONTS_URL=
NEXT_PUBLIC_ADOBE_FONTS_URL=https://use.typekit.net/xrv1cuz.css
# Brevo (SMTP & API → API Keys)
BREVO_API_KEY=
+5 -1
View File
@@ -17,6 +17,10 @@ export const metadata: Metadata = {
description: "Generated by create next app",
};
// Web projekt Adobe Fonts (Aptly pre cenovky) – dá sa zmeniť premennou NEXT_PUBLIC_ADOBE_FONTS_URL.
// V projekte na fonts.adobe.com musia byť povolené domény (localhost aj newsletter-coop.vercel.app).
const ADOBE_FONTS_URL = process.env.NEXT_PUBLIC_ADOBE_FONTS_URL || 'https://use.typekit.net/xrv1cuz.css';
export default function RootLayout({ children }: LayoutProps<"/">) {
return (
<html
@@ -27,7 +31,7 @@ export default function RootLayout({ children }: LayoutProps<"/">) {
{/* Písmo e-mailu (Poppins) – náhľad v editore aj na stránke s pripomienkami */}
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;600;700;800;900&display=swap" />
{/* Adobe Fonts (napr. Aptly pre cenovky a štítky) – odkaz na web projekt z fonts.adobe.com */}
{process.env.NEXT_PUBLIC_ADOBE_FONTS_URL && <link rel="stylesheet" href={process.env.NEXT_PUBLIC_ADOBE_FONTS_URL} />}
<link rel="stylesheet" href={ADOBE_FONTS_URL} />
</head>
<body className="min-h-full flex flex-col">{children}</body>
</html>
+16 -6
View File
@@ -126,21 +126,31 @@ const QUICK_LAYERS: Array<{ label: string; text: string; fontSize: number }> = [
{ label: 'Text', text: 'AKCIA', fontSize: 16 }
];
// Odkaz na CSS z Adobe Fonts: z vloženého textu (aj s úvodzovkami, celý <link ...> alebo @import url(...))
// vyberieme samotnú adresu https://…
export function cleanFontCssUrl(text: string): string {
return text.match(/https?:\/\/[^\s"'<>()]+/i)?.[0] || '';
}
// Je už v stránke <link> s daným atribútom a hodnotou? (bez skladania CSS selektora z textu používateľa)
const hasLink = (attr: string, value: string) => [...document.querySelectorAll(`link[${attr}]`)].some((l) => l.getAttribute(attr) === value);
function loadFont(layer: BadgeLayer) {
if (typeof document === 'undefined' || !layer.fontFamily) return;
if (layer.fontSource === 'adobe' && layer.fontUrl) {
if (!document.querySelector(`link[data-adobe-font="${layer.fontUrl}"]`)) {
if (layer.fontSource === 'adobe') {
const url = cleanFontCssUrl(layer.fontUrl || '');
if (url && !hasLink('data-adobe-font', url) && ![...document.querySelectorAll('link[rel="stylesheet"]')].some((l) => (l as HTMLLinkElement).href === url)) {
const link = document.createElement('link');
link.rel = 'stylesheet';
link.href = layer.fontUrl;
link.setAttribute('data-adobe-font', layer.fontUrl);
link.href = url;
link.setAttribute('data-adobe-font', url);
document.head.appendChild(link);
}
return;
}
if (layer.fontSource === 'system') return;
const clean = layer.fontFamily.trim().replace(/\s+/g, '+');
if (!document.querySelector(`link[data-google-font="${clean}"]`)) {
if (!hasLink('data-google-font', clean)) {
const link = document.createElement('link');
link.rel = 'stylesheet';
link.href = `https://fonts.googleapis.com/css2?family=${clean}:wght@400;600;700;800;900&display=swap`;
@@ -939,7 +949,7 @@ export const BadgeEditorModal: React.FC<BadgeEditorModalProps> = ({
{layer.fontSource === 'adobe' && (
<input
value={layer.fontUrl || ''}
onChange={(e) => updateLayer(layer.id, { fontUrl: e.target.value })}
onChange={(e) => updateLayer(layer.id, { fontUrl: cleanFontCssUrl(e.target.value) || e.target.value })}
placeholder="Odkaz na CSS z Adobe Fonts (https://use.typekit.net/xxxx.css)"
className="w-full text-[10px] font-mono border border-gray-300 rounded-lg px-2 py-1.5"
/>