Skip to content

Commit a0a7881

Browse files
committed
Merge branch 'settings' into gh-pages
2 parents aa19d65 + 4f0ac1f commit a0a7881

File tree

8 files changed

+410
-12
lines changed

8 files changed

+410
-12
lines changed

src/components/WeatherNavbar.vue

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,16 @@
22
import { storeToRefs } from "pinia";
33
44
import { useWeatherStore } from "@/stores/weather";
5-
import { TemperatureUnits } from "@/utils/constants";
65
import Searchbar from "@/components/LocationSearchbar.vue";
76
87
const weatherStore = useWeatherStore();
9-
const { temperatureUnit, weather } = storeToRefs(weatherStore);
8+
const { weather } = storeToRefs(weatherStore);
9+
10+
defineProps<{
11+
menuOpen: boolean
12+
}>();
13+
14+
defineEmits(["menuButton"]);
1015
</script>
1116

1217
<template>
@@ -21,9 +26,16 @@ const { temperatureUnit, weather } = storeToRefs(weatherStore);
2126
<Searchbar class="navbar__search-bar" />
2227
<button
2328
class="navbar__menu-button"
24-
@click="weatherStore.toggleTemperatureUnit"
29+
:class="{
30+
'navbar__menu-button--day' : weather?.current?.is_day,
31+
'navbar__menu-button--active' : menuOpen
32+
}"
33+
@click="$emit('menuButton')"
2534
>
26-
{{ temperatureUnit === TemperatureUnits.FAHRENHEIT ? "F" : "C" }}
35+
<font-awesome-icon
36+
:icon="['fas', 'gear']"
37+
size="xl"
38+
/>
2739
</button>
2840
</div>
2941
</div>
@@ -88,7 +100,28 @@ const { temperatureUnit, weather } = storeToRefs(weatherStore);
88100
height: 40px;
89101
width: 40px;
90102
border-radius: 16px;
91-
border: none;
103+
border: 1px solid #ccc;
104+
105+
color: #FFF;
106+
background-color: #3382;
107+
108+
aspect-ratio: 1;
109+
110+
transition: 0.25s ease;
111+
112+
&:hover:not(&--active) {
113+
background-color: #FFF;
114+
color: #1d104b;
115+
}
116+
117+
&--active {
118+
background-color: #FFF;
119+
color: #1d104b;
120+
121+
&:hover {
122+
color: #2885dd;
123+
}
124+
}
92125
}
93126
}
94127
</style>

