mirror of
https://github.com/sky-systems/sky_phone.git
synced 2026-08-28 17:01:18 +00:00
ENH - polish phone UI and repository hygiene
This commit is contained in:
@@ -1 +1,2 @@
|
||||
/sky_phone/source/html
|
||||
.pnpm-store/
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
node_modules/
|
||||
dist/
|
||||
.vite/
|
||||
*.local
|
||||
dev-server*.log
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ import pluginVue from 'eslint-plugin-vue'
|
||||
|
||||
export default defineConfigWithVueTs(
|
||||
{ files: ['**/*.{ts,mts,tsx,vue}'], name: 'app/files-to-lint' },
|
||||
globalIgnores(['**/dist/**', 'testserver/**', 'build.cjs']),
|
||||
globalIgnores(['**/.vite/**', '**/dist/**', 'testserver/**', 'build.cjs']),
|
||||
pluginVue.configs['flat/essential'],
|
||||
vueTsConfigs.recommended,
|
||||
skipFormatting,
|
||||
|
||||
+61
-307
@@ -1202,54 +1202,26 @@ button {
|
||||
opacity: 0.2;
|
||||
}
|
||||
|
||||
.banking-header {
|
||||
.banking-navbar {
|
||||
--k-safe-area-top: 46px;
|
||||
position: absolute;
|
||||
z-index: 5;
|
||||
top: 0;
|
||||
right: 0;
|
||||
left: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 54px 22px 13px;
|
||||
background: linear-gradient(to bottom, rgb(7 13 29 / 85%), transparent);
|
||||
}
|
||||
|
||||
.banking-header > div {
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.banking-header span {
|
||||
display: block;
|
||||
color: rgb(208 220 248 / 64%);
|
||||
font-size: 11px;
|
||||
letter-spacing: 0.03em;
|
||||
}
|
||||
|
||||
.banking-header h1 {
|
||||
overflow: hidden;
|
||||
margin: 2px 0 0;
|
||||
font-size: 17px;
|
||||
font-weight: 650;
|
||||
letter-spacing: -0.02em;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.banking-profile {
|
||||
position: relative;
|
||||
display: grid;
|
||||
width: 42px;
|
||||
height: 42px;
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
flex: 0 0 auto;
|
||||
place-items: center;
|
||||
border: 1px solid rgb(255 255 255 / 16%);
|
||||
border-radius: 15px;
|
||||
background: linear-gradient(145deg, rgb(65 130 255 / 42%), rgb(19 35 78 / 48%));
|
||||
box-shadow: inset 0 1px rgb(255 255 255 / 18%), 0 9px 28px rgb(0 0 0 / 22%);
|
||||
border-radius: 50%;
|
||||
background: transparent;
|
||||
color: #dce9ff;
|
||||
backdrop-filter: blur(18px) saturate(145%);
|
||||
-webkit-backdrop-filter: blur(18px) saturate(145%);
|
||||
}
|
||||
|
||||
.banking-profile .banking-spin {
|
||||
@@ -1297,30 +1269,8 @@ button {
|
||||
}
|
||||
|
||||
.banking-balance {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
padding: 22px 20px 20px;
|
||||
border: 1px solid rgb(135 178 255 / 22%);
|
||||
border-radius: 27px;
|
||||
background:
|
||||
linear-gradient(145deg, rgb(50 106 218 / 38%), rgb(15 29 67 / 36%)),
|
||||
rgb(255 255 255 / 3%);
|
||||
box-shadow: inset 0 1px rgb(255 255 255 / 16%), 0 22px 52px rgb(0 0 0 / 26%);
|
||||
backdrop-filter: blur(26px) saturate(150%);
|
||||
-webkit-backdrop-filter: blur(26px) saturate(150%);
|
||||
}
|
||||
|
||||
.banking-balance::after {
|
||||
position: absolute;
|
||||
width: 150px;
|
||||
height: 150px;
|
||||
top: -92px;
|
||||
right: -24px;
|
||||
border-radius: 50%;
|
||||
background: var(--bank-blue);
|
||||
box-shadow: 0 0 68px 25px rgb(45 118 255 / 48%);
|
||||
content: '';
|
||||
opacity: 0.25;
|
||||
}
|
||||
|
||||
.banking-balance__label {
|
||||
@@ -1361,47 +1311,67 @@ button {
|
||||
|
||||
.banking-actions {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 9px;
|
||||
margin: 13px 0 18px;
|
||||
}
|
||||
|
||||
.banking-actions button {
|
||||
.banking-action {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
gap: 7px;
|
||||
padding: 12px 5px 10px;
|
||||
border: 1px solid rgb(255 255 255 / 10%);
|
||||
justify-content: center;
|
||||
gap: 8px;
|
||||
min-height: 64px;
|
||||
padding: 11px 12px;
|
||||
border-radius: 19px;
|
||||
background: rgb(255 255 255 / 5.5%);
|
||||
box-shadow: inset 0 1px rgb(255 255 255 / 9%);
|
||||
color: rgb(237 243 255 / 82%);
|
||||
font-size: 10px;
|
||||
backdrop-filter: blur(17px);
|
||||
-webkit-backdrop-filter: blur(17px);
|
||||
}
|
||||
|
||||
.banking-actions button span {
|
||||
.banking-action__icon {
|
||||
display: grid;
|
||||
width: 38px;
|
||||
height: 38px;
|
||||
width: 34px;
|
||||
height: 34px;
|
||||
flex: 0 0 auto;
|
||||
place-items: center;
|
||||
border-radius: 13px;
|
||||
border-radius: 11px;
|
||||
background: linear-gradient(145deg, rgb(60 129 255 / 34%), rgb(25 54 115 / 25%));
|
||||
color: #8fb8ff;
|
||||
}
|
||||
|
||||
.banking-action b {
|
||||
font-size: 11px;
|
||||
font-weight: 610;
|
||||
}
|
||||
|
||||
.banking-action--primary {
|
||||
grid-column: 1 / -1;
|
||||
justify-content: flex-start;
|
||||
min-height: 58px;
|
||||
padding: 10px 13px;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.banking-action--primary .banking-action__icon {
|
||||
background: rgb(255 255 255 / 15%);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.banking-action--primary svg:last-child {
|
||||
margin-left: auto;
|
||||
opacity: 0.78;
|
||||
}
|
||||
|
||||
.banking-action--secondary {
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.banking-card {
|
||||
margin: 0 0 18px !important;
|
||||
padding: 16px !important;
|
||||
border: 1px solid rgb(255 255 255 / 10%) !important;
|
||||
border-radius: 24px !important;
|
||||
background: linear-gradient(145deg, rgb(255 255 255 / 8%), rgb(255 255 255 / 3%)) !important;
|
||||
box-shadow: inset 0 1px rgb(255 255 255 / 9%), 0 18px 38px rgb(0 0 0 / 18%) !important;
|
||||
color: #fff !important;
|
||||
backdrop-filter: blur(24px) saturate(140%);
|
||||
-webkit-backdrop-filter: blur(24px) saturate(140%);
|
||||
}
|
||||
|
||||
.banking-transaction-card {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.banking-section-title {
|
||||
@@ -1425,140 +1395,22 @@ button {
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
.banking-account-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
padding: 12px;
|
||||
border-radius: 17px;
|
||||
.banking-account-list,
|
||||
.banking-transaction-list {
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
.banking-account-row + .banking-account-row { margin-top: 7px; }
|
||||
|
||||
.banking-account-row--primary {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
border: 1px solid rgb(125 174 255 / 17%);
|
||||
background: linear-gradient(120deg, rgb(37 103 230 / 38%), rgb(36 72 143 / 15%));
|
||||
}
|
||||
|
||||
.banking-account-row > span:first-child {
|
||||
display: grid;
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
flex: 0 0 auto;
|
||||
place-items: center;
|
||||
border-radius: 12px;
|
||||
background: rgb(255 255 255 / 9%);
|
||||
color: #9fc0ff;
|
||||
}
|
||||
|
||||
.banking-account-row div {
|
||||
display: flex;
|
||||
min-width: 0;
|
||||
flex: 1;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.banking-account-row small {
|
||||
color: rgb(216 227 250 / 54%);
|
||||
font-size: 9px;
|
||||
}
|
||||
|
||||
.banking-account-row strong {
|
||||
margin-top: 2px;
|
||||
font-size: 16px;
|
||||
font-weight: 620;
|
||||
}
|
||||
|
||||
.banking-card-mark {
|
||||
position: relative;
|
||||
width: 32px !important;
|
||||
background: transparent !important;
|
||||
}
|
||||
|
||||
.banking-card-mark::before,
|
||||
.banking-card-mark::after {
|
||||
position: absolute;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
top: 8px;
|
||||
border-radius: 50%;
|
||||
background: rgb(255 255 255 / 64%);
|
||||
content: '';
|
||||
}
|
||||
|
||||
.banking-card-mark::before { left: 0; }
|
||||
.banking-card-mark::after { right: 0; background: rgb(120 164 255 / 65%); }
|
||||
|
||||
.banking-transactions { padding: 0 3px; }
|
||||
.banking-transactions--all { margin-top: 18px; }
|
||||
|
||||
.banking-transaction-list {
|
||||
overflow: hidden;
|
||||
border: 1px solid rgb(255 255 255 / 8%);
|
||||
border-radius: 22px;
|
||||
background: rgb(255 255 255 / 3.5%);
|
||||
backdrop-filter: blur(18px);
|
||||
-webkit-backdrop-filter: blur(18px);
|
||||
}
|
||||
|
||||
.banking-transaction {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 11px;
|
||||
padding: 12px;
|
||||
}
|
||||
|
||||
.banking-transaction + .banking-transaction {
|
||||
border-top: 1px solid rgb(255 255 255 / 6%);
|
||||
}
|
||||
|
||||
.banking-transaction > span {
|
||||
display: grid;
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
flex: 0 0 auto;
|
||||
place-items: center;
|
||||
border-radius: 12px;
|
||||
background: rgb(255 106 120 / 10%);
|
||||
color: #ff8793;
|
||||
}
|
||||
|
||||
.banking-transaction > span.is-incoming {
|
||||
background: rgb(78 230 164 / 10%);
|
||||
color: var(--bank-green);
|
||||
}
|
||||
|
||||
.banking-transaction > div {
|
||||
display: flex;
|
||||
min-width: 0;
|
||||
flex: 1;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.banking-transaction strong {
|
||||
overflow: hidden;
|
||||
font-size: 11px;
|
||||
font-weight: 570;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.banking-transaction small {
|
||||
margin-top: 2px;
|
||||
color: rgb(210 221 245 / 43%);
|
||||
font-size: 8px;
|
||||
}
|
||||
|
||||
.banking-transaction b {
|
||||
.banking-transaction-list b {
|
||||
flex: 0 0 auto;
|
||||
color: #f2a0a8;
|
||||
font-size: 11px;
|
||||
font-weight: 620;
|
||||
}
|
||||
|
||||
.banking-transaction b.is-incoming { color: var(--bank-green); }
|
||||
.banking-transaction-list b.is-incoming { color: var(--bank-green); }
|
||||
|
||||
.banking-no-transactions {
|
||||
padding: 24px 12px;
|
||||
@@ -1570,39 +1422,6 @@ button {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.banking-tabbar {
|
||||
position: absolute;
|
||||
z-index: 10;
|
||||
right: 16px;
|
||||
bottom: 22px;
|
||||
left: 16px;
|
||||
width: auto;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.banking-tabbar__background {
|
||||
border: 1px solid rgb(255 255 255 / 13%);
|
||||
border-radius: 24px;
|
||||
background: rgb(14 22 45 / 72%);
|
||||
box-shadow: inset 0 1px rgb(255 255 255 / 12%), 0 16px 48px rgb(0 0 0 / 48%);
|
||||
backdrop-filter: blur(30px) saturate(165%);
|
||||
-webkit-backdrop-filter: blur(30px) saturate(165%);
|
||||
}
|
||||
|
||||
.banking-tabbar__inner {
|
||||
gap: 4px;
|
||||
padding: 7px;
|
||||
}
|
||||
|
||||
.banking-tabbar .k-link {
|
||||
color: rgb(210 222 247 / 48%);
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
.banking-tabbar .k-tabbar-link-active {
|
||||
color: #93b9ff;
|
||||
}
|
||||
|
||||
.banking-activity-hero {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -1693,30 +1512,10 @@ button {
|
||||
font-size: 8px;
|
||||
}
|
||||
|
||||
.banking-modal-backdrop {
|
||||
position: absolute;
|
||||
z-index: 30;
|
||||
inset: 0;
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
padding: 14px 14px 20px;
|
||||
background: rgb(0 3 12 / 58%);
|
||||
backdrop-filter: blur(9px);
|
||||
-webkit-backdrop-filter: blur(9px);
|
||||
}
|
||||
|
||||
.banking-modal {
|
||||
.banking-sheet__content {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
padding: 22px 18px 18px;
|
||||
border: 1px solid rgb(255 255 255 / 14%);
|
||||
border-radius: 29px;
|
||||
background:
|
||||
radial-gradient(circle at 16% 0%, rgb(47 117 255 / 24%), transparent 42%),
|
||||
rgb(13 22 45 / 92%);
|
||||
box-shadow: inset 0 1px rgb(255 255 255 / 14%), 0 24px 70px rgb(0 0 0 / 55%);
|
||||
backdrop-filter: blur(34px) saturate(165%);
|
||||
-webkit-backdrop-filter: blur(34px) saturate(165%);
|
||||
}
|
||||
|
||||
.banking-modal__close {
|
||||
@@ -1742,75 +1541,30 @@ button {
|
||||
box-shadow: 0 12px 28px rgb(22 76 196 / 36%), inset 0 1px rgb(255 255 255 / 28%);
|
||||
}
|
||||
|
||||
.banking-modal h2 {
|
||||
.banking-sheet__content h2 {
|
||||
margin: 14px 0 4px;
|
||||
font-size: 20px;
|
||||
letter-spacing: -0.035em;
|
||||
}
|
||||
|
||||
.banking-modal > p {
|
||||
.banking-sheet__content > p {
|
||||
margin: 0 0 15px;
|
||||
color: rgb(213 225 248 / 52%);
|
||||
font-size: 10px;
|
||||
line-height: 1.45;
|
||||
}
|
||||
|
||||
.banking-modal label {
|
||||
display: block;
|
||||
margin-top: 11px;
|
||||
}
|
||||
.banking-form-list { margin: 12px 0 0 !important; }
|
||||
|
||||
.banking-modal label > span {
|
||||
display: block;
|
||||
margin: 0 0 6px 4px;
|
||||
color: rgb(218 229 251 / 62%);
|
||||
font-size: 9px;
|
||||
}
|
||||
|
||||
.banking-modal input {
|
||||
width: 100%;
|
||||
height: 48px;
|
||||
padding: 0 14px;
|
||||
border: 1px solid rgb(255 255 255 / 10%);
|
||||
border-radius: 15px;
|
||||
outline: none;
|
||||
background: rgb(255 255 255 / 5%);
|
||||
color: #fff;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.banking-modal input:focus {
|
||||
border-color: rgb(72 137 255 / 62%);
|
||||
box-shadow: 0 0 0 3px rgb(45 118 255 / 11%);
|
||||
}
|
||||
|
||||
.banking-amount-input { position: relative; }
|
||||
|
||||
.banking-amount-input i {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 14px;
|
||||
color: #7faaff;
|
||||
font-size: 15px;
|
||||
font-style: normal;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
|
||||
.banking-amount-input input { padding-left: 31px; }
|
||||
|
||||
.banking-modal .banking-form-error {
|
||||
.banking-sheet__content .banking-form-error {
|
||||
margin: 10px 3px 0;
|
||||
color: #ff8b98;
|
||||
font-size: 9px;
|
||||
}
|
||||
|
||||
.banking-modal > button:last-child {
|
||||
margin-top: 15px;
|
||||
background: linear-gradient(135deg, #397fff, #1a55d1) !important;
|
||||
box-shadow: 0 12px 28px rgb(25 78 190 / 30%);
|
||||
}
|
||||
.banking-sheet__content > button:last-child { margin-top: 15px; }
|
||||
|
||||
.banking-modal > button:last-child > span {
|
||||
.banking-sheet__content > button:last-child > span {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
@@ -2,10 +2,18 @@
|
||||
import {
|
||||
kButton,
|
||||
kCard,
|
||||
kGlass,
|
||||
kIcon,
|
||||
kList,
|
||||
kListInput,
|
||||
kListItem,
|
||||
kNavbar,
|
||||
kPage,
|
||||
kPreloader,
|
||||
kSheet,
|
||||
kTabbar,
|
||||
kTabbarLink,
|
||||
kToolbarPane,
|
||||
} from 'konsta/vue'
|
||||
import {
|
||||
ArrowDownLeft,
|
||||
@@ -162,27 +170,29 @@ onMounted(() => void banking.load())
|
||||
<template>
|
||||
<k-page
|
||||
component="main"
|
||||
class="banking-app"
|
||||
class="banking-app pb-safe-24"
|
||||
:colors="{ bgIos: 'bg-transparent' }"
|
||||
>
|
||||
<div class="banking-app__aurora" aria-hidden="true"></div>
|
||||
|
||||
<header class="banking-header">
|
||||
<div>
|
||||
<span>{{ phone.t('Apps.banking.welcome') }}</span>
|
||||
<h1>{{ banking.overview?.playerName ?? phone.t('Common.loading') }}</h1>
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
class="banking-profile"
|
||||
:aria-label="phone.t('Apps.banking.refresh')"
|
||||
:disabled="banking.isLoading"
|
||||
@click="banking.load()"
|
||||
>
|
||||
<Landmark :size="20" />
|
||||
<RefreshCw v-if="banking.isLoading" class="banking-spin" :size="10" />
|
||||
</button>
|
||||
</header>
|
||||
<k-navbar
|
||||
class="banking-navbar"
|
||||
:subtitle="phone.t('Apps.banking.welcome')"
|
||||
:title="banking.overview?.playerName ?? phone.t('Common.loading')"
|
||||
>
|
||||
<template #right>
|
||||
<button
|
||||
type="button"
|
||||
class="banking-profile"
|
||||
:aria-label="phone.t('Apps.banking.refresh')"
|
||||
:disabled="banking.isLoading"
|
||||
@click="banking.load()"
|
||||
>
|
||||
<Landmark :size="20" />
|
||||
<RefreshCw v-if="banking.isLoading" class="banking-spin" :size="10" />
|
||||
</button>
|
||||
</template>
|
||||
</k-navbar>
|
||||
|
||||
<div v-if="!banking.overview && banking.isLoading" class="banking-loading">
|
||||
<k-preloader />
|
||||
@@ -200,7 +210,7 @@ onMounted(() => void banking.load())
|
||||
|
||||
<div v-else class="banking-scroll">
|
||||
<template v-if="activeTab === 'home'">
|
||||
<section class="banking-balance">
|
||||
<k-glass class="banking-balance">
|
||||
<div class="banking-balance__label">
|
||||
<span>{{ phone.t('Apps.banking.totalBalance') }}</span>
|
||||
<small>#{{ banking.overview.playerId }}</small>
|
||||
@@ -210,43 +220,57 @@ onMounted(() => void banking.load())
|
||||
<span>{{ formatMoney(totals.incoming - totals.outgoing, true) }}</span>
|
||||
{{ phone.t('Apps.banking.recentPeriod') }}
|
||||
</div>
|
||||
</section>
|
||||
</k-glass>
|
||||
|
||||
<section class="banking-actions" :aria-label="phone.t('Apps.banking.actions')">
|
||||
<button type="button" @click="openAction('transfer')">
|
||||
<span><Send :size="20" /></span>
|
||||
{{ phone.t('Apps.banking.send') }}
|
||||
</button>
|
||||
<button type="button" @click="openAction('deposit')">
|
||||
<span><ArrowDownLeft :size="20" /></span>
|
||||
{{ phone.t('Apps.banking.deposit') }}
|
||||
</button>
|
||||
<button type="button" @click="openAction('withdraw')">
|
||||
<span><ArrowUpRight :size="20" /></span>
|
||||
{{ phone.t('Apps.banking.withdraw') }}
|
||||
</button>
|
||||
<k-glass
|
||||
component="button"
|
||||
type="button"
|
||||
class="banking-action banking-action--primary"
|
||||
@click="openAction('transfer')"
|
||||
>
|
||||
<span class="banking-action__icon"><Send :size="20" /></span>
|
||||
<b>{{ phone.t('Apps.banking.send') }}</b>
|
||||
<ChevronRight :size="16" aria-hidden="true" />
|
||||
</k-glass>
|
||||
<k-glass
|
||||
component="button"
|
||||
type="button"
|
||||
class="banking-action banking-action--secondary"
|
||||
@click="openAction('deposit')"
|
||||
>
|
||||
<span class="banking-action__icon"><ArrowDownLeft :size="20" /></span>
|
||||
<b>{{ phone.t('Apps.banking.deposit') }}</b>
|
||||
</k-glass>
|
||||
<k-glass
|
||||
component="button"
|
||||
type="button"
|
||||
class="banking-action banking-action--secondary"
|
||||
@click="openAction('withdraw')"
|
||||
>
|
||||
<span class="banking-action__icon"><ArrowUpRight :size="20" /></span>
|
||||
<b>{{ phone.t('Apps.banking.withdraw') }}</b>
|
||||
</k-glass>
|
||||
</section>
|
||||
|
||||
<k-card :content-wrap="false" class="banking-card banking-accounts">
|
||||
<k-card class="banking-card banking-accounts">
|
||||
<div class="banking-section-title">
|
||||
<h2>{{ phone.t('Apps.banking.accounts') }}</h2>
|
||||
<ChevronRight :size="17" />
|
||||
</div>
|
||||
<div class="banking-account-row banking-account-row--primary">
|
||||
<span><WalletCards :size="18" /></span>
|
||||
<div>
|
||||
<small>{{ phone.t('Apps.banking.bankAccount') }}</small>
|
||||
<strong>{{ formatMoney(banking.overview.bank) }}</strong>
|
||||
</div>
|
||||
<span class="banking-card-mark" aria-hidden="true"></span>
|
||||
</div>
|
||||
<div class="banking-account-row">
|
||||
<span><CircleDollarSign :size="18" /></span>
|
||||
<div>
|
||||
<small>{{ phone.t('Apps.banking.cash') }}</small>
|
||||
<strong>{{ formatMoney(banking.overview.cash) }}</strong>
|
||||
</div>
|
||||
</div>
|
||||
<k-list inset strong class="banking-account-list">
|
||||
<k-list-item
|
||||
:title="phone.t('Apps.banking.bankAccount')"
|
||||
:after="formatMoney(banking.overview.bank)"
|
||||
>
|
||||
<template #media><WalletCards :size="18" /></template>
|
||||
</k-list-item>
|
||||
<k-list-item
|
||||
:title="phone.t('Apps.banking.cash')"
|
||||
:after="formatMoney(banking.overview.cash)"
|
||||
>
|
||||
<template #media><CircleDollarSign :size="18" /></template>
|
||||
</k-list-item>
|
||||
</k-list>
|
||||
</k-card>
|
||||
|
||||
<section class="banking-transactions">
|
||||
@@ -256,24 +280,29 @@ onMounted(() => void banking.load())
|
||||
{{ phone.t('Apps.banking.viewAll') }}
|
||||
</button>
|
||||
</div>
|
||||
<div v-if="banking.overview.transactions.length" class="banking-transaction-list">
|
||||
<article
|
||||
<k-card
|
||||
v-if="banking.overview.transactions.length"
|
||||
:content-wrap="false"
|
||||
class="banking-card banking-transaction-card"
|
||||
>
|
||||
<k-list inset strong class="banking-transaction-list">
|
||||
<k-list-item
|
||||
v-for="transaction in banking.overview.transactions.slice(0, 5)"
|
||||
:key="transaction.id"
|
||||
class="banking-transaction"
|
||||
>
|
||||
<span :class="{ 'is-incoming': isIncoming(transaction.kind) }">
|
||||
<component :is="transactionIcons[transaction.kind]" :size="17" />
|
||||
</span>
|
||||
<div>
|
||||
<strong>{{ transactionTitle(transaction) }}</strong>
|
||||
<small>{{ formatDate(transaction.createdAt) }}</small>
|
||||
</div>
|
||||
<b :class="{ 'is-incoming': isIncoming(transaction.kind) }">
|
||||
{{ formatMoney(isIncoming(transaction.kind) ? transaction.amount : -transaction.amount, true) }}
|
||||
</b>
|
||||
</article>
|
||||
</div>
|
||||
:subtitle="formatDate(transaction.createdAt)"
|
||||
:title="transactionTitle(transaction)"
|
||||
>
|
||||
<template #media>
|
||||
<component :is="transactionIcons[transaction.kind]" :size="17" />
|
||||
</template>
|
||||
<template #after>
|
||||
<b :class="{ 'is-incoming': isIncoming(transaction.kind) }">
|
||||
{{ formatMoney(isIncoming(transaction.kind) ? transaction.amount : -transaction.amount, true) }}
|
||||
</b>
|
||||
</template>
|
||||
</k-list-item>
|
||||
</k-list>
|
||||
</k-card>
|
||||
<p v-else class="banking-no-transactions">
|
||||
{{ phone.t('Apps.banking.noTransactions') }}
|
||||
</p>
|
||||
@@ -307,24 +336,25 @@ onMounted(() => void banking.load())
|
||||
<div class="banking-section-title">
|
||||
<h2>{{ phone.t('Apps.banking.allTransactions') }}</h2>
|
||||
</div>
|
||||
<div class="banking-transaction-list">
|
||||
<article
|
||||
v-for="transaction in banking.overview.transactions"
|
||||
:key="transaction.id"
|
||||
class="banking-transaction"
|
||||
>
|
||||
<span :class="{ 'is-incoming': isIncoming(transaction.kind) }">
|
||||
<component :is="transactionIcons[transaction.kind]" :size="17" />
|
||||
</span>
|
||||
<div>
|
||||
<strong>{{ transactionTitle(transaction) }}</strong>
|
||||
<small>{{ formatDate(transaction.createdAt) }}</small>
|
||||
</div>
|
||||
<b :class="{ 'is-incoming': isIncoming(transaction.kind) }">
|
||||
{{ formatMoney(isIncoming(transaction.kind) ? transaction.amount : -transaction.amount, true) }}
|
||||
</b>
|
||||
</article>
|
||||
</div>
|
||||
<k-card :content-wrap="false" class="banking-card banking-transaction-card">
|
||||
<k-list inset strong class="banking-transaction-list">
|
||||
<k-list-item
|
||||
v-for="transaction in banking.overview.transactions"
|
||||
:key="transaction.id"
|
||||
:subtitle="formatDate(transaction.createdAt)"
|
||||
:title="transactionTitle(transaction)"
|
||||
>
|
||||
<template #media>
|
||||
<component :is="transactionIcons[transaction.kind]" :size="17" />
|
||||
</template>
|
||||
<template #after>
|
||||
<b :class="{ 'is-incoming': isIncoming(transaction.kind) }">
|
||||
{{ formatMoney(isIncoming(transaction.kind) ? transaction.amount : -transaction.amount, true) }}
|
||||
</b>
|
||||
</template>
|
||||
</k-list-item>
|
||||
</k-list>
|
||||
</k-card>
|
||||
</section>
|
||||
</template>
|
||||
</div>
|
||||
@@ -334,33 +364,37 @@ onMounted(() => void banking.load())
|
||||
component="nav"
|
||||
icons
|
||||
labels
|
||||
class="banking-tabbar"
|
||||
bg-class="banking-tabbar__background"
|
||||
inner-class="banking-tabbar__inner"
|
||||
class="bottom-0 left-0 fixed"
|
||||
:aria-label="phone.t('Apps.banking.navigation')"
|
||||
>
|
||||
<k-tabbar-link
|
||||
component="button"
|
||||
:active="activeTab === 'home'"
|
||||
:label="phone.t('Apps.banking.home')"
|
||||
:link-props="{ type: 'button' }"
|
||||
@click="activeTab = 'home'"
|
||||
>
|
||||
<template #icon><House :size="19" /></template>
|
||||
</k-tabbar-link>
|
||||
<k-tabbar-link
|
||||
component="button"
|
||||
:active="activeTab === 'activity'"
|
||||
:label="phone.t('Apps.banking.activity')"
|
||||
:link-props="{ type: 'button' }"
|
||||
@click="activeTab = 'activity'"
|
||||
>
|
||||
<template #icon><BarChart3 :size="19" /></template>
|
||||
</k-tabbar-link>
|
||||
<k-toolbar-pane>
|
||||
<k-tabbar-link
|
||||
component="button"
|
||||
:active="activeTab === 'home'"
|
||||
:link-props="{ type: 'button' }"
|
||||
@click="activeTab = 'home'"
|
||||
>
|
||||
<template #label>{{ phone.t('Apps.banking.home') }}</template>
|
||||
<template #icon>
|
||||
<k-icon><House class="w-7 h-7" /></k-icon>
|
||||
</template>
|
||||
</k-tabbar-link>
|
||||
<k-tabbar-link
|
||||
component="button"
|
||||
:active="activeTab === 'activity'"
|
||||
:link-props="{ type: 'button' }"
|
||||
@click="activeTab = 'activity'"
|
||||
>
|
||||
<template #label>{{ phone.t('Apps.banking.activity') }}</template>
|
||||
<template #icon>
|
||||
<k-icon><BarChart3 class="w-7 h-7" /></k-icon>
|
||||
</template>
|
||||
</k-tabbar-link>
|
||||
</k-toolbar-pane>
|
||||
</k-tabbar>
|
||||
|
||||
<div v-if="action" class="banking-modal-backdrop" @click.self="closeAction">
|
||||
<section class="banking-modal" role="dialog" aria-modal="true">
|
||||
<k-sheet :opened="Boolean(action)" class="banking-sheet" @backdropclick="closeAction">
|
||||
<section v-if="action" class="banking-sheet__content" role="dialog" aria-modal="true">
|
||||
<button
|
||||
type="button"
|
||||
class="banking-modal__close"
|
||||
@@ -376,30 +410,30 @@ onMounted(() => void banking.load())
|
||||
</span>
|
||||
<h2>{{ phone.t(`Apps.banking.forms.${action}.title`) }}</h2>
|
||||
<p>{{ phone.t(`Apps.banking.forms.${action}.body`) }}</p>
|
||||
<label v-if="action === 'transfer'">
|
||||
<span>{{ phone.t('Apps.banking.playerId') }}</span>
|
||||
<input
|
||||
v-model="target"
|
||||
<k-list inset strong class="banking-form-list">
|
||||
<k-list-input
|
||||
v-if="action === 'transfer'"
|
||||
:label="phone.t('Apps.banking.playerId')"
|
||||
inputmode="numeric"
|
||||
min="1"
|
||||
type="number"
|
||||
outline
|
||||
:placeholder="phone.t('Apps.banking.playerIdPlaceholder')"
|
||||
type="number"
|
||||
:value="target"
|
||||
@input="target = $event"
|
||||
/>
|
||||
</label>
|
||||
<label>
|
||||
<span>{{ phone.t('Apps.banking.amount') }}</span>
|
||||
<div class="banking-amount-input">
|
||||
<i>{{ banking.overview?.currency }}</i>
|
||||
<input
|
||||
v-model="amount"
|
||||
inputmode="numeric"
|
||||
min="1"
|
||||
type="number"
|
||||
:placeholder="phone.t('Apps.banking.amountPlaceholder')"
|
||||
@keydown.enter="submitAction"
|
||||
/>
|
||||
</div>
|
||||
</label>
|
||||
<k-list-input
|
||||
:label="phone.t('Apps.banking.amount')"
|
||||
inputmode="numeric"
|
||||
min="1"
|
||||
outline
|
||||
:placeholder="phone.t('Apps.banking.amountPlaceholder')"
|
||||
type="number"
|
||||
:value="amount"
|
||||
@input="amount = $event"
|
||||
@keydown.enter="submitAction"
|
||||
/>
|
||||
</k-list>
|
||||
<p v-if="formError" class="banking-form-error">{{ formError }}</p>
|
||||
<k-button
|
||||
large
|
||||
@@ -414,6 +448,6 @@ onMounted(() => void banking.load())
|
||||
</template>
|
||||
</k-button>
|
||||
</section>
|
||||
</div>
|
||||
</k-sheet>
|
||||
</k-page>
|
||||
</template>
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Sky Phone</title>
|
||||
<script type="module" crossorigin src="./assets/sky-index-CsAxDiPY.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="./assets/sky-index-D9Q9SXH9.css">
|
||||
<script type="module" crossorigin src="./assets/sky-index-i5PQ5yRP.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="./assets/sky-index-p1qSFvW3.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
|
||||
Reference in New Issue
Block a user