mirror of
https://code.equilibrium.co.ao/ITO/doneit-web.git
synced 2026-04-18 20:47:54 +00:00
new inputs
This commit is contained in:
Generated
+10
-1
@@ -3393,6 +3393,14 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@ngx-translate/core": {
|
||||||
|
"version": "13.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@ngx-translate/core/-/core-13.0.0.tgz",
|
||||||
|
"integrity": "sha512-+tzEp8wlqEnw0Gc7jtVRAJ6RteUjXw6JJR4O65KlnxOmJrCGPI0xjV/lKRnQeU0w4i96PQs/jtpL921Wrb7PWg==",
|
||||||
|
"requires": {
|
||||||
|
"tslib": "^2.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"@nodelib/fs.scandir": {
|
"@nodelib/fs.scandir": {
|
||||||
"version": "2.1.4",
|
"version": "2.1.4",
|
||||||
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz",
|
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz",
|
||||||
@@ -19108,7 +19116,8 @@
|
|||||||
},
|
},
|
||||||
"ssri": {
|
"ssri": {
|
||||||
"version": "6.0.1",
|
"version": "6.0.1",
|
||||||
"resolved": "",
|
"resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz",
|
||||||
|
"integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"figgy-pudding": "^3.5.1"
|
"figgy-pudding": "^3.5.1"
|
||||||
|
|||||||
@@ -50,6 +50,7 @@
|
|||||||
"@ionic/storage": "^2.3.1",
|
"@ionic/storage": "^2.3.1",
|
||||||
"@logisticinfotech/ionic4-datepicker": "^1.4.4",
|
"@logisticinfotech/ionic4-datepicker": "^1.4.4",
|
||||||
"@ng-bootstrap/ng-bootstrap": "^9.1.2",
|
"@ng-bootstrap/ng-bootstrap": "^9.1.2",
|
||||||
|
"@ngx-translate/core": "^13.0.0",
|
||||||
"angular-calendar": "^0.28.22",
|
"angular-calendar": "^0.28.22",
|
||||||
"angular-tag-cloud-module": "^5.2.2",
|
"angular-tag-cloud-module": "^5.2.2",
|
||||||
"bootstrap": "^4.5.0",
|
"bootstrap": "^4.5.0",
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ export class IndexGuard implements CanActivate {
|
|||||||
public storageService:StorageService,
|
public storageService:StorageService,
|
||||||
private router:Router
|
private router:Router
|
||||||
){}
|
){}
|
||||||
canActivate(): Promise<boolean>{
|
canActivate(): Promise<boolean> {
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
/* this.storageService.get(AuthConnstants.AUTH).then(res => {
|
/* this.storageService.get(AuthConnstants.AUTH).then(res => {
|
||||||
if(res){
|
if(res){
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ export class HomePage implements OnInit {
|
|||||||
private platform: Platform) {
|
private platform: Platform) {
|
||||||
|
|
||||||
router.events.subscribe((val) => {
|
router.events.subscribe((val) => {
|
||||||
// document.querySelectorAll('ion-modal').forEach((e) => e.remove())
|
document.querySelectorAll('ion-modal').forEach((e) => e.remove())
|
||||||
});
|
});
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ import { MatDatepickerModule } from '@angular/material/datepicker';
|
|||||||
import { MatInputModule } from '@angular/material/input';
|
import { MatInputModule } from '@angular/material/input';
|
||||||
|
|
||||||
import { MatNativeDateModule } from '@angular/material/core';
|
import { MatNativeDateModule } from '@angular/material/core';
|
||||||
import { MatMomentDateModule, MomentDateAdapter } from "@angular/material-moment-adapter";
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
NgxMatDatetimePickerModule,
|
NgxMatDatetimePickerModule,
|
||||||
@@ -26,6 +25,13 @@ import { MatButtonModule } from '@angular/material/button';
|
|||||||
import { MatSelectModule } from '@angular/material/select';
|
import { MatSelectModule } from '@angular/material/select';
|
||||||
import { NgxMatMomentModule } from '@angular-material-components/moment-adapter';
|
import { NgxMatMomentModule } from '@angular-material-components/moment-adapter';
|
||||||
|
|
||||||
|
import {
|
||||||
|
MAT_MOMENT_DATE_FORMATS,
|
||||||
|
MomentDateAdapter,
|
||||||
|
MAT_MOMENT_DATE_ADAPTER_OPTIONS
|
||||||
|
} from '@angular/material-moment-adapter';
|
||||||
|
import {DateAdapter, MAT_DATE_FORMATS, MAT_DATE_LOCALE} from '@angular/material/core';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [
|
imports: [
|
||||||
CommonModule,
|
CommonModule,
|
||||||
@@ -52,6 +58,9 @@ import { NgxMatMomentModule } from '@angular-material-components/moment-adapter'
|
|||||||
ReactiveFormsModule
|
ReactiveFormsModule
|
||||||
],
|
],
|
||||||
declarations: [NewEventPage],
|
declarations: [NewEventPage],
|
||||||
|
providers: [
|
||||||
|
{ provide: MAT_DATE_LOCALE, useValue: 'pt-br' },
|
||||||
|
],
|
||||||
exports: [NewEventPage]
|
exports: [NewEventPage]
|
||||||
})
|
})
|
||||||
export class NewEventPageModule {}
|
export class NewEventPageModule {}
|
||||||
|
|||||||
@@ -15,15 +15,6 @@
|
|||||||
|
|
||||||
<!-- THIS -->
|
<!-- THIS -->
|
||||||
|
|
||||||
<!-- <mat-form-field>
|
|
||||||
<input matInput [ngxMatDatetimePicker]="picker" placeholder="Choose a date" [formControl]="dateControl"
|
|
||||||
[min]="minDate" [max]="maxDate" [disabled]="disabled">
|
|
||||||
<mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
|
|
||||||
<ngx-mat-datetime-picker #picker [showSpinners]="showSpinners" [showSeconds]="showSeconds"
|
|
||||||
[stepHour]="stepHour" [stepMinute]="stepMinute" [stepSecond]="stepSecond" [touchUi]="touchUi"
|
|
||||||
[color]="color" [enableMeridian]="enableMeridian">
|
|
||||||
</ngx-mat-datetime-picker>
|
|
||||||
</mat-form-field> -->
|
|
||||||
|
|
||||||
<!-- <form class="form-inline">
|
<!-- <form class="form-inline">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
@@ -65,14 +56,18 @@
|
|||||||
<ion-icon slot="start" src="assets/images/icons-calendar.svg"></ion-icon>
|
<ion-icon slot="start" src="assets/images/icons-calendar.svg"></ion-icon>
|
||||||
</div>
|
</div>
|
||||||
<div class="ion-input-class flex-grow-1">
|
<div class="ion-input-class flex-grow-1">
|
||||||
<ion-select placeholder="Selecione agenda"
|
|
||||||
selectedText="{{postEvent.CalendarName}}"
|
<mat-form-field class="width-100" [(ngModel)]="postEvent.CalendarName" placeholder="Selecione agenda" required>
|
||||||
[(ngModel)]="postEvent.CalendarName"
|
<mat-select>
|
||||||
interface="action-sheet" Cancel-text="Cancelar"
|
<mat-option value="Oficial">
|
||||||
required>
|
Oficial
|
||||||
<ion-select-option value="Oficial">Oficial</ion-select-option>
|
</mat-option>
|
||||||
<ion-select-option value="Pessoal">Pessoal</ion-select-option>
|
<mat-option value="Pessoal">
|
||||||
</ion-select>
|
Pessoal
|
||||||
|
</mat-option>
|
||||||
|
</mat-select>
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -83,15 +78,24 @@
|
|||||||
<ion-icon slot="start" src="assets/images/icons-calendar.svg"></ion-icon>
|
<ion-icon slot="start" src="assets/images/icons-calendar.svg"></ion-icon>
|
||||||
</div>
|
</div>
|
||||||
<div class="ion-input-class flex-grow-1">
|
<div class="ion-input-class flex-grow-1">
|
||||||
<ion-select placeholder="Selecione tipo"
|
|
||||||
[(ngModel)]="postEvent.Categories[0]"
|
<mat-form-field class="width-100" [(ngModel)]="postEvent.Categories[0]" placeholder="Selecione tipo" required>
|
||||||
interface="action-sheet"
|
<mat-select>
|
||||||
Cancel-text="Cancelar" required>
|
<mat-option value="Reunião">
|
||||||
<ion-select-option value="Reunião">Reunião</ion-select-option>
|
Reunião
|
||||||
<ion-select-option value="Viagem">Viagem</ion-select-option>
|
</mat-option>
|
||||||
<ion-select-option value="Conferência">Conferência</ion-select-option>
|
<mat-option value="Viagem">
|
||||||
<ion-select-option value="Encontro">Encontro</ion-select-option>
|
Viagem
|
||||||
</ion-select>
|
</mat-option>
|
||||||
|
<mat-option value="Conferência">
|
||||||
|
Conferência
|
||||||
|
</mat-option>
|
||||||
|
<mat-option value="Encontro">
|
||||||
|
Encontro
|
||||||
|
</mat-option>
|
||||||
|
</mat-select>
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -101,31 +105,18 @@
|
|||||||
<div class="ion-icon-class">
|
<div class="ion-icon-class">
|
||||||
<ion-icon slot="start" src="assets/images/icons-calendar.svg"></ion-icon>
|
<ion-icon slot="start" src="assets/images/icons-calendar.svg"></ion-icon>
|
||||||
</div>
|
</div>
|
||||||
<div class="ion-input-class flex-grow-1">
|
<div (click)="openInicio()" class="ion-input-class flex-grow-1">
|
||||||
<ion-datetime
|
<mat-form-field class="date-hour-picker width-100">
|
||||||
class=""
|
<input matInput [ngxMatDatetimePicker]="picker" placeholder="Choose a date" [formControl]="dateControl"
|
||||||
placeholder="Início"
|
|
||||||
[(ngModel)]="postEvent.StartDate"
|
[(ngModel)]="postEvent.StartDate"
|
||||||
displayFormat="D MMM YYYY H:mm"
|
[min]="minDate" [max]="maxDate" [disabled]="disabled">
|
||||||
minuteValues="0,15,30,45"
|
<mat-datepicker-toggle id="new-inicio" #inicio matSuffix [for]="picker"></mat-datepicker-toggle>
|
||||||
monthShortNames="Jan, Fev, Mar, Abr, Mai, Jun, Jul, Aug, Sep, Out, Nov, Dez"
|
<ngx-mat-datetime-picker #picker [showSpinners]="showSpinners" [showSeconds]="showSeconds"
|
||||||
min="2018"
|
[stepHour]="stepHour" [stepMinute]="stepMinute" [stepSecond]="stepSecond" [touchUi]=false
|
||||||
max="2022"
|
[color]="'#0000'" [enableMeridian]="enableMeridian">
|
||||||
>
|
</ngx-mat-datetime-picker>
|
||||||
</ion-datetime>
|
</mat-form-field>
|
||||||
|
|
||||||
<!-- <input
|
|
||||||
class="d-none width-100"
|
|
||||||
placeholder="Início"
|
|
||||||
[matDatepicker]="picker"
|
|
||||||
(focus)="picker.open()"
|
|
||||||
(click)="picker.open()"
|
|
||||||
[(ngModel)]="postEvent.StartDate"
|
|
||||||
>
|
|
||||||
<mat-datepicker #picker></mat-datepicker> -->
|
|
||||||
|
|
||||||
|
|
||||||
<!-- <ion-input placeholder="Data início" [(ngModel)]="postData.StartDate"></ion-input> -->
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -135,18 +126,18 @@
|
|||||||
<div class="ion-icon-class">
|
<div class="ion-icon-class">
|
||||||
<ion-icon slot="start" src="assets/images/icons-calendar.svg"></ion-icon>
|
<ion-icon slot="start" src="assets/images/icons-calendar.svg"></ion-icon>
|
||||||
</div>
|
</div>
|
||||||
<div class="ion-input-class flex-grow-1">
|
<div (click)="openFim()" class="ion-input-class flex-grow-1">
|
||||||
<ion-datetime
|
<mat-form-field class="date-hour-picker width-100">
|
||||||
placeholder="Fim"
|
<input matInput [ngxMatDatetimePicker]="fim" placeholder="Choose a date" [formControl]="dateControl"
|
||||||
[(ngModel)]="postEvent.EndDate"
|
[(ngModel)]="postEvent.EndDate"
|
||||||
displayFormat="D MMM YYYY H:mm"
|
[min]="minDate" [max]="maxDate" [disabled]="disabled">
|
||||||
minuteValues="0,15,30,45"
|
<mat-datepicker-toggle id="new-fim" #inicio matSuffix [for]="fim"></mat-datepicker-toggle>
|
||||||
monthShortNames="Jan, Fev, Mar, Abr, Mai, Jun, Jul, Aug, Sep, Out, Nov, Dez"
|
<ngx-mat-datetime-picker [showSpinners]=false #fim [showSpinners]="showSpinners" [showSeconds]="showSeconds"
|
||||||
min="2018"
|
[stepHour]="stepHour" [stepMinute]="stepMinute" [stepSecond]="stepSecond" [touchUi]=false appearance = "standard"
|
||||||
max="2022"
|
[color]="'#0000'" [enableMeridian]="enableMeridian">
|
||||||
>
|
</ngx-mat-datetime-picker>
|
||||||
</ion-datetime>
|
</mat-form-field>
|
||||||
<!-- <ion-input placeholder="Data fim" [(ngModel)]="postData.EndDate"></ion-input> -->
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -157,10 +148,18 @@
|
|||||||
<ion-icon slot="start" src="assets/images/icons-refresh.svg"></ion-icon>
|
<ion-icon slot="start" src="assets/images/icons-refresh.svg"></ion-icon>
|
||||||
</div>
|
</div>
|
||||||
<div class="ion-input-class flex-grow-1">
|
<div class="ion-input-class flex-grow-1">
|
||||||
<ion-select placeholder="Selecione repetição" value="false" interface="action-sheet" Cancel-text="Cancelar" required>
|
|
||||||
<ion-select-option value="false">Não se repete</ion-select-option>
|
<mat-form-field class="width-100" placeholder="Selecione repetição" value="false" interface="action-sheet" Cancel-text="Cancelar" required>
|
||||||
<ion-select-option value="true">Repete</ion-select-option>
|
<mat-select>
|
||||||
</ion-select>
|
<mat-option value="false">
|
||||||
|
Não se repete
|
||||||
|
</mat-option>
|
||||||
|
<mat-option value="true">
|
||||||
|
Repete
|
||||||
|
</mat-option>
|
||||||
|
</mat-select>
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
ion-content{
|
ion-content{
|
||||||
--background:transparent;
|
--background:transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
.header-toolbar{
|
.header-toolbar{
|
||||||
--background:transparent;
|
--background:transparent;
|
||||||
--opacity: 1;
|
--opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.main-header{
|
.main-header{
|
||||||
width: 100%; /* 400px */
|
width: 100%; /* 400px */
|
||||||
height: 100%;
|
height: 100%;
|
||||||
@@ -211,3 +213,4 @@ ion-content{
|
|||||||
display: block !important;
|
display: block !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,27 +9,22 @@ import { removeDuplicate } from 'src/plugin/removeDuplicate.js'
|
|||||||
import { SearchPage } from 'src/app/pages/search/search.page';
|
import { SearchPage } from 'src/app/pages/search/search.page';
|
||||||
import { SearchDocument } from "src/app/models/search-document";
|
import { SearchDocument } from "src/app/models/search-document";
|
||||||
import { EventAttachment } from 'src/app/models/attachment.model';
|
import { EventAttachment } from 'src/app/models/attachment.model';
|
||||||
import { BadRequestPage } from '../../popover/bad-request/bad-request.page';
|
|
||||||
import { SuccessMessagePage} from '../../popover/success-message/success-message.page';
|
|
||||||
import { ToastService } from 'src/app/services/toast.service';
|
import { ToastService } from 'src/app/services/toast.service';
|
||||||
import { User } from 'src/app/models/user.model';
|
import { User } from 'src/app/models/user.model';
|
||||||
import { AuthService } from 'src/app/services/auth.service';
|
import { AuthService } from 'src/app/services/auth.service';
|
||||||
|
|
||||||
|
import {DateAdapter} from '@angular/material/core';
|
||||||
import {MomentDateAdapter, MAT_MOMENT_DATE_ADAPTER_OPTIONS} from '@angular/material-moment-adapter';
|
|
||||||
import {DateAdapter, MAT_DATE_FORMATS, MAT_DATE_LOCALE} from '@angular/material/core';
|
|
||||||
import * as _moment from 'moment';
|
import * as _moment from 'moment';
|
||||||
import * as _rollupMoment from 'moment';
|
import * as _rollupMoment from 'moment';
|
||||||
import {FormControl} from '@angular/forms';
|
import {FormControl} from '@angular/forms';
|
||||||
import { NgxMatDateFormats } from '@angular-material-components/datetime-picker';
|
import { NgxMatDateFormats } from '@angular-material-components/datetime-picker';
|
||||||
import { ThemePalette } from '@angular/material/core';
|
import { ThemePalette } from '@angular/material/core';
|
||||||
|
|
||||||
|
|
||||||
import { HttpClient } from '@angular/common/http';
|
import { HttpClient } from '@angular/common/http';
|
||||||
import { NgZone, ViewChild } from '@angular/core';
|
import { NgZone, ViewChild } from '@angular/core';
|
||||||
import { FormGroup, Validators } from '@angular/forms';
|
import { FormGroup, Validators } from '@angular/forms';
|
||||||
import { NgxMatDatetimePickerModule, NgxMatTimepickerModule, NGX_MAT_DATE_FORMATS, NgxMatDateAdapter } from '@angular-material-components/datetime-picker';
|
import { NGX_MAT_DATE_FORMATS } from '@angular-material-components/datetime-picker';
|
||||||
|
|
||||||
|
|
||||||
const moment = _rollupMoment || _moment;
|
const moment = _rollupMoment || _moment;
|
||||||
|
|
||||||
@@ -50,18 +45,7 @@ const CUSTOM_DATE_FORMATS: NgxMatDateFormats = {
|
|||||||
templateUrl: './new-event.page.html',
|
templateUrl: './new-event.page.html',
|
||||||
styleUrls: ['./new-event.page.scss'],
|
styleUrls: ['./new-event.page.scss'],
|
||||||
providers: [
|
providers: [
|
||||||
// `MomentDateAdapter` can be automatically provided by importing `MomentDateModule` in your
|
|
||||||
// application's root module. We provide it at the component level here, due to limitations of
|
|
||||||
// our example generation script.
|
|
||||||
// {
|
|
||||||
// provide: DateAdapter,
|
|
||||||
// useClass: MomentDateAdapter,
|
|
||||||
// deps: [MAT_DATE_LOCALE, MAT_MOMENT_DATE_ADAPTER_OPTIONS]
|
|
||||||
// },
|
|
||||||
|
|
||||||
{ provide: NGX_MAT_DATE_FORMATS, useValue: CUSTOM_DATE_FORMATS },
|
{ provide: NGX_MAT_DATE_FORMATS, useValue: CUSTOM_DATE_FORMATS },
|
||||||
// { provide: MAT_DATE_LOCALE, useValue: 'pt-br' },
|
|
||||||
// { provide: LOCALE_ID, useValue: "en-GB" }
|
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -81,8 +65,8 @@ export class NewEventPage implements OnInit {
|
|||||||
public minDate: any;
|
public minDate: any;
|
||||||
public maxDate: any;
|
public maxDate: any;
|
||||||
public stepHour = 1;
|
public stepHour = 1;
|
||||||
public stepMinute = 1;
|
public stepMinute = 5;
|
||||||
public stepSecond = 1;
|
public stepSecond = 5;
|
||||||
public color: ThemePalette = 'primary';
|
public color: ThemePalette = 'primary';
|
||||||
|
|
||||||
|
|
||||||
@@ -108,6 +92,8 @@ export class NewEventPage implements OnInit {
|
|||||||
|
|
||||||
loggeduser: User;
|
loggeduser: User;
|
||||||
@ViewChild('picker') picker: any;
|
@ViewChild('picker') picker: any;
|
||||||
|
@ViewChild('fim') fim: any;
|
||||||
|
// @ViewChild('inicio') inicio: any;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private modalController: ModalController,
|
private modalController: ModalController,
|
||||||
@@ -118,7 +104,8 @@ export class NewEventPage implements OnInit {
|
|||||||
private userService: AuthService,
|
private userService: AuthService,
|
||||||
private http: HttpClient,
|
private http: HttpClient,
|
||||||
private zone: NgZone,
|
private zone: NgZone,
|
||||||
private dateAdapter: DateAdapter<any>
|
private dateAdapter: DateAdapter<any>,
|
||||||
|
// private translate: TranslateService
|
||||||
) {
|
) {
|
||||||
this.dateAdapter.setLocale('pt');
|
this.dateAdapter.setLocale('pt');
|
||||||
this.loggeduser = userService.ValidatedUser;
|
this.loggeduser = userService.ValidatedUser;
|
||||||
@@ -248,6 +235,21 @@ export class NewEventPage implements OnInit {
|
|||||||
this.picker.cancel();
|
this.picker.cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
openInicio() {
|
||||||
|
let input: any = document.querySelector('#new-inicio')
|
||||||
|
if(input) {
|
||||||
|
console.log(input)
|
||||||
|
input.click()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
openFim() {
|
||||||
|
let input: any = document.querySelector('#new-fim')
|
||||||
|
if(input) {
|
||||||
|
input.click()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private _setMinDate() {
|
private _setMinDate() {
|
||||||
const now = new Date();
|
const now = new Date();
|
||||||
this.minDate = new Date();
|
this.minDate = new Date();
|
||||||
|
|||||||
Reference in New Issue
Block a user