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