feat: soft-delete sites with 7-day grace period #55
29
app/page.tsx
29
app/page.tsx
@@ -408,15 +408,22 @@ export default function HomePage() {
|
|||||||
const siteLimit = getSitesLimitForPlan(subscription?.plan_id)
|
const siteLimit = getSitesLimitForPlan(subscription?.plan_id)
|
||||||
const atLimit = siteLimit != null && sites.length >= siteLimit
|
const atLimit = siteLimit != null && sites.length >= siteLimit
|
||||||
return atLimit ? (
|
return atLimit ? (
|
||||||
<div className="flex items-center gap-3">
|
<div>
|
||||||
<span className="text-sm font-medium text-neutral-500 dark:text-neutral-400 bg-neutral-100 dark:bg-neutral-800 px-3 py-1.5 rounded-lg border border-neutral-200 dark:border-neutral-700">
|
<div className="flex items-center gap-3">
|
||||||
Limit reached ({sites.length}/{siteLimit})
|
<span className="text-sm font-medium text-neutral-500 dark:text-neutral-400 bg-neutral-100 dark:bg-neutral-800 px-3 py-1.5 rounded-lg border border-neutral-200 dark:border-neutral-700">
|
||||||
</span>
|
Limit reached ({sites.length}/{siteLimit})
|
||||||
<Link href="/pricing">
|
</span>
|
||||||
<Button variant="primary" className="text-sm">
|
<Link href="/pricing">
|
||||||
Upgrade
|
<Button variant="primary" className="text-sm">
|
||||||
</Button>
|
Upgrade
|
||||||
</Link>
|
</Button>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
{deletedSites.length > 0 && (
|
||||||
|
<p className="text-sm text-neutral-500 dark:text-neutral-400 mt-2">
|
||||||
|
You have a site pending deletion. Restore it or permanently delete it to free the slot.
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
) : null
|
) : null
|
||||||
})() ?? (
|
})() ?? (
|
||||||
@@ -556,7 +563,9 @@ export default function HomePage() {
|
|||||||
<div>
|
<div>
|
||||||
<span className="font-medium text-neutral-700 dark:text-neutral-300">{site.name}</span>
|
<span className="font-medium text-neutral-700 dark:text-neutral-300">{site.name}</span>
|
||||||
<span className="ml-2 text-sm text-neutral-400">{site.domain}</span>
|
<span className="ml-2 text-sm text-neutral-400">{site.domain}</span>
|
||||||
<span className="ml-3 text-xs text-red-500 font-medium">Deleting in {daysLeft} day{daysLeft !== 1 ? 's' : ''}</span>
|
<span className="ml-3 inline-flex items-center rounded-full bg-red-50 px-2 py-0.5 text-xs font-medium text-red-600 dark:bg-red-900/20 dark:text-red-400">
|
||||||
|
Deleting in {daysLeft} day{daysLeft !== 1 ? 's' : ''}
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex gap-2">
|
<div className="flex gap-2">
|
||||||
<button
|
<button
|
||||||
|
|||||||
@@ -100,13 +100,13 @@ export default function DeleteSiteModal({ open, onClose, onDeleted, siteName, si
|
|||||||
<div className="flex items-center gap-3 p-3 bg-red-50 dark:bg-red-900/10 border border-red-100 dark:border-red-900/20 rounded-lg">
|
<div className="flex items-center gap-3 p-3 bg-red-50 dark:bg-red-900/10 border border-red-100 dark:border-red-900/20 rounded-lg">
|
||||||
<AlertTriangleIcon className="h-4 w-4 text-red-500 shrink-0" />
|
<AlertTriangleIcon className="h-4 w-4 text-red-500 shrink-0" />
|
||||||
<span className="text-sm font-medium text-red-700 dark:text-red-300">
|
<span className="text-sm font-medium text-red-700 dark:text-red-300">
|
||||||
Site will stop collecting data immediately
|
All events and analytics data
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-3 p-3 bg-red-50 dark:bg-red-900/10 border border-red-100 dark:border-red-900/20 rounded-lg">
|
<div className="flex items-center gap-3 p-3 bg-red-50 dark:bg-red-900/10 border border-red-100 dark:border-red-900/20 rounded-lg">
|
||||||
<AlertTriangleIcon className="h-4 w-4 text-red-500 shrink-0" />
|
<AlertTriangleIcon className="h-4 w-4 text-red-500 shrink-0" />
|
||||||
<span className="text-sm font-medium text-red-700 dark:text-red-300">
|
<span className="text-sm font-medium text-red-700 dark:text-red-300">
|
||||||
All data will be purged after 7 days
|
Report schedules and goals
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -149,7 +149,7 @@ export default function DeleteSiteModal({ open, onClose, onDeleted, siteName, si
|
|||||||
onClick={() => setShowPermanent(true)}
|
onClick={() => setShowPermanent(true)}
|
||||||
className="w-full text-center text-xs text-neutral-400 hover:text-red-500 dark:hover:text-red-400 transition-colors"
|
className="w-full text-center text-xs text-neutral-400 hover:text-red-500 dark:hover:text-red-400 transition-colors"
|
||||||
>
|
>
|
||||||
Permanently delete now
|
Permanently delete now (cannot be undone)
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
|
|||||||
Reference in New Issue
Block a user