mirror of
https://github.com/jaronpate/folio.git
synced 2026-10-19 01:07:39 +00:00
feat: implement dark mode support, update writing route logic, and add content entry placeholder
This commit is contained in:
+1
-17
@@ -2,23 +2,7 @@
|
|||||||
import '~/assets/css/main.css';
|
import '~/assets/css/main.css';
|
||||||
|
|
||||||
useHead({
|
useHead({
|
||||||
link: [
|
link: [{ rel: 'icon', type: 'image/png', href: '/favicon.png' }],
|
||||||
{ rel: 'icon', type: 'image/png', href: '/favicon.png' },
|
|
||||||
// { rel: 'preconnect', href: 'https://fonts.googleapis.com' },
|
|
||||||
// {
|
|
||||||
// rel: 'preconnect',
|
|
||||||
// href: 'https://fonts.gstatic.com',
|
|
||||||
// crossorigin: '',
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// rel: 'stylesheet',
|
|
||||||
// href: 'https://fonts.googleapis.com/css2?family=Baskervville:ital,wght@0,400..700;1,400..700&display=swap',
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// rel: 'stylesheet',
|
|
||||||
// href: 'https://fonts.googleapis.com/css2?family=EB+Garamond:ital,wght@0,400..800;1,400..800&display=swap',
|
|
||||||
// },
|
|
||||||
],
|
|
||||||
});
|
});
|
||||||
|
|
||||||
onMounted(() => {});
|
onMounted(() => {});
|
||||||
|
|||||||
Binary file not shown.
+20
-3
@@ -4,14 +4,31 @@
|
|||||||
/* --font: 'Baskervville', serif; */
|
/* --font: 'Baskervville', serif; */
|
||||||
/* --font: 'EB Garamond', serif; */
|
/* --font: 'EB Garamond', serif; */
|
||||||
/* --font: 'Plantin MT Pro', serif; */
|
/* --font: 'Plantin MT Pro', serif; */
|
||||||
--font: 'Redaction', serif;
|
|
||||||
/* --font: 'Young Serif', serif; */
|
/* --font: 'Young Serif', serif; */
|
||||||
/* --font: "SohneBuch", sans-serif; */
|
/* --font: "SohneBuch", sans-serif; */
|
||||||
|
--font: 'Redaction', serif;
|
||||||
--font-hover: 'Redaction 70', serif;
|
--font-hover: 'Redaction 70', serif;
|
||||||
/* --font-hover: var(--font); */
|
/* --font-hover: var(--font); */
|
||||||
--text: #333;
|
--text: #333;
|
||||||
--muted: #666;
|
--muted: #666;
|
||||||
--bg: #fbfbf7;
|
--bg: #fbfbf7;
|
||||||
|
|
||||||
|
--color-white-500: #fbfbf7;
|
||||||
|
|
||||||
|
--gap: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
::selection {
|
||||||
|
background: var(--text);
|
||||||
|
color: var(--bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark-mode {
|
||||||
|
--text: #fbfbf7;
|
||||||
|
--bg: #111111;
|
||||||
|
--muted: #d1d1d1;
|
||||||
|
|
||||||
|
--color-white-500: #fbfbf7;
|
||||||
}
|
}
|
||||||
|
|
||||||
.flex {
|
.flex {
|
||||||
@@ -70,12 +87,12 @@ body {
|
|||||||
display: inline-block;
|
display: inline-block;
|
||||||
vertical-align: bottom;
|
vertical-align: bottom;
|
||||||
position: relative;
|
position: relative;
|
||||||
color: var(--bg);
|
color: var(--color-white-500);
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
transition: all 200ms ease;
|
transition: all 200ms ease;
|
||||||
padding: 0 4px;
|
padding: 0 4px;
|
||||||
margin: 0 -4px;
|
margin: 0 -4px;
|
||||||
background-image: linear-gradient(var(--bg), var(--bg));
|
background-image: linear-gradient(var(--color-white-500), var(--color-white-500));
|
||||||
background-size: 100% 1px;
|
background-size: 100% 1px;
|
||||||
background-position: bottom;
|
background-position: bottom;
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
|
|||||||
+34
-7
@@ -3,6 +3,12 @@ defineProps<{
|
|||||||
title?: string;
|
title?: string;
|
||||||
description?: string;
|
description?: string;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
|
const theme = useColorMode();
|
||||||
|
|
||||||
|
const toggleTheme = () => {
|
||||||
|
theme.preference = theme.preference === 'light' ? 'dark' : 'light';
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -27,14 +33,20 @@ defineProps<{
|
|||||||
<div class="header-upper">
|
<div class="header-upper">
|
||||||
<slot name="header-upper">
|
<slot name="header-upper">
|
||||||
<div class="flex-center header-upper-nav">
|
<div class="flex-center header-upper-nav">
|
||||||
<p style="font-family: monospace">🐟🎩.dev</p>
|
<button
|
||||||
|
class="theme-toggle"
|
||||||
|
@click="toggleTheme"
|
||||||
|
v-if="!theme.unknown"
|
||||||
|
>
|
||||||
|
{{ theme.value === 'dark' ? '🌚' : '🌝' }}
|
||||||
|
</button>
|
||||||
<div class="flex-ff"></div>
|
<div class="flex-ff"></div>
|
||||||
<!-- <NuxtLink to="/resume" class="basic-link"
|
<!-- <NuxtLink to="/resume" class="basic-link"
|
||||||
>Resume</NuxtLink
|
>Resume</NuxtLink
|
||||||
> -->
|
> -->
|
||||||
<NuxtLink to="/writing" class="basic-link"
|
<!-- <NuxtLink to="/writing" class="basic-link">
|
||||||
>Writing</NuxtLink
|
Writing
|
||||||
>
|
</NuxtLink> -->
|
||||||
</div>
|
</div>
|
||||||
</slot>
|
</slot>
|
||||||
</div>
|
</div>
|
||||||
@@ -71,8 +83,9 @@ defineProps<{
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="footer-lower">
|
<div class="footer-lower">
|
||||||
<div class="flex-center">
|
<div class="flex-center" style="gap: var(--gap)">
|
||||||
<p style="text-align: right">Est. 2003</p>
|
<p style="text-align: right">Est. 2003</p>
|
||||||
|
<!-- <p style="font-family: monospace">🐟🎩.dev</p> -->
|
||||||
<div class="flex-ff"></div>
|
<div class="flex-ff"></div>
|
||||||
<p style="text-align: right">Austin, TX</p>
|
<p style="text-align: right">Austin, TX</p>
|
||||||
</div>
|
</div>
|
||||||
@@ -158,7 +171,7 @@ svg[height='0'] {
|
|||||||
border-top: 1px solid var(--muted);
|
border-top: 1px solid var(--muted);
|
||||||
border-bottom: 1px solid var(--muted);
|
border-bottom: 1px solid var(--muted);
|
||||||
padding: 2rem;
|
padding: 2rem;
|
||||||
color: var(--bg);
|
color: var(--color-white-500);
|
||||||
|
|
||||||
position: relative;
|
position: relative;
|
||||||
isolation: isolate;
|
isolation: isolate;
|
||||||
@@ -180,7 +193,7 @@ svg[height='0'] {
|
|||||||
border-top: 1px solid var(--muted);
|
border-top: 1px solid var(--muted);
|
||||||
border-bottom: 1px solid var(--muted);
|
border-bottom: 1px solid var(--muted);
|
||||||
padding: 2rem;
|
padding: 2rem;
|
||||||
color: var(--bg);
|
color: var(--color-white-500);
|
||||||
min-height: 10vh;
|
min-height: 10vh;
|
||||||
position: relative;
|
position: relative;
|
||||||
isolation: isolate;
|
isolation: isolate;
|
||||||
@@ -205,6 +218,20 @@ svg[height='0'] {
|
|||||||
gap: 1rem;
|
gap: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.theme-toggle {
|
||||||
|
background: transparent;
|
||||||
|
border: none;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: large;
|
||||||
|
font-weight: bold;
|
||||||
|
color: var(--text);
|
||||||
|
transition: opacity 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.theme-toggle:hover {
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
@media (max-width: 1024px) {
|
@media (max-width: 1024px) {
|
||||||
.page-wrapper {
|
.page-wrapper {
|
||||||
--main-width: 80vw;
|
--main-width: 80vw;
|
||||||
|
|||||||
+13
-6
@@ -73,11 +73,18 @@ definePageMeta({
|
|||||||
<h5>About</h5>
|
<h5>About</h5>
|
||||||
<div class="section__content">
|
<div class="section__content">
|
||||||
<p>
|
<p>
|
||||||
I work across the full stack; backend, frontend, and
|
I enjoy the entire process of building things; backend,
|
||||||
product. My favorite side projects are ones that bring me
|
frontend, product, etc.
|
||||||
new skills. Even better are ones where I solve a problem or
|
</p>
|
||||||
build a tool I can use. I'm always open to interesting work
|
<p>
|
||||||
and conversations.
|
I left school and my job at Chick-fil-A in 2022 to write
|
||||||
|
code full time. It's definitely one of the best decisions
|
||||||
|
I've ever made. I've learned so much since then and
|
||||||
|
<em>still</em> have so much more to learn.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
If you want to build something cool or connect hit me up! I
|
||||||
|
still dont know enough people to form a band yet ;)
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
@@ -300,7 +307,7 @@ section:last-of-type {
|
|||||||
font-size: small;
|
font-size: small;
|
||||||
}
|
}
|
||||||
|
|
||||||
.about p {
|
.about p:last-child {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const { data: page } = await useAsyncData(route.path, () => {
|
const { data: page } = await useAsyncData(route.path, () => {
|
||||||
return queryCollection('writing').path(route.path).first();
|
return queryCollection('writing')
|
||||||
|
.path(route.path.replace('/writing/', ''))
|
||||||
|
.first();
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!page.value) {
|
if (!page.value) {
|
||||||
|
|||||||
@@ -27,20 +27,20 @@ const formatDate = (dateString: string) => {
|
|||||||
<section>
|
<section>
|
||||||
<div class="section__content">
|
<div class="section__content">
|
||||||
<template v-if="pages?.length">
|
<template v-if="pages?.length">
|
||||||
<a
|
<NuxtLink
|
||||||
v-for="page in pages"
|
v-for="page in pages"
|
||||||
:href="page.path"
|
:to="'/writing/' + page.path"
|
||||||
:key="page.path"
|
:key="page.path"
|
||||||
class="article"
|
class="article"
|
||||||
>
|
>
|
||||||
<h3 class="article__title">{{ page.title }}</h3>
|
<h3 class="article__title">{{ page.title }}</h3>
|
||||||
<p class="article__date">
|
<!-- <p class="article__date">
|
||||||
{{ formatDate(page.date) }}
|
{{ formatDate(page.date) }}
|
||||||
</p>
|
</p> -->
|
||||||
<p class="article__description">
|
<p class="article__description">
|
||||||
{{ page.description }}
|
{{ page.description }}
|
||||||
</p>
|
</p>
|
||||||
</a>
|
</NuxtLink>
|
||||||
</template>
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<div class="empty-state">
|
<div class="empty-state">
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
"wrangler": "^4.86.0",
|
"wrangler": "^4.86.0",
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@nuxtjs/color-mode": "^4.0.0",
|
||||||
"prettier": "^3.8.3",
|
"prettier": "^3.8.3",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -262,6 +263,8 @@
|
|||||||
|
|
||||||
"@nuxt/vite-builder": ["@nuxt/vite-builder@4.4.2", "", { "dependencies": { "@nuxt/kit": "4.4.2", "@rollup/plugin-replace": "^6.0.3", "@vitejs/plugin-vue": "^6.0.4", "@vitejs/plugin-vue-jsx": "^5.1.4", "autoprefixer": "^10.4.27", "consola": "^3.4.2", "cssnano": "^7.1.3", "defu": "^6.1.4", "escape-string-regexp": "^5.0.0", "exsolve": "^1.0.8", "get-port-please": "^3.2.0", "jiti": "^2.6.1", "knitwork": "^1.3.0", "magic-string": "^0.30.21", "mlly": "^1.8.1", "mocked-exports": "^0.1.1", "nypm": "^0.6.5", "pathe": "^2.0.3", "pkg-types": "^2.3.0", "postcss": "^8.5.8", "seroval": "^1.5.1", "std-env": "^4.0.0", "ufo": "^1.6.3", "unenv": "^2.0.0-rc.24", "vite": "^7.3.1", "vite-node": "^5.3.0", "vite-plugin-checker": "^0.12.0", "vue-bundle-renderer": "^2.2.0" }, "peerDependencies": { "@babel/plugin-proposal-decorators": "^7.25.0", "@babel/plugin-syntax-jsx": "^7.25.0", "nuxt": "4.4.2", "rolldown": "^1.0.0-beta.38", "rollup-plugin-visualizer": "^6.0.0 || ^7.0.1", "vue": "^3.3.4" }, "optionalPeers": ["@babel/plugin-proposal-decorators", "@babel/plugin-syntax-jsx", "rolldown", "rollup-plugin-visualizer"] }, "sha512-fJaIwMA8ID6BU5EqmoDvnhq4qYDJeWjdHk4jfqy8D3Nm7CoUW0BvX7Ee92XoO05rtUiClGlk/NQ1Ii8hs3ZIbw=="],
|
"@nuxt/vite-builder": ["@nuxt/vite-builder@4.4.2", "", { "dependencies": { "@nuxt/kit": "4.4.2", "@rollup/plugin-replace": "^6.0.3", "@vitejs/plugin-vue": "^6.0.4", "@vitejs/plugin-vue-jsx": "^5.1.4", "autoprefixer": "^10.4.27", "consola": "^3.4.2", "cssnano": "^7.1.3", "defu": "^6.1.4", "escape-string-regexp": "^5.0.0", "exsolve": "^1.0.8", "get-port-please": "^3.2.0", "jiti": "^2.6.1", "knitwork": "^1.3.0", "magic-string": "^0.30.21", "mlly": "^1.8.1", "mocked-exports": "^0.1.1", "nypm": "^0.6.5", "pathe": "^2.0.3", "pkg-types": "^2.3.0", "postcss": "^8.5.8", "seroval": "^1.5.1", "std-env": "^4.0.0", "ufo": "^1.6.3", "unenv": "^2.0.0-rc.24", "vite": "^7.3.1", "vite-node": "^5.3.0", "vite-plugin-checker": "^0.12.0", "vue-bundle-renderer": "^2.2.0" }, "peerDependencies": { "@babel/plugin-proposal-decorators": "^7.25.0", "@babel/plugin-syntax-jsx": "^7.25.0", "nuxt": "4.4.2", "rolldown": "^1.0.0-beta.38", "rollup-plugin-visualizer": "^6.0.0 || ^7.0.1", "vue": "^3.3.4" }, "optionalPeers": ["@babel/plugin-proposal-decorators", "@babel/plugin-syntax-jsx", "rolldown", "rollup-plugin-visualizer"] }, "sha512-fJaIwMA8ID6BU5EqmoDvnhq4qYDJeWjdHk4jfqy8D3Nm7CoUW0BvX7Ee92XoO05rtUiClGlk/NQ1Ii8hs3ZIbw=="],
|
||||||
|
|
||||||
|
"@nuxtjs/color-mode": ["@nuxtjs/color-mode@4.0.0", "", { "dependencies": { "@nuxt/kit": "^4.2.1", "exsolve": "^1.0.8", "pathe": "^2.0.3", "pkg-types": "^2.3.0", "semver": "^7.7.3" } }, "sha512-xyaVR/TPLdMuRa2VOgH6b75jvmFEsn9QKL6ISldaAw38ooFJfWY1ts2F3ye43wcT/goCbcuvPuskF2f8yUZhlw=="],
|
||||||
|
|
||||||
"@nuxtjs/mdc": ["@nuxtjs/mdc@0.21.1", "", { "dependencies": { "@nuxt/kit": "^4.4.2", "@shikijs/core": "^4.0.2", "@shikijs/engine-javascript": "^4.0.2", "@shikijs/langs": "^4.0.2", "@shikijs/themes": "^4.0.2", "@shikijs/transformers": "^4.0.2", "@types/hast": "^3.0.4", "@types/mdast": "^4.0.4", "@vue/compiler-core": "^3.5.31", "consola": "^3.4.2", "debug": "^4.4.3", "defu": "^6.1.4", "destr": "^2.0.5", "detab": "^3.0.2", "github-slugger": "^2.0.0", "hast-util-format": "^1.1.0", "hast-util-to-mdast": "^10.1.2", "hast-util-to-string": "^3.0.1", "mdast-util-to-hast": "^13.2.1", "micromark-util-sanitize-uri": "^2.0.1", "parse5": "^8.0.0", "pathe": "^2.0.3", "property-information": "^7.1.0", "rehype-external-links": "^3.0.0", "rehype-minify-whitespace": "^6.0.2", "rehype-raw": "^7.0.0", "rehype-remark": "^10.0.1", "rehype-slug": "^6.0.0", "rehype-sort-attribute-values": "^5.0.1", "rehype-sort-attributes": "^5.0.1", "remark-emoji": "^5.0.2", "remark-gfm": "^4.0.1", "remark-mdc": "^3.10.0", "remark-parse": "^11.0.0", "remark-rehype": "^11.1.2", "remark-stringify": "^11.0.0", "scule": "^1.3.0", "shiki": "^4.0.2", "ufo": "^1.6.3", "unified": "^11.0.5", "unist-builder": "^4.0.0", "unist-util-visit": "^5.1.0", "unwasm": "^0.5.3", "vfile": "^6.0.3" } }, "sha512-DIeUD7IahWVUSoZExysxH9dX51Io6hcQYgGJODq0cMTGqaoDD32lRfHBJxYUmy+sUCV1+1hfa2ixspgJgEd2GA=="],
|
"@nuxtjs/mdc": ["@nuxtjs/mdc@0.21.1", "", { "dependencies": { "@nuxt/kit": "^4.4.2", "@shikijs/core": "^4.0.2", "@shikijs/engine-javascript": "^4.0.2", "@shikijs/langs": "^4.0.2", "@shikijs/themes": "^4.0.2", "@shikijs/transformers": "^4.0.2", "@types/hast": "^3.0.4", "@types/mdast": "^4.0.4", "@vue/compiler-core": "^3.5.31", "consola": "^3.4.2", "debug": "^4.4.3", "defu": "^6.1.4", "destr": "^2.0.5", "detab": "^3.0.2", "github-slugger": "^2.0.0", "hast-util-format": "^1.1.0", "hast-util-to-mdast": "^10.1.2", "hast-util-to-string": "^3.0.1", "mdast-util-to-hast": "^13.2.1", "micromark-util-sanitize-uri": "^2.0.1", "parse5": "^8.0.0", "pathe": "^2.0.3", "property-information": "^7.1.0", "rehype-external-links": "^3.0.0", "rehype-minify-whitespace": "^6.0.2", "rehype-raw": "^7.0.0", "rehype-remark": "^10.0.1", "rehype-slug": "^6.0.0", "rehype-sort-attribute-values": "^5.0.1", "rehype-sort-attributes": "^5.0.1", "remark-emoji": "^5.0.2", "remark-gfm": "^4.0.1", "remark-mdc": "^3.10.0", "remark-parse": "^11.0.0", "remark-rehype": "^11.1.2", "remark-stringify": "^11.0.0", "scule": "^1.3.0", "shiki": "^4.0.2", "ufo": "^1.6.3", "unified": "^11.0.5", "unist-builder": "^4.0.0", "unist-util-visit": "^5.1.0", "unwasm": "^0.5.3", "vfile": "^6.0.3" } }, "sha512-DIeUD7IahWVUSoZExysxH9dX51Io6hcQYgGJODq0cMTGqaoDD32lRfHBJxYUmy+sUCV1+1hfa2ixspgJgEd2GA=="],
|
||||||
|
|
||||||
"@oxc-minify/binding-android-arm-eabi": ["@oxc-minify/binding-android-arm-eabi@0.117.0", "", { "os": "android", "cpu": "arm" }, "sha512-5Hf2KsGRjxp3HnPU/mse7cQJa5tWfMFUPZQcgSMVsv2JZnGFFOIDzA0Oja2KDD+VPJqMpEJKc2dCHAGZgJxsGg=="],
|
"@oxc-minify/binding-android-arm-eabi": ["@oxc-minify/binding-android-arm-eabi@0.117.0", "", { "os": "android", "cpu": "arm" }, "sha512-5Hf2KsGRjxp3HnPU/mse7cQJa5tWfMFUPZQcgSMVsv2JZnGFFOIDzA0Oja2KDD+VPJqMpEJKc2dCHAGZgJxsGg=="],
|
||||||
|
|||||||
+4
-1
@@ -4,7 +4,10 @@ export default defineContentConfig({
|
|||||||
collections: {
|
collections: {
|
||||||
writing: defineCollection({
|
writing: defineCollection({
|
||||||
type: 'page',
|
type: 'page',
|
||||||
source: 'writing/**/*.md',
|
source: {
|
||||||
|
include: 'writing/**/*.md',
|
||||||
|
prefix: '',
|
||||||
|
},
|
||||||
schema: z.object({
|
schema: z.object({
|
||||||
title: z.string(),
|
title: z.string(),
|
||||||
date: z.coerce.date(),
|
date: z.coerce.date(),
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
title: 'hot take: frontend developers are underpaid.'
|
||||||
|
date: 2026-05-03
|
||||||
|
description: that shit is hard
|
||||||
|
---
|
||||||
|
|
||||||
|
blah blah blah
|
||||||
+10
-1
@@ -45,5 +45,14 @@ export default defineNuxtConfig({
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
modules: ['@nuxt/content'],
|
modules: ['@nuxt/content', '@nuxtjs/color-mode'],
|
||||||
|
colorMode: {
|
||||||
|
preference: 'system', // default value of $colorMode.preference
|
||||||
|
fallback: 'light', // fallback value if not system preference found
|
||||||
|
globalName: '__NUXT_COLOR_MODE__',
|
||||||
|
componentName: 'ColorScheme',
|
||||||
|
classPrefix: '',
|
||||||
|
classSuffix: '-mode', // Results in .dark-mode or .light-mode
|
||||||
|
storageKey: 'color-mode',
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
"wrangler": "^4.86.0"
|
"wrangler": "^4.86.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@nuxtjs/color-mode": "^4.0.0",
|
||||||
"prettier": "^3.8.3"
|
"prettier": "^3.8.3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user