Header Test
This commit is contained in:
@@ -94,42 +94,7 @@ Statuses:
|
|||||||
|
|
||||||
Complete the following:
|
Complete the following:
|
||||||
|
|
||||||
- [-] In the process of testing widgets, I noticed that some are being given the "card" treatment (the glossy purple background element) even if there is no card container. Example here: http://localhost:4567/user/admin
|
- [ ] Experiment with adding a neat new background. Pull it from @/home/vicky/Projects/nwnee-shadowsoverwestgate/media/ae02ec4a-88df-4a53-b780-00b7c3f482f4.png and try to overlay the header with it. Use your best judgment for what "looks good".
|
||||||
- [x] Widgets without the card containers should display plainly.
|
|
||||||
- [x] Widgets can be put inside of a card container to make a card.
|
|
||||||
- [x] Expand this from a single-widget bug into a theme-wide widget compatibility pass. The current issue appears broader: too many generic containers, especially plain `<div>` wrappers emitted by widgets or templates, are inheriting the glossy purple gradient card treatment even when they are only structural wrappers.
|
|
||||||
- [x] Define a compatibility model for widget rendering before implementation:
|
|
||||||
- [x] Structural wrappers should remain visually neutral by default. A wrapper existing only for layout, spacing, templating, or plugin/widget output should not automatically become a "Westgate card".
|
|
||||||
- [x] Card styling should be opt-in and intentional. The gradient/gloss/chrome treatment should apply only to known card surfaces, explicit card utility classes, or template regions that are semantically meant to read as panels.
|
|
||||||
- [x] Plain-text widgets and lightweight HTML widgets must render cleanly without needing custom markup just to avoid accidental card chrome.
|
|
||||||
- [x] Nested widget markup should not compound card styling. A widget inside a panel should not create boxes-within-boxes unless the nested card is intentional.
|
|
||||||
- [x] Footer widgets require special handling. Footer text such as "Powered by NodeBB" should behave like footer chrome, not like a content card or panel.
|
|
||||||
- [x] Build a proper investigation plan for global compatibility:
|
|
||||||
- [x] Inventory which selectors currently apply the purple gradient/card treatment too broadly. Pay particular attention to rules targeting generic `div`, broad widget wrappers, `.card`, `.panel`, Bootstrap containers, Harmony wrappers, and footer/sidebar/account-page blocks.
|
|
||||||
- [x] Trace the rendered wrapper stack for several widget types in the running forum, not just one route. Include at minimum: footer HTML widget, profile-page widget areas, sidebar widgets, category-page widgets, and any ACP-placed plain text/HTML widget.
|
|
||||||
- [x] Distinguish between three classes of surfaces:
|
|
||||||
- [x] structural wrappers
|
|
||||||
- [x] content cards/panels
|
|
||||||
- [x] utility text blocks / footer chrome / metadata strips
|
|
||||||
- [x] Decide whether the best long-term model is:
|
|
||||||
- [ ] tightening overly broad selectors so they only target real card components
|
|
||||||
- [ ] introducing a small explicit Westgate card utility class for opt-in chrome
|
|
||||||
- [ ] adding a small set of opt-out compatibility rules for widget regions that must stay plain
|
|
||||||
- [x] or a hybrid of the above
|
|
||||||
- 2026-04-24 implementation note: `scss/westgate/_widgets.scss` now limits chrome to known panel surfaces (`.card`, `.alert`, `.forum-stats`, `.search-widget`, `.category`, legacy `.panel`/`.well`/`.jumbotron`) plus explicit opt-in utility classes `.westgate-widget-card` and `.wg-widget-card`. Generic top-level wrappers in widget areas are neutral again, and footer wrappers are forced back to plain chrome.
|
|
||||||
- [x] Define expected compatibility outcomes before coding:
|
|
||||||
- [x] A plain HTML widget that outputs only text or a single `<div>` should render plainly.
|
|
||||||
- [x] A widget wrapped in an intentional card class should receive the full glossy Westgate card treatment.
|
|
||||||
- [x] Existing topic lists, category lists, and intentional content panels should keep their current Westgate identity.
|
|
||||||
- [x] Footer widget areas should not automatically gain panel framing unless explicitly requested.
|
|
||||||
- [x] Account/profile pages such as `/user/admin` should not pick up accidental panel chrome from generic wrappers.
|
|
||||||
- [x] Widget/plugin markup from outside this theme should degrade gracefully even if it uses simple Bootstrap or generic `<div>` containers.
|
|
||||||
- [-] Validation plan once implementation starts:
|
|
||||||
- [ ] Check desktop and mobile for footer widgets, sidebar widgets, profile widgets, and at least one plain HTML widget with no special classes.
|
|
||||||
- [ ] Confirm that intentionally carded widgets still look like Westgate cards.
|
|
||||||
- [ ] Confirm that nested wrappers no longer create accidental card-on-card stacking.
|
|
||||||
- [ ] Verify no regressions to topic cards, category panels, or other intentional glossy surfaces.
|
|
||||||
- [x] Local investigation covered the rendered wrapper stack on `http://localhost:4567/user/admin`, `http://localhost:4567/categories`, `http://localhost:4567/category/2/announcements`, and the sidebar footer widget HTML from the live local render.
|
|
||||||
|
|
||||||
## Future Tasks
|
## Future Tasks
|
||||||
|
|
||||||
@@ -192,9 +157,44 @@ Tasks to be considered in the future, not implemented immediately. Keep them in
|
|||||||
- [ ] Decide whether uploaded category background images should be cleared for icon-driven categories after seeing the final ACP-configured visuals.
|
- [ ] Decide whether uploaded category background images should be cleared for icon-driven categories after seeing the final ACP-configured visuals.
|
||||||
- [ ] Explain any operational follow-up after ACP setup, especially asset rebuild, restart/cache behavior, and whether legacy Bootstrap layout classes should remain in category custom class fields.
|
- [ ] Explain any operational follow-up after ACP setup, especially asset rebuild, restart/cache behavior, and whether legacy Bootstrap layout classes should remain in category custom class fields.
|
||||||
|
|
||||||
Next useful moves:
|
- [-] In the process of testing widgets, I noticed that some are being given the "card" treatment (the glossy purple background element) even if there is no card container. Example here: http://localhost:4567/user/admin
|
||||||
|
- [x] Widgets without the card containers should display plainly.
|
||||||
|
- [x] Widgets can be put inside of a card container to make a card.
|
||||||
|
- [x] Expand this from a single-widget bug into a theme-wide widget compatibility pass. The current issue appears broader: too many generic containers, especially plain `<div>` wrappers emitted by widgets or templates, are inheriting the glossy purple gradient card treatment even when they are only structural wrappers.
|
||||||
|
- [x] Define a compatibility model for widget rendering before implementation:
|
||||||
|
- [x] Structural wrappers should remain visually neutral by default. A wrapper existing only for layout, spacing, templating, or plugin/widget output should not automatically become a "Westgate card".
|
||||||
|
- [x] Card styling should be opt-in and intentional. The gradient/gloss/chrome treatment should apply only to known card surfaces, explicit card utility classes, or template regions that are semantically meant to read as panels.
|
||||||
|
- [x] Plain-text widgets and lightweight HTML widgets must render cleanly without needing custom markup just to avoid accidental card chrome.
|
||||||
|
- [x] Nested widget markup should not compound card styling. A widget inside a panel should not create boxes-within-boxes unless the nested card is intentional.
|
||||||
|
- [x] Footer widgets require special handling. Footer text such as "Powered by NodeBB" should behave like footer chrome, not like a content card or panel.
|
||||||
|
- [x] Build a proper investigation plan for global compatibility:
|
||||||
|
- [x] Inventory which selectors currently apply the purple gradient/card treatment too broadly. Pay particular attention to rules targeting generic `div`, broad widget wrappers, `.card`, `.panel`, Bootstrap containers, Harmony wrappers, and footer/sidebar/account-page blocks.
|
||||||
|
- [x] Trace the rendered wrapper stack for several widget types in the running forum, not just one route. Include at minimum: footer HTML widget, profile-page widget areas, sidebar widgets, category-page widgets, and any ACP-placed plain text/HTML widget.
|
||||||
|
- [x] Distinguish between three classes of surfaces:
|
||||||
|
- [x] structural wrappers
|
||||||
|
- [x] content cards/panels
|
||||||
|
- [x] utility text blocks / footer chrome / metadata strips
|
||||||
|
- [x] Decide whether the best long-term model is:
|
||||||
|
- [ ] tightening overly broad selectors so they only target real card components
|
||||||
|
- [ ] introducing a small explicit Westgate card utility class for opt-in chrome
|
||||||
|
- [ ] adding a small set of opt-out compatibility rules for widget regions that must stay plain
|
||||||
|
- [x] or a hybrid of the above
|
||||||
|
- 2026-04-24 implementation note: `scss/westgate/_widgets.scss` now limits chrome to known panel surfaces (`.card`, `.alert`, `.forum-stats`, `.search-widget`, `.category`, legacy `.panel`/`.well`/`.jumbotron`) plus explicit opt-in utility classes `.westgate-widget-card` and `.wg-widget-card`. Generic top-level wrappers in widget areas are neutral again, and footer wrappers are forced back to plain chrome.
|
||||||
|
- [x] Define expected compatibility outcomes before coding:
|
||||||
|
- [x] A plain HTML widget that outputs only text or a single `<div>` should render plainly.
|
||||||
|
- [x] A widget wrapped in an intentional card class should receive the full glossy Westgate card treatment.
|
||||||
|
- [x] Existing topic lists, category lists, and intentional content panels should keep their current Westgate identity.
|
||||||
|
- [x] Footer widget areas should not automatically gain panel framing unless explicitly requested.
|
||||||
|
- [x] Account/profile pages such as `/user/admin` should not pick up accidental panel chrome from generic wrappers.
|
||||||
|
- [x] Widget/plugin markup from outside this theme should degrade gracefully even if it uses simple Bootstrap or generic `<div>` containers.
|
||||||
|
- [-] Validation plan once implementation starts:
|
||||||
|
- [ ] Check desktop and mobile for footer widgets, sidebar widgets, profile widgets, and at least one plain HTML widget with no special classes.
|
||||||
|
- [ ] Confirm that intentionally carded widgets still look like Westgate cards.
|
||||||
|
- [ ] Confirm that nested wrappers no longer create accidental card-on-card stacking.
|
||||||
|
- [ ] Verify no regressions to topic cards, category panels, or other intentional glossy surfaces.
|
||||||
|
- [x] Local investigation covered the rendered wrapper stack on `http://localhost:4567/user/admin`, `http://localhost:4567/categories`, `http://localhost:4567/category/2/announcements`, and the sidebar footer widget HTML from the live local render.
|
||||||
|
|
||||||
Re-enter the preferred wg-icon-\* classes from GAME_ICONS.md into this local NodeBB instance, then rerun the rendered checks. Decide whether category background images should be cleared once the real ACP-configured icons are visible. Add the short operational note about rebuild/restart/cache behavior after ACP updates.
|
Next useful moves:
|
||||||
|
|
||||||
### Context for categories
|
### Context for categories
|
||||||
|
|
||||||
|
|||||||
+2
-1
@@ -18,6 +18,7 @@
|
|||||||
},
|
},
|
||||||
"staticDirs": {
|
"staticDirs": {
|
||||||
"fonts": "public/fonts",
|
"fonts": "public/fonts",
|
||||||
"game-icons": "public/game-icons"
|
"game-icons": "public/game-icons",
|
||||||
|
"images": "public/images"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 1.2 MiB |
Binary file not shown.
|
After Width: | Height: | Size: 2.4 MiB |
@@ -0,0 +1,169 @@
|
|||||||
|
.westgate-brand-hero {
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
margin-top: 0.25rem;
|
||||||
|
border: 1px solid rgba(194, 163, 90, 0.22);
|
||||||
|
border-radius: 10px;
|
||||||
|
padding: 1.05rem 1.05rem;
|
||||||
|
filter: saturate(1) contrast(1) brightness(1);
|
||||||
|
background: url("./plugins/nodebb-theme-westgate/images/plum-header-bg.png") center 50% / cover no-repeat;
|
||||||
|
box-shadow:
|
||||||
|
inset 0 1px 0 rgba(255, 242, 204, 0.08),
|
||||||
|
inset 0 0 0 1px rgba(33, 21, 28, 0.5),
|
||||||
|
0 18px 42px rgba(0, 0, 0, 0.3);
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
background:
|
||||||
|
radial-gradient(circle at 22% 46%, rgba(120, 46, 94, 0.15), transparent 26%),
|
||||||
|
linear-gradient(90deg, rgba(14, 11, 18, 0.54) 0%, rgba(37, 19, 36, 0.24) 24%, rgba(37, 19, 36, 0.18) 76%, rgba(14, 11, 18, 0.58) 100%);
|
||||||
|
opacity: 0.82;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.westgate-brand-hero__veil,
|
||||||
|
.westgate-brand-hero__inner {
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.westgate-brand-hero__veil {
|
||||||
|
position: absolute;
|
||||||
|
inset: auto 0 0 0;
|
||||||
|
height: 54%;
|
||||||
|
background: linear-gradient(180deg, rgba(11, 8, 15, 0), rgba(34, 15, 30, 0.62));
|
||||||
|
z-index: 0;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.westgate-brand-hero__inner {
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 0;
|
||||||
|
min-height: 128px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.westgate-brand-hero__brand {
|
||||||
|
width: 100%;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
min-height: inherit;
|
||||||
|
padding: 0 0 0 clamp(1rem, 4vw, 3rem);
|
||||||
|
|
||||||
|
&:hover,
|
||||||
|
&:focus-within {
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.westgate-brand-hero__brand :where([component="brand/anchor"], [component="siteTitle"]) {
|
||||||
|
color: inherit;
|
||||||
|
text-decoration: none;
|
||||||
|
|
||||||
|
&:hover,
|
||||||
|
&:focus {
|
||||||
|
color: inherit;
|
||||||
|
text-decoration: none;
|
||||||
|
background: transparent;
|
||||||
|
box-shadow: none;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.westgate-brand-hero__brand [component="siteTitle"] {
|
||||||
|
width: 100%;
|
||||||
|
padding: 0;
|
||||||
|
justify-content: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.westgate-brand-hero__title-block {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: flex-start;
|
||||||
|
gap: 0.35rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.westgate-brand-hero__brand [component="siteTitle"] :where(h1, .fs-6) {
|
||||||
|
font-family: var(--wg-font-display);
|
||||||
|
font-size: clamp(1.65rem, 2.8vw, 2.5rem) !important;
|
||||||
|
line-height: 0.92;
|
||||||
|
font-weight: 600;
|
||||||
|
letter-spacing: 0.1em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
text-shadow:
|
||||||
|
0 1px 0 rgba(255, 222, 142, 0.05),
|
||||||
|
0 2px 0 rgba(52, 37, 15, 0.92),
|
||||||
|
0 4px 0 rgba(16, 11, 6, 0.96),
|
||||||
|
0 8px 14px rgba(0, 0, 0, 0.72),
|
||||||
|
0 14px 26px rgba(0, 0, 0, 0.46),
|
||||||
|
0 0 16px rgba(48, 10, 26, 0.24);
|
||||||
|
opacity: 0.82;
|
||||||
|
mix-blend-mode: screen;
|
||||||
|
}
|
||||||
|
|
||||||
|
.westgate-brand-hero__subtitle {
|
||||||
|
color: #c2a35a;
|
||||||
|
font-family: var(--wg-font-display);
|
||||||
|
font-size: 0.86rem;
|
||||||
|
font-weight: 600;
|
||||||
|
letter-spacing: 0.22em;
|
||||||
|
line-height: 1;
|
||||||
|
text-transform: uppercase;
|
||||||
|
text-shadow:
|
||||||
|
0 1px 0 rgba(0, 0, 0, 0.92),
|
||||||
|
0 3px 8px rgba(0, 0, 0, 0.34);
|
||||||
|
}
|
||||||
|
|
||||||
|
.westgate-brand-hero__widgets {
|
||||||
|
position: relative;
|
||||||
|
color: var(--wg-text);
|
||||||
|
text-shadow: 0 1px 0 rgba(0, 0, 0, 0.74);
|
||||||
|
width: 100%;
|
||||||
|
padding-left: 0;
|
||||||
|
border-left: 0;
|
||||||
|
text-align: center;
|
||||||
|
margin-top: 0.5rem;
|
||||||
|
|
||||||
|
> :last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 991.98px) {
|
||||||
|
.westgate-brand-hero {
|
||||||
|
margin-top: 0;
|
||||||
|
padding: 0.95rem 0.9rem;
|
||||||
|
background-position: center 46%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.westgate-brand-hero__inner {
|
||||||
|
min-height: 108px;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.westgate-brand-hero__brand {
|
||||||
|
min-height: 0;
|
||||||
|
padding: 0 0 0 0.4rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.westgate-brand-hero__title-block {
|
||||||
|
gap: 0.28rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.westgate-brand-hero__brand [component="siteTitle"] :where(h1, .fs-6) {
|
||||||
|
font-size: clamp(1.3rem, 5.2vw, 1.8rem) !important;
|
||||||
|
letter-spacing: 0.07em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.westgate-brand-hero__subtitle {
|
||||||
|
font-size: 0.74rem;
|
||||||
|
letter-spacing: 0.18em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.westgate-brand-hero__widgets {
|
||||||
|
border-top: 1px solid rgba(216, 194, 138, 0.12);
|
||||||
|
padding-top: 0.85rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="{function.localeToHTML, userLang, defaultLang}" {{{if languageDirection}}}data-dir="{languageDirection}" style="direction: {languageDirection};"{{{end}}}>
|
||||||
|
<head>
|
||||||
|
<title>{browserTitle}</title>
|
||||||
|
{{{each metaTags}}}{function.buildMetaTag}{{{end}}}
|
||||||
|
<link rel="stylesheet" type="text/css" href="{relative_path}/assets/client{{{if bootswatchSkin}}}-{bootswatchSkin}{{{end}}}{{{ if (languageDirection=="rtl") }}}-rtl{{{ end }}}.css?{config.cache-buster}" />
|
||||||
|
{{{each linkTags}}}{function.buildLinkTag}{{{end}}}
|
||||||
|
|
||||||
|
<script>
|
||||||
|
var config = JSON.parse('{{configJSON}}');
|
||||||
|
var app = {
|
||||||
|
user: JSON.parse('{{userJSON}}')
|
||||||
|
};
|
||||||
|
document.documentElement.style.setProperty('--panel-offset', `0px`);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{{{if useCustomHTML}}}
|
||||||
|
{{customHTML}}
|
||||||
|
{{{end}}}
|
||||||
|
{{{if useCustomCSS}}}
|
||||||
|
<style>{{customCSS}}</style>
|
||||||
|
{{{end}}}
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body class="{bodyClass} skin-{{{if bootswatchSkin}}}{bootswatchSkin}{{{else}}}noskin{{{end}}}">
|
||||||
|
<a class="visually-hidden-focusable position-absolute top-0 start-0 p-3 m-3 bg-body" style="z-index: 1021;" href="#content">[[global:skip-to-content]]</a>
|
||||||
|
|
||||||
|
{{{ if config.theme.topMobilebar }}}
|
||||||
|
<!-- IMPORT partials/mobile-header.tpl -->
|
||||||
|
{{{ end }}}
|
||||||
|
|
||||||
|
<div class="layout-container d-flex justify-content-between pb-4 pb-md-0">
|
||||||
|
<!-- IMPORT partials/sidebar-left.tpl -->
|
||||||
|
|
||||||
|
<main id="panel" class="d-flex flex-column gap-3 flex-grow-1 mt-3" style="min-width: 0;">
|
||||||
|
<div class="container-lg px-md-4 d-flex flex-column gap-3 h-100 mb-5 mb-lg-0" id="content">
|
||||||
|
<!-- IMPORT partials/header/brand.tpl -->
|
||||||
|
<!-- IMPORT partials/noscript/warning.tpl -->
|
||||||
|
<!-- IMPORT partials/noscript/message.tpl -->
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
{{{ if (brand:logo || (config.showSiteTitle || widgets.brand-header.length)) }}}
|
||||||
|
<div class="container-lg px-md-4 brand-container westgate-brand-hero">
|
||||||
|
<div class="westgate-brand-hero__veil"></div>
|
||||||
|
<div class="d-flex westgate-brand-hero__inner {{{ if config.theme.centerHeaderElements }}}justify-content-left{{{ end }}}">
|
||||||
|
{{{ if config.showSiteTitle }}}
|
||||||
|
<div component="brand/wrapper" class="d-flex align-items-center justify-content-left align-content-stretch westgate-brand-hero__brand">
|
||||||
|
<a component="siteTitle" class="text-truncate align-self-stretch align-items-center d-flex justify-content-left" href="{{{ if title:url }}}{title:url}{{{ else }}}{relative_path}/{{{ end }}}">
|
||||||
|
<span class="westgate-brand-hero__title-block">
|
||||||
|
<h1 class="fs-6 fw-bold text-body mb-0">{config.siteTitle}</h1>
|
||||||
|
<span class="westgate-brand-hero__subtitle">Forums</span>
|
||||||
|
</span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
{{{ end }}}
|
||||||
|
{{{ if widgets.brand-header.length }}}
|
||||||
|
<div data-widget-area="brand-header" class="flex-fill gap-3 align-self-center westgate-brand-hero__widgets">
|
||||||
|
{{{each widgets.brand-header}}}
|
||||||
|
{{./html}}
|
||||||
|
{{{end}}}
|
||||||
|
</div>
|
||||||
|
{{{ end }}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{{ end }}}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
@import "../nodebb-theme-harmony/theme";
|
@import "../nodebb-theme-harmony/theme";
|
||||||
@import "./scss/westgate/tokens";
|
@import "./scss/westgate/tokens";
|
||||||
|
@import "./scss/westgate/header";
|
||||||
@import "./scss/westgate/surfaces";
|
@import "./scss/westgate/surfaces";
|
||||||
@import "./scss/westgate/categories";
|
@import "./scss/westgate/categories";
|
||||||
@import "./scss/westgate/topics";
|
@import "./scss/westgate/topics";
|
||||||
|
|||||||
Reference in New Issue
Block a user