diff --git a/apps/miniapp/src/App.tsx b/apps/miniapp/src/App.tsx index 7464662..3ed8619 100644 --- a/apps/miniapp/src/App.tsx +++ b/apps/miniapp/src/App.tsx @@ -14,7 +14,6 @@ import { addMiniAppUtilityBill, addMiniAppPayment, approveMiniAppPendingMember, - closeMiniAppBillingCycle, deleteMiniAppPayment, deleteMiniAppPurchase, deleteMiniAppUtilityBill, @@ -39,7 +38,16 @@ import { type MiniAppDashboard, type MiniAppPendingMember } from './miniapp-api' -import { Button, Field, MiniChip, Modal } from './components/ui' +import { + Button, + Field, + HomeIcon, + HouseIcon, + MiniChip, + Modal, + ReceiptIcon, + WalletIcon +} from './components/ui' import { NavigationTabs } from './components/layout/navigation-tabs' import { TopBar } from './components/layout/top-bar' import { BlockedState } from './components/session/blocked-state' @@ -96,7 +104,6 @@ type SessionState = } type NavigationKey = 'home' | 'balances' | 'ledger' | 'house' -type HouseSectionKey = 'billing' | 'utilities' | 'members' | 'topics' type UtilityBillDraft = { billName: string @@ -124,7 +131,6 @@ type PaymentDraft = { type TestingRolePreview = 'admin' | 'resident' -const chartPalette = ['#f7b389', '#6fd3c0', '#f06a8d', '#94a8ff', '#f3d36f', '#7dc96d'] as const const TESTING_ROLE_TAP_WINDOW_MS = 30 * 60 * 1000 const demoSession: Extract = { @@ -180,30 +186,6 @@ function defaultCyclePeriod(): string { return new Date().toISOString().slice(0, 7) } -function absoluteMinor(value: bigint): bigint { - return value < 0n ? -value : value -} - -function memberBaseDueMajor(member: MiniAppDashboard['members'][number]): string { - return minorToMajorString( - majorStringToMinor(member.rentShareMajor) + majorStringToMinor(member.utilityShareMajor) - ) -} - -function memberRemainingClass(member: MiniAppDashboard['members'][number]): string { - const remainingMinor = majorStringToMinor(member.remainingMajor) - - if (remainingMinor < 0n) { - return 'is-credit' - } - - if (remainingMinor === 0n) { - return 'is-settled' - } - - return 'is-due' -} - function ledgerPrimaryAmount(entry: MiniAppDashboard['ledger'][number]): string { return `${entry.displayAmountMajor} ${entry.displayCurrency}` } @@ -305,7 +287,6 @@ function App() { status: 'loading' }) const [activeNav, setActiveNav] = createSignal('home') - const [activeHouseSection, setActiveHouseSection] = createSignal('billing') const [dashboard, setDashboard] = createSignal(null) const [pendingMembers, setPendingMembers] = createSignal([]) const [adminSettings, setAdminSettings] = createSignal(null) @@ -335,7 +316,6 @@ function App() { const [savingBillingSettings, setSavingBillingSettings] = createSignal(false) const [savingCategorySlug, setSavingCategorySlug] = createSignal(null) const [openingCycle, setOpeningCycle] = createSignal(false) - const [closingCycle, setClosingCycle] = createSignal(false) const [savingCycleRent, setSavingCycleRent] = createSignal(false) const [savingUtilityBill, setSavingUtilityBill] = createSignal(false) const [savingUtilityBillId, setSavingUtilityBillId] = createSignal(null) @@ -475,134 +455,6 @@ function App() { ) ) ) - const memberBalanceVisuals = createMemo(() => { - const data = dashboard() - if (!data) { - return [] - } - - const totals = data.members.map((member) => { - const rentMinor = absoluteMinor(majorStringToMinor(member.rentShareMajor)) - const utilityMinor = absoluteMinor(majorStringToMinor(member.utilityShareMajor)) - const purchaseMinor = absoluteMinor(majorStringToMinor(member.purchaseOffsetMajor)) - - return { - member, - totalMinor: rentMinor + utilityMinor + purchaseMinor, - segments: [ - { - key: 'rent', - label: copy().shareRent, - amountMajor: member.rentShareMajor, - amountMinor: rentMinor - }, - { - key: 'utilities', - label: copy().shareUtilities, - amountMajor: member.utilityShareMajor, - amountMinor: utilityMinor - }, - { - key: - majorStringToMinor(member.purchaseOffsetMajor) < 0n - ? 'purchase-credit' - : 'purchase-debit', - label: copy().shareOffset, - amountMajor: member.purchaseOffsetMajor, - amountMinor: purchaseMinor - } - ] - } - }) - - const maxTotalMinor = totals.reduce( - (max, item) => (item.totalMinor > max ? item.totalMinor : max), - 0n - ) - - return totals - .sort((left, right) => { - const leftRemaining = majorStringToMinor(left.member.remainingMajor) - const rightRemaining = majorStringToMinor(right.member.remainingMajor) - - if (rightRemaining === leftRemaining) { - return left.member.displayName.localeCompare(right.member.displayName) - } - - return rightRemaining > leftRemaining ? 1 : -1 - }) - .map((item) => ({ - ...item, - barWidthPercent: - maxTotalMinor > 0n ? (Number(item.totalMinor) / Number(maxTotalMinor)) * 100 : 0, - segments: item.segments.map((segment) => ({ - ...segment, - widthPercent: - item.totalMinor > 0n ? (Number(segment.amountMinor) / Number(item.totalMinor)) * 100 : 0 - })) - })) - }) - const purchaseInvestmentChart = createMemo(() => { - const data = dashboard() - if (!data) { - return { - totalMajor: '0.00', - slices: [] - } - } - - const membersById = new Map(data.members.map((member) => [member.memberId, member.displayName])) - const totals = new Map() - - for (const entry of purchaseLedger()) { - const key = entry.memberId ?? entry.actorDisplayName ?? entry.id - const label = - (entry.memberId ? membersById.get(entry.memberId) : null) ?? - entry.actorDisplayName ?? - copy().ledgerActorFallback - const current = totals.get(key) ?? { - label, - amountMinor: 0n - } - - totals.set(key, { - label, - amountMinor: - current.amountMinor + absoluteMinor(majorStringToMinor(entry.displayAmountMajor)) - }) - } - - const items = [...totals.entries()] - .map(([key, value], index) => ({ - key, - label: value.label, - amountMinor: value.amountMinor, - amountMajor: minorToMajorString(value.amountMinor), - color: chartPalette[index % chartPalette.length]! - })) - .filter((item) => item.amountMinor > 0n) - .sort((left, right) => (right.amountMinor > left.amountMinor ? 1 : -1)) - - const totalMinor = items.reduce((sum, item) => sum + item.amountMinor, 0n) - const circumference = 2 * Math.PI * 42 - let offset = 0 - - return { - totalMajor: minorToMajorString(totalMinor), - slices: items.map((item) => { - const ratio = totalMinor > 0n ? Number(item.amountMinor) / Number(totalMinor) : 0 - const dash = ratio * circumference - const slice = { - ...item, - percentage: Math.round(ratio * 100), - dasharray: `${dash} ${Math.max(circumference - dash, 0)}`, - dashoffset: `${-offset}` - } - offset += dash - return slice - }) - } - }) const webApp = getTelegramWebApp() function ledgerTitle(entry: MiniAppDashboard['ledger'][number]): string { @@ -1395,25 +1247,6 @@ function App() { } } - async function handleCloseCycle() { - const initData = webApp?.initData?.trim() - const currentReady = readySession() - if (!initData || currentReady?.mode !== 'live' || !currentReady.member.isAdmin) { - return - } - - setClosingCycle(true) - - try { - const state = await closeMiniAppBillingCycle(initData, cycleState()?.cycle?.period) - setCycleState(state) - setUtilityBillDrafts(cycleUtilityBillDrafts(state.utilityBills)) - setCycleRentOpen(false) - } finally { - setClosingCycle(false) - } - } - async function handleSaveCycleRent() { const initData = webApp?.initData?.trim() const currentReady = readySession() @@ -1969,12 +1802,6 @@ function App() { copy={copy()} dashboard={dashboard()} currentMemberLine={currentMemberLine()} - utilityTotalMajor={utilityTotalMajor()} - purchaseTotalMajor={purchaseTotalMajor()} - memberBalanceVisuals={memberBalanceVisuals()} - purchaseChart={purchaseInvestmentChart()} - memberBaseDueMajor={memberBaseDueMajor} - memberRemainingClass={memberRemainingClass} /> ) case 'ledger': @@ -2115,8 +1942,6 @@ function App() { adminSettings={adminSettings()} cycleState={cycleState()} pendingMembers={pendingMembers()} - activeHouseSection={activeHouseSection()} - onChangeHouseSection={setActiveHouseSection} billingForm={billingForm()} cycleForm={cycleForm()} newCategoryName={newCategoryName()} @@ -2134,7 +1959,6 @@ function App() { memberAbsencePolicyDrafts={memberAbsencePolicyDrafts()} rentWeightDrafts={rentWeightDrafts()} openingCycle={openingCycle()} - closingCycle={closingCycle()} savingCycleRent={savingCycleRent()} savingBillingSettings={savingBillingSettings()} savingUtilityBill={savingUtilityBill()} @@ -2156,7 +1980,6 @@ function App() { onCloseCycleModal={() => setCycleRentOpen(false)} onSaveCycleRent={handleSaveCycleRent} onOpenCycle={handleOpenCycle} - onCloseCycle={handleCloseCycle} onCycleRentAmountChange={(value) => setCycleForm((current) => ({ ...current, @@ -2524,20 +2347,21 @@ function App() { - -
{panel()}
+
+ }, + { key: 'balances', label: copy().balances, icon: }, + { key: 'ledger', label: copy().ledger, icon: }, + { key: 'house', label: copy().house, icon: } + ] as const + } + active={activeNav()} + onChange={setActiveNav} + /> +
= { key: T label: string + icon?: JSX.Element } type Props = { @@ -20,7 +21,8 @@ export function NavigationTabs(props: Props): JSX.Element { type="button" onClick={() => props.onChange(item.key)} > - {item.label} + {item.icon} + {item.label} ))} diff --git a/apps/miniapp/src/components/ui/icons.tsx b/apps/miniapp/src/components/ui/icons.tsx index 5081e18..736398f 100644 --- a/apps/miniapp/src/components/ui/icons.tsx +++ b/apps/miniapp/src/components/ui/icons.tsx @@ -66,6 +66,56 @@ export function GlobeIcon(props: IconProps) { ) } +export function HomeIcon(props: IconProps) { + return ( + + + + + + ) +} + +export function WalletIcon(props: IconProps) { + return ( + + + + + + + ) +} + +export function ReceiptIcon(props: IconProps) { + return ( + + + + + + + ) +} + +export function HouseIcon(props: IconProps) { + return ( + + + + + + ) +} + +export function ChevronDownIcon(props: IconProps) { + return ( + + + + ) +} + export function XIcon(props: IconProps) { return ( diff --git a/apps/miniapp/src/i18n.ts b/apps/miniapp/src/i18n.ts index 5dd0cb9..a880ce3 100644 --- a/apps/miniapp/src/i18n.ts +++ b/apps/miniapp/src/i18n.ts @@ -56,14 +56,22 @@ export const dictionary = { yourBalanceTitle: 'Your balance', yourBalanceBody: 'See rent, pure utilities, purchase balance adjustment, and what is still left to pay.', + payNowTitle: 'Pay now', + payNowBody: + 'Your current-cycle summary stays here so you can see the number that matters first.', + currentCycleLabel: 'Current cycle', cycleBillLabel: 'Cycle bill', balanceAdjustmentLabel: 'Balance adjustment', pureUtilitiesLabel: 'Pure utilities', + rentAdjustedTotalLabel: 'Rent after adjustment', utilitiesAdjustedTotalLabel: 'Utilities after adjustment', baseDue: 'Base due', finalDue: 'Final due', houseSnapshotTitle: 'House totals', houseSnapshotBody: 'Whole-house totals for the current cycle.', + balanceScreenScopeTitle: 'Balance breakdown', + balanceScreenScopeBody: + 'This screen only explains your current cycle balance. Older activity stays in the ledger.', householdBalancesTitle: 'Household balances', householdBalancesBody: 'Everyone’s current split for this cycle.', financeVisualsTitle: 'Visual balance split', @@ -309,14 +317,22 @@ export const dictionary = { yourBalanceTitle: 'Твой баланс', yourBalanceBody: 'Здесь отдельно видно аренду, чистую коммуналку, поправку по покупкам и то, что осталось оплатить.', + payNowTitle: 'К оплате сейчас', + payNowBody: + 'Здесь остаётся только короткая сводка по текущему циклу, чтобы сразу видеть нужную сумму.', + currentCycleLabel: 'Текущий цикл', cycleBillLabel: 'Счёт за цикл', balanceAdjustmentLabel: 'Поправка по балансу', pureUtilitiesLabel: 'Чистая коммуналка', + rentAdjustedTotalLabel: 'Аренда после зачёта', utilitiesAdjustedTotalLabel: 'Коммуналка после зачёта', baseDue: 'База к оплате', finalDue: 'Итог к оплате', houseSnapshotTitle: 'Сводка по дому', houseSnapshotBody: 'Общие суммы по дому за текущий цикл.', + balanceScreenScopeTitle: 'Разбор баланса', + balanceScreenScopeBody: + 'На этом экране только разбор твоего текущего баланса. Более старые записи остаются в леджере.', householdBalancesTitle: 'Баланс household', householdBalancesBody: 'Текущий расклад по всем участникам за этот цикл.', financeVisualsTitle: 'Визуальный разбор баланса', diff --git a/apps/miniapp/src/index.css b/apps/miniapp/src/index.css index b53bf5f..847cc61 100644 --- a/apps/miniapp/src/index.css +++ b/apps/miniapp/src/index.css @@ -44,7 +44,7 @@ button { position: relative; min-height: 100vh; overflow: hidden; - padding: 24px 18px 32px; + padding: 24px 18px 108px; } .shell__backdrop { @@ -315,18 +315,37 @@ button { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 6px; - margin-top: 12px; padding: 4px; border: 1px solid rgb(255 255 255 / 0.08); border-radius: 18px; - background: rgb(255 255 255 / 0.03); + background: rgb(18 26 36 / 0.9); + box-shadow: 0 18px 36px rgb(0 0 0 / 0.26); } .nav-grid button { + display: grid; + justify-items: center; + gap: 4px; border: none; border-radius: 14px; - min-height: 38px; - padding: 9px 10px; + min-height: 52px; + padding: 8px 6px; + font-size: 0.72rem; + font-weight: 700; + letter-spacing: 0.02em; + text-align: center; +} + +.nav-grid button span { + overflow-wrap: anywhere; +} + +.app-bottom-nav { + position: fixed; + right: 18px; + bottom: 20px; + left: 18px; + z-index: 3; } .content-grid { @@ -432,6 +451,14 @@ button { grid-template-columns: minmax(0, 1fr); } +.home-pay-card, +.home-pay-card__header, +.home-pay-card__copy, +.home-pay-card__chips { + display: grid; + gap: 12px; +} + .stat-card { display: grid; gap: 8px; @@ -750,6 +777,52 @@ button { gap: 12px; } +.admin-disclosure { + border: 1px solid rgb(255 255 255 / 0.08); + border-radius: 20px; + background: rgb(255 255 255 / 0.03); + overflow: hidden; +} + +.admin-disclosure[open] { + background: + linear-gradient(180deg, rgb(255 255 255 / 0.05), rgb(255 255 255 / 0.02)), + rgb(255 255 255 / 0.03); +} + +.admin-disclosure__summary { + display: grid; + grid-template-columns: minmax(0, 1fr) auto; + align-items: center; + gap: 12px; + padding: 16px; + cursor: pointer; + list-style: none; +} + +.admin-disclosure__summary::-webkit-details-marker { + display: none; +} + +.admin-disclosure__copy { + display: grid; + gap: 6px; +} + +.admin-disclosure__icon { + transition: transform 140ms ease; +} + +.admin-disclosure[open] .admin-disclosure__icon { + transform: rotate(180deg); +} + +.admin-disclosure__content { + display: grid; + gap: 12px; + padding: 0 16px 16px; +} + .admin-sublist { margin-top: 12px; } @@ -1191,7 +1264,7 @@ button { } .nav-grid { - grid-template-columns: repeat(2, minmax(0, 1fr)); + grid-template-columns: repeat(4, minmax(0, 1fr)); } .balance-breakdown { diff --git a/apps/miniapp/src/screens/balances-screen.tsx b/apps/miniapp/src/screens/balances-screen.tsx index c78d93a..cc985eb 100644 --- a/apps/miniapp/src/screens/balances-screen.tsx +++ b/apps/miniapp/src/screens/balances-screen.tsx @@ -1,7 +1,5 @@ -import { For, Show } from 'solid-js' +import { Show } from 'solid-js' -import { FinanceSummaryCards } from '../components/finance/finance-summary-cards' -import { FinanceVisuals } from '../components/finance/finance-visuals' import { MemberBalanceCard } from '../components/finance/member-balance-card' import type { MiniAppDashboard } from '../miniapp-api' @@ -9,34 +7,6 @@ type Props = { copy: Record dashboard: MiniAppDashboard | null currentMemberLine: MiniAppDashboard['members'][number] | null - utilityTotalMajor: string - purchaseTotalMajor: string - memberBalanceVisuals: { - member: MiniAppDashboard['members'][number] - totalMinor: bigint - barWidthPercent: number - segments: { - key: string - label: string - amountMajor: string - amountMinor: bigint - widthPercent: number - }[] - }[] - purchaseChart: { - totalMajor: string - slices: { - key: string - label: string - amountMajor: string - color: string - percentage: number - dasharray: string - dashoffset: string - }[] - } - memberBaseDueMajor: (member: MiniAppDashboard['members'][number]) => string - memberRemainingClass: (member: MiniAppDashboard['members'][number]) => string } export function BalancesScreen(props: Props) { @@ -61,82 +31,13 @@ export function BalancesScreen(props: Props) { /> )} -
+
-
{props.copy.houseSnapshotTitle ?? ''} + {props.copy.balanceScreenScopeTitle ?? ''} {dashboard().period} -

{props.copy.houseSnapshotBody ?? ''}

-
- -
+

{props.copy.balanceScreenScopeBody ?? ''}

- -
-
- {props.copy.householdBalancesTitle ?? ''} - {String(dashboard().members.length)} -
-

{props.copy.householdBalancesBody ?? ''}

-
- - {(member) => ( -
-
- {member.displayName} - - {member.remainingMajor} {dashboard().currency} - -
-

- {props.copy.baseDue ?? ''}: {props.memberBaseDueMajor(member)}{' '} - {dashboard().currency} -

-

- {props.copy.shareRent ?? ''}: {member.rentShareMajor} {dashboard().currency} -

-

- {props.copy.shareUtilities ?? ''}: {member.utilityShareMajor}{' '} - {dashboard().currency} -

-

- {props.copy.shareOffset ?? ''}: {member.purchaseOffsetMajor}{' '} - {dashboard().currency} -

-

- {props.copy.paidLabel ?? ''}: {member.paidMajor} {dashboard().currency} -

-

- {props.copy.remainingLabel ?? ''}: {member.remainingMajor} {dashboard().currency} -

-
- )} -
)} diff --git a/apps/miniapp/src/screens/home-screen.tsx b/apps/miniapp/src/screens/home-screen.tsx index 0406d90..07ea978 100644 --- a/apps/miniapp/src/screens/home-screen.tsx +++ b/apps/miniapp/src/screens/home-screen.tsx @@ -1,7 +1,7 @@ import { Show } from 'solid-js' import { FinanceSummaryCards } from '../components/finance/finance-summary-cards' -import { MemberBalanceCard } from '../components/finance/member-balance-card' +import { sumMajorStrings } from '../lib/money' import type { MiniAppDashboard } from '../miniapp-api' type Props = { @@ -13,6 +13,28 @@ type Props = { } export function HomeScreen(props: Props) { + const adjustedRentMajor = () => { + if (!props.currentMemberLine) { + return null + } + + return sumMajorStrings( + props.currentMemberLine.rentShareMajor, + props.currentMemberLine.purchaseOffsetMajor + ) + } + + const adjustedUtilitiesMajor = () => { + if (!props.currentMemberLine) { + return null + } + + return sumMajorStrings( + props.currentMemberLine.utilityShareMajor, + props.currentMemberLine.purchaseOffsetMajor + ) + } + return ( {(member) => ( - +
+
+
+ {props.copy.payNowTitle ?? props.copy.yourBalanceTitle ?? ''} +

{props.copy.payNowBody ?? ''}

+
+
+ {props.copy.remainingLabel ?? ''} + + {member().remainingMajor} {dashboard().currency} + + + {props.copy.totalDue ?? ''}: {member().netDueMajor} {dashboard().currency} + +
+
+ +
+
+ {props.copy.paidLabel ?? ''} + + {member().paidMajor} {dashboard().currency} + +
+
+ {props.copy.currentCycleLabel ?? ''} + {dashboard().period} +
+
+ +
+ + {dashboard().paymentBalanceAdjustmentPolicy === 'rent' + ? props.copy.rentAdjustedTotalLabel + : props.copy.shareRent} + :{' '} + {dashboard().paymentBalanceAdjustmentPolicy === 'rent' + ? adjustedRentMajor() + : member().rentShareMajor}{' '} + {dashboard().currency} + + + {dashboard().paymentBalanceAdjustmentPolicy === 'utilities' + ? props.copy.utilitiesAdjustedTotalLabel + : props.copy.shareUtilities} + :{' '} + {dashboard().paymentBalanceAdjustmentPolicy === 'utilities' + ? adjustedUtilitiesMajor() + : member().utilityShareMajor}{' '} + {dashboard().currency} + + + {props.copy.balanceAdjustmentLabel ?? props.copy.shareOffset}:{' '} + {member().purchaseOffsetMajor} {dashboard().currency} + +
+
)}
diff --git a/apps/miniapp/src/screens/house-screen.tsx b/apps/miniapp/src/screens/house-screen.tsx index 82fade9..2509e7c 100644 --- a/apps/miniapp/src/screens/house-screen.tsx +++ b/apps/miniapp/src/screens/house-screen.tsx @@ -1,8 +1,9 @@ -import { For, Show } from 'solid-js' +import { For, Show, type JSX } from 'solid-js' import { Button, CalendarIcon, + ChevronDownIcon, Field, IconButton, Modal, @@ -10,7 +11,6 @@ import { PlusIcon, SettingsIcon } from '../components/ui' -import { NavigationTabs } from '../components/layout/navigation-tabs' import type { MiniAppAdminCycleState, MiniAppAdminSettingsPayload, @@ -19,8 +19,6 @@ import type { MiniAppPendingMember } from '../miniapp-api' -type HouseSectionKey = 'billing' | 'utilities' | 'members' | 'topics' - type UtilityBillDraft = { billName: string amountMajor: string @@ -58,8 +56,6 @@ type Props = { adminSettings: MiniAppAdminSettingsPayload | null cycleState: MiniAppAdminCycleState | null pendingMembers: readonly MiniAppPendingMember[] - activeHouseSection: HouseSectionKey - onChangeHouseSection: (section: HouseSectionKey) => void billingForm: BillingForm cycleForm: CycleForm newCategoryName: string @@ -81,7 +77,6 @@ type Props = { memberAbsencePolicyDrafts: Record rentWeightDrafts: Record openingCycle: boolean - closingCycle: boolean savingCycleRent: boolean savingBillingSettings: boolean savingUtilityBill: boolean @@ -107,7 +102,6 @@ type Props = { onCloseCycleModal: () => void onSaveCycleRent: () => Promise onOpenCycle: () => Promise - onCloseCycle: () => Promise onCycleRentAmountChange: (value: string) => void onCycleRentCurrencyChange: (value: 'USD' | 'GEL') => void onCyclePeriodChange: (value: string) => void @@ -168,6 +162,26 @@ type Props = { onPromoteMember: (memberId: string) => Promise } +function HouseSection(props: { + title: string + body?: string | undefined + defaultOpen?: boolean | undefined + children: JSX.Element +}) { + return ( +
+ +
+ {props.title} + {(body) =>

{body()}

}
+
+ +
+
{props.children}
+
+ ) +} + export function HouseScreen(props: Props) { function parseBillingDayInput(value: string): number | null { const trimmed = value.trim() @@ -201,20 +215,11 @@ export function HouseScreen(props: Props) { } >
- - - +
@@ -250,15 +255,6 @@ export function HouseScreen(props: Props) { ? (props.copy.manageCycleAction ?? '') : (props.copy.openCycleAction ?? '')} - - -
@@ -541,9 +537,12 @@ export function HouseScreen(props: Props) {
- + - +
@@ -874,9 +873,9 @@ export function HouseScreen(props: Props) { )}
-
+ - +
@@ -1126,9 +1125,12 @@ export function HouseScreen(props: Props) { })()}
-
+ - +
@@ -1162,7 +1164,7 @@ export function HouseScreen(props: Props) {
-
+ )