feat: deposit module — QR flow, PayDepositPage, BookingDetailPanel widget

- Backend: GET /api/pay/:slug (public) — returns active hold confirmation URL
- PayDepositPage: public page /:slug/pay for guests (no login required)
- DepositSettingsPage: QR code section with print button
- BookingDetailPanel: DepositWidget in payment tab
  - Наличными / ЮКасса (QR) buttons
  - hold_created: copy link + refresh
  - hold_confirmed: release form (вернуть / списать)
  - Final status badges

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-06 11:22:55 +03:00
parent b91859218a
commit 754f03b7fa
7 changed files with 470 additions and 2 deletions

View File

@@ -1,5 +1,6 @@
import { useState, useEffect } from 'react'
import { Save, Eye, EyeOff, Loader2, ShieldCheck } from 'lucide-react'
import { Save, Eye, EyeOff, Loader2, ShieldCheck, Printer } from 'lucide-react'
import { QRCodeSVG } from 'qrcode.react'
import { api, type DepositSettings } from '../lib/api'
import { useAuth } from '../contexts/AuthContext'
import { cn } from '../lib/utils'
@@ -172,6 +173,52 @@ export function DepositSettingsPage() {
</div>
</div>
</div>
{/* QR code section — only when shopId is configured */}
{shopId && (
<div className="border-t border-slate-100 dark:border-slate-700 pt-4">
<p className="font-medium text-slate-800 dark:text-slate-200 text-sm mb-1">QR-код для гостей</p>
<p className="text-xs text-slate-500 dark:text-slate-400 mb-4">
Распечатайте и разместите на стойке ресепшена. Гость сканирует код и оплачивает депозит картой.
</p>
<div className="print-qr-section flex flex-col items-center gap-4">
<div className="p-4 bg-white rounded-xl border border-slate-200 dark:border-slate-600 inline-block">
<QRCodeSVG
value={`https://app.hotelsync.ru/${slug}/pay`}
size={160}
level="M"
/>
</div>
<p className="text-xs text-slate-400 font-mono break-all text-center">
https://app.hotelsync.ru/{slug}/pay
</p>
<button
type="button"
onClick={() => window.print()}
className="btn-secondary flex items-center gap-2"
>
<Printer size={15} />
Распечатать QR-код
</button>
</div>
<style>{`
@media print {
body > * { display: none !important; }
.print-qr-section,
.print-qr-section * { display: flex !important; }
.print-qr-section {
position: fixed;
inset: 0;
align-items: center;
justify-content: center;
flex-direction: column;
gap: 1rem;
}
button { display: none !important; }
}
`}</style>
</div>
)}
</>
)}
</div>