Compare commits
24 Commits
6156012c00
...
3.4.0
| Author | SHA1 | Date | |
|---|---|---|---|
| 8184d42942 | |||
| 04dfecc099 | |||
| ec10d45fd0 | |||
| ceb70c7049 | |||
| 4dbc5d12a3 | |||
| b55c3a0e31 | |||
| e63abf03ef | |||
| a7e7e5b0e8 | |||
| 96724d0016 | |||
| 30b2e980c0 | |||
| 113f42ca21 | |||
| 1f2820e4b4 | |||
| dc088306ce | |||
| f6c1cf1bf5 | |||
| 962f354208 | |||
| bf43212afc | |||
|
ef810efd24
|
|||
| b8379bbc38 | |||
| e2f5bbbe9c | |||
| f030da549e | |||
| 2fbc9a764f | |||
| 940342cc3f | |||
| 05d7ad6557 | |||
| 31621e4f7e |
@@ -3,7 +3,7 @@ name: release-image-gitea
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 2.*
|
||||
- 3.*
|
||||
|
||||
workflow_dispatch:
|
||||
|
||||
@@ -14,36 +14,34 @@ jobs:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Set up pnpm
|
||||
uses: pnpm/action-setup@v4
|
||||
- name: Set up Bun
|
||||
uses: oven-sh/setup-bun@v2
|
||||
with:
|
||||
version: 10.x
|
||||
bun-version: 1.3.10
|
||||
|
||||
- name: Set up Node.js
|
||||
- name: Set up Node
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: 24.14.0
|
||||
cache: pnpm
|
||||
|
||||
- name: Install Dependencies
|
||||
run: pnpm install --frozen-lockfile
|
||||
run: bun install --frozen-lockfile
|
||||
|
||||
- name: Cache Astro Build Cache
|
||||
uses: actions/cache@v5
|
||||
with:
|
||||
path: |
|
||||
node_modules/.cache
|
||||
.astro/cache
|
||||
key: ${{ runner.os }}-astro-cache-${{ hashFiles('**/pnpm-lock.yaml') }}-${{ github.sha }}
|
||||
.astro
|
||||
node_modules/.vite
|
||||
key: ${{ runner.os }}-astro-${{ hashFiles('**/*.astro', 'astro.config.mjs') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-astro-cache-${{ hashFiles('**/pnpm-lock.yaml') }}-
|
||||
${{ runner.os }}-astro-cache-
|
||||
${{ runner.os }}-astro-
|
||||
|
||||
- name: Lint Code
|
||||
run: pnpm lint
|
||||
run: bun run lint
|
||||
|
||||
- name: Build Project
|
||||
run: pnpm build
|
||||
run: bun run build
|
||||
|
||||
release:
|
||||
runs-on: ubuntu-js
|
||||
|
||||
@@ -3,7 +3,7 @@ name: release-image-harbor
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 2.*
|
||||
- 3.*
|
||||
|
||||
workflow_dispatch:
|
||||
|
||||
@@ -14,36 +14,34 @@ jobs:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Set up pnpm
|
||||
uses: pnpm/action-setup@v4
|
||||
- name: Set up Bun
|
||||
uses: oven-sh/setup-bun@v2
|
||||
with:
|
||||
version: 10.x
|
||||
bun-version: 1.3.10
|
||||
|
||||
- name: Set up Node.js
|
||||
- name: Set up Node
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: 24.14.0
|
||||
cache: pnpm
|
||||
|
||||
- name: Install Dependencies
|
||||
run: pnpm install --frozen-lockfile
|
||||
run: bun install --frozen-lockfile
|
||||
|
||||
- name: Cache Astro Build Cache
|
||||
uses: actions/cache@v5
|
||||
with:
|
||||
path: |
|
||||
node_modules/.cache
|
||||
.astro/cache
|
||||
key: ${{ runner.os }}-astro-cache-${{ hashFiles('**/pnpm-lock.yaml') }}-${{ github.sha }}
|
||||
.astro
|
||||
node_modules/.vite
|
||||
key: ${{ runner.os }}-astro-${{ hashFiles('**/*.astro', 'astro.config.mjs') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-astro-cache-${{ hashFiles('**/pnpm-lock.yaml') }}-
|
||||
${{ runner.os }}-astro-cache-
|
||||
${{ runner.os }}-astro-
|
||||
|
||||
- name: Lint Code
|
||||
run: pnpm lint
|
||||
run: bun run lint
|
||||
|
||||
- name: Build Project
|
||||
run: pnpm build
|
||||
run: bun run build
|
||||
|
||||
release:
|
||||
runs-on: ubuntu-js
|
||||
|
||||
@@ -16,36 +16,34 @@ jobs:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Set up pnpm
|
||||
uses: pnpm/action-setup@v4
|
||||
- name: Set up Bun
|
||||
uses: oven-sh/setup-bun@v2
|
||||
with:
|
||||
version: 10.x
|
||||
bun-version: 1.3.10
|
||||
|
||||
- name: Set up Node.js
|
||||
- name: Set up Node
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: 24.14.0
|
||||
cache: pnpm
|
||||
|
||||
- name: Install Dependencies
|
||||
run: pnpm install --frozen-lockfile
|
||||
run: bun install --frozen-lockfile
|
||||
|
||||
- name: Cache Astro Build Cache
|
||||
uses: actions/cache@v5
|
||||
with:
|
||||
path: |
|
||||
node_modules/.cache
|
||||
.astro/cache
|
||||
key: ${{ runner.os }}-astro-cache-${{ hashFiles('**/pnpm-lock.yaml') }}-${{ github.sha }}
|
||||
.astro
|
||||
node_modules/.vite
|
||||
key: ${{ runner.os }}-astro-${{ hashFiles('**/*.astro', 'astro.config.mjs') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-astro-cache-${{ hashFiles('**/pnpm-lock.yaml') }}-
|
||||
${{ runner.os }}-astro-cache-
|
||||
${{ runner.os }}-astro-
|
||||
|
||||
- name: Lint Code
|
||||
run: pnpm lint
|
||||
run: bun run lint
|
||||
|
||||
- name: Build Project
|
||||
run: pnpm build
|
||||
run: bun run build
|
||||
|
||||
- name: ntfy Failed
|
||||
uses: niniyas/ntfy-action@master
|
||||
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -10,8 +10,6 @@ node_modules/
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
|
||||
|
||||
# environment variables
|
||||
.env
|
||||
|
||||
3
.npmrc
3
.npmrc
@@ -1,3 +0,0 @@
|
||||
registry=https://registry.npmjs.org/
|
||||
engine-strict=true
|
||||
save-exact=true
|
||||
26
Dockerfile
26
Dockerfile
@@ -1,32 +1,30 @@
|
||||
FROM docker.io/node:24.14.0-alpine AS builder
|
||||
|
||||
ENV PNPM_HOME="/pnpm"
|
||||
ENV PATH="$PNPM_HOME:$PATH"
|
||||
RUN corepack enable
|
||||
|
||||
FROM dhi.io/bun:1.3.10-debian13-dev AS builder
|
||||
WORKDIR /app
|
||||
COPY package.json pnpm-lock.yaml ./
|
||||
|
||||
COPY package.json bun.lock ./
|
||||
|
||||
FROM builder AS prod-deps
|
||||
RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --prod --frozen-lockfile
|
||||
RUN --mount=type=cache,id=bun,target=/root/.bun/install/cache \
|
||||
bun install --production --frozen-lockfile
|
||||
|
||||
FROM prod-deps AS build-deps
|
||||
RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --frozen-lockfile
|
||||
FROM builder AS build-deps
|
||||
RUN --mount=type=cache,id=bun,target=/root/.bun/install/cache \
|
||||
bun install --frozen-lockfile
|
||||
|
||||
FROM build-deps AS build
|
||||
COPY . .
|
||||
RUN pnpm run build
|
||||
RUN bun run build
|
||||
|
||||
FROM dhi.io/node:24.14.0 AS runtime
|
||||
FROM dhi.io/bun:1.3.10-alpine3.22 AS runtime
|
||||
WORKDIR /app
|
||||
COPY --from=prod-deps /app/node_modules /app/node_modules
|
||||
COPY --from=build /app/dist /app/dist
|
||||
|
||||
LABEL version="2.25.0"
|
||||
LABEL version="3.3.0"
|
||||
LABEL description="Astro based personal website"
|
||||
|
||||
ENV HOST=0.0.0.0
|
||||
ENV PORT=4321
|
||||
|
||||
EXPOSE $PORT
|
||||
CMD ["node", "./dist/server/entry.mjs"]
|
||||
CMD ["bun", "run", "./dist/server/entry.mjs"]
|
||||
|
||||
@@ -7,9 +7,8 @@ Personal site used for information about myself and blog.
|
||||
|
||||
With dependencies installed, you can utilize the following npm scripts to manage your project's development lifecycle:
|
||||
|
||||
- `pnpm build`: Bundles your site into static files for production.
|
||||
- `pnpm dev`: Starts a local development server with hot reloading enabled.
|
||||
- `pnpm preview`: Serves your build output locally for preview before deployment.
|
||||
- `bun run build`: Bundles your site into static files for production.
|
||||
- `bun run dev`: Starts a local development server with hot reloading enabled.
|
||||
|
||||
For detailed help with Astro CLI commands, visit [Astro's documentation](https://docs.astro.build/en/reference/cli-reference/).
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { defineConfig } from 'astro/config';
|
||||
|
||||
import node from '@astrojs/node';
|
||||
import partytown from '@astrojs/partytown';
|
||||
import react from '@astrojs/react';
|
||||
import sitemap from '@astrojs/sitemap';
|
||||
|
||||
@@ -14,6 +13,8 @@ import { getSiteURL } from './src/support/url';
|
||||
export default defineConfig({
|
||||
site: getSiteURL(),
|
||||
|
||||
// security: { csp: true },
|
||||
|
||||
image: {
|
||||
remotePatterns: [
|
||||
{ protocol: 'https', hostname: '*.alexlebens.net' },
|
||||
@@ -28,7 +29,6 @@ export default defineConfig({
|
||||
prefetch: true,
|
||||
|
||||
integrations: [
|
||||
partytown(),
|
||||
react(),
|
||||
sitemap(),
|
||||
icon({
|
||||
|
||||
13
package.json
13
package.json
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "site-profile",
|
||||
"type": "module",
|
||||
"version": "2.25.0",
|
||||
"version": "3.3.0",
|
||||
"homepage": "https://www.alexlebens.dev",
|
||||
"bugs": {
|
||||
"url": "https://gitea.alexlebens.dev/alexlebens/site-profile/issues",
|
||||
@@ -28,9 +28,8 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@astrojs/check": "^0.9.7",
|
||||
"@astrojs/node": "^9.5.5",
|
||||
"@astrojs/partytown": "^2.1.5",
|
||||
"@astrojs/react": "^4.4.2",
|
||||
"@astrojs/node": "^10.0.0",
|
||||
"@astrojs/react": "^5.0.0",
|
||||
"@astrojs/rss": "^4.0.17",
|
||||
"@astrojs/sitemap": "^3.7.1",
|
||||
"@directus/sdk": "^21.2.0",
|
||||
@@ -44,9 +43,9 @@
|
||||
"@tailwindcss/vite": "^4.2.1",
|
||||
"@types/react": "^19.2.14",
|
||||
"@types/unist": "^3.0.3",
|
||||
"astro": "^5.18.1",
|
||||
"astro": "^6.0.2",
|
||||
"astro-icon": "^1.1.5",
|
||||
"markdown-it": "14.1.1",
|
||||
"markdown-it": "^14.1.1",
|
||||
"marked": "^17.0.4",
|
||||
"marked-shiki": "^1.2.1",
|
||||
"mdast-util-to-string": "^4.0.0",
|
||||
@@ -65,7 +64,7 @@
|
||||
"@eslint-react/eslint-plugin": "^2.13.0",
|
||||
"@tailwindcss/forms": "^0.5.11",
|
||||
"@tailwindcss/typography": "^0.5.19",
|
||||
"@types/markdown-it": "14.1.2",
|
||||
"@types/markdown-it": "^14.1.2",
|
||||
"eslint": "^10.0.3",
|
||||
"eslint-config-prettier": "^10.1.8",
|
||||
"eslint-plugin-astro": "^1.6.0",
|
||||
|
||||
12711
pnpm-lock.yaml
generated
12711
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -1,2 +0,0 @@
|
||||
onlyBuiltDependencies:
|
||||
- swup
|
||||
@@ -1,4 +0,0 @@
|
||||
User-agent: *
|
||||
Allow: /
|
||||
|
||||
Sitemap: https://www.alexlebens.dev/sitemap-index.xml
|
||||
@@ -10,7 +10,7 @@ const { dayName, label, icon, temp } = Astro.props;
|
||||
---
|
||||
|
||||
<div class="smooth-reveal-2 group flex flex-col">
|
||||
<div class="card-base w-32 md:w-40">
|
||||
<div class="card-base w-40">
|
||||
<div class="p-5 text-center">
|
||||
<span class="card-text-description block font-bold text-xs uppercase tracking-widest">
|
||||
{dayName}
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
---
|
||||
import { readItems, readSingleton } from '@directus/sdk';
|
||||
|
||||
import LargeCategoryCard from '@components/cards/LargeCategoryCard.astro';
|
||||
import directus from '@lib/directus';
|
||||
import { timeago } from '@support/time';
|
||||
|
||||
const global = await directus.request(readSingleton('site_global'));
|
||||
|
||||
const posts = await directus.request(
|
||||
readItems('posts', {
|
||||
filter: { published: { _eq: true } },
|
||||
fields: ['*'],
|
||||
sort: ['-published_date'],
|
||||
})
|
||||
);
|
||||
---
|
||||
|
||||
<section class:list={['mx-auto px-4 py-10 sm:px-6 lg:px-8 lg:py-14 lg:pt-10 2xl:max-w-full', Astro.props.className]}>
|
||||
<div class="grid grid-cols-1">
|
||||
<LargeCategoryCard
|
||||
title="All Posts"
|
||||
description="Here you can forgoe the organization and browse everything I've posted"
|
||||
url="/all"
|
||||
logoLight={global.all_logoLight}
|
||||
logoDark={global.all_logoDark}
|
||||
count={posts.length}
|
||||
publishDate={timeago(posts[0]?.published_date)}
|
||||
/>
|
||||
</div>
|
||||
</section>
|
||||
@@ -1,20 +0,0 @@
|
||||
---
|
||||
import { readSingleton } from '@directus/sdk';
|
||||
|
||||
import LargeLinkCard from '@components/cards/LargeLinkCard.astro';
|
||||
import directus from '@lib/directus';
|
||||
|
||||
const global = await directus.request(readSingleton('site_global'));
|
||||
---
|
||||
|
||||
<section class:list={['mx-auto px-4 pb-10 sm:px-6 lg:px-8 lg:pb-14 2xl:max-w-full', Astro.props.className]}>
|
||||
<div class="grid grid-cols-1">
|
||||
<LargeLinkCard
|
||||
title="All Posts"
|
||||
subTitle="Catch up on everything I've written so far here"
|
||||
url="/all"
|
||||
logoLight={global.all_logoLight}
|
||||
logoDark={global.all_logoDark}
|
||||
/>
|
||||
</div>
|
||||
</section>
|
||||
@@ -1,12 +1,15 @@
|
||||
---
|
||||
import { readItems } from '@directus/sdk';
|
||||
import { readItems, readSingleton } from '@directus/sdk';
|
||||
|
||||
import type { Post } from '@lib/directusTypes';
|
||||
|
||||
import CategoryCard from '@components/cards/CategoryCard.astro';
|
||||
import LargeCategoryCard from '@components/cards/LargeCategoryCard.astro';
|
||||
import directus from '@lib/directus';
|
||||
import { timeago } from '@support/time';
|
||||
|
||||
const global = await directus.request(readSingleton('site_global'));
|
||||
|
||||
const posts = await directus.request(
|
||||
readItems('posts', {
|
||||
filter: { published: { _eq: true } },
|
||||
@@ -95,5 +98,16 @@ const categories = (await directus.request(readItems('categories')))
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
<div class="col-span-full mt-8">
|
||||
<LargeCategoryCard
|
||||
title="All Posts"
|
||||
description="Here you can forgoe the organization and browse everything I've posted"
|
||||
url="/all"
|
||||
logoLight={global.all_logoLight}
|
||||
logoDark={global.all_logoDark}
|
||||
count={posts.length}
|
||||
publishDate={timeago(posts[0]?.published_date)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@@ -7,10 +7,10 @@ import directus from '@lib/directus';
|
||||
const global = await directus.request(readSingleton('site_global'));
|
||||
---
|
||||
|
||||
<section class="max-w-340 2xl:max-w-full px-4 sm:px-6 lg:px-8 py-10 lg:py-14 mx-auto mb-2 md:mb-8">
|
||||
<div class="flex flex-col sm:flex-row items-center justify-center gap-y-2 sm:gap-x-12 sm:gap-y-0 lg:gap-x-24">
|
||||
<div class="max-w-5xl sm:px-6 lg:px-8">
|
||||
<div class="flex flex-wrap gap-6 sm:grid-cols-2 sm:gap-6 lg:grid-cols-3 justify-center">
|
||||
<section class="max-w-340 2xl:max-w-full px-4 py-10 mx-auto mb-2 md:mb-8">
|
||||
<div class="flex items-center justify-center">
|
||||
<div class="max-w-5xl">
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 lg:gap-6">
|
||||
<FeaturesCard
|
||||
title="Cloud Engineer"
|
||||
description="Full stack and cloud engineer."
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
---
|
||||
import { readSingleton } from '@directus/sdk';
|
||||
|
||||
import type { Post } from '@lib/directusTypes';
|
||||
|
||||
import BlogCard from '@components/cards/BlogCard.astro';
|
||||
import LargeLinkCard from '@components/cards/LargeLinkCard.astro';
|
||||
import directus from '@lib/directus';
|
||||
|
||||
interface Props {
|
||||
posts: Post[];
|
||||
@@ -9,6 +13,8 @@ interface Props {
|
||||
subTitle?: string;
|
||||
}
|
||||
|
||||
const global = await directus.request(readSingleton('site_global'));
|
||||
|
||||
const { posts, title, subTitle } = Astro.props;
|
||||
---
|
||||
|
||||
@@ -27,5 +33,14 @@ const { posts, title, subTitle } = Astro.props;
|
||||
{posts.map((b) =>
|
||||
<BlogCard post={b} />
|
||||
)}
|
||||
<div class="col-span-full">
|
||||
<LargeLinkCard
|
||||
title="All Posts"
|
||||
subTitle="Catch up on everything I've written"
|
||||
url="/all"
|
||||
logoLight={global.all_logoLight}
|
||||
logoDark={global.all_logoDark}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@@ -24,13 +24,15 @@ const { forecastDays, error } = await getFiveDayForecast(latitude, longitude, ti
|
||||
</div>
|
||||
) : (
|
||||
<div class="flex flex-wrap justify-center gap-4 lg:gap-6">
|
||||
{forecastDays.map((forecastDay) => (
|
||||
<WeatherCard
|
||||
dayName={forecastDay.dayName}
|
||||
label={forecastDay.label}
|
||||
icon={forecastDay.icon}
|
||||
temp={forecastDay.temp}
|
||||
/>
|
||||
{forecastDays.map((forecastDay, index) => (
|
||||
<div class={index === 3 ? "hidden min-[800px]:block" : index >= 4 ? "hidden min-[1100px]:block" : ""}>
|
||||
<WeatherCard
|
||||
dayName={forecastDay.dayName}
|
||||
label={forecastDay.label}
|
||||
icon={forecastDay.icon}
|
||||
temp={forecastDay.temp}
|
||||
/>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -6,7 +6,6 @@ import type { Post } from '@lib/directusTypes';
|
||||
import HeroSection from '@components/sections/HeroSection.astro';
|
||||
import SelectedPostsSection from '@components/sections/SelectedPostsSection.astro';
|
||||
import RecentPostsSection from '@components/sections/RecentPostsSection.astro';
|
||||
import AllPostsSection from '@components/sections/AllPostsSection.astro';
|
||||
import BaseLayout from '@layouts/BaseLayout.astro';
|
||||
import directus from '@lib/directus';
|
||||
|
||||
@@ -57,8 +56,6 @@ const recentPosts: Post[] = posts.filter(
|
||||
title="Recent Posts"
|
||||
/>
|
||||
|
||||
<AllPostsSection />
|
||||
|
||||
</BaseLayout>
|
||||
|
||||
<script>
|
||||
|
||||
@@ -3,7 +3,6 @@ import { readSingleton } from '@directus/sdk';
|
||||
|
||||
import HeroSection from '@components/sections/HeroSection.astro';
|
||||
import CategorySection from '@components/sections/CategorySection.astro';
|
||||
import AllCategoriesSection from '@components/sections/AllCategoriesSection.astro';
|
||||
import BaseLayout from '@layouts/BaseLayout.astro';
|
||||
import directus from '@lib/directus';
|
||||
|
||||
@@ -37,8 +36,6 @@ const global = await directus.request(readSingleton('site_global'));
|
||||
|
||||
<CategorySection />
|
||||
|
||||
<AllCategoriesSection />
|
||||
|
||||
</BaseLayout>
|
||||
|
||||
<script>
|
||||
|
||||
@@ -7,7 +7,6 @@ import HeroSection from '@components/sections/HeroSection.astro';
|
||||
import FeatureSection from '@components/sections/FeatureSection.astro';
|
||||
import WeatherSection from '@components/sections/WeatherSection.astro';
|
||||
import RecentPostsSection from '@components/sections/RecentPostsSection.astro';
|
||||
import AllPostsSection from '@components/sections/AllPostsSection.astro';
|
||||
import GiteaSection from '@components/sections/GiteaSection.astro';
|
||||
import BaseLayout from '@layouts/BaseLayout.astro';
|
||||
import directus from '@lib/directus';
|
||||
@@ -70,8 +69,6 @@ const recentPosts = posts
|
||||
subTitle="Checkout my most recent thoughts here"
|
||||
/>
|
||||
|
||||
<AllPostsSection />
|
||||
|
||||
<GiteaSection
|
||||
title="Follow me on Gitea"
|
||||
subTitle="I love open source and have my code availabile on my Gitea server."
|
||||
|
||||
@@ -76,7 +76,7 @@
|
||||
@utility card-hover-icon-scale {
|
||||
@apply transition-transform duration-300 will-change-transform
|
||||
drop-shadow-md dark:drop-shadow-xl dark:drop-shadow-neutral-500/60
|
||||
group-hover:scale-3d group-hover:scale-110
|
||||
group-hover:scale-3d group-hover:scale-105
|
||||
}
|
||||
|
||||
@utility card-text-header {
|
||||
|
||||
Reference in New Issue
Block a user