init project
This commit is contained in:
commit
03a8a0eef5
2
.env.example
Normal file
2
.env.example
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
VITE_APP_NAME="Kamil Niemczycki CV"
|
||||||
|
VITE_API_URL="http://localhost"
|
25
.gitignore
vendored
Normal file
25
.gitignore
vendored
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
# Logs
|
||||||
|
logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
pnpm-debug.log*
|
||||||
|
lerna-debug.log*
|
||||||
|
|
||||||
|
node_modules
|
||||||
|
dist
|
||||||
|
dist-ssr
|
||||||
|
*.local
|
||||||
|
|
||||||
|
# Editor directories and files
|
||||||
|
.vscode/*
|
||||||
|
!.vscode/extensions.json
|
||||||
|
.idea
|
||||||
|
.DS_Store
|
||||||
|
*.suo
|
||||||
|
*.ntvs*
|
||||||
|
*.njsproj
|
||||||
|
*.sln
|
||||||
|
*.sw?
|
||||||
|
.env
|
3
.vscode/extensions.json
vendored
Normal file
3
.vscode/extensions.json
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"recommendations": ["Vue.volar", "Vue.vscode-typescript-vue-plugin"]
|
||||||
|
}
|
7
README.md
Normal file
7
README.md
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
# Vue 3 + Vite
|
||||||
|
|
||||||
|
This template should help get you started developing with Vue 3 in Vite. The template uses Vue 3 `<script setup>` SFCs, check out the [script setup docs](https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup) to learn more.
|
||||||
|
|
||||||
|
## Recommended IDE Setup
|
||||||
|
|
||||||
|
- [VS Code](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).
|
14
index.html
Normal file
14
index.html
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="pl">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||||
|
<title>Kamil Niemczycki CV</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="cv"></div>
|
||||||
|
<script type="module" src="/src/main.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
1863
package-lock.json
generated
Normal file
1863
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
28
package.json
Normal file
28
package.json
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
{
|
||||||
|
"name": "cv",
|
||||||
|
"private": true,
|
||||||
|
"version": "v1.0.0",
|
||||||
|
"type": "module",
|
||||||
|
"scripts": {
|
||||||
|
"dev": "vite",
|
||||||
|
"build": "vite build",
|
||||||
|
"preview": "vite preview"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@fortawesome/fontawesome-svg-core": "^6.4.0",
|
||||||
|
"@fortawesome/free-brands-svg-icons": "^6.4.0",
|
||||||
|
"@fortawesome/free-regular-svg-icons": "^6.4.0",
|
||||||
|
"@fortawesome/free-solid-svg-icons": "^6.4.0",
|
||||||
|
"@fortawesome/vue-fontawesome": "^3.0.3",
|
||||||
|
"qrcode.vue": "^3.4.0",
|
||||||
|
"vue": "^3.2.47",
|
||||||
|
"vue-router": "^4.2.2"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@vitejs/plugin-vue": "^4.1.0",
|
||||||
|
"autoprefixer": "^10.4.14",
|
||||||
|
"postcss": "^8.4.24",
|
||||||
|
"tailwindcss": "^3.3.2",
|
||||||
|
"vite": "^4.3.9"
|
||||||
|
}
|
||||||
|
}
|
6
postcss.config.js
Normal file
6
postcss.config.js
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
export default {
|
||||||
|
plugins: {
|
||||||
|
tailwindcss: {},
|
||||||
|
autoprefixer: {},
|
||||||
|
},
|
||||||
|
}
|
BIN
public/background/gradient.webp
Normal file
BIN
public/background/gradient.webp
Normal file
Binary file not shown.
After Width: | Height: | Size: 46 KiB |
BIN
public/background/grain.webp
Normal file
BIN
public/background/grain.webp
Normal file
Binary file not shown.
After Width: | Height: | Size: 9.9 KiB |
BIN
public/me.webp
Normal file
BIN
public/me.webp
Normal file
Binary file not shown.
After Width: | Height: | Size: 33 KiB |
1
public/vite.svg
Normal file
1
public/vite.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>
|
After Width: | Height: | Size: 1.5 KiB |
26
src/App.vue
Normal file
26
src/App.vue
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
<script setup>
|
||||||
|
function print() {
|
||||||
|
window.print();
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="css">
|
||||||
|
.print-section {
|
||||||
|
@apply text-center pt-5 pb-6;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media print {
|
||||||
|
.print-section {
|
||||||
|
@apply hidden;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="print-section">
|
||||||
|
<button class="px-4 py-2 w-full sm:w-80 font-semibold text-sm bg-orange-300 text-orange-700 rounded-full shadow-sm" @click="print">Drukuj CV</button>
|
||||||
|
</div>
|
||||||
|
<main class="main bg-blob">
|
||||||
|
<router-view />
|
||||||
|
</main>
|
||||||
|
</template>
|
1
src/assets/vue.svg
Normal file
1
src/assets/vue.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="37.07" height="36" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 198"><path fill="#41B883" d="M204.8 0H256L128 220.8L0 0h97.92L128 51.2L157.44 0h47.36Z"></path><path fill="#41B883" d="m0 0l128 220.8L256 0h-51.2L128 132.48L50.56 0H0Z"></path><path fill="#35495E" d="M50.56 0L128 133.12L204.8 0h-47.36L128 51.2L97.92 0H50.56Z"></path></svg>
|
After Width: | Height: | Size: 496 B |
58
src/components/Body.vue
Normal file
58
src/components/Body.vue
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
<script setup>
|
||||||
|
import { defineProps, computed, ref } from 'vue';
|
||||||
|
import Education from '../components/Education.vue';
|
||||||
|
import MajorAchivments from '../components/MajorAchivments.vue';
|
||||||
|
import Skills from '../components/Skills.vue';
|
||||||
|
import Certificates from '../components/Certificates.vue';
|
||||||
|
import Links from '../components/Links.vue';
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
token: {
|
||||||
|
default: null,
|
||||||
|
type: [String, null],
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const qrCodeLink = computed(() => {
|
||||||
|
if(props.token) {
|
||||||
|
return `https://cv.kamilcraft.com/show/${props.token}`;
|
||||||
|
}
|
||||||
|
return 'https://cv.kamilcraft.com';
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="flex flex-col-reverse print:flex-row print:gap-2 md:flex-row md:gap-2">
|
||||||
|
<div class="relative print:w-2/3 print:flex-shrink-0 md:w-2/3 pb-3 md:flex-shrink-0 pt-1 px-4">
|
||||||
|
<MajorAchivments />
|
||||||
|
<Education />
|
||||||
|
<div class="print:absolute bottom-5 left-0 w-full pt-3 print:pt-0 px-2 print:px-6 text-[.5rem] leading-3 l text-justify text-[#E57D4C]">
|
||||||
|
Wyrażam zgodę na przetwarzanie moich danych osobowych dla potrzeb
|
||||||
|
niezbędnych do realizacji procesu rekrutacji (zgodnie z ustawą z
|
||||||
|
dnia 10 maja 2018 roku o ochronie danych osobowych (Dz. Ustaw z 2018,
|
||||||
|
poz. 1000) oraz zgodnie z Rozporządzeniem Parlamentu
|
||||||
|
Europejskiego i Rady (UE) 2016/679 z dnia 27 kwietnia 2016 r. w sprawie
|
||||||
|
ochrony osób fizycznych w związku z przetwarzaniem danych
|
||||||
|
osobowych i w sprawie swobodnego przepływu takich danych oraz
|
||||||
|
uchylenia dyrektywy 95/46/WE (RODO)
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="relative print:w-1/3 print:flex-shrink-1 md:w-1/3 md:flex-shrink-1 bg-[#fff0e9]">
|
||||||
|
<Skills />
|
||||||
|
<Certificates />
|
||||||
|
<Links />
|
||||||
|
<div class="hidden print:block print:absolute bottom-5 right-0 w-full">
|
||||||
|
<a :href="qrCodeLink" title="Link do CV w wersji przeglądarkowej" target="_blink">
|
||||||
|
<QRCode
|
||||||
|
render-as="svg"
|
||||||
|
class="mx-auto mb-2"
|
||||||
|
:value="qrCodeLink"
|
||||||
|
:size="100"
|
||||||
|
level="L"
|
||||||
|
background="transparent" />
|
||||||
|
</a>
|
||||||
|
<div class="text-center">Wersja online</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
32
src/components/Certificates.vue
Normal file
32
src/components/Certificates.vue
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
<script setup>
|
||||||
|
const certificates = [
|
||||||
|
{
|
||||||
|
faIcon: ['fas', 'star'],
|
||||||
|
link: null,
|
||||||
|
title: 'Konkurs „Mój pierwszy biznes”',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
faIcon: ['fas', 'certificate'],
|
||||||
|
link: 'https://kamilcraft.com/download/certyfikat-laravel.pdf',
|
||||||
|
title: 'Architektura aplikacji internetowych opartych o framework Laravel',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="px-4 py-3">
|
||||||
|
<h2 class="text-xl text-[#E57D4C] pb-2">Konkursy i Certyfikaty</h2>
|
||||||
|
<ul class="flex flex-col gap-1">
|
||||||
|
<li v-for="(certificate, key) in certificates"
|
||||||
|
:key="key"
|
||||||
|
class="flex gap-1 align-baseline">
|
||||||
|
<FontAwesomeIcon class="text-[#ffd43b]" :icon="certificate.faIcon" />
|
||||||
|
<span v-if="! certificate.link">{{ certificate.title }}</span>
|
||||||
|
<a v-else
|
||||||
|
:href="certificate.link"
|
||||||
|
:title="certificate.title"
|
||||||
|
target="_blank">{{ certificate.title }}</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</template>
|
65
src/components/ContactList.vue
Normal file
65
src/components/ContactList.vue
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
<script setup>
|
||||||
|
import { defineProps, computed } from 'vue';
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
loading: {
|
||||||
|
default: false,
|
||||||
|
type: Boolean,
|
||||||
|
},
|
||||||
|
email: {
|
||||||
|
default: 'conact@kamilcraft.com',
|
||||||
|
type: String,
|
||||||
|
},
|
||||||
|
tel: {
|
||||||
|
default: {
|
||||||
|
hasPhoneNumber: false,
|
||||||
|
},
|
||||||
|
type: Object,
|
||||||
|
},
|
||||||
|
locations: {
|
||||||
|
default: [],
|
||||||
|
type: Array,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const location = computed(() => {
|
||||||
|
return props.locations.join(' / ');
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="css">
|
||||||
|
.animated-bg {
|
||||||
|
animation-duration: 10s;
|
||||||
|
animation-fill-mode: forwards;
|
||||||
|
animation-iteration-count: infinite;
|
||||||
|
animation-name: placeHolderShimmer;
|
||||||
|
animation-timing-function: linear;
|
||||||
|
background-color: #f6f7f8;
|
||||||
|
background: linear-gradient(to right, #eeeeee 8%, #bbbbbb 18%, #eeeeee 33%);
|
||||||
|
position: relative;
|
||||||
|
width: 150px;
|
||||||
|
height: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes placeHolderShimmer {
|
||||||
|
0% {
|
||||||
|
background-position: -800px 0
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
background-position: 800px 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<ul v-if="loading">
|
||||||
|
<li class="animated-bg"></li>
|
||||||
|
<li class="animated-bg"></li>
|
||||||
|
<li class="animated-bg"></li>
|
||||||
|
</ul>
|
||||||
|
<ul v-else>
|
||||||
|
<li><FontAwesomeIcon class="w-5" :icon="['fas', 'envelope']" /> <a :href="`mailto:${email}`">{{ email }}</a></li>
|
||||||
|
<li v-if="tel.hasPhoneNumber"><FontAwesomeIcon class="w-5" :icon="['fas', 'mobile-screen-button']" /><a :href="`tel:${tel.phoneNumber}`">{{ tel.formattedPhoneNumber }}</a></li>
|
||||||
|
<li><FontAwesomeIcon class="w-5" :icon="['fas', 'location-dot']" />{{ location }}</li>
|
||||||
|
</ul>
|
||||||
|
</template>
|
27
src/components/Education.vue
Normal file
27
src/components/Education.vue
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
<template>
|
||||||
|
<div class="px-1 py-2">
|
||||||
|
<h2 class="text-xl text-[#E57D4C] pb-2">Wykształcenie</h2>
|
||||||
|
<div class="pb-4 mb-4 border-b last:pb-0 last:mb-0 last:border-b-0">
|
||||||
|
<header class="relative mb-2">
|
||||||
|
<h3 class="text-base font-bold">Magister</h3>
|
||||||
|
<span class="absolute top-0 right-0 text-base">10.2021 - obecnie</span>
|
||||||
|
<span class="text-slate-500">Collegium Witelona Uczelnia Państwowa w Legnicy</span>
|
||||||
|
</header>
|
||||||
|
<ul class="pl-5 list-disc">
|
||||||
|
<li><span class="font-bold">Kierunek:</span> Inżynieria produkcji i logistyki</li>
|
||||||
|
<li><span class="font-bold">Specjalizacja:</span> Przemysł 4.0</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class="pb-4 mb-4 border-b last:pb-0 last:mb-0 last:border-b-0">
|
||||||
|
<header class="relative mb-2">
|
||||||
|
<h3 class="text-base font-bold">Inżynier</h3>
|
||||||
|
<span class="absolute top-0 right-0 text-base">10.2017 – 06.2021</span>
|
||||||
|
<span class="text-slate-500">Państwowa Wyższa Szkoła Zawodowa im. Witelona w Legnicy</span>
|
||||||
|
</header>
|
||||||
|
<ul class="pl-5 list-disc">
|
||||||
|
<li><span class="font-bold">Kierunek:</span> Informatyka</li>
|
||||||
|
<li><span class="font-bold">Specjalizacja:</span> Programowanie aplikacji mobilnych i internetowych</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
48
src/components/Header.vue
Normal file
48
src/components/Header.vue
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
<script setup>
|
||||||
|
import { defineProps } from 'vue';
|
||||||
|
import { useRoute } from 'vue-router';
|
||||||
|
import Mission from '../components/Mission.vue';
|
||||||
|
import ContactList from './ContactList.vue';
|
||||||
|
|
||||||
|
defineProps({
|
||||||
|
loading: {
|
||||||
|
tyle: Boolean,
|
||||||
|
},
|
||||||
|
email: {
|
||||||
|
type: String,
|
||||||
|
},
|
||||||
|
tel: {
|
||||||
|
type: Object,
|
||||||
|
},
|
||||||
|
locations: {
|
||||||
|
type: Array,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="flex justify-between mx-1 mt-1 print:border-b-2 md:border-b-2">
|
||||||
|
<div class="flex-shrink-0 w-32 h-32">
|
||||||
|
<img class="w-full h-full" alt="Profilowe" src="/me.webp" />
|
||||||
|
</div>
|
||||||
|
<div class="flex flex-col flex-shrink-1 justify-center gap-3 w-full px-4 py-3">
|
||||||
|
<div>
|
||||||
|
<h1 class="text-2xl pb-0.5">Kamil Niemczycki</h1>
|
||||||
|
<p>Inżynier oprogramowania</p>
|
||||||
|
</div>
|
||||||
|
<ContactList
|
||||||
|
:loading="loading"
|
||||||
|
:email="email"
|
||||||
|
:tel="tel"
|
||||||
|
:locations="locations"
|
||||||
|
class="hidden md:flex gap-1 sm:gap-2 md:gap-5 print:flex print:gap-5 flex-wrap flex-1 text-sm" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<ContactList
|
||||||
|
:loading="loading"
|
||||||
|
:email="email"
|
||||||
|
:tel="tel"
|
||||||
|
:locations="locations"
|
||||||
|
class="md:hidden print:hidden flex flex-col gap-2 px-5 py-3 border-b text-sm" />
|
||||||
|
<Mission />
|
||||||
|
</template>
|
37
src/components/Links.vue
Normal file
37
src/components/Links.vue
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
<script setup>
|
||||||
|
const links = [
|
||||||
|
{
|
||||||
|
slug: 'kamilcraft',
|
||||||
|
faIcon: ['fas', 'link'],
|
||||||
|
url: 'https://kamilcraft.com',
|
||||||
|
title: 'Moja strona',
|
||||||
|
text: 'kamilcraft.com',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
slug: 'linkedin',
|
||||||
|
faIcon: ['fab', 'linkedin'],
|
||||||
|
url: 'https://www.linkedin.com/in/kamilniemczycki/',
|
||||||
|
title: 'Mój LinkedIn',
|
||||||
|
text: '/in/kamilniemczycki',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
slug: 'github',
|
||||||
|
faIcon: ['fab', 'github'],
|
||||||
|
url: 'https://github.com/kamilniemczycki',
|
||||||
|
title: 'Mój GitHub',
|
||||||
|
text: '/kamilniemczycki',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="px-4 py-3">
|
||||||
|
<h2 class="text-xl text-[#E57D4C] pb-2">Znajdziesz mnie</h2>
|
||||||
|
<ul class="flex flex-col gap-1">
|
||||||
|
<li v-for="link in links" :key="link.slug"><a :href="link.url"
|
||||||
|
:title="link.title"
|
||||||
|
target="_blink"
|
||||||
|
><FontAwesomeIcon class="w-6" :icon="link.faIcon" />{{ link.text }}</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</template>
|
38
src/components/MajorAchivments.vue
Normal file
38
src/components/MajorAchivments.vue
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
<template>
|
||||||
|
<div class="px-1 py-2">
|
||||||
|
<h2 class="text-xl text-[#E57D4C] pb-2">Doświadczenie</h2>
|
||||||
|
<div class="pb-4 mb-4 border-b last:pb-0 last:mb-0 last:border-b-0">
|
||||||
|
<header class="relative mb-2">
|
||||||
|
<h3 class="text-base font-bold">Praktykant</h3>
|
||||||
|
<span class="absolute top-0 right-0 text-base">06.2022 – 07.2022</span>
|
||||||
|
<span class="text-slate-500">Blumilk sp. z o.o.</span>
|
||||||
|
</header>
|
||||||
|
<ul class="pl-5 list-disc">
|
||||||
|
<li>Tworzenie oprogramowania HR dla celów wewnętrznych firmy</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class="pb-4 mb-4 border-b last:pb-0 last:mb-0 last:border-b-0">
|
||||||
|
<header class="relative mb-2">
|
||||||
|
<h3 class="text-base font-bold">Praktykant</h3>
|
||||||
|
<span class="absolute top-0 right-0 text-base">07.2019 – 08.2019</span>
|
||||||
|
<span class="text-slate-500">Legnickie Przedsiębiorstwo Wodociągów i Kanalizacji S.A.</span>
|
||||||
|
</header>
|
||||||
|
<ul class="pl-5 list-disc">
|
||||||
|
<li>Podstawowy serwis komputerów i drukarek</li>
|
||||||
|
<li>Tworzenie pluginu do obsługi tabel dla oprogramowania DokuWiki</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class="pb-4 mb-4 border-b last:pb-0 last:mb-0 last:border-b-0">
|
||||||
|
<header class="relative mb-2">
|
||||||
|
<h3 class="text-base font-bold">Praktykant</h3>
|
||||||
|
<span class="absolute top-0 right-0 text-base">07.2018 – 08.2018</span>
|
||||||
|
<span class="text-slate-500">Big Bit Komputer S.J.</span>
|
||||||
|
</header>
|
||||||
|
<ul class="pl-5 list-disc">
|
||||||
|
<li>Podstawowy serwis komputerów i drukarek</li>
|
||||||
|
<li>Aktualizacja, reinstalacja, naprawa systemu Windows</li>
|
||||||
|
<li>Instalacja oprogramowania dla organizacji</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
6
src/components/Mission.vue
Normal file
6
src/components/Mission.vue
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<template>
|
||||||
|
<div class="px-5 py-3 border-b text-justify text-slate-600">
|
||||||
|
<p>Ambitny i nastawiony na cel, gotowy do podjęcia wyzwań absolwent informatyki, który szuka pierwszej pracy jako inżynier oprogramowania.</p>
|
||||||
|
<p>Wyróżnia mnie pracowitość i umiejętność pracy w zespole. Szybko zdobywam potrzebną mi wiedzę i potrafię ją dobrze wykorzystać. Przyjemność sprawia mi tworzenie web aplikacji. Jestem gotowy by rozwijać swoją wiedzę jak i karierę zawodową w tym kierunku.</p>
|
||||||
|
</div>
|
||||||
|
</template>
|
56
src/components/Skills.vue
Normal file
56
src/components/Skills.vue
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
<script setup>
|
||||||
|
import { ref } from 'vue';
|
||||||
|
import { skills as importSkills, otherSkills as importOtherSkills } from '../composables/Skills.js';
|
||||||
|
|
||||||
|
const skills = ref(importSkills);
|
||||||
|
const otherSkills = ref(importOtherSkills);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="css">
|
||||||
|
.php {
|
||||||
|
@apply text-[#777BB3];
|
||||||
|
}
|
||||||
|
.laravel {
|
||||||
|
@apply text-[#F05340];
|
||||||
|
}
|
||||||
|
.js {
|
||||||
|
@apply text-[#F0DB4F];
|
||||||
|
}
|
||||||
|
.vuejs {
|
||||||
|
@apply text-[#41B883];
|
||||||
|
}
|
||||||
|
.html5 {
|
||||||
|
@apply text-[#e34c26];
|
||||||
|
}
|
||||||
|
.css3-alt {
|
||||||
|
@apply text-[#2965f1];
|
||||||
|
}
|
||||||
|
.git {
|
||||||
|
@apply text-[#f1502f];
|
||||||
|
}
|
||||||
|
.linux {
|
||||||
|
@apply text-black;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="px-4 py-3">
|
||||||
|
<h2 class="text-xl text-[#E57D4C] pb-2">Główne umiejętności</h2>
|
||||||
|
<ul class="flex flex-row flex-wrap justify-center align-baseline gap-4 text-xl">
|
||||||
|
<li
|
||||||
|
v-for="(skill, key) in skills"
|
||||||
|
:key="key"
|
||||||
|
class="flex flex-col items-center gap-1"
|
||||||
|
>
|
||||||
|
<FontAwesomeIcon :class="skill.class" :title="skill.title" size="xl" :icon="skill.faIcon"/>
|
||||||
|
<span class="text-xs">{{ skill.text }}</span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<div class="mt-3">
|
||||||
|
<h3 class="text-lg text-[#E57D4C] pb-1">Dodatkowo</h3>
|
||||||
|
<ul class="flex flex-row flex-wrap align-baseline gap-1">
|
||||||
|
<li v-for="(skill, key) in otherSkills" :key="key" class="border border-slate-200 rounded-md px-1.5 py-0.5 bg-white">{{ skill }}</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
68
src/composables/Skills.js
Normal file
68
src/composables/Skills.js
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
const skills = [
|
||||||
|
{
|
||||||
|
class: 'php',
|
||||||
|
faIcon: ['fab', 'php'],
|
||||||
|
title: 'PHP Icon',
|
||||||
|
text: 'PHP 7/8',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
class: 'laravel',
|
||||||
|
faIcon: ['fab', 'laravel'],
|
||||||
|
title: 'Laravel Icon',
|
||||||
|
text: 'Laravel',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
class: 'js',
|
||||||
|
faIcon: ['fab', 'js'],
|
||||||
|
title: 'JavaScript Icon',
|
||||||
|
text: 'JavaScript',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
class: 'vuejs',
|
||||||
|
faIcon: ['fab', 'vuejs'],
|
||||||
|
title: 'Vue.js Icon',
|
||||||
|
text: 'Vue.js',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
class: 'html5',
|
||||||
|
faIcon: ['fab', 'html5'],
|
||||||
|
title: 'HTML 5 Icon',
|
||||||
|
text: 'HTML',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
class: 'css3-alt',
|
||||||
|
faIcon: ['fab', 'css3-alt'],
|
||||||
|
title: 'CSS 3 Icon',
|
||||||
|
text: 'CSS',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
class: 'git',
|
||||||
|
faIcon: ['fab', 'git'],
|
||||||
|
title: 'Git Icon',
|
||||||
|
text: 'Git',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
class: 'linux',
|
||||||
|
faIcon: ['fab', 'linux'],
|
||||||
|
title: 'Linux Icon',
|
||||||
|
text: 'GNU/Linux',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const otherSkills = [
|
||||||
|
'Composer',
|
||||||
|
'GitHub',
|
||||||
|
'Node.js',
|
||||||
|
'NPM',
|
||||||
|
'Sqlite',
|
||||||
|
'MySQL',
|
||||||
|
'Docker',
|
||||||
|
'WSL',
|
||||||
|
'LXC/LXD',
|
||||||
|
'i więcej?',
|
||||||
|
];
|
||||||
|
|
||||||
|
export {
|
||||||
|
skills,
|
||||||
|
otherSkills,
|
||||||
|
};
|
19
src/main.js
Normal file
19
src/main.js
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import { createApp } from 'vue';
|
||||||
|
import './style.css';
|
||||||
|
import App from './App.vue';
|
||||||
|
import router from './router.js';
|
||||||
|
|
||||||
|
import { library } from '@fortawesome/fontawesome-svg-core';
|
||||||
|
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome';
|
||||||
|
import { fas } from '@fortawesome/free-solid-svg-icons';
|
||||||
|
import { fab } from '@fortawesome/free-brands-svg-icons';
|
||||||
|
import { far } from '@fortawesome/free-regular-svg-icons';
|
||||||
|
import QrcodeVue from 'qrcode.vue';
|
||||||
|
|
||||||
|
library.add(fas, fab, far);
|
||||||
|
|
||||||
|
createApp(App)
|
||||||
|
.use(router)
|
||||||
|
.component('FontAwesomeIcon', FontAwesomeIcon)
|
||||||
|
.component('QRCode', QrcodeVue)
|
||||||
|
.mount('#cv');
|
16
src/router.js
Normal file
16
src/router.js
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
import { createRouter, createWebHistory } from 'vue-router';
|
||||||
|
import Home from './views/Home.vue';
|
||||||
|
|
||||||
|
export default createRouter({
|
||||||
|
history: createWebHistory(),
|
||||||
|
routes: [
|
||||||
|
{
|
||||||
|
path: '/',
|
||||||
|
component: Home,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/show/:token',
|
||||||
|
component: Home,
|
||||||
|
}
|
||||||
|
],
|
||||||
|
});
|
66
src/style.css
Normal file
66
src/style.css
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
@import url('https://fonts.googleapis.com/css2?family=Roboto:wght@100;400&display=swap');
|
||||||
|
|
||||||
|
@tailwind base;
|
||||||
|
@tailwind components;
|
||||||
|
@tailwind utilities;
|
||||||
|
|
||||||
|
@layer base {
|
||||||
|
body {
|
||||||
|
@apply text-sm text-slate-700;
|
||||||
|
font-family: 'Roboto', sans-serif;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-blob {
|
||||||
|
background-image: var(--theme-bg-blob);
|
||||||
|
background-color: white;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-size: 170px;
|
||||||
|
background-position: -25px -22px;
|
||||||
|
}
|
||||||
|
|
||||||
|
main {
|
||||||
|
max-width: 21cm;
|
||||||
|
margin: 0 auto;
|
||||||
|
border: 1px solid #dddddd;
|
||||||
|
-webkit-print-color-adjust: exact;
|
||||||
|
print-color-adjust: exact;
|
||||||
|
}
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--theme-bg-blob: url('data:image/svg+xml;base64,PCEtLT94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/LS0+CjxzdmcgaWQ9InN3LWpzLWJsb2Itc3ZnIiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2ZXJzaW9uPSIxLjEiPgoJPGRlZnM+IAoJCTxsaW5lYXJHcmFkaWVudCBpZD0ic3ctZ3JhZGllbnQiIHgxPSIwIiB4Mj0iMSIgeTE9IjEiIHkyPSIwIj4KCQkJPHN0b3AgaWQ9InN0b3AxIiBzdG9wLWNvbG9yPSJyZ2JhKDIyOC44ODgsIDEyNS4zMzQsIDc2LjMyMywgMSkiIG9mZnNldD0iMCUiPjwvc3RvcD4KCQkJPHN0b3AgaWQ9InN0b3AyIiBzdG9wLWNvbG9yPSJyZ2JhKDIxNS4yMjcsIDE4Ny42OTMsIDE0Mi4yNDUsIDEpIiBvZmZzZXQ9IjEwMCUiPjwvc3RvcD4KCQk8L2xpbmVhckdyYWRpZW50PgoJPC9kZWZzPgoJPHBhdGggZmlsbD0idXJsKCNzdy1ncmFkaWVudCkiIGQ9Ik0xOC45LC0yMi42QzI1LjksLTE2LjYsMzQsLTEyLDM2LjgsLTUuMkMzOS41LDEuNywzNywxMC44LDMyLjcsMTkuN0MyOC41LDI4LjYsMjIuNiwzNy4zLDE0LjgsMzkuOEM2LjksNDIuMywtMi45LDM4LjUsLTExLjcsMzQuNEMtMjAuNiwzMC4yLC0yOC42LDI1LjcsLTMxLjksMTguOUMtMzUuMywxMi4yLC0zNCwzLjIsLTMyLC01LjJDLTMwLC0xMy43LC0yNy40LC0yMS42LC0yMS45LC0yNy43Qy0xNi41LC0zMy45LC04LjIsLTM4LjQsLTEuMSwtMzdDNS45LC0zNS42LDExLjksLTI4LjUsMTguOSwtMjIuNloiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDUwIDUwKSIgc3Ryb2tlLXdpZHRoPSIwIiBzdHlsZT0idHJhbnNpdGlvbjogYWxsIDAuM3MgZWFzZSAwczsiPjwvcGF0aD4KPC9zdmc+');
|
||||||
|
--theme-bg-gradient: url('/background/gradient.webp');
|
||||||
|
--theme-bg-grain: url('/background/grain.webp');
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
@apply underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen {
|
||||||
|
body {
|
||||||
|
background-image: var(--theme-bg-grain), var(--theme-bg-gradient);
|
||||||
|
background-position: top, top;
|
||||||
|
background-size: 75px, 100% 100%;
|
||||||
|
}
|
||||||
|
#cv {
|
||||||
|
@apply px-3 py-2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@page {
|
||||||
|
size: A4;
|
||||||
|
margin: 0;
|
||||||
|
appearance: none;
|
||||||
|
-moz-appearance: none;
|
||||||
|
-webkit-appearance: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media print {
|
||||||
|
main {
|
||||||
|
@apply border-0 w-[21cm] h-[29.7cm];
|
||||||
|
}
|
||||||
|
a {
|
||||||
|
@apply no-underline;
|
||||||
|
}
|
||||||
|
}
|
72
src/views/Home.vue
Normal file
72
src/views/Home.vue
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
<script setup>
|
||||||
|
import { onMounted, ref, reactive } from 'vue';
|
||||||
|
import { useRoute } from 'vue-router';
|
||||||
|
import Header from '../components/Header.vue';
|
||||||
|
import Body from '../components/Body.vue';
|
||||||
|
|
||||||
|
const loading = ref(false);
|
||||||
|
const token = ref(null);
|
||||||
|
const email = ref('contact@kamilcraft.com');
|
||||||
|
const tel = reactive({
|
||||||
|
hasPhoneNumber: false,
|
||||||
|
phoneNumber: '',
|
||||||
|
formattedPhoneNumber: '',
|
||||||
|
});
|
||||||
|
|
||||||
|
const locations = reactive([
|
||||||
|
'Wrocław',
|
||||||
|
'Legnica',
|
||||||
|
'Remote',
|
||||||
|
]);
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
const router = useRoute();
|
||||||
|
token.value = router.params['token'] ?? null;
|
||||||
|
|
||||||
|
if (token.value) {
|
||||||
|
loading.value = true;
|
||||||
|
const apiUrl = import.meta.env.VITE_API_URL;
|
||||||
|
fetch(`${apiUrl}/v1/cv/${token.value}`, {
|
||||||
|
method: 'GET',
|
||||||
|
cache: "no-cache",
|
||||||
|
credentials: "same-origin",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
}
|
||||||
|
}).then(response => (response.json().then(data => ({ status: response.status, data }))))
|
||||||
|
.then(response => {
|
||||||
|
setTimeout(() => showData(response), 1000);
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
loading.value = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
function showData(response) {
|
||||||
|
if (response.status === 200) {
|
||||||
|
const data = response.data;
|
||||||
|
email.value = data.email;
|
||||||
|
tel.hasPhoneNumber = true;
|
||||||
|
tel.phoneNumber = data.phoneNumber;
|
||||||
|
tel.formattedPhoneNumber = data.formattedPhoneNumber;
|
||||||
|
while(locations.length > 0) {
|
||||||
|
locations.pop();
|
||||||
|
}
|
||||||
|
data.locations?.forEach(value => {
|
||||||
|
locations.push(value);
|
||||||
|
});
|
||||||
|
loading.value = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="grid grid-rows-[max-content_max-content_auto] h-full">
|
||||||
|
<Header :loading="loading"
|
||||||
|
:email="email"
|
||||||
|
:tel="tel"
|
||||||
|
:locations="locations" />
|
||||||
|
<Body :token="token" />
|
||||||
|
</div>
|
||||||
|
</template>
|
12
tailwind.config.js
Normal file
12
tailwind.config.js
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
/** @type {import('tailwindcss').Config} */
|
||||||
|
export default {
|
||||||
|
content: [
|
||||||
|
"./index.html",
|
||||||
|
"./src/**/*.{vue,js,ts,jsx,tsx}",
|
||||||
|
],
|
||||||
|
theme: {
|
||||||
|
extend: {},
|
||||||
|
},
|
||||||
|
plugins: [],
|
||||||
|
}
|
||||||
|
|
13
vite.config.js
Normal file
13
vite.config.js
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
import { defineConfig, splitVendorChunkPlugin } from 'vite'
|
||||||
|
import vue from '@vitejs/plugin-vue'
|
||||||
|
|
||||||
|
// https://vitejs.dev/config/
|
||||||
|
export default defineConfig({
|
||||||
|
plugins: [ vue(), splitVendorChunkPlugin() ],
|
||||||
|
resolve: {
|
||||||
|
vue: 'vue/dist/vue.esm-bundler.js',
|
||||||
|
},
|
||||||
|
build: {
|
||||||
|
chunkSizeWarningLimit: 2048,
|
||||||
|
},
|
||||||
|
});
|
Loading…
x
Reference in New Issue
Block a user