Skip to content
This repository was archived by the owner on May 16, 2026. It is now read-only.

Commit 09a97ca

Browse files
committed
מסך העדפות משתמש
1 parent 35b090d commit 09a97ca

6 files changed

Lines changed: 172 additions & 0 deletions

File tree

src/components/AppBar.vue

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@
99
<v-spacer></v-spacer>
1010
<v-btn v-if="isLoggedIn && !isVerified" :to="{ name: 'VerifyPage' }">אימות דוא"ל</v-btn>
1111
<template v-if="isLoggedIn && isVerified">
12+
<v-btn :to="{ name: 'SettingsPage' }">
13+
<v-icon>mdi-cog</v-icon>
14+
</v-btn>
1215
<v-btn :to="{ name: 'UnreadPage' }">
1316
<v-icon>
1417
mdi-inbox-full
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<template>
2+
<v-dialog max-width="500px">
3+
<v-card>
4+
<v-card-title>
5+
יש לך שינויים שלא נשמרו!
6+
</v-card-title>
7+
<v-card-text>
8+
האם אתה בטוח שברצונך לצאת מהדף?
9+
</v-card-text>
10+
<v-card-actions>
11+
<v-spacer></v-spacer>
12+
<v-btn color="black" variant="text" @click="emit('cancel')">
13+
ביטול
14+
</v-btn>
15+
<v-btn color="green-darken-1" variant="text" @click="leavePage()">
16+
כן, צא
17+
</v-btn>
18+
</v-card-actions>
19+
</v-card>
20+
</v-dialog>
21+
</template>
22+
23+
<script setup>
24+
import { toRefs } from 'vue';
25+
import { useRouter } from 'vue-router';
26+
27+
const $router = useRouter()
28+
const props = defineProps({
29+
leaveTo: {
30+
type: [null, Object]
31+
}
32+
})
33+
const { leaveTo } = toRefs(props)
34+
const emit = defineEmits(['ok', 'cancel'])
35+
36+
function leavePage () {
37+
$router.push(leaveTo.value)
38+
emit('ok')
39+
}
40+
</script>

src/components/SettingsForm.vue

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<template>
2+
<v-form @submit.prevent="emit('save')">
3+
<v-card :width="width < 400 ? 350 : 400" class="mx-auto mt-3 mb-3">
4+
<v-card-title class="text-h5">
5+
העדפות התראות
6+
</v-card-title>
7+
<v-switch v-model="settings.enableEmailNotifications" label="קבלת מאמרים ממקורות במעקב ישירות למייל" class="mx-5" color="green" />
8+
<v-switch v-model="settings.allowAttachmentsInEmail" label="אפשר שליחת תמונת מאמר כקובץ מצורף" class="mx-5" color="green" />
9+
<v-divider></v-divider>
10+
<v-card-actions>
11+
<v-spacer></v-spacer>
12+
<v-btn color="green" :variant="props.hasChanges ? 'outlined' : 'text'" type="submit" :loading="props.loadingSaveSettings">
13+
שמירה
14+
</v-btn>
15+
</v-card-actions>
16+
</v-card>
17+
</v-form>
18+
</template>
19+
20+
<script setup>
21+
import { ref, watch } from 'vue';
22+
import { useDisplay } from 'vuetify';
23+
24+
const { width } = useDisplay();
25+
const props = defineProps({
26+
initialSettings: {
27+
type: Object,
28+
required: true
29+
},
30+
loadingSaveSettings: {
31+
type: Boolean,
32+
required: true,
33+
},
34+
hasChanges: {
35+
type: Boolean,
36+
required: true
37+
}
38+
})
39+
const settings = ref({ ...props.initialSettings })
40+
const emit = defineEmits(['changeSettings', 'save'])
41+
42+
watch(settings, (newSettings) => {
43+
emit('changeSettings', newSettings);
44+
}, { deep: true })
45+
</script>

src/components/TheSettings.vue

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
<template>
2+
<ConfirmLeavePageDialog @cancel="() => { showConfirmLeaveDialog = false; leaveTo = null }"
3+
@ok="() => { showConfirmLeaveDialog = false; skipConfirmLeavePageDialog = true }"
4+
v-model="showConfirmLeaveDialog" :leaveTo="leaveTo" />
5+
<SettingsForm v-bind="{ initialSettings, loadingSaveSettings, hasChanges }" @changeSettings="settings = $event" @save="saveSettings" />
6+
</template>
7+
8+
<script setup>
9+
import { ref, computed } from 'vue'
10+
import ConfirmLeavePageDialog from './ConfirmLeavePageDialog.vue'
11+
import SettingsForm from './SettingsForm.vue'
12+
import { onBeforeRouteLeave } from 'vue-router'
13+
import axios from '@/services/axios'
14+
import { useSnacksStore } from '@/stores/snacks'
15+
16+
const snacksStore = useSnacksStore()
17+
const initialSettings = ref({});
18+
await axios.get('/users/settings').then(({ data }) => {
19+
initialSettings.value = data;
20+
})
21+
22+
const settings = ref({ ...initialSettings.value });
23+
const showConfirmLeaveDialog = ref(false);
24+
const leaveTo = ref(null);
25+
const skipConfirmLeavePageDialog = ref(false);
26+
const loadingSaveSettings = ref(false);
27+
28+
const hasChanges = computed(() => {
29+
return JSON.stringify(initialSettings.value) !== JSON.stringify(settings.value);
30+
})
31+
32+
onBeforeRouteLeave(to => {
33+
if (!hasChanges.value || skipConfirmLeavePageDialog.value) {
34+
return true
35+
}
36+
showConfirmLeaveDialog.value = true
37+
leaveTo.value = to
38+
return false
39+
});
40+
41+
async function saveSettings () {
42+
loadingSaveSettings.value = true
43+
try {
44+
await axios.put('/users/settings', { ...settings.value });
45+
initialSettings.value = { ...settings.value }
46+
snacksStore.addSnack({
47+
text: '⚙️ ההעדפות שלך נשמרו בהצלחה',
48+
color: 'success'
49+
})
50+
} catch (err) {
51+
snacksStore.addSnack({
52+
text: err.message,
53+
color: 'error'
54+
})
55+
} finally {
56+
loadingSaveSettings.value = false
57+
}
58+
}
59+
</script>

src/router/index.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import TagView from '@/views/TagPage.vue'
1010
import ForgotPasswordView from '@/views/ForgotPasswordPage.vue'
1111
import UnreadView from '@/views/UnreadPage.vue'
1212
import TagsView from '@/views/TagsPage.vue'
13+
import SettingsView from '@/views/SettingsPage.vue'
1314

1415
import { useUserStore } from '@/stores/user'
1516
import { useSnacksStore } from '@/stores/snacks'
@@ -70,6 +71,16 @@ const router = createRouter({
7071
nextRoute: route.query.next
7172
}),
7273
},
74+
{
75+
path: '/settings',
76+
name: 'SettingsPage',
77+
component: SettingsView,
78+
meta: {
79+
viewName: 'הגדרות',
80+
requiresLogin: true,
81+
requiresVerification: true,
82+
},
83+
},
7384
{
7485
path: '/subscriptions',
7586
name: 'SubscriptionsPage',

src/views/SettingsPage.vue

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<template>
2+
<Suspense>
3+
<template #default>
4+
<TheSettings />
5+
</template>
6+
<template #fallback>
7+
<v-progress-linear indeterminate color="green" />
8+
</template>
9+
</Suspense>
10+
</template>
11+
12+
<script setup>
13+
import TheSettings from '@/components/TheSettings.vue'
14+
</script>

0 commit comments

Comments
 (0)