- Introduce a comprehensive roadmap for integrating nostr-market-app purchasing functionality into the web-app. - Outline key components of the shopping cart system, checkout process, and order management. - Detail phased implementation strategy, including enhanced user experience and advanced features. - Include security, performance, and testing considerations to ensure robust integration. feat: Enhance market store with new order and cart management features - Introduce new interfaces for Order, OrderItem, ContactInfo, and ShippingZone to support enhanced order management. - Update Stall and Product interfaces to include currency and shipping details. - Implement a comprehensive shopping cart system with stall-specific carts, including methods for adding, removing, and updating items. - Add payment-related interfaces and methods for managing payment requests and statuses. - Enhance filter options to include in-stock status and payment methods, improving product filtering capabilities. - Refactor computed properties and methods for better cart management and checkout processes. feat: Implement shopping cart functionality with new components and routing - Add ShoppingCart, CartItem, and CartSummary components to manage cart items and display summaries. - Introduce Cart.vue page to serve as the main shopping cart interface, integrating cart and summary components. - Update Navbar.vue to include a cart icon with item count, enhancing user navigation. - Implement cart management features in the market store, including item addition, quantity updates, and removal. - Establish routing for the cart page, ensuring seamless navigation for users. - Enhance ProductCard.vue to support adding items to the cart directly from the product listing. feat: Update cart and checkout functionality with improved navigation and button labels - Change "Proceed to Checkout" button text to dynamic "Place Order" based on context in CartSummary.vue. - Update "Continue Shopping" button to "Back to Cart" in CartSummary.vue for clearer navigation. - Modify routing for checkout to include stall ID in ShoppingCart.vue, enhancing checkout process. - Simplify Cart.vue by removing CartSummary component and focusing on ShoppingCart display. - Add new route for checkout with stall ID in router configuration for better handling of checkout flows. feat: Enhance cart and checkout components with improved shipping address handling - Update CartSummary.vue to use readonly types for cart items and shipping zones, ensuring immutability. - Modify Checkout.vue to conditionally display the shipping address field based on the selected shipping zone's requirements for physical shipping. - Add a digital delivery note for products that do not require a shipping address. - Introduce a computed property to determine if a shipping address is required, improving validation logic during checkout. - Update market store to include a new property for shipping zones indicating if physical shipping is required. feat: Implement order placement functionality in checkout process - Add a "Place Order" button in Checkout.vue that triggers the order placement process. - Introduce loading state during order placement to enhance user experience. - Implement createAndPlaceOrder method in market store to handle order creation and status updates. - Include error handling for order placement failures, providing user feedback on errors. - Update checkout logic to validate shipping zone and contact information before proceeding. feat: Add Order History page and update Navbar for order tracking - Introduce a new OrderHistory.vue page to display users' past orders with filtering and sorting options. - Update Navbar.vue to include an "Order History" option with a badge showing the count of orders. - Implement computed properties for order count and enhance user navigation experience. feat: Integrate Nostr functionality for order management and user notifications - Add NostrExtensionGuide component to inform users about the required Nostr extension for order transmission. - Implement useNostrOrders composable to manage Nostr connection, event creation, and order sending. - Update Checkout.vue to display Nostr connection status and provide feedback on order transmission. - Enhance OrderHistory.vue to show Nostr transmission status and details for each order. - Modify market store to handle Nostr event details and errors during order placement, ensuring local fallback. - Introduce types for Nostr events to improve type safety and integration with the existing order management system. refactor: Update Nostr relay configuration to use environment variable - Change DEFAULT_RELAYS to dynamically retrieve relay URLs from the VITE_MARKET_RELAYS environment variable. - Add error handling to ensure relays are configured before establishing a connection. - Modify createBlankEvent function to return a more precise type. - Update event signing process to ensure the event ID is generated correctly before signing. refactor: useAuth switch Enhance Nostr order management with authentication checks - Integrate user authentication checks to ensure Nostr features are only accessible to authenticated users. - Replace direct window.nostr calls with auth store methods for retrieving public and private keys. - Implement a helper function for signing events and mock encryption for order content. - Remove obsolete Nostr type definitions to streamline the codebase. feat: Enhance Checkout.vue with Nostr processing feedback and cleanup - Update the checkout button to disable based on order placement state. - Simplify order placement feedback by removing unnecessary Nostr processing checks. - Introduce a new visual indicator for Nostr order processing status. - Refactor computed properties for better clarity and efficiency in shipping zone handling. refactor: Streamline Nostr order handling and integrate buyer public key retrieval - Remove redundant Nostr relay tag from order event creation in useNostrOrders. - Update Checkout.vue to retrieve the buyer's public key from the auth store, enhancing order placement logic. - Modify createAndPlaceOrder method in market store to accept an optional Nostr orders instance for improved flexibility in order processing. refactor: Remove Nostr-related components and streamline order processing - Delete NostrExtensionGuide.vue and associated type definitions to simplify the codebase. - Remove unused useNostr.ts file and related logic from useNostrOrders.ts. - Update order handling in market store to directly integrate Nostr publishing without relying on external components. - Enhance Checkout.vue and Cart.vue to reflect changes in Nostr integration and provide clearer order status feedback. feat: Enhance Nostr chat functionality with malformed message handling - Introduce tracking for malformed message IDs to prevent repeated processing attempts. - Implement functions to mark messages as malformed, clean up old entries, and retrieve statistics on malformed messages. - Add periodic cleanup of malformed messages to manage memory usage. - Enhance message processing logic to skip previously identified malformed messages and provide detailed error handling for decryption failures. - Update the return object to include new functions for managing malformed messages. ZZ feat: Implement Lightning invoice management in market store - Add functionality to create and manage Lightning invoices for orders. - Introduce payment monitoring and status updates for invoices. - Implement payment confirmation messaging via Nostr upon successful payment. - Enhance order interface to include new fields for Lightning invoice details and payment status. ZZ feat: Enhance OrderHistory.vue with payment status indicators and invoice management - Add visual indicators for payment status, including 'Paid' and 'Payment Pending' badges. - Implement expandable payment display for orders with Lightning invoices. - Introduce functionality to toggle payment display and generate Lightning invoices. - Update order status messaging to reflect payment requirements and invoice generation status. ZZ feat: Enhance OrderHistory.vue with payment status indicators and invoice management - Add visual indicators for payment status, including 'Paid' and 'Payment Pending' badges. - Implement expandable payment display for orders with Lightning invoices. - Introduce functionality to toggle payment display and generate Lightning invoices. - Update order status messaging to reflect payment requirements and invoice generation status. feat: Implement order event handling in useOrderEvents composable - Introduce useOrderEvents composable to manage subscription and processing of order-related events. - Define order event types and interfaces for better type safety and clarity. - Implement methods to handle payment requests, order status updates, and invoice generation. - Enhance OrderHistory.vue to display order event subscription status and last update timestamp. - Update market store to include order update functionality for better integration with order events. FIX: Build errors refactor: Update component styles and improve UI consistency across market pages - Replace various color classes with updated design tokens for better consistency. - Change background colors of components to align with the new design system. - Update text colors to enhance readability and maintain a cohesive look. - Refactor class names in CartItem.vue, CartSummary.vue, DashboardOverview.vue, and other components to use the new color scheme. - Ensure all components reflect the updated design guidelines for a unified user experience. refactor: Remove Order History references from Navbar component - Eliminate order count computation and related UI elements from the Navbar. - Streamline the Navbar by removing the Order History button and badge. - Maintain existing functionality for other menu items, ensuring a cleaner user interface. feat: Implement QR code generation and download functionality in PaymentDisplay component - Add QR code generation for payment requests using the qrcode library. - Enhance UI to display loading states and error messages during QR code generation. - Introduce a download button for users to save the generated QR code. - Implement logic to regenerate QR code when the invoice changes. refactor: Replace useRelayHub with relayHubComposable across components - Update imports in multiple components and composables to use the new relayHubComposable for better consistency and maintainability. - Enhance OrderHistory.vue with debug information for development, displaying key states related to orders, authentication, and relay hub connectivity. - Remove unnecessary reconnect button from RelayHubStatus.vue to streamline user interactions. - Improve logging in useOrderEvents for better debugging and monitoring of order event subscriptions. refactor: Update OrderHistory.vue styles for improved UI consistency - Replace color classes with updated design tokens for better alignment with the new design system. - Enhance readability by adjusting text colors and background styles for payment status indicators. - Ensure a cohesive look across the component by standardizing class names and styles. refactor: Update component styles for improved UI consistency across checkout pages - Replace color classes with updated design tokens for better alignment with the new design system. - Enhance readability by adjusting text colors and background styles in CartSummary.vue, PaymentDisplay.vue, Checkout.vue, and OrderHistory.vue. - Standardize class names and styles to ensure a cohesive look across all components. feat: Implement invoice generation and Nostr integration in MerchantStore component - Add functionality to generate Lightning invoices for orders and send them to customers via Nostr. - Introduce a new sendInvoiceToCustomer method to update order details and publish invoice information. - Enhance order event handling in useOrderEvents to update existing orders with new invoice data. - Improve error handling and logging for invoice generation and sending processes. feat: Enhance MerchantStore and PaymentDisplay components for improved invoice handling - Add wallet indicator in MerchantStore to display the selected wallet name during pending orders. - Implement temporary fixes for missing buyer and seller public keys when generating invoices. - Update invoice generation logic to utilize the first available wallet and improve error handling. - Modify PaymentDisplay to use the new bolt11 field for payment requests and enhance date formatting. - Refactor order event handling to ensure accurate updates and invoice management across components. feat: Enhance order event processing in useOrderEvents composable - Refactor processOrderEvent to handle incoming Nostr market order events with improved validation and logging. - Implement logic to update existing orders or create new ones based on event data, ensuring accurate order management. - Add detailed console logging for better debugging and tracking of order events and their statuses. - Ensure compatibility with market order structure and invoice details for seamless integration with payment processing. feat: Enhance order management with localStorage persistence - Update createOrder method to optionally accept an order ID from events, improving order tracking. - Convert items from readonly to mutable for better manipulation. - Implement localStorage persistence for orders, ensuring data is saved and loaded across sessions. - Add methods to save and load orders from localStorage, enhancing user experience and data reliability. feat: Update invoice creation to support additional metadata and nostrmarket compatibility - Modify createInvoice method to accept an optional extra parameter for additional metadata. - Change invoice tag to 'nostrmarket' for improved compatibility with Nostr market. - Include merchant and buyer public keys in the invoice data for better integration. - Update invoice creation in market store to utilize new parameters for enhanced functionality. feat: Enhance order and invoice handling for Nostr market compatibility - Add originalOrderId to order events for tracking Nostr order IDs. - Update invoice creation to utilize original Nostr order ID when generating invoices. - Improve logging for invoice requests to LNBits, providing better visibility into the data being sent. - Ensure compatibility with nostrmarket by adjusting order ID handling in the market store. fix: Refine invoice creation logic for Nostr market compatibility - Adjust order ID handling in invoice creation to prioritize originalOrderId for better compatibility with nostrmarket. - Enhance logging to provide clearer insights into the order ID being used during invoice generation. feat: Integrate nostrmarket service for order publishing and merchant catalog management - Implement functionality to publish orders via the nostrmarket protocol, replacing the previous Nostr integration. - Add methods to publish merchant catalogs, including stalls and products, to nostrmarket with event ID tracking. - Enhance order interface to include nostrEventId for better integration with nostrmarket. - Improve error handling and logging for nostrmarket publishing processes. refactor: Simplify order creation logic in useOrderEvents and update contact structure in nostrmarketService - Streamline order creation by using event.id and defaulting to 'unknown' for stallId. - Update contact structure to include address and message, removing optional email and phone fields for clarity. - Ensure compatibility with new order data structure for improved integration with nostrmarket. feat: Add bech32 to hex conversion utility and integrate into nostrmarketService - Implement a new utility function to convert bech32 keys to hex format, enhancing key handling. - Update nostrmarketService to utilize the new conversion function for user public and private keys. - Modify contact structure to include additional fields for improved order information management. feat: Add nostrclient configuration to AppConfig for enhanced Nostr integration - Introduce a new nostrclient property in AppConfig to manage Nostr client settings. - Include url and enabled fields to configure the Nostr client connection dynamically. - Ensure compatibility with environment variables for flexible deployment configurations. feat: Introduce comprehensive order management and fulfillment documentation - Add ORDER_MANAGEMENT_FULFILLMENT.md to detail the complete order lifecycle, including order states, data models, and merchant/customer interfaces. - Implement test scripts for verifying order and payment request formats in test-nostrmarket-format.js. - Create PaymentRequestDialog.vue for handling payment requests with dynamic options and QR code generation. - Enhance useOrderEvents.ts to process nostrmarket protocol messages for order management. - Update nostrmarketService.ts to handle payment requests and order status updates, ensuring seamless integration with the marketplace. - Integrate payment request dialog in Market.vue and manage its state in the market store. refactor: Remove obsolete test script for nostrmarket order format - Delete test-nostrmarket-format.js as it is no longer needed for verifying order and payment request formats. - Update PaymentRequestDialog.vue to enhance UI components and integrate QR code generation for payment requests. - Refactor payment handling and notification logic to utilize toast notifications instead of Quasar's notify system. feat: Enhance OrderHistory component with payment request handling and QR code generation - Add UI elements to display payment request status and options in OrderHistory.vue. - Implement functions to copy payment requests, open Lightning wallets, and download QR codes. - Update nostrmarketService to generate QR codes for payment requests and manage order statuses effectively. - Remove obsolete PaymentRequestDialog integration from Market.vue for a cleaner UI. feat: Add debug information and toast notifications in OrderHistory component - Introduce debug info display for payment requests and hashes in OrderHistory.vue. - Implement toast notifications for actions like copying payment requests, opening wallets, and downloading QR codes. - Enhance error handling with user feedback for various order-related actions. - Remove obsolete payment request dialog methods from market store for cleaner code. feat: Revamp CartItem and ShoppingCart components for improved layout and functionality - Enhance CartItem.vue with responsive design for desktop and mobile views, including better organization of product details, price, quantity controls, and remove button. - Update ShoppingCart.vue to separate desktop and mobile layouts, improving the user experience with clearer action buttons and cart summary display. - Implement consistent styling and layout adjustments for better visual coherence across different screen sizes.
344 lines
11 KiB
Vue
344 lines
11 KiB
Vue
<template>
|
||
<div class="bg-white border rounded-lg p-6">
|
||
<div class="flex items-center justify-between mb-4">
|
||
<h3 class="text-lg font-semibold text-gray-900">Payment</h3>
|
||
<Badge :variant="getPaymentStatusVariant(paymentStatus)">
|
||
{{ formatPaymentStatus(paymentStatus) }}
|
||
</Badge>
|
||
</div>
|
||
|
||
<!-- Invoice Information -->
|
||
<div v-if="invoice" class="space-y-4">
|
||
<!-- Amount and Status -->
|
||
<div class="flex items-center justify-between p-4 bg-gray-50 rounded-lg">
|
||
<div>
|
||
<p class="text-sm text-gray-600">Amount</p>
|
||
<p class="text-2xl font-bold text-gray-900">
|
||
{{ invoice.amount }} {{ currency }}
|
||
</p>
|
||
</div>
|
||
<div class="text-right">
|
||
<p class="text-sm text-gray-600">Status</p>
|
||
<p class="text-lg font-semibold" :class="getStatusColor(paymentStatus)">
|
||
{{ formatPaymentStatus(paymentStatus) }}
|
||
</p>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Lightning Invoice QR Code -->
|
||
<div class="text-center">
|
||
<div class="mb-4">
|
||
<h4 class="font-medium text-gray-900 mb-2">Lightning Invoice</h4>
|
||
<p class="text-sm text-gray-600">Scan with your Lightning wallet to pay</p>
|
||
</div>
|
||
|
||
<!-- QR Code -->
|
||
<div class="w-48 h-48 mx-auto mb-4">
|
||
<div v-if="qrCodeDataUrl && !qrCodeError" class="w-full h-full">
|
||
<img
|
||
:src="qrCodeDataUrl"
|
||
:alt="`QR Code for ${invoice.amount} ${currency} payment`"
|
||
class="w-full h-full border border-gray-200 rounded-lg"
|
||
/>
|
||
</div>
|
||
<div v-else-if="qrCodeLoading" class="w-full h-full bg-gray-100 rounded-lg flex items-center justify-center">
|
||
<div class="text-center text-gray-500">
|
||
<div class="text-4xl mb-2 animate-pulse">⚡</div>
|
||
<div class="text-sm">Generating QR...</div>
|
||
</div>
|
||
</div>
|
||
<div v-else-if="qrCodeError" class="w-full h-full bg-red-50 border border-red-200 rounded-lg flex items-center justify-center">
|
||
<div class="text-center text-red-500">
|
||
<div class="text-4xl mb-2">⚠️</div>
|
||
<div class="text-sm">{{ qrCodeError }}</div>
|
||
<Button
|
||
@click="retryQRCode"
|
||
variant="outline"
|
||
size="sm"
|
||
class="mt-2"
|
||
>
|
||
Retry
|
||
</Button>
|
||
</div>
|
||
</div>
|
||
<div v-else class="w-full h-full bg-gray-100 rounded-lg flex items-center justify-center">
|
||
<div class="text-center text-gray-500">
|
||
<div class="text-4xl mb-2">⚡</div>
|
||
<div class="text-sm">No invoice</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- QR Code Actions -->
|
||
<div v-if="qrCodeDataUrl && !qrCodeError" class="mb-4">
|
||
<Button
|
||
@click="downloadQRCode"
|
||
variant="outline"
|
||
size="sm"
|
||
class="w-full"
|
||
>
|
||
<Download class="w-4 h-4 mr-2" />
|
||
Download QR Code
|
||
</Button>
|
||
</div>
|
||
|
||
<!-- Payment Request -->
|
||
<div class="mb-4">
|
||
<label class="block text-sm font-medium text-gray-700 mb-2">
|
||
Payment Request
|
||
</label>
|
||
<div class="flex items-center gap-2">
|
||
<Input
|
||
:value="invoice.bolt11"
|
||
readonly
|
||
class="flex-1 font-mono text-sm"
|
||
/>
|
||
<Button
|
||
@click="copyPaymentRequest"
|
||
variant="outline"
|
||
size="sm"
|
||
>
|
||
<Copy class="w-4 h-4" />
|
||
</Button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Copy to Wallet Button -->
|
||
<Button
|
||
@click="openInWallet"
|
||
variant="default"
|
||
class="w-full"
|
||
>
|
||
<Wallet class="w-4 h-4 mr-2" />
|
||
Open in Lightning Wallet
|
||
</Button>
|
||
</div>
|
||
|
||
<!-- Payment Details -->
|
||
<div class="border-t pt-4">
|
||
<h4 class="font-medium text-gray-900 mb-3">Payment Details</h4>
|
||
<div class="space-y-2 text-sm">
|
||
<div class="flex justify-between">
|
||
<span class="text-gray-600">Payment Hash:</span>
|
||
<span class="font-mono text-gray-900">{{ formatHash(invoice.payment_hash) }}</span>
|
||
</div>
|
||
<div class="flex justify-between">
|
||
<span class="text-gray-600">Created:</span>
|
||
<span class="text-gray-900">{{ formatDate(invoice.created_at ? new Date(invoice.created_at).getTime() : Date.now()) }}</span>
|
||
</div>
|
||
<div class="flex justify-between">
|
||
<span class="text-gray-600">Expires:</span>
|
||
<span class="text-gray-900">{{ formatDate(invoice.expiry ? new Date(invoice.expiry).getTime() : Date.now()) }}</span>
|
||
</div>
|
||
<div v-if="paidAt" class="flex justify-between">
|
||
<span class="text-gray-600">Paid At:</span>
|
||
<span class="text-gray-900">{{ formatDate(paidAt) }}</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- No Invoice State -->
|
||
<div v-else class="text-center py-8">
|
||
<div class="w-16 h-16 bg-gray-100 rounded-full flex items-center justify-center mx-auto mb-4">
|
||
<Wallet class="w-8 h-8 text-gray-400" />
|
||
</div>
|
||
<h4 class="text-lg font-medium text-gray-900 mb-2">No Payment Invoice</h4>
|
||
<p class="text-gray-600 mb-4">
|
||
A Lightning invoice will be sent by the merchant once they process your order.
|
||
</p>
|
||
<p class="text-sm text-gray-500">
|
||
You'll receive the invoice via Nostr when it's ready.
|
||
</p>
|
||
</div>
|
||
|
||
<!-- Payment Instructions -->
|
||
<div v-if="paymentStatus === 'pending'" class="mt-6 p-4 bg-muted/50 border border-border rounded-lg">
|
||
<div class="flex items-start space-x-3">
|
||
<div class="w-5 h-5 bg-muted rounded-full flex items-center justify-center mt-0.5">
|
||
<Info class="w-3 h-3 text-muted-foreground" />
|
||
</div>
|
||
<div class="text-sm text-muted-foreground">
|
||
<h5 class="font-medium mb-1 text-foreground">Payment Instructions</h5>
|
||
<ul class="space-y-1">
|
||
<li>• Use a Lightning-compatible wallet (e.g., Phoenix, Breez, Alby)</li>
|
||
<li>• Scan the QR code or copy the payment request</li>
|
||
<li>• Confirm the payment amount and send</li>
|
||
<li>• Your order will be processed once payment is confirmed</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Payment Success -->
|
||
<div v-if="paymentStatus === 'paid'" class="mt-6 p-4 bg-green-50 border border-green-200 rounded-lg">
|
||
<div class="flex items-center space-x-3">
|
||
<div class="w-5 h-5 bg-green-100 rounded-full flex items-center justify-center">
|
||
<CheckCircle class="w-3 h-3 text-green-600" />
|
||
</div>
|
||
<div class="text-sm text-green-800">
|
||
<h5 class="font-medium">Payment Confirmed!</h5>
|
||
<p>Your order is being processed. You'll receive updates via Nostr.</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
|
||
<script setup lang="ts">
|
||
import { computed, onMounted, ref, watch } from 'vue'
|
||
import { Button } from '@/components/ui/button'
|
||
import { Input } from '@/components/ui/input'
|
||
import { Badge } from '@/components/ui/badge'
|
||
import {
|
||
Copy,
|
||
Wallet,
|
||
|
||
Info,
|
||
CheckCircle,
|
||
Download
|
||
} from 'lucide-vue-next'
|
||
import { useMarketStore } from '@/stores/market'
|
||
import QRCode from 'qrcode'
|
||
|
||
|
||
interface Props {
|
||
orderId: string
|
||
}
|
||
|
||
const props = defineProps<Props>()
|
||
const marketStore = useMarketStore()
|
||
|
||
// Computed properties
|
||
const order = computed(() => marketStore.orders[props.orderId])
|
||
const invoice = computed(() => order.value?.lightningInvoice)
|
||
const paymentStatus = computed(() => order.value?.paymentStatus || 'pending')
|
||
const currency = computed(() => order.value?.currency || 'sat')
|
||
const paidAt = computed(() => order.value?.paidAt)
|
||
|
||
// QR Code generation
|
||
const qrCodeDataUrl = ref<string | null>(null)
|
||
const qrCodeLoading = ref(false)
|
||
const qrCodeError = ref<string | null>(null)
|
||
|
||
const generateQRCode = async (paymentRequest: string) => {
|
||
try {
|
||
qrCodeLoading.value = true
|
||
qrCodeError.value = null
|
||
|
||
const dataUrl = await QRCode.toDataURL(paymentRequest, {
|
||
width: 192, // 48 * 4 for high DPI displays
|
||
margin: 2,
|
||
color: {
|
||
dark: '#000000',
|
||
light: '#FFFFFF'
|
||
}
|
||
})
|
||
qrCodeDataUrl.value = dataUrl
|
||
} catch (error) {
|
||
console.error('Failed to generate QR code:', error)
|
||
qrCodeError.value = 'Failed to generate QR code'
|
||
qrCodeDataUrl.value = null
|
||
} finally {
|
||
qrCodeLoading.value = false
|
||
}
|
||
}
|
||
|
||
// Methods
|
||
const getPaymentStatusVariant = (status: string) => {
|
||
switch (status) {
|
||
case 'paid': return 'default'
|
||
case 'pending': return 'secondary'
|
||
case 'expired': return 'destructive'
|
||
default: return 'outline'
|
||
}
|
||
}
|
||
|
||
const formatPaymentStatus = (status: string) => {
|
||
switch (status) {
|
||
case 'paid': return 'Paid'
|
||
case 'pending': return 'Pending'
|
||
case 'expired': return 'Expired'
|
||
default: return 'Unknown'
|
||
}
|
||
}
|
||
|
||
const getStatusColor = (status: string) => {
|
||
switch (status) {
|
||
case 'paid': return 'text-green-600'
|
||
case 'pending': return 'text-yellow-600'
|
||
case 'expired': return 'text-red-600'
|
||
default: return 'text-gray-600'
|
||
}
|
||
}
|
||
|
||
const formatHash = (hash: string) => {
|
||
if (!hash) return 'N/A'
|
||
return `${hash.substring(0, 8)}...${hash.substring(hash.length - 8)}`
|
||
}
|
||
|
||
const formatDate = (timestamp: number) => {
|
||
if (!timestamp) return 'N/A'
|
||
return new Date(timestamp * 1000).toLocaleString()
|
||
}
|
||
|
||
const copyPaymentRequest = async () => {
|
||
if (!invoice.value?.bolt11) return
|
||
|
||
try {
|
||
await navigator.clipboard.writeText(invoice.value.bolt11)
|
||
// TODO: Show toast notification
|
||
console.log('Payment request copied to clipboard')
|
||
} catch (error) {
|
||
console.error('Failed to copy payment request:', error)
|
||
}
|
||
}
|
||
|
||
const openInWallet = () => {
|
||
if (!invoice.value?.bolt11) return
|
||
|
||
// Open in Lightning wallet
|
||
const walletUrl = `lightning:${invoice.value.bolt11}`
|
||
window.open(walletUrl, '_blank')
|
||
}
|
||
|
||
const downloadQRCode = () => {
|
||
if (!qrCodeDataUrl.value) return
|
||
|
||
const link = document.createElement('a')
|
||
link.href = qrCodeDataUrl.value
|
||
link.download = `qr-code-${invoice.value?.amount}-${currency.value}.png`
|
||
document.body.appendChild(link)
|
||
link.click()
|
||
document.body.removeChild(link)
|
||
}
|
||
|
||
const retryQRCode = () => {
|
||
if (invoice.value?.bolt11) {
|
||
generateQRCode(invoice.value.bolt11)
|
||
}
|
||
}
|
||
|
||
// Lifecycle
|
||
onMounted(() => {
|
||
// Set up payment monitoring if invoice exists
|
||
if (invoice.value && props.orderId) {
|
||
// Payment monitoring is handled by the market store
|
||
console.log('Payment display mounted for order:', props.orderId)
|
||
|
||
// Generate QR code for the invoice
|
||
if (invoice.value.bolt11) {
|
||
generateQRCode(invoice.value.bolt11)
|
||
}
|
||
}
|
||
})
|
||
|
||
// Watch for invoice changes to regenerate QR code
|
||
watch(() => invoice.value?.bolt11, (newPaymentRequest) => {
|
||
if (newPaymentRequest) {
|
||
generateQRCode(newPaymentRequest)
|
||
} else {
|
||
qrCodeDataUrl.value = null
|
||
}
|
||
}, { immediate: true })
|
||
</script>
|