Compare commits
16 Commits
0.8.13
...
71a6660c93
Author | SHA1 | Date | |
---|---|---|---|
71a6660c93
|
|||
d47d67572e | |||
fa4841948a
|
|||
71e2b0185b | |||
7f9fb4d2b9 | |||
8420c8dd58 | |||
fa6ed18edb | |||
30860fce1e | |||
b479e0e22c | |||
cf01ebcd3c | |||
df8ccf81c2
|
|||
073911c1b9 | |||
3eeea3dd8f | |||
43fea76778
|
|||
d64df6473a | |||
63a6a00817
|
@@ -1,35 +0,0 @@
|
|||||||
name: process-pull-requests
|
|
||||||
|
|
||||||
on:
|
|
||||||
schedule:
|
|
||||||
- cron: '@daily'
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
process-pull-requests:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Checkout Python Script
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
repository: alexlebens/workflow-scripts
|
|
||||||
ref: main
|
|
||||||
token: ${{ secrets.BOT_TOKEN }}
|
|
||||||
path: scripts
|
|
||||||
|
|
||||||
- name: Set up Python
|
|
||||||
uses: actions/setup-python@v5
|
|
||||||
with:
|
|
||||||
python-version: '3.13'
|
|
||||||
|
|
||||||
- name: Install dependencies
|
|
||||||
run: pip install requests
|
|
||||||
|
|
||||||
- name: Run Script
|
|
||||||
env:
|
|
||||||
INSTANCE_URL: ${{ vars.INSTANCE_URL }}
|
|
||||||
REPOSITORY: ${{ gitea.repository }}
|
|
||||||
TOKEN: ${{ secrets.BOT_TOKEN }}
|
|
||||||
STALE_DAYS: 3
|
|
||||||
STALE_TAG: 'stale'
|
|
||||||
REQUIRED_TAG: 'automerge'
|
|
||||||
run: python ./scripts/scripts/process-pull-requests.py
|
|
@@ -1,11 +1,11 @@
|
|||||||
name: process-issues
|
name: process-repository
|
||||||
|
|
||||||
on:
|
on:
|
||||||
schedule:
|
schedule:
|
||||||
- cron: '@daily'
|
- cron: "@daily"
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
process-issues:
|
process-repository:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout Python Script
|
- name: Checkout Python Script
|
||||||
@@ -14,22 +14,27 @@ jobs:
|
|||||||
repository: alexlebens/workflow-scripts
|
repository: alexlebens/workflow-scripts
|
||||||
ref: main
|
ref: main
|
||||||
token: ${{ secrets.BOT_TOKEN }}
|
token: ${{ secrets.BOT_TOKEN }}
|
||||||
path: scripts
|
path: workflow-scripts
|
||||||
|
|
||||||
- name: Set up Python
|
- name: Set up Python
|
||||||
uses: actions/setup-python@v5
|
uses: actions/setup-python@v5
|
||||||
with:
|
with:
|
||||||
python-version: '3.13'
|
python-version: "3.13"
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: pip install requests
|
run: pip install requests immutabledict
|
||||||
|
|
||||||
- name: Run Script
|
- name: Run Script
|
||||||
env:
|
env:
|
||||||
INSTANCE_URL: ${{ vars.INSTANCE_URL }}
|
INSTANCE_URL: ${{ vars.INSTANCE_URL }}
|
||||||
|
OWNER: ${{ gitea.owner }}
|
||||||
REPOSITORY: ${{ gitea.repository }}
|
REPOSITORY: ${{ gitea.repository }}
|
||||||
TOKEN: ${{ secrets.BOT_TOKEN }}
|
TOKEN: ${{ secrets.BOT_TOKEN }}
|
||||||
STALE_DAYS: 3
|
LOG_LEVEL: DEBUG
|
||||||
STALE_TAG: 'stale'
|
ISSUE_STALE_DAYS: 3
|
||||||
EXCLUDE_TAG: 'renovate'
|
ISSUE_STALE_TAG: 23
|
||||||
run: python ./scripts/scripts/process-issues.py
|
ISSUE_EXCLUDE_TAG: 17
|
||||||
|
PULL_REQUEST_STALE_DAYS: 3
|
||||||
|
PULL_REQUEST_STALE_TAG: 23
|
||||||
|
PULL_REQUEST_REQUIRED_TAG: 22
|
||||||
|
run: python ./workflow-scripts/process-repository.py
|
@@ -1,7 +1,7 @@
|
|||||||
ARG REGISTRY=docker.io
|
ARG REGISTRY=docker.io
|
||||||
FROM ${REGISTRY}/node:22.17.0-alpine3.22 AS base
|
FROM ${REGISTRY}/node:22.17.0-alpine3.22 AS base
|
||||||
|
|
||||||
LABEL version="0.8.13"
|
LABEL version="0.9.0"
|
||||||
LABEL description="Astro based personal website"
|
LABEL description="Astro based personal website"
|
||||||
|
|
||||||
ENV PNPM_HOME="/pnpm"
|
ENV PNPM_HOME="/pnpm"
|
||||||
|
@@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
Copyright (c) 2025 Lê Vĩnh Khang
|
Copyright (c) 2025 Lê Vĩnh Khang
|
||||||
|
|
||||||
|
Copyright (c) 2025 Alex Lebens
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
in the Software without restriction, including without limitation the rights
|
in the Software without restriction, including without limitation the rights
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "site-profile",
|
"name": "site-profile",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"version": "0.8.13",
|
"version": "0.9.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "astro dev",
|
"dev": "astro dev",
|
||||||
@@ -31,13 +31,13 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@tailwindcss/typography": "^0.5.16",
|
"@tailwindcss/typography": "^0.5.16",
|
||||||
"@typescript-eslint/parser": "8.36.0",
|
"@typescript-eslint/parser": "8.37.0",
|
||||||
"eslint": "9.30.1",
|
"eslint": "9.31.0",
|
||||||
"eslint-config-prettier": "10.1.5",
|
"eslint-config-prettier": "10.1.5",
|
||||||
"eslint-plugin-astro": "1.3.1",
|
"eslint-plugin-astro": "1.3.1",
|
||||||
"prettier": "^3.5.3",
|
"prettier": "^3.5.3",
|
||||||
"prettier-plugin-astro": "^0.14.1",
|
"prettier-plugin-astro": "^0.14.1",
|
||||||
"prettier-plugin-tailwindcss": "^0.6.12",
|
"prettier-plugin-tailwindcss": "^0.6.12",
|
||||||
"typescript-eslint": "8.36.0"
|
"typescript-eslint": "8.37.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
884
pnpm-lock.yaml
generated
884
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
38
src/components/DynamicIcon.tsx
Normal file
38
src/components/DynamicIcon.tsx
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import * as FaIcons from 'react-icons/fa';
|
||||||
|
import * as MdIcons from 'react-icons/md';
|
||||||
|
import * as AiIcons from 'react-icons/ai';
|
||||||
|
import * as GiIcons from 'react-icons/gi';
|
||||||
|
import * as IoIcons from 'react-icons/io';
|
||||||
|
import * as CiIcons from "react-icons/ci";
|
||||||
|
import * as FiIcons from "react-icons/fi";
|
||||||
|
import * as LuIcons from "react-icons/lu";
|
||||||
|
import * as SiIcons from 'react-icons/si';
|
||||||
|
|
||||||
|
const iconSets = {
|
||||||
|
fa: FaIcons,
|
||||||
|
md: MdIcons,
|
||||||
|
ai: AiIcons,
|
||||||
|
gi: GiIcons,
|
||||||
|
io: IoIcons,
|
||||||
|
ci: CiIcons,
|
||||||
|
fi: FiIcons,
|
||||||
|
lu: LuIcons,
|
||||||
|
si: SiIcons,
|
||||||
|
};
|
||||||
|
|
||||||
|
const DynamicIcon = ({ name, set = 'fa', size = 20, color = 'currentColor', className = '' }: {name: string, set: string, size: number, color: string, className: string }) => {
|
||||||
|
let IconComponent = FaIcons.FaAlignCenter;
|
||||||
|
|
||||||
|
if (name.startsWith("Fa")) {
|
||||||
|
IconComponent = iconSets["fa"][name]
|
||||||
|
} else if (name.startsWith("Si")) {
|
||||||
|
IconComponent = iconSets["si"][name]
|
||||||
|
} else {
|
||||||
|
IconComponent = iconSets[set][name];
|
||||||
|
}
|
||||||
|
|
||||||
|
return <IconComponent size={size} color={color} className={className} />;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default DynamicIcon;
|
@@ -1,7 +1,6 @@
|
|||||||
---
|
---
|
||||||
import BaseLayout from '../layouts/BaseLayout.astro';
|
import BaseLayout from '../layouts/BaseLayout.astro';
|
||||||
import { FaJs, FaReact, FaNodeJs, FaPython } from 'react-icons/fa';
|
import DynamicIcon from '../components/DynamicIcon.tsx';
|
||||||
import { SiTypescript, SiAstro } from 'react-icons/si';
|
|
||||||
|
|
||||||
import directus from '../../lib/directus';
|
import directus from '../../lib/directus';
|
||||||
import { readSingleton, readItems } from '@directus/sdk';
|
import { readSingleton, readItems } from '@directus/sdk';
|
||||||
@@ -107,7 +106,7 @@ const skills = await directus.request(
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Skills Section -->
|
<!-- Skills Section - Improved for mobile -->
|
||||||
<div class="theme-transition-all mb-16 sm:mb-20 md:mb-24">
|
<div class="theme-transition-all mb-16 sm:mb-20 md:mb-24">
|
||||||
<h2
|
<h2
|
||||||
class="theme-transition-color mb-8 text-center text-2xl font-bold text-zinc-900 sm:mb-12 sm:text-3xl dark:text-zinc-100"
|
class="theme-transition-color mb-8 text-center text-2xl font-bold text-zinc-900 sm:mb-12 sm:text-3xl dark:text-zinc-100"
|
||||||
@@ -119,13 +118,13 @@ const skills = await directus.request(
|
|||||||
<!-- Main slider container -->
|
<!-- Main slider container -->
|
||||||
<div class="slider-track animate-slide flex">
|
<div class="slider-track animate-slide flex">
|
||||||
{
|
{
|
||||||
skills.map((skill, index) => (
|
[...skills, ...skills, ...skills].map((skill) => (
|
||||||
<div class="skill-card theme-transition-element mx-2 min-w-[220px] transform rounded-xl border border-zinc-200 bg-white transition-all duration-300 hover:-translate-y-2 hover:scale-105 hover:border-zinc-300 hover:shadow-xl sm:mx-4 sm:min-w-[280px] dark:border-zinc-700 dark:bg-zinc-800/50 dark:hover:border-zinc-600">
|
<div class="skill-card theme-transition-element mx-2 min-w-[220px] transform rounded-xl border border-zinc-200 bg-white transition-all duration-300 hover:-translate-y-2 hover:scale-105 hover:border-zinc-300 hover:shadow-xl sm:mx-4 sm:min-w-[280px] dark:border-zinc-700 dark:bg-zinc-800/50 dark:hover:border-zinc-600">
|
||||||
<div class="p-4 sm:p-6">
|
<div class="p-4 sm:p-6">
|
||||||
<div class="mb-4 flex items-center justify-between sm:mb-6">
|
<div class="mb-4 flex items-center justify-between sm:mb-6">
|
||||||
<div class="flex items-center gap-2 sm:gap-4">
|
<div class="flex items-center gap-2 sm:gap-4">
|
||||||
<div class="theme-transition-bg theme-transition-color flex h-8 w-8 transform items-center justify-center rounded-lg bg-zinc-100 text-zinc-800 transition-transform group-hover:rotate-12 sm:h-12 sm:w-12 dark:bg-zinc-800 dark:text-zinc-200">
|
<div class="theme-transition-bg theme-transition-color flex h-8 w-8 transform items-center justify-center rounded-lg bg-zinc-100 text-zinc-800 transition-transform group-hover:rotate-12 sm:h-12 sm:w-12 dark:bg-zinc-800 dark:text-zinc-200">
|
||||||
<skill.icon />
|
<DynamicIcon name={skill.icon} />
|
||||||
</div>
|
</div>
|
||||||
<h3 class="theme-transition-color text-base font-semibold text-zinc-900 sm:text-xl dark:text-zinc-100">
|
<h3 class="theme-transition-color text-base font-semibold text-zinc-900 sm:text-xl dark:text-zinc-100">
|
||||||
{skill.title}
|
{skill.title}
|
||||||
|
@@ -1,6 +1,10 @@
|
|||||||
/* Remove all the complex mobile menu styles and keep only what's necessary */
|
/* Remove all the complex mobile menu styles and keep only what's necessary */
|
||||||
@import 'tailwindcss';
|
@import 'tailwindcss';
|
||||||
|
|
||||||
|
/* Dark mode support for Tailwind CSS v4 */
|
||||||
|
/* https://tailwindcss.com/docs/dark-mode */
|
||||||
|
@custom-variant dark (&:where(.dark, .dark *));
|
||||||
|
|
||||||
@layer base {
|
@layer base {
|
||||||
:root {
|
:root {
|
||||||
font-family: 'Inter', sans-serif;
|
font-family: 'Inter', sans-serif;
|
||||||
@@ -12,6 +16,7 @@
|
|||||||
html {
|
html {
|
||||||
scroll-behavior: smooth;
|
scroll-behavior: smooth;
|
||||||
scroll-padding-top: 5rem;
|
scroll-padding-top: 5rem;
|
||||||
|
overflow-y: scroll;
|
||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
|
@@ -3,6 +3,7 @@
|
|||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"lib": ["dom", "dom.iterable", "esnext"],
|
"lib": ["dom", "dom.iterable", "esnext"],
|
||||||
"allowJs": true,
|
"allowJs": true,
|
||||||
|
"allowImportingTsExtensions": true,
|
||||||
"target": "ES6",
|
"target": "ES6",
|
||||||
"skipLibCheck": true,
|
"skipLibCheck": true,
|
||||||
"strict": true,
|
"strict": true,
|
||||||
|
Reference in New Issue
Block a user