diff --git a/components/ActionPage/TransferTicketModal.tsx b/components/ActionPage/TransferTicketModal.tsx index cc30a52..dc18a67 100644 --- a/components/ActionPage/TransferTicketModal.tsx +++ b/components/ActionPage/TransferTicketModal.tsx @@ -1,11 +1,11 @@ 'use client'; -import React, { useMemo, useState } from 'react'; -import { Check, Loader2, Search, Send, UserRound, X } from 'lucide-react'; +import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'; +import { Camera, Check, ImageUp, Link2, Loader2, Search, Send, UserRound, Users, X } from 'lucide-react'; import { Dialog, DialogContent } from '@/components/ui/dialog'; import { useAuthToken } from '@/hooks/use-auth-token'; import { useGetAcceptedContactsQuery } from '@/states/contactSlice'; -import { transferActionPurchase } from '@/helpers/api'; +import { transferActionPurchase, getUserById, getOrganizationById } from '@/helpers/api'; import { toast } from '@/hooks/use-toast'; interface TransferTicketModalProps { @@ -14,11 +14,12 @@ interface TransferTicketModalProps { /** The purchase to transfer (from the QR object's actionPurchaseId) */ purchaseId: string; ticketName: string; + /** The current owner — used to guard against transferring to yourself */ senderId: string; onTransferred: () => void; } -interface ContactUser { +interface RecipientUser { id: string; firstName: string; lastName: string; @@ -26,10 +27,36 @@ interface ContactUser { profile?: { profileImage?: string }; } -const fullName = (u: ContactUser) => `${u.firstName || ''} ${u.lastName || ''}`.trim() || u.email; -const initials = (u: ContactUser) => +type Mode = 'contacts' | 'link'; + +const UUID_RE = /[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/i; + +const fullName = (u: RecipientUser) => `${u.firstName || ''} ${u.lastName || ''}`.trim() || u.email; +const initials = (u: RecipientUser) => `${(u.firstName || u.email || '?')[0] || ''}${(u.lastName || '')[0] || ''}`.toUpperCase(); +/** Pull a user id out of a profile link, full URL, or raw id — QR codes encode the same link. */ +const extractUserId = (input: string): string | null => { + const trimmed = input.trim(); + const welcomeMatch = trimmed.match(/\/welcome\/([^/?#]+)/i); + if (welcomeMatch) return welcomeMatch[1]; + const uuid = trimmed.match(UUID_RE); + return uuid ? uuid[0] : null; +}; + +const Avatar: React.FC<{ user: RecipientUser; size?: number }> = ({ user, size = 36 }) => ( +