mirror of
https://github.com/LJ5O/website.git
synced 2026-08-11 22:54:46 +02:00
Compare commits
1 Commits
6860be027b
...
contact
| Author | SHA1 | Date | |
|---|---|---|---|
|
dd31944bc5
|
@@ -94,5 +94,30 @@
|
||||
"desc": "When working with AI, creating a high-quality dataset for training is vital. Many operations and transformations need to be executed, which require a solid understanding of data management. Some infrasctructures also come with databases containing valuable information, that should be extracted and analysed to extract the best from it."
|
||||
}
|
||||
}
|
||||
},
|
||||
"contact": {
|
||||
"title": "Send me a message !",
|
||||
"subtitle": "Thanks for your interest ! If you wish to contact me, the easiest way is by Email.",
|
||||
"captcha":{
|
||||
"title": "Sorry, but could you check that you're an human ?",
|
||||
"desc": "Some bots are exploring the web to collect email adresses and send spam. In order to avoid this, please fill the following :",
|
||||
"question": "If we add {x} and {y} minus {z}, what would the result be ?",
|
||||
"submit": "Submit",
|
||||
"false": "Sorry, this doesn't seems right !"
|
||||
},
|
||||
"emails": {
|
||||
"work" :{
|
||||
"title": "Work",
|
||||
"desc": "If your message is about a job opportunity, a company or some professional matter, please use {email}"
|
||||
},
|
||||
"school" :{
|
||||
"title": "Academics and research",
|
||||
"desc": "{email} is the best suited to talk about universities and research."
|
||||
},
|
||||
"others" :{
|
||||
"title": "Other cases",
|
||||
"desc": "In case the two previous emails don't suit your needs, you can also use {email}. This address is considered to be a general purposes one."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
98
src/components/contact/emails.vue
Normal file
98
src/components/contact/emails.vue
Normal file
@@ -0,0 +1,98 @@
|
||||
<template>
|
||||
<div v-if="isHuman">
|
||||
<h2>{{ $t("contact.emails.work.title") }}</h2>
|
||||
<p>{{ $t("contact.emails.work.desc", {email:mail1}) }}</p>
|
||||
<h2>{{ $t("contact.emails.school.title") }}</h2>
|
||||
<p>{{ $t("contact.emails.school.desc", {email:mail2}) }}</p>
|
||||
<h2>{{ $t("contact.emails.others.title") }}</h2>
|
||||
<p>{{ $t("contact.emails.others.desc", {email:mail3}) }}</p>
|
||||
</div>
|
||||
<div v-else>
|
||||
<h2>{{ $t("contact.captcha.title") }}</h2>
|
||||
<p>{{ $t("contact.captcha.desc") }}</p>
|
||||
<p v-if="isFalse">{{ $t("contact.captcha.false") }}</p>
|
||||
<label for="captcha">{{ $t("contact.captcha.question", {x:x, y:y, z:z}) }}</label>
|
||||
<input type="number" id="captcha" v-model="captchaValue"/>
|
||||
<button class="button" @click="captchaSubmit">{{ $t("contact.captcha.submit") }}</button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { onBeforeMount, ref } from 'vue';
|
||||
|
||||
const validationChar = "&"; // Used to check that provided number is valid
|
||||
const x = 7;
|
||||
const y =20;
|
||||
const z = 1;
|
||||
|
||||
let mail1 = ref("");
|
||||
let mail2 = ref("");
|
||||
let mail3 = ref("");
|
||||
|
||||
let captchaValue = ref(0);
|
||||
let isHuman = ref(false);
|
||||
let isFalse = ref(false);
|
||||
|
||||
onBeforeMount(()=>{
|
||||
|
||||
});
|
||||
|
||||
const captchaSubmit = ()=>{
|
||||
if(ceasarEncryption(validationChar, captchaValue.value) == "@"){
|
||||
//OK
|
||||
isFalse.value = false;
|
||||
isHuman;value = true;
|
||||
readEmails();
|
||||
}else{
|
||||
isFalse.value = true;
|
||||
}
|
||||
};
|
||||
|
||||
const readEmails = ()=>{
|
||||
for(let i=0; i<encryptedEmails.length; i++){
|
||||
const letter = ceasarEncryption(encryptedEmails[i], 26);
|
||||
if(letter == "*") continue;
|
||||
if(i%3==0){
|
||||
//mail1.value= mail1.value+letter;
|
||||
}else if(i%3==1){
|
||||
//mail2.value = mail2.value+letter;
|
||||
}else{
|
||||
//mail3.value = mail3.value+letter;
|
||||
}
|
||||
if(i%3==1)console.log(letter);
|
||||
}
|
||||
}
|
||||
|
||||
const ceasarEncryption = (input, gap)=>{
|
||||
return String.fromCharCode(input.charCodeAt(0) + gap);
|
||||
}
|
||||
const encodeEmails = (emails, key)=>{
|
||||
let output = "";
|
||||
let i=0;
|
||||
let j=0;
|
||||
let letterIndex=0;
|
||||
while(true){
|
||||
const mail = emails[i%emails.length];
|
||||
let end = true;
|
||||
|
||||
if(j<mail.length){
|
||||
//still letters to add
|
||||
output+=ceasarEncryption(mail[j], key);
|
||||
end=false;
|
||||
}else{
|
||||
output+=ceasarEncryption('*', key);
|
||||
}
|
||||
|
||||
i++;
|
||||
if(end)break;
|
||||
if(i%emails.length == emails.length-1)j++; // Looped through all emails, next letter
|
||||
}
|
||||
return output;
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
label{
|
||||
color: #EAEAEA;
|
||||
}
|
||||
</style>
|
||||
@@ -2,14 +2,16 @@
|
||||
<div class="intersection_div">
|
||||
<div class="intersection_content test">
|
||||
<h2 class="test">{{ props.text }}</h2>
|
||||
<a :href="props.buttonLink"><div class="button intersection_button_div test">
|
||||
<RouterLink :to="buttonLink"><div class="button intersection_button_div test">
|
||||
<p>{{buttonText}}</p>
|
||||
</div></a>
|
||||
</div></RouterLink>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { RouterLink } from 'vue-router';
|
||||
|
||||
const props = defineProps({
|
||||
text:{
|
||||
type: String,
|
||||
|
||||
@@ -2,6 +2,7 @@ import { createRouter, createWebHistory } from 'vue-router'
|
||||
import HomeView from '../views/HomeView.vue'
|
||||
import BaseArticle from '@/views/BaseArticle.vue'
|
||||
import SkillsView from '@/views/SkillsView.vue'
|
||||
import ContactView from '@/views/ContactView.vue'
|
||||
|
||||
const router = createRouter({
|
||||
history: createWebHistory(import.meta.env.BASE_URL),
|
||||
@@ -21,6 +22,11 @@ const router = createRouter({
|
||||
name: 'skills',
|
||||
component: SkillsView
|
||||
},
|
||||
{
|
||||
path: '/contact',
|
||||
name: 'contact',
|
||||
component: ContactView
|
||||
},
|
||||
{
|
||||
path: '/about',
|
||||
name: 'about',
|
||||
|
||||
36
src/views/ContactView.vue
Normal file
36
src/views/ContactView.vue
Normal file
@@ -0,0 +1,36 @@
|
||||
<template>
|
||||
<Header/>
|
||||
<div id="contact_content">
|
||||
<h1>{{ $t("contact.title") }}</h1>
|
||||
<p>{{ $t("contact.subtitle") }}</p>
|
||||
<!--<img :src="ContactSvg"/>-->
|
||||
<emails/>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import Header from '@/components/header.vue';
|
||||
import emails from '@/components/contact/emails.vue';
|
||||
|
||||
import ContactSvg from '@/assets/svg/contact.svg';
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
#contact_content{
|
||||
width: 80%;
|
||||
margin: auto;
|
||||
margin-top: 20px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
/*justify-content: center;*/
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
min-height: 100vh;
|
||||
}
|
||||
#contact_content img{
|
||||
width: 100%;
|
||||
max-width: 600px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
<welcome/>
|
||||
|
||||
<intersection :text="i18n.t('home.contactMe')" :button-text="i18n.t('home.contactButton')" button-link="#"/>
|
||||
<intersection :text="i18n.t('home.contactMe')" :button-text="i18n.t('home.contactButton')" button-link="contact"/>
|
||||
|
||||
<presentation/>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user