src/components/core/CoreModal.vue

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
<script setup lang="ts">
2+
import { useCoreStore } from '@/stores/core';
3+
import { storeToRefs } from 'pinia';
4+
import { watch } from 'vue';
5+
6+
const store = useCoreStore();
7+
const { modalActive } = storeToRefs(store);
8+
9+
watch(modalActive, () => {
10+
modalActive.value
11+
? document.body.style.overflow = "hidden"
12+
: document.body.style.removeProperty("overflow")
13+
});
14+
</script>
15+
16+
<template>
17+
<Teleport to="body">
18+
<Transition>
19+
<div
20+
v-show="modalActive"
21+
class="core-modal"
22+
>
23+
<slot />
24+
</div>
25+
</Transition>
26+
</Teleport>
27+
</template>
28+
29+
<style scoped lang="scss">
30+
.core-modal {
31+
position: fixed;
32+
inset: 0;
33+
width: 100%;
34+
height: 100%;
35+
backdrop-filter: blur(8px);
36+
z-index: 10;
37+
38+
@media (min-width: 576px) {
39+
backdrop-filter: blur(4px);
40+
}
41+
42+
@media (min-width: 1024px) {
43+
backdrop-filter: blur(2px);
44+
}
45+
}
46+
47+
.v-enter-active,
48+
.v-leave-active {
49+
transition: opacity 0.25s ease;
50+
}
51+
52+
.v-enter-from,
53+
.v-leave-to {
54+
opacity: 0;
55+
}
56+
</style>
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
<script setup lang="ts">
2+
defineProps<{
3+
isOn: boolean;
4+
leftText?: string;
5+
rightText?: string;
6+
}>();
7+
8+
const emit = defineEmits(["toggle"]);
9+
</script>
10+
11+
<template>
12+
<div
13+
class="toggle"
14+
@click="emit('toggle')"
15+
>
16+
<div
17+
class="toggle__switch"
18+
:class="{'toggle__switch--active' : isOn}"
19+
/>
20+
<div class="toggle__body">
21+
<div
22+
class="toggle__left"
23+
:class="{'toggle__left--active' : !isOn}"
24+
>
25+
{{ leftText }}
26+
</div>
27+
<div
28+
class="toggle__right"
29+
:class="{'toggle__right--active' : isOn}"
30+
>
31+
{{ rightText }}
32+
</div>
33+
</div>
34+
</div>
35+
</template>
36+
37+
<style scoped lang="scss">
38+
.toggle {
39+
display: flex;
40+
position: relative;
41+
height: 24px;
42+
padding: 4px;
43+
border: 1px solid white;
44+
border-radius: 128px;
45+
background-color: transparent;
46+
box-sizing: content-box;
47+
cursor: pointer;
48+
49+
&__body {
50+
display: grid;
51+
grid-template-columns: 1fr 1fr;
52+
}
53+
54+
&__switch {
55+
position: absolute;
56+
left: 4px;
57+
width: 50%;
58+
height: 24px;
59+
background-color: white;
60+
border-radius: 16px;
61+
transition: left 0.25s ease;
62+
63+
&--active {
64+
left: calc(50% - 4px);
65+
}
66+
}
67+
68+
&__left,
69+
&__right {
70+
min-width: 32px;
71+
padding: 0 8px;
72+
text-align: center;
73+
z-index: 2;
74+
color: white;
75+
76+
transition: color 0.25s ease;
77+
}
78+
79+
&__left--active,
80+
&__right--active {
81+
color: #338;
82+
}
83+
}
84+
</style>
Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
<script setup lang="ts">
2+
import { storeToRefs } from 'pinia';
3+
import { useCoreStore } from '@/stores/core';
4+
import { useWeatherStore } from '@/stores/weather';
5+
import { onMounted, ref } from 'vue';
6+
import CoreModal from '@/components/core/CoreModal.vue';
7+
import TextToggleSwitch from '@/components/core/TextToggleSwitch.vue';
8+
import { TemperatureUnits } from '@/utils/constants';
9+
10+
const { openModal, closeModal } = useCoreStore();
11+
const weatherStore = useWeatherStore();
12+
13+
const { temperatureUnit } = storeToRefs(weatherStore);
14+
15+
interface Props {
16+
menuStyle?: "default" | "glass";
17+
}
18+
19+
defineProps<Props>();
20+
21+
const isOpen = ref(false);
22+
23+
const emit = defineEmits(["close"]);
24+
25+
function close() {
26+
isOpen.value = false;
27+
closeModal();
28+
setTimeout(() => {
29+
emit('close');
30+
}, 350)
31+
}
32+
33+
onMounted(() => {
34+
isOpen.value = true;
35+
openModal();
36+
})
37+
</script>
38+
39+
<template>
40+
<CoreModal>
41+
<Transition>
42+
<div
43+
v-if="isOpen"
44+
class="side-menu-modal"
45+
:class="{'side-menu-modal--glass' : menuStyle === 'glass'}"
46+
>
47+
<div class="side-menu-modal__head">
48+
<span class="side-menu-modal__title">Settings</span>
49+
<button
50+
class="side-menu-modal__close-button"
51+
@click="close"
52+
>
53+
<font-awesome-icon
54+
:icon="['fas', 'xmark']"
55+
size="xl"
56+
/>
57+
</button>
58+
</div>
59+
<div class="side-menu-modal__body">
60+
<div class="side-menu-modal__list-item">
61+
<label>Temperature Unit</label>
62+
<TextToggleSwitch
63+
:is-on="temperatureUnit === TemperatureUnits.FAHRENHEIT"
64+
left-text="Celsius"
65+
right-text="Fahrenheit"
66+
@toggle="weatherStore.toggleTemperatureUnit"
67+
/>
68+
</div>
69+
</div>
70+
</div>
71+
</Transition>
72+
</CoreModal>
73+
</template>
74+
75+
<style lang="scss">
76+
.side-menu-modal {
77+
display: flex;
78+
flex-direction: column;
79+
position: fixed;
80+
top: 0;
81+
right: 0;
82+
width: 100vw;
83+
height: 100vh;
84+
padding: 16px;
85+
86+
background-color: #3382;
87+
88+
z-index: 100;
89+
90+
@media (min-width: 576px) {
91+
width: 384px;
92+
}
93+
94+
&--glass {
95+
background-color: none;
96+
backdrop-filter: blur(4px);
97+
border: 1px solid #3382;
98+
}
99+
100+
&__head {
101+
display: flex;
102+
align-items: center;
103+
height: 40px;
104+
margin-bottom: 16px;
105+
border-radius: 16px;
106+
}
107+
108+
&__title {
109+
display: flex;
110+
align-items: center;
111+
flex-grow: 1;
112+
height: 40px;
113+
margin-right: 16px;
114+
border-radius: 16px;
115+
padding: 0 16px;
116+
background-color: #3387;
117+
118+
line-height: 32px;
119+
font-weight: 500;
120+
font-size: 24px;
121+
color: #f8f8f8;
122+
}
123+
124+
&__close-button {
125+
margin: auto;
126+
margin-right: 0;
127+
128+
height: 40px;
129+
width: 40px;
130+
border: none;
131+
border-radius: 16px;
132+
133+
color: #FFF;
134+
background-color: #3387;
135+
136+
aspect-ratio: 1;
137+
138+
transition: 0.25s ease;
139+
140+
&:hover {
141+
background-color: #FFF;
142+
color: #1d104b;
143+
}
144+
}
145+
146+
&__body {
147+
display: flex;
148+
flex-direction: column;
149+
align-items: center;
150+
padding: 8px 16px;
151+
margin-bottom: 16px;
152+
153+
border-radius: 16px;
154+
background-color: #3387;
155+
}
156+
157+
&__list-item {
158+
display: flex;
159+
flex-direction: row;
160+
justify-content: space-between;
161+
align-items: center;
162+
163+
width: 100%;
164+
padding: 8px 0;
165+
}
166+
}
167+
168+
.v-enter-active,
169+
.v-leave-active {
170+
transition: right 0.35s ease;
171+
}
172+
173+
.v-enter-from,
174+
.v-leave-to {
175+
right: -100vw;
176+
177+
@media (min-width: 576px) {
178+
right: -384px;
179+
}
180+
}
181+
</style>

0 commit comments

Comments
 (0)