Binary file not shown.
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 13 KiB |
@@ -0,0 +1,34 @@
|
|||||||
|
import { NextRequest, NextResponse } from "next/server";
|
||||||
|
|
||||||
|
export async function GET(req: NextRequest) {
|
||||||
|
const username = "kleo-dev";
|
||||||
|
const token = process.env.GITHUB_TOKEN;
|
||||||
|
|
||||||
|
const query = `
|
||||||
|
query {
|
||||||
|
user(login: "${username}") {
|
||||||
|
contributionsCollection {
|
||||||
|
contributionCalendar {
|
||||||
|
totalContributions
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const response = await fetch("https://api.github.com/graphql", {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
Authorization: `Bearer ${token}`,
|
||||||
|
},
|
||||||
|
body: JSON.stringify({ query }),
|
||||||
|
});
|
||||||
|
|
||||||
|
const data = await response.json();
|
||||||
|
const total =
|
||||||
|
data.data.user.contributionsCollection.contributionCalendar
|
||||||
|
.totalContributions;
|
||||||
|
|
||||||
|
return NextResponse.json({ total }, { status: 200 });
|
||||||
|
}
|
||||||
+1
-3
@@ -17,9 +17,7 @@ export default function RootLayout({
|
|||||||
<html lang="en">
|
<html lang="en">
|
||||||
<body className="antialiased bg-black">
|
<body className="antialiased bg-black">
|
||||||
<Background>
|
<Background>
|
||||||
<div className="relative h-screen overflow-y-scroll">
|
<div className="relative h-screen overflow-y-scroll">{children}</div>
|
||||||
{children}
|
|
||||||
</div>
|
|
||||||
</Background>
|
</Background>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
+56
-16
@@ -1,3 +1,5 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
import PinnedRepos from "@/components/PinnedRepos";
|
import PinnedRepos from "@/components/PinnedRepos";
|
||||||
import Skill from "@/components/Skill";
|
import Skill from "@/components/Skill";
|
||||||
import {
|
import {
|
||||||
@@ -12,20 +14,33 @@ import {
|
|||||||
} from "@fortawesome/free-brands-svg-icons";
|
} from "@fortawesome/free-brands-svg-icons";
|
||||||
import { faJava } from "@fortawesome/free-brands-svg-icons/faJava";
|
import { faJava } from "@fortawesome/free-brands-svg-icons/faJava";
|
||||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
import GitHubCalendar from "react-github-calendar";
|
import GitHubCalendar from "react-github-calendar";
|
||||||
|
|
||||||
export default function App() {
|
export default function App() {
|
||||||
|
const [contribs, setContribs] = useState<number>();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const fetchContributions = async () => {
|
||||||
|
const res = await fetch("/api/contribs");
|
||||||
|
const data = await res.json();
|
||||||
|
console.log("Total contributions:", data.total);
|
||||||
|
setContribs(data.total || undefined);
|
||||||
|
};
|
||||||
|
fetchContributions();
|
||||||
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div className="content-center w-full lg:mx-auto pt-5 relative z-20 pb-10 animate-fadeIn">
|
<div className="content-center w-full lg:mx-auto pt-5 relative z-20 pb-5 animate-fadeIn">
|
||||||
<div className="w-full max-w-screen-lg mx-auto">
|
<div className="w-full max-w-screen-lg mx-auto">
|
||||||
<div className="px-8 md:px-10 lg:px-15 xl:px-24">
|
<div className="px-8 md:px-10 lg:px-15 xl:px-24">
|
||||||
<h1 className="py-2 text-gray-300">Hey, I'm Klesti! 👋🏻</h1>
|
<h1 className="py-2 text-gray-300">Hey, I'm Klesti! 👋🏻</h1>
|
||||||
<p className="font-semibold text-gray-300">
|
<p className="font-semibold text-gray-300">
|
||||||
A 15 year old Software Engineer from Tirane, Albania, with 6 years
|
A 15 year old Software Engineer from Tirane, Albania, with 6 years
|
||||||
of experience, specializing in full-stack web development, desktop
|
of experience, specializing in full-stack web development, desktop
|
||||||
applications, TUI apps, and hacking. I also have a deep interest in
|
applications, TUI apps, and hacking. I also have a deep interest
|
||||||
low-level programming.
|
in low-level programming.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
{/* Socials and skill */}
|
{/* Socials and skill */}
|
||||||
@@ -35,8 +50,7 @@ export default function App() {
|
|||||||
<a href="https://github.com/kleo-dev/" target="blank_">
|
<a href="https://github.com/kleo-dev/" target="blank_">
|
||||||
<FontAwesomeIcon
|
<FontAwesomeIcon
|
||||||
icon={faGithub}
|
icon={faGithub}
|
||||||
width={36}
|
className="text-slate-300 size-[2.3rem]"
|
||||||
className="text-red"
|
|
||||||
/>
|
/>
|
||||||
</a>
|
</a>
|
||||||
<a
|
<a
|
||||||
@@ -45,15 +59,16 @@ export default function App() {
|
|||||||
>
|
>
|
||||||
<FontAwesomeIcon
|
<FontAwesomeIcon
|
||||||
icon={faLinkedin}
|
icon={faLinkedin}
|
||||||
width={36}
|
className="text-slate-300 size-[2.3rem]"
|
||||||
className="text-red"
|
|
||||||
/>
|
/>
|
||||||
</a>
|
</a>
|
||||||
<a href="https://www.instagram.com/kleo.dev/" target="blank_">
|
<a
|
||||||
|
href="https://www.instagram.com/selimaj.dev/"
|
||||||
|
target="blank_"
|
||||||
|
>
|
||||||
<FontAwesomeIcon
|
<FontAwesomeIcon
|
||||||
icon={faInstagram}
|
icon={faInstagram}
|
||||||
width={36}
|
className="text-slate-300 size-[2.3rem]"
|
||||||
className="text-red"
|
|
||||||
/>
|
/>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
@@ -71,16 +86,41 @@ export default function App() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<h1 className="text-red-400">Pinned Projects</h1>
|
<h1 className="text-slate-300">Pinned Projects</h1>
|
||||||
<section className="">
|
<section className="">
|
||||||
<PinnedRepos />
|
<PinnedRepos />
|
||||||
</section>
|
</section>
|
||||||
<section className="mt-8">
|
<h2 className="text-slate-300 mt-7">
|
||||||
<GitHubCalendar username="kleo-dev" theme={{
|
{contribs || "Loading.."} contributions in the last year
|
||||||
light: ["#1a000f", "#5c001d", "#9f0030", "#d10045", "#f5304c"],
|
</h2>
|
||||||
dark: ["#1a000f", "#5c001d", "#9f0030", "#d10045", "#f5304c"],
|
<section className="mt-4">
|
||||||
}} />
|
<GitHubCalendar
|
||||||
|
hideTotalCount
|
||||||
|
username="kleo-dev"
|
||||||
|
theme={{
|
||||||
|
light: [
|
||||||
|
"rgba(255, 255, 255, 0.1)",
|
||||||
|
"rgba(255, 255, 255, 0.3)",
|
||||||
|
"rgba(255, 255, 255, 0.5)",
|
||||||
|
"rgba(255, 255, 255, 0.7)",
|
||||||
|
"rgba(255, 255, 255, 1)",
|
||||||
|
],
|
||||||
|
dark: [
|
||||||
|
"rgba(255, 255, 255, 0.1)",
|
||||||
|
"rgba(255, 255, 255, 0.3)",
|
||||||
|
"rgba(255, 255, 255, 0.5)",
|
||||||
|
"rgba(255, 255, 255, 0.7)",
|
||||||
|
"rgba(255, 255, 255, 1)",
|
||||||
|
],
|
||||||
|
}}
|
||||||
|
/>
|
||||||
</section>
|
</section>
|
||||||
|
<footer className="mt-8 border-t pt-3">
|
||||||
|
If you see this i ❤️ you
|
||||||
|
<p className="text-slate-300 mx-auto w-max mt-2">
|
||||||
|
© 2025 Klesti. All rights reserved.
|
||||||
|
</p>
|
||||||
|
</footer>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+54
-163
@@ -1,4 +1,4 @@
|
|||||||
'use client';
|
"use client";
|
||||||
|
|
||||||
import React, { useEffect, useRef, useState } from "react";
|
import React, { useEffect, useRef, useState } from "react";
|
||||||
|
|
||||||
@@ -7,183 +7,74 @@ export default function Background({
|
|||||||
}: Readonly<{
|
}: Readonly<{
|
||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
}>) {
|
}>) {
|
||||||
const canvasRef = useRef<HTMLCanvasElement | null>(null);
|
const [pos, setPos] = useState({ x: 30, y: 100 });
|
||||||
const animationRef = useRef<number>(0);
|
const [vel, setVel] = useState({ x: 1, y: 1 });
|
||||||
const particlesRef = useRef<Particle[]>([]);
|
|
||||||
const [dimensions, setDimensions] = useState<{ width: number; height: number }>({
|
|
||||||
width: 0,
|
|
||||||
height: 0,
|
|
||||||
});
|
|
||||||
|
|
||||||
// Particle configuration
|
useEffect(() => {
|
||||||
const config = {
|
let frame: number;
|
||||||
particleCount: 400,
|
let x = pos.x;
|
||||||
maxDistance: 120,
|
let y = pos.y;
|
||||||
particleSpeed: 0.5,
|
let vx = vel.x;
|
||||||
particleSize: 2,
|
let vy = vel.y;
|
||||||
lineOpacity: 0.6,
|
|
||||||
particleOpacity: 0.8,
|
const speed = 0.5;
|
||||||
colors: {
|
const size = 100;
|
||||||
particles: "#f5304c", // blue-400
|
|
||||||
connections: "#f5304c", // blue-500
|
// helper for collision detection
|
||||||
},
|
const detectCollision = (
|
||||||
|
nextX: number,
|
||||||
|
nextY: number,
|
||||||
|
w: number,
|
||||||
|
h: number
|
||||||
|
) => {
|
||||||
|
let collidedX = false;
|
||||||
|
let collidedY = false;
|
||||||
|
|
||||||
|
// Left or Right wall
|
||||||
|
if (nextX <= 0 || nextX + size >= w) collidedX = true;
|
||||||
|
|
||||||
|
// Top or Bottom wall
|
||||||
|
if (nextY <= 0 || nextY + size >= h) collidedY = true;
|
||||||
|
|
||||||
|
return { collidedX, collidedY };
|
||||||
};
|
};
|
||||||
|
|
||||||
// Particle class
|
|
||||||
class Particle {
|
|
||||||
x: number;
|
|
||||||
y: number;
|
|
||||||
vx: number;
|
|
||||||
vy: number;
|
|
||||||
size: number;
|
|
||||||
|
|
||||||
constructor(width: number, height: number) {
|
|
||||||
this.x = Math.random() * width;
|
|
||||||
this.y = Math.random() * height;
|
|
||||||
this.vx = (Math.random() - 0.5) * config.particleSpeed;
|
|
||||||
this.vy = (Math.random() - 0.5) * config.particleSpeed;
|
|
||||||
this.size = config.particleSize + Math.random() * 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
update(width: number, height: number) {
|
|
||||||
this.x += this.vx;
|
|
||||||
this.y += this.vy;
|
|
||||||
|
|
||||||
// Bounce off edges
|
|
||||||
if (this.x < 0 || this.x > width) {
|
|
||||||
this.vx = -this.vx;
|
|
||||||
this.x = Math.max(0, Math.min(width, this.x));
|
|
||||||
}
|
|
||||||
if (this.y < 0 || this.y > height) {
|
|
||||||
this.vy = -this.vy;
|
|
||||||
this.y = Math.max(0, Math.min(height, this.y));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
draw(ctx: CanvasRenderingContext2D) {
|
|
||||||
ctx.beginPath();
|
|
||||||
ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2);
|
|
||||||
ctx.fillStyle = `${config.colors.particles}${Math.round(
|
|
||||||
config.particleOpacity * 255
|
|
||||||
)
|
|
||||||
.toString(16)
|
|
||||||
.padStart(2, "0")}`;
|
|
||||||
ctx.fill();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize particles
|
|
||||||
const initParticles = (width: number, height: number) => {
|
|
||||||
particlesRef.current = [];
|
|
||||||
for (let i = 0; i < config.particleCount; i++) {
|
|
||||||
particlesRef.current.push(new Particle(width, height));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Draw connections between nearby particles
|
|
||||||
const drawConnections = (ctx: CanvasRenderingContext2D, particles: Particle[]) => {
|
|
||||||
for (let i = 0; i < particles.length; i++) {
|
|
||||||
for (let j = i + 1; j < particles.length; j++) {
|
|
||||||
const dx = particles[i].x - particles[j].x;
|
|
||||||
const dy = particles[i].y - particles[j].y;
|
|
||||||
const distance = Math.sqrt(dx * dx + dy * dy);
|
|
||||||
|
|
||||||
if (distance < config.maxDistance) {
|
|
||||||
const opacity = 1 - distance / config.maxDistance;
|
|
||||||
ctx.beginPath();
|
|
||||||
ctx.moveTo(particles[i].x, particles[i].y);
|
|
||||||
ctx.lineTo(particles[j].x, particles[j].y);
|
|
||||||
ctx.strokeStyle = `${config.colors.connections}${Math.round(
|
|
||||||
opacity * config.lineOpacity * 255
|
|
||||||
)
|
|
||||||
.toString(16)
|
|
||||||
.padStart(2, "0")}`;
|
|
||||||
ctx.lineWidth = 1;
|
|
||||||
ctx.stroke();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Animation loop
|
|
||||||
const animate = () => {
|
const animate = () => {
|
||||||
const canvas = canvasRef.current;
|
const w = window.innerWidth;
|
||||||
if (!canvas) return;
|
const h = window.innerHeight;
|
||||||
|
|
||||||
const ctx = canvas.getContext("2d");
|
const nextX = x + vx * speed;
|
||||||
if (!ctx) return;
|
const nextY = y + vy * speed;
|
||||||
|
|
||||||
const { width, height } = dimensions;
|
const { collidedX, collidedY } = detectCollision(nextX, nextY, w, h);
|
||||||
|
|
||||||
// Clear canvas
|
if (collidedX) vx *= -1;
|
||||||
ctx.clearRect(0, 0, width, height);
|
if (collidedY) vy *= -1;
|
||||||
|
|
||||||
// Update and draw particles
|
x += vx * speed;
|
||||||
particlesRef.current.forEach((particle) => {
|
y += vy * speed;
|
||||||
particle.update(width, height);
|
|
||||||
particle.draw(ctx);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Draw connections
|
setPos({ x, y });
|
||||||
drawConnections(ctx, particlesRef.current);
|
setVel({ x: vx, y: vy });
|
||||||
|
|
||||||
animationRef.current = requestAnimationFrame(animate);
|
frame = requestAnimationFrame(animate);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Handle window resize
|
frame = requestAnimationFrame(animate);
|
||||||
const handleResize = () => {
|
return () => cancelAnimationFrame(frame);
|
||||||
const canvas = canvasRef.current;
|
|
||||||
if (!canvas || !canvas.parentElement) return;
|
|
||||||
|
|
||||||
const rect = canvas.parentElement.getBoundingClientRect();
|
|
||||||
const width = rect.width;
|
|
||||||
const height = rect.height;
|
|
||||||
|
|
||||||
const dpr = window.devicePixelRatio || 1;
|
|
||||||
canvas.width = width * dpr;
|
|
||||||
canvas.height = height * dpr;
|
|
||||||
canvas.style.width = `${width}px`;
|
|
||||||
canvas.style.height = `${height}px`;
|
|
||||||
|
|
||||||
const ctx = canvas.getContext("2d");
|
|
||||||
if (ctx) {
|
|
||||||
ctx.setTransform(1, 0, 0, 1, 0, 0); // reset scaling before re-scaling
|
|
||||||
ctx.scale(dpr, dpr);
|
|
||||||
}
|
|
||||||
|
|
||||||
setDimensions({ width, height });
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
handleResize();
|
|
||||||
window.addEventListener("resize", handleResize);
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
window.removeEventListener("resize", handleResize);
|
|
||||||
if (animationRef.current) {
|
|
||||||
cancelAnimationFrame(animationRef.current);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (dimensions.width && dimensions.height) {
|
|
||||||
initParticles(dimensions.width, dimensions.height);
|
|
||||||
animate();
|
|
||||||
}
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
if (animationRef.current) {
|
|
||||||
cancelAnimationFrame(animationRef.current);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}, [dimensions]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="relative w-full min-h-screen overflow-hidden bg-black">
|
<div className="relative w-full min-h-screen overflow-hidden bg-black">
|
||||||
<canvas ref={canvasRef} className="absolute inset-0 w-full h-full" />
|
<img
|
||||||
|
style={{
|
||||||
{children}
|
transform: `translate(${pos.x}px, ${pos.y}px)`,
|
||||||
|
}}
|
||||||
|
src="/logo.png"
|
||||||
|
alt="Logo"
|
||||||
|
className="size-24 rounded-full border-slate-500 border"
|
||||||
|
/>
|
||||||
|
<div className="relative z-10">{children}</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
}
|
||||||
|
|||||||
@@ -13,8 +13,8 @@ export default function Navbar() {
|
|||||||
<Link
|
<Link
|
||||||
href="/"
|
href="/"
|
||||||
className={
|
className={
|
||||||
"hover:text-red transition-colors duration-300" +
|
"hover:slate-200 transition-colors duration-300" +
|
||||||
(pathname === "/" ? " text-red" : "")
|
(pathname === "/" ? " slate-200" : "")
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
Home
|
Home
|
||||||
@@ -22,8 +22,8 @@ export default function Navbar() {
|
|||||||
<Link
|
<Link
|
||||||
href="/pricing"
|
href="/pricing"
|
||||||
className={
|
className={
|
||||||
"hover:text-red transition-colors duration-300" +
|
"hover:slate-200 transition-colors duration-300" +
|
||||||
(pathname === "/pricing" ? " text-red" : "")
|
(pathname === "/pricing" ? " slate-200" : "")
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
Pricing
|
Pricing
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
'use client';
|
"use client";
|
||||||
|
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
|
|
||||||
@@ -31,7 +31,7 @@ export function Repo({
|
|||||||
rounded-xl
|
rounded-xl
|
||||||
h-full
|
h-full
|
||||||
border
|
border
|
||||||
border-red
|
border-slate-300
|
||||||
hover:shadow-md
|
hover:shadow-md
|
||||||
transition-shadow
|
transition-shadow
|
||||||
duration-300
|
duration-300
|
||||||
@@ -41,7 +41,7 @@ export function Repo({
|
|||||||
<div className="w-full">
|
<div className="w-full">
|
||||||
<div className="rounded-xl border text-card-foreground shadow h-full bg-transparent border-none flex flex-col">
|
<div className="rounded-xl border text-card-foreground shadow h-full bg-transparent border-none flex flex-col">
|
||||||
<div className="flex flex-col space-y-1.5 p-6 flex-grow">
|
<div className="flex flex-col space-y-1.5 p-6 flex-grow">
|
||||||
<h3 className="tracking-tight text-base sm:text-lg font-semibold text-red-400">
|
<h3 className="tracking-tight text-base sm:text-lg font-semibold text-slate-300">
|
||||||
<a
|
<a
|
||||||
href={href}
|
href={href}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
@@ -73,7 +73,7 @@ export function Repo({
|
|||||||
strokeWidth="2"
|
strokeWidth="2"
|
||||||
strokeLinecap="round"
|
strokeLinecap="round"
|
||||||
strokeLinejoin="round"
|
strokeLinejoin="round"
|
||||||
className="lucide lucide-star text-yellow-500 h-3 w-3 sm:h-4 sm:w-4"
|
className="lucide lucide-star text-gray-300 h-3 w-3 sm:h-4 sm:w-4"
|
||||||
>
|
>
|
||||||
<polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2" />
|
<polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2" />
|
||||||
</svg>
|
</svg>
|
||||||
@@ -106,7 +106,7 @@ export function Repo({
|
|||||||
</div>
|
</div>
|
||||||
{lang && (
|
{lang && (
|
||||||
<div
|
<div
|
||||||
className="inline-flex items-center rounded-md border px-2.5 py-0.5 font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-foreground text-xs bg-red-600/10 border-red-600"
|
className="inline-flex items-center rounded-md border px-2.5 py-0.5 font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-foreground text-xs bg-slate-400/10 border-slate-400"
|
||||||
data-sentry-component="Badge"
|
data-sentry-component="Badge"
|
||||||
data-sentry-source-file="badge.tsx"
|
data-sentry-source-file="badge.tsx"
|
||||||
>
|
>
|
||||||
@@ -142,15 +142,19 @@ export default function PinnedRepos() {
|
|||||||
const [pinned, setPinned] = useState<PinnedRepo[]>([]);
|
const [pinned, setPinned] = useState<PinnedRepo[]>([]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetch("https://pinned.berrysauce.dev/get/kleo-dev").then(r => {
|
fetch("https://pinned.berrysauce.dev/get/kleo-dev")
|
||||||
r.json().then(p => {
|
.then((r) => {
|
||||||
|
r.json()
|
||||||
|
.then((p) => {
|
||||||
setPinned(p);
|
setPinned(p);
|
||||||
}).catch(e => {
|
|
||||||
console.error(e)
|
|
||||||
})
|
})
|
||||||
}).catch(e => {
|
.catch((e) => {
|
||||||
console.error(e)
|
console.error(e);
|
||||||
|
});
|
||||||
})
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
console.error(e);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -170,8 +174,6 @@ export default function PinnedRepos() {
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
return (
|
return <p>{e.toString()}</p>;
|
||||||
<p>{e.toString()}</p>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,13 +17,12 @@ export default function Skill({
|
|||||||
bg-black text-white text-sm px-2 py-1 rounded
|
bg-black text-white text-sm px-2 py-1 rounded
|
||||||
opacity-0 group-hover:opacity-100 transition-opacity duration-300 whitespace-nowrap"
|
opacity-0 group-hover:opacity-100 transition-opacity duration-300 whitespace-nowrap"
|
||||||
>
|
>
|
||||||
Skilled in {" "} {skill}
|
Skilled in {skill}
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<FontAwesomeIcon
|
<FontAwesomeIcon
|
||||||
icon={icon}
|
icon={icon}
|
||||||
width={40}
|
className={`text-gray-300 ${classInsert} size-[2.3rem]`}
|
||||||
className={`text-red ${classInsert} cursor-pointer`}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user