SEO/GEO-Basics: Descriptions & Titles normalisiert, Outline-Fixes, CLS-Maße
Audit aller 23 indexierbaren Routen (lokaler Crawl) und Fixes: - Descriptions auf ~130-160 Zeichen; Turnen-Disziplinseiten hatten den kurzen Hero-Teaser als Description, jetzt eigene SERP-Texte - Titles: team-erste gekürzt, sportheimbuchung ohne doppelten Brand - h1->h3-Sprünge behoben: visually-hidden h2 aus JSON-Section-Titeln (sportheimbuchung, partner-werden), sichtbarer choice.title auf mitglied-werden; historie bekommt Breadcrumb-Schema - Neuer Helper img_intrinsic_attrs() liefert width/height aus der Bilddatei (PNG via getimagesize, SVG via viewBox) für Partner-Grid- und Banner-Slider-Logos — kein Layout-Shift mehr Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -68,7 +68,9 @@ Sichtbare FAQ + FAQPage-Schema aus derselben `data/*.json`-Quelle, damit Inhalt
|
|||||||
Pfade), `abs_url()` (absolute URLs für Canonical/OG), `asset()` (Versionierung via filemtime),
|
Pfade), `abs_url()` (absolute URLs für Canonical/OG), `asset()` (Versionierung via filemtime),
|
||||||
`json_load('name')` (liest `data/name.json`, static cache), `component()`, `config('key')` (Werte aus
|
`json_load('name')` (liest `data/name.json`, static cache), `component()`, `config('key')` (Werte aus
|
||||||
`config/config.php`), `icon('name', 'klasse', 'label?')` (Inline-SVG aus `public/assets/icons/`, siehe
|
`config/config.php`), `icon('name', 'klasse', 'label?')` (Inline-SVG aus `public/assets/icons/`, siehe
|
||||||
Abschnitt Icons), `form_token()`/`form_token_valid()` (Time-Trap-Token, siehe Formulare).
|
Abschnitt Icons), `form_token()`/`form_token_valid()` (Time-Trap-Token, siehe Formulare),
|
||||||
|
`img_intrinsic_attrs('pfad')` (width/height-Attribute aus der Bilddatei für CLS-freie `<img>`,
|
||||||
|
wenn die Maße nicht schon statisch bekannt sind).
|
||||||
- **CSS:** 6 Dateien als `<link>` in fester Reihenfolge: tokens → reset → base → layout → components →
|
- **CSS:** 6 Dateien als `<link>` in fester Reihenfolge: tokens → reset → base → layout → components →
|
||||||
utilities. Kein `@import`, kein Inline-Style. Komponenten-Styles in `components.css` mit
|
utilities. Kein `@import`, kein Inline-Style. Komponenten-Styles in `components.css` mit
|
||||||
Banner-Kommentaren (`/* === hero === */`).
|
Banner-Kommentaren (`/* === hero === */`).
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ $total = count($banners);
|
|||||||
<li class="<?= e($classes) ?>"<?= $style ?> data-carousel-slide role="group" aria-roledescription="Folie" aria-label="<?= ($i + 1) ?> von <?= $total ?>"<?= $i === 0 ? '' : ' hidden' ?>>
|
<li class="<?= e($classes) ?>"<?= $style ?> data-carousel-slide role="group" aria-roledescription="Folie" aria-label="<?= ($i + 1) ?> von <?= $total ?>"<?= $i === 0 ? '' : ' hidden' ?>>
|
||||||
<?php if (!empty($banner['logo'])): ?>
|
<?php if (!empty($banner['logo'])): ?>
|
||||||
<div class="ad-banner__logo<?= !empty($banner['logo_light']) ? ' ad-banner__logo--light' : '' ?>">
|
<div class="ad-banner__logo<?= !empty($banner['logo_light']) ? ' ad-banner__logo--light' : '' ?>">
|
||||||
<img src="<?= e(asset($banner['logo'])) ?>" alt="<?= e($banner['company'] ?? $banner['title']) ?>" loading="lazy" decoding="async">
|
<img src="<?= e(asset($banner['logo'])) ?>" alt="<?= e($banner['company'] ?? $banner['title']) ?>"<?= img_intrinsic_attrs($banner['logo']) ?> loading="lazy" decoding="async">
|
||||||
</div>
|
</div>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
<div class="ad-banner__content">
|
<div class="ad-banner__content">
|
||||||
|
|||||||
@@ -18,10 +18,10 @@ $partners = json_load('partners')['partners'] ?? [];
|
|||||||
<li class="partners__item">
|
<li class="partners__item">
|
||||||
<?php if (!empty($partner['url'])): ?>
|
<?php if (!empty($partner['url'])): ?>
|
||||||
<a href="<?= e($partner['url']) ?>" rel="noopener">
|
<a href="<?= e($partner['url']) ?>" rel="noopener">
|
||||||
<img src="<?= e(asset($partner['logo'])) ?>" alt="<?= e($partner['name']) ?>" loading="lazy" decoding="async">
|
<img src="<?= e(asset($partner['logo'])) ?>" alt="<?= e($partner['name']) ?>"<?= img_intrinsic_attrs($partner['logo']) ?> loading="lazy" decoding="async">
|
||||||
</a>
|
</a>
|
||||||
<?php else: ?>
|
<?php else: ?>
|
||||||
<img src="<?= e(asset($partner['logo'])) ?>" alt="<?= e($partner['name']) ?>" loading="lazy" decoding="async">
|
<img src="<?= e(asset($partner['logo'])) ?>" alt="<?= e($partner['name']) ?>"<?= img_intrinsic_attrs($partner['logo']) ?> loading="lazy" decoding="async">
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
</li>
|
</li>
|
||||||
<?php endforeach; ?>
|
<?php endforeach; ?>
|
||||||
|
|||||||
@@ -96,6 +96,35 @@ function json_load(string $name): array
|
|||||||
return $cache[$name];
|
return $cache[$name];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Intrinsische Bildmaße als ' width="…" height="…"' für CLS-freie <img>-Tags.
|
||||||
|
* $rel = Pfad relativ zu public/assets/. PNG/JPG via getimagesize, SVG via
|
||||||
|
* viewBox (Fallback: width/height-Attribute, Einheiten werden ignoriert —
|
||||||
|
* fürs Seitenverhältnis reicht die Zahl). Liefert '' wenn nicht bestimmbar.
|
||||||
|
*/
|
||||||
|
function img_intrinsic_attrs(string $rel): string
|
||||||
|
{
|
||||||
|
static $cache = [];
|
||||||
|
if (!isset($cache[$rel])) {
|
||||||
|
$file = PUBLIC_PATH . '/assets/' . ltrim($rel, '/');
|
||||||
|
$w = $h = 0;
|
||||||
|
if (is_file($file)) {
|
||||||
|
if (str_ends_with(strtolower($file), '.svg')) {
|
||||||
|
$svg = (string) file_get_contents($file);
|
||||||
|
if (preg_match('/viewBox="\s*[\d.-]+[\s,]+[\d.-]+[\s,]+([\d.]+)[\s,]+([\d.]+)/', $svg, $m)) {
|
||||||
|
[$w, $h] = [(int) round((float) $m[1]), (int) round((float) $m[2])];
|
||||||
|
} elseif (preg_match('/<svg\b[^>]*\bwidth="([\d.]+)[a-z%]*"[^>]*\bheight="([\d.]+)[a-z%]*"/s', $svg, $m)) {
|
||||||
|
[$w, $h] = [(int) round((float) $m[1]), (int) round((float) $m[2])];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
[$w, $h] = (getimagesize($file) ?: [0, 0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$cache[$rel] = ($w > 0 && $h > 0) ? ' width="' . $w . '" height="' . $h . '"' : '';
|
||||||
|
}
|
||||||
|
return $cache[$rel];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Komponente rendern: component('hero', ['title' => …]).
|
* Komponente rendern: component('hero', ['title' => …]).
|
||||||
* Props werden als lokale Variablen extrahiert; Komponenten sind dumme Includes.
|
* Props werden als lokale Variablen extrahiert; Komponenten sind dumme Includes.
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ $anchor_slug = static function (string $s): string {
|
|||||||
|
|
||||||
$meta = [
|
$meta = [
|
||||||
'title' => 'Ansprechpartner',
|
'title' => 'Ansprechpartner',
|
||||||
'description' => 'Ansprechpartner und Kontaktwege beim TSV 1908 Kulmbach – Geschäftsstelle, Turnabteilung und Vorstand auf einen Blick.',
|
'description' => 'Ansprechpartner und Kontaktwege beim TSV 1908 Kulmbach – Geschäftsstelle, Turnabteilung und Vorstand mit E-Mail und Telefon auf einen Blick.',
|
||||||
'schema' => page_schema([
|
'schema' => page_schema([
|
||||||
['name' => 'Startseite', 'slug' => ''],
|
['name' => 'Startseite', 'slug' => ''],
|
||||||
['name' => 'Der Verein', 'slug' => 'verein'],
|
['name' => 'Der Verein', 'slug' => 'verein'],
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ $dpo = $club['data_protection_contact'] ?? '';
|
|||||||
|
|
||||||
$meta = [
|
$meta = [
|
||||||
'title' => 'Datenschutzerklärung',
|
'title' => 'Datenschutzerklärung',
|
||||||
'description' => 'Datenschutzerklärung des TSV 1908 Kulmbach e. V. – welche Daten beim Besuch unserer Website verarbeitet werden. Komplett self-hosted, ohne Tracking und ohne Drittanbieter-Dienste im Browser.',
|
'description' => 'Datenschutzerklärung des TSV 1908 Kulmbach e. V. – welche Daten beim Besuch der Website verarbeitet werden. Self-hosted, ohne Tracking und Drittanbieter.',
|
||||||
'schema' => page_schema([
|
'schema' => page_schema([
|
||||||
['name' => 'Startseite', 'slug' => ''],
|
['name' => 'Startseite', 'slug' => ''],
|
||||||
['name' => 'Datenschutz', 'slug' => 'datenschutz'],
|
['name' => 'Datenschutz', 'slug' => 'datenschutz'],
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ $cards = [
|
|||||||
|
|
||||||
$meta = [
|
$meta = [
|
||||||
'title' => 'Fußball in Kulmbach',
|
'title' => 'Fußball in Kulmbach',
|
||||||
'description' => 'Herren-, Damen- und Jugendfußball beim TSV 08 Kulmbach: erste und zweite Mannschaft auf Kreisklasse-Niveau, Damenmannschaft und Nachwuchs – aktiv werden im Katzbachtal.',
|
'description' => 'Herren-, Damen- und Jugendfußball beim TSV 08 Kulmbach: zwei Herrenmannschaften, Damenmannschaft und Nachwuchs – aktiv werden im Katzbachtal.',
|
||||||
'og_image' => 'img/pages/fussball-hero-1600.jpg',
|
'og_image' => 'img/pages/fussball-hero-1600.jpg',
|
||||||
'schema' => page_schema(
|
'schema' => page_schema(
|
||||||
[
|
[
|
||||||
|
|||||||
@@ -12,6 +12,11 @@ $meta = [
|
|||||||
'title' => 'Vereinshistorie – Der Katzbachtaler Weg',
|
'title' => 'Vereinshistorie – Der Katzbachtaler Weg',
|
||||||
'description' => 'Erlebe die bewegte Geschichte des TSV 08 Kulmbach – von den ersten Spielen an der Bayreuther Straße 1947 bis zur Hans-Rausch-Sportanlage im Katzbachtal.',
|
'description' => 'Erlebe die bewegte Geschichte des TSV 08 Kulmbach – von den ersten Spielen an der Bayreuther Straße 1947 bis zur Hans-Rausch-Sportanlage im Katzbachtal.',
|
||||||
'scripts' => ['timeline.js'],
|
'scripts' => ['timeline.js'],
|
||||||
|
'schema' => page_schema([
|
||||||
|
['name' => 'Startseite', 'slug' => ''],
|
||||||
|
['name' => 'Der Verein', 'slug' => 'verein'],
|
||||||
|
['name' => 'Vereinshistorie', 'slug' => 'historie'],
|
||||||
|
]),
|
||||||
];
|
];
|
||||||
|
|
||||||
component('hero', ['hero' => $historie['hero']]);
|
component('hero', ['hero' => $historie['hero']]);
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ $feeOptions = array_map(
|
|||||||
|
|
||||||
$meta = [
|
$meta = [
|
||||||
'title' => 'Mitglied werden',
|
'title' => 'Mitglied werden',
|
||||||
'description' => 'Mitglied werden beim TSV 08 Kulmbach: Fußball bequem online anmelden oder Turnen per Aufnahmeantrag. Alle Beiträge, Aufnahme und Infos für deinen Vereinsbeitritt in Kulmbach.',
|
'description' => 'Mitglied werden beim TSV 08 Kulmbach: Fußball online anmelden oder Turnen per Aufnahmeantrag – alle Beiträge und Infos für deinen Vereinsbeitritt.',
|
||||||
'og_image' => 'img/hero/hero-1600.jpg',
|
'og_image' => 'img/hero/hero-1600.jpg',
|
||||||
'scripts' => ['form.js'],
|
'scripts' => ['form.js'],
|
||||||
'schema' => page_schema(
|
'schema' => page_schema(
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ $contact_for = static function (array $pos) use ($directory): ?array {
|
|||||||
|
|
||||||
$meta = [
|
$meta = [
|
||||||
'title' => 'Mitmachen & Ehrenamt',
|
'title' => 'Mitmachen & Ehrenamt',
|
||||||
'description' => 'Werde ehrenamtlicher Helfer beim TSV 1908 Kulmbach: Jugendtrainer, Betreuer und Unterstützung bei Veranstaltungen. Offene Aufgaben mit direktem Ansprechpartner – ohne Vorerfahrung.',
|
'description' => 'Ehrenamt beim TSV 08 Kulmbach: offene Aufgaben als Jugendtrainer, Betreuer oder Helfer bei Veranstaltungen – mit direktem Ansprechpartner, ohne Vorerfahrung.',
|
||||||
'og_image' => 'img/pages/jugendfussball-hero-1440.jpg',
|
'og_image' => 'img/pages/jugendfussball-hero-1440.jpg',
|
||||||
'scripts' => ['position-filter.js'],
|
'scripts' => ['position-filter.js'],
|
||||||
'schema' => array_merge(
|
'schema' => array_merge(
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ component('hero', ['hero' => $page['hero']]);
|
|||||||
?>
|
?>
|
||||||
<section class="section sponsor-arguments" id="warum">
|
<section class="section sponsor-arguments" id="warum">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
|
<h2 class="visually-hidden"><?= e($page['arguments']['title']) ?></h2>
|
||||||
<ul class="sponsor-arguments__grid" role="list">
|
<ul class="sponsor-arguments__grid" role="list">
|
||||||
<?php foreach ($page['arguments']['items'] as $arg): ?>
|
<?php foreach ($page['arguments']['items'] as $arg): ?>
|
||||||
<li class="sponsor-arguments__item">
|
<li class="sponsor-arguments__item">
|
||||||
|
|||||||
@@ -10,8 +10,8 @@ $page = json_load('sportheimbuchung');
|
|||||||
$club = json_load('club');
|
$club = json_load('club');
|
||||||
|
|
||||||
$meta = [
|
$meta = [
|
||||||
'title' => 'Sportheim mieten – TSV 08 Kulmbach',
|
'title' => 'Sportheim mieten in Kulmbach',
|
||||||
'description' => 'Das Sportheim auf der Hans-Rausch-Sportanlage in Kulmbach für Feiern und Veranstaltungen mieten – Küche, Außenbereich und Beamer optional. Jetzt unverbindlich anfragen.',
|
'description' => 'Das Sportheim auf der Hans-Rausch-Sportanlage in Kulmbach für Feiern und Veranstaltungen mieten – Küche, Außenbereich, Beamer optional. Jetzt anfragen.',
|
||||||
'og_image' => 'img/pages/sportheim-2.jpg',
|
'og_image' => 'img/pages/sportheim-2.jpg',
|
||||||
'schema' => page_schema(
|
'schema' => page_schema(
|
||||||
[
|
[
|
||||||
@@ -30,6 +30,7 @@ component('hero', ['hero' => $page['hero']]);
|
|||||||
<?php /* === argumente === */ ?>
|
<?php /* === argumente === */ ?>
|
||||||
<section class="section sponsor-arguments" id="ausstattung">
|
<section class="section sponsor-arguments" id="ausstattung">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
|
<h2 class="visually-hidden"><?= e($page['features']['title']) ?></h2>
|
||||||
<ul class="sponsor-arguments__grid" role="list">
|
<ul class="sponsor-arguments__grid" role="list">
|
||||||
<?php foreach ($page['features']['items'] as $item): ?>
|
<?php foreach ($page['features']['items'] as $item): ?>
|
||||||
<li class="sponsor-arguments__item">
|
<li class="sponsor-arguments__item">
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ $slug = 'fussball/erste-mannschaft';
|
|||||||
$team = json_load('teams')['erste-mannschaft'];
|
$team = json_load('teams')['erste-mannschaft'];
|
||||||
|
|
||||||
$meta = [
|
$meta = [
|
||||||
'title' => '1. Mannschaft – Herrenfußball Kreisklasse Kulmbach',
|
'title' => '1. Mannschaft – Kreisklasse Kulmbach',
|
||||||
'description' => 'Die erste Herrenmannschaft des TSV 08 Kulmbach spielt auf Kreisklasse-Niveau – ambitioniert und mit echtem Vereinsgeist. Komm vorbei und spiel mit.',
|
'description' => 'Die erste Herrenmannschaft des TSV 08 Kulmbach spielt auf Kreisklasse-Niveau – ambitioniert und mit echtem Vereinsgeist. Komm vorbei und spiel mit.',
|
||||||
'og_image' => $team['hero']['image']['base'] . '-1600.jpg',
|
'og_image' => $team['hero']['image']['base'] . '-1600.jpg',
|
||||||
'schema' => team_schema($team, $slug),
|
'schema' => team_schema($team, $slug),
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ $d = json_load('turnen')['disciplines']['erwachsenenturnen'];
|
|||||||
|
|
||||||
$meta = [
|
$meta = [
|
||||||
'title' => 'Erwachsenenturnen in Kulmbach',
|
'title' => 'Erwachsenenturnen in Kulmbach',
|
||||||
'description' => $d['hero']['text'],
|
'description' => 'Beweglich bleiben, Kraft und Koordination trainieren – Erwachsenenturnen beim TSV 08 Kulmbach im Mäximum Gym. Trainingszeiten und Kontakt auf einen Blick.',
|
||||||
'og_image' => 'img/hero/hero-1600.jpg',
|
'og_image' => 'img/hero/hero-1600.jpg',
|
||||||
'schema' => page_schema([
|
'schema' => page_schema([
|
||||||
['name' => 'Startseite', 'slug' => ''],
|
['name' => 'Startseite', 'slug' => ''],
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ $d = json_load('turnen')['disciplines']['step-aerobic-fitness-pilates'];
|
|||||||
|
|
||||||
$meta = [
|
$meta = [
|
||||||
'title' => 'Step Aerobic, Fitness & Pilates in Kulmbach',
|
'title' => 'Step Aerobic, Fitness & Pilates in Kulmbach',
|
||||||
'description' => $d['hero']['text'],
|
'description' => 'Ausdauer, Kräftigung und Beweglichkeit für Erwachsene – Step Aerobic, Fitness & Pilates beim TSV 08 Kulmbach in der Max-Hundt-Schule. Zeiten und Kontakt.',
|
||||||
'og_image' => 'img/hero/hero-1600.jpg',
|
'og_image' => 'img/hero/hero-1600.jpg',
|
||||||
'schema' => page_schema([
|
'schema' => page_schema([
|
||||||
['name' => 'Startseite', 'slug' => ''],
|
['name' => 'Startseite', 'slug' => ''],
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ $d = json_load('turnen')['disciplines']['trampolin'];
|
|||||||
|
|
||||||
$meta = [
|
$meta = [
|
||||||
'title' => 'Trampolinturnen in Kulmbach',
|
'title' => 'Trampolinturnen in Kulmbach',
|
||||||
'description' => $d['hero']['text'],
|
'description' => 'Sprünge, Schrauben und Salti auf dem Großtrampolin – Trampolinturnen beim TSV 08 Kulmbach in der Carl-von-Linde-Realschule. Zeiten und Kontakt im Überblick.',
|
||||||
'og_image' => 'img/hero/hero-1600.jpg',
|
'og_image' => 'img/hero/hero-1600.jpg',
|
||||||
'schema' => page_schema([
|
'schema' => page_schema([
|
||||||
['name' => 'Startseite', 'slug' => ''],
|
['name' => 'Startseite', 'slug' => ''],
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ $d = json_load('turnen')['disciplines']['wettkampfturnen'];
|
|||||||
|
|
||||||
$meta = [
|
$meta = [
|
||||||
'title' => 'Wettkampfturnen in Kulmbach',
|
'title' => 'Wettkampfturnen in Kulmbach',
|
||||||
'description' => $d['hero']['text'],
|
'description' => 'Leistungsorientiertes Gerätturnen mit Training und Wettkämpfen – Wettkampfturnen beim TSV 08 Kulmbach im Mäximum Gym. Trainingszeiten und Kontakt im Überblick.',
|
||||||
'og_image' => 'img/hero/hero-1600.jpg',
|
'og_image' => 'img/hero/hero-1600.jpg',
|
||||||
'schema' => page_schema([
|
'schema' => page_schema([
|
||||||
['name' => 'Startseite', 'slug' => ''],
|
['name' => 'Startseite', 'slug' => ''],
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ $cards = [
|
|||||||
|
|
||||||
$meta = [
|
$meta = [
|
||||||
'title' => 'Der Verein',
|
'title' => 'Der Verein',
|
||||||
'description' => 'Der TSV 1908 Kulmbach e. V. – seit 1908 dein Sportverein im Katzbachtal in Kulmbach. Über 650 Mitglieder, die Abteilungen Fußball und Turnen, zuhause auf der Hans-Rausch-Sportanlage.',
|
'description' => 'Der TSV 1908 Kulmbach e. V. – seit 1908 dein Sportverein im Katzbachtal: über 650 Mitglieder, Fußball und Turnen, zuhause auf der Hans-Rausch-Sportanlage.',
|
||||||
'og_image' => 'img/pages/vereinsgelaende-1600.jpg',
|
'og_image' => 'img/pages/vereinsgelaende-1600.jpg',
|
||||||
'schema' => page_schema(
|
'schema' => page_schema(
|
||||||
[
|
[
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"choice": {
|
"choice": {
|
||||||
|
"title": "Wähle deine Abteilung",
|
||||||
"items": [
|
"items": [
|
||||||
{
|
{
|
||||||
"title": "Abteilung Fußball",
|
"title": "Abteilung Fußball",
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"arguments": {
|
"arguments": {
|
||||||
|
"title": "Warum Partner des TSV 08 werden?",
|
||||||
"items": [
|
"items": [
|
||||||
{
|
{
|
||||||
"icon": "clock-history",
|
"icon": "clock-history",
|
||||||
|
|||||||
Reference in New Issue
Block a user