mirror of
https://github.com/kremalicious/portfolio.git
synced 2024-12-22 17:23:22 +01:00
changes
This commit is contained in:
parent
a6ba0b1ff6
commit
51524e9bd9
@ -9,7 +9,8 @@
|
|||||||
},
|
},
|
||||||
"env": {
|
"env": {
|
||||||
"browser": true,
|
"browser": true,
|
||||||
"node": true
|
"node": true,
|
||||||
|
"es6": true
|
||||||
},
|
},
|
||||||
"globals": {
|
"globals": {
|
||||||
"graphql": true
|
"graphql": true
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
const meta = require('./data/meta.json')
|
const meta = require('./src/data/meta.json')
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
siteMetadata: {
|
siteMetadata: {
|
||||||
@ -7,24 +7,21 @@ module.exports = {
|
|||||||
plugins: [
|
plugins: [
|
||||||
'gatsby-plugin-react-next',
|
'gatsby-plugin-react-next',
|
||||||
'gatsby-plugin-react-helmet',
|
'gatsby-plugin-react-helmet',
|
||||||
'gatsby-transformer-json',
|
|
||||||
'gatsby-plugin-sitemap',
|
'gatsby-plugin-sitemap',
|
||||||
'gatsby-plugin-offline',
|
'gatsby-plugin-offline',
|
||||||
|
{
|
||||||
|
resolve: 'gatsby-plugin-sass',
|
||||||
|
options: {
|
||||||
|
includePaths: [`${__dirname}/node_modules`, `${__dirname}/src/styles`],
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
resolve: 'gatsby-source-filesystem',
|
resolve: 'gatsby-source-filesystem',
|
||||||
options: {
|
options: {
|
||||||
name: 'data',
|
name: 'data',
|
||||||
path: `${__dirname}/data/`,
|
path: `${__dirname}/src/data/`,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
'gatsby-transformer-json',
|
||||||
resolve: 'gatsby-plugin-sass',
|
],
|
||||||
options: {
|
|
||||||
includePaths: [
|
|
||||||
`${__dirname}/node_modules`,
|
|
||||||
`${__dirname}/src/styles`
|
|
||||||
],
|
|
||||||
},
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,10 @@
|
|||||||
const path = require('path')
|
const path = require('path')
|
||||||
|
|
||||||
// Implement the Gatsby API “createPages”. This is called once the
|
|
||||||
// data layer is bootstrapped to let plugins create pages from data.
|
|
||||||
exports.createPages = ({ boundActionCreators, graphql }) => {
|
exports.createPages = ({ boundActionCreators, graphql }) => {
|
||||||
const { createPage } = boundActionCreators
|
const { createPage } = boundActionCreators
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const template = path.resolve('src/layouts/Project.js')
|
const template = path.resolve('src/components/organisms/Project.js')
|
||||||
|
|
||||||
resolve(
|
resolve(
|
||||||
graphql(`
|
graphql(`
|
||||||
@ -34,15 +32,27 @@ exports.createPages = ({ boundActionCreators, graphql }) => {
|
|||||||
reject(result.errors)
|
reject(result.errors)
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(result)
|
|
||||||
|
|
||||||
result.data.allProjectsJson.edges.forEach(({ node }) => {
|
result.data.allProjectsJson.edges.forEach(({ node }) => {
|
||||||
const slug = node.slug
|
const slug = node.slug
|
||||||
|
const title = node.title
|
||||||
|
const img = node.img
|
||||||
|
const img_more = node.img_more
|
||||||
|
const description = node.description
|
||||||
|
const links = node.links
|
||||||
|
const techstack = node.techstack
|
||||||
|
|
||||||
createPage({
|
createPage({
|
||||||
path: slug,
|
path: slug,
|
||||||
component: template,
|
component: template,
|
||||||
context: { slug: slug },
|
context: {
|
||||||
|
title,
|
||||||
|
slug,
|
||||||
|
img,
|
||||||
|
img_more,
|
||||||
|
description,
|
||||||
|
techstack,
|
||||||
|
links
|
||||||
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -20,13 +20,14 @@
|
|||||||
"babel-eslint": "^8.2.2",
|
"babel-eslint": "^8.2.2",
|
||||||
"eslint": "^4.19.1",
|
"eslint": "^4.19.1",
|
||||||
"eslint-plugin-graphql": "^1.5.0",
|
"eslint-plugin-graphql": "^1.5.0",
|
||||||
|
"eslint-plugin-prettier": "^2.6.0",
|
||||||
"eslint-plugin-react": "^7.7.0",
|
"eslint-plugin-react": "^7.7.0",
|
||||||
"prettier": "^1.11.1",
|
"prettier": "^1.11.1",
|
||||||
"stylelint": "^9.2.0",
|
"stylelint": "^9.2.0",
|
||||||
"stylelint-config-standard": "^18.2.0"
|
"stylelint-config-standard": "^18.2.0"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"lint:js": "eslint ./src/**/*.js",
|
"lint:js": "eslint ./gatsby-*.js && eslint ./src/**/*.js",
|
||||||
"lint:css": "stylelint ./src/**/*.scss",
|
"lint:css": "stylelint ./src/**/*.scss",
|
||||||
"lint": "npm run lint:js && npm run lint:css",
|
"lint": "npm run lint:js && npm run lint:css",
|
||||||
"build": "gatsby build",
|
"build": "gatsby build",
|
||||||
|
@ -2,7 +2,7 @@ import React from 'react'
|
|||||||
import CSSTransition from 'react-transition-group/CSSTransition'
|
import CSSTransition from 'react-transition-group/CSSTransition'
|
||||||
import './FadeIn.scss'
|
import './FadeIn.scss'
|
||||||
|
|
||||||
const FadeIn = (props) => (
|
const FadeIn = props => (
|
||||||
<CSSTransition
|
<CSSTransition
|
||||||
{...props}
|
{...props}
|
||||||
classNames="fadein"
|
classNames="fadein"
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import meta from '../../../data/meta.json'
|
import PropTypes from 'prop-types'
|
||||||
import './Footer.scss'
|
import './Footer.scss'
|
||||||
|
|
||||||
const Footer = () => {
|
const Footer = ({ meta }) => {
|
||||||
const year = new Date().getFullYear()
|
const year = new Date().getFullYear()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -12,4 +12,8 @@ const Footer = () => {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Footer.propTypes = {
|
||||||
|
meta: PropTypes.object,
|
||||||
|
}
|
||||||
|
|
||||||
export default Footer
|
export default Footer
|
||||||
|
20
src/components/molecules/Head.js
Normal file
20
src/components/molecules/Head.js
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import PropTypes from 'prop-types'
|
||||||
|
import Helmet from 'react-helmet'
|
||||||
|
|
||||||
|
const Head = ({ meta }) => {
|
||||||
|
return (
|
||||||
|
<Helmet
|
||||||
|
defaultTitle={`${meta.title.toLowerCase()} { ${meta.tagline.toLowerCase()} }`}
|
||||||
|
titleTemplate={`%s // ${meta.title.toLowerCase()} { ${meta.tagline.toLowerCase()} }`}
|
||||||
|
>
|
||||||
|
<link rel="stylesheet" href="https://use.typekit.net/dtg3zui.css" />
|
||||||
|
</Helmet>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
Head.propTypes = {
|
||||||
|
meta: PropTypes.object,
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Head
|
@ -1,31 +1,28 @@
|
|||||||
import React, { Component } from 'react'
|
import React from 'react'
|
||||||
import Link from 'react-router-dom/Link'
|
import Link from 'react-router-dom/Link'
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
import Social from './Social'
|
import Social from './Social'
|
||||||
import './Header.scss'
|
import './Header.scss'
|
||||||
import meta from '../../../data/meta.json'
|
|
||||||
|
|
||||||
class Header extends Component {
|
const Header = ({ meta, minimal }) => {
|
||||||
render() {
|
const classes = minimal ? 'header header--minimal' : 'header'
|
||||||
const minimal = this.props.minimal
|
|
||||||
const classes = (minimal ? 'header header--minimal' : 'header')
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<header className={classes}>
|
<header className={classes}>
|
||||||
<Link className="header__name" to="/">
|
<Link className="header__name" to="/">
|
||||||
<span className="header__logo">␥</span>
|
<span className="header__logo">␥</span>
|
||||||
<h1 className="header__title">{meta.title}</h1>
|
<h1 className="header__title">{meta.title}</h1>
|
||||||
<p className="header__description">{meta.tagline}</p>
|
<p className="header__description">{meta.tagline}</p>
|
||||||
</Link>
|
</Link>
|
||||||
|
|
||||||
<Social />
|
<Social meta={meta} />
|
||||||
</header>
|
</header>
|
||||||
)
|
)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Header.propTypes = {
|
Header.propTypes = {
|
||||||
minimal: PropTypes.bool
|
minimal: PropTypes.bool,
|
||||||
|
meta: PropTypes.object,
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Header
|
export default Header
|
||||||
|
@ -1,10 +1,8 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
|
import PropTypes from 'prop-types'
|
||||||
import { Twitter, GitHub, Facebook } from '../atoms/Icons'
|
import { Twitter, GitHub, Facebook } from '../atoms/Icons'
|
||||||
import meta from '../../../data/meta.json'
|
|
||||||
import './Social.scss'
|
import './Social.scss'
|
||||||
|
|
||||||
const social = meta.social
|
|
||||||
|
|
||||||
const SocialIcon = ({ title }) => {
|
const SocialIcon = ({ title }) => {
|
||||||
if (title === 'Twitter') {
|
if (title === 'Twitter') {
|
||||||
return <Twitter />
|
return <Twitter />
|
||||||
@ -15,14 +13,22 @@ const SocialIcon = ({ title }) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const Social = () => (
|
const Social = ({ meta }) => {
|
||||||
<aside className="social">
|
const social = meta.social
|
||||||
{Object.keys(social).map((key, i) => (
|
|
||||||
<a className="social__link" href={social[key]} key={i} title={key}>
|
return (
|
||||||
<SocialIcon title={key} />
|
<aside className="social">
|
||||||
</a>
|
{Object.keys(social).map((key, i) => (
|
||||||
))}
|
<a className="social__link" href={social[key]} key={i} title={key}>
|
||||||
</aside>
|
<SocialIcon title={key} />
|
||||||
)
|
</a>
|
||||||
|
))}
|
||||||
|
</aside>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
Social.propTypes = {
|
||||||
|
meta: PropTypes.object,
|
||||||
|
}
|
||||||
|
|
||||||
export default Social
|
export default Social
|
||||||
|
87
src/components/organisms/Project.js
Normal file
87
src/components/organisms/Project.js
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
import React, { Fragment } from 'react'
|
||||||
|
import PropTypes from 'prop-types'
|
||||||
|
import Helmet from 'react-helmet'
|
||||||
|
import ReactMarkdown from 'react-markdown'
|
||||||
|
import Content from '../atoms/Content'
|
||||||
|
import FullWidth from '../atoms/FullWidth'
|
||||||
|
import images from '../../images'
|
||||||
|
import './Project.scss'
|
||||||
|
|
||||||
|
const Project = props => {
|
||||||
|
const project = props.pathContext
|
||||||
|
const title = project.title
|
||||||
|
const img = project.img
|
||||||
|
const img_more = project.img_more
|
||||||
|
const description = project.description
|
||||||
|
const links = project.links
|
||||||
|
const techstack = project.techstack
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Fragment>
|
||||||
|
<Helmet>
|
||||||
|
<title>{title}</title>
|
||||||
|
</Helmet>
|
||||||
|
|
||||||
|
<main className="screen screen--project">
|
||||||
|
<article className="project">
|
||||||
|
<Content>
|
||||||
|
<h1 className="project__title">{title}</h1>
|
||||||
|
<ReactMarkdown
|
||||||
|
source={description}
|
||||||
|
escapeHtml={false}
|
||||||
|
className="project__description"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<FullWidth>
|
||||||
|
<img className="project__image" src={images[img]} alt={title} />
|
||||||
|
</FullWidth>
|
||||||
|
|
||||||
|
<FullWidth>
|
||||||
|
{!!img_more &&
|
||||||
|
img_more.map(key => (
|
||||||
|
<img
|
||||||
|
key={key}
|
||||||
|
className="project__image"
|
||||||
|
src={images[key]}
|
||||||
|
alt={title}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</FullWidth>
|
||||||
|
|
||||||
|
<footer className="project__meta">
|
||||||
|
<div className="project__techstack">
|
||||||
|
<h3 className="project__meta__title">
|
||||||
|
Technologies <span>The tech stack I was involved with.</span>
|
||||||
|
</h3>
|
||||||
|
<ul>
|
||||||
|
{!!techstack &&
|
||||||
|
techstack.map(tech => <li key={tech}>{tech}</li>)}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="project__links">
|
||||||
|
<h3 className="project__meta__title">
|
||||||
|
Links <span>See the project live on the interwebz.</span>
|
||||||
|
</h3>
|
||||||
|
<ul>
|
||||||
|
{!!links &&
|
||||||
|
Object.keys(links).map(key => (
|
||||||
|
<li key={key}>
|
||||||
|
<a href={links[key]}>{key}</a>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
</Content>
|
||||||
|
</article>
|
||||||
|
</main>
|
||||||
|
</Fragment>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
Project.propTypes = {
|
||||||
|
pathContext: PropTypes.object,
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Project
|
@ -6,10 +6,10 @@ import images from '../../images'
|
|||||||
import './Projects.scss'
|
import './Projects.scss'
|
||||||
|
|
||||||
const Projects = ({ data }) => {
|
const Projects = ({ data }) => {
|
||||||
const projects = data.allProjectsJson
|
const projects = data.allProjectsJson.edges
|
||||||
|
|
||||||
return <div className="projects full-width">
|
return <div className="projects full-width">
|
||||||
{projects.edges.map(({ node }) => <FadeIn key={node.slug}>
|
{projects.map(({ node }) => <FadeIn key={node.slug}>
|
||||||
<Link key={node.slug} to={`/${node.slug}`} className="projects__project">
|
<Link key={node.slug} to={`/${node.slug}`} className="projects__project">
|
||||||
<h1 className="projects__project__title">{node.title}</h1>
|
<h1 className="projects__project__title">{node.title}</h1>
|
||||||
|
|
||||||
|
@ -7,7 +7,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.projects__project {
|
.projects__project {
|
||||||
max-height: 100vh;
|
|
||||||
position: relative;
|
position: relative;
|
||||||
background-color: $brand-grey-light;
|
background-color: $brand-grey-light;
|
||||||
margin-bottom: $spacer * 4;
|
margin-bottom: $spacer * 4;
|
||||||
|
@ -1,101 +0,0 @@
|
|||||||
import React from 'react'
|
|
||||||
import PropTypes from 'prop-types'
|
|
||||||
import Helmet from 'react-helmet'
|
|
||||||
import ReactMarkdown from 'react-markdown'
|
|
||||||
import Header from '../components/molecules/Header'
|
|
||||||
import Content from '../components/atoms/Content'
|
|
||||||
import FullWidth from '../components/atoms/FullWidth'
|
|
||||||
import images from '../images'
|
|
||||||
import './Project.scss'
|
|
||||||
|
|
||||||
const Project = ({ data }) => {
|
|
||||||
const project = data.allProjectsJson.edges[0].node
|
|
||||||
const title = project.title
|
|
||||||
const img = project.img
|
|
||||||
const img_more = project.img_more
|
|
||||||
const description = project.description
|
|
||||||
const links = project.links
|
|
||||||
const techstack = project.techstack
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<Helmet>
|
|
||||||
<title>{title}</title>
|
|
||||||
</Helmet>
|
|
||||||
|
|
||||||
<Header minimal />
|
|
||||||
|
|
||||||
<main className="screen screen--project">
|
|
||||||
<article className="project">
|
|
||||||
<Content>
|
|
||||||
<h1 className="project__title">{title}</h1>
|
|
||||||
<ReactMarkdown source={description} escapeHtml={false} className="project__description" />
|
|
||||||
|
|
||||||
<FullWidth>
|
|
||||||
<img className="project__image" src={images[img]} alt={title} />
|
|
||||||
</FullWidth>
|
|
||||||
|
|
||||||
<FullWidth>
|
|
||||||
{!!img_more && img_more.map(key => (
|
|
||||||
<img key={key} className="project__image" src={images[key]} alt={title} />
|
|
||||||
))}
|
|
||||||
</FullWidth>
|
|
||||||
|
|
||||||
<footer className="project__meta">
|
|
||||||
<div className="project__techstack">
|
|
||||||
<h3 className="project__meta__title">Technologies <span>The tech stack I was involved with.</span></h3>
|
|
||||||
<ul>
|
|
||||||
{!!techstack && techstack.map(tech => (
|
|
||||||
<li key={tech}>
|
|
||||||
{tech}
|
|
||||||
</li>
|
|
||||||
))}
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="project__links">
|
|
||||||
<h3 className="project__meta__title">Links <span>See the project live on the interwebz.</span></h3>
|
|
||||||
<ul>
|
|
||||||
{!!links && Object.keys(links).map(key => (
|
|
||||||
<li key={key}>
|
|
||||||
<a href={links[key]}>{key}</a>
|
|
||||||
</li>
|
|
||||||
))}
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</footer>
|
|
||||||
|
|
||||||
</Content>
|
|
||||||
</article>
|
|
||||||
</main>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
Project.propTypes = {
|
|
||||||
data: PropTypes.object
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Project
|
|
||||||
|
|
||||||
export const query = graphql`
|
|
||||||
query ProjectQuery($slug: String) {
|
|
||||||
allProjectsJson(filter: { slug: { eq: $slug } }) {
|
|
||||||
edges {
|
|
||||||
node {
|
|
||||||
title
|
|
||||||
slug
|
|
||||||
img
|
|
||||||
img_more
|
|
||||||
links {
|
|
||||||
Link
|
|
||||||
GitHub
|
|
||||||
Info
|
|
||||||
}
|
|
||||||
description
|
|
||||||
techstack
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`
|
|
@ -1,30 +1,48 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
import Helmet from 'react-helmet'
|
import Head from '../components/molecules/Head'
|
||||||
import FadeIn from '../components/atoms/FadeIn'
|
import FadeIn from '../components/atoms/FadeIn'
|
||||||
|
import Header from '../components/molecules/Header'
|
||||||
import Footer from '../components/molecules/Footer'
|
import Footer from '../components/molecules/Footer'
|
||||||
import meta from '../../data/meta.json'
|
|
||||||
import './index.scss'
|
import './index.scss'
|
||||||
|
|
||||||
const Head = () => (
|
const TemplateWrapper = props => {
|
||||||
<Helmet
|
const meta = props.data.allDataJson.edges[0].node
|
||||||
defaultTitle={`${meta.title.toLowerCase()} { ${meta.tagline.toLowerCase()} }`}
|
|
||||||
titleTemplate={`%s // ${meta.title.toLowerCase()} { ${meta.tagline.toLowerCase()} }`}
|
|
||||||
>
|
|
||||||
<link rel="stylesheet" href="https://use.typekit.net/dtg3zui.css" />
|
|
||||||
</Helmet>
|
|
||||||
)
|
|
||||||
|
|
||||||
const TemplateWrapper = ({ children }) => (
|
return <div className="app">
|
||||||
<div className="app">
|
<Head meta={meta} />
|
||||||
<Head />
|
<Header meta={meta} />
|
||||||
<FadeIn>{children()}</FadeIn>
|
<FadeIn>{props.children()}</FadeIn>
|
||||||
<Footer />
|
<Footer meta={meta} />
|
||||||
</div>
|
</div>
|
||||||
)
|
}
|
||||||
|
|
||||||
TemplateWrapper.propTypes = {
|
TemplateWrapper.propTypes = {
|
||||||
children: PropTypes.func,
|
children: PropTypes.func,
|
||||||
|
data: PropTypes.object,
|
||||||
}
|
}
|
||||||
|
|
||||||
export default TemplateWrapper
|
export default TemplateWrapper
|
||||||
|
|
||||||
|
export const query = graphql`
|
||||||
|
query pageLayoutQueryAndMetaQuery {
|
||||||
|
allDataJson {
|
||||||
|
edges {
|
||||||
|
node {
|
||||||
|
title
|
||||||
|
tagline
|
||||||
|
description
|
||||||
|
url
|
||||||
|
social {
|
||||||
|
Twitter
|
||||||
|
GitHub
|
||||||
|
Facebook
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sitePage {
|
||||||
|
jsonName
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
@ -1,15 +1,11 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
import Header from '../components/molecules/Header'
|
|
||||||
import Projects from '../components/organisms/Projects'
|
import Projects from '../components/organisms/Projects'
|
||||||
|
|
||||||
const Home = ({ data }) => (
|
const Home = ({ data }) => (
|
||||||
<div>
|
<main className="screen screen--home">
|
||||||
<Header />
|
<Projects data={data} />
|
||||||
<main className="screen screen--home">
|
</main>
|
||||||
<Projects data={data} />
|
|
||||||
</main>
|
|
||||||
</div>
|
|
||||||
)
|
)
|
||||||
|
|
||||||
Home.propTypes = {
|
Home.propTypes = {
|
||||||
|
Loading…
Reference in New Issue
Block a user