facebook post analysis page
This commit is contained in:
parent
2b150427f2
commit
76ac53959f
@ -13,6 +13,7 @@ import { RouterModule, Routes } from '@angular/router';
|
|||||||
import { SentimentAnalysisComponent } from './demo-models-page/sentiment-analysis/sentiment-analysis.component';
|
import { SentimentAnalysisComponent } from './demo-models-page/sentiment-analysis/sentiment-analysis.component';
|
||||||
import { IronyAnalysisComponent } from './demo-models-page/irony-analysis/irony-analysis.component';
|
import { IronyAnalysisComponent } from './demo-models-page/irony-analysis/irony-analysis.component';
|
||||||
import { AdvertiseAnalysisComponent } from './demo-models-page/advertise-analysis/advertise-analysis.component';
|
import { AdvertiseAnalysisComponent } from './demo-models-page/advertise-analysis/advertise-analysis.component';
|
||||||
|
import { FacebookAnalysisComponent } from './demo-models-page/facebook-analysis/facebook-analysis.component';
|
||||||
|
|
||||||
const routes: Routes = [
|
const routes: Routes = [
|
||||||
{ path: '', component: HomePageComponent },
|
{ path: '', component: HomePageComponent },
|
||||||
@ -22,6 +23,7 @@ const routes: Routes = [
|
|||||||
{ path: 'errors', component: ErrorsCorrectionPageComponent },
|
{ path: 'errors', component: ErrorsCorrectionPageComponent },
|
||||||
{ path: 'irony', component: IronyAnalysisComponent },
|
{ path: 'irony', component: IronyAnalysisComponent },
|
||||||
{ path: 'advertise', component: AdvertiseAnalysisComponent},
|
{ path: 'advertise', component: AdvertiseAnalysisComponent},
|
||||||
|
{ path: 'post-analysis', component: FacebookAnalysisComponent},
|
||||||
{
|
{
|
||||||
path: 'main-view', component: MainViewComponent, children: [
|
path: 'main-view', component: MainViewComponent, children: [
|
||||||
{ path: '', component: DashboardComponent },
|
{ path: '', component: DashboardComponent },
|
||||||
|
@ -27,6 +27,7 @@ import { ErrorsCorrectionPageComponent } from './demo-models-page/errors-correct
|
|||||||
import {MatProgressSpinnerModule} from '@angular/material/progress-spinner';
|
import {MatProgressSpinnerModule} from '@angular/material/progress-spinner';
|
||||||
import { IronyAnalysisComponent } from './demo-models-page/irony-analysis/irony-analysis.component';
|
import { IronyAnalysisComponent } from './demo-models-page/irony-analysis/irony-analysis.component';
|
||||||
import { AdvertiseAnalysisComponent } from './demo-models-page/advertise-analysis/advertise-analysis.component';
|
import { AdvertiseAnalysisComponent } from './demo-models-page/advertise-analysis/advertise-analysis.component';
|
||||||
|
import { FacebookAnalysisComponent } from './demo-models-page/facebook-analysis/facebook-analysis.component';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [
|
declarations: [
|
||||||
@ -45,7 +46,8 @@ import { AdvertiseAnalysisComponent } from './demo-models-page/advertise-analysi
|
|||||||
SentimentAnalysisComponent,
|
SentimentAnalysisComponent,
|
||||||
ErrorsCorrectionPageComponent,
|
ErrorsCorrectionPageComponent,
|
||||||
IronyAnalysisComponent,
|
IronyAnalysisComponent,
|
||||||
AdvertiseAnalysisComponent
|
AdvertiseAnalysisComponent,
|
||||||
|
FacebookAnalysisComponent
|
||||||
],
|
],
|
||||||
imports: [
|
imports: [
|
||||||
BrowserModule,
|
BrowserModule,
|
||||||
|
@ -0,0 +1,52 @@
|
|||||||
|
<div class="facebook-analysis-container">
|
||||||
|
<div class="title-container">
|
||||||
|
<div class="title">ANALIZA POSTA Z FACEBOOKA</div>
|
||||||
|
<button (click)="goToMainPage()" class="button-primary main-page-button">strona główna</button>
|
||||||
|
</div>
|
||||||
|
<div class="text">cos tu sie wpisze</div>
|
||||||
|
<div class="form-container">
|
||||||
|
<div [formGroup]="linkForm">
|
||||||
|
<div class="exe-input">
|
||||||
|
<input formControlName="link">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="button-container">
|
||||||
|
<button [disabled]="!linkForm.valid" (click)="getComments()" class="button-primary">Analizuj
|
||||||
|
komentarze</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="results-table" *ngIf="analysisStart">
|
||||||
|
<ng-container *ngIf="analysisLoading; else loading">
|
||||||
|
<div class="info-container">
|
||||||
|
<div class="post-title">Treść posta</div>
|
||||||
|
<div class="post">
|
||||||
|
{{post}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="analysis-results">
|
||||||
|
<div>
|
||||||
|
<div class="post-title">Komentarze</div>
|
||||||
|
<div *ngFor="let res of results">
|
||||||
|
<div class="result-row">
|
||||||
|
<div class="sentence">{{res.sentence}}</div>
|
||||||
|
<div [ngSwitch]="res.label">
|
||||||
|
<div class="label-0" *ngSwitchCase="0">Negatywny</div>
|
||||||
|
<div class="label-1" *ngSwitchCase="1">Pozytywny</div>
|
||||||
|
<div class="label-2" *ngSwitchCase="2">Neutralny</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="chart">
|
||||||
|
<canvas baseChart width="300" height="300" [data]="barChartData" [options]="barChartOptions"
|
||||||
|
[plugins]="barChartPlugins" [legend]="barChartLegend" [type]="'bar'">
|
||||||
|
</canvas>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ng-container>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<ng-template #loading>
|
||||||
|
<div class="spinner"><mat-spinner></mat-spinner></div>
|
||||||
|
</ng-template>
|
@ -0,0 +1,98 @@
|
|||||||
|
.facebook-analysis-container {
|
||||||
|
padding: 30px 200px;
|
||||||
|
background: rgb(0, 0, 0);
|
||||||
|
background: linear-gradient(35deg, rgba(0, 0, 0, 1) 0%, rgb(15, 32, 116) 50%, rgba(0, 0, 0, 1) 100%) !important;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
min-height: calc(100% - 60px);
|
||||||
|
height: fit-content
|
||||||
|
}
|
||||||
|
|
||||||
|
.title-container {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
|
||||||
|
.main-page-button {
|
||||||
|
height: 40px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
font-size: 50px;
|
||||||
|
color: silver;
|
||||||
|
padding-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text {
|
||||||
|
font-size: 20px;
|
||||||
|
padding-bottom: 20px;
|
||||||
|
color: silver
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-container {
|
||||||
|
|
||||||
|
width: 600px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button-container {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
column-gap: 10px;
|
||||||
|
padding-top: 15px
|
||||||
|
}
|
||||||
|
|
||||||
|
.results-table {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
column-gap: 40px;
|
||||||
|
padding-top: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.analysis-results {
|
||||||
|
display: flex;
|
||||||
|
column-gap: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.post {
|
||||||
|
color: silver
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-container{
|
||||||
|
padding-bottom:25px
|
||||||
|
}
|
||||||
|
|
||||||
|
.post-title {
|
||||||
|
font-size: 25px;
|
||||||
|
color: white;
|
||||||
|
padding-bottom:20px
|
||||||
|
}
|
||||||
|
|
||||||
|
.label-0 {
|
||||||
|
color: rgb(255, 66, 66)
|
||||||
|
}
|
||||||
|
|
||||||
|
.label-1 {
|
||||||
|
color: rgb(84, 84, 255)
|
||||||
|
}
|
||||||
|
|
||||||
|
.label-2 {
|
||||||
|
color: rgb(196, 196, 196)
|
||||||
|
}
|
||||||
|
|
||||||
|
.result-row {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
border-bottom: 1px solid grey;
|
||||||
|
padding-top: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sentence {
|
||||||
|
font-size: 15px;
|
||||||
|
color: white
|
||||||
|
}
|
||||||
|
|
||||||
|
.spinner{
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { FacebookAnalysisComponent } from './facebook-analysis.component';
|
||||||
|
|
||||||
|
describe('FacebookAnalysisComponent', () => {
|
||||||
|
let component: FacebookAnalysisComponent;
|
||||||
|
let fixture: ComponentFixture<FacebookAnalysisComponent>;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
await TestBed.configureTestingModule({
|
||||||
|
declarations: [ FacebookAnalysisComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(FacebookAnalysisComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
@ -0,0 +1,75 @@
|
|||||||
|
import { HttpClient } from '@angular/common/http';
|
||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms';
|
||||||
|
import { Router } from '@angular/router';
|
||||||
|
import { concatMap, tap } from 'rxjs';
|
||||||
|
import { ChartConfiguration, ChartOptions, ChartType } from 'chart.js';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-facebook-analysis',
|
||||||
|
templateUrl: './facebook-analysis.component.html',
|
||||||
|
styleUrls: ['./facebook-analysis.component.scss']
|
||||||
|
})
|
||||||
|
export class FacebookAnalysisComponent implements OnInit {
|
||||||
|
|
||||||
|
|
||||||
|
comments!: string[];
|
||||||
|
results: { label: number, score: number, sentence: string }[] = []
|
||||||
|
analysisStart = false;
|
||||||
|
analysisLoading = false;
|
||||||
|
post!: string;
|
||||||
|
public barChartLegend = true;
|
||||||
|
public barChartPlugins = [];
|
||||||
|
public barChartOptions: ChartConfiguration<'bar'>['options'] = {
|
||||||
|
responsive: false,
|
||||||
|
scales: {
|
||||||
|
yAxes: {
|
||||||
|
display: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
public barChartData: ChartConfiguration<'bar'>['data'] = {
|
||||||
|
labels: ['Statystyki'],
|
||||||
|
datasets: []
|
||||||
|
};
|
||||||
|
|
||||||
|
get link(): FormControl {
|
||||||
|
return this.linkForm.controls['link'] as FormControl
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(private router: Router, private fb: FormBuilder, private http: HttpClient) { }
|
||||||
|
|
||||||
|
linkForm: FormGroup = this.fb.group({
|
||||||
|
link: ['', Validators.required]
|
||||||
|
})
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
}
|
||||||
|
|
||||||
|
goToMainPage(): void {
|
||||||
|
this.router.navigate([''])
|
||||||
|
}
|
||||||
|
|
||||||
|
getComments() {
|
||||||
|
this.analysisStart = true
|
||||||
|
this.analysisLoading = false
|
||||||
|
let link = this.link.value
|
||||||
|
this.http.post('http://127.0.0.1:5000/scrapp_comments', { link: link }).pipe(concatMap((resp: any) => {
|
||||||
|
this.post = resp.post
|
||||||
|
return this.http.post('http://127.0.0.1:5000/get_sentiment_data', { sentences: resp.comments }).pipe(tap((resp: any) => {
|
||||||
|
console.log(resp)
|
||||||
|
this.results = resp.predictions
|
||||||
|
this.barChartData.datasets = [
|
||||||
|
{ data: [resp.count_labels.negative], label: String(resp.count_labels.negative) + ' negatywny', backgroundColor: 'rgba(250, 66, 66, 1)', borderRadius: 15, },
|
||||||
|
{ data: [resp.count_labels.positive], label: String(resp.count_labels.positive) + ' pozytywny', backgroundColor: 'rgba(124, 136, 248, 1)', borderRadius: 15, },
|
||||||
|
{ data: [resp.count_labels.neutral], label: String(resp.count_labels.neutral) + ' neutralny', backgroundColor: 'rgba(211,211,211)', borderRadius: 15, }
|
||||||
|
]
|
||||||
|
}))
|
||||||
|
})).subscribe({
|
||||||
|
next: () => {
|
||||||
|
this.analysisLoading = true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,3 +1,7 @@
|
|||||||
|
<div class="jurney">
|
||||||
|
<div class="jurney-text">START YOUR JURNEY NOW</div>
|
||||||
|
<mat-icon (click)="scrollDown()">expand_more</mat-icon>
|
||||||
|
</div>
|
||||||
<div class="home-page">
|
<div class="home-page">
|
||||||
<!-- <div class="nav-bar-container">
|
<!-- <div class="nav-bar-container">
|
||||||
<div class="logo-container"><img class="logo-image" src="assets/images/logo.svg" alt=""></div>
|
<div class="logo-container"><img class="logo-image" src="assets/images/logo.svg" alt=""></div>
|
||||||
@ -79,5 +83,13 @@
|
|||||||
galley of type and scrambled it to make a type specimen book.</div>
|
galley of type and scrambled it to make a type specimen book.</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="row-2">
|
||||||
|
<div class="facebook" (click)="goToFacebook()">
|
||||||
|
<div class="title">ANALIZUJ POST FACEBOOK</div>
|
||||||
|
<div class="text">Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum
|
||||||
|
has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a
|
||||||
|
galley of type and scrambled it to make a type specimen book.</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -132,9 +132,12 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.home-page {
|
.home-page {
|
||||||
height: 100%;
|
//height: 100%;
|
||||||
// background: rgb(99,94,175);
|
// background: rgb(99,94,175);
|
||||||
// background: linear-gradient(162deg, rgba(99,94,175,1) 0%, rgba(6,6,91,1) 27%, rgba(6,79,94,1) 100%);
|
// background: linear-gradient(162deg, rgba(99,94,175,1) 0%, rgba(6,6,91,1) 27%, rgba(6,79,94,1) 100%);
|
||||||
|
background: rgb(0, 0, 0);
|
||||||
|
background: linear-gradient(35deg, rgba(0, 0, 0, 1) 0%, rgba(0, 85, 94, 1) 50%, rgba(0, 0, 0, 1) 100%);
|
||||||
|
height: fit-content
|
||||||
}
|
}
|
||||||
|
|
||||||
.main-title {
|
.main-title {
|
||||||
@ -145,7 +148,7 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
background: -webkit-linear-gradient(35deg, rgba(0,0,0,1) 0%, rgba(0,85,94,1) 50%, rgba(0,0,0,1) 100%);
|
background: -webkit-linear-gradient(35deg, rgba(0, 0, 0, 1) 0%, rgba(0, 85, 94, 1) 50%, rgba(0, 0, 0, 1) 100%);
|
||||||
-webkit-background-clip: text;
|
-webkit-background-clip: text;
|
||||||
-webkit-text-fill-color: transparent;
|
-webkit-text-fill-color: transparent;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
@ -169,7 +172,8 @@
|
|||||||
.sentiment,
|
.sentiment,
|
||||||
.irony,
|
.irony,
|
||||||
.analysis,
|
.analysis,
|
||||||
.errors {
|
.errors,
|
||||||
|
.facebook {
|
||||||
width: 30%;
|
width: 30%;
|
||||||
height: 200px;
|
height: 200px;
|
||||||
border-radius: 15px;
|
border-radius: 15px;
|
||||||
@ -181,21 +185,46 @@
|
|||||||
.sentiment {
|
.sentiment {
|
||||||
background: rgb(0, 0, 0);
|
background: rgb(0, 0, 0);
|
||||||
background: linear-gradient(35deg, rgba(0, 0, 0, 1) 0%, rgba(9, 64, 71, 1) 50%, rgba(0, 0, 0, 1) 100%);
|
background: linear-gradient(35deg, rgba(0, 0, 0, 1) 0%, rgba(9, 64, 71, 1) 50%, rgba(0, 0, 0, 1) 100%);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: linear-gradient(35deg, rgba(0, 0, 0, 1) 0%, rgb(16, 112, 125) 50%, rgba(0, 0, 0, 1) 100%);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.irony {
|
.irony {
|
||||||
background: rgb(0, 0, 0);
|
background: rgb(0, 0, 0);
|
||||||
background: linear-gradient(35deg, rgba(0, 0, 0, 1) 0%, rgba(71, 9, 65, 1) 50%, rgba(0, 0, 0, 1) 100%);
|
background: linear-gradient(35deg, rgba(0, 0, 0, 1) 0%, rgba(71, 9, 65, 1) 50%, rgba(0, 0, 0, 1) 100%);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: linear-gradient(35deg, rgba(0, 0, 0, 1) 0%, rgb(127, 16, 116) 50%, rgba(0, 0, 0, 1) 100%);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.analysis {
|
.analysis {
|
||||||
background: rgb(0, 0, 0);
|
background: rgb(0, 0, 0);
|
||||||
background: linear-gradient(35deg, rgba(0, 0, 0, 1) 0%, rgba(71, 71, 9, 1) 50%, rgba(0, 0, 0, 1) 100%);
|
background: linear-gradient(35deg, rgba(0, 0, 0, 1) 0%, rgba(71, 71, 9, 1) 50%, rgba(0, 0, 0, 1) 100%);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: linear-gradient(35deg, rgba(0, 0, 0, 1) 0%, rgb(123, 123, 16) 50%, rgba(0, 0, 0, 1) 100%);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.errors {
|
.errors {
|
||||||
background: rgb(0, 0, 0);
|
background: rgb(0, 0, 0);
|
||||||
background: linear-gradient(35deg, rgba(0, 0, 0, 1) 0%, rgba(10, 71, 9, 1) 50%, rgba(0, 0, 0, 1) 100%);
|
background: linear-gradient(35deg, rgba(0, 0, 0, 1) 0%, rgba(10, 71, 9, 1) 50%, rgba(0, 0, 0, 1) 100%);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: linear-gradient(35deg, rgba(0, 0, 0, 1) 0%, rgb(15, 106, 14) 50%, rgba(0, 0, 0, 1) 100%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.facebook {
|
||||||
|
background: rgb(0, 0, 0);
|
||||||
|
background: linear-gradient(35deg, rgba(0, 0, 0, 1) 0%, rgb(15, 32, 116) 50%, rgba(0, 0, 0, 1) 100%) !important;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: linear-gradient(35deg, rgba(0, 0, 0, 1) 0%, rgb(21, 45, 165) 50%, rgba(0, 0, 0, 1) 100%) !important;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
@ -215,3 +244,30 @@
|
|||||||
padding-right: 15px
|
padding-right: 15px
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.jurney {
|
||||||
|
height: 100%;
|
||||||
|
background: rgb(65, 65, 65);
|
||||||
|
background: radial-gradient(circle, rgba(65, 65, 65, 1) 0%, rgba(0, 0, 0, 1) 100%);
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
mat-icon{
|
||||||
|
color:rgb(125, 125, 125);
|
||||||
|
font-size:100px;
|
||||||
|
width:100px;
|
||||||
|
cursor:pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.jurney-text {
|
||||||
|
font-size: 50px;
|
||||||
|
text-align: center;
|
||||||
|
background: rgb(107,107,107);
|
||||||
|
background: radial-gradient(circle, rgba(107,107,107,1) 0%, rgba(69,69,69,1) 100%);
|
||||||
|
-webkit-background-clip: text;
|
||||||
|
-webkit-text-fill-color: transparent;
|
||||||
|
-webkit-text-stroke: 0.1px rgb(128, 128, 128);
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -35,4 +35,12 @@ export class HomePageComponent implements OnInit {
|
|||||||
this.router.navigate(['/advertise'])
|
this.router.navigate(['/advertise'])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
goToFacebook() {
|
||||||
|
this.router.navigate(['/post-analysis'])
|
||||||
|
}
|
||||||
|
|
||||||
|
scrollDown(): void{
|
||||||
|
window.scrollTo({top:document.body.clientHeight,behavior: "smooth",});
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user