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 && }
-
-
+
);
}