diff --git a/apps/rebreak-native/components/blocker/VipDomainList.tsx b/apps/rebreak-native/components/blocker/VipDomainList.tsx index e3d6c6c..a08b657 100644 --- a/apps/rebreak-native/components/blocker/VipDomainList.tsx +++ b/apps/rebreak-native/components/blocker/VipDomainList.tsx @@ -475,7 +475,18 @@ export function VipDomainList({ domains, open, onToggle, colors }: VipListProps) const list = vipList ?? [...customStatusMap.keys()]; - const customDomains = list.filter((d) => customStatusMap.has(d)); + const now = Date.now(); + const customDomains = list + .filter((d) => customStatusMap.has(d)) + .sort((a, b) => { + const evictA = customStatusMap.get(a)?.vipEvictAt; + const evictB = customStatusMap.get(b)?.vipEvictAt; + const aIsPending = evictA ? new Date(evictA).getTime() > now : false; + const bIsPending = evictB ? new Date(evictB).getTime() > now : false; + if (aIsPending && !bIsPending) return -1; + if (!aIsPending && bIsPending) return 1; + return 0; + }); const curatedDomains = list.filter((d) => !customStatusMap.has(d)); function getMeta(d: string): VipCustomMeta { @@ -637,18 +648,17 @@ function VipCustomTile({ return Math.ceil(ms / (1000 * 60 * 60)); })(); + const isEvictPending = evictBadgeHours !== null; + const statusColor: string = (() => { - switch (status) { - case 'submitted': return colors.warning; - case 'approved': return '#22c55e'; - default: return colors.brandOrange; - } + if (status === 'submitted') return colors.warning; + if (isEvictPending) return '#f97316'; + return '#22c55e'; })(); const badgeLabel: string = (() => { switch (status) { case 'submitted': return t('blocker.domain_badge_pruefung'); - case 'approved': return t('blocker.domain_badge_active'); default: return t('blocker.domain_badge_active'); } })(); @@ -722,16 +732,21 @@ function VipCustomTile({ {evictBadgeHours !== null && ( + {t('blocker.vip_evict_badge', { hours: evictBadgeHours })} diff --git a/apps/rebreak-native/components/blocker/VipSwapSheet.tsx b/apps/rebreak-native/components/blocker/VipSwapSheet.tsx index a81843c..9a86c07 100644 --- a/apps/rebreak-native/components/blocker/VipSwapSheet.tsx +++ b/apps/rebreak-native/components/blocker/VipSwapSheet.tsx @@ -39,11 +39,11 @@ export function VipSwapSheet({ visible, newDomainId, candidates, onClose, onSwap onClose(); } - async function handleSwap() { - if (!selectedId || submitting) return; + async function handleSwap(evictedId: string) { + if (submitting) return; setSubmitting(true); setError(null); - const result = await onSwap(newDomainId, selectedId); + const result = await onSwap(newDomainId, evictedId); setSubmitting(false); if (result.ok) { close(); @@ -52,8 +52,6 @@ export function VipSwapSheet({ visible, newDomainId, candidates, onClose, onSwap setError(t('blocker.vip_swap_error')); } - const ctaEnabled = selectedId !== null && !submitting; - return ( - {/* Erklärtext */} - {/* Pick-Label */} - {/* Domain-Liste */} {eligible.length === 0 ? ( setSelectedId(d.id)} + submitting={submitting && selectedId === d.id} + onSelect={() => setSelectedId(selectedId === d.id ? null : d.id)} + onConfirm={() => handleSwap(d.id)} colors={colors} /> ))} @@ -142,62 +139,6 @@ export function VipSwapSheet({ visible, newDomainId, candidates, onClose, onSwap {error} )} - - {/* Buttons */} - - - - - {t('common.cancel')} - - - - - - - {submitting ? ( - - ) : ( - - {t('blocker.vip_swap_cta')} - - )} - - - ); @@ -206,87 +147,119 @@ export function VipSwapSheet({ visible, newDomainId, candidates, onClose, onSwap function SwapCandidateTile({ domain, selected, + submitting, onSelect, + onConfirm, colors, }: { domain: CustomDomain; selected: boolean; + submitting: boolean; onSelect: () => void; + onConfirm: () => void; colors: ReturnType; }) { + const { t } = useTranslation(); const [imgError, setImgError] = useState(false); const stripped = domain.domain.replace(/^www\./, ''); return ( - - {!imgError ? ( - setImgError(true)} - /> - ) : ( - - + {!imgError ? ( + setImgError(true)} + /> + ) : ( + - {stripped.slice(0, 2).toUpperCase()} - - + + {stripped.slice(0, 2).toUpperCase()} + + + )} + + + {stripped} + + + + + + {selected && ( + + {submitting ? ( + + ) : ( + + {t('blocker.vip_swap_cta')} + + )} + )} - - - {stripped} - - - - {selected && } - - + ); }