mirror of
https://github.com/whekin/household-bot.git
synced 2026-03-31 08:44:02 +00:00
Mini App Home Screen: - Add 'Record Payment' button to utilities and rent period cards - Pre-fill payment amount with member's share (rentShare/utilityShare) - Modal dialog with amount input and currency display - Toast notifications for copy and payment success/failure feedback Copy Button Improvements: - Increase spacing between icon and text (4px → 8px) - Add hover background and padding for better touch target - Green background highlight when copied (in addition to icon color change) - Toast notification appears when copying any value Backend: - Add /api/miniapp/payments/add endpoint for quick payments - Payment notifications sent to 'reminders' topic in Telegram - Include member name, payment type, amount, and period in notification Files: - New: apps/miniapp/src/components/ui/toast.tsx - Modified: apps/miniapp/src/routes/home.tsx, apps/miniapp/src/index.css, apps/miniapp/src/theme.css, apps/miniapp/src/i18n.ts, apps/bot/src/miniapp-billing.ts, apps/bot/src/server.ts Quality Gates: ✅ format, lint, typecheck, build, test Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
51 lines
1.1 KiB
TypeScript
51 lines
1.1 KiB
TypeScript
import { Show, createEffect, onCleanup } from 'solid-js'
|
|
|
|
import { cn } from '../../lib/cn'
|
|
|
|
export interface ToastOptions {
|
|
message: string
|
|
type?: 'success' | 'info' | 'error'
|
|
duration?: number
|
|
}
|
|
|
|
export interface ToastState {
|
|
visible: boolean
|
|
message: string
|
|
type: 'success' | 'info' | 'error'
|
|
}
|
|
|
|
const toastVariants = {
|
|
success: 'toast--success',
|
|
info: 'toast--info',
|
|
error: 'toast--error'
|
|
}
|
|
|
|
export function Toast(props: { state: ToastState; onClose: () => void }) {
|
|
let timeoutId: ReturnType<typeof setTimeout> | undefined
|
|
|
|
createEffect(() => {
|
|
if (props.state.visible) {
|
|
timeoutId = setTimeout(
|
|
() => {
|
|
props.onClose()
|
|
},
|
|
props.state.type === 'error' ? 4000 : 2000
|
|
)
|
|
}
|
|
})
|
|
|
|
onCleanup(() => {
|
|
if (timeoutId) {
|
|
clearTimeout(timeoutId)
|
|
}
|
|
})
|
|
|
|
return (
|
|
<Show when={props.state.visible}>
|
|
<div role="status" aria-live="polite" class={cn('toast', toastVariants[props.state.type])}>
|
|
<span class="toast__message">{props.state.message}</span>
|
|
</div>
|
|
</Show>
|
|
)
|
|
}
|