Added native os notifications
This commit is contained in:
@@ -1,11 +1,11 @@
|
||||
<script lang="ts" setup>
|
||||
import { reactive, ref, computed } from 'vue'
|
||||
import { reactive, ref } from 'vue'
|
||||
import axios from 'axios'
|
||||
import type { SettingField } from "@/Types/types"
|
||||
|
||||
const props = defineProps<{
|
||||
fields: SettingField[],
|
||||
categories: Record<string, string>
|
||||
description?: string | null
|
||||
}>()
|
||||
|
||||
const values = reactive(
|
||||
@@ -15,14 +15,6 @@ const saving = ref(false)
|
||||
const saved = ref(false)
|
||||
const error = ref(false)
|
||||
|
||||
const groupedFields = computed(() =>
|
||||
props.fields.reduce((groups: Record<string, SettingField[]>, field) => {
|
||||
const cat = field.category ?? 'General'
|
||||
;(groups[cat] ??= []).push(field)
|
||||
return groups
|
||||
}, {} as Record<string, SettingField[]>)
|
||||
)
|
||||
|
||||
async function save() {
|
||||
saving.value = true
|
||||
error.value = false
|
||||
@@ -40,64 +32,59 @@ async function save() {
|
||||
|
||||
<template>
|
||||
<v-form @submit.prevent="save">
|
||||
<template v-for="(groupFields, category) in groupedFields" :key="category">
|
||||
<p class="text-overline text-medium-emphasis mb-1 mt-4">{{ category }}</p>
|
||||
<small v-if="categories[category]" class="text-body-2 text-medium-emphasis mb-3">
|
||||
{{ categories[category] }}
|
||||
</small>
|
||||
<v-divider class="mb-4" />
|
||||
<small v-if="description" class="text-body-2 text-medium-emphasis mb-3 d-block">
|
||||
{{ description }}
|
||||
</small>
|
||||
|
||||
<template v-for="field in groupFields" :key="field.key">
|
||||
<template v-for="field in fields" :key="field.key">
|
||||
|
||||
<v-select
|
||||
v-if="field.type === 'select'"
|
||||
v-model="values[field.key]"
|
||||
:label="field.label"
|
||||
:items="field.options"
|
||||
item-title="label"
|
||||
item-value="value"
|
||||
variant="outlined"
|
||||
density="comfortable"
|
||||
class="mb-2"
|
||||
/>
|
||||
<v-select
|
||||
v-if="field.type === 'select'"
|
||||
v-model="values[field.key]"
|
||||
:label="field.label"
|
||||
:items="field.options"
|
||||
item-title="label"
|
||||
item-value="value"
|
||||
variant="outlined"
|
||||
density="comfortable"
|
||||
class="mb-2"
|
||||
/>
|
||||
|
||||
<v-text-field
|
||||
v-else-if="field.type === 'text'"
|
||||
v-model="values[field.key]"
|
||||
:label="field.label"
|
||||
variant="outlined"
|
||||
density="comfortable"
|
||||
class="mb-2"
|
||||
/>
|
||||
<v-text-field
|
||||
v-else-if="field.type === 'text'"
|
||||
v-model="values[field.key]"
|
||||
:label="field.label"
|
||||
variant="outlined"
|
||||
density="comfortable"
|
||||
class="mb-2"
|
||||
/>
|
||||
|
||||
<v-checkbox
|
||||
v-else-if="field.type === 'checkbox'"
|
||||
v-model="values[field.key]"
|
||||
:label="field.label"
|
||||
color="primary"
|
||||
density="comfortable"
|
||||
hide-details
|
||||
class="mb-2"
|
||||
/>
|
||||
<v-checkbox
|
||||
v-else-if="field.type === 'checkbox'"
|
||||
v-model="values[field.key]"
|
||||
:label="field.label"
|
||||
color="primary"
|
||||
density="comfortable"
|
||||
hide-details
|
||||
class="mb-2"
|
||||
/>
|
||||
|
||||
<v-select
|
||||
v-else-if="field.type === 'multiselect'"
|
||||
v-model="values[field.key]"
|
||||
:label="field.label"
|
||||
:items="field.options"
|
||||
item-title="label"
|
||||
item-value="value"
|
||||
variant="outlined"
|
||||
density="comfortable"
|
||||
chips
|
||||
multiple
|
||||
closable-chips
|
||||
clearable
|
||||
class="mb-2"
|
||||
/>
|
||||
<v-select
|
||||
v-else-if="field.type === 'multiselect'"
|
||||
v-model="values[field.key]"
|
||||
:label="field.label"
|
||||
:items="field.options"
|
||||
item-title="label"
|
||||
item-value="value"
|
||||
variant="outlined"
|
||||
density="comfortable"
|
||||
chips
|
||||
multiple
|
||||
closable-chips
|
||||
clearable
|
||||
class="mb-2"
|
||||
/>
|
||||
|
||||
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<v-divider class="my-4" />
|
||||
|
||||
@@ -44,7 +44,7 @@ const props = defineProps<{
|
||||
<RoutePanel :flight="flight" />
|
||||
<Panel label="Flight Details">
|
||||
<BoardingPass :user="user" :showToolTips="false" style="width:100%;max-width:600px; margin:0 auto" :flight="flight" :canEdit="canEdit" />
|
||||
<DetailRows>
|
||||
<DetailRows v-if="otherUsersOnFlight.length > 0">
|
||||
<PanelLabel>Other Users On This Flight</PanelLabel>
|
||||
<div class="d-flex flex-wrap ga-2">
|
||||
<v-chip
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
import MainLayout from "@/Layouts/MainLayout.vue"
|
||||
import GlassBox from "@/Components/FlightsGoneBy/GlassBox.vue"
|
||||
import { Head } from "@inertiajs/vue3"
|
||||
import { ref, watch } from "vue"
|
||||
import { computed, ref, watch } from "vue"
|
||||
import type { SettingField } from "@/Types/types"
|
||||
import GeneralSettings from "@/Pages/Settings/GeneralSettings.vue"
|
||||
import CategorySettingsForm from "@/Components/CategorySettingsForm.vue"
|
||||
import FollowerSettings from "@/Pages/Settings/FollowerSettings.vue"
|
||||
|
||||
defineOptions({ layout: MainLayout })
|
||||
@@ -17,28 +17,69 @@ const props = defineProps<{
|
||||
|
||||
const tab = ref(props.defaultTab)
|
||||
|
||||
function slugify(name: string) {
|
||||
return name
|
||||
.toLowerCase()
|
||||
.replace(/[^a-z0-9]+/g, '-')
|
||||
.replace(/(^-|-$)/g, '')
|
||||
}
|
||||
|
||||
const groupedFields = computed(() =>
|
||||
props.fields.reduce((groups: Record<string, SettingField[]>, field) => {
|
||||
const cat = field.category ?? 'General'
|
||||
;(groups[cat] ??= []).push(field)
|
||||
return groups
|
||||
}, {} as Record<string, SettingField[]>)
|
||||
)
|
||||
|
||||
const categoryTabs = computed(() =>
|
||||
Object.entries(groupedFields.value).map(([name, fields]) => ({
|
||||
name,
|
||||
slug: slugify(name),
|
||||
description: props.categories[name] ?? null,
|
||||
fields,
|
||||
}))
|
||||
)
|
||||
|
||||
watch(tab, (value) => {
|
||||
const path = value === 'general' ? '/settings' : `/settings/${value}`
|
||||
const path = value === props.defaultTab ? '/settings' : `/settings/${value}`
|
||||
window.history.replaceState(window.history.state, '', path)
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Head title="Settings" />
|
||||
<GlassBox title="Your Settings">
|
||||
<v-tabs v-model="tab" class="mb-4">
|
||||
<v-tab value="general">General</v-tab>
|
||||
<v-tab value="followers">Followers</v-tab>
|
||||
</v-tabs>
|
||||
<GlassBox wide title="Your Settings">
|
||||
<v-row>
|
||||
<v-col cols="12" md="3">
|
||||
<v-tabs
|
||||
v-model="tab"
|
||||
direction="vertical"
|
||||
color="primary"
|
||||
>
|
||||
<v-tab
|
||||
v-for="cat in categoryTabs"
|
||||
:key="cat.slug"
|
||||
:value="cat.slug"
|
||||
class="justify-start"
|
||||
>
|
||||
{{ cat.name }}
|
||||
</v-tab>
|
||||
<v-tab value="followers" class="justify-start">Followers</v-tab>
|
||||
</v-tabs>
|
||||
</v-col>
|
||||
|
||||
<v-window v-model="tab">
|
||||
<v-window-item value="general">
|
||||
<GeneralSettings :fields="fields" :categories="categories" />
|
||||
</v-window-item>
|
||||
<v-col cols="12" md="9">
|
||||
<v-window v-model="tab">
|
||||
<v-window-item v-for="cat in categoryTabs" :key="cat.slug" :value="cat.slug">
|
||||
<CategorySettingsForm :fields="cat.fields" :description="cat.description" />
|
||||
</v-window-item>
|
||||
|
||||
<v-window-item value="followers">
|
||||
<FollowerSettings />
|
||||
</v-window-item>
|
||||
</v-window>
|
||||
<v-window-item value="followers">
|
||||
<FollowerSettings />
|
||||
</v-window-item>
|
||||
</v-window>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</GlassBox>
|
||||
</template>
|
||||
|
||||
Reference in New Issue
Block a user