forked from Mirrors/elk
feat(settings): about page
This commit is contained in:
parent
3563b58651
commit
c0a2aca98a
7 changed files with 146 additions and 59 deletions
|
@ -1,41 +1,7 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
interface Team {
|
|
||||||
github: string
|
|
||||||
display: string
|
|
||||||
twitter: string
|
|
||||||
mastodon: string
|
|
||||||
}
|
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
(event: 'close'): void
|
(event: 'close'): void
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const teams: Team[] = [
|
|
||||||
{
|
|
||||||
github: 'antfu',
|
|
||||||
display: 'Anthony Fu',
|
|
||||||
twitter: 'antfu7',
|
|
||||||
mastodon: 'antfu@mas.to',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
github: 'patak-dev',
|
|
||||||
display: 'Patak',
|
|
||||||
twitter: 'patak_dev',
|
|
||||||
mastodon: 'patak@webtoo.ls',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
github: 'danielroe',
|
|
||||||
display: 'Daniel Roe',
|
|
||||||
twitter: 'danielcroe',
|
|
||||||
mastodon: 'daniel@roe.dev',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
github: 'sxzz',
|
|
||||||
display: 'sxzz',
|
|
||||||
twitter: 'sanxiaozhizi',
|
|
||||||
mastodon: 'sxzz@mas.to',
|
|
||||||
},
|
|
||||||
].sort(() => Math.random() - 0.5)
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
text?: string
|
text?: string
|
||||||
|
content?: string
|
||||||
description?: string
|
description?: string
|
||||||
icon?: string
|
icon?: string
|
||||||
to: string | Record<string, string>
|
to?: string | Record<string, string>
|
||||||
command?: boolean
|
command?: boolean
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
|
@ -12,13 +13,19 @@ const router = useRouter()
|
||||||
useCommand({
|
useCommand({
|
||||||
scope: 'Settings',
|
scope: 'Settings',
|
||||||
|
|
||||||
name: () => props.text ?? (typeof props.to === 'string' ? props.to as string : props.to.name),
|
name: () => props.text
|
||||||
|
?? (props.to
|
||||||
|
? typeof props.to === 'string'
|
||||||
|
? props.to
|
||||||
|
: props.to.name
|
||||||
|
: ''
|
||||||
|
),
|
||||||
description: () => props.description,
|
description: () => props.description,
|
||||||
icon: () => props.icon || '',
|
icon: () => props.icon || '',
|
||||||
visible: () => props.command,
|
visible: () => props.command && props.to,
|
||||||
|
|
||||||
onActivate() {
|
onActivate() {
|
||||||
router.push(props.to)
|
router.push(props.to!)
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
@ -28,7 +35,7 @@ useCommand({
|
||||||
:to="to"
|
:to="to"
|
||||||
exact-active-class="text-primary"
|
exact-active-class="text-primary"
|
||||||
block w-full group focus:outline-none
|
block w-full group focus:outline-none
|
||||||
@click="$scrollToTop"
|
@click="to ? $scrollToTop() : undefined"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
w-full flex w-fit px5 py3 md:gap2 gap4 items-center
|
w-full flex w-fit px5 py3 md:gap2 gap4 items-center
|
||||||
|
@ -37,6 +44,7 @@ useCommand({
|
||||||
>
|
>
|
||||||
<div flex-1 flex items-center md:gap2 gap4>
|
<div flex-1 flex items-center md:gap2 gap4>
|
||||||
<div
|
<div
|
||||||
|
v-if="$slots.icon || icon"
|
||||||
flex items-center justify-center flex-shrink-0
|
flex items-center justify-center flex-shrink-0
|
||||||
:class="$slots.description ? 'w-12 h-12' : ''"
|
:class="$slots.description ? 'w-12 h-12' : ''"
|
||||||
>
|
>
|
||||||
|
@ -50,14 +58,19 @@ useCommand({
|
||||||
<span>{{ text }}</span>
|
<span>{{ text }}</span>
|
||||||
</slot>
|
</slot>
|
||||||
</p>
|
</p>
|
||||||
<p v-if="$slots.description" text-sm text-secondary>
|
<p v-if="$slots.description || description" text-sm text-secondary>
|
||||||
<slot name="description">
|
<slot name="description">
|
||||||
{{ description }}
|
{{ description }}
|
||||||
</slot>
|
</slot>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div i-ri:arrow-right-s-line text-xl text-secondary-light class="rtl-flip" />
|
<p v-if="$slots.content || content" text-sm text-secondary>
|
||||||
|
<slot name="content">
|
||||||
|
{{ content }}
|
||||||
|
</slot>
|
||||||
|
</p>
|
||||||
|
<div v-if="to" i-ri:arrow-right-s-line text-xl text-secondary-light class="rtl-flip" />
|
||||||
</div>
|
</div>
|
||||||
</NuxtLink>
|
</NuxtLink>
|
||||||
</template>
|
</template>
|
33
composables/about.ts
Normal file
33
composables/about.ts
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
export interface Team {
|
||||||
|
github: string
|
||||||
|
display: string
|
||||||
|
twitter: string
|
||||||
|
mastodon: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export const teams: Team[] = [
|
||||||
|
{
|
||||||
|
github: 'antfu',
|
||||||
|
display: 'Anthony Fu',
|
||||||
|
twitter: 'antfu7',
|
||||||
|
mastodon: 'antfu@mas.to',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
github: 'patak-dev',
|
||||||
|
display: 'Patak',
|
||||||
|
twitter: 'patak_dev',
|
||||||
|
mastodon: 'patak@webtoo.ls',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
github: 'danielroe',
|
||||||
|
display: 'Daniel Roe',
|
||||||
|
twitter: 'danielcroe',
|
||||||
|
mastodon: 'daniel@roe.dev',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
github: 'sxzz',
|
||||||
|
display: 'sxzz',
|
||||||
|
twitter: 'sanxiaozhizi',
|
||||||
|
mastodon: 'sxzz@mas.to',
|
||||||
|
},
|
||||||
|
].sort(() => Math.random() - 0.5)
|
|
@ -1,5 +1,4 @@
|
||||||
import type { MaybeRef } from '@vueuse/shared'
|
import type { MaybeComputedRef, MaybeRef, UseTimeAgoOptions } from '@vueuse/core'
|
||||||
import type { MaybeComputedRef, UseTimeAgoOptions } from '@vueuse/core'
|
|
||||||
|
|
||||||
const formatter = Intl.NumberFormat()
|
const formatter = Intl.NumberFormat()
|
||||||
|
|
||||||
|
@ -31,7 +30,7 @@ export const useHumanReadableNumber = () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useFormattedDateTime = (
|
export const useFormattedDateTime = (
|
||||||
value: MaybeComputedRef<string | Date | undefined | null>,
|
value: MaybeComputedRef<string | number | Date | undefined | null>,
|
||||||
options: Intl.DateTimeFormatOptions = { dateStyle: 'long', timeStyle: 'medium' },
|
options: Intl.DateTimeFormatOptions = { dateStyle: 'long', timeStyle: 'medium' },
|
||||||
) => {
|
) => {
|
||||||
const { locale } = useI18n()
|
const { locale } = useI18n()
|
||||||
|
|
|
@ -20,38 +20,38 @@ const isRootPath = computedEager(() => route.name === 'settings')
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<div xl:w-97 lg:w-78 w-full>
|
<div xl:w-97 lg:w-78 w-full>
|
||||||
<SettingsNavItem
|
<SettingsItem
|
||||||
v-if="isHydrated && currentUser "
|
v-if="isHydrated && currentUser "
|
||||||
command
|
command
|
||||||
icon="i-ri:user-line"
|
icon="i-ri:user-line"
|
||||||
:text="$t('settings.profile.label')"
|
:text="$t('settings.profile.label')"
|
||||||
to="/settings/profile"
|
to="/settings/profile"
|
||||||
/>
|
/>
|
||||||
<SettingsNavItem
|
<SettingsItem
|
||||||
command
|
command
|
||||||
icon="i-ri-compasses-2-line"
|
icon="i-ri-compasses-2-line"
|
||||||
:text="$t('settings.interface.label')"
|
:text="$t('settings.interface.label')"
|
||||||
to="/settings/interface"
|
to="/settings/interface"
|
||||||
/>
|
/>
|
||||||
<SettingsNavItem
|
<SettingsItem
|
||||||
command
|
command
|
||||||
icon="i-ri-globe-line"
|
icon="i-ri-globe-line"
|
||||||
:text="$t('settings.language.label')"
|
:text="$t('settings.language.label')"
|
||||||
to="/settings/language"
|
to="/settings/language"
|
||||||
/>
|
/>
|
||||||
<SettingsNavItem
|
<SettingsItem
|
||||||
command
|
command
|
||||||
icon="i-ri:settings-2-line"
|
icon="i-ri:settings-2-line"
|
||||||
:text="$t('settings.preferences.label')"
|
:text="$t('settings.preferences.label')"
|
||||||
to="/settings/preferences"
|
to="/settings/preferences"
|
||||||
/>
|
/>
|
||||||
<SettingsNavItem
|
<SettingsItem
|
||||||
command
|
command
|
||||||
icon="i-ri-group-line"
|
icon="i-ri-group-line"
|
||||||
:text="$t('settings.users.label')"
|
:text="$t('settings.users.label')"
|
||||||
to="/settings/users"
|
to="/settings/users"
|
||||||
/>
|
/>
|
||||||
<SettingsNavItem
|
<SettingsItem
|
||||||
command
|
command
|
||||||
icon="i-ri:information-line"
|
icon="i-ri:information-line"
|
||||||
:text="$t('settings.about.label')"
|
:text="$t('settings.about.label')"
|
||||||
|
|
|
@ -1,3 +1,16 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import buildInfo from 'virtual:build-info'
|
||||||
|
|
||||||
|
let showCommit = $ref(false)
|
||||||
|
const builtTime = useFormattedDateTime(buildInfo.time)
|
||||||
|
|
||||||
|
const handleShowCommit = () => {
|
||||||
|
setTimeout(() => {
|
||||||
|
showCommit = true
|
||||||
|
}, 50)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<MainContent back-on-small-screen>
|
<MainContent back-on-small-screen>
|
||||||
<template #title>
|
<template #title>
|
||||||
|
@ -5,13 +18,76 @@
|
||||||
<span>{{ $t('settings.about.label') }}</span>
|
<span>{{ $t('settings.about.label') }}</span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<div text-center mt-10>
|
|
||||||
<h1 text-4xl>
|
<div flex="~ col gap4" w-full items-center justify-center my5>
|
||||||
🚧
|
<img :alt="$t('app_logo')" src="/logo.svg" w-24 h-24 class="rtl-flip">
|
||||||
</h1>
|
<p text-lg>
|
||||||
<h3 text-xl>
|
{{ $t('app_desc_short') }}
|
||||||
{{ $t('settings.about.label') }}
|
</p>
|
||||||
</h3>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<template v-if="isHydrated">
|
||||||
|
<SettingsItem
|
||||||
|
text="Version"
|
||||||
|
:to="showCommit ? `https://github.com/elk-zone/elk/commit/${buildInfo.commit}` : undefined"
|
||||||
|
external target="_blank"
|
||||||
|
@click="handleShowCommit"
|
||||||
|
>
|
||||||
|
<template #content>
|
||||||
|
<div font-mono>
|
||||||
|
v{{ buildInfo.version }}
|
||||||
|
<span v-if="showCommit">({{ buildInfo.commit.slice(0, 7) }})</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</SettingsItem>
|
||||||
|
|
||||||
|
<SettingsItem text="Built time" :content="builtTime" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<div h-1px bg-border my2 />
|
||||||
|
|
||||||
|
<SettingsItem
|
||||||
|
:text="$t('nav.show_intro')"
|
||||||
|
icon="i-ri:article-line"
|
||||||
|
cursor-pointer
|
||||||
|
@click="openPreviewHelp"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<SettingsItem
|
||||||
|
text="Mastodon"
|
||||||
|
icon="i-ri:mastodon-line"
|
||||||
|
to="https://m.webtoo.ls/@elk"
|
||||||
|
external target="_blank"
|
||||||
|
/>
|
||||||
|
<SettingsItem
|
||||||
|
text="Discord"
|
||||||
|
icon="i-ri:discord-fill"
|
||||||
|
to="https://chat.elk.zone"
|
||||||
|
external target="_blank"
|
||||||
|
/>
|
||||||
|
<SettingsItem
|
||||||
|
text="GitHub"
|
||||||
|
icon="i-ri:github-fill"
|
||||||
|
to="https://github.com/elk-zone"
|
||||||
|
external target="_blank"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<div h-1px bg-border my2 />
|
||||||
|
|
||||||
|
<template v-if="isHydrated">
|
||||||
|
<p px5 py3 font-bold text-lg>
|
||||||
|
Meet the team
|
||||||
|
</p>
|
||||||
|
<SettingsItem
|
||||||
|
v-for="team in teams" :key="team.github"
|
||||||
|
:text="team.display"
|
||||||
|
:to="`https://github.com/sponsors/${team.github}`"
|
||||||
|
external target="_blank"
|
||||||
|
>
|
||||||
|
<template #icon>
|
||||||
|
<img :src="`https://res.cloudinary.com/dchoja2nb/image/twitter_name/h_32,w_32/f_auto/${team.twitter}.jpg`" :alt="team.display" rounded-full w-8 h-8 height="32" width="32">
|
||||||
|
</template>
|
||||||
|
</SettingsItem>
|
||||||
|
</template>
|
||||||
</MainContent>
|
</MainContent>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -12,14 +12,14 @@ definePageMeta({
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<SettingsNavItem
|
<SettingsItem
|
||||||
command
|
command
|
||||||
icon="i-ri:user-settings-line"
|
icon="i-ri:user-settings-line"
|
||||||
:text="$t('settings.profile.appearance.label')"
|
:text="$t('settings.profile.appearance.label')"
|
||||||
:description="$t('settings.profile.appearance.description')"
|
:description="$t('settings.profile.appearance.description')"
|
||||||
to="/settings/profile/appearance"
|
to="/settings/profile/appearance"
|
||||||
/>
|
/>
|
||||||
<SettingsNavItem
|
<SettingsItem
|
||||||
command
|
command
|
||||||
icon="i-ri:hashtag"
|
icon="i-ri:hashtag"
|
||||||
:text="$t('settings.profile.featured_tags.label')"
|
:text="$t('settings.profile.featured_tags.label')"
|
||||||
|
|
Loading…
Reference in a new issue