Skip to content

Commit 93b2743

Browse files
authored
FastAPI Implementation (#17)
2 parents 47015a5 + 3aa3434 commit 93b2743

File tree

2 files changed

+128
-240
lines changed

2 files changed

+128
-240
lines changed

src/views/Contact.vue

Lines changed: 42 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -1,87 +1,37 @@
11
<script setup>
2-
import { ref } from 'vue';
3-
4-
const contactInfo = ref([
5-
{
6-
type: 'Email',
7-
8-
icon: 'pi pi-envelope',
9-
link: 'mailto:[email protected]',
10-
description: 'Best way to reach me for professional inquiries',
11-
dataTest: 'contact-email'
12-
},
13-
{
14-
type: 'LinkedIn',
15-
value: 'Jacob Kohl',
16-
icon: 'pi pi-linkedin',
17-
link: 'https://linkedin.com/in/jacob-jp-kohl',
18-
description: 'Connect with me professionally',
19-
dataTest: 'contact-linkedin'
20-
},
21-
{
22-
type: 'GitHub',
23-
value: 'jakekohl',
24-
icon: 'pi pi-github',
25-
link: 'https://github.com/jakekohl',
26-
description: 'Check out my code and projects',
27-
dataTest: 'contact-github'
28-
},
29-
{
30-
type: 'Discord',
31-
value: 'hawkeye.59',
32-
icon: 'pi pi-discord',
33-
link: 'https://github.com/jakekohl#:~:text=https%3A//discordapp.com/users/1097326508814639194',
34-
description: 'Chat with me on Discord for quick discussions',
35-
dataTest: 'contact-discord'
36-
},
37-
{
38-
type: '(Twitter)',
39-
value: '@jacobofwonder',
40-
icon: 'pi pi-twitter',
41-
link: 'https://x.com/jacobofwonder',
42-
description: 'I post on X every now and then but it\'s not my main platform',
43-
dataTest: 'contact-twitter'
44-
}
45-
]);
46-
47-
const specialties = ref([
48-
{
49-
title: 'Test Automation',
50-
description: 'Cypress, Playwright, and comprehensive testing strategies',
51-
icon: 'pi pi-cog',
52-
dataTest: 'contact-test-automation'
53-
},
54-
{
55-
title: 'Consulting & Mentoring',
56-
description: 'Technical guidance, code reviews, and team mentoring',
57-
icon: 'pi pi-users',
58-
dataTest: 'contact-consulting-mentoring'
59-
},
60-
{
61-
title: 'Development Side Projects',
62-
description: 'Coding, testing, and more! Always learning and growing.',
63-
icon: 'pi pi-code',
64-
dataTest: 'contact-development-side-projects'
65-
}
66-
]);
2+
import { ref, onMounted } from 'vue';
673
68-
// const openExternalLink = (url) => {
69-
// if (url) {
70-
// window.open(url, '_blank', 'noopener,noreferrer');
71-
// }
72-
// };
4+
const contactInfo = ref([]);
5+
const specialties = ref([]);
6+
7+
const fetchContactInfo = async () => {
8+
try {
9+
const response = await fetch('https://portfolio.jakekohl.dev/contact');
10+
if (!response.ok) {
11+
throw new Error(`HTTP error! Status: ${response.status}`);
12+
}
13+
const contactResponse = await response.json();
14+
contactInfo.value = contactResponse.contact;
15+
specialties.value = contactResponse.specialties;
16+
} catch (error) {
17+
console.error('Failed to fetch contact info:', error);
18+
contactInfo.value = [];
19+
specialties.value = [];
20+
}
21+
};
7322
7423
const copyToClipboard = async (text) => {
7524
try {
7625
await navigator.clipboard.writeText(text);
77-
// In a real app, you'd show a toast notification here
78-
alert(`Copied ${text} to clipboard!`);
7926
} catch (err) {
80-
console.error('Failed to copy: ', err);
27+
console.error('Failed to copy:', err);
8128
}
8229
};
83-
</script>
8430
31+
onMounted(() => {
32+
fetchContactInfo();
33+
});
34+
</script>
8535
<template>
8636
<div class="contact-container">
8737
<div class="content-wrapper">
@@ -96,8 +46,8 @@ const copyToClipboard = async (text) => {
9646
Ready to collaborate? Let's discuss your next project!
9747
</p>
9848
<p class="contact-description">
99-
I'm always excited to work on new projects and help bring your ideas to life.
100-
Whether you need a full-stack developer, testing specialist, or technical consultant,
49+
I'm always excited to work on new projects and help bring your ideas to life.
50+
Whether you need a full-stack developer, testing specialist, or technical consultant,
10151
I'm here to help.
10252
</p>
10353
</div>
@@ -108,9 +58,9 @@ const copyToClipboard = async (text) => {
10858
<section class="contact-methods">
10959
<h2 class="section-title">Contact Information</h2>
11060
<div class="contact-grid">
111-
<PrimeCard
112-
v-for="contact in contactInfo"
113-
:key="contact.type"
61+
<PrimeCard
62+
v-for="contact in contactInfo"
63+
:key="contact.type"
11464
class="contact-card"
11565
:data-test="contact.dataTest"
11666
>
@@ -147,9 +97,9 @@ const copyToClipboard = async (text) => {
14797
<section class="specialties-section">
14898
<h2 class="section-title">What I Can Help You With</h2>
14999
<div class="specialties-grid">
150-
<PrimeCard
151-
v-for="specialty in specialties"
152-
:key="specialty.title"
100+
<PrimeCard
101+
v-for="specialty in specialties"
102+
:key="specialty.title"
153103
class="specialty-card"
154104
:data-test="specialty.dataTest"
155105
>
@@ -371,42 +321,42 @@ const copyToClipboard = async (text) => {
371321
.page-title {
372322
font-size: 2.5rem;
373323
}
374-
324+
375325
.section-title {
376326
font-size: 2rem;
377327
}
378-
328+
379329
.contact-grid {
380330
grid-template-columns: 1fr;
381331
}
382-
332+
383333
.specialties-grid {
384334
grid-template-columns: 1fr;
385335
}
386-
336+
387337
.contact-card-content {
388338
text-align: center;
389339
}
390-
340+
391341
.contact-header {
392342
flex-direction: column;
393343
text-align: center;
394344
}
395-
345+
396346
.contact-value-wrapper {
397347
justify-content: center;
398348
}
399-
349+
400350
.contact-actions {
401351
justify-content: center;
402352
}
403-
353+
404354
.contact-header {
405355
margin-bottom: 3rem;
406356
}
407-
357+
408358
.contact-methods {
409359
margin-bottom: 3rem;
410360
}
411361
}
412-
</style>
362+
</style>

0 commit comments

Comments
 (0)