add details views
continuous-integration/drone/push Build is failing Details

main
Lucas DELANIER 10 months ago
parent 11289b890e
commit c027cc92d6

249
package-lock.json generated

@ -10,9 +10,13 @@
"dependencies": {
"dotenv": "^16.4.5",
"lottie-vuejs": "^0.4.0",
"markdown-it": "^14.1.0",
"marked": "^12.0.2",
"vite-svg-loader": "^5.1.0",
"vue": "^3.4.21",
"vue-i18n": "^9.13.1",
"vue-markdown": "^2.2.4",
"vue-router": "^4.3.2",
"vue-svg-loader": "^0.16.0",
"vue3-lottie": "^3.3.0"
},
@ -1307,6 +1311,14 @@
"node": ">= 6"
}
},
"node_modules/clone": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz",
"integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==",
"engines": {
"node": ">=0.8"
}
},
"node_modules/coa": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/coa/-/coa-2.0.2.tgz",
@ -2193,6 +2205,16 @@
"he": "bin/he"
}
},
"node_modules/highlight.js": {
"version": "9.18.5",
"resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-9.18.5.tgz",
"integrity": "sha512-a5bFyofd/BHCX52/8i8uJkjr9DYwXIPnM/plwI6W7ezItLGqzt7X2G2nXuYSfsIJdkwwj/g9DG1LkcGJI/dDoA==",
"deprecated": "Support has ended for 9.x series. Upgrade to @latest",
"hasInstallScript": true,
"engines": {
"node": "*"
}
},
"node_modules/internal-slot": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz",
@ -2517,6 +2539,17 @@
"json5": "lib/cli.js"
}
},
"node_modules/katex": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/katex/-/katex-0.6.0.tgz",
"integrity": "sha512-rS4mY3SvHYg5LtQV6RBcK0if7ur6plyEukAOV+jGGPqFImuzu8fHL6M752iBmRGoUyF0bhZbAPoezehn7xYksA==",
"dependencies": {
"match-at": "^0.1.0"
},
"bin": {
"katex": "cli.js"
}
},
"node_modules/klona": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/klona/-/klona-2.0.6.tgz",
@ -2540,6 +2573,14 @@
"integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
"dev": true
},
"node_modules/linkify-it": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz",
"integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==",
"dependencies": {
"uc.micro": "^2.0.0"
}
},
"node_modules/loader-utils": {
"version": "1.4.2",
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.2.tgz",
@ -2590,11 +2631,115 @@
"@jridgewell/sourcemap-codec": "^1.4.15"
}
},
"node_modules/markdown-it": {
"version": "14.1.0",
"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz",
"integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==",
"dependencies": {
"argparse": "^2.0.1",
"entities": "^4.4.0",
"linkify-it": "^5.0.0",
"mdurl": "^2.0.0",
"punycode.js": "^2.3.1",
"uc.micro": "^2.1.0"
},
"bin": {
"markdown-it": "bin/markdown-it.mjs"
}
},
"node_modules/markdown-it-abbr": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/markdown-it-abbr/-/markdown-it-abbr-1.0.4.tgz",
"integrity": "sha512-ZeA4Z4SaBbYysZap5iZcxKmlPL6bYA8grqhzJIHB1ikn7njnzaP8uwbtuXc4YXD5LicI4/2Xmc0VwmSiFV04gg=="
},
"node_modules/markdown-it-deflist": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/markdown-it-deflist/-/markdown-it-deflist-2.1.0.tgz",
"integrity": "sha512-3OuqoRUlSxJiuQYu0cWTLHNhhq2xtoSFqsZK8plANg91+RJQU1ziQ6lA2LzmFAEes18uPBsHZpcX6We5l76Nzg=="
},
"node_modules/markdown-it-emoji": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/markdown-it-emoji/-/markdown-it-emoji-1.4.0.tgz",
"integrity": "sha512-QCz3Hkd+r5gDYtS2xsFXmBYrgw6KuWcJZLCEkdfAuwzZbShCmCfta+hwAMq4NX/4xPzkSHduMKgMkkPUJxSXNg=="
},
"node_modules/markdown-it-footnote": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/markdown-it-footnote/-/markdown-it-footnote-2.0.0.tgz",
"integrity": "sha512-GMWkJXSHh5tiQt77zCLOSZI2Xy3Oqdb82GmT0Q0h2UT6SbUrMCAiHEiMBIt5V7Xfm73rBxS0VOhlLndkn1GPnw=="
},
"node_modules/markdown-it-ins": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/markdown-it-ins/-/markdown-it-ins-2.0.0.tgz",
"integrity": "sha512-DhLLxseIg2C7+AULvoyVI+zMeufR0QFvXJ2o0oV013hN5HvBvNh2rbVtTdxZjI959+hgo2AA0aRdtEIUaKPbhg=="
},
"node_modules/markdown-it-katex": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/markdown-it-katex/-/markdown-it-katex-2.0.3.tgz",
"integrity": "sha512-nUkkMtRWeg7OpdflamflE/Ho/pWl64Lk9wNBKOmaj33XkQdumhXAIYhI0WO03GeiycPCsxbmX536V5NEXpC3Ng==",
"dependencies": {
"katex": "^0.6.0"
}
},
"node_modules/markdown-it-mark": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/markdown-it-mark/-/markdown-it-mark-2.0.0.tgz",
"integrity": "sha512-iT8ua0Bda8QrVwHDOUNw1eyCuL7irXeYch5n8zGS4tb7wsDIn7EjQZLjihKaijzBiL0ikfWL2zAvL/ECqTvsNA=="
},
"node_modules/markdown-it-sub": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/markdown-it-sub/-/markdown-it-sub-1.0.0.tgz",
"integrity": "sha512-z2Rm/LzEE1wzwTSDrI+FlPEveAAbgdAdPhdWarq/ZGJrGW/uCQbKAnhoCsE4hAbc3SEym26+W2z/VQB0cQiA9Q=="
},
"node_modules/markdown-it-sup": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/markdown-it-sup/-/markdown-it-sup-1.0.0.tgz",
"integrity": "sha512-E32m0nV9iyhRR7CrhnzL5msqic7rL1juWre6TQNxsnApg7Uf+F97JOKxUijg5YwXz86lZ0mqfOnutoryyNdntQ=="
},
"node_modules/markdown-it-task-lists": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/markdown-it-task-lists/-/markdown-it-task-lists-2.1.1.tgz",
"integrity": "sha512-TxFAc76Jnhb2OUu+n3yz9RMu4CwGfaT788br6HhEDlvWfdeJcLUsxk1Hgw2yJio0OXsxv7pyIPmvECY7bMbluA=="
},
"node_modules/markdown-it-toc-and-anchor": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/markdown-it-toc-and-anchor/-/markdown-it-toc-and-anchor-4.2.0.tgz",
"integrity": "sha512-DusSbKtg8CwZ92ztN7bOojDpP4h0+w7BVOPuA3PHDIaabMsERYpwsazLYSP/UlKedoQjOz21mwlai36TQ04EpA==",
"dependencies": {
"clone": "^2.1.0",
"uslug": "^1.0.4"
}
},
"node_modules/markdown-it/node_modules/argparse": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="
},
"node_modules/marked": {
"version": "12.0.2",
"resolved": "https://registry.npmjs.org/marked/-/marked-12.0.2.tgz",
"integrity": "sha512-qXUm7e/YKFoqFPYPa3Ukg9xlI5cyAtGmyEIzMfW//m6kXwCy2Ps9DYf5ioijFKQ8qyuscrHoY04iJGctu2Kg0Q==",
"bin": {
"marked": "bin/marked.js"
},
"engines": {
"node": ">= 18"
}
},
"node_modules/match-at": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/match-at/-/match-at-0.1.1.tgz",
"integrity": "sha512-h4Yd392z9mST+dzc+yjuybOGFNOZjmXIPKWjxBd1Bb23r4SmDOsk2NYCU2BMUBGbSpZqwVsZYNq26QS3xfaT3Q=="
},
"node_modules/mdn-data": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.4.tgz",
"integrity": "sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA=="
},
"node_modules/mdurl": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz",
"integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w=="
},
"node_modules/merge2": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
@ -3034,6 +3179,14 @@
"integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==",
"dev": true
},
"node_modules/punycode.js": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz",
"integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==",
"engines": {
"node": ">=6"
}
},
"node_modules/q": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz",
@ -3720,6 +3873,11 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/uc.micro": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz",
"integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A=="
},
"node_modules/unbox-primitive": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz",
@ -3734,6 +3892,14 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/unorm": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/unorm/-/unorm-1.6.0.tgz",
"integrity": "sha512-b2/KCUlYZUeA7JFUuRJZPUtr4gZvBh7tavtv4fvk4+KV9pfGiR6CQAQAWl49ZpR3ts2dk4FYkP7EIgDJoiOLDA==",
"engines": {
"node": ">= 0.4.0"
}
},
"node_modules/unquote": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/unquote/-/unquote-1.1.1.tgz",
@ -3769,6 +3935,17 @@
"browserslist": ">= 4.21.0"
}
},
"node_modules/uslug": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/uslug/-/uslug-1.0.4.tgz",
"integrity": "sha512-Jrbpp/NS3TvIGNjfJT1sn3/BCeykoxR8GbNYW5lF6fUscLkbXFwj1b7m4DvIkHm8k3Qr6Co68lbTmoZTMGk/ow==",
"dependencies": {
"unorm": ">= 1.0.0"
},
"engines": {
"node": ">= 0.4.0"
}
},
"node_modules/util-deprecate": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
@ -4059,6 +4236,78 @@
"vue": "^3.0.0"
}
},
"node_modules/vue-markdown": {
"version": "2.2.4",
"resolved": "https://registry.npmjs.org/vue-markdown/-/vue-markdown-2.2.4.tgz",
"integrity": "sha512-hoTX/W1UIdHZrp/b0vpHSsJXAEfWsafaQLgtE2VX4gY8O/C3L2Gabqu95gyG429rL4ML1SwGv+xsPABX7yfFIQ==",
"dependencies": {
"highlight.js": "^9.12.0",
"markdown-it": "^6.0.1",
"markdown-it-abbr": "^1.0.3",
"markdown-it-deflist": "^2.0.1",
"markdown-it-emoji": "^1.1.1",
"markdown-it-footnote": "^2.0.0",
"markdown-it-ins": "^2.0.0",
"markdown-it-katex": "^2.0.3",
"markdown-it-mark": "^2.0.0",
"markdown-it-sub": "^1.0.0",
"markdown-it-sup": "^1.0.0",
"markdown-it-task-lists": "^2.0.1",
"markdown-it-toc-and-anchor": "^4.1.2"
}
},
"node_modules/vue-markdown/node_modules/entities": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz",
"integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w=="
},
"node_modules/vue-markdown/node_modules/linkify-it": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-1.2.4.tgz",
"integrity": "sha512-eGHwtlABkp1NOJSiKUNqBf3SYAS5jPHtvRXPAgNaQwTqmkTahjtiLH9NtxdR5IOPhNvwNMN/diswSfZKzUkhGg==",
"dependencies": {
"uc.micro": "^1.0.1"
}
},
"node_modules/vue-markdown/node_modules/markdown-it": {
"version": "6.1.1",
"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-6.1.1.tgz",
"integrity": "sha512-woFl7h/sqt9xRmiMweNuO7nu+w8Lz3SXsDlvE3TYeu1SdPqQ+VW4GZyaKP442Bq6XUN6V6IQjJTR93RDYG2mjw==",
"dependencies": {
"argparse": "^1.0.7",
"entities": "~1.1.1",
"linkify-it": "~1.2.2",
"mdurl": "~1.0.1",
"uc.micro": "^1.0.1"
},
"bin": {
"markdown-it": "bin/markdown-it.js"
}
},
"node_modules/vue-markdown/node_modules/mdurl": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz",
"integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g=="
},
"node_modules/vue-markdown/node_modules/uc.micro": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz",
"integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA=="
},
"node_modules/vue-router": {
"version": "4.3.2",
"resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.3.2.tgz",
"integrity": "sha512-hKQJ1vDAZ5LVkKEnHhmm1f9pMiWIBNGF5AwU67PdH7TyXCj/a4hTccuUuYCAMgJK6rO/NVYtQIEN3yL8CECa7Q==",
"dependencies": {
"@vue/devtools-api": "^6.5.1"
},
"funding": {
"url": "https://github.com/sponsors/posva"
},
"peerDependencies": {
"vue": "^3.2.0"
}
},
"node_modules/vue-svg-loader": {
"version": "0.16.0",
"resolved": "https://registry.npmjs.org/vue-svg-loader/-/vue-svg-loader-0.16.0.tgz",

@ -11,9 +11,13 @@
"dependencies": {
"dotenv": "^16.4.5",
"lottie-vuejs": "^0.4.0",
"markdown-it": "^14.1.0",
"marked": "^12.0.2",
"vite-svg-loader": "^5.1.0",
"vue": "^3.4.21",
"vue-i18n": "^9.13.1",
"vue-markdown": "^2.2.4",
"vue-router": "^4.3.2",
"vue-svg-loader": "^0.16.0",
"vue3-lottie": "^3.3.0"
},

@ -6,7 +6,6 @@
"about": "About",
"skills": "Skills",
"experiences": "Experiences",
"projects": "Projects",
"welcome-message": "Hey, I'm Lucas",
"catch-phrase": "Developer & <br> Designer of applications",
"banner": {
@ -26,5 +25,10 @@
"highlight": " six essential pillars",
"end": ""
}
},
"projects": {
"title": "Projects",
"find-more": "Find more...",
"repository": "Repository"
}
}

