Re-worked icons
All checks were successful
Docker Deploy / build-and-push (push) Successful in 3m48s
All checks were successful
Docker Deploy / build-and-push (push) Successful in 3m48s
This commit is contained in:
@@ -3,7 +3,6 @@ import { defineConfig } from "astro/config";
|
||||
import tailwindcss from "@tailwindcss/vite";
|
||||
import vue from "@astrojs/vue";
|
||||
import node from "@astrojs/node";
|
||||
import icon from "astro-icon";
|
||||
import mdx from "@astrojs/mdx";
|
||||
|
||||
// https://astro.build/config
|
||||
@@ -30,47 +29,6 @@ export default defineConfig({
|
||||
integrations: [
|
||||
vue(),
|
||||
mdx(),
|
||||
icon({
|
||||
include: {
|
||||
mdi: [
|
||||
"clock",
|
||||
"tag",
|
||||
"arrow-right",
|
||||
"link",
|
||||
"email",
|
||||
"rss",
|
||||
"download",
|
||||
"web",
|
||||
"arrow-left",
|
||||
"source-commit",
|
||||
"code-tags",
|
||||
"tag-multiple",
|
||||
"clock-outline",
|
||||
"apple",
|
||||
"google-play",
|
||||
"code-braces",
|
||||
"circle",
|
||||
"open-in-new",
|
||||
],
|
||||
"simple-icons": [
|
||||
"gitea",
|
||||
"bluesky",
|
||||
"react",
|
||||
"vuedotjs",
|
||||
"typescript",
|
||||
"astro",
|
||||
"go",
|
||||
"postgresql",
|
||||
"dotnet",
|
||||
"docker",
|
||||
"github",
|
||||
"kotlin",
|
||||
"swift",
|
||||
"flutter",
|
||||
"nixos",
|
||||
],
|
||||
},
|
||||
}),
|
||||
],
|
||||
|
||||
adapter: node({
|
||||
|
||||
9771
package-lock.json
generated
Normal file
9771
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
14
package.json
14
package.json
@@ -10,28 +10,22 @@
|
||||
"nix": "nix develop"
|
||||
},
|
||||
"dependencies": {
|
||||
"@astrojs/mdx": "5.0.0-beta.5",
|
||||
"@astrojs/node": "10.0.0-beta.2",
|
||||
"@astrojs/mdx": "5.0.0-beta.7",
|
||||
"@astrojs/node": "10.0.0-beta.4",
|
||||
"@astrojs/rss": "4.0.15",
|
||||
"@astrojs/vue": "6.0.0-beta.0",
|
||||
"@astrojs/vue": "6.0.0-beta.1",
|
||||
"@iarna/toml": "^2.2.5",
|
||||
"@mdi/js": "^7.4.47",
|
||||
"@react-pdf/renderer": "^4.3.2",
|
||||
"@tailwindcss/typography": "^0.5.19",
|
||||
"@tailwindcss/vite": "^4.1.18",
|
||||
"astro": "6.0.0-beta.9",
|
||||
"astro-icon": "^1.1.5",
|
||||
"lucide-vue-next": "^0.563.0",
|
||||
"astro": "6.0.0-beta.11",
|
||||
"react": "^19.2.4",
|
||||
"sharp": "^0.34.5",
|
||||
"simple-icons": "^16.8.0",
|
||||
"tailwindcss": "^4.1.18",
|
||||
"vue": "^3.5.28"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@catppuccin/daisyui": "^2.1.1",
|
||||
"@iconify-json/mdi": "^1.2.3",
|
||||
"@iconify-json/simple-icons": "^1.2.70",
|
||||
"@types/react": "^19.2.14",
|
||||
"daisyui": "^5.5.18"
|
||||
}
|
||||
|
||||
891
pnpm-lock.yaml
generated
891
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
27
src/components/Icon.astro
Normal file
27
src/components/Icon.astro
Normal file
@@ -0,0 +1,27 @@
|
||||
---
|
||||
import { icons, type IconName } from "../config/icons";
|
||||
|
||||
interface Props {
|
||||
name: IconName;
|
||||
class?: string;
|
||||
"class:list"?: any;
|
||||
}
|
||||
|
||||
const { name, class: className, "class:list": classList } = Astro.props;
|
||||
const svg = icons[name];
|
||||
|
||||
if (!svg) {
|
||||
throw new Error(`Icon "${name}" not found in icon registry`);
|
||||
}
|
||||
---
|
||||
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
width="1em"
|
||||
height="1em"
|
||||
fill="none"
|
||||
class:list={[className, classList]}
|
||||
aria-hidden="true"
|
||||
set:html={svg}
|
||||
/>
|
||||
30
src/components/Icon.vue
Normal file
30
src/components/Icon.vue
Normal file
@@ -0,0 +1,30 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from "vue";
|
||||
import { icons, type IconName } from "../config/icons";
|
||||
|
||||
const props = defineProps<{
|
||||
name: IconName;
|
||||
class?: string;
|
||||
}>();
|
||||
|
||||
const svg = computed(() => {
|
||||
const content = icons[props.name];
|
||||
if (!content) {
|
||||
console.error(`Icon "${props.name}" not found in icon registry`);
|
||||
}
|
||||
return content;
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
width="1em"
|
||||
height="1em"
|
||||
fill="none"
|
||||
:class="props.class"
|
||||
aria-hidden="true"
|
||||
v-html="svg"
|
||||
/>
|
||||
</template>
|
||||
@@ -1,7 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, onMounted, onUnmounted } from "vue";
|
||||
import { config } from "../config";
|
||||
import type { Component } from "vue";
|
||||
import Icon from "./Icon.vue";
|
||||
|
||||
const props = defineProps<{
|
||||
currentPath: string;
|
||||
@@ -109,10 +109,9 @@ onUnmounted(() => {
|
||||
:data-tip="item.tooltip"
|
||||
data-astro-prefetch="hover"
|
||||
>
|
||||
<component
|
||||
:is="item.icon as Component"
|
||||
:size="18"
|
||||
class="sm:w-5 sm:h-5"
|
||||
<Icon
|
||||
:name="item.icon"
|
||||
class="w-[18px] h-[18px] sm:w-5 sm:h-5"
|
||||
/>
|
||||
<span class="sr-only">{{ item.name }}</span>
|
||||
</a>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, computed } from "vue";
|
||||
import { Settings, X } from "lucide-vue-next";
|
||||
import Icon from "./Icon.vue";
|
||||
|
||||
const tomlContent = ref("");
|
||||
const isGenerating = ref(false);
|
||||
@@ -162,7 +162,7 @@ const loadTemplate = async () => {
|
||||
:class="$attrs.class"
|
||||
aria-label="Resume Settings"
|
||||
>
|
||||
<Settings class="text-lg" />
|
||||
<Icon name="settings" class="text-lg" />
|
||||
</button>
|
||||
|
||||
<!-- Modal -->
|
||||
@@ -176,7 +176,7 @@ const loadTemplate = async () => {
|
||||
@click="closeModal"
|
||||
class="btn btn-circle btn-secondary hover:btn-primary"
|
||||
>
|
||||
<X class="text-lg" />
|
||||
<Icon name="x" class="text-lg" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted, onUnmounted } from "vue";
|
||||
import { ArrowUp } from "lucide-vue-next";
|
||||
import Icon from "./Icon.vue";
|
||||
|
||||
const isVisible = ref(false);
|
||||
let ticking = false;
|
||||
@@ -45,6 +45,6 @@ onUnmounted(() => {
|
||||
"
|
||||
aria-label="Scroll to top"
|
||||
>
|
||||
<ArrowUp class="text-lg" />
|
||||
<Icon name="arrow-up" class="text-lg" />
|
||||
</button>
|
||||
</template>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
import { Icon } from "astro-icon/components";
|
||||
import Icon from "./Icon.astro";
|
||||
import { config } from "../config";
|
||||
---
|
||||
|
||||
|
||||
@@ -1,29 +1,20 @@
|
||||
---
|
||||
import { Icon } from "astro-icon/components";
|
||||
import Icon from "./Icon.astro";
|
||||
import { config } from "../config";
|
||||
|
||||
function isAstroIcon(icon: any): icon is string {
|
||||
return typeof icon === "string";
|
||||
}
|
||||
---
|
||||
|
||||
<div class="flex flex-row gap-3 text-3xl flex-wrap justify-center">
|
||||
{
|
||||
config.techLinks.map((link) => {
|
||||
if (isAstroIcon(link.icon)) {
|
||||
return (
|
||||
<a
|
||||
href={link.url}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
aria-label={link.ariaLabel}
|
||||
class="hover:text-primary transition-colors"
|
||||
>
|
||||
<Icon name={link.icon} />
|
||||
</a>
|
||||
);
|
||||
}
|
||||
return null;
|
||||
})
|
||||
config.techLinks.map((link) => (
|
||||
<a
|
||||
href={link.url}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
aria-label={link.ariaLabel}
|
||||
class="hover:text-primary transition-colors"
|
||||
>
|
||||
<Icon name={link.icon} />
|
||||
</a>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
|
||||
@@ -1,27 +1,8 @@
|
||||
import type { Config } from "./types";
|
||||
|
||||
import { Home, Newspaper, FileUser, CodeXml, Megaphone } from "lucide-vue-next";
|
||||
|
||||
import logo from "./assets/logo.webp";
|
||||
import resumeToml from "./assets/resume.toml?raw";
|
||||
|
||||
// Astro Icon references
|
||||
const EMAIL_ICON = "mdi:email" as const;
|
||||
const RSS_ICON = "mdi:rss" as const;
|
||||
const GITEA_ICON = "simple-icons:gitea" as const;
|
||||
const BLUESKY_ICON = "simple-icons:bluesky" as const;
|
||||
const REACT_ICON = "simple-icons:react" as const;
|
||||
const VUEJS_ICON = "simple-icons:vuedotjs" as const;
|
||||
const TYPESCRIPT_ICON = "simple-icons:typescript" as const;
|
||||
const ASTRO_ICON = "simple-icons:astro" as const;
|
||||
const GO_ICON = "simple-icons:go" as const;
|
||||
const POSTGRESQL_ICON = "simple-icons:postgresql" as const;
|
||||
const DOTNET_ICON = "simple-icons:dotnet" as const;
|
||||
const DOCKER_ICON = "simple-icons:docker" as const;
|
||||
const KOTLIN_ICON = "simple-icons:kotlin" as const;
|
||||
const SWIFT_ICON = "simple-icons:swift" as const;
|
||||
const NIX_ICON = "simple-icons:nixos" as const;
|
||||
|
||||
export const config: Config = {
|
||||
personalInfo: {
|
||||
name: "Atridad Lahiji",
|
||||
@@ -281,28 +262,28 @@ export const config: Config = {
|
||||
id: "email",
|
||||
name: "Email",
|
||||
url: "mailto:me@atri.dad",
|
||||
icon: EMAIL_ICON,
|
||||
icon: "email",
|
||||
ariaLabel: "Email me",
|
||||
},
|
||||
{
|
||||
id: "rss",
|
||||
name: "RSS Feed",
|
||||
url: "/feed",
|
||||
icon: RSS_ICON,
|
||||
icon: "rss",
|
||||
ariaLabel: "RSS Feed",
|
||||
},
|
||||
{
|
||||
id: "gitea",
|
||||
name: "Forgejo (Git)",
|
||||
url: "https://git.atri.dad/atridad",
|
||||
icon: GITEA_ICON,
|
||||
icon: "gitea",
|
||||
ariaLabel: "Forgejo (Git)",
|
||||
},
|
||||
{
|
||||
id: "bluesky",
|
||||
name: "Bluesky",
|
||||
url: "https://bsky.app/profile/atri.dad",
|
||||
icon: BLUESKY_ICON,
|
||||
icon: "bluesky",
|
||||
ariaLabel: "Bluesky Profile",
|
||||
},
|
||||
],
|
||||
@@ -312,77 +293,77 @@ export const config: Config = {
|
||||
id: "react",
|
||||
name: "React",
|
||||
url: "https://react.dev/",
|
||||
icon: REACT_ICON,
|
||||
icon: "react",
|
||||
ariaLabel: "React",
|
||||
},
|
||||
{
|
||||
id: "vuejs",
|
||||
name: "Vue.js",
|
||||
url: "https://vuejs.org//",
|
||||
icon: VUEJS_ICON,
|
||||
icon: "vuedotjs",
|
||||
ariaLabel: "Vue.js",
|
||||
},
|
||||
{
|
||||
id: "typescript",
|
||||
name: "TypeScript",
|
||||
url: "https://www.typescriptlang.org/",
|
||||
icon: TYPESCRIPT_ICON,
|
||||
icon: "typescript",
|
||||
ariaLabel: "TypeScript",
|
||||
},
|
||||
{
|
||||
id: "astro",
|
||||
name: "Astro",
|
||||
url: "https://astro.build/",
|
||||
icon: ASTRO_ICON,
|
||||
icon: "astro",
|
||||
ariaLabel: "Astro",
|
||||
},
|
||||
{
|
||||
id: "go",
|
||||
name: "Go",
|
||||
url: "https://go.dev/",
|
||||
icon: GO_ICON,
|
||||
icon: "go",
|
||||
ariaLabel: "Go",
|
||||
},
|
||||
{
|
||||
id: "postgresql",
|
||||
name: "PostgreSQL",
|
||||
url: "https://www.postgresql.org/",
|
||||
icon: POSTGRESQL_ICON,
|
||||
icon: "postgresql",
|
||||
ariaLabel: "PostgreSQL",
|
||||
},
|
||||
{
|
||||
id: "dotnet",
|
||||
name: "DotNet",
|
||||
url: "https://dot.net/",
|
||||
icon: DOTNET_ICON,
|
||||
icon: "dotnet",
|
||||
ariaLabel: "DotNet",
|
||||
},
|
||||
{
|
||||
id: "docker",
|
||||
name: "Docker",
|
||||
url: "https://www.docker.com/",
|
||||
icon: DOCKER_ICON,
|
||||
icon: "docker",
|
||||
ariaLabel: "Docker",
|
||||
},
|
||||
{
|
||||
id: "kotlin",
|
||||
name: "Kotlin",
|
||||
url: "https://kotlinlang.org/",
|
||||
icon: KOTLIN_ICON,
|
||||
icon: "kotlin",
|
||||
ariaLabel: "Kotlin",
|
||||
},
|
||||
{
|
||||
id: "swift",
|
||||
name: "Swift",
|
||||
url: "https://www.swift.org/",
|
||||
icon: SWIFT_ICON,
|
||||
icon: "swift",
|
||||
ariaLabel: "Swift",
|
||||
},
|
||||
{
|
||||
id: "nix",
|
||||
name: "Nix",
|
||||
url: "https://nix.org",
|
||||
icon: NIX_ICON,
|
||||
icon: "nixos",
|
||||
ariaLabel: "Nix",
|
||||
},
|
||||
],
|
||||
@@ -393,7 +374,7 @@ export const config: Config = {
|
||||
name: "Home",
|
||||
path: "/",
|
||||
tooltip: "Home",
|
||||
icon: Home,
|
||||
icon: "house",
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
@@ -401,7 +382,7 @@ export const config: Config = {
|
||||
name: "Posts",
|
||||
path: "/posts",
|
||||
tooltip: "Posts",
|
||||
icon: Newspaper,
|
||||
icon: "newspaper",
|
||||
enabled: true,
|
||||
isActive: (path: string) =>
|
||||
path.startsWith("/posts") || path.startsWith("/post/"),
|
||||
@@ -411,7 +392,7 @@ export const config: Config = {
|
||||
name: "Resume",
|
||||
path: "/resume",
|
||||
tooltip: "Resume",
|
||||
icon: FileUser,
|
||||
icon: "file-user",
|
||||
enabled: !!(resumeToml && resumeToml.trim()),
|
||||
},
|
||||
{
|
||||
@@ -419,7 +400,7 @@ export const config: Config = {
|
||||
name: "Projects",
|
||||
path: "/projects",
|
||||
tooltip: "Projects",
|
||||
icon: CodeXml,
|
||||
icon: "code-xml",
|
||||
enabled: true,
|
||||
isActive: (path: string) => path.startsWith("/projects"),
|
||||
},
|
||||
@@ -428,7 +409,7 @@ export const config: Config = {
|
||||
name: "Talks",
|
||||
path: "/talks",
|
||||
tooltip: "Talks",
|
||||
icon: Megaphone,
|
||||
icon: "megaphone",
|
||||
enabled: true,
|
||||
isActive: (path: string) => path.startsWith("/talks"),
|
||||
},
|
||||
|
||||
57
src/config/icons.ts
Normal file
57
src/config/icons.ts
Normal file
@@ -0,0 +1,57 @@
|
||||
export const icons = {
|
||||
clock: `<path fill="currentColor" d="M12 2A10 10 0 0 0 2 12a10 10 0 0 0 10 10a10 10 0 0 0 10-10A10 10 0 0 0 12 2m4.2 14.2L11 13V7h1.5v5.2l4.5 2.7z"/>`,
|
||||
tag: `<path fill="currentColor" d="M5.5 7A1.5 1.5 0 0 1 4 5.5A1.5 1.5 0 0 1 5.5 4A1.5 1.5 0 0 1 7 5.5A1.5 1.5 0 0 1 5.5 7m15.91 4.58l-9-9C12.05 2.22 11.55 2 11 2H4c-1.11 0-2 .89-2 2v7c0 .55.22 1.05.59 1.41l8.99 9c.37.36.87.59 1.42.59s1.05-.23 1.41-.59l7-7c.37-.36.59-.86.59-1.41c0-.56-.23-1.06-.59-1.42"/>`,
|
||||
"arrow-right": `<path fill="currentColor" d="M4 11v2h12l-5.5 5.5l1.42 1.42L19.84 12l-7.92-7.92L10.5 5.5L16 11z"/>`,
|
||||
link: `<path fill="currentColor" d="M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7a5 5 0 0 0-5 5a5 5 0 0 0 5 5h4v-1.9H7c-1.71 0-3.1-1.39-3.1-3.1M8 13h8v-2H8zm9-6h-4v1.9h4c1.71 0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4a5 5 0 0 0 5-5a5 5 0 0 0-5-5"/>`,
|
||||
email: `<path fill="currentColor" d="m20 8l-8 5l-8-5V6l8 5l8-5m0-2H4c-1.11 0-2 .89-2 2v12a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V6a2 2 0 0 0-2-2"/>`,
|
||||
rss: `<path fill="currentColor" d="M6.18 15.64a2.18 2.18 0 0 1 2.18 2.18C8.36 19 7.38 20 6.18 20C5 20 4 19 4 17.82a2.18 2.18 0 0 1 2.18-2.18M4 4.44A15.56 15.56 0 0 1 19.56 20h-2.83A12.73 12.73 0 0 0 4 7.27zm0 5.66a9.9 9.9 0 0 1 9.9 9.9h-2.83A7.07 7.07 0 0 0 4 12.93z"/>`,
|
||||
download: `<path fill="currentColor" d="M5 20h14v-2H5m14-9h-4V3H9v6H5l7 7z"/>`,
|
||||
web: `<path fill="currentColor" d="M16.36 14c.08-.66.14-1.32.14-2s-.06-1.34-.14-2h3.38c.16.64.26 1.31.26 2s-.1 1.36-.26 2m-5.15 5.56c.6-1.11 1.06-2.31 1.38-3.56h2.95a8.03 8.03 0 0 1-4.33 3.56M14.34 14H9.66c-.1-.66-.16-1.32-.16-2s.06-1.35.16-2h4.68c.09.65.16 1.32.16 2s-.07 1.34-.16 2M12 19.96c-.83-1.2-1.5-2.53-1.91-3.96h3.82c-.41 1.43-1.08 2.76-1.91 3.96M8 8H5.08A7.92 7.92 0 0 1 9.4 4.44C8.8 5.55 8.35 6.75 8 8m-2.92 8H8c.35 1.25.8 2.45 1.4 3.56A8 8 0 0 1 5.08 16m-.82-2C4.1 13.36 4 12.69 4 12s.1-1.36.26-2h3.38c-.08.66-.14 1.32-.14 2s.06 1.34.14 2M12 4.03c.83 1.2 1.5 2.54 1.91 3.97h-3.82c.41-1.43 1.08-2.77 1.91-3.97M18.92 8h-2.95a15.7 15.7 0 0 0-1.38-3.56c1.84.63 3.37 1.9 4.33 3.56M12 2C6.47 2 2 6.5 2 12a10 10 0 0 0 10 10a10 10 0 0 0 10-10A10 10 0 0 0 12 2"/>`,
|
||||
"arrow-left": `<path fill="currentColor" d="M20 11v2H8l5.5 5.5l-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5L8 11z"/>`,
|
||||
"source-commit": `<path fill="currentColor" d="M17 12a5 5 0 0 1-4 4.9V21h-2v-4.1a5 5 0 0 1 0-9.8V3h2v4.1a5 5 0 0 1 4 4.9m-5-3a3 3 0 0 0-3 3a3 3 0 0 0 3 3a3 3 0 0 0 3-3a3 3 0 0 0-3-3"/>`,
|
||||
"code-tags": `<path fill="currentColor" d="m14.6 16.6l4.6-4.6l-4.6-4.6L16 6l6 6l-6 6zm-5.2 0L4.8 12l4.6-4.6L8 6l-6 6l6 6z"/>`,
|
||||
"tag-multiple": `<path fill="currentColor" d="M5.5 9A1.5 1.5 0 0 0 7 7.5A1.5 1.5 0 0 0 5.5 6A1.5 1.5 0 0 0 4 7.5A1.5 1.5 0 0 0 5.5 9m11.91 2.58c.36.36.59.86.59 1.42c0 .55-.22 1.05-.59 1.41l-5 5a1.996 1.996 0 0 1-2.83 0l-6.99-6.99C2.22 12.05 2 11.55 2 11V6c0-1.11.89-2 2-2h5c.55 0 1.05.22 1.41.58zm-3.87-5.87l1-1l6.87 6.87c.37.36.59.87.59 1.42s-.22 1.05-.58 1.41l-5.38 5.38l-1-1L20.75 13z"/>`,
|
||||
"clock-outline": `<path fill="currentColor" d="M12 20a8 8 0 0 0 8-8a8 8 0 0 0-8-8a8 8 0 0 0-8 8a8 8 0 0 0 8 8m0-18a10 10 0 0 1 10 10a10 10 0 0 1-10 10C6.47 22 2 17.5 2 12A10 10 0 0 1 12 2m.5 5v5.25l4.5 2.67l-.75 1.23L11 13V7z"/>`,
|
||||
apple: `<path fill="currentColor" d="M18.71 19.5c-.83 1.24-1.71 2.45-3.05 2.47c-1.34.03-1.77-.79-3.29-.79c-1.53 0-2 .77-3.27.82c-1.31.05-2.3-1.32-3.14-2.53C4.25 17 2.94 12.45 4.7 9.39c.87-1.52 2.43-2.48 4.12-2.51c1.28-.02 2.5.87 3.29.87c.78 0 2.26-1.07 3.81-.91c.65.03 2.47.26 3.64 1.98c-.09.06-2.17 1.28-2.15 3.81c.03 3.02 2.65 4.03 2.68 4.04c-.03.07-.42 1.44-1.38 2.83M13 3.5c.73-.83 1.94-1.46 2.94-1.5c.13 1.17-.34 2.35-1.04 3.19c-.69.85-1.83 1.51-2.95 1.42c-.15-1.15.41-2.35 1.05-3.11"/>`,
|
||||
"google-play": `<path fill="currentColor" d="M3 20.5v-17c0-.59.34-1.11.84-1.35L13.69 12l-9.85 9.85c-.5-.25-.84-.76-.84-1.35m13.81-5.38L6.05 21.34l8.49-8.49zm3.35-4.31c.34.27.59.69.59 1.19s-.22.9-.57 1.18l-2.29 1.32l-2.5-2.5l2.5-2.5zM6.05 2.66l10.76 6.22l-2.27 2.27z"/>`,
|
||||
"code-braces": `<path fill="currentColor" d="M8 3a2 2 0 0 0-2 2v4a2 2 0 0 1-2 2H3v2h1a2 2 0 0 1 2 2v4a2 2 0 0 0 2 2h2v-2H8v-5a2 2 0 0 0-2-2a2 2 0 0 0 2-2V5h2V3m6 0a2 2 0 0 1 2 2v4a2 2 0 0 0 2 2h1v2h-1a2 2 0 0 0-2 2v4a2 2 0 0 1-2 2h-2v-2h2v-5a2 2 0 0 1 2-2a2 2 0 0 1-2-2V5h-2V3z"/>`,
|
||||
circle: `<path fill="currentColor" d="M12 2A10 10 0 0 0 2 12a10 10 0 0 0 10 10a10 10 0 0 0 10-10A10 10 0 0 0 12 2"/>`,
|
||||
"open-in-new": `<path fill="currentColor" d="M14 3v2h3.59l-9.83 9.83l1.41 1.41L19 6.41V10h2V3m-2 16H5V5h7V3H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7h-2z"/>`,
|
||||
phone: `<path fill="currentColor" d="M6.62 10.79c1.44 2.83 3.76 5.15 6.59 6.59l2.2-2.2c.28-.28.67-.36 1.02-.25c1.12.37 2.32.57 3.57.57a1 1 0 0 1 1 1V20a1 1 0 0 1-1 1A17 17 0 0 1 3 4a1 1 0 0 1 1-1h3.5a1 1 0 0 1 1 1c0 1.25.2 2.45.57 3.57c.11.35.03.74-.25 1.02z"/>`,
|
||||
|
||||
gitea: `<path fill="currentColor" d="M4.209 4.603c-.247 0-.525.02-.84.088c-.333.07-1.28.283-2.054 1.027C-.403 7.25.035 9.685.089 10.052c.065.446.263 1.687 1.21 2.768c1.749 2.141 5.513 2.092 5.513 2.092s.462 1.103 1.168 2.119c.955 1.263 1.936 2.248 2.89 2.367c2.406 0 7.212-.004 7.212-.004s.458.004 1.08-.394c.535-.324 1.013-.893 1.013-.893s.492-.527 1.18-1.73c.21-.37.385-.729.538-1.068c0 0 2.107-4.471 2.107-8.823c-.042-1.318-.367-1.55-.443-1.627c-.156-.156-.366-.153-.366-.153s-4.475.252-6.792.306c-.508.011-1.012.023-1.512.027v4.474l-.634-.301c0-1.39-.004-4.17-.004-4.17c-1.107.016-3.405-.084-3.405-.084s-5.399-.27-5.987-.324c-.187-.011-.401-.032-.648-.032zm.354 1.832h.111s.271 2.269.6 3.597C5.549 11.147 6.22 13 6.22 13s-.996-.119-1.641-.348c-.99-.324-1.409-.714-1.409-.714s-.73-.511-1.096-1.52C1.444 8.73 2.021 7.7 2.021 7.7s.32-.859 1.47-1.145c.395-.106.863-.12 1.072-.12m8.33 2.554c.26.003.509.127.509.127l.868.422l-.529 1.075a.69.69 0 0 0-.614.359a.69.69 0 0 0 .072.756l-.939 1.924a.69.69 0 0 0-.66.527a.69.69 0 0 0 .347.763a.686.686 0 0 0 .867-.206a.69.69 0 0 0-.069-.882l.916-1.874a.7.7 0 0 0 .237-.02a.66.66 0 0 0 .271-.137a9 9 0 0 1 1.016.512a.76.76 0 0 1 .286.282c.073.21-.073.569-.073.569c-.087.29-.702 1.55-.702 1.55a.69.69 0 0 0-.676.477a.681.681 0 1 0 1.157-.252c.073-.141.141-.282.214-.431c.19-.397.515-1.16.515-1.16c.035-.066.218-.394.103-.814c-.095-.435-.48-.638-.48-.638c-.467-.301-1.116-.58-1.116-.58s0-.156-.042-.27a.7.7 0 0 0-.148-.241l.516-1.062l2.89 1.401s.48.218.583.619c.073.282-.019.534-.069.657c-.24.587-2.1 4.317-2.1 4.317s-.232.554-.748.588a1.1 1.1 0 0 1-.393-.045l-.202-.08l-4.31-2.1s-.417-.218-.49-.596c-.083-.31.104-.691.104-.691l2.073-4.272s.183-.37.466-.497a.9.9 0 0 1 .35-.077"/>`,
|
||||
bluesky: `<path fill="currentColor" d="M5.202 2.857C7.954 4.922 10.913 9.11 12 11.358c1.087-2.247 4.046-6.436 6.798-8.501C20.783 1.366 24 .213 24 3.883c0 .732-.42 6.156-.667 7.037c-.856 3.061-3.978 3.842-6.755 3.37c4.854.826 6.089 3.562 3.422 6.299c-5.065 5.196-7.28-1.304-7.847-2.97c-.104-.305-.152-.448-.153-.327c0-.121-.05.022-.153.327c-.568 1.666-2.782 8.166-7.847 2.97c-2.667-2.737-1.432-5.473 3.422-6.3c-2.777.473-5.899-.308-6.755-3.369C.42 10.04 0 4.615 0 3.883c0-3.67 3.217-2.517 5.202-1.026"/>`,
|
||||
react: `<path fill="currentColor" d="M14.23 12.004a2.236 2.236 0 0 1-2.235 2.236a2.236 2.236 0 0 1-2.236-2.236a2.236 2.236 0 0 1 2.235-2.236a2.236 2.236 0 0 1 2.236 2.236m2.648-10.69c-1.346 0-3.107.96-4.888 2.622c-1.78-1.653-3.542-2.602-4.887-2.602c-.41 0-.783.093-1.106.278c-1.375.793-1.683 3.264-.973 6.365C1.98 8.917 0 10.42 0 12.004c0 1.59 1.99 3.097 5.043 4.03c-.704 3.113-.39 5.588.988 6.38c.32.187.69.275 1.102.275c1.345 0 3.107-.96 4.888-2.624c1.78 1.654 3.542 2.603 4.887 2.603c.41 0 .783-.09 1.106-.275c1.374-.792 1.683-3.263.973-6.365C22.02 15.096 24 13.59 24 12.004c0-1.59-1.99-3.097-5.043-4.032c.704-3.11.39-5.587-.988-6.38a2.17 2.17 0 0 0-1.092-.278zm-.005 1.09v.006c.225 0 .406.044.558.127c.666.382.955 1.835.73 3.704c-.054.46-.142.945-.25 1.44a23.5 23.5 0 0 0-3.107-.534A24 24 0 0 0 12.769 4.7c1.592-1.48 3.087-2.292 4.105-2.295zm-9.77.02c1.012 0 2.514.808 4.11 2.28c-.686.72-1.37 1.537-2.02 2.442a23 23 0 0 0-3.113.538a15 15 0 0 1-.254-1.42c-.23-1.868.054-3.32.714-3.707c.19-.09.4-.127.563-.132zm4.882 3.05q.684.704 1.36 1.564c-.44-.02-.89-.034-1.345-.034q-.691-.001-1.36.034c.44-.572.895-1.096 1.345-1.565zM12 8.1c.74 0 1.477.034 2.202.093q.61.874 1.183 1.86q.557.961 1.018 1.946c-.308.655-.646 1.31-1.013 1.95c-.38.66-.773 1.288-1.18 1.87a25.6 25.6 0 0 1-4.412.005a27 27 0 0 1-1.183-1.86q-.557-.961-1.018-1.946a25 25 0 0 1 1.013-1.954c.38-.66.773-1.286 1.18-1.868A25 25 0 0 1 12 8.098zm-3.635.254c-.24.377-.48.763-.704 1.16q-.336.585-.635 1.174c-.265-.656-.49-1.31-.676-1.947c.64-.15 1.315-.283 2.015-.386zm7.26 0q1.044.153 2.006.387c-.18.632-.405 1.282-.66 1.933a26 26 0 0 0-1.345-2.32zm3.063.675q.727.226 1.375.498c1.732.74 2.852 1.708 2.852 2.476c-.005.768-1.125 1.74-2.857 2.475c-.42.18-.88.342-1.355.493a24 24 0 0 0-1.1-2.98c.45-1.017.81-2.01 1.085-2.964zm-13.395.004c.278.96.645 1.957 1.1 2.98a23 23 0 0 0-1.086 2.964c-.484-.15-.944-.318-1.37-.5c-1.732-.737-2.852-1.706-2.852-2.474s1.12-1.742 2.852-2.476c.42-.18.88-.342 1.356-.494m11.678 4.28c.265.657.49 1.312.676 1.948c-.64.157-1.316.29-2.016.39a26 26 0 0 0 1.341-2.338zm-9.945.02c.2.392.41.783.64 1.175q.345.586.705 1.143a22 22 0 0 1-2.006-.386c.18-.63.406-1.282.66-1.933zM17.92 16.32c.112.493.2.968.254 1.423c.23 1.868-.054 3.32-.714 3.708c-.147.09-.338.128-.563.128c-1.012 0-2.514-.807-4.11-2.28c.686-.72 1.37-1.536 2.02-2.44c1.107-.118 2.154-.3 3.113-.54zm-11.83.01c.96.234 2.006.415 3.107.532c.66.905 1.345 1.727 2.035 2.446c-1.595 1.483-3.092 2.295-4.11 2.295a1.2 1.2 0 0 1-.553-.132c-.666-.38-.955-1.834-.73-3.703c.054-.46.142-.944.25-1.438zm4.56.64q.661.032 1.345.034q.691.001 1.36-.034c-.44.572-.895 1.095-1.345 1.565q-.684-.706-1.36-1.565"/>`,
|
||||
vuedotjs: `<path fill="currentColor" d="M24 1.61h-9.94L12 5.16L9.94 1.61H0l12 20.78ZM12 14.08L5.16 2.23h4.43L12 6.41l2.41-4.18h4.43Z"/>`,
|
||||
typescript: `<path fill="currentColor" d="M1.125 0C.502 0 0 .502 0 1.125v21.75C0 23.498.502 24 1.125 24h21.75c.623 0 1.125-.502 1.125-1.125V1.125C24 .502 23.498 0 22.875 0zm17.363 9.75q.918 0 1.627.111a6.4 6.4 0 0 1 1.306.34v2.458a4 4 0 0 0-.643-.361a5 5 0 0 0-.717-.26a5.5 5.5 0 0 0-1.426-.2q-.45 0-.819.086a2.1 2.1 0 0 0-.623.242q-.254.156-.393.374a.9.9 0 0 0-.14.49q0 .294.156.529q.156.234.443.444c.287.21.423.276.696.41q.41.203.926.416q.705.296 1.266.628q.561.333.963.753q.402.418.614.957q.213.538.214 1.253q0 .986-.373 1.656a3 3 0 0 1-1.012 1.085a4.4 4.4 0 0 1-1.487.596q-.85.18-1.79.18a10 10 0 0 1-1.84-.164a5.5 5.5 0 0 1-1.512-.493v-2.63a5.03 5.03 0 0 0 3.237 1.2q.5 0 .872-.09q.373-.09.623-.25q.249-.162.373-.38a1.02 1.02 0 0 0-.074-1.089a2.1 2.1 0 0 0-.537-.5a5.6 5.6 0 0 0-.807-.444a28 28 0 0 0-1.007-.436q-1.377-.575-2.053-1.405t-.676-2.005q0-.92.369-1.582q.368-.662 1.004-1.089a4.5 4.5 0 0 1 1.47-.629a7.5 7.5 0 0 1 1.77-.201m-15.113.188h9.563v2.166H9.506v9.646H6.789v-9.646H3.375z"/>`,
|
||||
astro: `<path fill="currentColor" d="M8.358 20.162c-1.186-1.07-1.532-3.316-1.038-4.944c.856 1.026 2.043 1.352 3.272 1.535c1.897.283 3.76.177 5.522-.678c.202-.098.388-.229.608-.36c.166.473.209.95.151 1.437c-.14 1.185-.738 2.1-1.688 2.794c-.38.277-.782.525-1.175.787c-1.205.804-1.531 1.747-1.078 3.119l.044.148a3.16 3.16 0 0 1-1.407-1.188a3.3 3.3 0 0 1-.544-1.815c-.004-.32-.004-.642-.048-.958c-.106-.769-.472-1.113-1.161-1.133c-.707-.02-1.267.411-1.415 1.09c-.012.053-.028.104-.045.165zm-5.961-4.445s3.24-1.575 6.49-1.575l2.451-7.565c.092-.366.36-.614.662-.614s.57.248.662.614l2.45 7.565c3.85 0 6.491 1.575 6.491 1.575L16.088.727C15.93.285 15.663 0 15.303 0H8.697c-.36 0-.615.285-.784.727z"/>`,
|
||||
go: `<path fill="currentColor" d="M1.811 10.231c-.047 0-.058-.023-.035-.059l.246-.315c.023-.035.081-.058.128-.058h4.172c.046 0 .058.035.035.07l-.199.303c-.023.036-.082.07-.117.07zM.047 11.306c-.047 0-.059-.023-.035-.058l.245-.316c.023-.035.082-.058.129-.058h5.328c.047 0 .07.035.058.07l-.093.28c-.012.047-.058.07-.105.07zm2.828 1.075c-.047 0-.059-.035-.035-.07l.163-.292c.023-.035.07-.07.117-.07h2.337c.047 0 .07.035.07.082l-.023.28c0 .047-.047.082-.082.082zm12.129-2.36c-.736.187-1.239.327-1.963.514c-.176.046-.187.058-.34-.117c-.174-.199-.303-.327-.548-.444c-.737-.362-1.45-.257-2.115.175c-.795.514-1.204 1.274-1.192 2.22c.011.935.654 1.706 1.577 1.835c.795.105 1.46-.175 1.987-.77c.105-.13.198-.27.315-.434H10.47c-.245 0-.304-.152-.222-.35c.152-.362.432-.97.596-1.274a.32.32 0 0 1 .292-.187h4.253c-.023.316-.023.631-.07.947a5 5 0 0 1-.958 2.29c-.841 1.11-1.94 1.8-3.33 1.986c-1.145.152-2.209-.07-3.143-.77c-.865-.655-1.356-1.52-1.484-2.595c-.152-1.274.222-2.419.993-3.424c.83-1.086 1.928-1.776 3.272-2.02c1.098-.2 2.15-.07 3.096.571c.62.41 1.063.97 1.356 1.648c.07.105.023.164-.117.2m3.868 6.461c-1.064-.024-2.034-.328-2.852-1.029a3.67 3.67 0 0 1-1.262-2.255c-.21-1.32.152-2.489.947-3.529c.853-1.122 1.881-1.706 3.272-1.95c1.192-.21 2.314-.095 3.33.595c.923.63 1.496 1.484 1.648 2.605c.198 1.578-.257 2.863-1.344 3.962c-.771.783-1.718 1.273-2.805 1.495c-.315.06-.63.07-.934.106m2.78-4.72c-.011-.153-.011-.27-.034-.387c-.21-1.157-1.274-1.81-2.384-1.554c-1.087.245-1.788.935-2.045 2.033c-.21.912.234 1.835 1.075 2.21c.643.28 1.285.244 1.905-.07c.923-.48 1.425-1.228 1.484-2.233z"/>`,
|
||||
postgresql: `<path fill="currentColor" d="M23.56 14.723a.5.5 0 0 0-.057-.12q-.21-.395-1.007-.231c-1.654.34-2.294.13-2.526-.02c1.342-2.048 2.445-4.522 3.041-6.83c.272-1.05.798-3.523.122-4.73a1.6 1.6 0 0 0-.15-.236C21.693.91 19.8.025 17.51.001c-1.495-.016-2.77.346-3.116.479a10 10 0 0 0-.516-.082a8 8 0 0 0-1.312-.127c-1.182-.019-2.203.264-3.05.84C8.66.79 4.729-.534 2.296 1.19C.935 2.153.309 3.873.43 6.304c.041.818.507 3.334 1.243 5.744q.69 2.26 1.433 3.582q.83 1.493 1.714 1.79c.448.148 1.133.143 1.858-.729a56 56 0 0 1 1.945-2.206c.435.235.906.362 1.39.377v.004a11 11 0 0 0-.247.305c-.339.43-.41.52-1.5.745c-.31.064-1.134.233-1.146.811a.6.6 0 0 0 .091.327c.227.423.922.61 1.015.633c1.335.333 2.505.092 3.372-.679c-.017 2.231.077 4.418.345 5.088c.221.553.762 1.904 2.47 1.904q.375.001.829-.094c1.782-.382 2.556-1.17 2.855-2.906c.15-.87.402-2.875.539-4.101c.017-.07.036-.12.057-.136c0 0 .07-.048.427.03l.044.007l.254.022l.015.001c.847.039 1.911-.142 2.531-.43c.644-.3 1.806-1.033 1.595-1.67M2.37 11.876c-.744-2.435-1.178-4.885-1.212-5.571c-.109-2.172.417-3.683 1.562-4.493c1.837-1.299 4.84-.54 6.108-.13l-.01.01C6.795 3.734 6.843 7.226 6.85 7.44c0 .082.006.199.016.36c.034.586.1 1.68-.074 2.918c-.16 1.15.194 2.276.973 3.089q.12.126.252.237c-.347.371-1.1 1.193-1.903 2.158c-.568.682-.96.551-1.088.508c-.392-.13-.813-.587-1.239-1.322c-.48-.839-.963-2.032-1.415-3.512m6.007 5.088a1.6 1.6 0 0 1-.432-.178c.089-.039.237-.09.483-.14c1.284-.265 1.482-.451 1.915-1a8 8 0 0 1 .367-.443a.4.4 0 0 0 .074-.13c.17-.151.272-.11.436-.042c.156.065.308.26.37.475c.03.102.062.295-.045.445c-.904 1.266-2.222 1.25-3.168 1.013m2.094-3.988l-.052.14c-.133.357-.257.689-.334 1.004c-.667-.002-1.317-.288-1.81-.803c-.628-.655-.913-1.566-.783-2.5c.183-1.308.116-2.447.08-3.059l-.013-.22c.296-.262 1.666-.996 2.643-.772c.446.102.718.406.83.928c.585 2.704.078 3.83-.33 4.736a9 9 0 0 0-.23.546m7.364 4.572q-.024.266-.062.596l-.146.438a.4.4 0 0 0-.018.108c-.006.475-.054.649-.115.87a4.8 4.8 0 0 0-.18 1.057c-.11 1.414-.878 2.227-2.417 2.556c-1.515.325-1.784-.496-2.02-1.221a7 7 0 0 0-.078-.227c-.215-.586-.19-1.412-.157-2.555c.016-.561-.025-1.901-.33-2.646q.006-.44.019-.892a.4.4 0 0 0-.016-.113a2 2 0 0 0-.044-.208c-.122-.428-.42-.786-.78-.935c-.142-.059-.403-.167-.717-.087c.067-.276.183-.587.309-.925l.053-.142c.06-.16.134-.325.213-.5c.426-.948 1.01-2.246.376-5.178c-.237-1.098-1.03-1.634-2.232-1.51c-.72.075-1.38.366-1.709.532a6 6 0 0 0-.196.104c.092-1.106.439-3.174 1.736-4.482a4 4 0 0 1 .303-.276a.35.35 0 0 0 .145-.064c.752-.57 1.695-.85 2.802-.833q.616.01 1.174.081c1.94.355 3.244 1.447 4.036 2.383c.814.962 1.255 1.931 1.431 2.454c-1.323-.134-2.223.127-2.68.78c-.992 1.418.544 4.172 1.282 5.496c.135.242.252.452.289.54c.24.583.551.972.778 1.256c.07.087.138.171.189.245c-.4.116-1.12.383-1.055 1.717a35 35 0 0 1-.084.815c-.046.208-.07.46-.1.766m.89-1.621c-.04-.832.27-.919.597-1.01l.135-.041a1 1 0 0 0 .134.103c.57.376 1.583.421 3.007.134c-.202.177-.519.4-.953.601c-.41.19-1.096.333-1.747.364c-.72.034-1.086-.08-1.173-.151m.57-9.271a7 7 0 0 1-.105 1.001c-.055.358-.112.728-.127 1.177c-.014.436.04.89.093 1.33c.107.887.216 1.8-.207 2.701a4 4 0 0 1-.188-.385a8 8 0 0 0-.325-.617c-.616-1.104-2.057-3.69-1.32-4.744c.38-.543 1.342-.566 2.179-.463m.228 7.013l-.085-.107l-.035-.044c.726-1.2.584-2.387.457-3.439c-.052-.432-.1-.84-.088-1.222c.013-.407.066-.755.118-1.092c.064-.415.13-.844.111-1.35a.6.6 0 0 0 .012-.19c-.046-.486-.6-1.938-1.73-3.253a7.8 7.8 0 0 0-2.688-2.04A9.3 9.3 0 0 1 17.62.746c2.052.046 3.675.814 4.824 2.283a1 1 0 0 1 .067.1c.723 1.356-.276 6.275-2.987 10.54m-8.816-6.116c-.025.18-.31.423-.621.423l-.081-.006a.8.8 0 0 1-.506-.315c-.046-.06-.12-.178-.106-.285a.22.22 0 0 1 .093-.149c.118-.089.352-.122.61-.086c.316.044.642.193.61.418m7.93-.411c.011.08-.049.2-.153.31a.72.72 0 0 1-.408.223l-.075.005c-.293 0-.541-.234-.56-.371c-.024-.177.264-.31.56-.352c.298-.042.612.009.636.185"/>`,
|
||||
dotnet: `<path fill="currentColor" d="M24 8.77h-2.468v7.565h-1.425V8.77h-2.462V7.53H24zm-6.852 7.565h-4.821V7.53h4.63v1.24h-3.205v2.494h2.953v1.234h-2.953v2.604h3.396zm-6.708 0H8.882L4.78 9.863a3 3 0 0 1-.258-.51h-.036q.048.283.048 1.21v5.772H3.157V7.53h1.659l3.965 6.32q.25.392.323.54h.024q-.06-.35-.06-1.185V7.529h1.372zm-8.703-.693a.868.829 0 0 1-.869.829a.868.829 0 0 1-.868-.83a.868.829 0 0 1 .868-.828a.868.829 0 0 1 .869.829"/>`,
|
||||
docker: `<path fill="currentColor" d="M13.983 11.078h2.119a.186.186 0 0 0 .186-.185V9.006a.186.186 0 0 0-.186-.186h-2.119a.185.185 0 0 0-.185.185v1.888c0 .102.083.185.185.185m-2.954-5.43h2.118a.186.186 0 0 0 .186-.186V3.574a.186.186 0 0 0-.186-.185h-2.118a.185.185 0 0 0-.185.185v1.888c0 .102.082.185.185.185m0 2.716h2.118a.187.187 0 0 0 .186-.186V6.29a.186.186 0 0 0-.186-.185h-2.118a.185.185 0 0 0-.185.185v1.887c0 .102.082.185.185.186m-2.93 0h2.12a.186.186 0 0 0 .184-.186V6.29a.185.185 0 0 0-.185-.185H8.1a.185.185 0 0 0-.185.185v1.887c0 .102.083.185.185.186m-2.964 0h2.119a.186.186 0 0 0 .185-.186V6.29a.185.185 0 0 0-.185-.185H5.136a.186.186 0 0 0-.186.185v1.887c0 .102.084.185.186.186m5.893 2.715h2.118a.186.186 0 0 0 .186-.185V9.006a.186.186 0 0 0-.186-.186h-2.118a.185.185 0 0 0-.185.185v1.888c0 .102.082.185.185.185m-2.93 0h2.12a.185.185 0 0 0 .184-.185V9.006a.185.185 0 0 0-.184-.186h-2.12a.185.185 0 0 0-.184.185v1.888c0 .102.083.185.185.185m-2.964 0h2.119a.185.185 0 0 0 .185-.185V9.006a.185.185 0 0 0-.184-.186h-2.12a.186.186 0 0 0-.186.186v1.887c0 .102.084.185.186.185m-2.92 0h2.12a.185.185 0 0 0 .184-.185V9.006a.185.185 0 0 0-.184-.186h-2.12a.185.185 0 0 0-.184.185v1.888c0 .102.082.185.185.185M23.763 9.89c-.065-.051-.672-.51-1.954-.51q-.508.001-1.01.087c-.248-1.7-1.653-2.53-1.716-2.566l-.344-.199l-.226.327c-.284.438-.49.922-.612 1.43c-.23.97-.09 1.882.403 2.661c-.595.332-1.55.413-1.744.42H.751a.75.75 0 0 0-.75.748a11.4 11.4 0 0 0 .692 4.062c.545 1.428 1.355 2.48 2.41 3.124c1.18.723 3.1 1.137 5.275 1.137a15.7 15.7 0 0 0 2.93-.266a12.3 12.3 0 0 0 3.823-1.389a10.5 10.5 0 0 0 2.61-2.136c1.252-1.418 1.998-2.997 2.553-4.4h.221c1.372 0 2.215-.549 2.68-1.009c.309-.293.55-.65.707-1.046l.098-.288Z"/>`,
|
||||
github: `<path fill="currentColor" d="M12 .297c-6.63 0-12 5.373-12 12c0 5.303 3.438 9.8 8.205 11.385c.6.113.82-.258.82-.577c0-.285-.01-1.04-.015-2.04c-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729c1.205.084 1.838 1.236 1.838 1.236c1.07 1.835 2.809 1.305 3.495.998c.108-.776.417-1.305.76-1.605c-2.665-.3-5.466-1.332-5.466-5.93c0-1.31.465-2.38 1.235-3.22c-.135-.303-.54-1.523.105-3.176c0 0 1.005-.322 3.3 1.23c.96-.267 1.98-.399 3-.405c1.02.006 2.04.138 3 .405c2.28-1.552 3.285-1.23 3.285-1.23c.645 1.653.24 2.873.12 3.176c.765.84 1.23 1.91 1.23 3.22c0 4.61-2.805 5.625-5.475 5.92c.42.36.81 1.096.81 2.22c0 1.606-.015 2.896-.015 3.286c0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"/>`,
|
||||
kotlin: `<path fill="currentColor" d="M24 24H0V0h24L12 12Z"/>`,
|
||||
swift: `<path fill="currentColor" d="m7.508 0l-.86.002q-.362.001-.724.01q-.198.005-.395.015A9 9 0 0 0 4.348.15A5.5 5.5 0 0 0 2.85.645A5.04 5.04 0 0 0 .645 2.848c-.245.48-.4.972-.495 1.5c-.093.52-.122 1.05-.136 1.576a35 35 0 0 0-.012.724L0 7.508v8.984l.002.862q.002.36.012.722c.014.526.043 1.057.136 1.576c.095.528.25 1.02.495 1.5a5.03 5.03 0 0 0 2.205 2.203c.48.244.97.4 1.498.495c.52.093 1.05.124 1.576.138q.362.01.724.01q.43.003.86.002h8.984l.86-.002q.362 0 .724-.01a10.5 10.5 0 0 0 1.578-.138a5.3 5.3 0 0 0 1.498-.495a5.04 5.04 0 0 0 2.203-2.203c.245-.48.4-.972.495-1.5c.093-.52.124-1.05.138-1.576q.01-.361.01-.722q.003-.431.002-.862V7.508l-.002-.86a34 34 0 0 0-.01-.724a10.5 10.5 0 0 0-.138-1.576a5.3 5.3 0 0 0-.495-1.5A5.04 5.04 0 0 0 21.152.645A5.3 5.3 0 0 0 19.654.15a10.5 10.5 0 0 0-1.578-.138a35 35 0 0 0-.722-.01L16.492 0zm6.035 3.41c4.114 2.47 6.545 7.162 5.549 11.131c-.024.093-.05.181-.076.272l.002.001c2.062 2.538 1.5 5.258 1.236 4.745c-1.072-2.086-3.066-1.568-4.088-1.043a7 7 0 0 1-.281.158l-.02.012l-.002.002c-2.115 1.123-4.957 1.205-7.812-.022a12.57 12.57 0 0 1-5.64-4.838c.649.48 1.35.902 2.097 1.252c3.019 1.414 6.051 1.311 8.197-.002C9.651 12.73 7.101 9.67 5.146 7.191a10.6 10.6 0 0 1-1.005-1.384c2.34 2.142 6.038 4.83 7.365 5.576C8.69 8.408 6.208 4.743 6.324 4.86c4.436 4.47 8.528 6.996 8.528 6.996c.154.085.27.154.36.213q.128-.322.224-.668c.708-2.588-.09-5.548-1.893-7.992z"/>`,
|
||||
flutter: `<path fill="currentColor" d="M14.314 0L2.3 12L6 15.7L21.684.013h-7.357zm.014 11.072L7.857 17.53l6.47 6.47H21.7l-6.46-6.468l6.46-6.46h-7.37z"/>`,
|
||||
nixos: `<path fill="currentColor" d="m7.352 1.592l-1.364.002L5.32 2.75l1.557 2.713l-3.137-.008l-1.32 2.34h11.69l-1.353-2.332l-3.192-.006l-2.214-3.865zm6.175 0l-2.687.025l5.846 10.127l1.341-2.34l-1.59-2.765l2.24-3.85l-.683-1.182h-1.336l-1.57 2.705l-1.56-2.72zm6.887 4.195l-5.846 10.125l2.696-.008l1.601-2.76l4.453.016l.682-1.183l-.666-1.157l-3.13-.008L21.778 8.1l-1.365-2.313zM9.432 8.086l-2.696.008l-1.601 2.76l-4.453-.016L0 12.02l.666 1.157l3.13.008l-1.575 2.71l1.365 2.315zM7.33 12.25l-.006.01l-.002-.004l-1.342 2.34l1.59 2.765l-2.24 3.85l.684 1.182H7.35l.004-.006h.001l1.567-2.698l1.558 2.72l2.688-.026l-.004-.006h.01zm2.55 3.93l1.354 2.332l3.192.006l2.215 3.865l1.363-.002l.668-1.156l-1.557-2.713l3.137.008l1.32-2.34z"/>`,
|
||||
|
||||
house: `<path d="M15 21v-8a1 1 0 0 0-1-1h-4a1 1 0 0 0-1 1v8" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path d="M3 10a2 2 0 0 1 .709-1.528l7-6a2 2 0 0 1 2.582 0l7 6A2 2 0 0 1 21 10v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>`,
|
||||
newspaper: `<path d="M15 18h-5" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path d="M18 14h-8" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path d="M4 22h16a2 2 0 0 0 2-2V4a2 2 0 0 0-2-2H8a2 2 0 0 0-2 2v16a2 2 0 0 1-4 0v-9a2 2 0 0 1 2-2h2" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><rect width="8" height="4" x="10" y="6" rx="1" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>`,
|
||||
"file-user": `<path d="M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path d="M14 2v5a1 1 0 0 0 1 1h5" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path d="M16 22a4 4 0 0 0-8 0" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><circle cx="12" cy="15" r="3" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>`,
|
||||
"code-xml": `<path d="m18 16 4-4-4-4" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path d="m6 8-4 4 4 4" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path d="m14.5 4-5 16" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>`,
|
||||
megaphone: `<path d="M11 6a13 13 0 0 0 8.4-2.8A1 1 0 0 1 21 4v12a1 1 0 0 1-1.6.8A13 13 0 0 0 11 14H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path d="M6 14a12 12 0 0 0 2.4 7.2 2 2 0 0 0 3.2-2.4A8 8 0 0 1 10 14" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path d="M8 6v8" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>`,
|
||||
settings: `<path d="M9.671 4.136a2.34 2.34 0 0 1 4.659 0 2.34 2.34 0 0 0 3.319 1.915 2.34 2.34 0 0 1 2.33 4.033 2.34 2.34 0 0 0 0 3.831 2.34 2.34 0 0 1-2.33 4.033 2.34 2.34 0 0 0-3.319 1.915 2.34 2.34 0 0 1-4.659 0 2.34 2.34 0 0 0-3.32-1.915 2.34 2.34 0 0 1-2.33-4.033 2.34 2.34 0 0 0 0-3.831A2.34 2.34 0 0 1 6.35 6.051a2.34 2.34 0 0 0 3.319-1.915" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><circle cx="12" cy="12" r="3" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>`,
|
||||
x: `<path d="M18 6 6 18" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path d="m6 6 12 12" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>`,
|
||||
"arrow-up": `<path d="m5 12 7-7 7 7" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path d="M12 19V5" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>`,
|
||||
} as const;
|
||||
|
||||
export type IconName = keyof typeof icons;
|
||||
|
||||
export const pdfIconPaths: Record<string, string> = {
|
||||
email:
|
||||
"m20 8l-8 5l-8-5V6l8 5l8-5m0-2H4c-1.11 0-2 .89-2 2v12a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V6a2 2 0 0 0-2-2",
|
||||
phone:
|
||||
"M6.62 10.79c1.44 2.83 3.76 5.15 6.59 6.59l2.2-2.2c.28-.28.67-.36 1.02-.25c1.12.37 2.32.57 3.57.57a1 1 0 0 1 1 1V20a1 1 0 0 1-1 1A17 17 0 0 1 3 4a1 1 0 0 1 1-1h3.5a1 1 0 0 1 1 1c0 1.25.2 2.45.57 3.57c.11.35.03.74-.25 1.02z",
|
||||
gitea:
|
||||
"M4.209 4.603c-.247 0-.525.02-.84.088c-.333.07-1.28.283-2.054 1.027C-.403 7.25.035 9.685.089 10.052c.065.446.263 1.687 1.21 2.768c1.749 2.141 5.513 2.092 5.513 2.092s.462 1.103 1.168 2.119c.955 1.263 1.936 2.248 2.89 2.367c2.406 0 7.212-.004 7.212-.004s.458.004 1.08-.394c.535-.324 1.013-.893 1.013-.893s.492-.527 1.18-1.73c.21-.37.385-.729.538-1.068c0 0 2.107-4.471 2.107-8.823c-.042-1.318-.367-1.55-.443-1.627c-.156-.156-.366-.153-.366-.153s-4.475.252-6.792.306c-.508.011-1.012.023-1.512.027v4.474l-.634-.301c0-1.39-.004-4.17-.004-4.17c-1.107.016-3.405-.084-3.405-.084s-5.399-.27-5.987-.324c-.187-.011-.401-.032-.648-.032zm.354 1.832h.111s.271 2.269.6 3.597C5.549 11.147 6.22 13 6.22 13s-.996-.119-1.641-.348c-.99-.324-1.409-.714-1.409-.714s-.73-.511-1.096-1.52C1.444 8.73 2.021 7.7 2.021 7.7s.32-.859 1.47-1.145c.395-.106.863-.12 1.072-.12m8.33 2.554c.26.003.509.127.509.127l.868.422l-.529 1.075a.69.69 0 0 0-.614.359a.69.69 0 0 0 .072.756l-.939 1.924a.69.69 0 0 0-.66.527a.69.69 0 0 0 .347.763a.686.686 0 0 0 .867-.206a.69.69 0 0 0-.069-.882l.916-1.874a.7.7 0 0 0 .237-.02a.66.66 0 0 0 .271-.137a9 9 0 0 1 1.016.512a.76.76 0 0 1 .286.282c.073.21-.073.569-.073.569c-.087.29-.702 1.55-.702 1.55a.69.69 0 0 0-.676.477a.681.681 0 1 0 1.157-.252c.073-.141.141-.282.214-.431c.19-.397.515-1.16.515-1.16c.035-.066.218-.394.103-.814c-.095-.435-.48-.638-.48-.638c-.467-.301-1.116-.58-1.116-.58s0-.156-.042-.27a.7.7 0 0 0-.148-.241l.516-1.062l2.89 1.401s.48.218.583.619c.073.282-.019.534-.069.657c-.24.587-2.1 4.317-2.1 4.317s-.232.554-.748.588a1.1 1.1 0 0 1-.393-.045l-.202-.08l-4.31-2.1s-.417-.218-.49-.596c-.083-.31.104-.691.104-.691l2.073-4.272s.183-.37.466-.497a.9.9 0 0 1 .35-.077",
|
||||
};
|
||||
@@ -11,9 +11,7 @@ export const GET: APIRoute = async ({ request }) => {
|
||||
|
||||
let tomlContent: string;
|
||||
|
||||
// Check if tomlFile is a path (starts with /) or raw content
|
||||
if (config.resumeConfig.tomlFile.startsWith("/")) {
|
||||
// It's a file path - fetch it
|
||||
const url = new URL(request.url);
|
||||
const baseUrl = `${url.protocol}//${url.host}`;
|
||||
|
||||
@@ -27,7 +25,6 @@ export const GET: APIRoute = async ({ request }) => {
|
||||
|
||||
tomlContent = await response.text();
|
||||
} else {
|
||||
// It's raw TOML content
|
||||
tomlContent = config.resumeConfig.tomlFile;
|
||||
}
|
||||
const resumeData = TOML.parse(tomlContent);
|
||||
@@ -35,7 +32,7 @@ export const GET: APIRoute = async ({ request }) => {
|
||||
return new Response(JSON.stringify(resumeData), {
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"Cache-Control": "public, max-age=300", // Cache for 5 minutes
|
||||
"Cache-Control": "public, max-age=300",
|
||||
},
|
||||
});
|
||||
} catch (error) {
|
||||
|
||||
@@ -4,18 +4,25 @@ import type { ResumeData } from "../../../types";
|
||||
import * as TOML from "@iarna/toml";
|
||||
import { renderToStream } from "@react-pdf/renderer";
|
||||
import { ResumeDocument } from "../../../pdf/ResumeDocument";
|
||||
import { getMdiIconPath, fetchProfileIcons } from "../../../utils/icons";
|
||||
import { pdfIconPaths } from "../../../config/icons";
|
||||
|
||||
const generatePDF = async (data: ResumeData) => {
|
||||
const resumeConfig = config.resumeConfig;
|
||||
const profileIcons = fetchProfileIcons(data.basics.profiles);
|
||||
|
||||
const icons = {
|
||||
...profileIcons,
|
||||
email: getMdiIconPath("mdi:email"),
|
||||
phone: getMdiIconPath("mdi:phone"),
|
||||
const icons: { [key: string]: string } = {
|
||||
email: pdfIconPaths.email,
|
||||
phone: pdfIconPaths.phone,
|
||||
};
|
||||
|
||||
if (data.basics.profiles) {
|
||||
for (const profile of data.basics.profiles) {
|
||||
const key = profile.network.toLowerCase();
|
||||
if (pdfIconPaths[key]) {
|
||||
icons[key] = pdfIconPaths[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return await renderToStream(ResumeDocument({ data, resumeConfig, icons }));
|
||||
};
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
import { getCollection, render, type CollectionEntry } from "astro:content";
|
||||
import { Icon } from "astro-icon/components";
|
||||
import Icon from "../../components/Icon.astro";
|
||||
import Layout from "../../layouts/Layout.astro";
|
||||
|
||||
export const prerender = true;
|
||||
@@ -33,7 +33,7 @@ const { Content } = await render(post);
|
||||
<div
|
||||
class="flex items-center flex-row gap-2 text-base-content opacity-75"
|
||||
>
|
||||
<Icon name="mdi:clock" class="text-xl" />
|
||||
<Icon name="clock" class="text-xl" />
|
||||
<time datetime={post.data.pubDate.toISOString()}>
|
||||
{
|
||||
new Date(post.data.pubDate).toLocaleDateString(
|
||||
@@ -53,7 +53,7 @@ const { Content } = await render(post);
|
||||
href="/posts"
|
||||
class="btn btn-outline btn-primary btn-sm font-bold"
|
||||
>
|
||||
<Icon name="mdi:arrow-left" class="text-lg" />
|
||||
<Icon name="arrow-left" class="text-lg" />
|
||||
Back
|
||||
</a>
|
||||
</div>
|
||||
@@ -63,7 +63,7 @@ const { Content } = await render(post);
|
||||
<div class="flex gap-2 flex-wrap mb-6">
|
||||
{post.data.tags.map((tag: string) => (
|
||||
<div class="badge badge-primary font-bold">
|
||||
<Icon name="mdi:tag" class="text-lg" />
|
||||
<Icon name="tag" class="text-lg" />
|
||||
{tag}
|
||||
</div>
|
||||
))}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
---
|
||||
import Layout from "../layouts/Layout.astro";
|
||||
import { getCollection, type CollectionEntry } from "astro:content";
|
||||
import { Icon } from "astro-icon/components";
|
||||
import { config } from "../config";
|
||||
|
||||
// Get all posts from the content collection
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
import Layout from "../layouts/Layout.astro";
|
||||
import { Icon } from "astro-icon/components";
|
||||
import Icon from "../components/Icon.astro";
|
||||
import { config } from "../config";
|
||||
import { fetchGiteaInfoFromUrl, formatRelativeTime } from "../utils/gitea";
|
||||
import type { Project } from "../types";
|
||||
@@ -81,7 +81,7 @@ const sortedProjects = projectsWithGiteaInfo.sort((a, b) => {
|
||||
) : (
|
||||
<div class="w-12 h-12 rounded-lg bg-accent flex items-center justify-center">
|
||||
<Icon
|
||||
name="mdi:code-braces"
|
||||
name="code-braces"
|
||||
class="w-6 h-6 text-accent-content"
|
||||
/>
|
||||
</div>
|
||||
@@ -136,7 +136,7 @@ const sortedProjects = projectsWithGiteaInfo.sort((a, b) => {
|
||||
class="btn btn-sm btn-square btn-ghost text-primary hover:bg-primary hover:text-primary-content transition-all"
|
||||
aria-label={`Visit ${project.name} website`}
|
||||
>
|
||||
<Icon name="mdi:web" class="w-5 h-5" />
|
||||
<Icon name="web" class="w-5 h-5" />
|
||||
</a>
|
||||
)}
|
||||
{project.gitLink && (
|
||||
@@ -148,7 +148,7 @@ const sortedProjects = projectsWithGiteaInfo.sort((a, b) => {
|
||||
aria-label={`View ${project.name} source`}
|
||||
>
|
||||
<Icon
|
||||
name="simple-icons:gitea"
|
||||
name="gitea"
|
||||
class="w-5 h-5"
|
||||
/>
|
||||
</a>
|
||||
@@ -161,7 +161,7 @@ const sortedProjects = projectsWithGiteaInfo.sort((a, b) => {
|
||||
class="btn btn-sm btn-square btn-ghost text-accent hover:bg-accent hover:text-accent-content transition-all"
|
||||
aria-label={`${project.name} on iOS`}
|
||||
>
|
||||
<Icon name="mdi:apple" class="w-5 h-5" />
|
||||
<Icon name="apple" class="w-5 h-5" />
|
||||
</a>
|
||||
)}
|
||||
{project.androidLink && (
|
||||
@@ -173,7 +173,7 @@ const sortedProjects = projectsWithGiteaInfo.sort((a, b) => {
|
||||
aria-label={`${project.name} on Android`}
|
||||
>
|
||||
<Icon
|
||||
name="mdi:google-play"
|
||||
name="google-play"
|
||||
class="w-5 h-5"
|
||||
/>
|
||||
</a>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
import { Icon } from "astro-icon/components";
|
||||
import Icon from "../components/Icon.astro";
|
||||
import Layout from "../layouts/Layout.astro";
|
||||
import ResumeSkills from "../components/ResumeSkills.vue";
|
||||
import ResumeDownloadButton from "../components/ResumeDownloadButton.vue";
|
||||
@@ -118,13 +118,13 @@ if (!data) {
|
||||
href={`mailto:${data.basics.email}`}
|
||||
class="link link-hover inline-flex items-center gap-1 text-sm sm:text-base"
|
||||
>
|
||||
<Icon name="mdi:email" /> {data.basics.email}
|
||||
<Icon name="email" /> {data.basics.email}
|
||||
</a>
|
||||
)
|
||||
}
|
||||
{
|
||||
data.basics.profiles?.map((profile) => {
|
||||
const iconName = `simple-icons:${profile.network.toLowerCase()}`;
|
||||
const iconName = profile.network.toLowerCase();
|
||||
return (
|
||||
<a
|
||||
href={profile.url}
|
||||
@@ -217,7 +217,7 @@ if (!data) {
|
||||
rel="noopener noreferrer"
|
||||
class="inline-flex items-center gap-1 text-primary hover:text-primary-focus text-sm mt-2"
|
||||
>
|
||||
<Icon name="mdi:link" />
|
||||
<Icon name="link" />
|
||||
Website
|
||||
</a>
|
||||
)}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
import Layout from "../layouts/Layout.astro";
|
||||
import { Icon } from "astro-icon/components";
|
||||
import Icon from "../components/Icon.astro";
|
||||
import { config } from "../config";
|
||||
|
||||
// Sort talks by date, newest first
|
||||
@@ -68,7 +68,7 @@ function formatDate(dateStr: string): string {
|
||||
<div class="flex-grow flex flex-col gap-1 justify-center pl-4 z-10 pointer-events-none">
|
||||
<h2 class="font-bold text-lg sm:text-xl text-primary group-hover:text-accent transition-colors flex items-center gap-2">
|
||||
{talk.name}
|
||||
<Icon name="mdi:open-in-new" class="w-4 h-4 opacity-50 group-hover:opacity-100 transition-opacity" />
|
||||
<Icon name="open-in-new" class="w-4 h-4 opacity-50 group-hover:opacity-100 transition-opacity" />
|
||||
</h2>
|
||||
<p class="text-sm opacity-80 line-clamp-2 leading-relaxed">
|
||||
{talk.description}
|
||||
|
||||
@@ -118,12 +118,12 @@ const styles = StyleSheet.create({
|
||||
},
|
||||
progressBarBg: {
|
||||
height: 4,
|
||||
backgroundColor: "#E5E7EB", // bg-gray-200
|
||||
backgroundColor: "#E5E7EB",
|
||||
borderRadius: 2,
|
||||
},
|
||||
progressBarFill: {
|
||||
height: 4,
|
||||
backgroundColor: "#2563EB", // bg-blue-600
|
||||
backgroundColor: "#2563EB",
|
||||
borderRadius: 2,
|
||||
},
|
||||
// Education
|
||||
@@ -272,7 +272,7 @@ const AwardsSection = ({ awards }: { awards: ResumeData["awards"] }) => (
|
||||
interface ResumeDocumentProps {
|
||||
data: ResumeData;
|
||||
resumeConfig: any;
|
||||
icons: { [key: string]: string }; // Map of icon name to SVG path
|
||||
icons: { [key: string]: string };
|
||||
}
|
||||
|
||||
export const ResumeDocument = ({
|
||||
@@ -353,8 +353,8 @@ export const ResumeDocument = ({
|
||||
)}
|
||||
{data.basics.profiles?.map((profile: any, i: number) => (
|
||||
<View key={i} style={styles.contactItem}>
|
||||
{icons[profile.network] && (
|
||||
<Icon path={icons[profile.network]} />
|
||||
{icons[profile.network.toLowerCase()] && (
|
||||
<Icon path={icons[profile.network.toLowerCase()]} />
|
||||
)}
|
||||
<Link
|
||||
src={profile.url}
|
||||
|
||||
16
src/types.ts
16
src/types.ts
@@ -1,12 +1,6 @@
|
||||
import type { ImageMetadata } from "astro";
|
||||
import type { Component } from "vue";
|
||||
import type { GiteaRepoInfo } from "./utils/gitea";
|
||||
|
||||
// Icon Types
|
||||
export type LucideIcon = Component;
|
||||
export type AstroIconName = string;
|
||||
export type CustomIconComponent = Component;
|
||||
export type IconType = LucideIcon | AstroIconName | CustomIconComponent;
|
||||
import type { IconName } from "./config/icons";
|
||||
|
||||
export interface Talk {
|
||||
id: string;
|
||||
@@ -32,7 +26,7 @@ export interface SocialLink {
|
||||
id: string;
|
||||
name: string;
|
||||
url: string;
|
||||
icon: IconType;
|
||||
icon: IconName;
|
||||
ariaLabel: string;
|
||||
}
|
||||
|
||||
@@ -40,7 +34,7 @@ export interface TechLink {
|
||||
id: string;
|
||||
name: string;
|
||||
url: string;
|
||||
icon: IconType;
|
||||
icon: IconName;
|
||||
ariaLabel: string;
|
||||
}
|
||||
|
||||
@@ -49,7 +43,7 @@ export interface NavigationItem {
|
||||
name: string;
|
||||
path: string;
|
||||
tooltip: string;
|
||||
icon: IconType;
|
||||
icon: IconName;
|
||||
enabled?: boolean;
|
||||
isActive?: (path: string) => boolean;
|
||||
}
|
||||
@@ -64,7 +58,7 @@ export type ResumeSectionKey =
|
||||
| "awards";
|
||||
|
||||
export interface ResumeConfig {
|
||||
tomlFile: string; // Can be a file path or raw TOML content
|
||||
tomlFile: string;
|
||||
layout?: {
|
||||
leftColumn?: ResumeSectionKey[];
|
||||
rightColumn?: ResumeSectionKey[];
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
import { mdiEmail, mdiPhone, mdiDownload, mdiLink } from "@mdi/js";
|
||||
import * as simpleIcons from "simple-icons";
|
||||
|
||||
export function getSimpleIconPath(network: string): string {
|
||||
try {
|
||||
const slug = network.toLowerCase().normalize("NFKD").replace(/[^\w]/g, "");
|
||||
const iconKey = `si${slug.charAt(0).toUpperCase()}${slug.slice(1)}`;
|
||||
|
||||
const icon = (simpleIcons as any)[iconKey];
|
||||
return icon ? icon.path : "";
|
||||
} catch (error) {
|
||||
console.warn(`Error finding icon for network: ${network}`, error);
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
export function getMdiIconPath(iconName: string): string {
|
||||
const iconMap: { [key: string]: string } = {
|
||||
"mdi:email": mdiEmail,
|
||||
"mdi:phone": mdiPhone,
|
||||
"mdi:download": mdiDownload,
|
||||
"mdi:link": mdiLink,
|
||||
};
|
||||
return iconMap[iconName] || "";
|
||||
}
|
||||
|
||||
export const fetchProfileIcons = (profiles: any[]) => {
|
||||
const profileIcons: { [key: string]: string } = {};
|
||||
if (profiles) {
|
||||
for (const profile of profiles) {
|
||||
profileIcons[profile.network] = getSimpleIconPath(profile.network);
|
||||
}
|
||||
}
|
||||
return profileIcons;
|
||||
};
|
||||
Reference in New Issue
Block a user