456 files
This commit is contained in:
1 parent
4192ecbaae
commit
5d6d845ebf
456 files changed
+64951
-3828
No files matched your search
+5
-7
@@ -1,5 +1,5 @@
|
||||
/*! maintenance_supporter frontend 2.94.0 */
|
||||
import{j as M}from"./chunks/chunk-HSMB7CYB.js";import{c as T,d as l}from"./chunks/chunk-RVTWU5ZB.js";var D="maintenance-supporter",N=`ll-strategy-dashboard-${D}`,P="hui-maintenance-supporter-strategy-editor",V="NOT_RUNNING",B=[{status:"overdue",title:"Overdue",icon:l.overdue,path:"overdue"},{status:"triggered",title:"Triggered",icon:l.triggered,path:"triggered"},{status:"due_soon",title:"Due Soon",icon:l.due_soon,path:"due-soon"},{status:"ok",title:"OK",icon:l.ok,path:"ok"}],R=[{title:"Overdue",icon:l.overdue,path:"overdue",filter:{filter_due_max_days:-1},matches:n=>n<=-1},{title:"Today",icon:"mdi:calendar-today",path:"today",filter:{filter_due_min_days:0,filter_due_max_days:0},matches:n=>n===0},{title:"This Week",icon:"mdi:calendar-week",path:"this-week",filter:{filter_due_min_days:1,filter_due_max_days:7},matches:n=>n>=1&&n<=7},{title:"This Month",icon:"mdi:calendar-month",path:"this-month",filter:{filter_due_min_days:8,filter_due_max_days:30},matches:n=>n>=8&&n<=30},{title:"Later",icon:"mdi:calendar-clock",path:"later",filter:{filter_due_min_days:31},matches:n=>n>=31}];function d(n){return{type:"grid",cards:[n]}}var $={condition:"view_columns",min:2};function y(n,i,e){let s=i[n];if(s)return`{{ states('${s}') }}`;let t=e[n];return t==null?"\u2014":String(t)}function U(n={},i={}){return{type:"markdown",text_only:!0,content:[`\u{1F534} **${y("overdue",n,i)}** overdue`,`\u26A1 **${y("triggered",n,i)}** triggered`,`\u{1F7E1} **${y("due_soon",n,i)}** due soon`,`\u{1F7E2} **${y("ok",n,i)}** ok`].join(" \xB7 ")}}function W(){return{title:"Maintenance",type:"panel",cards:[{type:"empty-state",icon:"mdi:wrench-clock",icon_color:"primary",content_only:!0,title:"No maintenance objects yet",content:"Open the Maintenance panel to add your first object \u2014 pool pump, HVAC filter, vehicle, anything that needs scheduled care.",buttons:[{icon:"mdi:wrench",text:"Open Maintenance panel",appearance:"filled",variant:"brand",tap_action:{action:"navigate",navigation_path:"/maintenance-supporter"}},{icon:"mdi:plus",text:"Add object",appearance:"outlined",variant:"brand",tap_action:{action:"fire-dom-event",ll_custom:{type:"maintenance-supporter:add-object"}}}]}]}}function Y(n={},i={}){let e=U(n,i);return{title:"Overview",icon:"mdi:wrench-clock",path:"overview",type:"sections",header:{layout:"responsive",card:e},sidebar:{sections:[{type:"grid",cards:[{type:"heading",heading:"Status",heading_style:"title"},e]}],visibility:[$],content_label:"Tasks",sidebar_label:"Status"},sections:[d({type:"custom:maintenance-supporter-card",show_header:!1,filter_status:[...T]})]}}function F(n,i){let e=new Map;for(let a of n){let r=a.object.area_id||null;e.has(r)||e.set(r,[]),e.get(r).push(a)}let s=Array.from(e.keys()).filter(a=>a!==null);s.sort((a,r)=>{let u=i[a]?.name||a,c=i[r]?.name||r;return u.localeCompare(c)});let t=[];for(let a of s){let r=e.get(a);if(r.length===0)continue;let u=i[a];t.push({title:u?.name||a,icon:u?.icon||"mdi:floor-plan",path:`area-${a}`,type:"sections",sections:[d({type:"custom:maintenance-supporter-card",show_header:!1,filter_objects:r.map(c=>c.object.name)})]})}let o=e.get(null);return o&&o.length>0&&t.push({title:"Unassigned",icon:"mdi:help-circle-outline",path:"unassigned",type:"sections",sections:[d({type:"custom:maintenance-supporter-card",show_header:!1,filter_objects:o.map(a=>a.object.name)})]}),t}function K(n){let i=new Set;for(let s of n)for(let t of s.tasks||[])t.status&&i.add(t.status);let e=[];for(let s of B)i.has(s.status)&&e.push({title:s.title,icon:s.icon,path:s.path,type:"sections",sections:[d({type:"custom:maintenance-supporter-card",show_header:!1,filter_status:[s.status]})]});return e}function q(n,i,e){let s=new Map;for(let r of n){let u=r.object.area_id,c=u&&i[u]?.floor_id||null;s.has(c)||s.set(c,[]),s.get(c).push(r)}let t=Array.from(s.keys()).filter(r=>r!==null);t.sort((r,u)=>{let c=e[r],g=e[u],k=c?.level??0,E=g?.level??0;return k!==E?k-E:(c?.name||r).localeCompare(g?.name||u)});let o=[];for(let r of t){let u=s.get(r);if(u.length===0)continue;let c=e[r];o.push({title:c?.name||r,icon:c?.icon||"mdi:home-floor-1",path:`floor-${r}`,type:"sections",sections:[d({type:"custom:maintenance-supporter-card",show_header:!1,filter_objects:u.map(g=>g.object.name)})]})}let a=s.get(null);return a&&a.length>0&&o.push({title:"Other",icon:"mdi:help-circle-outline",path:"other",type:"sections",sections:[d({type:"custom:maintenance-supporter-card",show_header:!1,filter_objects:a.map(r=>r.object.name)})]}),o}function z(n){return[{title:"Week",icon:"mdi:calendar-week",path:"cal-7",window_days:7},{title:"Fortnight",icon:"mdi:calendar-week-begin",path:"cal-14",window_days:14},{title:"Month",icon:"mdi:calendar-month",path:"cal-30",window_days:30},{title:"Year",icon:"mdi:calendar-clock",path:"cal-365",window_days:365}].map(e=>({title:e.title,icon:e.icon,path:e.path,type:"panel",cards:[{type:"custom:maintenance-supporter-calendar-card",window_days:e.window_days,show_window_chips:!1,show_user_filter:!0}]}))}function Q(n){let i=Line truncated
|
||||
/*! maintenance_supporter frontend 2.95.0 */
|
||||
import{j as O}from"./chunks/chunk-4JW6SHXP.js";import{c as j,d as p,g as A,i as L}from"./chunks/chunk-3MSNNIFG.js";var Y={maintenance:"Maintenance",overview:"Overview",overdue:"Overdue",triggered:"Triggered",due_soon:"Due Soon",ok:"OK",today:"Today",today_this_week:"This week",unassigned:"Unassigned",tasks:"Tasks",strat_this_month:"This Month",strat_later:"Later",strat_week:"Week",strat_fortnight:"Fortnight",strat_month:"Month",strat_year:"Year",strat_other:"Other",strat_status:"Status",strat_empty_title:"No maintenance objects yet",strat_empty_content:"Open the Maintenance panel to add your first object \u2014 pool pump, HVAC filter, vehicle, anything that needs scheduled care.",strat_open_panel:"Open Maintenance panel",strat_add_object:"Add object",strat_not_loaded:"**Maintenance Supporter** is not loaded. Install/enable the integration first.",strat_group_by:"Group views by",strat_group_area:"By area (default)",strat_group_status:"By status (Overdue / Triggered / Due Soon / OK)",strat_group_floor:"By floor (uses HA floors)",strat_group_due_date:"By due date (Overdue / Today / Week / Month / Later)",strat_group_calendar:"Rolling calendar (Week / Fortnight / Month / Year)",strat_editor_help:'The "Overview" view is always first. Empty groups are skipped.'},h="en",c=t=>A(t,h,Y[t]);async function $(t){h=t?.language||"en",await L(h)}var V="maintenance-supporter",W=`ll-strategy-dashboard-${V}`,B="hui-maintenance-supporter-strategy-editor",F="NOT_RUNNING",q=[{status:"overdue",title:"overdue",icon:p.overdue,path:"overdue"},{status:"triggered",title:"triggered",icon:p.triggered,path:"triggered"},{status:"due_soon",title:"due_soon",icon:p.due_soon,path:"due-soon"},{status:"ok",title:"ok",icon:p.ok,path:"ok"}],x=[{title:"overdue",icon:p.overdue,path:"overdue",filter:{filter_due_max_days:-1},matches:t=>t<=-1},{title:"today",icon:"mdi:calendar-today",path:"today",filter:{filter_due_min_days:0,filter_due_max_days:0},matches:t=>t===0},{title:"today_this_week",icon:"mdi:calendar-week",path:"this-week",filter:{filter_due_min_days:1,filter_due_max_days:7},matches:t=>t>=1&&t<=7},{title:"strat_this_month",icon:"mdi:calendar-month",path:"this-month",filter:{filter_due_min_days:8,filter_due_max_days:30},matches:t=>t>=8&&t<=30},{title:"strat_later",icon:"mdi:calendar-clock",path:"later",filter:{filter_due_min_days:31},matches:t=>t>=31}];function l(t){return{type:"grid",cards:[t]}}var z={condition:"view_columns",min:2};function _(t,r,e){let s=r[t];if(s)return`{{ states('${s}') }}`;let n=e[t];return n==null?"\u2014":String(n)}function Q(t={},r={}){return{type:"markdown",text_only:!0,content:[`\u{1F534} **${_("overdue",t,r)}** ${c("overdue")}`,`\u26A1 **${_("triggered",t,r)}** ${c("triggered")}`,`\u{1F7E1} **${_("due_soon",t,r)}** ${c("due_soon")}`,`\u{1F7E2} **${_("ok",t,r)}** ${c("ok")}`].join(" \xB7 ")}}function X(){return{title:c("maintenance"),type:"panel",cards:[{type:"empty-state",icon:"mdi:wrench-clock",icon_color:"primary",content_only:!0,title:c("strat_empty_title"),content:c("strat_empty_content"),buttons:[{icon:"mdi:wrench",text:c("strat_open_panel"),appearance:"filled",variant:"brand",tap_action:{action:"navigate",navigation_path:"/maintenance-supporter"}},{icon:"mdi:plus",text:c("strat_add_object"),appearance:"outlined",variant:"brand",tap_action:{action:"fire-dom-event",ll_custom:{type:"maintenance-supporter:add-object"}}}]}]}}function J(t={},r={}){let e=Q(t,r);return{title:c("overview"),icon:"mdi:wrench-clock",path:"overview",type:"sections",header:{layout:"responsive",card:e},sidebar:{sections:[{type:"grid",cards:[{type:"heading",heading:c("strat_status"),heading_style:"title"},e]}],visibility:[z],content_label:c("tasks"),sidebar_label:c("strat_status")},sections:[l({type:"custom:maintenance-supporter-card",show_header:!1,filter_status:[...j]})]}}function Z(t,r){let e=new Map;for(let i of t){let a=i.object.area_id||null;e.has(a)||e.set(a,[]),e.get(a).push(i)}let s=Array.from(e.keys()).filter(i=>i!==null);s.sort((i,a)=>{let d=r[i]?.name||i,u=r[a]?.name||a;return d.localeCompare(u)});let n=[];for(let i of s){let a=e.get(i);if(a.length===0)continue;let d=r[i];n.push({title:d?.name||i,icon:d?.icon||"mdi:floor-plan",path:`area-${i}`,type:"sections",sections:[l({type:"custom:maintenance-supporter-card",show_header:!1,filter_objects:a.map(u=>u.object.name)})]})}let o=e.get(null);return o&&o.length>0&&n.push({title:c("unassigned"),icon:"mdi:help-circle-outline",path:"unassigned",type:"sections",sections:[l({type:"custom:maintenance-supporter-card",show_header:!1,filter_objects:o.map(i=>i.object.name)})]}),n}function ee(t){let r=new Set;for(let s of t)for(let n of s.tasks||[])n.status&&r.add(n.status);let e=[];for(let s of q)r.has(s.status)&&e.push({title:c(s.title),icon:s.icon,path:s.path,type:"sections",sections:[l({type:"custom:maintenance-supporter-card",show_header:!1,filter_status:[s.status]})]});return e}function te(t,r,e){let s=new Map;for(let a of t){let d=a.object.area_id,u=d&&r[d]?.floor_id||null;s.has(u)||s.seLine truncated
|
||||
<style>
|
||||
:host, .editor { display: block; padding: 16px 0; }
|
||||
label { display: block; font-weight: 500; margin-bottom: 8px; }
|
||||
@@ -16,10 +16,8 @@ import{j as M}from"./chunks/chunk-HSMB7CYB.js";import{c as T,d as l}from"./chunk
|
||||
}
|
||||
</style>
|
||||
<div class="editor">
|
||||
<label for="group-by">Group views by</label>
|
||||
<label for="group-by">${k(c("strat_group_by"))}</label>
|
||||
<select id="group-by">${s}</select>
|
||||
<div class="help">
|
||||
The "Overview" view is always first. Empty groups are skipped.
|
||||
</div>
|
||||
<div class="help">${k(c("strat_editor_help"))}</div>
|
||||
</div>
|
||||
`;let t=this.querySelector("#group-by");t?.addEventListener("change",()=>{let o={...this._config,group_by:t.value};this._config=o,this.dispatchEvent(new CustomEvent("config-changed",{detail:{config:o},bubbles:!0,composed:!0}))})}},S="maintenance-supporter-section",J=`ll-strategy-section-${S}`,_=class extends HTMLElement{static async generate(i,e){let s={type:"custom:maintenance-supporter-card",show_header:!1};i?.filter_status?.length&&(s.filter_status=i.filter_status),i?.max_items&&(s.max_items=i.max_items),i?.filter_due_min_days!==void 0&&(s.filter_due_min_days=i.filter_due_min_days),i?.filter_due_max_days!==void 0&&(s.filter_due_max_days=i.filter_due_max_days);let t=i?.filter_objects;if(i?.area_id&&!t)try{t=((await e.connection.sendMessagePromise({type:"maintenance_supporter/objects"})).objects||[]).filter(r=>r.object.area_id===i.area_id).map(r=>r.object.name)}catch{}t&&t.length>0&&(s.filter_objects=t);let o=[];return i?.title&&o.push({type:"heading",heading:i.title,heading_style:"title"}),o.push(s),{type:"grid",cards:o}}},G="2.3.6",Z="[maintenance-supporter]";function A(n,i){try{return customElements.get(n)?"skipped":(customElements.define(n,i),"ok")}catch(e){return`ERROR: ${String(e)}`}}var H={editor:A(P,C),section:A(J,_)};console.log(`${Z} strategy bundle v${G} loaded \u2014 registrations:`,H,"\u2014 run maintenanceSupporterDiagnose() in console for full state");window.maintenanceSupporterDiagnose=async()=>{let n=N,i=[];try{let e=document.querySelector("home-assistant");e?.hass&&(i=(await e.hass.connection.sendMessagePromise({type:"lovelace/resources"})).resources||[])}catch(e){i=[{url:`<error: ${String(e)}>`}]}return{version:G,el_registered:!!customElements.get(n),el_class_excerpt:customElements.get(n)?.toString().slice(0,100)||null,customStrategies_dashboard:window.customStrategies?.filter(e=>e.strategyType==="dashboard").map(e=>e.type)||[],scriptTagsInPage:Array.from(document.querySelectorAll("script[type=module]")).map(e=>e.src).filter(e=>/maint|strateg/i.test(e)),lovelaceResources_matching:i.filter(e=>/maint|strateg/i.test(e.url||"")).map(e=>e.url),registrations:H}};var h=class extends HTMLElement{static async generate(i,e){return await import("./chunks/vacation-section-card-NYA736FJ.js"),{type:"grid",cards:[{type:"custom:maintenance-vacation-section-card",title:i?.title}]}}},b=class extends HTMLElement{static async generate(i,e){return await import("./chunks/budget-section-card-ZFASWXPP.js"),{type:"grid",cards:[{type:"custom:maintenance-budget-section-card",title:i?.title}]}}},w=class extends HTMLElement{static async generate(i,e){return await import("./chunks/groups-section-card-QPDSJJK3.js"),{type:"grid",cards:[{type:"custom:maintenance-groups-section-card",title:i?.title}]}}},O="ll-strategy-section-maintenance-supporter-vacation",L="ll-strategy-section-maintenance-supporter-budget",x="ll-strategy-section-maintenance-supporter-groups";customElements.get(O)||customElements.define(O,h);customElements.get(L)||customElements.define(L,b);customElements.get(x)||customElements.define(x,w);var se={[S]:_,"maintenance-supporter-vacation":h,"maintenance-supporter-budget":b,"maintenance-supporter-groups":w},f=null;function ee(){return f||(f=import("./chunks/dialog-mount-WO4CSUQS.js").catch(n=>{throw f=null,n})),f}var I="_msSupporterLlCustomBound";function p(n){history.pushState(null,"",n),window.dispatchEvent(new CustomEvent("location-changed"))}function te(){let n=window;n[I]||(n[I]=!0,document.addEventListener("ll-custom",i=>{let e=i.detail;if(!e||typeof e!="object")return;let s=e.ll_custom,t=s&&typeof s=="object"?s:e;if(!t||typeof t.type!="string"||!t.type.startsWith("maintenance-supporter:"))return;let o=t.type.slice(22);if(o==="deep-link"&&typeof t.path=="string"){p(t.path);return}(async()=>{let a;try{a=await ee()}catch{p("/maintenance-supporter");return}if(o==="add-object"){if(a.openCreateObjectDialog())return;p("/maintenance-supporter?ms_action=add_object");return}if(o==="open-task"&&typeof t.entry_id=="string"&&typeof t.task_id=="string"){if(a.openTaskQuickActions(t.entry_id,t.task_id)||a.openEditTaskDialog(t.entry_id,t.task_id))return;p(`/maintenance-supporter?entry_id=${encodeURIComponent(t.entry_id)}&task_id=${encodeURIComponent(t.task_id)}`);return}if(o==="open-object"&&typeof t.entry_id=="string"){if(a.openObjectQuickActions(t.entry_id))return;p(`/maintenance-supporter?entry_id=${encodeURIComponent(t.entry_id)}`);return}if(o==="edit-history"&&typeof t.entry_id=="string"&&typeof t.task_id=="string"&&typeof t.original_timestamp=="string"){let u=document.querySelector("home-assistant")?.hass;if(!u)return;try{let c=await M(u,t.entry_id,t.task_id,t.original_timestamp);if(!c)return;a.openHistoryEditDialog(c)}catch{p("/maintenance-supporter")}}})()}))}te();var v=window;v.customStrategies=v.customStrategies||[];function m(n){v.customStrategies.some(e=>e.type===n.type&&e.strategyType===n.strategyType)||v.customStrategies.push(n)}m({type:D,strategyType:"dashboard",name:"Maintenance Supporter",descr
Line truncated
|
||||
`;let n=this.querySelector("#group-by");n?.addEventListener("change",()=>{let o={...this._config,group_by:n.value};this._config=o,this.dispatchEvent(new CustomEvent("config-changed",{detail:{config:o},bubbles:!0,composed:!0}))})}},E="maintenance-supporter-section",ae=`ll-strategy-section-${E}`,b=class extends HTMLElement{static async generate(r,e){let s={type:"custom:maintenance-supporter-card",show_header:!1};r?.filter_status?.length&&(s.filter_status=r.filter_status),r?.max_items&&(s.max_items=r.max_items),r?.filter_due_min_days!==void 0&&(s.filter_due_min_days=r.filter_due_min_days),r?.filter_due_max_days!==void 0&&(s.filter_due_max_days=r.filter_due_max_days);let n=r?.filter_objects;if(r?.area_id&&!n)try{n=((await e.connection.sendMessagePromise({type:"maintenance_supporter/objects"})).objects||[]).filter(a=>a.object.area_id===r.area_id).map(a=>a.object.name)}catch{}n&&n.length>0&&(s.filter_objects=n);let o=[];return r?.title&&o.push({type:"heading",heading:r.title,heading_style:"title"}),o.push(s),{type:"grid",cards:o}}},U="2.3.6",ie="[maintenance-supporter]";function D(t,r){try{return customElements.get(t)?"skipped":(customElements.define(t,r),"ok")}catch(e){return`ERROR: ${String(e)}`}}var K={editor:D(B,T),section:D(ae,b)};console.log(`${ie} strategy bundle v${U} loaded \u2014 registrations:`,K,"\u2014 run maintenanceSupporterDiagnose() in console for full state");window.maintenanceSupporterDiagnose=async()=>{let t=W,r=[];try{let e=document.querySelector("home-assistant");e?.hass&&(r=(await e.hass.connection.sendMessagePromise({type:"lovelace/resources"})).resources||[])}catch(e){r=[{url:`<error: ${String(e)}>`}]}return{version:U,el_registered:!!customElements.get(t),el_class_excerpt:customElements.get(t)?.toString().slice(0,100)||null,customStrategies_dashboard:window.customStrategies?.filter(e=>e.strategyType==="dashboard").map(e=>e.type)||[],scriptTagsInPage:Array.from(document.querySelectorAll("script[type=module]")).map(e=>e.src).filter(e=>/maint|strateg/i.test(e)),lovelaceResources_matching:r.filter(e=>/maint|strateg/i.test(e.url||"")).map(e=>e.url),registrations:K}};var w=class extends HTMLElement{static async generate(r,e){return await import("./chunks/vacation-section-card-R3FY4AUU.js"),{type:"grid",cards:[{type:"custom:maintenance-vacation-section-card",title:r?.title}]}}},v=class extends HTMLElement{static async generate(r,e){return await import("./chunks/budget-section-card-FYYZR3LV.js"),{type:"grid",cards:[{type:"custom:maintenance-budget-section-card",title:r?.title}]}}},S=class extends HTMLElement{static async generate(r,e){return await import("./chunks/groups-section-card-DLDUVDMS.js"),{type:"grid",cards:[{type:"custom:maintenance-groups-section-card",title:r?.title}]}}},G="ll-strategy-section-maintenance-supporter-vacation",P="ll-strategy-section-maintenance-supporter-budget",N="ll-strategy-section-maintenance-supporter-groups";customElements.get(G)||customElements.define(G,w);customElements.get(P)||customElements.define(P,v);customElements.get(N)||customElements.define(N,S);var pe={[E]:b,"maintenance-supporter-vacation":w,"maintenance-supporter-budget":v,"maintenance-supporter-groups":S},f=null;function oe(){return f||(f=import("./chunks/dialog-mount-BY7EKQPS.js").catch(t=>{throw f=null,t})),f}var H="_msSupporterLlCustomBound";function m(t){history.pushState(null,"",t),window.dispatchEvent(new CustomEvent("location-changed"))}function ce(){let t=window;t[H]||(t[H]=!0,document.addEventListener("ll-custom",r=>{let e=r.detail;if(!e||typeof e!="object")return;let s=e.ll_custom,n=s&&typeof s=="object"?s:e;if(!n||typeof n.type!="string"||!n.type.startsWith("maintenance-supporter:"))return;let o=n.type.slice(22);if(o==="deep-link"&&typeof n.path=="string"){m(n.path);return}(async()=>{let i;try{i=await oe()}catch{m("/maintenance-supporter");return}if(o==="add-object"){if(i.openCreateObjectDialog())return;m("/maintenance-supporter?ms_action=add_object");return}if(o==="open-task"&&typeof n.entry_id=="string"&&typeof n.task_id=="string"){if(i.openTaskQuickActions(n.entry_id,n.task_id)||i.openEditTaskDialog(n.entry_id,n.task_id))return;m(`/maintenance-supporter?entry_id=${encodeURIComponent(n.entry_id)}&task_id=${encodeURIComponent(n.task_id)}`);return}if(o==="open-object"&&typeof n.entry_id=="string"){if(i.openObjectQuickActions(n.entry_id))return;m(`/maintenance-supporter?entry_id=${encodeURIComponent(n.entry_id)}`);return}if(o==="edit-history"&&typeof n.entry_id=="string"&&typeof n.task_id=="string"&&typeof n.original_timestamp=="string"){let d=document.querySelector("home-assistant")?.hass;if(!d)return;try{let u=await O(d,n.entry_id,n.task_id,n.original_timestamp);if(!u)return;i.openHistoryEditDialog(u)}catch{m("/maintenance-supporter")}}})()}))}ce();var C=window;C.customStrategies=C.customStrategies||[];function g(t){C.customStrategies.some(e=>e.type===t.type&&e.strategyType===t.strategyType)||C.customStrategies.push(t)}g({type:V,strategyType:"dashboard",name:"Maintenance Supporter",d
Line truncated
|
||||
Reference in new issue
Block a user