feat: init
This commit is contained in:
32
src/components/Card.astro
Normal file
32
src/components/Card.astro
Normal file
@@ -0,0 +1,32 @@
|
||||
---
|
||||
interface Props {
|
||||
url: string;
|
||||
image: string;
|
||||
title: string;
|
||||
body: string;
|
||||
}
|
||||
|
||||
const { url, image, title, body } = Astro.props;
|
||||
---
|
||||
|
||||
<li class="card">
|
||||
<a class="card__link" href={url}>
|
||||
<div class="center">
|
||||
<img
|
||||
class="card__img"
|
||||
src={image}
|
||||
role="presentation"
|
||||
width="226"
|
||||
height="127"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
<h3 class="card__title">
|
||||
{title}
|
||||
</h3>
|
||||
<p class="card__txt">
|
||||
{body}
|
||||
</p>
|
||||
</a>
|
||||
</li>
|
||||
29
src/components/CardPost.astro
Normal file
29
src/components/CardPost.astro
Normal file
@@ -0,0 +1,29 @@
|
||||
---
|
||||
interface Props {
|
||||
url: string;
|
||||
image: string;
|
||||
title: string;
|
||||
date: string;
|
||||
}
|
||||
|
||||
const { url, image, title, date } = Astro.props;
|
||||
---
|
||||
|
||||
<li class="card">
|
||||
<a class="card__link" href={url}>
|
||||
<div class="center">
|
||||
<img
|
||||
class="card__img"
|
||||
src={image}
|
||||
role="presentation"
|
||||
width="226"
|
||||
height="127"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
<h3 class="card__title">
|
||||
{title}
|
||||
</h3>
|
||||
</a>
|
||||
</li>
|
||||
14
src/components/Footer.astro
Normal file
14
src/components/Footer.astro
Normal file
@@ -0,0 +1,14 @@
|
||||
---
|
||||
const year = new Date().getFullYear();
|
||||
---
|
||||
<footer>
|
||||
<div class="center">
|
||||
<ul class="footer">
|
||||
<li class="icon__btn"><a class="icon__link" href="#" target="_blank"><span class="git-icon">GitHub</span></a></li>
|
||||
<li class="icon__btn"><a class="icon__link" href="mailto: #@gmail.com"><span class="mail-icon">Email</span></a></li>
|
||||
<li class="icon__btn"><a class="icon__link" href="#" target="_blank"><span class="linked-in">LinkedIn</span></a></li>
|
||||
</ul>
|
||||
<small>© {year} Milky-Way by <a class="footer__link" href="https://github.com/ttomczak3">ttomczak</a>. All Rights Reserved.</small>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
9
src/components/Header.astro
Normal file
9
src/components/Header.astro
Normal file
@@ -0,0 +1,9 @@
|
||||
---
|
||||
import Navigation from './Navigation.astro';
|
||||
---
|
||||
<header>
|
||||
<nav transition:persist >
|
||||
<Navigation />
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
15
src/components/Navigation.astro
Normal file
15
src/components/Navigation.astro
Normal file
@@ -0,0 +1,15 @@
|
||||
---
|
||||
import ThemeIcon from './ThemeIcon.astro';
|
||||
---
|
||||
<div class="navbar">
|
||||
<div class="navbar__title">
|
||||
<a href="/">Milky-Way</a>
|
||||
</div>
|
||||
<div class="navbar__menu">
|
||||
<a href="/works/">Works</a>
|
||||
<a href="/posts/">Posts</a>
|
||||
<a href="https://github.com/ttomczak3/Milky-Way" target="_blank">GitHub</a>
|
||||
<ThemeIcon />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
55
src/components/ThemeIcon.astro
Normal file
55
src/components/ThemeIcon.astro
Normal file
@@ -0,0 +1,55 @@
|
||||
---
|
||||
---
|
||||
<button id="themeToggle" title="Theme Toggle">
|
||||
<svg width="30px" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||
<path class="sun" fill-rule="evenodd" d="M12 17.5a5.5 5.5 0 1 0 0-11 5.5 5.5 0 0 0 0 11zm0 1.5a7 7 0 1 0 0-14 7 7 0 0 0 0 14zm12-7a.8.8 0 0 1-.8.8h-2.4a.8.8 0 0 1 0-1.6h2.4a.8.8 0 0 1 .8.8zM4 12a.8.8 0 0 1-.8.8H.8a.8.8 0 0 1 0-1.6h2.5a.8.8 0 0 1 .8.8zm16.5-8.5a.8.8 0 0 1 0 1l-1.8 1.8a.8.8 0 0 1-1-1l1.7-1.8a.8.8 0 0 1 1 0zM6.3 17.7a.8.8 0 0 1 0 1l-1.7 1.8a.8.8 0 1 1-1-1l1.7-1.8a.8.8 0 0 1 1 0zM12 0a.8.8 0 0 1 .8.8v2.5a.8.8 0 0 1-1.6 0V.8A.8.8 0 0 1 12 0zm0 20a.8.8 0 0 1 .8.8v2.4a.8.8 0 0 1-1.6 0v-2.4a.8.8 0 0 1 .8-.8zM3.5 3.5a.8.8 0 0 1 1 0l1.8 1.8a.8.8 0 1 1-1 1L3.5 4.6a.8.8 0 0 1 0-1zm14.2 14.2a.8.8 0 0 1 1 0l1.8 1.7a.8.8 0 0 1-1 1l-1.8-1.7a.8.8 0 0 1 0-1z"/>
|
||||
<path class="moon" fill-rule="evenodd" d="M16.5 6A10.5 10.5 0 0 1 4.7 16.4 8.5 8.5 0 1 0 16.4 4.7l.1 1.3zm-1.7-2a9 9 0 0 1 .2 2 9 9 0 0 1-11 8.8 9.4 9.4 0 0 1-.8-.3c-.4 0-.8.3-.7.7a10 10 0 0 0 .3.8 10 10 0 0 0 9.2 6 10 10 0 0 0 4-19.2 9.7 9.7 0 0 0-.9-.3c-.3-.1-.7.3-.6.7a9 9 0 0 1 .3.8z"/>
|
||||
</svg>
|
||||
</button>
|
||||
<style>
|
||||
#themeToggle {
|
||||
border: 0;
|
||||
background: none;
|
||||
}
|
||||
|
||||
#themeToggle:hover {
|
||||
cursor: pointer;
|
||||
rotate: 10deg;
|
||||
}
|
||||
|
||||
.moon { fill: #eff1f5; }
|
||||
.sun { fill: transparent; }
|
||||
|
||||
:global(.light) .moon { fill: transparent; }
|
||||
:global(.light) .sun { fill: #1e1e2e; }
|
||||
</style>
|
||||
<script is:inline >
|
||||
const theme = (() => {
|
||||
if (typeof localStorage !== 'undefined' && localStorage.getItem('theme')) {
|
||||
return localStorage.getItem('theme');
|
||||
}
|
||||
if (window.matchMedia('(prefers-color-scheme: light)').matches) {
|
||||
return 'light';
|
||||
}
|
||||
return 'dark';
|
||||
})();
|
||||
|
||||
if (theme === 'dark') {
|
||||
document.documentElement.classList.remove('light');
|
||||
} else {
|
||||
document.documentElement.classList.add('light');
|
||||
}
|
||||
|
||||
window.localStorage.setItem('theme', theme);
|
||||
|
||||
const handleToggleClick = () => {
|
||||
const element = document.documentElement;
|
||||
element.classList.toggle("light");
|
||||
|
||||
const isLight = element.classList.contains("light");
|
||||
localStorage.setItem("theme", isLight ? "light" : "dark");
|
||||
}
|
||||
|
||||
document.getElementById("themeToggle").addEventListener("click", handleToggleClick);
|
||||
</script>
|
||||
|
||||
45
src/content.config.ts
Normal file
45
src/content.config.ts
Normal file
@@ -0,0 +1,45 @@
|
||||
import { z, defineCollection } from "astro:content";
|
||||
import { glob } from 'astro/loaders';
|
||||
|
||||
const projectsCollection = defineCollection({
|
||||
loader: glob({ pattern: '**/[^_]*.{md,mdx}', base: "./src/content/projects" }),
|
||||
schema: z.object({
|
||||
title: z.string(),
|
||||
description: z.string(),
|
||||
image: z.object({
|
||||
url: z.string(),
|
||||
alt: z.string()
|
||||
}),
|
||||
worksImage1: z.object({
|
||||
url: z.string(),
|
||||
alt: z.string()
|
||||
}),
|
||||
worksImage2: z.object({
|
||||
url: z.string(),
|
||||
alt: z.string()
|
||||
}),
|
||||
platform: z.string(),
|
||||
stack: z.string(),
|
||||
website: z.string(),
|
||||
github: z.string(),
|
||||
})
|
||||
});
|
||||
|
||||
const postsCollection = defineCollection({
|
||||
loader: glob({ pattern: '**/[^_]*.{md,mdx}', base: "./src/content/posts" }),
|
||||
schema: z.object({
|
||||
title: z.string(),
|
||||
author: z.string(),
|
||||
date: z.string(),
|
||||
image: z.object({
|
||||
url: z.string(),
|
||||
alt: z.string()
|
||||
})
|
||||
})
|
||||
});
|
||||
|
||||
export const collections = {
|
||||
projects: projectsCollection,
|
||||
posts: postsCollection
|
||||
};
|
||||
|
||||
22
src/content/posts/post-1.md
Normal file
22
src/content/posts/post-1.md
Normal file
@@ -0,0 +1,22 @@
|
||||
---
|
||||
title: 'Post 1'
|
||||
author: Tristen Tomczak
|
||||
date: '03-23-2025'
|
||||
image:
|
||||
url: '/.netlify/images?url=/images/blog-post.webp'
|
||||
alt: 'Post Thumbnail'
|
||||
---
|
||||
|
||||
Aenean a ex et metus finibus malesuada commodo in magna. In ut libero urna. Aenean in quam in ipsum rutrum egestas. Donec semper dignissim ante. Sed efficitur mi et sapien ultrices malesuada. Aliquam fermentum aliquam ante, eu semper mi vestibulum quis. Sed et purus metus. Pellentesque vestibulum commodo euismod. Duis a mauris accumsan lorem laoreet tempor. Mauris accumsan varius metus, in rutrum magna accumsan eget. Pellentesque at leo at sem tempor hendrerit non sit amet ante. Cras commodo augue sed magna rutrum rutrum.
|
||||
|
||||
<div class="center">
|
||||
<img class="pro-img" src="/.netlify/images?url=/images/image-1.webp" alt="First Image" width="500px" height="281" loading="lazy" decoding="async">
|
||||
</div>
|
||||
|
||||
Vivamus sed faucibus lorem. Aenean a lorem convallis, ultrices nisl vitae, imperdiet elit. Duis in tristique lacus. Quisque sollicitudin dolor ac dui faucibus, ut tincidunt velit blandit. Donec tincidunt metus eros, at dignissim enim blandit ut. Cras varius tincidunt tortor ac tincidunt. Interdum et malesuada fames ac ante ipsum primis in faucibus. Sed a ipsum quis nulla commodo pretium. Ut sed sem bibendum, facilisis dolor sit amet, interdum nibh. Aliquam id auctor dolor. In nulla diam, mattis quis nisl et, aliquam interdum quam. Donec lobortis ex arcu, ac pharetra ante vehicula euismod. Donec finibus faucibus felis vitae facilisis.
|
||||
|
||||
<div class="center">
|
||||
<img class="pro-img" src="/.netlify/images?url=/images/image-2.webp" alt="Second Image" width="500px" height="281" loading="lazy" decoding="async">
|
||||
</div>
|
||||
|
||||
Vivamus sed faucibus lorem. Aenean a lorem convallis, ultrices nisl vitae, imperdiet elit. Duis in tristique lacus. Quisque sollicitudin dolor ac dui faucibus, ut tincidunt velit blandit. Donec tincidunt metus eros, at dignissim enim blandit ut. Cras varius tincidunt tortor ac tincidunt. Interdum et malesuada fames ac ante ipsum primis in faucibus. Sed a ipsum quis nulla commodo pretium. Ut sed sem bibendum, facilisis dolor sit amet, interdum nibh. Aliquam id auctor dolor. In nulla diam, mattis quis nisl et, aliquam interdum quam. Donec lobortis ex arcu, ac pharetra ante vehicula euismod. Donec finibus faucibus felis vitae facilisis.
|
||||
22
src/content/posts/post-2.md
Normal file
22
src/content/posts/post-2.md
Normal file
@@ -0,0 +1,22 @@
|
||||
---
|
||||
title: 'Post 2'
|
||||
author: Tristen Tomczak
|
||||
date: '03-23-2025'
|
||||
image:
|
||||
url: '/.netlify/images?url=/images/blog-post.webp'
|
||||
alt: 'Post Thumbnail'
|
||||
---
|
||||
|
||||
Aenean a ex et metus finibus malesuada commodo in magna. In ut libero urna. Aenean in quam in ipsum rutrum egestas. Donec semper dignissim ante. Sed efficitur mi et sapien ultrices malesuada. Aliquam fermentum aliquam ante, eu semper mi vestibulum quis. Sed et purus metus. Pellentesque vestibulum commodo euismod. Duis a mauris accumsan lorem laoreet tempor. Mauris accumsan varius metus, in rutrum magna accumsan eget. Pellentesque at leo at sem tempor hendrerit non sit amet ante. Cras commodo augue sed magna rutrum rutrum.
|
||||
|
||||
<div class="center">
|
||||
<img class="pro-img" src="/.netlify/images?url=/images/image-1.webp" alt="First Image" width="500px" height="281" loading="lazy" decoding="async">
|
||||
</div>
|
||||
|
||||
Vivamus sed faucibus lorem. Aenean a lorem convallis, ultrices nisl vitae, imperdiet elit. Duis in tristique lacus. Quisque sollicitudin dolor ac dui faucibus, ut tincidunt velit blandit. Donec tincidunt metus eros, at dignissim enim blandit ut. Cras varius tincidunt tortor ac tincidunt. Interdum et malesuada fames ac ante ipsum primis in faucibus. Sed a ipsum quis nulla commodo pretium. Ut sed sem bibendum, facilisis dolor sit amet, interdum nibh. Aliquam id auctor dolor. In nulla diam, mattis quis nisl et, aliquam interdum quam. Donec lobortis ex arcu, ac pharetra ante vehicula euismod. Donec finibus faucibus felis vitae facilisis.
|
||||
|
||||
<div class="center">
|
||||
<img class="pro-img" src="/.netlify/images?url=/images/image-2.webp" alt="Second Image" width="500px" height="281" loading="lazy" decoding="async">
|
||||
</div>
|
||||
|
||||
Vivamus sed faucibus lorem. Aenean a lorem convallis, ultrices nisl vitae, imperdiet elit. Duis in tristique lacus. Quisque sollicitudin dolor ac dui faucibus, ut tincidunt velit blandit. Donec tincidunt metus eros, at dignissim enim blandit ut. Cras varius tincidunt tortor ac tincidunt. Interdum et malesuada fames ac ante ipsum primis in faucibus. Sed a ipsum quis nulla commodo pretium. Ut sed sem bibendum, facilisis dolor sit amet, interdum nibh. Aliquam id auctor dolor. In nulla diam, mattis quis nisl et, aliquam interdum quam. Donec lobortis ex arcu, ac pharetra ante vehicula euismod. Donec finibus faucibus felis vitae facilisis.
|
||||
22
src/content/posts/post-3.md
Normal file
22
src/content/posts/post-3.md
Normal file
@@ -0,0 +1,22 @@
|
||||
---
|
||||
title: 'Post 3'
|
||||
author: Tristen Tomczak
|
||||
date: '03-23-2025'
|
||||
image:
|
||||
url: '/.netlify/images?url=/images/blog-post.webp'
|
||||
alt: 'Post Thumbnail'
|
||||
---
|
||||
|
||||
Aenean a ex et metus finibus malesuada commodo in magna. In ut libero urna. Aenean in quam in ipsum rutrum egestas. Donec semper dignissim ante. Sed efficitur mi et sapien ultrices malesuada. Aliquam fermentum aliquam ante, eu semper mi vestibulum quis. Sed et purus metus. Pellentesque vestibulum commodo euismod. Duis a mauris accumsan lorem laoreet tempor. Mauris accumsan varius metus, in rutrum magna accumsan eget. Pellentesque at leo at sem tempor hendrerit non sit amet ante. Cras commodo augue sed magna rutrum rutrum.
|
||||
|
||||
<div class="center">
|
||||
<img class="pro-img" src="/.netlify/images?url=/images/image-1.webp" alt="First Image" width="500px" height="281" loading="lazy" decoding="async">
|
||||
</div>
|
||||
|
||||
Vivamus sed faucibus lorem. Aenean a lorem convallis, ultrices nisl vitae, imperdiet elit. Duis in tristique lacus. Quisque sollicitudin dolor ac dui faucibus, ut tincidunt velit blandit. Donec tincidunt metus eros, at dignissim enim blandit ut. Cras varius tincidunt tortor ac tincidunt. Interdum et malesuada fames ac ante ipsum primis in faucibus. Sed a ipsum quis nulla commodo pretium. Ut sed sem bibendum, facilisis dolor sit amet, interdum nibh. Aliquam id auctor dolor. In nulla diam, mattis quis nisl et, aliquam interdum quam. Donec lobortis ex arcu, ac pharetra ante vehicula euismod. Donec finibus faucibus felis vitae facilisis.
|
||||
|
||||
<div class="center">
|
||||
<img class="pro-img" src="/.netlify/images?url=/images/image-2.webp" alt="Second Image" width="500px" height="281" loading="lazy" decoding="async">
|
||||
</div>
|
||||
|
||||
Vivamus sed faucibus lorem. Aenean a lorem convallis, ultrices nisl vitae, imperdiet elit. Duis in tristique lacus. Quisque sollicitudin dolor ac dui faucibus, ut tincidunt velit blandit. Donec tincidunt metus eros, at dignissim enim blandit ut. Cras varius tincidunt tortor ac tincidunt. Interdum et malesuada fames ac ante ipsum primis in faucibus. Sed a ipsum quis nulla commodo pretium. Ut sed sem bibendum, facilisis dolor sit amet, interdum nibh. Aliquam id auctor dolor. In nulla diam, mattis quis nisl et, aliquam interdum quam. Donec lobortis ex arcu, ac pharetra ante vehicula euismod. Donec finibus faucibus felis vitae facilisis.
|
||||
22
src/content/posts/post-4.md
Normal file
22
src/content/posts/post-4.md
Normal file
@@ -0,0 +1,22 @@
|
||||
---
|
||||
title: 'Post 4'
|
||||
author: Tristen Tomczak
|
||||
date: '03-23-2025'
|
||||
image:
|
||||
url: '/.netlify/images?url=/images/blog-post.webp'
|
||||
alt: 'Post Thumbnail'
|
||||
---
|
||||
|
||||
Aenean a ex et metus finibus malesuada commodo in magna. In ut libero urna. Aenean in quam in ipsum rutrum egestas. Donec semper dignissim ante. Sed efficitur mi et sapien ultrices malesuada. Aliquam fermentum aliquam ante, eu semper mi vestibulum quis. Sed et purus metus. Pellentesque vestibulum commodo euismod. Duis a mauris accumsan lorem laoreet tempor. Mauris accumsan varius metus, in rutrum magna accumsan eget. Pellentesque at leo at sem tempor hendrerit non sit amet ante. Cras commodo augue sed magna rutrum rutrum.
|
||||
|
||||
<div class="center">
|
||||
<img class="pro-img" src="/.netlify/images?url=/images/image-1.webp" alt="First Image" width="500px" height="281" loading="lazy" decoding="async">
|
||||
</div>
|
||||
|
||||
Vivamus sed faucibus lorem. Aenean a lorem convallis, ultrices nisl vitae, imperdiet elit. Duis in tristique lacus. Quisque sollicitudin dolor ac dui faucibus, ut tincidunt velit blandit. Donec tincidunt metus eros, at dignissim enim blandit ut. Cras varius tincidunt tortor ac tincidunt. Interdum et malesuada fames ac ante ipsum primis in faucibus. Sed a ipsum quis nulla commodo pretium. Ut sed sem bibendum, facilisis dolor sit amet, interdum nibh. Aliquam id auctor dolor. In nulla diam, mattis quis nisl et, aliquam interdum quam. Donec lobortis ex arcu, ac pharetra ante vehicula euismod. Donec finibus faucibus felis vitae facilisis.
|
||||
|
||||
<div class="center">
|
||||
<img class="pro-img" src="/.netlify/images?url=/images/image-2.webp" alt="Second Image" width="500px" height="281" loading="lazy" decoding="async">
|
||||
</div>
|
||||
|
||||
Vivamus sed faucibus lorem. Aenean a lorem convallis, ultrices nisl vitae, imperdiet elit. Duis in tristique lacus. Quisque sollicitudin dolor ac dui faucibus, ut tincidunt velit blandit. Donec tincidunt metus eros, at dignissim enim blandit ut. Cras varius tincidunt tortor ac tincidunt. Interdum et malesuada fames ac ante ipsum primis in faucibus. Sed a ipsum quis nulla commodo pretium. Ut sed sem bibendum, facilisis dolor sit amet, interdum nibh. Aliquam id auctor dolor. In nulla diam, mattis quis nisl et, aliquam interdum quam. Donec lobortis ex arcu, ac pharetra ante vehicula euismod. Donec finibus faucibus felis vitae facilisis.
|
||||
19
src/content/projects/project-1.md
Normal file
19
src/content/projects/project-1.md
Normal file
@@ -0,0 +1,19 @@
|
||||
---
|
||||
title: 'Project 1'
|
||||
description: 'Neque porro quisquam est qui dolorem ipsum quia dolor sit amet, consectetur, adipisci'
|
||||
image:
|
||||
url: '/.netlify/images?url=/images/GitHub.webp'
|
||||
alt: 'GitHub wallpaper'
|
||||
worksImage1:
|
||||
url: '/.netlify/images?url=/images/image-1.webp'
|
||||
alt: 'first image of your project.'
|
||||
worksImage2:
|
||||
url: '/.netlify/images?url=/images/image-2.webp'
|
||||
alt: 'second image of your project.'
|
||||
platform: Web
|
||||
stack: Astro, JavaScript
|
||||
website: https://astro-milky-way.netlify.app/
|
||||
github: https://github.com/ttomczak3/Milky-Way
|
||||
---
|
||||
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras faucibus a tortor at molestie. Sed pellentesque leo auctor, auctor lorem nec, venenatis risus. Vivamus commodo ipsum vitae orci finibus, vel porta nunc viverra. In hac habitasse platea dictumst. Nunc pretium, ligula ultricies consequat sollicitudin, enim ex ullamcorper nisl.
|
||||
19
src/content/projects/project-2.md
Normal file
19
src/content/projects/project-2.md
Normal file
@@ -0,0 +1,19 @@
|
||||
---
|
||||
title: 'Project 2'
|
||||
description: 'Neque porro quisquam est qui dolorem ipsum quia dolor sit amet, consectetur, adipisci'
|
||||
image:
|
||||
url: '/.netlify/images?url=/images/GitHub.webp'
|
||||
alt: 'GitHub wallpaper'
|
||||
worksImage1:
|
||||
url: '/.netlify/images?url=/images/image-1.webp'
|
||||
alt: 'first image of your project.'
|
||||
worksImage2:
|
||||
url: '/.netlify/images?url=/images/image-2.webp'
|
||||
alt: 'second image of your project.'
|
||||
platform: Web
|
||||
stack: Astro, JavaScript
|
||||
website: https://astro-milky-way.netlify.app/
|
||||
github: https://github.com/ttomczak3/Milky-Way
|
||||
---
|
||||
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras faucibus a tortor at molestie. Sed pellentesque leo auctor, auctor lorem nec, venenatis risus. Vivamus commodo ipsum vitae orci finibus, vel porta nunc viverra. In hac habitasse platea dictumst. Nunc pretium, ligula ultricies consequat sollicitudin, enim ex ullamcorper nisl.
|
||||
2
src/env.d.ts
vendored
Normal file
2
src/env.d.ts
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
/// <reference path="../.astro/types.d.ts" />
|
||||
/// <reference types="astro/client" />
|
||||
45
src/layouts/Layout.astro
Normal file
45
src/layouts/Layout.astro
Normal file
@@ -0,0 +1,45 @@
|
||||
---
|
||||
import Header from '../components/Header.astro';
|
||||
import Footer from '../components/Footer.astro';
|
||||
import '../styles/global.css';
|
||||
const { pageTitle } = Astro.props;
|
||||
---
|
||||
<!DOCTYPE html>
|
||||
<html transition:animate="none" lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="description" content="Astro description">
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link rel="preload" href="https://fonts.googleapis.com/css2?family=Josefin+Sans&family=Pacifico&display=swap" as="style">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Josefin+Sans&family=Pacifico&display=swap" rel="stylesheet">
|
||||
<meta name="generator" content={Astro.generator} />
|
||||
<title>{pageTitle}</title>
|
||||
</head>
|
||||
<body>
|
||||
<Header />
|
||||
<main>
|
||||
<slot />
|
||||
<Footer />
|
||||
</main>
|
||||
<script>
|
||||
function colorMode() {
|
||||
if (
|
||||
localStorage.theme === "light" ||
|
||||
(!("theme" in localStorage) &&
|
||||
window.matchMedia("(prefers-color-scheme: light)").matches)
|
||||
) {
|
||||
document.documentElement.classList.add("light");
|
||||
} else {
|
||||
document.documentElement.classList.remove("light");
|
||||
}
|
||||
}
|
||||
|
||||
colorMode();
|
||||
document.addEventListener('astro:after-swap', colorMode);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
20
src/layouts/MarkdownPostsLayout.astro
Normal file
20
src/layouts/MarkdownPostsLayout.astro
Normal file
@@ -0,0 +1,20 @@
|
||||
---
|
||||
import BaseLayout from "./Layout.astro";
|
||||
const { frontmatter } = Astro.props;
|
||||
---
|
||||
|
||||
<BaseLayout pageTitle={frontmatter.title}>
|
||||
<div class="gif">
|
||||
<img src="/.netlify/images?url=/images/blog.webp" role="presentation" width="300" height="259" decoding="async">
|
||||
</div>
|
||||
<h2 style="text-decoration:none;">{frontmatter.title}</h2>
|
||||
<ul class="badge__list">
|
||||
<li>
|
||||
<span class="badge badge--item">AUTHOR</span>{frontmatter.author}
|
||||
</li>
|
||||
<li>
|
||||
<span class="badge badge--item">PUBLISHED</span>{frontmatter.date}
|
||||
</li>
|
||||
</ul>
|
||||
<slot />
|
||||
</BaseLayout>
|
||||
22
src/layouts/MarkdownWorksLayout.astro
Normal file
22
src/layouts/MarkdownWorksLayout.astro
Normal file
@@ -0,0 +1,22 @@
|
||||
---
|
||||
import BaseLayout from './Layout.astro';
|
||||
const { frontmatter } = Astro.props;
|
||||
---
|
||||
<BaseLayout pageTitle={frontmatter.title}>
|
||||
<div class="gif">
|
||||
<img src="/.netlify/images?url=/images/laptop.webp" role="presentation" width="300" height="259" decoding="async">
|
||||
</div>
|
||||
<h2>{frontmatter.title}</h2>
|
||||
<slot />
|
||||
<ul class="badge__list">
|
||||
<li><span class="badge badge--item">PLATFORM</span>{frontmatter.platform}</li>
|
||||
<li><span class="badge badge--item">STACK</span>{frontmatter.stack}</li>
|
||||
<li><span class="badge badge--item">WEBSITE</span><a class="badge__link" href={frontmatter.website} target="_blank">{frontmatter.website}</a></li>
|
||||
<li><span class="badge badge--item">GITHUB</span><a class="badge__link" href={frontmatter.github} target="_blank">{frontmatter.github}</a></li>
|
||||
</ul>
|
||||
<div class="center">
|
||||
<img class="pro-img" width="500px" height="281" src={frontmatter.worksImage1.url} alt={frontmatter.worksImage1.alt} />
|
||||
<img class="pro-img" width="500px" height="281" src={frontmatter.worksImage2.url} alt={frontmatter.worksImage2.alt} />
|
||||
</div>
|
||||
</BaseLayout>
|
||||
|
||||
17
src/pages/404.astro
Normal file
17
src/pages/404.astro
Normal file
@@ -0,0 +1,17 @@
|
||||
---
|
||||
const description = "404";
|
||||
import '../styles/global.css';
|
||||
---
|
||||
<layout>
|
||||
<div class="lost">
|
||||
<div class="gif">
|
||||
<img src="/.netlify/images?url=/images/404.webp" role="presentation" width="300" height="259" decoding="async">
|
||||
</div>
|
||||
<h1 class="lost__header">{ description }</h1>
|
||||
<p class="lost__body">It seems like you've wandered into the wrong forest!</p>
|
||||
<p>
|
||||
<a class="lost__link" href="/">Return Home</a>
|
||||
</p>
|
||||
</div>
|
||||
</layout>
|
||||
|
||||
51
src/pages/index.astro
Normal file
51
src/pages/index.astro
Normal file
@@ -0,0 +1,51 @@
|
||||
---
|
||||
import Layout from '../layouts/Layout.astro';
|
||||
const pageTitle = "Milky-Way";
|
||||
---
|
||||
<Layout pageTitle={pageTitle}>
|
||||
<div class="gif">
|
||||
<img src="/.netlify/images?url=/images/space.webp" role="presentation" width="300" height="259" decoding="async">
|
||||
</div>
|
||||
<h1>Milky-Way</h1>
|
||||
<span class="badge">Digital Craftsman (Developer)</span>
|
||||
<h2>About</h2>
|
||||
<p>
|
||||
Praesent malesuada mi nisi, quis tempus magna venenatis ut.
|
||||
Suspendisse tempor sem at scelerisque congue. Curabitur mollis,
|
||||
mi id molestie finibus, metus sem sagittis nunc, euismod feugiat orci neque non lorem.
|
||||
Aenean sollicitudin erat eu molestie tempus. Nunc ac eros elementum, fermentum lacus at,
|
||||
pellentesque mauris. Suspendisse eros neque, interdum euismod consectetur convallis,
|
||||
porttitor at massa. Phasellus a ultrices arcu. Donec viverra, lorem in pellentesque euismod,
|
||||
libero justo gravida nibh, non ultricies justo purus ultrices est.
|
||||
</p>
|
||||
<p>
|
||||
Ut at interdum dui. Donec ut ante ex. Maecenas id ex eget nibh consequat accumsan.
|
||||
Proin semper semper dui nec feugiat. Donec cursus neque id aliquet finibus. Morbi
|
||||
facilisis turpis nibh, nec dictum orci dictum nec. In hac habitasse platea dictumst.
|
||||
Maecenas mollis turpis vitae turpis bibendum, vitae tristique arcu eleifend.
|
||||
</p>
|
||||
<div class="center">
|
||||
<a href="/works/">
|
||||
<button class="btn">My portfolio</button>
|
||||
</a>
|
||||
</div>
|
||||
<h2>Skills</h2>
|
||||
<div class="skills center">
|
||||
<img class="skills__img" width="46" height="46" alt="Python" src="https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/python/python-original.svg"/>
|
||||
<img class="skills__img" width="46" height="46" alt="Golang" src="https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/go/go-original-wordmark.svg"/>
|
||||
<img class="skills__img" width="46" height="46" alt="JavaScript" src="https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/javascript/javascript-original.svg"/>
|
||||
<img class="skills__img" width="46" height="46" alt="TypeScript" src="https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/typescript/typescript-original.svg"/>
|
||||
<img class="skills__img" width="46" height="46" alt="Docker" src="https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/docker/docker-original.svg"/>
|
||||
<img class="skills__img" width="46" height="46" alt="Linux" src="https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/linux/linux-original.svg"/>
|
||||
<img class="skills__img" width="46" height="46" alt="Kubernetes" src="https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/kubernetes/kubernetes-original.svg"/>
|
||||
<img class="skills__img" width="46" height="46" alt="Git" src="https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/git/git-original.svg"/>
|
||||
</div>
|
||||
<h2>Interests</h2>
|
||||
<p>
|
||||
Ut at interdum dui. Donec ut ante ex. Maecenas id ex eget nibh consequat accumsan.
|
||||
Proin semper semper dui nec feugiat. Donec cursus neque id aliquet finibus. Morbi
|
||||
facilisis turpis nibh, nec dictum orci dictum nec. In hac habitasse platea dictumst.
|
||||
Maecenas mollis turpis vitae turpis bibendum, vitae tristique arcu eleifend.
|
||||
</p>
|
||||
</Layout>
|
||||
|
||||
26
src/pages/posts.astro
Normal file
26
src/pages/posts.astro
Normal file
@@ -0,0 +1,26 @@
|
||||
---
|
||||
import { getCollection } from "astro:content";
|
||||
import Layout from "../layouts/Layout.astro";
|
||||
import Card from "../components/CardPost.astro";
|
||||
const allPosts = await getCollection("posts");
|
||||
const pageTitle = "Posts";
|
||||
---
|
||||
|
||||
<Layout pageTitle={pageTitle}>
|
||||
<div class="gif">
|
||||
<img src="/.netlify/images?url=/images/blog.webp" role="presentation" width="300" height="259" decoding="async">
|
||||
</div>
|
||||
<h2>Blog</h2>
|
||||
<ul role="list" class="link-card-grid">
|
||||
{
|
||||
allPosts.map((cardPost) => (
|
||||
<Card
|
||||
url={`/posts/${cardPost.id}/`}
|
||||
image={cardPost.data.image.url}
|
||||
title={cardPost.data.title}
|
||||
date={cardPost.data.date}
|
||||
/>
|
||||
))
|
||||
}
|
||||
</ul>
|
||||
</Layout>
|
||||
20
src/pages/posts/[...slug].astro
Normal file
20
src/pages/posts/[...slug].astro
Normal file
@@ -0,0 +1,20 @@
|
||||
---
|
||||
import { getCollection, getEntry, render } from "astro:content";
|
||||
import MarkdownPostsLayout from "../../layouts/MarkdownPostsLayout.astro";
|
||||
|
||||
export const prerender = true;
|
||||
export async function getStaticPaths() {
|
||||
const postEntries = await getCollection("posts");
|
||||
return postEntries.map((entry) => ({
|
||||
params: { slug: entry.id },
|
||||
props: { entry },
|
||||
}));
|
||||
}
|
||||
|
||||
const { entry } = Astro.props;
|
||||
const { Content, headings } = await render(entry);
|
||||
---
|
||||
|
||||
<MarkdownPostsLayout frontmatter={entry.data}>
|
||||
<Content />
|
||||
</MarkdownPostsLayout>
|
||||
20
src/pages/projects/[...slug].astro
Normal file
20
src/pages/projects/[...slug].astro
Normal file
@@ -0,0 +1,20 @@
|
||||
---
|
||||
import { getCollection, getEntry, render } from "astro:content";
|
||||
import MarkdownWorksLayout from "../../layouts/MarkdownWorksLayout.astro";
|
||||
|
||||
export const prerender = true;
|
||||
export async function getStaticPaths() {
|
||||
const projectEntries = await getCollection("projects");
|
||||
return projectEntries.map((entry) => ({
|
||||
params: { slug: entry.id },
|
||||
props: { entry },
|
||||
}));
|
||||
}
|
||||
|
||||
const { entry } = Astro.props;
|
||||
const { Content, headings } = await render(entry);
|
||||
---
|
||||
|
||||
<MarkdownWorksLayout frontmatter={entry.data}>
|
||||
<Content />
|
||||
</MarkdownWorksLayout>
|
||||
22
src/pages/works.astro
Normal file
22
src/pages/works.astro
Normal file
@@ -0,0 +1,22 @@
|
||||
---
|
||||
import { getCollection } from "astro:content";
|
||||
import Layout from '../layouts/Layout.astro';
|
||||
import Card from '../components/Card.astro';
|
||||
const allProjects = await getCollection("projects");
|
||||
const pageTitle = "Works";
|
||||
---
|
||||
<Layout pageTitle={pageTitle}>
|
||||
<div class="gif">
|
||||
<img src="/.netlify/images?url=/images/laptop.webp" role="presentation" width="300" height="259" decoding="async">
|
||||
</div>
|
||||
<h2>Projects</h2>
|
||||
<ul role="list" class="link-card-grid">
|
||||
{allProjects.map((card) => <Card
|
||||
url={`/projects/${card.id}/`}
|
||||
image={card.data.image.url}
|
||||
title={card.data.title}
|
||||
body={card.data.description}
|
||||
/>)}
|
||||
</ul>
|
||||
</Layout>
|
||||
|
||||
390
src/styles/global.css
Normal file
390
src/styles/global.css
Normal file
@@ -0,0 +1,390 @@
|
||||
/* Global styles */
|
||||
:root {
|
||||
--background: #1e1e2e;
|
||||
--background-light: #fcebf3;
|
||||
--button: #78c2ad;
|
||||
--text: #eff1f5;
|
||||
--text-light: #1e1e2e;
|
||||
--text-link: #78c2ad;
|
||||
--text-link-light: #375a7f;
|
||||
--underline: #375a7f;
|
||||
--header: 'Pacifico', cursive;
|
||||
--body: 'Josefin Sans', sans-serif;
|
||||
}
|
||||
|
||||
html {
|
||||
background-color: var(--background);
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
body {
|
||||
max-width: 540px;
|
||||
margin: 0 auto;
|
||||
text-align: justify;
|
||||
}
|
||||
|
||||
h1,
|
||||
h2 {
|
||||
font-family: var(--header);
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 2.6rem;
|
||||
margin: 0;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
h2 {
|
||||
text-decoration: underline var(--underline);
|
||||
text-decoration-thickness: 4px;
|
||||
text-underline-offset: 6px;
|
||||
font-size: 2.1rem;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
p {
|
||||
font-family: var(--body);
|
||||
font-size: 1.1rem;
|
||||
hyphens: auto;
|
||||
line-height: 1.5;
|
||||
text-indent: 1rem;
|
||||
}
|
||||
|
||||
small,
|
||||
li {
|
||||
font-family: var(--body);
|
||||
}
|
||||
|
||||
/* Navigation Bar */
|
||||
.navbar {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
margin-top: 0.8rem;
|
||||
}
|
||||
|
||||
.navbar__title {
|
||||
font-family: var(--header);
|
||||
font-size: 1.3rem;
|
||||
}
|
||||
|
||||
.navbar__menu {
|
||||
font-family: var(--body);
|
||||
font-size: 1.1rem;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.navbar__title>a,
|
||||
.navbar__menu>a {
|
||||
color: var(--text);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.navbar__menu>a {
|
||||
margin: 0 10px;
|
||||
}
|
||||
|
||||
.navbar__title>a:hover,
|
||||
.navbar__menu>a:hover,
|
||||
.navbar__menu>a:focus {
|
||||
text-decoration: underline var(--underline);
|
||||
text-decoration-thickness: 2px;
|
||||
text-underline-offset: 6px;
|
||||
}
|
||||
|
||||
/* Gifs */
|
||||
.gif {
|
||||
margin: 20px 0 0 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* Badge */
|
||||
.badge {
|
||||
background-color: #584966;
|
||||
color: var(--text);
|
||||
border-radius: 6px;
|
||||
font-family: var(--body);
|
||||
font-weight: 600;
|
||||
font-size: .85rem;
|
||||
padding: 0.3em 0.6em 0.2em;
|
||||
}
|
||||
|
||||
.badge__list {
|
||||
text-indent: 1rem;
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.badge__list>li {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.badge--item {
|
||||
border-radius: 4px;
|
||||
font-size: 0.7rem;
|
||||
margin-right: 5px;
|
||||
padding: 0.5em 0.3em 0.3em 0.3em;
|
||||
}
|
||||
|
||||
.badge__link {
|
||||
color: var(--text-link);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.badge__link:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
/* Cards */
|
||||
.card {
|
||||
list-style: none;
|
||||
display: flex;
|
||||
background-size: 400%;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.card__link {
|
||||
width: 100%;
|
||||
text-decoration: none;
|
||||
line-height: 1.4;
|
||||
border-radius: 8px;
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.card__img {
|
||||
border-radius: 16px;
|
||||
}
|
||||
|
||||
.card__title {
|
||||
margin: 0;
|
||||
font-family: var(--body);
|
||||
font-size: 1.5rem;
|
||||
font-weight: normal;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.card__txt {
|
||||
font-size: 1rem;
|
||||
line-height: 1.5;
|
||||
text-indent: 0;
|
||||
text-align: center;
|
||||
margin: 0.5rem 0 0;
|
||||
}
|
||||
|
||||
.card__link:hover {
|
||||
transform: scale(1.05);
|
||||
}
|
||||
|
||||
.link-card-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(24ch, 1fr));
|
||||
gap: 1rem;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/* Button */
|
||||
.btn {
|
||||
text-align: center;
|
||||
background: rgba(0, 0, 0, 0);
|
||||
border: 2px solid var(--button);
|
||||
border-radius: 8px;
|
||||
color: var(--text);
|
||||
font: 600 16px var(--body);
|
||||
padding: 8px 16px;
|
||||
transition: background-color 0.4s, color 0.4s;
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
background-color: var(--button);
|
||||
color: var(--text-light);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* Skills */
|
||||
.skills {
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.skills__img {
|
||||
margin: 8px 4px;
|
||||
}
|
||||
|
||||
/* Items */
|
||||
.center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.pro-img {
|
||||
border-radius: 16px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
/* Footer */
|
||||
footer {
|
||||
margin: 4rem 0;
|
||||
}
|
||||
|
||||
.footer__link {
|
||||
color: var(--text-link);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.footer {
|
||||
cursor: default;
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.icon__btn {
|
||||
display: inline-block;
|
||||
padding: 0 0.5rem;
|
||||
}
|
||||
|
||||
.icon__link {
|
||||
display: flex;
|
||||
padding: 10px;
|
||||
height: 20px;
|
||||
width: 20px;
|
||||
border-radius: 50%;
|
||||
border: 2px solid #fdebf3;
|
||||
}
|
||||
|
||||
.icon__link:hover {
|
||||
border-color: var(--text-link);
|
||||
}
|
||||
|
||||
.git-icon {
|
||||
content: url("/.netlify/images?url=/images/github-mark-white.svg");
|
||||
}
|
||||
|
||||
.mail-icon {
|
||||
content: url("/.netlify/images?url=/images/mail-white.svg");
|
||||
}
|
||||
|
||||
.linked-in {
|
||||
content: url("/.netlify/images?url=/images/li-in-white.png");
|
||||
}
|
||||
|
||||
/* 404 */
|
||||
.lost {
|
||||
margin-top: 30%;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.lost__header {
|
||||
margin: 0 auto;
|
||||
text-align: center;
|
||||
border: 0;
|
||||
font-size: 7.5rem;
|
||||
letter-spacing: 10px;
|
||||
}
|
||||
|
||||
.lost__body {
|
||||
color: #5C5B77;
|
||||
}
|
||||
|
||||
.lost__link {
|
||||
color: var(--text-link);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
/* Theme Icon */
|
||||
html.light {
|
||||
background-color: var(--background-light);
|
||||
color: var(--text-light);
|
||||
}
|
||||
|
||||
.light .navbar__title>a {
|
||||
color: var(--text-light);
|
||||
}
|
||||
|
||||
.light .navbar__menu>a {
|
||||
color: var(--text-light);
|
||||
}
|
||||
|
||||
.light .card__title {
|
||||
color: var(--text-light);
|
||||
}
|
||||
|
||||
.light .card__txt {
|
||||
color: var(--text-light);
|
||||
}
|
||||
|
||||
.light .btn {
|
||||
color: var(--text-light);
|
||||
}
|
||||
|
||||
.light .btn:hover {
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.light .icon__link {
|
||||
border: 2px solid var(--text-light);
|
||||
}
|
||||
|
||||
.light .icon__link:hover {
|
||||
border-color: var(--text-link);
|
||||
}
|
||||
|
||||
.light .git-icon {
|
||||
content: url("/.netlify/images?url=/images/github-mark.svg");
|
||||
}
|
||||
|
||||
.light .mail-icon {
|
||||
content: url("/.netlify/images?url=/images/mail.svg");
|
||||
}
|
||||
|
||||
.light .linked-in {
|
||||
content: url("/.netlify/images?url=/images/li-in.png");
|
||||
}
|
||||
|
||||
.light .badge__link {
|
||||
color: var(--text-link-light);
|
||||
}
|
||||
|
||||
.light .footer__link {
|
||||
color: var(--text-link-light);
|
||||
}
|
||||
|
||||
.light .icon__link:hover {
|
||||
border-color: var(--text-link-light);
|
||||
}
|
||||
|
||||
/* Media Query */
|
||||
@media only screen and (max-width: 600px) {
|
||||
body {
|
||||
width: 350px;
|
||||
}
|
||||
|
||||
.navbar {
|
||||
display: initial;
|
||||
}
|
||||
|
||||
.navbar__title {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.navbar__menu {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.navbar__menu>a {
|
||||
margin: 0 11px;
|
||||
}
|
||||
|
||||
.skills__img {
|
||||
height: 30px;
|
||||
width: 30px;
|
||||
margin: 8px 1px;
|
||||
}
|
||||
|
||||
.badge__list {
|
||||
font-size: 0.9rem;
|
||||
text-indent: 0;
|
||||
}
|
||||
|
||||
.pro-img {
|
||||
height: auto;
|
||||
width: 350px;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user