0.1.2.1
This commit is contained in:
30
o.gitlab-ci.yml
Normal file
30
o.gitlab-ci.yml
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
# Using the node alpine image to build the React app
|
||||||
|
image: node:alpine
|
||||||
|
|
||||||
|
# Announce the URL as per CRA docs
|
||||||
|
# https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/template/README.md#advanced-configuration
|
||||||
|
|
||||||
|
# Cache node modules - speeds up future builds
|
||||||
|
#cache:
|
||||||
|
# paths:
|
||||||
|
# - node_modules
|
||||||
|
|
||||||
|
# Name the stages involved in the pipeline
|
||||||
|
stages:
|
||||||
|
- deploy
|
||||||
|
|
||||||
|
# Job name for gitlab to recognise this results in assets for Gitlab Pages
|
||||||
|
# https://docs.gitlab.com/ee/user/project/pages/introduction.html#gitlab-pages-requirements
|
||||||
|
pages:
|
||||||
|
stage: deploy
|
||||||
|
script:
|
||||||
|
- npm install # Install all dependencies
|
||||||
|
- npm run build --prod # Build for prod
|
||||||
|
- cp public/index.html public/404.html # Not necessary, but helps with https://medium.com/@pshrmn/demystifying-single-page-applications-3068d0555d46
|
||||||
|
- mv public _public # CRA and gitlab pages both use the public folder. Only do this in a build pipeline.
|
||||||
|
- mv build public # Move build files to public dir for Gitlab Pages
|
||||||
|
artifacts:
|
||||||
|
paths:
|
||||||
|
- public # The built files for Gitlab Pages to serve
|
||||||
|
only:
|
||||||
|
- master # Only run on master branch
|
||||||
78
package-lock.json
generated
78
package-lock.json
generated
@@ -2759,11 +2759,13 @@
|
|||||||
},
|
},
|
||||||
"balanced-match": {
|
"balanced-match": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"bundled": true
|
"bundled": true,
|
||||||
|
"optional": true
|
||||||
},
|
},
|
||||||
"brace-expansion": {
|
"brace-expansion": {
|
||||||
"version": "1.1.11",
|
"version": "1.1.11",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
|
"optional": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"balanced-match": "^1.0.0",
|
"balanced-match": "^1.0.0",
|
||||||
"concat-map": "0.0.1"
|
"concat-map": "0.0.1"
|
||||||
@@ -2776,15 +2778,18 @@
|
|||||||
},
|
},
|
||||||
"code-point-at": {
|
"code-point-at": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"bundled": true
|
"bundled": true,
|
||||||
|
"optional": true
|
||||||
},
|
},
|
||||||
"concat-map": {
|
"concat-map": {
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"bundled": true
|
"bundled": true,
|
||||||
|
"optional": true
|
||||||
},
|
},
|
||||||
"console-control-strings": {
|
"console-control-strings": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"bundled": true
|
"bundled": true,
|
||||||
|
"optional": true
|
||||||
},
|
},
|
||||||
"core-util-is": {
|
"core-util-is": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
@@ -2887,7 +2892,8 @@
|
|||||||
},
|
},
|
||||||
"inherits": {
|
"inherits": {
|
||||||
"version": "2.0.3",
|
"version": "2.0.3",
|
||||||
"bundled": true
|
"bundled": true,
|
||||||
|
"optional": true
|
||||||
},
|
},
|
||||||
"ini": {
|
"ini": {
|
||||||
"version": "1.3.5",
|
"version": "1.3.5",
|
||||||
@@ -2897,6 +2903,7 @@
|
|||||||
"is-fullwidth-code-point": {
|
"is-fullwidth-code-point": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
|
"optional": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"number-is-nan": "^1.0.0"
|
"number-is-nan": "^1.0.0"
|
||||||
}
|
}
|
||||||
@@ -2909,17 +2916,20 @@
|
|||||||
"minimatch": {
|
"minimatch": {
|
||||||
"version": "3.0.4",
|
"version": "3.0.4",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
|
"optional": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"brace-expansion": "^1.1.7"
|
"brace-expansion": "^1.1.7"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"minimist": {
|
"minimist": {
|
||||||
"version": "0.0.8",
|
"version": "0.0.8",
|
||||||
"bundled": true
|
"bundled": true,
|
||||||
|
"optional": true
|
||||||
},
|
},
|
||||||
"minipass": {
|
"minipass": {
|
||||||
"version": "2.3.5",
|
"version": "2.3.5",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
|
"optional": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"safe-buffer": "^5.1.2",
|
"safe-buffer": "^5.1.2",
|
||||||
"yallist": "^3.0.0"
|
"yallist": "^3.0.0"
|
||||||
@@ -2936,6 +2946,7 @@
|
|||||||
"mkdirp": {
|
"mkdirp": {
|
||||||
"version": "0.5.1",
|
"version": "0.5.1",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
|
"optional": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"minimist": "0.0.8"
|
"minimist": "0.0.8"
|
||||||
}
|
}
|
||||||
@@ -3008,7 +3019,8 @@
|
|||||||
},
|
},
|
||||||
"number-is-nan": {
|
"number-is-nan": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"bundled": true
|
"bundled": true,
|
||||||
|
"optional": true
|
||||||
},
|
},
|
||||||
"object-assign": {
|
"object-assign": {
|
||||||
"version": "4.1.1",
|
"version": "4.1.1",
|
||||||
@@ -3018,6 +3030,7 @@
|
|||||||
"once": {
|
"once": {
|
||||||
"version": "1.4.0",
|
"version": "1.4.0",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
|
"optional": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"wrappy": "1"
|
"wrappy": "1"
|
||||||
}
|
}
|
||||||
@@ -3123,6 +3136,7 @@
|
|||||||
"string-width": {
|
"string-width": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
|
"optional": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"code-point-at": "^1.0.0",
|
"code-point-at": "^1.0.0",
|
||||||
"is-fullwidth-code-point": "^1.0.0",
|
"is-fullwidth-code-point": "^1.0.0",
|
||||||
@@ -3279,6 +3293,11 @@
|
|||||||
"wrap-ansi": "^2.0.0"
|
"wrap-ansi": "^2.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"clone": {
|
||||||
|
"version": "2.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz",
|
||||||
|
"integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18="
|
||||||
|
},
|
||||||
"clone-deep": {
|
"clone-deep": {
|
||||||
"version": "0.2.4",
|
"version": "0.2.4",
|
||||||
"resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-0.2.4.tgz",
|
"resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-0.2.4.tgz",
|
||||||
@@ -5899,6 +5918,12 @@
|
|||||||
"resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz",
|
||||||
"integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg=="
|
"integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg=="
|
||||||
},
|
},
|
||||||
|
"image-size": {
|
||||||
|
"version": "0.5.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz",
|
||||||
|
"integrity": "sha1-Cd/Uq50g4p6xw+gLiZA3jfnjy5w=",
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
"immer": {
|
"immer": {
|
||||||
"version": "1.10.0",
|
"version": "1.10.0",
|
||||||
"resolved": "https://registry.npmjs.org/immer/-/immer-1.10.0.tgz",
|
"resolved": "https://registry.npmjs.org/immer/-/immer-1.10.0.tgz",
|
||||||
@@ -7580,6 +7605,45 @@
|
|||||||
"resolved": "https://registry.npmjs.org/left-pad/-/left-pad-1.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/left-pad/-/left-pad-1.3.0.tgz",
|
||||||
"integrity": "sha512-XI5MPzVNApjAyhQzphX8BkmKsKUxD4LdyK24iZeQGinBN9yTQT3bFlCBy/aVx2HrNcqQGsdot8ghrjyrvMCoEA=="
|
"integrity": "sha512-XI5MPzVNApjAyhQzphX8BkmKsKUxD4LdyK24iZeQGinBN9yTQT3bFlCBy/aVx2HrNcqQGsdot8ghrjyrvMCoEA=="
|
||||||
},
|
},
|
||||||
|
"less": {
|
||||||
|
"version": "3.9.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/less/-/less-3.9.0.tgz",
|
||||||
|
"integrity": "sha512-31CmtPEZraNUtuUREYjSqRkeETFdyEHSEPAGq4erDlUXtda7pzNmctdljdIagSb589d/qXGWiiP31R5JVf+v0w==",
|
||||||
|
"requires": {
|
||||||
|
"clone": "^2.1.2",
|
||||||
|
"errno": "^0.1.1",
|
||||||
|
"graceful-fs": "^4.1.2",
|
||||||
|
"image-size": "~0.5.0",
|
||||||
|
"mime": "^1.4.1",
|
||||||
|
"mkdirp": "^0.5.0",
|
||||||
|
"promise": "^7.1.1",
|
||||||
|
"request": "^2.83.0",
|
||||||
|
"source-map": "~0.6.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"mime": {
|
||||||
|
"version": "1.6.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
|
||||||
|
"integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"promise": {
|
||||||
|
"version": "7.3.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz",
|
||||||
|
"integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==",
|
||||||
|
"optional": true,
|
||||||
|
"requires": {
|
||||||
|
"asap": "~2.0.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"source-map": {
|
||||||
|
"version": "0.6.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
|
||||||
|
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"leven": {
|
"leven": {
|
||||||
"version": "2.1.0",
|
"version": "2.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/leven/-/leven-2.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/leven/-/leven-2.1.0.tgz",
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"less": "^3.9.0",
|
||||||
"react": "^16.8.6",
|
"react": "^16.8.6",
|
||||||
"react-dom": "^16.8.6",
|
"react-dom": "^16.8.6",
|
||||||
"react-scripts": "3.0.1"
|
"react-scripts": "3.0.1"
|
||||||
@@ -12,7 +13,7 @@
|
|||||||
"build": "react-scripts build",
|
"build": "react-scripts build",
|
||||||
"test": "react-scripts test",
|
"test": "react-scripts test",
|
||||||
"eject": "react-scripts eject",
|
"eject": "react-scripts eject",
|
||||||
"less":"less-watch-compiler ./src_less ./public/ main.less"
|
"less": "less-watch-compiler ./src_less ./public/ main.less"
|
||||||
},
|
},
|
||||||
"eslintConfig": {
|
"eslintConfig": {
|
||||||
"extends": "react-app"
|
"extends": "react-app"
|
||||||
|
|||||||
40
public/test.css
Normal file
40
public/test.css
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
@bg-color:#FFF;
|
||||||
|
|
||||||
|
*{
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
html,body{
|
||||||
|
margin:0;
|
||||||
|
}
|
||||||
|
.nav{
|
||||||
|
background-color:#353b48;
|
||||||
|
height:50px;
|
||||||
|
line-height: 50px;
|
||||||
|
select{
|
||||||
|
height: 42px;
|
||||||
|
border: 0;
|
||||||
|
outline:0;
|
||||||
|
min-width: 200px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.studentList{
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
.user{
|
||||||
|
border: 1px solid #454545;
|
||||||
|
margin: 5px;
|
||||||
|
padding: 5px;
|
||||||
|
.user_img{
|
||||||
|
img{
|
||||||
|
width:200px;
|
||||||
|
height:200px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.username{
|
||||||
|
text-align: center;
|
||||||
|
display: inline-block;
|
||||||
|
width: 200px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,6 +3,7 @@ import React from 'react';
|
|||||||
import {Classes} from './class/class_loader';
|
import {Classes} from './class/class_loader';
|
||||||
import {Students_loader} from './class/students_loader';
|
import {Students_loader} from './class/students_loader';
|
||||||
import { Student } from './ui/student';
|
import { Student } from './ui/student';
|
||||||
|
import { User } from './static/user';
|
||||||
|
|
||||||
export class Main extends React.Component{
|
export class Main extends React.Component{
|
||||||
constructor(props){
|
constructor(props){
|
||||||
@@ -11,15 +12,19 @@ export class Main extends React.Component{
|
|||||||
classes :['1'],
|
classes :['1'],
|
||||||
selected:"-",
|
selected:"-",
|
||||||
students:[],
|
students:[],
|
||||||
stud_html:[]
|
stud_html:[],
|
||||||
|
choose:1
|
||||||
}
|
}
|
||||||
|
|
||||||
this.selCh = this.selCh.bind(this);
|
this.selCh = this.selCh.bind(this);
|
||||||
|
this.changeChoosen = this.changeChoosen.bind(this);
|
||||||
|
this.choose = this.choose.bind(this);
|
||||||
|
|
||||||
var me = this;
|
var me = this;
|
||||||
Classes.load_Classes((data)=>{
|
Classes.load_Classes((data)=>{
|
||||||
me.setState({classes:data.classes});
|
me.setState({classes:data.classes});
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
selCh(e){
|
selCh(e){
|
||||||
console.log(e.target.value);
|
console.log(e.target.value);
|
||||||
@@ -28,7 +33,9 @@ export class Main extends React.Component{
|
|||||||
if(v!=='-'){
|
if(v!=='-'){
|
||||||
Students_loader.loadStudents(e.target.value,(data)=>{
|
Students_loader.loadStudents(e.target.value,(data)=>{
|
||||||
console.log(data)
|
console.log(data)
|
||||||
|
User.user_arr = [];
|
||||||
me.setState({students:[],stud_html:[]});
|
me.setState({students:[],stud_html:[]});
|
||||||
|
|
||||||
var ht = [];
|
var ht = [];
|
||||||
data.user.map((cl,i)=>
|
data.user.map((cl,i)=>
|
||||||
ht.push(<Student username={cl} cl={this.state.selected} i={i}></Student>)
|
ht.push(<Student username={cl} cl={this.state.selected} i={i}></Student>)
|
||||||
@@ -37,19 +44,47 @@ export class Main extends React.Component{
|
|||||||
me.setState({students:data.user,selected:v,stud_html:ht})
|
me.setState({students:data.user,selected:v,stud_html:ht})
|
||||||
})
|
})
|
||||||
}else{
|
}else{
|
||||||
|
User.user_arr = [];
|
||||||
me.setState({students:[],selected:v,stud_html:[]})
|
me.setState({students:[],selected:v,stud_html:[]})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
changeChoosen(e){
|
||||||
|
this.setState({choose:e.target.value})
|
||||||
|
}
|
||||||
|
choose(){
|
||||||
|
var me = this;
|
||||||
|
var c = [];
|
||||||
|
for(var i = 0;i<this.state.choose;i++){
|
||||||
|
var y = -1;
|
||||||
|
var nc = false;
|
||||||
|
y = Math.floor(Math.random()*User.user_arr.length);
|
||||||
|
if(c[0]==y){
|
||||||
|
y = Math.floor(Math.random()*User.user_arr.length);
|
||||||
|
}
|
||||||
|
c.push(y);
|
||||||
|
|
||||||
|
User.user_arr[y].disappear();
|
||||||
|
}
|
||||||
|
console.log(c)
|
||||||
|
}
|
||||||
render(){
|
render(){
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div className="nav">
|
<div className="nav">
|
||||||
<select onChange={this.selCh} value={this.state.selected}>
|
<div>
|
||||||
<option value="-">-</option>
|
<select onChange={this.selCh} value={this.state.selected}>
|
||||||
{this.state.classes.map((cl,i)=>
|
<option value="-">-</option>
|
||||||
<option value={cl.toLowerCase()}>{cl.toUpperCase()}</option>
|
{this.state.classes.map((cl,i)=>
|
||||||
)}
|
<option value={cl.toLowerCase()}>{cl.toUpperCase()}</option>
|
||||||
</select>
|
)}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<input type="number" min="1" value={this.state.choose} onChange={this.changeChoosen}/>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<button onClick={this.choose}>Auswählen</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="studentList">
|
<div className="studentList">
|
||||||
{this.state.stud_html}
|
{this.state.stud_html}
|
||||||
|
|||||||
3
src/jsx/static/user.jsx
Normal file
3
src/jsx/static/user.jsx
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
export class User{
|
||||||
|
static user_arr = [];
|
||||||
|
}
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
|
import {User} from './../static/user';
|
||||||
|
|
||||||
export class Student extends React.Component{
|
export class Student extends React.Component{
|
||||||
constructor(props){
|
constructor(props){
|
||||||
super(props);
|
super(props);
|
||||||
@@ -8,10 +10,14 @@ export class Student extends React.Component{
|
|||||||
name:props.username,
|
name:props.username,
|
||||||
cl:props.cl,
|
cl:props.cl,
|
||||||
img_url:'/data/class/'+props.cl+'/'+props.username+'.svg',
|
img_url:'/data/class/'+props.cl+'/'+props.username+'.svg',
|
||||||
num:props.i
|
num:props.i,
|
||||||
|
dis:""
|
||||||
}
|
}
|
||||||
|
|
||||||
this.onErr = this.onErr.bind(this);
|
this.onErr = this.onErr.bind(this);
|
||||||
|
this.disappear = this.disappear.bind(this);
|
||||||
|
|
||||||
|
User.user_arr.push(this);
|
||||||
}
|
}
|
||||||
camelize(str) {
|
camelize(str) {
|
||||||
var x = str.split('_');
|
var x = str.split('_');
|
||||||
@@ -24,8 +30,11 @@ export class Student extends React.Component{
|
|||||||
var url = '/data/class/student.svg';
|
var url = '/data/class/student.svg';
|
||||||
this.setState({img_url:url});
|
this.setState({img_url:url});
|
||||||
}
|
}
|
||||||
|
disappear(){
|
||||||
|
this.setState({dis:"disappear"});
|
||||||
|
}
|
||||||
render(){
|
render(){
|
||||||
var c = "user chosen_"+this.state.num;
|
var c = "user chosen_"+this.state.num+' '+this.state.dis;
|
||||||
return (
|
return (
|
||||||
<div className={c}>
|
<div className={c}>
|
||||||
<div className="user_img"><img src={this.state.img_url} onError={this.onErr} alt=""></img></div>
|
<div className="user_img"><img src={this.state.img_url} onError={this.onErr} alt=""></img></div>
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ html,body{
|
|||||||
background-color:#353b48;
|
background-color:#353b48;
|
||||||
height:50px;
|
height:50px;
|
||||||
line-height: 50px;
|
line-height: 50px;
|
||||||
|
display:flex;
|
||||||
select{
|
select{
|
||||||
height: 42px;
|
height: 42px;
|
||||||
border: 0;
|
border: 0;
|
||||||
@@ -25,6 +26,9 @@ html,body{
|
|||||||
border: 1px solid #454545;
|
border: 1px solid #454545;
|
||||||
margin: 5px;
|
margin: 5px;
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
|
&.disappear{
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
.user_img{
|
.user_img{
|
||||||
img{
|
img{
|
||||||
width:200px;
|
width:200px;
|
||||||
|
|||||||
Reference in New Issue
Block a user