fix(pos-selfpay): hide payment methods until email step completes

This commit is contained in:
Deploy
2026-08-26 22:03:23 +02:00
parent 665fc2a60d
commit eb655e109f
3 changed files with 19 additions and 7 deletions

View File

@@ -1,7 +1,7 @@
/// <reference types="next" /> /// <reference types="next" />
/// <reference types="next/image-types/global" /> /// <reference types="next/image-types/global" />
import "./.next/types/routes.d.ts"; import "./.next/dev/types/routes.d.ts";
import "./.next/types/root-params.d.ts"; import "./.next/dev/types/root-params.d.ts";
// NOTE: This file should not be edited // NOTE: This file should not be edited
// see https://nextjs.org/docs/app/api-reference/config/typescript for more information. // see https://nextjs.org/docs/app/api-reference/config/typescript for more information.

View File

@@ -143,6 +143,7 @@ export default function RegisterPage() {
// POS-SELFPAY-FLOW: optional email for receipt before payment // POS-SELFPAY-FLOW: optional email for receipt before payment
const [showSelfpayEmail, setShowSelfpayEmail] = useState(false); const [showSelfpayEmail, setShowSelfpayEmail] = useState(false);
const [selfpayEmail, setSelfpayEmail] = useState(''); const [selfpayEmail, setSelfpayEmail] = useState('');
const [selfpayPaymentReady, setSelfpayPaymentReady] = useState(false);
let toastTimer: ReturnType<typeof setTimeout> | undefined; let toastTimer: ReturnType<typeof setTimeout> | undefined;
const showAddedToast = (name: string) => { const showAddedToast = (name: string) => {
clearTimeout(toastTimer); clearTimeout(toastTimer);
@@ -509,6 +510,12 @@ export default function RegisterPage() {
}); });
setReceipt(result.receipt); setReceipt(result.receipt);
setRestPaymentFor(null); setRestPaymentFor(null);
// POS-SELFPAY-FLOW: send receipt by email if provided
if (isSelfpayMode && selfpayEmail.trim()) {
void posApi.emailReceipt(result.receipt.orderId, selfpayEmail.trim()).catch(() => {
// Non-blocking: email failure shouldn't interrupt the sale
});
}
void loadPendingSales(); void loadPendingSales();
} catch (err) { } catch (err) {
setError(err instanceof Error ? err.message : 'No se pudo confirmar la venta'); setError(err instanceof Error ? err.message : 'No se pudo confirmar la venta');
@@ -783,6 +790,8 @@ export default function RegisterPage() {
setError(''); setError('');
setSearch(''); setSearch('');
setShowClearConfirm(false); setShowClearConfirm(false);
setSelfpayPaymentReady(false);
setSelfpayEmail('');
}; };
const searchCustomers = async (query: string) => { const searchCustomers = async (query: string) => {
@@ -1649,7 +1658,7 @@ export default function RegisterPage() {
</p> </p>
)} )}
{/* POS-SELFPAY-FLOW: in selfpay mode, hide payment methods until email is captured */} {/* POS-SELFPAY-FLOW: in selfpay mode, hide payment methods until email is captured */}
{(!isSelfpayMode || selfpayEmail !== undefined) && ( {(!isSelfpayMode || selfpayPaymentReady) && (
<div className="mt-3 grid grid-cols-2 gap-2"> <div className="mt-3 grid grid-cols-2 gap-2">
{config.paymentMethods.map((method) => ( {config.paymentMethods.map((method) => (
<button <button
@@ -1683,8 +1692,9 @@ export default function RegisterPage() {
: void confirmSale() : void confirmSale()
} }
disabled={ disabled={
!isSelfpayMode && processing ||
(processing || cart.length === 0 || payments.length === 0 || paidCents <= 0 || paidCents > totals.total) cart.length === 0 ||
(!isSelfpayMode && (payments.length === 0 || paidCents <= 0 || paidCents > totals.total))
} }
className={`min-h-16 rounded-xl bg-[#1B4332] text-lg font-bold text-white disabled:opacity-40 ${ className={`min-h-16 rounded-xl bg-[#1B4332] text-lg font-bold text-white disabled:opacity-40 ${
isSelfpayMode ? 'col-span-2' : '' isSelfpayMode ? 'col-span-2' : ''
@@ -1758,6 +1768,7 @@ export default function RegisterPage() {
onSubmit={(e) => { onSubmit={(e) => {
e.preventDefault(); e.preventDefault();
setShowSelfpayEmail(false); setShowSelfpayEmail(false);
setSelfpayPaymentReady(true);
}} }}
className="space-y-4" className="space-y-4"
> >
@@ -1785,6 +1796,7 @@ export default function RegisterPage() {
onClick={() => { onClick={() => {
setSelfpayEmail(''); setSelfpayEmail('');
setShowSelfpayEmail(false); setShowSelfpayEmail(false);
setSelfpayPaymentReady(true);
}} }}
className="w-full rounded-xl border border-gray-300 py-2 text-sm font-medium text-gray-500" className="w-full rounded-xl border border-gray-300 py-2 text-sm font-medium text-gray-500"
> >

View File

@@ -1,7 +1,7 @@
/// <reference types="next" /> /// <reference types="next" />
/// <reference types="next/image-types/global" /> /// <reference types="next/image-types/global" />
import "./.next/types/routes.d.ts"; import "./.next/dev/types/routes.d.ts";
import "./.next/types/root-params.d.ts"; import "./.next/dev/types/root-params.d.ts";
// NOTE: This file should not be edited // NOTE: This file should not be edited
// see https://nextjs.org/docs/app/api-reference/config/typescript for more information. // see https://nextjs.org/docs/app/api-reference/config/typescript for more information.