From 6b87f411c6b061ad408666153f20cfa9ce11db13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luc=C3=A0s?= Date: Wed, 21 Dec 2022 15:32:27 +0100 Subject: [PATCH] Switch to Node.JS stack --- .gitignore | 3 + README.md | 62 ++++++++++-------- compile.sh | 1 - model/data.json | 134 --------------------------------------- model/macro.njk | 8 --- model/template.njk | 25 -------- src/config.json | 5 -- src/core.ts | 9 --- src/core/FooterBadge.ts | 6 ++ src/core/Link.ts | 7 ++ src/core/Log.ts | 32 ++++++++++ src/core/Skill.ts | 38 +++++++++++ src/data/footerBadges.ts | 18 ++++++ src/data/links.ts | 31 +++++++++ src/data/skills.ts | 37 +++++++++++ src/index.ts | 24 +++++++ views/README.njk | 24 +++++++ 17 files changed, 254 insertions(+), 210 deletions(-) delete mode 100644 compile.sh delete mode 100644 model/data.json delete mode 100644 model/macro.njk delete mode 100644 model/template.njk delete mode 100644 src/config.json delete mode 100644 src/core.ts create mode 100644 src/core/FooterBadge.ts create mode 100644 src/core/Link.ts create mode 100644 src/core/Log.ts create mode 100644 src/core/Skill.ts create mode 100644 src/data/footerBadges.ts create mode 100644 src/data/links.ts create mode 100644 src/data/skills.ts create mode 100644 src/index.ts create mode 100644 views/README.njk diff --git a/.gitignore b/.gitignore index 2fa6cce..d380386 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,6 @@ venv/* venv/**/* **/.DS_Store + +build/ +node_modules/ diff --git a/README.md b/README.md index 8431b84..0b2e693 100644 --- a/README.md +++ b/README.md @@ -1,46 +1,52 @@ - - # Hi, I'm Lucàs! 👋 ## 🚀 About Me -I'm a passionate developer from 🇫🇷 **Albi, France**. +I'm a passionate developer from 🇫🇷 **Albi, France**. ## 🔗 Links -[![portfolio](https://img.shields.io/badge/my_portfolio-000?style=for-the-badge&logo=ko-fi&logoColor=white)](https://lucasvbr.github.io/links/?portfolio) -[![linkedin](https://img.shields.io/badge/linkedin-0e76a8?style=for-the-badge&logo=linkedin&logoColor=white)](https://www.linkedin.com/in/lucasvbr) -[![freecodecamp](https://img.shields.io/badge/freecodecamp-0a0a23?style=for-the-badge&logo=freecodecamp&logoColor=white)](https://www.freecodecamp.org/LucasVbr) -[![openclassrooms](https://img.shields.io/badge/openclassrooms-7451eb?style=for-the-badge&logo=openclassrooms&logoColor=white)](https://openclassrooms.com/fr/members/97j9zltv6225) -[![exercism](https://img.shields.io/badge/exercism-2e57e8?style=for-the-badge&logo=exercism&logoColor=white)](https://exercism.org/profiles/LucasVbr) +[![Portfolio](https://img.shields.io/badge/my_portfolio-000?style=for-the-badge&logo=ko-fi&logoColor=white)](https://lucasvbr.github.io/links/?portfolio) +[![Linkedin Profile](https://img.shields.io/badge/linkedin-0e76a8?style=for-the-badge&logo=linkedin&logoColor=white)](https://www.linkedin.com/in/lucasvbr) +[![FreeCodeCamp Profile](https://img.shields.io/badge/freecodecamp-0a0a23?style=for-the-badge&logo=freecodecamp&logoColor=white)](https://www.freecodecamp.org/LucasVbr) +[![OpenClassRooms Profile](https://img.shields.io/badge/openclassrooms-7451eb?style=for-the-badge&logo=openclassrooms&logoColor=white)](https://openclassrooms.com/fr/members/97j9zltv6225) +[![Exercism Profile](https://img.shields.io/badge/exercism-2e57e8?style=for-the-badge&logo=exercism&logoColor=white)](https://exercism.org/profiles/LucasVbr) ## 🛠 Skills -![Angular](https://img.shields.io/static/v1?label=&message=Angular&color=%23df204a&logo=angular&logoColor=white) -![Symfony](https://img.shields.io/static/v1?label=&message=Symfony&color=%23df2020&logo=symfony&logoColor=white) -![Git](https://img.shields.io/static/v1?label=&message=Git&color=%23df3e20&logo=git&logoColor=white) -![HTML5](https://img.shields.io/static/v1?label=&message=HTML5&color=%23df4920&logo=html5&logoColor=white) -![Figma](https://img.shields.io/static/v1?label=&message=Figma&color=%23df4b20&logo=figma&logoColor=white) -![JavaScript](https://img.shields.io/static/v1?label=&message=JavaScript&color=%23dfca20&logo=javascript&logoColor=white) -![Bash](https://img.shields.io/static/v1?label=&message=GNU+Bash&color=%235bdf20&logo=gnubash&logoColor=white) -![Android](https://img.shields.io/static/v1?label=&message=Android&color=%2320df75&logo=android&logoColor=white) -![Bulma](https://img.shields.io/static/v1?label=&message=Bulma&color=%2320dfc3&logo=bulma&logoColor=white) -![MariaDB](https://img.shields.io/static/v1?label=&message=MariaDB&color=%2320b3df&logo=mariadb&logoColor=white) -![Java](https://img.shields.io/static/v1?label=&message=Java&color=%2320b2df&logo=java&logoColor=white) -![SQLite](https://img.shields.io/static/v1?label=&message=SQLite&color=%2320a2df&logo=sqlite&logoColor=white) -![CSS3](https://img.shields.io/static/v1?label=&message=CSS3&color=%23208edf&logo=css3&logoColor=white) -![MySQL](https://img.shields.io/static/v1?label=&message=MySQL&color=%23208ddf&logo=mysql&logoColor=white) -![Python](https://img.shields.io/static/v1?label=&message=Python&color=%232088df&logo=python&logoColor=white) -![C](https://img.shields.io/static/v1?label=&message=C&color=%23207adf&logo=c&logoColor=white) -![PostgreSQL](https://img.shields.io/static/v1?label=&message=PostgreSQL&color=%232050df&logo=postgresql&logoColor=white) -![PHP](https://img.shields.io/static/v1?label=&message=PHP&color=%23202cdf&logo=php&logoColor=white) -![Bootstrap](https://img.shields.io/static/v1?label=&message=Bootstrap&color=%236d20df&logo=bootstrap&logoColor=white) +![Android](https://img.shields.io/static/v1?label=&message=Android&color=3DDC84&logo=android&logoColor=white) +![Angular](https://img.shields.io/static/v1?label=&message=Angular&color=DD0031&logo=angular&logoColor=white) +![Bootstrap](https://img.shields.io/static/v1?label=&message=Bootstrap&color=7952B3&logo=bootstrap&logoColor=white) +![Bulma](https://img.shields.io/static/v1?label=&message=Bulma&color=00D1B2&logo=bulma&logoColor=white) +![C](https://img.shields.io/static/v1?label=&message=C&color=A8B9CC&logo=c&logoColor=white) +![CSS3](https://img.shields.io/static/v1?label=&message=CSS3&color=1572B6&logo=css3&logoColor=white) +![Deno](https://img.shields.io/static/v1?label=&message=Deno&color=000000&logo=deno&logoColor=white) +![Docker](https://img.shields.io/static/v1?label=&message=Docker&color=2496ED&logo=docker&logoColor=white) +![Express](https://img.shields.io/static/v1?label=&message=Express&color=000000&logo=express&logoColor=white) +![Figma](https://img.shields.io/static/v1?label=&message=Figma&color=F24E1E&logo=figma&logoColor=white) +![Git](https://img.shields.io/static/v1?label=&message=Git&color=F05032&logo=git&logoColor=white) +![GNU Bash](https://img.shields.io/static/v1?label=&message=GNU+Bash&color=4EAA25&logo=gnubash&logoColor=white) +![HTML5](https://img.shields.io/static/v1?label=&message=HTML5&color=E34F26&logo=html5&logoColor=white) +![JavaScript](https://img.shields.io/static/v1?label=&message=JavaScript&color=F7DF1E&logo=javascript&logoColor=white) +![MariaDB](https://img.shields.io/static/v1?label=&message=MariaDB&color=003545&logo=mariadb&logoColor=white) +![MongoDB](https://img.shields.io/static/v1?label=&message=MongoDB&color=47A248&logo=mongodb&logoColor=white) +![MySQL](https://img.shields.io/static/v1?label=&message=MySQL&color=4479A1&logo=mysql&logoColor=white) +![Node.js](https://img.shields.io/static/v1?label=&message=Node.js&color=339933&logo=nodedotjs&logoColor=white) +![OCaml](https://img.shields.io/static/v1?label=&message=OCaml&color=EC6813&logo=ocaml&logoColor=white) +![PHP](https://img.shields.io/static/v1?label=&message=PHP&color=777BB4&logo=php&logoColor=white) +![PostgreSQL](https://img.shields.io/static/v1?label=&message=PostgreSQL&color=4169E1&logo=postgresql&logoColor=white) +![Python](https://img.shields.io/static/v1?label=&message=Python&color=3776AB&logo=python&logoColor=white) +![React](https://img.shields.io/static/v1?label=&message=React&color=61DAFB&logo=react&logoColor=white) +![SQLite](https://img.shields.io/static/v1?label=&message=SQLite&color=003B57&logo=sqlite&logoColor=white) +![Symfony](https://img.shields.io/static/v1?label=&message=Symfony&color=000000&logo=symfony&logoColor=white) +![TypeScript](https://img.shields.io/static/v1?label=&message=TypeScript&color=3178C6&logo=typescript&logoColor=white) ---
-![Profile views](https://komarev.com/ghpvc/?username=lucasvbr&label=Profile%20views&color=0e75b6&style=flat) +![Profile Views](https://komarev.com/ghpvc/?username=lucasvbr&label=Profile%20views&color=0e75b6&style=flat) ![FreeCodeCamp Points](https://img.shields.io/freecodecamp/points/lucasvbr?label=FreeCodeCamp%20points) ![Made with love](https://img.shields.io/badge/-made%20with%20%E2%9D%A4%EF%B8%8F-red) +
\ No newline at end of file diff --git a/compile.sh b/compile.sh deleted file mode 100644 index 2c5e4c4..0000000 --- a/compile.sh +++ /dev/null @@ -1 +0,0 @@ -deno run --allow-write --allow-read src/core.ts \ No newline at end of file diff --git a/model/data.json b/model/data.json deleted file mode 100644 index 8abc87d..0000000 --- a/model/data.json +++ /dev/null @@ -1,134 +0,0 @@ -{ - "name": "Lucàs", - "about": "I'm a passionate developer from 🇫🇷 **Albi, France**.", - "links": [ - { - "href": "https://lucasvbr.github.io/links/?portfolio", - "img": { - "src": "https://img.shields.io/badge/my_portfolio-000?style=for-the-badge&logo=ko-fi&logoColor=white", - "alt": "portfolio" - } - }, - { - "href": "https://www.linkedin.com/in/lucasvbr", - "img": { - "src": "https://img.shields.io/badge/linkedin-0e76a8?style=for-the-badge&logo=linkedin&logoColor=white", - "alt": "linkedin" - } - }, - { - "href": "https://www.freecodecamp.org/LucasVbr", - "img": { - "src": "https://img.shields.io/badge/freecodecamp-0a0a23?style=for-the-badge&logo=freecodecamp&logoColor=white", - "alt": "freecodecamp" - } - }, - { - "href": "https://openclassrooms.com/fr/members/97j9zltv6225", - "img": { - "src": "https://img.shields.io/badge/openclassrooms-7451eb?style=for-the-badge&logo=openclassrooms&logoColor=white", - "alt": "openclassrooms" - } - }, - { - "href": "https://exercism.org/profiles/LucasVbr", - "img": { - "src": "https://img.shields.io/badge/exercism-2e57e8?style=for-the-badge&logo=exercism&logoColor=white", - "alt": "exercism" - } - } - - ], - "skills": [ - { - "src": "https://img.shields.io/static/v1?label=&message=Angular&color=%23df204a&logo=angular&logoColor=white", - "alt": "Angular" - }, - { - "src": "https://img.shields.io/static/v1?label=&message=Symfony&color=%23df2020&logo=symfony&logoColor=white", - "alt": "Symfony" - }, - { - "src": "https://img.shields.io/static/v1?label=&message=Git&color=%23df3e20&logo=git&logoColor=white", - "alt": "Git" - }, - { - "src": "https://img.shields.io/static/v1?label=&message=HTML5&color=%23df4920&logo=html5&logoColor=white", - "alt": "HTML5" - }, - { - "src": "https://img.shields.io/static/v1?label=&message=Figma&color=%23df4b20&logo=figma&logoColor=white", - "alt": "Figma" - }, - { - "src": "https://img.shields.io/static/v1?label=&message=JavaScript&color=%23dfca20&logo=javascript&logoColor=white", - "alt": "JavaScript" - }, - { - "src": "https://img.shields.io/static/v1?label=&message=GNU+Bash&color=%235bdf20&logo=gnubash&logoColor=white", - "alt": "Bash" - }, - { - "src": "https://img.shields.io/static/v1?label=&message=Android&color=%2320df75&logo=android&logoColor=white", - "alt": "Android" - }, - { - "src": "https://img.shields.io/static/v1?label=&message=Bulma&color=%2320dfc3&logo=bulma&logoColor=white", - "alt": "Bulma" - }, - { - "src": "https://img.shields.io/static/v1?label=&message=MariaDB&color=%2320b3df&logo=mariadb&logoColor=white", - "alt": "MariaDB" - }, - { - "src": "https://img.shields.io/static/v1?label=&message=Java&color=%2320b2df&logo=java&logoColor=white", - "alt": "Java" - }, - { - "src": "https://img.shields.io/static/v1?label=&message=SQLite&color=%2320a2df&logo=sqlite&logoColor=white", - "alt": "SQLite" - }, - { - "src": "https://img.shields.io/static/v1?label=&message=CSS3&color=%23208edf&logo=css3&logoColor=white", - "alt": "CSS3" - }, - { - "src": "https://img.shields.io/static/v1?label=&message=MySQL&color=%23208ddf&logo=mysql&logoColor=white", - "alt": "MySQL" - }, - { - "src": "https://img.shields.io/static/v1?label=&message=Python&color=%232088df&logo=python&logoColor=white", - "alt": "Python" - }, - { - "src": "https://img.shields.io/static/v1?label=&message=C&color=%23207adf&logo=c&logoColor=white", - "alt": "C" - }, - { - "src": "https://img.shields.io/static/v1?label=&message=PostgreSQL&color=%232050df&logo=postgresql&logoColor=white", - "alt": "PostgreSQL" - }, - { - "src": "https://img.shields.io/static/v1?label=&message=PHP&color=%23202cdf&logo=php&logoColor=white", - "alt": "PHP" - }, - { - "src": "https://img.shields.io/static/v1?label=&message=Bootstrap&color=%236d20df&logo=bootstrap&logoColor=white", - "alt": "Bootstrap" - } - ], - "badges": [ - { - "src": "https://komarev.com/ghpvc/?username=lucasvbr&label=Profile%20views&color=0e75b6&style=flat", - "alt": "Profile views" - }, - { - "src": "https://img.shields.io/freecodecamp/points/lucasvbr?label=FreeCodeCamp%20points", - "alt": "FreeCodeCamp Points" - }, - { - "src": "https://img.shields.io/badge/-made%20with%20%E2%9D%A4%EF%B8%8F-red", - "alt": "Made with love" - } - ] -} \ No newline at end of file diff --git a/model/macro.njk b/model/macro.njk deleted file mode 100644 index 63a3944..0000000 --- a/model/macro.njk +++ /dev/null @@ -1,8 +0,0 @@ -{% macro a(src, alt) -%} - [{{ alt }}]({{ src }}) -{%- endmacro %} - -{% macro img(src, alt) -%} - !{{ a(src, alt) }} -{%- endmacro %} - diff --git a/model/template.njk b/model/template.njk deleted file mode 100644 index f9ea485..0000000 --- a/model/template.njk +++ /dev/null @@ -1,25 +0,0 @@ -{% from "model/macro.njk" import a, img with context %} - -# Hi, I'm {{ name }}! 👋 - -## 🚀 About Me -{{ about }} - -## 🔗 Links -{% for link in links -%} - {{ a(link.href, img(link.img.src, link.img.alt)) }} -{% endfor %} - -## 🛠 Skills -{% for skill in skills -%} - {{ img(skill.src, skill.alt) }} -{% endfor %} - ---- - -
- -{% for badge in badges -%} - {{ img(badge.src, badge.alt) }} -{% endfor %} -
\ No newline at end of file diff --git a/src/config.json b/src/config.json deleted file mode 100644 index 8de3499..0000000 --- a/src/config.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "template": "model/template.njk", - "data": "model/data.json", - "output": "README.md" -} \ No newline at end of file diff --git a/src/core.ts b/src/core.ts deleted file mode 100644 index fc54c19..0000000 --- a/src/core.ts +++ /dev/null @@ -1,9 +0,0 @@ -import denjucks from "https://deno.land/x/denjucks/mod.js"; - -let { template, data, output } = JSON.parse(await Deno.readTextFile("src/config.json")); - -template = await Deno.readTextFile(template); -data = JSON.parse(await Deno.readTextFile(data)); - -const result = denjucks.renderString(template, data); -await Deno.writeTextFile(output, result); \ No newline at end of file diff --git a/src/core/FooterBadge.ts b/src/core/FooterBadge.ts new file mode 100644 index 0000000..54658f5 --- /dev/null +++ b/src/core/FooterBadge.ts @@ -0,0 +1,6 @@ +type FooterBadge = { + title: string + shield: string +} + +export default FooterBadge; \ No newline at end of file diff --git a/src/core/Link.ts b/src/core/Link.ts new file mode 100644 index 0000000..b436dae --- /dev/null +++ b/src/core/Link.ts @@ -0,0 +1,7 @@ +type Link = { + title: string + shield: string + url: string +} + +export default Link; \ No newline at end of file diff --git a/src/core/Log.ts b/src/core/Log.ts new file mode 100644 index 0000000..eb23d45 --- /dev/null +++ b/src/core/Log.ts @@ -0,0 +1,32 @@ +class Log { + colors = { + red: '\x1b[31m', + green: '\x1b[32m', + yellow: '\x1b[33m', + }; + + private readonly logFunction: (message?: any, ...optionalParams: any[]) => void; + + constructor(logFunction: (message?: any, ...optionalParams: any[]) => void) { + this.logFunction = logFunction; + } + + info(message: string): void { + this.logFunction(message); + } + + success(message: string): void { + this.logFunction(this.colors.green, message); + } + + error(message: string): void { + this.logFunction(this.colors.red, message); + } + + warning(message: string): void { + this.logFunction(this.colors.yellow, message); + } +} + +const log = new Log(console.log); +export default log; diff --git a/src/core/Skill.ts b/src/core/Skill.ts new file mode 100644 index 0000000..9b9b02d --- /dev/null +++ b/src/core/Skill.ts @@ -0,0 +1,38 @@ +import {SimpleIcon} from 'simple-icons/types'; + +export default class Skill { + private title: string; + private slug: string; + private shield: string; + + constructor(icon: SimpleIcon) { + this.title = icon.title; + this.slug = icon.slug; + this.shield = this.buildShield(icon); + } + + private buildShield(icon: SimpleIcon): string { + const baseUrl = 'https://img.shields.io/static/v1'; + const params = { + label: '', + message: icon.title, + color: icon.hex, + logo: icon.slug, + logoColor: 'white', + }; + + const shieldUrl = new URL(baseUrl); + Object.entries(params).forEach(param => { + const [key, value] = param; + shieldUrl.searchParams.append(key, value); + }); + + return shieldUrl.toString(); + } + + public static sortBySlug(a: Skill, b: Skill) { + if (a.slug < b.slug) return -1; + if (a.slug > b.slug) return 1; + return 0; + } +} \ No newline at end of file diff --git a/src/data/footerBadges.ts b/src/data/footerBadges.ts new file mode 100644 index 0000000..63d7b40 --- /dev/null +++ b/src/data/footerBadges.ts @@ -0,0 +1,18 @@ +import FooterBadge from '../core/FooterBadge'; + +const footerBadges: FooterBadge[] = [ + { + title: 'Profile Views', + shield: 'https://komarev.com/ghpvc/?username=lucasvbr&label=Profile%20views&color=0e75b6&style=flat', + }, + { + title: "FreeCodeCamp Points", + shield: "https://img.shields.io/freecodecamp/points/lucasvbr?label=FreeCodeCamp%20points" + }, + { + title: "Made with love", + shield: "https://img.shields.io/badge/-made%20with%20%E2%9D%A4%EF%B8%8F-red" + } +]; + +export default footerBadges; \ No newline at end of file diff --git a/src/data/links.ts b/src/data/links.ts new file mode 100644 index 0000000..06c810c --- /dev/null +++ b/src/data/links.ts @@ -0,0 +1,31 @@ +import Link from '../core/Link'; + +const links: Link[] = [ + { + title: 'Portfolio', + shield: 'https://img.shields.io/badge/my_portfolio-000?style=for-the-badge&logo=ko-fi&logoColor=white', + url: 'https://lucasvbr.github.io/links/?portfolio', + }, + { + title: 'Linkedin Profile', + shield: 'https://img.shields.io/badge/linkedin-0e76a8?style=for-the-badge&logo=linkedin&logoColor=white', + url: 'https://www.linkedin.com/in/lucasvbr', + }, + { + title: 'FreeCodeCamp Profile', + shield: 'https://img.shields.io/badge/freecodecamp-0a0a23?style=for-the-badge&logo=freecodecamp&logoColor=white', + url: 'https://www.freecodecamp.org/LucasVbr', + }, + { + title: 'OpenClassRooms Profile', + shield: 'https://img.shields.io/badge/openclassrooms-7451eb?style=for-the-badge&logo=openclassrooms&logoColor=white', + url: 'https://openclassrooms.com/fr/members/97j9zltv6225', + }, + { + title: 'Exercism Profile', + shield: 'https://img.shields.io/badge/exercism-2e57e8?style=for-the-badge&logo=exercism&logoColor=white', + url: 'https://exercism.org/profiles/LucasVbr', + }, +]; + +export default links; \ No newline at end of file diff --git a/src/data/skills.ts b/src/data/skills.ts new file mode 100644 index 0000000..73c4749 --- /dev/null +++ b/src/data/skills.ts @@ -0,0 +1,37 @@ +import {SimpleIcon} from 'simple-icons/types'; +import icons from 'simple-icons'; +import Skill from '../core/Skill'; + +const LIST_OF_ICONS: SimpleIcon[] = [ + icons.siAngular, + icons.siSymfony, + icons.siGit, + icons.siHtml5, + icons.siFigma, + icons.siJavascript, + icons.siGnubash, + icons.siAndroid, + icons.siBulma, + icons.siMariadb, + icons.siSqlite, + icons.siCss3, + icons.siMysql, + icons.siPython, + icons.siC, + icons.siPostgresql, + icons.siPhp, + icons.siBootstrap, + icons.siExpress, + icons.siNodedotjs, + icons.siDeno, + icons.siTypescript, + icons.siOcaml, + icons.siMongodb, + icons.siReact, + icons.siDocker, +]; + +export default function getSkills(): Skill[] { + return LIST_OF_ICONS.map((icon: SimpleIcon) => new Skill(icon)). + sort(Skill.sortBySlug); +} \ No newline at end of file diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000..6fc54ff --- /dev/null +++ b/src/index.ts @@ -0,0 +1,24 @@ +import {writeFile} from 'fs/promises'; +import nunjucks from 'nunjucks'; +import getSkills from './data/skills'; +import Skill from './core/Skill'; +import log from './core/Log'; +import links from './data/links'; +import footerBadges from './data/footerBadges'; + +const TEMPLATE_FILE: string = 'README.njk'; +const OUTPUT_FILE: string = 'README.md'; + +const skills: Skill[] = getSkills(); + +nunjucks.configure('views/'); +nunjucks.render(TEMPLATE_FILE, {skills, links, footerBadges}, (err, renderView : string | null) => { + if (err) { + log.error(err.message) + return; + } + + writeFile(OUTPUT_FILE, renderView ?? "") + .then(() => log.success(`${OUTPUT_FILE} successfully generated`)) + .catch((err: string) => console.error(err)); +}); \ No newline at end of file diff --git a/views/README.njk b/views/README.njk new file mode 100644 index 0000000..9532cea --- /dev/null +++ b/views/README.njk @@ -0,0 +1,24 @@ +# Hi, I'm Lucàs! 👋 + +## 🚀 About Me +I'm a passionate developer from 🇫🇷 **Albi, France**. + +## 🔗 Links +{% for link in links -%} + [![{{link.title}}]({{link.shield}})]({{link.url}}) +{% endfor %} + +## 🛠 Skills +{% for skill in skills -%} + ![{{skill.title}}]({{skill.shield}}) +{% endfor %} + +--- + +
+ +{% for badge in footerBadges -%} + ![{{badge.title}}]({{badge.shield}}) +{% endfor %} + +
\ No newline at end of file