Skip to content

Commit f95d4db

Browse files
committed
Merge branch 'dev'
2 parents 1e0576d + 08949c5 commit f95d4db

File tree

19 files changed

+571
-64
lines changed

19 files changed

+571
-64
lines changed

.eslintrc.cjs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,13 @@ module.exports = {
99
'@vue/eslint-config-typescript',
1010
'@vue/eslint-config-prettier/skip-formatting'
1111
],
12+
'rules': {
13+
"vue/multi-word-component-names": ["error", {
14+
"ignores": [
15+
"Layout",
16+
]
17+
}]
18+
},
1219
overrides: [
1320
{
1421
files: [

src/App.vue

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
<script lang="ts" setup>
22
import { RouterView } from 'vue-router'
3-
import HeaderComponent from './components/Header/HeaderComponent.vue'
3+
import AppHeader from '@/components/Header/AppHeader.vue'
4+
import AppFooter from '@/components/Footer/AppFooter.vue'
45
</script>
56

67
<template>
78
<div>
8-
<HeaderComponent />
9+
<AppHeader />
910
<RouterView
1011
v-slot="{
1112
Component,
@@ -22,6 +23,7 @@ import HeaderComponent from './components/Header/HeaderComponent.vue'
2223
/>
2324
</Transition>
2425
</RouterView>
26+
<AppFooter />
2527
</div>
2628
</template>
2729

@@ -36,3 +38,4 @@ import HeaderComponent from './components/Header/HeaderComponent.vue'
3638
opacity: 0;
3739
}
3840
</style>
41+
./components/Header/Header.vue

src/assets/images/me.png

7.83 KB
Loading
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
<script lang="ts" setup>
2+
import avatar from '@/assets/images/me.png'
3+
4+
import { useDark } from '@vueuse/core'
5+
6+
const isDark = useDark()
7+
8+
const props = defineProps({
9+
source: {
10+
type: String,
11+
required: false,
12+
default: avatar,
13+
},
14+
tooltip: {
15+
type: String,
16+
required: false,
17+
default: 'Art by @drawkit, created with Avatartion',
18+
},
19+
alt: {
20+
type: String,
21+
required: false,
22+
default: 'Avatar image',
23+
},
24+
})
25+
</script>
26+
27+
<template>
28+
<div
29+
class="avatar__wrapper"
30+
:class="isDark ? 'dark__avatar' : 'light__avatar'"
31+
>
32+
<img
33+
:src="props.source"
34+
:alt="props.alt"
35+
class="avatar__content"
36+
v-tooltip="props.tooltip"
37+
>
38+
</div>
39+
</template>
40+
41+
<style lang="scss" scoped>
42+
@import '@/styles/app.scss';
43+
44+
.avatar__wrapper {
45+
@include flex(row, center, center);
46+
height: 100%;
47+
width: fit-content;
48+
49+
overflow: hidden;
50+
51+
border-radius: 50%;
52+
border: 0.25rem solid;
53+
54+
&:hover {
55+
.avatar__content {
56+
animation: headBalance 0.675s ease;
57+
}
58+
}
59+
}
60+
61+
.avatar__content {
62+
max-width: 250px;
63+
}
64+
65+
.dark__avatar {
66+
border-color: $white;
67+
box-shadow: 0 0.375px 2.25rem 0.125rem rgba(135, 135, 187, 0.35),
68+
0 0.188rem 3.5rem -0.188rem rgba(158, 158, 158, 0.35),
69+
0 0.188rem 4.5rem -0.188rem rgba(158, 158, 158, 0.15);
70+
71+
background: radial-gradient(circle, $darker-cyan, $cyan 45%, $white 95%);
72+
}
73+
74+
.light__avatar {
75+
border-color: $black;
76+
box-shadow: 0 0.375px 2.25rem 0.125rem rgba(46, 46, 47, 0.65),
77+
0 0.188rem 3.5rem -0.188rem rgba(40, 38, 38, 0.45),
78+
0 0.188rem 4.5rem -0.188rem rgba(128, 127, 127, 0.35);
79+
80+
background: radial-gradient(circle, $cyan, $darker-cyan 65%, $black 95%);
81+
}
82+
83+
@keyframes headBalance {
84+
0% {
85+
transform: rotate(0deg);
86+
}
87+
50% {
88+
transform: rotate(5deg) scale(1.075) rotateZ(-5deg);
89+
}
90+
100% {
91+
transform: rotate(0deg);
92+
}
93+
}
94+
</style>

src/components/Footer/AppFooter.vue

Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
<script lang="ts" setup>
2+
import { useDark } from '@vueuse/core'
3+
4+
import IconVue from '../Icons/IconVue.vue'
5+
import IconGmail from '../Icons/IconGmail.vue'
6+
import IconGithub from '@/components/Icons/IconGithub.vue'
7+
import IconLinkedin from '../Icons/IconLinkedin.vue'
8+
import FooterLinkIcon from '../FooterLinkIcon/FooterLinkIcon.vue'
9+
10+
import FooterLink from '@/types/components/FooterLink/FooterLink'
11+
12+
const isDark = useDark()
13+
14+
const footerLinks: Array<FooterLink> = [
15+
{
16+
icon: IconGithub,
17+
link: 'https://github.com/hfidelis',
18+
label: 'hfidelis',
19+
},
20+
{
21+
icon: IconLinkedin,
22+
link: 'https://www.linkedin.com/in/hfidelis/',
23+
label: 'in/hfidelis',
24+
},
25+
{
26+
icon: IconGmail,
27+
link: 'mailto:heitorc88@gmail.com',
28+
label: 'heitorc88@gmail.com',
29+
},
30+
]
31+
</script>
32+
33+
<template>
34+
<section
35+
class="footer__container"
36+
>
37+
<footer
38+
class="app__footer"
39+
:class="isDark ? 'dark__footer' : 'light__footer'"
40+
>
41+
<section
42+
class="footer__title"
43+
>
44+
<h3>
45+
{{ $t('components.footer.title') }}
46+
</h3>
47+
</section>
48+
<section
49+
class="footer__links"
50+
>
51+
<ul>
52+
<li
53+
v-for="(link, index) in footerLinks"
54+
:key="`footer-link-${link.label}-${index}`"
55+
>
56+
<FooterLinkIcon
57+
v-bind="link"
58+
/>
59+
</li>
60+
</ul>
61+
</section>
62+
<section
63+
class="footer__owner"
64+
>
65+
<span>
66+
{{ $t('components.footer.madeWith') }}
67+
</span>
68+
<IconVue
69+
size="20"
70+
/>
71+
<span>
72+
{{ $t('components.footer.by') }}
73+
</span>
74+
</section>
75+
</footer>
76+
</section>
77+
</template>
78+
79+
<style lang="scss" scoped>
80+
@import '@/styles/app.scss';
81+
82+
.footer__container {
83+
@include flex(column, center, center);
84+
min-height: $footer-height;
85+
width: 100dvw;
86+
padding: 2dvh 25dvw;
87+
88+
@media screen {
89+
@media (max-width: 1400px) {
90+
padding: 2dvh 15dvw;
91+
}
92+
93+
@media (max-width: 1024px) {
94+
padding: 1.2rem 10dvw;
95+
}
96+
97+
@media (max-width: 768px) {
98+
padding: 1.2rem 1.8rem;
99+
}
100+
}
101+
102+
> .app__footer {
103+
@include flex(column, center, space-between, 0.4rem);
104+
flex: 1;
105+
106+
width: 100%;
107+
padding: 1.2rem;
108+
109+
border-radius: $radius-lg;
110+
111+
@media screen {
112+
@media (max-width: 768px) {
113+
@include flex(column, center, center, 1.2rem);
114+
}
115+
}
116+
117+
> .footer__title,
118+
.footer__links,
119+
.footer__owner {
120+
width: 100%;
121+
}
122+
123+
> .footer__title {
124+
font-size: $text-sm;
125+
text-align: center;
126+
127+
@media screen {
128+
@media (max-width: 768px) {
129+
font-size: $text-xsm;
130+
}
131+
}
132+
}
133+
134+
> .footer__links {
135+
@include flex(row, center, center, 0.8rem);
136+
width: 100%;
137+
138+
> ul {
139+
@include flex(row, center, center, 0.8rem);
140+
list-style: none;
141+
padding: 0;
142+
margin: 0;
143+
width: 100%;
144+
145+
> li {
146+
@include flex(row, center, center);
147+
width: 22.5%;
148+
}
149+
}
150+
151+
@media screen {
152+
@media (max-width: 768px) {
153+
> ul {
154+
@include flex(column, center, center, 0.4rem);
155+
156+
> li {
157+
width: 80%;
158+
}
159+
}
160+
}
161+
}
162+
}
163+
164+
> .footer__owner {
165+
@include flex(row, center, center, 0.4rem);
166+
text-align: center;
167+
font-weight: 500;
168+
font-size: $text-xsm;
169+
}
170+
}
171+
}
172+
173+
.dark__footer {
174+
border: 2px solid $dark-border;
175+
box-shadow: $dark-mode-shadow,
176+
0 0 1.5rem 0.2rem rgba(135, 135, 187, 0.16) inset;
177+
}
178+
179+
.light__footer {
180+
border: 2px solid $light-border;
181+
box-shadow: $light-mode-shadow,
182+
0 0 1.5rem 0.2rem rgba(50, 50, 93, 0.35) inset;
183+
}
184+
</style>

0 commit comments

Comments
 (0)