@ -6,7 +6,6 @@
"about": "À propos",
"skills": "Compétences",
"experiences": "Expériences",
"projects": "Projets",
"welcome-message": "Salut, je suis Lucas",
"catch-phrase": "Developpeur & <br> Designer d'applications",
"banner": {
@ -26,5 +25,10 @@
"highlight": " six piliers",
"end": "essentiels."
}
},
"projects": {
"title": "Projets",
"find-more": "En savoir plus...",
"repository": "Dépôt de code"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 549 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 306 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 204 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 197 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 209 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 417 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 796 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 729 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 520 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 153 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 210 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 386 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 195 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 544 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 410 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 408 KiB

@ -1,279 +1,9 @@
<script setup>
import HeaderContainer from './components/HeaderContainer.vue'
import HeroContainer from './components/HeroContainer.vue';
import ShowcaseBanner from "./components/ShowcaseBanner.vue";
import GridSkill from "./components/GridSkill.vue";
import BannerCell from "./components/BannerCell.vue";
import ListExperience from "./components/ListExperience.vue";
import ExperienceCell from "./components/ExperienceCell.vue";
import {ref, onMounted, onUnmounted, computed} from 'vue';
import ProjectShow from "./components/ProjectShow.vue";
import Footer from "./components/Footer.vue";
const langages = [
{ name: 'Vue.js', image: 'vuejs.png' },
{ name: 'Flutter', image: 'flutter.png' },
{ name: 'React', image: 'react.png' },
{ name: 'JavaScript', image: 'javascript.png' },
{ name: 'Swift', image: 'swift.png' },
{ name: 'HTML', image: 'html.png' },
{ name: 'Python', image: 'python.png' }
];
const experiences = [
{
duration: "10 semaines",
year: "2023",
image: "inrae-blue.png",
company: "INRAE",
description: "Stage de 10 semaines portant sur lélaboration dun jeu sérieux (quizz) sur un site web à " +
"destination des chercheurs pour les aider dans leurs recherches sur lalimentation et lactivité " +
"physique des jeunes français.<br><br>Jai mis en pratique mes compétences à concevoir et optimiser une " +
"application existante ainsi qu'à faire des choix techniques décisifs. Jai également su gérer la gestion " +
"de ce projet en mettant en place des pratiques propres aux méthodes agiles telles que la méthode " +
"SCRUM.<br><br>Jai eu à utiliser des technologies du Web comme PHP, HTML & CSS ainsi que Bootstrap. " +
"Pour la gestion des données, jai mis en place une base de données SQL. Nous avons également dû porter " +
"une attention toute particulière au RGPD en raison de la manipulation de données de santé sensibles.",
important: true
},
{
duration: "2 mois",
year: "2023",
image: "inrae-grey.png",
company: "INRAE",
description: "CDD de 2 mois pour réaliser une version mobile multiplateforme en utilisant Flutter.",
important: false
},
{
duration: "1 an",
year: "2024",
image: "cikaba-blue.png",
company: "Cikaba",
description: "Alternance d'un an.<br><br>Jai eu lopportunité de rejoindre une équipe dynamique et agréable " +
"qui ma permis de me professionnaliser dans un contexte favorable. Jai travaillé en tant que développeur " +
"frontend.<br><br>Ma mission consistait principalement à lélaboration dune application web en Vue.js qui " +
"sert de plateforme SSO pour centraliser lauthentification des utilisateurs sur une application.<br><br>Jai "+
"également pu mettre en pratique mes compétences en design dinterface pour produire des maquettes et " +
"prototypes afin daméliorer lesthétique des applications en cours de développement.",
important: true
},
{
duration: "2 ans",
year: "2024-2026",
image: "cikaba-grey.png",
company: "Cikaba",
description: "Je vais poursuivre mon aventure chez Cikaba, en alternance, dans le cadre d'un Mastère Expert " +
"en ingénierie logicielle.",
important: false
},
];
const projects = [
{application: "MovieFinder", title: "J'ai créé l'application", image:"moviefinder-mockup.png"},
{application: "JustMusic", title: "J'ai co-créé l'application", image:"justmusic-mockup.png"},
{application: "Allin", title: "J'ai co-créé l'application", image:"allin-mockup.png"},
{application: "Compagnon", title: "J'ai créé l'application", image:"compagnon-mockup.png"},
]
const currentProjectIndex = ref(0);
const currentProject = computed(() => {
return Math.floor(currentProjectIndex.value);
});
const percentY = ref(0);
const opacity = ref(0);
const progress = ref(0);
// Variable to track if middle text is visible
const visibleTextIndex = ref(0);
// Function to check if middle text is visible
const checkVisibleTextIndex = () => {
const textElements = document.querySelectorAll('.magic-div > span');
textElements.forEach((element, index) => {
const bounding = element.getBoundingClientRect(); // Getting the position of each <p> element
if (bounding.top <= window.innerHeight - 500 && bounding.bottom >= 0) {
visibleTextIndex.value = index;
}
});
updateValue();
};
const updateValue = () => {
const elContainer = document.querySelector('.magic-showcase');
if (elContainer) {
const screenH = window.innerHeight;
const halfH = screenH / 2;
const clientHeight = elContainer.clientHeight;
const offsetTop = elContainer.offsetTop;
percentY.value =
Math.min(clientHeight + halfH, Math.max(-screenH, window.scrollY - offsetTop) + halfH) /
clientHeight;
currentProjectIndex.value = Math.max(0, percentY.value * projects.length);
}
progress.value = Math.max(0, currentProjectIndex.value - currentProject.value);
opacity.value = Math.min(1, Math.max(0, progress.value * 4));
if (progress.value > 0.85 && currentProject.value < projects.length - 1) {
opacity.value= Math.max(0, (1.0 - progress.value) * 4);
}
};
// Hook to add and remove scroll event listener
onMounted(() => {
window.addEventListener('scroll', checkVisibleTextIndex);
});
onUnmounted(() => {
window.removeEventListener('scroll', checkVisibleTextIndex);
});
</script>
<template>
<div class=" absolute pointer-events-none w-full h-full overflow-hidden">
<transition name="fadeImage" appear>
<img src="/images/camera-effect.png" class="top-10 right-10 w-full h-full object-cover z-0 scale-110"
alt="" width="1512" height="1071" role="presentation">
</transition>
<img src="/images/filter.png" class="fixed bottom-0 right-0 w-full object-cover z-50 opacity-70"
alt="" width="1508" height="1376" role="presentation">
</div>
<transition name="fade" appear>
<HeaderContainer id="about"></HeaderContainer>
</transition>
<HeroContainer class=" mt-6 sm:mt-14"/>
<ShowcaseBanner class=" mt-24 sm:mt-36 z-10 relative">
<BannerCell number="1" label="ANNEE <br> D'EXPERIENCE"/>
<BannerCell number="8" label="PROJETS <br> REALISES"/>
<BannerCell number="+" label="FRONT-END <br> BACK-END"/>
<BannerCell number="+" label="UI/UX <br> DESIGN"/>
</ShowcaseBanner>
<div class="flex-col flex pt-24 sm:pt-48 pb-28 z-10 relative bg-black" id="skills">
<span class="mx-4 text-3xl sm:text-4xl text-center font-medium bg-gradient-to-r from-grey-50
to-grey-100 bg-clip-text text-transparent px-10 " role="heading">
{{ $t('skills-list.title.start')}}
<span class="bg-blue text-white hover:bg-transparent hover:text-grey-75 ease-in-out transition-all duration-1000"
role="heading">
{{ $t('skills-list.title.highlight')}}
</span>
<br>
{{ $t('skills-list.title.end')}}
</span>
<GridSkill class="mx-8 sm:mx-28 py-28"/>
</div>
<ShowcaseBanner>
<img v-for="langage in langages"
:src="`https://codefirst.iut.uca.fr/containers/lucasdelanier-portfolio/images/${ langage.image}`"
class="w-18 h-18 hover:-translate-y-1 transition-all duration-300 ease-in-out hover:rotate-12 origin-center"
:alt="langage.name" width="64" height="64"/>
</ShowcaseBanner>
<div class="flex-col flex pt-48 z-10 relative" id="experiences">
<span class="mx-4 text-3xl sm:text-4xl text-center font-medium bg-gradient-to-r from-grey-50 to-grey-100
bg-clip-text text-transparent" role="heading">
Des expériences
<span class="bg-blue text-white hover:bg-transparent hover:text-grey-75 ease-in-out transition-all duration-1000"
role="heading">
professionnelles
</span>
qui mont
<br>
énormément apportées.
</span>
<ListExperience>
<ExperienceCell v-for="experience in experiences" v-bind="experience" />
</ListExperience>
</div>
<div class="flex-col flex z-50 justify-center align-middle px-14 sm:px-64 pb-14 sm:pb-96 top-0 ">
<div class="magic-div flex flex-col justify-center align-middle sticky py-60 sm:py-72">
<span :class="{ 'text-white scale-101': visibleTextIndex === 0, 'text-gray-600': visibleTextIndex !== 0 }"
class="text-4xl sm:text-7xl font-bold transition-all ease-in-out duration-500" role="heading">
Jai toujours envie de coder de nouveaux projets.
</span>
<span :class="{ 'text-white scale-101': visibleTextIndex === 1, 'text-gray-600': visibleTextIndex !== 1 }"
class="text-4xl sm:text-7xl font-bold transition-all ease-in-out duration-500" role="heading">
Cette passion me pousse à créer des expériences.
</span>
<span :class="{ 'text-white scale-101': visibleTextIndex === 2, 'text-gray-600': visibleTextIndex !== 2 }"
class="text-4xl sm:text-7xl font-bold transition-all ease-in-out duration-500" role="heading">
Jaime me réinventer et jouer avec les
<span :class="{ 'text-yellow-300': visibleTextIndex === 2, 'text-gray-600': visibleTextIndex !== 2 }"
class="transition-all ease-in-out duration-700" role="heading">
couleurs
</span>
et les
<span :class="{ 'text-white': visibleTextIndex === 2, 'text-gray-600': visibleTextIndex !== 2 }"
class="transition-all ease-in-out duration-700" role="heading">
formes
</span>
.
</span>
</div>
<div class="flex h-50 w-full"/>
</div>
<div class="flex h-300 w-full relative z-10 top-0 magic-showcase width-container"
:style="{ height: projects.length * 100 + 'vh'}">
<div class="absolute h-full w-full">
<div class="sticky top-0 grid min-h-screen w-full grid-cols-1 lg:grid-cols-2">
<div class="h-[30vh] bg-black lg:h-auto"></div>
<div class="h-[70vh] bg-white lg:h-auto"></div>
</div>
</div>
<div class="sticky top-0 h-screen overflow-hidden w-full" id="projects">
<ProjectShow :text="`J'ai réalisé l'application`"
:application="projects[currentProject].application"
:image="projects[currentProject].image"
:title="projects[currentProject].title"
:opacity="opacity"
:progress="progress"/>
</div>
</div>
<Footer></Footer>
<main>
<RouterView />
</main>
</template>
<style scoped>
.width-container{
width:calc( v-bind('projects.length') * 100 )"vh";
}
.sticky {
position: -webkit-sticky;
position: sticky;
top: 0;
z-index: 1000;
}
.v-enter-active,
.v-leave-active {
transition: opacity 0.5s ease;
}
.v-enter-from,
.v-leave-to {
opacity: 0;
}
.fade-enter-active,
.fade-leave-active {
transition: 1.5s ease-out;
transition-delay: 1s !important;
}
.fade-enter-from,
.fade-leave-to {
opacity: 0;
transform: translateY(-80px);
}
.fadeImage-enter-active,
.fadeImage-leave-active {
transition: 5s ease-out;
}
.fadeImage-enter-from,
.fadeImage-leave-to {
opacity: 0;
}
</style>

@ -55,7 +55,7 @@ function copyEmail(event) {
<BreadCrumbCell url="experiences">{{ $t('experiences')}}</BreadCrumbCell>
</template>
<template v-slot:fourth>
<BreadCrumbCell url="projects">{{ $t('projects')}}</BreadCrumbCell>
<BreadCrumbCell url="projects">{{ $t('projects.title')}}</BreadCrumbCell>
</template>
</BreadCrumb>
</div>

@ -6,7 +6,7 @@ const props = defineProps({
<template>
<a :href="props.url" target="_blank" :aria-label="`${props.url} - (link opens in a new tab)`">
<button class="px-10 bg-grey-900 border border-grey-300 flex flex-row justify-center items-center py-3 gap-2
text-grey-100 transition-all duration-300 ease-in-out hover:bg-grey-100/10 hover:text-white hover:shadow-xl
text-grey-100 transition-all duration-300 ease-in-out hover:bg-grey-275 hover:text-white hover:shadow-xl
hover:-translate-y-1 hover:scale-105" :aria-label="`redirect to ${props.url}`">
<slot></slot>
</button>

@ -1,6 +1,8 @@
<script setup>
import {ref, watch} from "vue";
import LinkButton from "./LinkButton.vue";
import RedirectLogo from "../assets/icons/redirect.svg";
const props = defineProps({
title : String,
@ -22,10 +24,16 @@ watch(() => props.progress, (progress) => {
<template>
<div class="grid min-h-screen w-full grid-cols-1 lg:grid-cols-2 opacity-container">
<div class="flex h-[30vh] flex-col items-center justify-center text-3xl lg:h-auto lg:text-3xl transform-container">
<div class="flex h-[30vh] flex-col pl-44 pr-44 justify-center text-3xl lg:h-auto lg:text-3xl transform-container">
<div class="leading-10 text-white">
<p class="text-2xl font-medium md:text-3xl xl:text-4xl text-gray-500"> {{ props.title}}</p>
<p class="text-2xl font-bold md:text-3xl xl:text-4xl text-white"> {{ props.application}}</p>
<p class="text-2xl font-bold md:text-3xl xl:text-4xl text-white pb-8"> {{ props.application}}</p>
<RouterLink :to="`/${props.application}`">
<LinkButton class="text-xl">
{{ $t('projects.find-more')}}
<RedirectLogo/>
</LinkButton>
</RouterLink>
</div>
</div>
<div class="flex h-[70vh] lg:h-screen flex-1 justify-center lg:items-center p-4 transform-container-2">

@ -0,0 +1,58 @@
<script setup>
import LinkButton from "../LinkButton.vue";
import RedirectLogo from "../../assets/icons/redirect.svg";
</script>
<template>
<div class="flex flex-col h-[75vh] w-full bg-black overflow-hidden relative items-center justify-center px-96">
<p class="text-6xl font-extrabold text-white pb-8 z-10">Allin</p>
<p class="text-xl font-light text-white text-center z-10">
J'ai participé au développement du projet Allin, une application mobile multiplateforme
permettant de parier sur des événements de la vie quotidienne ou sportifs. Vous pouvez ajouter des amis
et les défier pour remporter leurs Allcoins !
</p>
<div class="flex scale-90 sm:scale-100 flex-row gap-3 pt-12 flex-wrap items-center justify-center z-10">
<LinkButton class="text-sm" url="https://www.figma.com/design/GRTGdZFMUXb58lV48F3tC1/ALLIN!?node-id=0-1&t=QbWaiVCjjO9nhUx8-1">
Figma
<RedirectLogo/>
</LinkButton>
<LinkButton class="text-sm" url="https://codefirst.iut.uca.fr/git/AllDev">
GitHub
<RedirectLogo/>
</LinkButton>
</div>
<router-link to="/">
<img src="/images/back-button.png" class="absolute z-10 top-0 left-0 p-10 scale-25 hover:scale-35 ease-in-out transition-all"/>
</router-link>
<img src="/images/projects/allin/allin-banner.png" class="opacity-10 absolute z-0 pointer-events-none"/>
</div>
<div class="bg-white w-full px-80 py-20 transition-all flex flex-col gap-20 pb-36 items-center relative">
<img src="/images/projects/allin/logo.png" class=" absolute z-0 pointer-events-none w-20 -top-12 left-20"/>
<img src="/images/projects/allin/allin-banner.png" class="pointer-events-none rounded-md"/>
<p class="text-xl font-normal text-black">
Allin est un projet qui m'a permis de découvrir le développement mobile et de mettre en pratique une véritable
gestion de projet agile. Nous avons commencé par élaborer un backlog comprenant nos idées et les fonctionnalités
que nous souhaitions implémenter. Ensuite, nous avons créé des maquettes sur Figma, disponibles ci-dessus,
pour visualiser l'application et la rendre plus concrète. Avec l'aide d'un enseignant, nous avons mis en place
un suivi de projet agile avec des sprints de deux semaines.
</p>
<div class="flex flox-row w-full justify-between overflow-hidden">
<img src="/images/projects/allin/allin-1.png" class="pointer-events-none w-52 object-contain"/>
<img src="/images/projects/allin/allin-4.png" class="pointer-events-none w-52 object-contain"/>
<img src="/images/projects/allin/allin-2.png" class="pointer-events-none w-52 object-contain"/>
<img src="/images/projects/allin/allin-3.png" class="pointer-events-none w-52 object-contain"/>
</div>
<p class="text-xl font-normal text-black">
J'ai principalement travaillé sur l'application mobile native iOS en Swift. J'ai également contribué à
l'élaboration du modèle et au développement de l'API, réalisée avec Ktor.
<br/><br/>
Ce projet nous a permis de nous familiariser avec les technologies mobiles natives et de travailler en équipe sur
un projet de longue durée.
</p>
<iframe style="border: 1px solid rgba(0, 0, 0, 0.1);" width="800" height="450" src="https://www.figma.com/embed?embed_host=share&url=https%3A%2F%2Fwww.figma.com%2Fdesign%2FGRTGdZFMUXb58lV48F3tC1%2FALLIN!%3Fnode-id%3D0-1%26t%3DQbWaiVCjjO9nhUx8-1" allowfullscreen></iframe>
</div>
</template>
<style scoped>
</style>

@ -0,0 +1,58 @@
<script setup>
import LinkButton from "../LinkButton.vue";
import RedirectLogo from "../../assets/icons/redirect.svg";
</script>
<template>
<div class="flex flex-col h-[75vh] w-full bg-black overflow-hidden relative items-center justify-center px-96">
<p class="text-6xl font-extrabold text-white pb-8 z-10">Compagnon</p>
<p class="text-xl font-light text-white text-center z-10">
Compagnon est une application web qui vous assiste dans toutes sortes de tâches. Que ce soit pour noter des idées,
enregistrer et générer des mots de passe, organiser vos photos ou planifier vos voyages, Compagnon est pour
vous.
</p>
<div class="flex scale-90 sm:scale-100 flex-row gap-3 pt-12 flex-wrap items-center justify-center z-10">
<LinkButton class="text-sm" url="https://www.figma.com/design/p2VVeZuwBhhK5BBQ7hdzur/Untitled?node-id=0-1&t=3xQJCJCjjKSzQwIx-1">
Figma
<RedirectLogo/>
</LinkButton>
<LinkButton class="text-sm" url="https://github.com/WINK3R/Compagnon">
GitHub
<RedirectLogo/>
</LinkButton>
</div>
<router-link to="/">
<img src="/images/back-button.png" class="absolute z-10 top-0 left-0 p-10 scale-25 hover:scale-35 ease-in-out transition-all"/>
</router-link>
<img src="/images/projects/compagnon/compagnon-banner.png" class="opacity-5 absolute z-0 pointer-events-none"/>
</div>
<div class="bg-white w-full px-80 py-20 transition-all flex flex-col gap-20 pb-36 items-center">
<img src="/images/projects/compagnon/compagnon-banner.png" class="pointer-events-none rounded-md"/>
<p class="text-xl font-normal text-black">
Compagnon est une application web réalisée avec le framework Vue et le framework CSS Tailwind. J'ai conçu les
maquettes de Compagnon sur Figma, disponibles ci-dessus. J'ai imaginé une application permettant de stocker des
informations personnelles, des photos, des notes, des mots de passe et des voyages. J'ai également intégré une
fonctionnalité de génération de mots de passe sécurisés.
</p>
<div class="flex flox-row w-full justify-between overflow-hidden gap-3">
<img src="/images/projects/compagnon/compagnon-1.png" class="pointer-events-none w-1/2 object-contain"/>
<img src="/images/projects/compagnon/compagnon-4.png" class="pointer-events-none w-1/2 object-contain"/>
</div>
<div class="flex flox-row w-full justify-between overflow-hidden gap-3">
<img src="/images/projects/compagnon/compagnon-2.png" class="pointer-events-none w-1/2 object-contain"/>
<img src="/images/projects/compagnon/compagnon-3.png" class="pointer-events-none w-1/2 object-contain"/>
</div>
<p class="text-xl font-normal text-black">
La gestion des données se fait grâce à l'API de Firebase, qui permet de stocker les informations de l'utilisateur
dans une base de données non structurée. J'ai également utilisé l'API de Firebase pour l'authentification via
Twitter et Google.
<br/><br/>
Ce projet n'est pas encore terminé, mais je continue de le développer pour ajouter de nouvelles fonctionnalités
et j'espère le voir un jour en production.
</p>
<iframe style="border: 1px solid rgba(0, 0, 0, 0.1);" width="800" height="450" src="https://www.figma.com/embed?embed_host=share&url=https%3A%2F%2Fwww.figma.com%2Fdesign%2Fp2VVeZuwBhhK5BBQ7hdzur%2FUntitled%3Fnode-id%3D0-1%26t%3D3xQJCJCjjKSzQwIx-1" allowfullscreen></iframe>
</div>
</template>
<style scoped>
</style>

@ -0,0 +1,279 @@
<script setup>
import HeaderContainer from '../HeaderContainer.vue'
import HeroContainer from '../HeroContainer.vue';
import ShowcaseBanner from "../ShowcaseBanner.vue";
import GridSkill from "../GridSkill.vue";
import BannerCell from "../BannerCell.vue";
import ListExperience from "../ListExperience.vue";
import ExperienceCell from "../ExperienceCell.vue";
import {ref, onMounted, onUnmounted, computed} from 'vue';
import ProjectShow from "../ProjectShow.vue";
import Footer from "../Footer.vue";
const langages = [
{ name: 'Vue.js', image: 'vuejs.png' },
{ name: 'Flutter', image: 'flutter.png' },
{ name: 'React', image: 'react.png' },
{ name: 'JavaScript', image: 'javascript.png' },
{ name: 'Swift', image: 'swift.png' },
{ name: 'HTML', image: 'html.png' },
{ name: 'Python', image: 'python.png' }
];
const experiences = [
{
duration: "10 semaines",
year: "2023",
image: "inrae-blue.png",
company: "INRAE",
description: "Stage de 10 semaines portant sur lélaboration dun jeu sérieux (quizz) sur un site web à " +
"destination des chercheurs pour les aider dans leurs recherches sur lalimentation et lactivité " +
"physique des jeunes français.<br><br>Jai mis en pratique mes compétences à concevoir et optimiser une " +
"application existante ainsi qu'à faire des choix techniques décisifs. Jai également su gérer la gestion " +
"de ce projet en mettant en place des pratiques propres aux méthodes agiles telles que la méthode " +
"SCRUM.<br><br>Jai eu à utiliser des technologies du Web comme PHP, HTML & CSS ainsi que Bootstrap. " +
"Pour la gestion des données, jai mis en place une base de données SQL. Nous avons également dû porter " +
"une attention toute particulière au RGPD en raison de la manipulation de données de santé sensibles.",
important: true
},
{
duration: "2 mois",
year: "2023",
image: "inrae-grey.png",
company: "INRAE",
description: "CDD de 2 mois pour réaliser une version mobile multiplateforme en utilisant Flutter.",
important: false
},
{
duration: "1 an",
year: "2024",
image: "cikaba-blue.png",
company: "Cikaba",
description: "Alternance d'un an.<br><br>Jai eu lopportunité de rejoindre une équipe dynamique et agréable " +
"qui ma permis de me professionnaliser dans un contexte favorable. Jai travaillé en tant que développeur " +
"frontend.<br><br>Ma mission consistait principalement à lélaboration dune application web en Vue.js qui " +
"sert de plateforme SSO pour centraliser lauthentification des utilisateurs sur une application.<br><br>Jai "+
"également pu mettre en pratique mes compétences en design dinterface pour produire des maquettes et " +
"prototypes afin daméliorer lesthétique des applications en cours de développement.",
important: true
},
{
duration: "2 ans",
year: "2024-2026",
image: "cikaba-grey.png",
company: "Cikaba",
description: "Je vais poursuivre mon aventure chez Cikaba, en alternance, dans le cadre d'un Mastère Expert " +
"en ingénierie logicielle.",
important: false
},
];
const projects = [
{application: "MovieFinder", title: "J'ai créé l'application", image:"moviefinder-mockup.png"},
{application: "JustMusic", title: "J'ai co-créé l'application", image:"justmusic-mockup.png"},
{application: "Allin", title: "J'ai co-créé l'application", image:"allin-mockup.png"},
{application: "Compagnon", title: "J'ai créé l'application", image:"compagnon-mockup.png"},
]
const currentProjectIndex = ref(0);
const currentProject = computed(() => {
return Math.floor(currentProjectIndex.value);
});
const percentY = ref(0);
const opacity = ref(0);
const progress = ref(0);
// Variable to track if middle text is visible
const visibleTextIndex = ref(0);
// Function to check if middle text is visible
const checkVisibleTextIndex = () => {
const textElements = document.querySelectorAll('.magic-div > span');
textElements.forEach((element, index) => {
const bounding = element.getBoundingClientRect(); // Getting the position of each <p> element
if (bounding.top <= window.innerHeight - 500 && bounding.bottom >= 0) {
visibleTextIndex.value = index;
}
});
updateValue();
};
const updateValue = () => {
const elContainer = document.querySelector('.magic-showcase');
if (elContainer) {
const screenH = window.innerHeight;
const halfH = screenH / 2;
const clientHeight = elContainer.clientHeight;
const offsetTop = elContainer.offsetTop;
percentY.value =
Math.min(clientHeight + halfH, Math.max(-screenH, window.scrollY - offsetTop) + halfH) /
clientHeight;
currentProjectIndex.value = Math.max(0, percentY.value * projects.length);
}
progress.value = Math.max(0, currentProjectIndex.value - currentProject.value);
opacity.value = Math.min(1, Math.max(0, progress.value * 4));
if (progress.value > 0.85 && currentProject.value < projects.length - 1) {
opacity.value= Math.max(0, (1.0 - progress.value) * 4);
}
};
// Hook to add and remove scroll event listener
onMounted(() => {
window.addEventListener('scroll', checkVisibleTextIndex);
});
onUnmounted(() => {
window.removeEventListener('scroll', checkVisibleTextIndex);
});
</script>
<template>
<div class=" absolute pointer-events-none w-full h-full overflow-hidden">
<transition name="fadeImage" appear>
<img src="/images/camera-effect.png" class="top-10 right-10 w-full h-full object-cover z-0 scale-110"
alt="" width="1512" height="1071" role="presentation">
</transition>
<img src="/images/filter.png" class="fixed bottom-0 right-0 w-full object-cover z-50 opacity-70"
alt="" width="1508" height="1376" role="presentation">
</div>
<transition name="fade" appear>
<HeaderContainer id="about"></HeaderContainer>
</transition>
<HeroContainer class=" mt-6 sm:mt-14"/>
<ShowcaseBanner class=" mt-24 sm:mt-36 z-10 relative">
<BannerCell number="1" label="ANNEE <br> D'EXPERIENCE"/>
<BannerCell number="8" label="PROJETS <br> REALISES"/>
<BannerCell number="+" label="FRONT-END <br> BACK-END"/>
<BannerCell number="+" label="UI/UX <br> DESIGN"/>
</ShowcaseBanner>
<div class="flex-col flex pt-24 sm:pt-48 pb-28 z-10 relative bg-black" id="skills">
<span class="mx-4 text-3xl sm:text-4xl text-center font-medium bg-gradient-to-r from-grey-50
to-grey-100 bg-clip-text text-transparent px-10 " role="heading">
{{ $t('skills-list.title.start')}}
<span class="bg-blue text-white hover:bg-transparent hover:text-grey-75 ease-in-out transition-all duration-1000"
role="heading">
{{ $t('skills-list.title.highlight')}}
</span>
<br>
{{ $t('skills-list.title.end')}}
</span>
<GridSkill class="mx-8 sm:mx-28 py-28"/>
</div>
<ShowcaseBanner>
<img v-for="langage in langages"
:src="`https://codefirst.iut.uca.fr/containers/lucasdelanier-portfolio/images/${ langage.image}`"
class="w-18 h-18 hover:-translate-y-1 transition-all duration-300 ease-in-out hover:rotate-12 origin-center"
:alt="langage.name" width="64" height="64"/>
</ShowcaseBanner>
<div class="flex-col flex pt-48 z-10 relative" id="experiences">
<span class="mx-4 text-3xl sm:text-4xl text-center font-medium bg-gradient-to-r from-grey-50 to-grey-100
bg-clip-text text-transparent" role="heading">
Des expériences
<span class="bg-blue text-white hover:bg-transparent hover:text-grey-75 ease-in-out transition-all duration-1000"
role="heading">
professionnelles
</span>
qui mont
<br>
énormément apportées.
</span>
<ListExperience>
<ExperienceCell v-for="experience in experiences" v-bind="experience" />
</ListExperience>
</div>
<div class="flex-col flex z-50 justify-center align-middle px-14 sm:px-64 pb-14 sm:pb-96 top-0 ">
<div class="magic-div flex flex-col justify-center align-middle sticky py-60 sm:py-72">
<span :class="{ 'text-white scale-101': visibleTextIndex === 0, 'text-gray-600': visibleTextIndex !== 0 }"
class="text-4xl sm:text-7xl font-bold transition-all ease-in-out duration-500" role="heading">
Jai toujours envie de coder de nouveaux projets.
</span>
<span :class="{ 'text-white scale-101': visibleTextIndex === 1, 'text-gray-600': visibleTextIndex !== 1 }"
class="text-4xl sm:text-7xl font-bold transition-all ease-in-out duration-500" role="heading">
Cette passion me pousse à créer des expériences.
</span>
<span :class="{ 'text-white scale-101': visibleTextIndex === 2, 'text-gray-600': visibleTextIndex !== 2 }"
class="text-4xl sm:text-7xl font-bold transition-all ease-in-out duration-500" role="heading">
Jaime me réinventer et jouer avec les
<span :class="{ 'text-yellow-300': visibleTextIndex === 2, 'text-gray-600': visibleTextIndex !== 2 }"
class="transition-all ease-in-out duration-700" role="heading">
couleurs
</span>
et les
<span :class="{ 'text-white': visibleTextIndex === 2, 'text-gray-600': visibleTextIndex !== 2 }"
class="transition-all ease-in-out duration-700" role="heading">
formes
</span>
.
</span>
</div>
<div class="flex h-50 w-full"/>
</div>
<div class="flex h-300 w-full relative z-10 top-0 magic-showcase width-container"
:style="{ height: projects.length * 100 + 'vh'}">
<div class="absolute h-full w-full">
<div class="sticky top-0 grid min-h-screen w-full grid-cols-1 lg:grid-cols-2">
<div class="h-[30vh] bg-black lg:h-auto"></div>
<div class="h-[70vh] bg-white lg:h-auto"></div>
</div>
</div>
<div class="sticky top-0 h-screen overflow-hidden w-full" id="projects">
<ProjectShow :text="`J'ai réalisé l'application`"
:application="projects[currentProject].application"
:image="projects[currentProject].image"
:title="projects[currentProject].title"
:opacity="opacity"
:progress="progress"/>
</div>
</div>
<Footer></Footer>
</template>
<style scoped>
.width-container{
width:calc( v-bind('projects.length') * 100 )"vh";
}
.sticky {
position: -webkit-sticky;
position: sticky;
top: 0;
z-index: 1000;
}
.v-enter-active,
.v-leave-active {
transition: opacity 0.5s ease;
}
.v-enter-from,
.v-leave-to {
opacity: 0;
}
.fade-enter-active,
.fade-leave-active {
transition: 1.5s ease-out;
transition-delay: 1s !important;
}
.fade-enter-from,
.fade-leave-to {
opacity: 0;
transform: translateY(-80px);
}
.fadeImage-enter-active,
.fadeImage-leave-active {
transition: 5s ease-out;
}
.fadeImage-enter-from,
.fadeImage-leave-to {
opacity: 0;
}
</style>

@ -0,0 +1,59 @@
<script setup>
import LinkButton from "../LinkButton.vue";
import RedirectLogo from "../../assets/icons/redirect.svg";
</script>
<template>
<div class="flex flex-col h-[75vh] w-full bg-black overflow-hidden relative items-center justify-center px-96">
<p class="text-6xl font-extrabold text-white pb-8 z-10">JustMusic</p>
<p class="text-xl font-light text-white text-center z-10">
Avec un ami, j'ai développé l'application justMusic, un réseau social captivant qui combine musique et vie
quotidienne. Sur cette application, vous êtes invité à poster une "capsule" par jour, composée d'une musique et
d'un selfie de vous.
</p>
<div class="flex scale-90 sm:scale-100 flex-row gap-3 pt-12 flex-wrap items-center justify-center z-10">
<LinkButton class="text-sm" url="https://www.figma.com/design/DNjFgso8otcul2ApCEHPvm/justMusic?node-id=410-269&t=MLIwBBtJOY57pGE1-1">
Figma
<RedirectLogo/>
</LinkButton>
<LinkButton class="text-sm" url="https://github.com/WINK3R/justMusic">
GitHub
<RedirectLogo/>
</LinkButton>
</div>
<router-link to="/">
<img src="/images/back-button.png" class="absolute z-10 top-0 left-0 p-10 scale-25 hover:scale-35 ease-in-out transition-all"/>
</router-link>
<img src="/images/projects/justmusic/justmusic-banner.png" class="opacity-10 absolute z-0 pointer-events-none"/>
</div>
<div class="bg-white w-full px-80 py-20 transition-all flex flex-col gap-20 pb-36 items-center relative">
<img src="/images/projects/justmusic/logo.png" class=" absolute z-0 pointer-events-none w-20 -top-12 left-20 border-white border-2 rounded-lg"/>
<img src="/images/projects/justmusic/justmusic-banner.png" class="pointer-events-none rounded-md"/>
<p class="text-xl font-normal text-black">
JustMusic est un projet passionnant qui m'a beaucoup appris en matière de design et de développement. J'ai conçu
les maquettes de JustMusic sur Figma, disponibles ci-dessus. Nous avons imaginé un réseau social axé sur la
musique, permettant de partager avec ses amis et son groupe des morceaux qui nous tiennent à cœur. Accompagné
d'un selfie pris sur le vif, vous pouvez partager à tout moment de la journée votre moment favori et interagir
avec les autres utilisateurs.
</p>
<div class="flex flox-row w-full justify-between overflow-hidden">
<img src="/images/projects/justmusic/justmusic-1.png" class="pointer-events-none w-52 object-contain"/>
<img src="/images/projects/justmusic/justmusic-4.png" class="pointer-events-none w-52 object-contain"/>
<img src="/images/projects/justmusic/justmusic-2.png" class="pointer-events-none w-52 object-contain"/>
<img src="/images/projects/justmusic/justmusic-3.png" class="pointer-events-none w-52 object-contain"/>
</div>
<p class="text-xl font-normal text-black">
D'un point de vue technique, nous avons utilisé le framework Flutter pour développer deux applications, une
pour iOS et une pour Android, à partir d'un seul code source. Nous avons également utilisé Firebase pour la
gestion des utilisateurs et des données. Enfin, pour trouver les titres musicaux, obtenir leurs informations
et les lire directement dans l'application, nous avons intégré l'API de Spotify.
<br/><br/>
Nous avons publié cette application sur le Google Play Store et espérons, un jour, reprendre le projet pour le
faire connaître au plus grand nombre.
</p>
<iframe style="border: 1px solid rgba(0, 0, 0, 0.1);" width="800" height="450" src="https://www.figma.com/embed?embed_host=share&url=https%3A%2F%2Fwww.figma.com%2Fdesign%2FDNjFgso8otcul2ApCEHPvm%2FjustMusic%3Fnode-id%3D410-269%26t%3DMLIwBBtJOY57pGE1-1" allowfullscreen></iframe> </div>
</template>
<style scoped>
</style>

@ -0,0 +1,59 @@
<script setup>
import LinkButton from "../LinkButton.vue";
import RedirectLogo from "../../assets/icons/redirect.svg";
</script>
<template>
<div class="flex flex-col h-[75vh] w-full bg-black overflow-hidden relative items-center justify-center px-96">
<p class="text-6xl font-extrabold text-white pb-8 z-10">MovieFinder</p>
<p class="text-xl font-light text-white text-center z-10">J'ai développé l'application MovieFinder pour permettre
la découverte des films tendance et des sorties en salle à travers le monde entier. Inspirée par les applications
de rencontres, MovieFinder vous permet de "liker" ou de rejeter des films et séries tendances.</p>
<div class="flex scale-90 sm:scale-100 flex-row gap-3 pt-12 flex-wrap items-center justify-center z-10">
<LinkButton class="text-sm" url="https://www.figma.com/design/dbTIviWlglo4boYu1hTJ1e/MovieFinder?node-id=0-1&t=h8xSFDiYYhF3n8aC-1">
Figma
<RedirectLogo/>
</LinkButton>
<LinkButton class="text-sm" url="https://github.com/WINK3R/MovieFinder">
GitHub
<RedirectLogo/>
</LinkButton>
</div>
<router-link to="/">
<img src="/images/back-button.png" class="absolute z-10 top-0 left-0 p-10 scale-25 hover:scale-35 ease-in-out transition-all"/>
</router-link>
<img src="/images/projects/moviefinder/movie-finder-banner.png" class="opacity-10 absolute z-0 pointer-events-none"/>
</div>
<div class="bg-white w-full px-80 py-20 transition-all flex flex-col gap-20 pb-36 items-center relative">
<img src="/images/projects/moviefinder/logo.png" class=" absolute z-0 pointer-events-none w-20 -top-12 left-20"/>
<img src="/images/projects/moviefinder/banner-1.png" class="pointer-events-none rounded-md"/>
<p class="text-xl font-normal text-black">
Durant ma deuxième année de BUT informatique, j'ai développé une application de découverte de films appelée
MovieFinder dans le cadre de mes cours de React Native. Inspirée des applications de rencontres, MovieFinder vous
permet de swiper 20 films par jour pour ne plus jamais manquer un film tendance. Vous pouvez également consulter
les détails de chaque film, incluant le synopsis, la bande-annonce, les acteurs principaux et leur popularité,
ainsi que des recommandations de films similaires et des commentaires d'internautes.
</p>
<div class="flex flox-row w-full justify-between overflow-hidden">
<img src="/images/projects/moviefinder/moviefinder-1.png" class="pointer-events-none w-52 object-contain"/>
<img src="/images/projects/moviefinder/moviefinder-2.png" class="pointer-events-none w-52 object-contain"/>
<img src="/images/projects/moviefinder/moviefinder-3.png" class="pointer-events-none w-52 object-contain"/>
<img src="/images/projects/moviefinder/moviefinder-4.png" class="pointer-events-none w-52 object-contain"/>
</div>
<p class="text-xl font-normal text-black">
D'un point de vue technique, j'ai conçu les maquettes de MovieFinder sur Figma, disponibles ci-dessous.
J'ai ensuite développé le front-end de l'application en React Native et le back-end en TypeScript.
Pour disposer d'une base de données riche en films, j'ai utilisé l'API publique de TMDB, qui fournit toutes
les informations nécessaires sur les films.
<br/><br/>
Pour ajouter un défi supplémentaire, j'ai également créé une API en C# qui stocke les identifiants des films
que je recommande aux utilisateurs, en affichant un petit bandeau "Coup de cœur" sur les cartes correspondantes.
</p>
<iframe style="border: 1px solid rgba(0, 0, 0, 0.1);" width="800" height="450" src="https://www.figma.com/embed?embed_host=share&url=https%3A%2F%2Fwww.figma.com%2Fdesign%2FdbTIviWlglo4boYu1hTJ1e%2FMovieFinder%3Fnode-id%3D0-1%26t%3D1XHL4yfxBtaLVg8f-1" allowfullscreen></iframe>
</div>
</template>
<style scoped>
</style>

@ -5,6 +5,29 @@ import {Vue3Lottie} from "vue3-lottie";
import { createI18n } from 'vue-i18n';
import fr from '../public/i18n/fr.json'
import en from '../public/i18n/en.json'
import {createMemoryHistory, createRouter} from "vue-router";
import HomeView from "./components/views/HomeView.vue";
import JustMusicView from "./components/views/JustMusicView.vue";
import MovieFinderView from "./components/views/MovieFinderView.vue";
import AllinView from "./components/views/AllinView.vue";
import CompagnonView from "./components/views/CompagnonView.vue";
const routes = [
{ path: '/', component: HomeView },
{ path: '/moviefinder', component: MovieFinderView },
{ path: '/justmusic', component: JustMusicView },
{ path: '/allin', component: AllinView },
{ path: '/compagnon', component: CompagnonView },
]
const router = createRouter({
history: createMemoryHistory(),
routes,
scrollBehavior(to, from, savedPosition) {
return { top: 0 }
},
})
const i18n = createI18n({
locale: 'fr',
@ -14,4 +37,4 @@ const i18n = createI18n({
fr: fr
}
})
createApp(App).use(Vue3Lottie).use(i18n).mount('#app')
createApp(App).use(Vue3Lottie).use(i18n).use(router).mount('#app')

@ -12,6 +12,7 @@ module.exports = {
'grey-100': '#8B8B8B',
'grey-200': '#7D7D7E',
'grey-250': '#747475',
'grey-275': '#292929',
'grey-300': '#242424',
'grey-400': '#141314',
'grey-900': '#111111',
@ -42,7 +43,10 @@ module.exports = {
'8': '8px',
},
scale: {
'25': '0.25',
'35': '0.35',
'101': '1.015',
},
width: {
'18': '4rem',

Loading…
Cancel
Save