feat: unify phone apps with Sky UI

This commit is contained in:
Leon.Schmidt
2026-08-16 15:23:21 +02:00
parent 8d9cdb5d6b
commit 1071b4bde7
62 changed files with 5658 additions and 3349 deletions
+12 -25
View File
@@ -1,25 +1,21 @@
<script setup lang="ts">
import {
kBlock,
kBlockTitle,
kButton,
kLink,
kList,
kListInput,
kListItem,
kNavbar,
} from 'konsta/vue'
SkyBlock as kBlock,
SkyBlockTitle as kBlockTitle,
SkyButton as kButton,
SkyField as kListInput,
SkyLink as kLink,
SkyList as kList,
SkyListItem as kListItem,
SkyNavbar as kNavbar,
} from '@/ui'
import { ChevronRight, Check, X } from 'lucide-vue-next'
import { reactive, ref } from 'vue'
import AlarmSoundMenu from '@/components/AlarmSoundMenu.vue'
import { usePhoneStore } from '@/stores/phone'
import TimeWheelPicker from '@/components/TimeWheelPicker.vue'
import {
type Alarm,
type AlarmDraft,
WEEKDAY_IDS,
} from '@/utils/alarms'
import { type Alarm, type AlarmDraft, WEEKDAY_IDS } from '@/utils/alarms'
const props = defineProps<{ alarm?: Alarm }>()
const emit = defineEmits<{
@@ -44,14 +40,6 @@ const draft = reactive<AlarmDraft>({
time: props.alarm?.time ?? '07:00',
weekdays: [...(props.alarm?.weekdays ?? [])],
})
const dangerColors = {
tonalBgIos: 'bg-red-500/15 active:bg-red-500/25',
tonalTextIos: 'text-red-500',
}
const saveLinkColors = {
navbarTextIos: 'text-[#ff9f0a]',
}
function setNote(event: Event): void {
draft.note = (event.target as HTMLInputElement).value.slice(0, 80)
}
@@ -97,7 +85,7 @@ function toggleWeekday(weekday: number): void {
<k-link
component="button"
icon-only
:colors="saveLinkColors"
class="clock-alarm-save"
:link-props="{ type: 'button' }"
:aria-label="phone.t('Common.save')"
@click="save"
@@ -168,8 +156,7 @@ function toggleWeekday(weekday: number): void {
v-if="alarm"
large
rounded
tonal
:colors="dangerColors"
variant="danger"
class="clock-alarm-delete"
@click="emit('delete')"
>
+6 -1
View File
@@ -1,5 +1,10 @@
<script setup lang="ts">
import { kList, kListItem, kNavbar, kNavbarBackLink } from 'konsta/vue'
import {
SkyList as kList,
SkyListItem as kListItem,
SkyNavbar as kNavbar,
SkyNavbarBackLink as kNavbarBackLink,
} from '@/ui'
import { Check } from 'lucide-vue-next'
import { onBeforeUnmount } from 'vue'
+3 -12
View File
@@ -1,5 +1,5 @@
<script setup lang="ts">
import { kBadge } from 'konsta/vue'
import { SkyBadge as kBadge } from '@/ui'
import { Minus } from 'lucide-vue-next'
import { computed, onBeforeUnmount, onMounted, ref, watch } from 'vue'
import { useRouter } from 'vue-router'
@@ -100,10 +100,6 @@ const unreadCount = computed(() => {
if (props.app.id === 'companies') return companies.unreadCount
return 0
})
const notificationBadgeColors = {
bg: 'bg-[#ff3b30]',
text: 'text-white',
}
const calendarWeekday = computed(() =>
new Intl.DateTimeFormat(phone.lang, { weekday: 'short' })
.format(calendarToday.value)
@@ -142,11 +138,6 @@ function launch(event: MouseEvent): void {
void router.push(props.app.route)
}
const removeBadgeColors = {
bg: 'bg-[#8e8e93]',
text: 'text-black',
}
function clearHold(): void {
if (holdTimer !== undefined) window.clearTimeout(holdTimer)
holdTimer = undefined
@@ -321,7 +312,7 @@ onBeforeUnmount(() => {
v-if="unreadCount"
class="app-icon-badge"
:small="compact"
:colors="notificationBadgeColors"
tone="danger"
>
{{ unreadCount > 99 ? '99+' : unreadCount }}
</k-badge>
@@ -343,7 +334,7 @@ onBeforeUnmount(() => {
@click.stop="emit('remove')"
@pointerdown.stop
>
<k-badge class="app-icon-remove__badge" :colors="removeBadgeColors">
<k-badge class="app-icon-remove__badge" tone="neutral">
<Minus :size="15" :stroke-width="3" aria-hidden="true" />
</k-badge>
</button>
+7 -2
View File
@@ -1,5 +1,10 @@
<script setup lang="ts">
import { kBlock, kButton, kPage, kPreloader } from 'konsta/vue'
import {
SkyAppPage as kPage,
SkyBlock as kBlock,
SkyButton as kButton,
SkySpinner as kPreloader,
} from '@/ui'
import { computed, onBeforeMount, onBeforeUnmount, ref, watch } from 'vue'
import { useRouter } from 'vue-router'
@@ -478,7 +483,7 @@ watch(() => catalog.openRequests[props.app.id], flushOpenRequest, {
text-align: center;
}
.custom-app-state :deep(.k-block) {
.custom-app-state :deep(.sky-block) {
margin: 0;
}
@@ -1,5 +1,5 @@
<script setup lang="ts">
import { kDialog, kDialogButton } from 'konsta/vue'
import { SkyDialog as kDialog, SkyDialogButton as kDialogButton } from '@/ui'
import { useAppAuthStore, type AppAuthId } from '@/stores/app-auth'
import { useCrewLinkStore } from '@/stores/crewlink'
@@ -39,7 +39,9 @@ function confirmLogout(): void {
<template>
<k-dialog :opened="opened" @backdropclick="close">
<template #title>{{ phone.t('Common.signOutTitle', { app: appName }) }}</template>
<template #title>{{
phone.t('Common.signOutTitle', { app: appName })
}}</template>
<p>{{ phone.t('Common.signOutBody', { app: appName }) }}</p>
<template #buttons>
<k-dialog-button @click="close">
@@ -8,14 +8,14 @@ import {
UserRound,
} from 'lucide-vue-next'
import {
kButton,
kGlass,
kList,
kListInput,
kPreloader,
kSegmented,
kSegmentedButton,
} from 'konsta/vue'
SkyButton as kButton,
SkyField as kListInput,
SkyGlass as kGlass,
SkyList as kList,
SkySegmented as kSegmented,
SkySegmentedButton as kSegmentedButton,
SkySpinner as kPreloader,
} from '@/ui'
import { computed } from 'vue'
const props = withDefaults(
@@ -328,7 +328,7 @@ const canSubmit = computed(() => {
flex: 1;
gap: 6px;
}
.app-profile-auth__photo :deep(.k-button) {
.app-profile-auth__photo :deep(.sky-button) {
min-height: 32px;
justify-content: flex-start;
gap: 6px;
@@ -410,8 +410,8 @@ const canSubmit = computed(() => {
font-size: 11px;
}
.app-profile-auth__submit {
--k-button-bg-color: var(--auth-accent, var(--yellow, #ffd63e));
--k-button-text-color: #fff;
--sky-app-accent: var(--auth-accent, var(--yellow, #ffd63e));
--sky-button-text: #fff;
width: 100%;
min-height: 44px;
display: flex;
@@ -1,12 +1,12 @@
<script setup lang="ts">
import {
kButton,
kList,
kListInput,
kPreloader,
kSegmented,
kSegmentedButton,
} from 'konsta/vue'
SkyButton as kButton,
SkyField as kListInput,
SkyList as kList,
SkySegmented as kSegmented,
SkySegmentedButton as kSegmentedButton,
SkySpinner as kPreloader,
} from '@/ui'
import { computed, ref } from 'vue'
import { useAccountStore } from '@/stores/account'
@@ -36,11 +36,13 @@ const error = ref('')
const canSubmit = computed(() => {
const normalized = normalizeMailAddress(email.value)
const passwordValid = password.value.length >= 6 && password.value.length <= 64
const passwordValid =
password.value.length >= 6 && password.value.length <= 64
return Boolean(
normalized &&
passwordValid &&
(mode.value === 'login' || (confirm.value && confirm.value === password.value)),
(mode.value === 'login' ||
(confirm.value && confirm.value === password.value)),
)
})
@@ -101,7 +103,10 @@ async function submit(): Promise<void> {
<k-segmented-button :active="mode === 'login'" @click="setMode('login')">
{{ phone.t('Common.appAuth.login') }}
</k-segmented-button>
<k-segmented-button :active="mode === 'register'" @click="setMode('register')">
<k-segmented-button
:active="mode === 'register'"
@click="setMode('register')"
>
{{ phone.t('Common.appAuth.register') }}
</k-segmented-button>
</k-segmented>
@@ -144,7 +149,13 @@ async function submit(): Promise<void> {
<k-button large rounded :disabled="!canSubmit || pending" @click="submit">
<k-preloader v-if="pending" />
<template v-else>
{{ phone.t(mode === 'login' ? 'Common.appAuth.loginAction' : 'Common.appAuth.registerAction') }}
{{
phone.t(
mode === 'login'
? 'Common.appAuth.loginAction'
: 'Common.appAuth.registerAction',
)
}}
</template>
</k-button>
</section>
@@ -159,7 +170,7 @@ async function submit(): Promise<void> {
text-align: center;
}
.ifruit-app-auth > small {
color: var(--k-color-primary);
color: var(--sky-app-accent);
font-size: 10px;
font-weight: 800;
letter-spacing: 0.08em;
@@ -1,6 +1,6 @@
<script setup lang="ts">
import { Check, ChevronDown } from 'lucide-vue-next'
import { kGlass } from 'konsta/vue'
import { SkyGlass as kGlass } from '@/ui'
import { computed, onMounted, onUnmounted, ref } from 'vue'
type SelectOption = {
@@ -8,7 +8,11 @@ import {
Share2,
UserRound,
} from 'lucide-vue-next'
import { kButton, kGlass, kIcon } from 'konsta/vue'
import {
SkyButton as kButton,
SkyGlass as kGlass,
SkyIcon as kIcon,
} from '@/ui'
import { computed, ref } from 'vue'
import { usePhoneStore } from '@/stores/phone'
@@ -263,8 +267,8 @@ function relativeTime(timestamp: number): string {
color: #438cf5;
}
.feather-follow {
--k-button-bg-color: transparent;
--k-button-text-color: var(--feather-blue, #1d9bf0);
--sky-app-accent: transparent;
--sky-button-text: var(--feather-blue, #1d9bf0);
width: auto;
min-width: 58px;
max-width: 68px;