feat(miniapp): simplify ready state layout

This commit is contained in:
2026-03-11 17:57:35 +04:00
parent e07dfeadf5
commit d40f5e1d84
3 changed files with 69 additions and 34 deletions

View File

@@ -369,6 +369,7 @@ function App() {
const [cycleRentOpen, setCycleRentOpen] = createSignal(false) const [cycleRentOpen, setCycleRentOpen] = createSignal(false)
const [addingUtilityBillOpen, setAddingUtilityBillOpen] = createSignal(false) const [addingUtilityBillOpen, setAddingUtilityBillOpen] = createSignal(false)
const [addingPaymentOpen, setAddingPaymentOpen] = createSignal(false) const [addingPaymentOpen, setAddingPaymentOpen] = createSignal(false)
const [profileEditorOpen, setProfileEditorOpen] = createSignal(false)
const [addingPayment, setAddingPayment] = createSignal(false) const [addingPayment, setAddingPayment] = createSignal(false)
const [billingForm, setBillingForm] = createSignal({ const [billingForm, setBillingForm] = createSignal({
settlementCurrency: 'GEL' as 'USD' | 'GEL', settlementCurrency: 'GEL' as 'USD' | 'GEL',
@@ -3984,6 +3985,13 @@ function App() {
{readySession()?.telegramUser.firstName ?? readySession()?.member.displayName} {readySession()?.telegramUser.firstName ?? readySession()?.member.displayName}
</h2> </h2>
<p>{copy().overviewBody}</p> <p>{copy().overviewBody}</p>
<Show when={readySession()?.mode === 'live'}>
<div class="panel-toolbar">
<Button variant="secondary" onClick={() => setProfileEditorOpen(true)}>
{copy().manageProfileAction}
</Button>
</div>
</Show>
</section> </section>
<nav class="nav-grid"> <nav class="nav-grid">
@@ -4006,9 +4014,11 @@ function App() {
</nav> </nav>
<section class="content-grid"> <section class="content-grid">
<article class="panel panel--wide"> <article class="balance-item balance-item--accent profile-card">
<p class="eyebrow">{copy().overviewTitle}</p> <header>
<h3>{readySession()?.member.displayName}</h3> <strong>{readySession()?.member.displayName}</strong>
<span>{readySession()?.member.isAdmin ? copy().adminTag : copy().residentTag}</span>
</header>
<p> <p>
{copy().memberStatusSummary.replace( {copy().memberStatusSummary.replace(
'{status}', '{status}',
@@ -4017,35 +4027,49 @@ function App() {
: copy().memberStatusActive : copy().memberStatusActive
)} )}
</p> </p>
<Show when={readySession()?.mode === 'live'}> <div class="ledger-compact-card__meta">
<div class="settings-grid"> <span class="mini-chip">
<label class="settings-field settings-field--wide"> {readySession()?.mode === 'demo' ? copy().demoBadge : copy().liveBadge}
<span>{copy().displayNameLabel}</span> </span>
<input <span class="mini-chip mini-chip--muted">{locale().toUpperCase()}</span>
value={displayNameDraft()} </div>
onInput={(event) => setDisplayNameDraft(event.currentTarget.value)}
/>
<small>{copy().displayNameHint}</small>
</label>
</div>
<div class="inline-actions">
<button
class="ghost-button"
type="button"
disabled={
savingOwnDisplayName() ||
displayNameDraft().trim().length < 2 ||
displayNameDraft().trim() === readySession()?.member.displayName
}
onClick={() => void handleSaveOwnDisplayName()}
>
{savingOwnDisplayName() ? copy().savingDisplayName : copy().saveDisplayName}
</button>
</div>
</Show>
<div>{renderPanel()}</div>
</article> </article>
<div class="content-stack">{renderPanel()}</div>
</section> </section>
<Modal
open={profileEditorOpen()}
title={copy().displayNameLabel}
description={copy().profileEditorBody}
closeLabel={copy().closeEditorAction}
onClose={() => setProfileEditorOpen(false)}
footer={
<div class="modal-action-row modal-action-row--single">
<Button variant="ghost" onClick={() => setProfileEditorOpen(false)}>
{copy().closeEditorAction}
</Button>
<Button
variant="primary"
disabled={
savingOwnDisplayName() ||
displayNameDraft().trim().length < 2 ||
displayNameDraft().trim() === readySession()?.member.displayName
}
onClick={() => void handleSaveOwnDisplayName()}
>
{savingOwnDisplayName() ? copy().savingDisplayName : copy().saveDisplayName}
</Button>
</div>
}
>
<div class="editor-grid">
<Field label={copy().displayNameLabel} hint={copy().displayNameHint} wide>
<input
value={displayNameDraft()}
onInput={(event) => setDisplayNameDraft(event.currentTarget.value)}
/>
</Field>
</div>
</Modal>
</Match> </Match>
</Switch> </Switch>
</main> </main>

View File

@@ -181,6 +181,8 @@ export const dictionary = {
adminsBody: 'Promote trusted household members so they can manage billing and approvals.', adminsBody: 'Promote trusted household members so they can manage billing and approvals.',
displayNameLabel: 'Household display name', displayNameLabel: 'Household display name',
displayNameHint: 'This name appears in balances, ledger entries, and assistant replies.', displayNameHint: 'This name appears in balances, ledger entries, and assistant replies.',
manageProfileAction: 'Edit profile',
profileEditorBody: 'Keep your own display name in a focused editor instead of the page body.',
memberEditorBody: 'Member billing state and admin controls stay grouped in one editor.', memberEditorBody: 'Member billing state and admin controls stay grouped in one editor.',
editMemberAction: 'Edit member', editMemberAction: 'Edit member',
saveDisplayName: 'Save name', saveDisplayName: 'Save name',
@@ -402,6 +404,9 @@ export const dictionary = {
'Повышай доверенных участников, чтобы они могли управлять биллингом и подтверждениями.', 'Повышай доверенных участников, чтобы они могли управлять биллингом и подтверждениями.',
displayNameLabel: 'Имя в household', displayNameLabel: 'Имя в household',
displayNameHint: 'Это имя будет видно в балансе, леджере и ответах ассистента.', displayNameHint: 'Это имя будет видно в балансе, леджере и ответах ассистента.',
manageProfileAction: 'Редактировать профиль',
profileEditorBody:
'Своё имя для household лучше менять в отдельном окне, а не на самой странице.',
memberEditorBody: 'Статус, политика и админские действия по участнику собраны в одном окне.', memberEditorBody: 'Статус, политика и админские действия по участнику собраны в одном окне.',
editMemberAction: 'Редактировать участника', editMemberAction: 'Редактировать участника',
saveDisplayName: 'Сохранить имя', saveDisplayName: 'Сохранить имя',

View File

@@ -279,6 +279,11 @@ button {
margin-top: 16px; margin-top: 16px;
} }
.content-stack {
display: grid;
gap: 12px;
}
.panel { .panel {
border-radius: 24px; border-radius: 24px;
padding: 18px; padding: 18px;
@@ -312,6 +317,10 @@ button {
border-color: rgb(247 179 137 / 0.28); border-color: rgb(247 179 137 / 0.28);
} }
.profile-card {
gap: 10px;
}
.balance-item header, .balance-item header,
.ledger-item header, .ledger-item header,
.activity-row header, .activity-row header,
@@ -679,6 +688,7 @@ button {
.panel-toolbar { .panel-toolbar {
display: flex; display: flex;
flex-wrap: wrap;
justify-content: flex-end; justify-content: flex-end;
margin-top: 12px; margin-top: 12px;
} }
@@ -893,10 +903,6 @@ button {
padding: 32px 24px 40px; padding: 32px 24px 40px;
} }
.content-grid {
grid-template-columns: 1.3fr 1fr 1fr;
}
.home-grid { .home-grid {
grid-template-columns: repeat(4, minmax(0, 1fr)); grid-template-columns: repeat(4, minmax(0, 1fr));
} }