fix: consent banner dismiss on decline + short viewport layout
Bug 1: Clicking 'Ablehnen' now properly dismisses the dialog by calling the delete account mutation and signing out (previously it redirected to /settings/privacy which re-rendered the banner in a loop). Bug 2: Restructured the dialog layout with flex-col + overflow-y-auto on the content area only. Header and action buttons are pinned (shrink-0) so they're always accessible on short viewports. Added max-h constraint with min() to cap at 600px or 90vh.
This commit is contained in:
@@ -3,8 +3,10 @@
|
||||
import { useState } from "react"
|
||||
import {
|
||||
useConsentCheckQuery,
|
||||
useDeleteAccountMutation,
|
||||
useGrantConsentMutation,
|
||||
} from "@/services/consent"
|
||||
import { signOut } from "next-auth/react"
|
||||
import { useTranslations } from "next-intl"
|
||||
import { CheckCircle, Shield } from "lucide-react"
|
||||
|
||||
@@ -19,6 +21,7 @@ export function ConsentBanner() {
|
||||
|
||||
const { data: consentCheck, isLoading } = useConsentCheckQuery()
|
||||
const grantMutation = useGrantConsentMutation()
|
||||
const deleteMutation = useDeleteAccountMutation()
|
||||
|
||||
// Don't show if still loading or consent already granted
|
||||
if (isLoading || consentCheck?.hasDataProcessingConsent) {
|
||||
@@ -34,19 +37,25 @@ export function ConsentBanner() {
|
||||
}
|
||||
}
|
||||
|
||||
const handleReject = () => {
|
||||
// Redirect to deletion confirmation
|
||||
window.location.href = "/settings/privacy?action=delete"
|
||||
const handleReject = async () => {
|
||||
// Delete account and sign out — dismisses the dialog by leaving the app
|
||||
await deleteMutation.mutateAsync()
|
||||
await signOut({ callbackUrl: "/login" })
|
||||
}
|
||||
|
||||
const isPending = grantMutation.isPending || deleteMutation.isPending
|
||||
|
||||
return (
|
||||
<div className="fixed inset-0 z-[9999] flex items-center justify-center bg-black/70 backdrop-blur-sm">
|
||||
<div className="mx-4 max-h-[90vh] w-full max-w-lg overflow-y-auto rounded-xl bg-card p-6 shadow-2xl">
|
||||
<div className="mb-4 flex items-center gap-3">
|
||||
<div className="fixed inset-0 z-[9999] flex items-center justify-center bg-black/70 backdrop-blur-sm p-4">
|
||||
<div className="flex max-h-[min(90vh,600px)] w-full max-w-lg flex-col rounded-xl bg-card shadow-2xl">
|
||||
{/* Header — fixed */}
|
||||
<div className="flex shrink-0 items-center gap-3 border-b px-6 pt-6 pb-4">
|
||||
<Shield className="h-8 w-8 text-primary" />
|
||||
<h2 className="text-xl font-semibold">{t("title")}</h2>
|
||||
</div>
|
||||
|
||||
{/* Scrollable content */}
|
||||
<div className="flex-1 overflow-y-auto px-6 py-4">
|
||||
{/* Required: Data Processing */}
|
||||
<div className="mb-4 rounded-lg border border-primary/20 bg-primary/5 p-4">
|
||||
<h3 className="mb-1 font-medium">{t("dataProcessing")}</h3>
|
||||
@@ -59,7 +68,7 @@ export function ConsentBanner() {
|
||||
</div>
|
||||
|
||||
{/* Optional: Marketing */}
|
||||
<div className="mb-6 rounded-lg border p-4">
|
||||
<div className="rounded-lg border p-4">
|
||||
<label className="flex cursor-pointer items-start gap-3">
|
||||
<input
|
||||
type="checkbox"
|
||||
@@ -75,12 +84,13 @@ export function ConsentBanner() {
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Actions */}
|
||||
<div className="flex flex-col gap-3">
|
||||
{/* Actions — fixed at bottom */}
|
||||
<div className="flex shrink-0 flex-col gap-3 border-t px-6 pt-4 pb-6">
|
||||
<button
|
||||
onClick={handleAccept}
|
||||
disabled={grantMutation.isPending}
|
||||
disabled={isPending}
|
||||
className="flex w-full items-center justify-center gap-2 rounded-lg bg-primary px-4 py-3 text-sm font-medium text-primary-foreground transition-colors hover:bg-primary/90 disabled:opacity-50"
|
||||
>
|
||||
<CheckCircle className="h-4 w-4" />
|
||||
@@ -89,9 +99,10 @@ export function ConsentBanner() {
|
||||
|
||||
<button
|
||||
onClick={handleReject}
|
||||
className="w-full text-center text-sm text-destructive underline transition-colors hover:text-destructive/80"
|
||||
disabled={isPending}
|
||||
className="w-full text-center text-sm text-destructive underline transition-colors hover:text-destructive/80 disabled:opacity-50"
|
||||
>
|
||||
{t("reject")}
|
||||
{deleteMutation.isPending ? "..." : t("reject")}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user