added skill badges
This commit is contained in:
@@ -1,14 +1,14 @@
|
||||
---
|
||||
import { array } from "astro/zod";
|
||||
|
||||
import SkillBadge from "./SkillBadge.astro";
|
||||
import type { SkillKey } from "../data/skills";
|
||||
interface Props {
|
||||
name: string;
|
||||
skills: SkillKey[];
|
||||
href?: string;
|
||||
gallery?: string | string[];
|
||||
center?: true;
|
||||
}
|
||||
|
||||
const { name, href, gallery, center } = Astro.props;
|
||||
const { name, href, gallery, center, skills } = Astro.props;
|
||||
---
|
||||
|
||||
<style lang="scss">
|
||||
@@ -32,16 +32,29 @@ const { name, href, gallery, center } = Astro.props;
|
||||
max-width: 40vw;
|
||||
transition: border-color 0.3s;
|
||||
.gallery {
|
||||
margin-top: -30px;
|
||||
margin: 15px;
|
||||
margin-top: -10px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
img {
|
||||
max-height: 250px;
|
||||
margin: 20px 10px;
|
||||
max-width: 100%;
|
||||
border-radius: 10px;
|
||||
transition: transform 0.3s;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
transform: scale(1.1);
|
||||
}
|
||||
|
||||
@media (max-width: $responsive-width) {
|
||||
max-height: 12vh !important;
|
||||
}
|
||||
}
|
||||
@media (max-width: $responsive-width) {
|
||||
.single {
|
||||
max-height: 17vh !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
h2 {
|
||||
@@ -56,47 +69,35 @@ const { name, href, gallery, center } = Astro.props;
|
||||
border: 1px solid lighten($highlight, 12%);
|
||||
}
|
||||
}
|
||||
@media (max-width: $responsive-width) {
|
||||
.gallery {
|
||||
margin-top: -4px;
|
||||
text-align: center;
|
||||
img {
|
||||
max-height: 15vh !important;
|
||||
}
|
||||
* {
|
||||
margin: 2px !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<script lang="ts"></script>
|
||||
|
||||
<div id="galary-zoom"><img id="zoom-image" /></div>
|
||||
|
||||
<div class={href ? "content" : "content no-hover"}>
|
||||
<a class="project-external" target={href ? "_blank" : ""} href={href}>
|
||||
<h2>{name}</h2><slot />
|
||||
<a>
|
||||
<div
|
||||
style={center ? "text-align: center;" : ""}
|
||||
class={gallery ? "gallery" : ""}
|
||||
>
|
||||
{
|
||||
Array.isArray(gallery) ? (
|
||||
gallery.map((src) => (
|
||||
<img onclick="maximizeImage(this)" loading="lazy" src={src} />
|
||||
))
|
||||
) : (
|
||||
<img
|
||||
class="single"
|
||||
onclick="maximizeImage(this)"
|
||||
loading="lazy"
|
||||
src={gallery as string}
|
||||
/>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
</a>
|
||||
<h2>{name}</h2><slot /><br />
|
||||
</a>
|
||||
<div style="margin-inline: 20px;">
|
||||
<b style="color: #fff;">Tools used:</b><br />
|
||||
{skills.map((skill: SkillKey) => <SkillBadge key={skill} />)}
|
||||
</div><br />
|
||||
<div
|
||||
style={center ? "text-align: center;" : ""}
|
||||
class={gallery ? "gallery" : ""}
|
||||
>
|
||||
{
|
||||
Array.isArray(gallery) ? (
|
||||
gallery.map((src) => (
|
||||
<img onclick="maximizeImage(this)" loading="lazy" src={src} />
|
||||
))
|
||||
) : (
|
||||
<img
|
||||
class="single"
|
||||
onclick="maximizeImage(this)"
|
||||
loading="lazy"
|
||||
src={gallery as string}
|
||||
/>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
56
src/components/SkillBadge.astro
Normal file
56
src/components/SkillBadge.astro
Normal file
@@ -0,0 +1,56 @@
|
||||
---
|
||||
import { Icon } from "astro-icon/components";
|
||||
import { skills } from "../data/skills";
|
||||
import type { SkillKey } from "../data/skills";
|
||||
interface Props {
|
||||
key: SkillKey;
|
||||
}
|
||||
const { key } = Astro.props;
|
||||
---
|
||||
|
||||
<style lang="scss">
|
||||
@import "../styles/_var.scss";
|
||||
.icon {
|
||||
color: white;
|
||||
margin-block: 10px;
|
||||
}
|
||||
.tooltip {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
&:hover {
|
||||
.tooltiptext {
|
||||
visibility: visible;
|
||||
}
|
||||
}
|
||||
.tooltiptext {
|
||||
visibility: hidden;
|
||||
background-color: $primary;
|
||||
text-align: center;
|
||||
padding: 5px 0;
|
||||
border-radius: 6px;
|
||||
border: 2px solid;
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
width: 120px;
|
||||
bottom: 85%;
|
||||
left: 50%;
|
||||
margin-left: -60px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="tooltip">
|
||||
<span style={"border-color:" + skills[key].color} class="tooltiptext"
|
||||
><a
|
||||
style={skills[key].url ? "" : "color: #fff"}
|
||||
href={skills[key].url}
|
||||
target={skills[key].url ? "_blank" : ""}>{key}</a
|
||||
></span
|
||||
>
|
||||
<Icon
|
||||
name={skills[key].iconName}
|
||||
size={25}
|
||||
class="icon"
|
||||
style={"color:" + skills[key].color}
|
||||
/>
|
||||
</div>
|
@@ -1,12 +1,4 @@
|
||||
type Skill = {
|
||||
[name: string]: {
|
||||
iconName: string
|
||||
url?: string
|
||||
color?: string
|
||||
}
|
||||
}
|
||||
|
||||
const skills: Skill = {
|
||||
const skilllist = {
|
||||
"React": {
|
||||
iconName: "mdi:react",
|
||||
url: "https://react.dev/",
|
||||
@@ -94,6 +86,7 @@ const skills: Skill = {
|
||||
},
|
||||
"Bun": {
|
||||
iconName: "logos:bun",
|
||||
color:"#FBF0DF",
|
||||
url: "https://bun.sh/"
|
||||
},
|
||||
"Blender": {
|
||||
@@ -121,6 +114,15 @@ const skills: Skill = {
|
||||
"Adobe Indesign": {
|
||||
iconName: "logos:adobe-indesign"
|
||||
}
|
||||
} as const;
|
||||
|
||||
type Skill = {
|
||||
iconName: string
|
||||
url?: string
|
||||
color?: string
|
||||
}
|
||||
|
||||
export { skills }
|
||||
type SkillKey = keyof typeof skilllist;
|
||||
const skills: Record<SkillKey, Skill> = skilllist
|
||||
export { skills }
|
||||
export type { SkillKey }
|
@@ -19,6 +19,20 @@ import GalaryZoom from "../components/GalaryZoom.astro";
|
||||
<GalaryZoom />
|
||||
<ProjectCard
|
||||
name="voicenext"
|
||||
skills={[
|
||||
"React",
|
||||
"TypeScript",
|
||||
"Tailwind",
|
||||
"Bun",
|
||||
"Capacitor.js",
|
||||
"Astro",
|
||||
"React Native",
|
||||
"Python",
|
||||
"Tauri",
|
||||
"Android",
|
||||
"iOS",
|
||||
"Git",
|
||||
]}
|
||||
center={true}
|
||||
gallery={[
|
||||
"/img/projects/voicenext/Promo.png",
|
||||
@@ -34,13 +48,24 @@ import GalaryZoom from "../components/GalaryZoom.astro";
|
||||
features that other messaging apps haven't considered because we are
|
||||
solely focused on audio.
|
||||
</ProjectCard>
|
||||
<ProjectCard name="SmartCustomerAI" gallery="/img/projects/sca.png"
|
||||
<ProjectCard
|
||||
name="SmartCustomerAI"
|
||||
skills={[
|
||||
"Vue",
|
||||
"TypeScript",
|
||||
"Bun",
|
||||
"OpenAI API",
|
||||
"Elevenlabs API",
|
||||
"Git",
|
||||
]}
|
||||
gallery="/img/projects/sca.png"
|
||||
>I am currently developing a program that can simulate customer calls.
|
||||
For this, I am using the Web Speech Recognition API, OpenAI, and
|
||||
Elevenlabs.
|
||||
</ProjectCard>
|
||||
<ProjectCard
|
||||
name="acecore"
|
||||
skills={["Go", "Python", "Git", "Linux"]}
|
||||
gallery="/img/projects/acecore.png"
|
||||
href="https://github.com/vaporvee/acecore"
|
||||
>Modular multi purpose bot powering your Discord server.<br />
|
||||
@@ -49,6 +74,7 @@ import GalaryZoom from "../components/GalaryZoom.astro";
|
||||
</ProjectCard>
|
||||
<ProjectCard
|
||||
name="DiscordRPC Godot Plugin"
|
||||
skills={["Godot", "C++", "Python", "Git", "Linux"]}
|
||||
gallery="/img/projects/discord-rpc.png"
|
||||
href="https://github.com/vaporvee/discord-rpc-godot"
|
||||
>The first Discord RPC plugin for the version 4 of the Godot game
|
||||
@@ -56,6 +82,7 @@ import GalaryZoom from "../components/GalaryZoom.astro";
|
||||
</ProjectCard>
|
||||
<ProjectCard
|
||||
name="Astro.js GitHub Component"
|
||||
skills={["TypeScript", "Astro", "Git"]}
|
||||
href="https://github.com/vaporvee/astro-github-component"
|
||||
>Adds a component to astro with statically built GitHub info and dynamic
|
||||
updated stars and forks. Supports GitHub auth tokens in the built
|
||||
|
@@ -8,6 +8,7 @@
|
||||
::selection {
|
||||
background-color: $accent;
|
||||
}
|
||||
|
||||
::marker {
|
||||
color: $accent;
|
||||
}
|
||||
@@ -43,6 +44,7 @@ main {
|
||||
padding: 20px;
|
||||
margin-bottom: 11vh;
|
||||
}
|
||||
|
||||
.second-content {
|
||||
align-self: center;
|
||||
text-align: center;
|
||||
@@ -52,7 +54,12 @@ main {
|
||||
border: 1px solid lighten($second-content-clr, 12%);
|
||||
min-width: 30vw;
|
||||
margin-inline: 10vw;
|
||||
p, ul,h1,h2,h3{
|
||||
|
||||
p,
|
||||
ul,
|
||||
h1,
|
||||
h2,
|
||||
h3 {
|
||||
padding-inline: 2vw;
|
||||
}
|
||||
}
|
||||
@@ -67,13 +74,16 @@ table {
|
||||
display: block;
|
||||
}
|
||||
|
||||
b, strong {
|
||||
b,
|
||||
strong {
|
||||
font-family: "Satoshi-Bold";
|
||||
color: $accent;
|
||||
}
|
||||
|
||||
a {
|
||||
color: $link;
|
||||
&[target="_blank"]::after{
|
||||
|
||||
&[target="_blank"]::after {
|
||||
display: inline-block;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
@@ -92,14 +102,17 @@ figure {
|
||||
|
||||
.expressive-code {
|
||||
border: 1px solid lighten(#282a36, 10%);
|
||||
|
||||
code {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
pre {
|
||||
background-color: transparent !important;
|
||||
border: transparent !important;
|
||||
background: none !important;
|
||||
}
|
||||
|
||||
.copy {
|
||||
button {
|
||||
width: 30px !important;
|
||||
@@ -109,6 +122,7 @@ figure {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
.copy {
|
||||
button {
|
||||
@@ -116,6 +130,7 @@ figure {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
& {
|
||||
position: relative;
|
||||
overflow: scroll;
|
||||
@@ -125,6 +140,7 @@ figure {
|
||||
background-color: #282a36;
|
||||
border-radius: 20px;
|
||||
}
|
||||
|
||||
.frame.is-terminal .header::before {
|
||||
background-color: gray !important;
|
||||
}
|
||||
@@ -164,6 +180,7 @@ button {
|
||||
background-color: $button-color;
|
||||
border: 1px solid lighten($button-color, 12%);
|
||||
font-size: 18px;
|
||||
|
||||
&:active {
|
||||
background-color: darken($button-color, 10);
|
||||
transform: translateY(1px);
|
||||
@@ -179,12 +196,13 @@ button {
|
||||
}
|
||||
|
||||
@media (max-width: $responsive-width) {
|
||||
.content{
|
||||
.content {
|
||||
min-width: 50vw !important;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: $responsive-width-secondary) {
|
||||
.content{
|
||||
.content {
|
||||
min-width: 85vw !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user