- refactoring code
This commit is contained in:
@@ -6,8 +6,8 @@ const router = useRouter();
|
||||
|
||||
function scrollTo(id) {
|
||||
document.querySelector(id).scrollIntoView({
|
||||
behavior: 'smooth'
|
||||
})
|
||||
behavior: 'smooth',
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
|
@@ -1,3 +1,27 @@
|
||||
<script setup>
|
||||
import { onMounted, reactive } from 'vue';
|
||||
|
||||
let list = reactive([]);
|
||||
|
||||
onMounted(() => {
|
||||
const importedList = () => import('@/resource/data/Technologies');
|
||||
importedList().then(data => {
|
||||
data.default.forEach(obj => {
|
||||
obj.showMore = false;
|
||||
list.push(obj);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function parseText(text) {
|
||||
return text.substr(0, 200).trim();
|
||||
}
|
||||
|
||||
function showMore(skill) {
|
||||
skill.showMore = !skill.showMore;
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<div class="max-w-screen-xl mx-auto px-6 xl:px-2 py-11">
|
||||
@@ -30,20 +54,12 @@
|
||||
{{ skill.header }}
|
||||
</h3>
|
||||
</header>
|
||||
<p
|
||||
v-if="skill.showMore.value || skill.description.length < 200"
|
||||
class="text-sm"
|
||||
>
|
||||
{{ skill.description }}
|
||||
</p>
|
||||
<p
|
||||
v-else
|
||||
class="text-sm"
|
||||
>
|
||||
{{ parseText(skill.description) }}...
|
||||
<p class="text-sm">
|
||||
{{ skill.showMore || skill.description.length < 200 ? skill.description : parseText(skill.description) }}...
|
||||
<a
|
||||
v-if="!skill.showMore"
|
||||
class="text-neutral-500 hover:text-neutral-700 hover:underline cursor-pointer"
|
||||
@click="changeMoreStatus(skill)"
|
||||
@click="showMore(skill)"
|
||||
>Więcej</a>
|
||||
</p>
|
||||
</div>
|
||||
@@ -52,128 +68,6 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
|
||||
let list = [
|
||||
{
|
||||
icons: [
|
||||
{
|
||||
class: 'icon-php',
|
||||
name: 'php',
|
||||
alt: 'Ikona przedstawiająca język PHP',
|
||||
title: 'Ikona PHP'
|
||||
},
|
||||
{
|
||||
class: 'icon-laravel',
|
||||
name: 'laravel',
|
||||
alt: 'Ikona przedstawiająca framework Laravel',
|
||||
title: 'Ikona Laravel'
|
||||
}
|
||||
],
|
||||
header: 'PHP & Laravel',
|
||||
showMore: ref(false),
|
||||
description: `PHP wraz z frameworkiem Laravel wykorzystuję do tworzenia nowych projektów. Laravel znacznie
|
||||
przyspiesza pisanie części backendowej, odciążając programistę od pisania skomplikownych filtrów i monotonnych
|
||||
walidacji przyjmowanych danych od użytkowników. Jednakże, choć dobrze pracuje mi się w środowisku Laravel
|
||||
w miarę możliwości staram się pisać kod w samym PHP z wykorzystaniem bibliotek i paczek autorskich.`
|
||||
},
|
||||
{
|
||||
icons: [
|
||||
{
|
||||
class: 'icon-js',
|
||||
name: 'js-square',
|
||||
alt: 'Ikona przedstawiająca język JavaScript',
|
||||
title: 'Ikona JavaScript'
|
||||
}
|
||||
],
|
||||
header: 'JavaScript Vanilla',
|
||||
showMore: ref(false),
|
||||
description: `JavaScript wykorzystuję głównie do logiki frontendowej jak i pisania kodu wykonywalnego po stronie
|
||||
przeglądarki internetowej. Wykorzystując możliwości reaktywnych frameworków mogę przyspieszyć pisanie UI.`
|
||||
},
|
||||
{
|
||||
icons: [
|
||||
{
|
||||
class: 'icon-vue',
|
||||
name: 'vuejs',
|
||||
alt: 'Ikona przedstawiająca framework Vue.js',
|
||||
title: 'Ikona Vue.js'
|
||||
}
|
||||
],
|
||||
header: 'Vue',
|
||||
showMore: ref(false),
|
||||
description: `Framework ten wspomaga mnie w pisaniu aplikacji frontendowej. Przyspiesza tworzenie warstwy
|
||||
wizualnej, obsługę interakcji z użytkownikiem i bindowanie zdefiniowanych pól, które są odpowiednio renderowane
|
||||
przez przeglądarkę. To wszystko, umożliwia łatwe łączenie CSS i HTML z logiką i otrzymanymi danymi z API.`
|
||||
},
|
||||
{
|
||||
icons: [
|
||||
{
|
||||
class: 'icon-html5',
|
||||
name: 'html5',
|
||||
alt: 'Ikona przedstawiająca HTML5',
|
||||
title: 'Ikona HTML5'
|
||||
},
|
||||
{
|
||||
class: 'icon-css3',
|
||||
name: 'css3-alt',
|
||||
alt: 'Ikona przedstawiająca CSS3',
|
||||
title: 'Ikona CSS3'
|
||||
}
|
||||
],
|
||||
header: 'HTML & CSS',
|
||||
showMore: ref(false),
|
||||
description: `HTML i CSS to już nieodłączne technologie, które w łatwy sposób umożliwiają nadanie wizualnej
|
||||
spójności dla treści, obrazów lub ułożenia elementów. Nie raz, odpowednie zaprojektowanie interfejsu użytkownika
|
||||
przyspiesza integrację z naszą stroną/sklepem. Ma to przełożenie na zyski dla obu stron - firmy (finanse)
|
||||
i klienta (czas).`
|
||||
},
|
||||
{
|
||||
icons: [
|
||||
{
|
||||
class: 'icon-node',
|
||||
name: 'node',
|
||||
alt: 'Ikona przedstawiająca Node.js',
|
||||
title: 'Ikona Node.js'
|
||||
}
|
||||
],
|
||||
header: 'Node.js',
|
||||
showMore: ref(false),
|
||||
description: `Node jest wieloplatformowym środowiskiem uruchomieniowym, umożliwiającym uruchomienie kodu
|
||||
JavaScript po stronie backendowej. Jest to bardzo przyjemny język, który ułatwia projektowanie logiki biznesowej
|
||||
aplikacji, dla mniej wymagających serwisów pod względem analizy i przetwarzania danych.`
|
||||
},
|
||||
{
|
||||
icons: [
|
||||
{
|
||||
class: 'icon-sass',
|
||||
name: 'sass',
|
||||
alt: 'Ikona przedstawiająca Sass',
|
||||
title: 'Ikona Sass'
|
||||
}
|
||||
],
|
||||
header: 'Sass',
|
||||
showMore: ref(false),
|
||||
description: `Sass zwiększa czytelność kodu dla programisty. Zawiera abstrakcje znane z języków obiektowych,
|
||||
przy czym ogranicza powtarzalność i umożliwia optymalizację kodu. Kompilacja napisanego stylu w Sass jest
|
||||
przekształcana do formy czytelnej dla silnika graficznego przeglądarki, co przyspiesza proces generowania strony.`
|
||||
}
|
||||
]
|
||||
|
||||
function parseText(text) {
|
||||
let shortText = text.substr(0, 200)
|
||||
if (shortText.slice(-1) === ' ') {
|
||||
shortText = text.substr(0, 199)
|
||||
}
|
||||
return shortText
|
||||
}
|
||||
|
||||
function changeMoreStatus(skill) {
|
||||
skill.showMore.value = !skill.showMore.value
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.icon-js {
|
||||
color: #F1DE4F;
|
||||
|
@@ -1,3 +1,27 @@
|
||||
<script setup>
|
||||
import { ref, onMounted } from 'vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
import Projects from '@/components/SelectedProjects.vue';
|
||||
import GhostButton from '@/components/buttons/GhostButton.vue';
|
||||
|
||||
const router = useRouter();
|
||||
const apiURL = import.meta.env.VITE_APP_API_URL;
|
||||
|
||||
let select_projects = ref([]);
|
||||
|
||||
onMounted(() => {
|
||||
loadProjectList();
|
||||
});
|
||||
|
||||
function loadProjectList() {
|
||||
fetch(apiURL + '/projects?category=selected')
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
select_projects.value = data
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section class="bg-neutral-50">
|
||||
<projects :projects="select_projects">
|
||||
@@ -21,30 +45,6 @@
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import Projects from '@/components/SelectedProjects.vue'
|
||||
import GhostButton from '@/components/buttons/GhostButton.vue'
|
||||
|
||||
const router = useRouter()
|
||||
const apiURL = import.meta.env.VITE_APP_API_URL
|
||||
|
||||
let select_projects = ref([])
|
||||
|
||||
onMounted(() => {
|
||||
loadProjectList()
|
||||
})
|
||||
|
||||
function loadProjectList() {
|
||||
fetch(apiURL + '/projects?category=selected')
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
select_projects.value = data
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@import "scss/default";
|
||||
|
||||
|
@@ -1,3 +1,118 @@
|
||||
<script setup>
|
||||
import { ref, reactive, watch, computed } from 'vue';
|
||||
import BaseButton from '@/components/buttons/BaseButton.vue';
|
||||
|
||||
function emailValidate (mailObj) {
|
||||
const mailFormat = /^\w+([.-]?\w+)*@\w+([.-]?\w+)*(\.\w{2,3})+$/;
|
||||
return mailObj.match(mailFormat);
|
||||
}
|
||||
|
||||
async function postData (url = '', data = {}) {
|
||||
const response = await fetch(url, {
|
||||
method: 'POST',
|
||||
cache: 'no-cache',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify(data),
|
||||
})
|
||||
return response.json();
|
||||
}
|
||||
|
||||
const buttonDisabled = ref(false)
|
||||
const statusError = ref(0)
|
||||
const emailValue = ref('')
|
||||
const messageValue = ref('')
|
||||
const senderValue = ref('')
|
||||
|
||||
const messageError = ref('')
|
||||
const messageOk = ref('')
|
||||
|
||||
const errors = reactive({
|
||||
email: false,
|
||||
message: false,
|
||||
sender: false,
|
||||
});
|
||||
|
||||
const isButtonDisabled = computed(() => buttonDisabled.value || errors.email || errors.message || errors.sender);
|
||||
const isEmailError = computed(() => errors.email);
|
||||
const isMessageError = computed(() => errors.message);
|
||||
const isSenderError = computed(() => errors.sender);
|
||||
const hasMessageError = computed(() => messageError.value);
|
||||
const hasMessageOkStatus = computed(() => messageOk.value && !hasMessageError.value);
|
||||
|
||||
watch([statusError, emailValue], ([errorCount, value]) => {
|
||||
errors.email = errorCount > 0 && !emailValidate(value);
|
||||
})
|
||||
|
||||
watch([statusError, messageValue], ([errorCount, value]) => {
|
||||
errors.message = errorCount > 0 && (value === '' || value.length < 3);
|
||||
})
|
||||
|
||||
watch([statusError, senderValue], ([errorCount, value]) => {
|
||||
errors.sender = errorCount > 0 && (value === '' || value.length < 3);
|
||||
})
|
||||
|
||||
function clearErrors() {
|
||||
statusError.value = 0;
|
||||
errors.email = false;
|
||||
errors.message = false;
|
||||
errors.sender = false;
|
||||
}
|
||||
|
||||
function checkForm() {
|
||||
clearErrors();
|
||||
if (!emailValidate(emailValue.value)) {
|
||||
errors.email = true;
|
||||
statusError.value++;
|
||||
}
|
||||
if (messageValue.value === '') {
|
||||
errors.message = true;
|
||||
statusError.value++;
|
||||
}
|
||||
if (senderValue.value === '') {
|
||||
errors.sender = true;
|
||||
statusError.value++;
|
||||
}
|
||||
}
|
||||
|
||||
function formSubmit(event) {
|
||||
event.preventDefault();
|
||||
|
||||
checkForm();
|
||||
|
||||
if (statusError.value === 0) {
|
||||
buttonDisabled.value = true;
|
||||
postData('https://kamilcraft.com/send', {
|
||||
email: emailValue.value,
|
||||
message: messageValue.value,
|
||||
sender: senderValue.value,
|
||||
}).then(result => {
|
||||
if (result.error) {
|
||||
messageError.value = result.message;
|
||||
} else {
|
||||
messageOk.value = result.message;
|
||||
messageValue.value = '';
|
||||
emailValue.value = '';
|
||||
senderValue.value = '';
|
||||
}
|
||||
buttonDisabled.value = false
|
||||
}).catch(() => {
|
||||
messageError.value = 'Wystąpił błąd podczas wysyłania wiadomości. Proszę spróbować później.';
|
||||
buttonDisabled.value = false;
|
||||
});
|
||||
}
|
||||
|
||||
scrollTo('#contact-form');
|
||||
}
|
||||
|
||||
function scrollTo(id) {
|
||||
document.querySelector(id).scrollIntoView({
|
||||
behavior: 'smooth',
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
id="contact-form"
|
||||
@@ -102,123 +217,7 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import BaseButton from '@/components/buttons/BaseButton.vue'
|
||||
import { ref, reactive, watch, computed } from 'vue'
|
||||
|
||||
function emailValidate (mailObj) {
|
||||
const mailFormat = /^\w+([.-]?\w+)*@\w+([.-]?\w+)*(\.\w{2,3})+$/
|
||||
return mailObj.match(mailFormat)
|
||||
}
|
||||
|
||||
async function postData (url = '', data = {}) {
|
||||
const response = await fetch(url, {
|
||||
method: 'POST',
|
||||
cache: 'no-cache',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify(data)
|
||||
})
|
||||
return response.json()
|
||||
}
|
||||
|
||||
const buttonDisabled = ref(false)
|
||||
const statusError = ref(0)
|
||||
const emailValue = ref('')
|
||||
const messageValue = ref('')
|
||||
const senderValue = ref('')
|
||||
|
||||
const messageError = ref('')
|
||||
const messageOk = ref('')
|
||||
|
||||
const errors = reactive({
|
||||
email: false,
|
||||
message: false,
|
||||
sender: false
|
||||
})
|
||||
|
||||
const isButtonDisabled = computed(() => buttonDisabled.value || errors.email || errors.message || errors.sender)
|
||||
const isEmailError = computed(() => errors.email)
|
||||
const isMessageError = computed(() => errors.message)
|
||||
const isSenderError = computed(() => errors.sender)
|
||||
const hasMessageError = computed(() => messageError.value)
|
||||
const hasMessageOkStatus = computed(() => messageOk.value && !hasMessageError.value)
|
||||
|
||||
watch([statusError, emailValue], ([errorCount, value]) => {
|
||||
errors.email = errorCount > 0 && !emailValidate(value)
|
||||
})
|
||||
|
||||
watch([statusError, messageValue], ([errorCount, value]) => {
|
||||
errors.message = errorCount > 0 && (value === '' || value.length < 3)
|
||||
})
|
||||
|
||||
watch([statusError, senderValue], ([errorCount, value]) => {
|
||||
errors.sender = errorCount > 0 && (value === '' || value.length < 3)
|
||||
})
|
||||
|
||||
function clearErrors() {
|
||||
statusError.value = 0
|
||||
errors.email = false
|
||||
errors.message = false
|
||||
errors.sender = false
|
||||
}
|
||||
|
||||
function checkForm() {
|
||||
clearErrors()
|
||||
if (!emailValidate(emailValue.value)) {
|
||||
errors.email = true
|
||||
statusError.value++
|
||||
}
|
||||
if (messageValue.value === '') {
|
||||
errors.message = true
|
||||
statusError.value++
|
||||
}
|
||||
if (senderValue.value === '') {
|
||||
errors.sender = true
|
||||
statusError.value++
|
||||
}
|
||||
}
|
||||
|
||||
function formSubmit(event) {
|
||||
event.preventDefault()
|
||||
|
||||
checkForm()
|
||||
|
||||
if (statusError.value === 0) {
|
||||
console.log('Send!')
|
||||
buttonDisabled.value = true
|
||||
postData('https://kamilcraft.com/send', {
|
||||
email: emailValue.value,
|
||||
message: messageValue.value,
|
||||
sender: senderValue.value
|
||||
}).then(result => {
|
||||
if (result.error) {
|
||||
messageError.value = result.message
|
||||
} else {
|
||||
messageOk.value = result.message
|
||||
messageValue.value = ''
|
||||
emailValue.value = ''
|
||||
senderValue.value = ''
|
||||
}
|
||||
buttonDisabled.value = false
|
||||
}).catch(() => {
|
||||
messageError.value = 'Wystąpił błąd podczas wysyłania wiadomości. Proszę spróbować później.'
|
||||
buttonDisabled.value = false
|
||||
})
|
||||
}
|
||||
|
||||
scrollTo('#contact-form')
|
||||
}
|
||||
|
||||
function scrollTo(id) {
|
||||
document.querySelector(id).scrollIntoView({
|
||||
behavior: 'smooth'
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
<style lang="scss">
|
||||
@screen md {
|
||||
.contact_container {
|
||||
flex-basis: 500px;
|
||||
|
@@ -91,7 +91,7 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
<style lang="scss">
|
||||
@import "scss/media";
|
||||
|
||||
@screen md {
|
||||
|
Reference in New Issue
Block a user