Add PostHog consent integration and extract integration plugin system
Add PostHog opt-in/opt-out consent support mirroring the existing Google Consent Mode integration: database column, GraphQL field, console UI toggle, and client-side posthog-js calls. Extract both GCM and PostHog logic from CookieBannerClient into a ConsentIntegration plugin interface so future integrations can be added without modifying the client core. Signed-off-by: Émile Ré <emile@getprobo.com>
This commit is contained in:
@@ -60,6 +60,7 @@ export const categorySectionFragment = graphql`
|
||||
description
|
||||
kind
|
||||
gcmConsentTypes
|
||||
posthogConsent
|
||||
cookies(first: 100, orderBy: { field: CREATED_AT, direction: ASC })
|
||||
@connection(key: "CategorySection_cookies", filters: [])
|
||||
@required(action: THROW) {
|
||||
@@ -99,6 +100,7 @@ const updateCategoryMutation = graphql`
|
||||
description
|
||||
rank
|
||||
gcmConsentTypes
|
||||
posthogConsent
|
||||
updatedAt
|
||||
}
|
||||
cookieBanner {
|
||||
@@ -239,7 +241,10 @@ export function CategorySection({ categoryKey, onDelete }: CategorySectionProps)
|
||||
const cookies = category.cookies.edges.map(e => e.node);
|
||||
const isMutating = isUpdating || isCreating || isUpdatingCookie;
|
||||
|
||||
const handleSaveCategory = (name: string, slug: string, description: string, gcmConsentTypes: string[]) => {
|
||||
const handleSaveCategory = (
|
||||
name: string, slug: string, description: string,
|
||||
gcmConsentTypes: string[], posthogConsent: boolean,
|
||||
) => {
|
||||
updateCategory({
|
||||
variables: {
|
||||
input: {
|
||||
@@ -248,6 +253,7 @@ export function CategorySection({ categoryKey, onDelete }: CategorySectionProps)
|
||||
slug,
|
||||
description,
|
||||
gcmConsentTypes,
|
||||
posthogConsent,
|
||||
},
|
||||
},
|
||||
onCompleted(_response, errors) {
|
||||
@@ -485,6 +491,7 @@ export function CategorySection({ categoryKey, onDelete }: CategorySectionProps)
|
||||
slug={category.slug}
|
||||
description={category.description}
|
||||
gcmConsentTypes={[...category.gcmConsentTypes]}
|
||||
posthogConsent={category.posthogConsent}
|
||||
isUpdating={isUpdating}
|
||||
onSave={handleSaveCategory}
|
||||
onCancel={() => setIsEditingCategory(false)}
|
||||
@@ -541,6 +548,16 @@ export function CategorySection({ categoryKey, onDelete }: CategorySectionProps)
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
{category.posthogConsent && (
|
||||
<div className="mt-2 flex items-center gap-1.5">
|
||||
<span className="text-xs text-txt-secondary/70">
|
||||
{__("PostHog:")}
|
||||
</span>
|
||||
<Badge variant="neutral">
|
||||
{__("Tracking consent")}
|
||||
</Badge>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -31,8 +31,9 @@ interface EditCategoryFormProps {
|
||||
slug: string;
|
||||
description: string;
|
||||
gcmConsentTypes: string[];
|
||||
posthogConsent: boolean;
|
||||
isUpdating: boolean;
|
||||
onSave: (name: string, slug: string, description: string, gcmConsentTypes: string[]) => void;
|
||||
onSave: (name: string, slug: string, description: string, gcmConsentTypes: string[], posthogConsent: boolean) => void;
|
||||
onCancel: () => void;
|
||||
}
|
||||
|
||||
@@ -41,6 +42,7 @@ export function EditCategoryForm({
|
||||
slug,
|
||||
description,
|
||||
gcmConsentTypes,
|
||||
posthogConsent,
|
||||
isUpdating,
|
||||
onSave,
|
||||
onCancel,
|
||||
@@ -50,6 +52,7 @@ export function EditCategoryForm({
|
||||
const [editSlug, setEditSlug] = useState(slug);
|
||||
const [editDescription, setEditDescription] = useState(description);
|
||||
const [editGcmTypes, setEditGcmTypes] = useState<string[]>(gcmConsentTypes);
|
||||
const [editPosthogConsent, setEditPosthogConsent] = useState(posthogConsent);
|
||||
|
||||
const toggleGcmType = (type: string) => {
|
||||
setEditGcmTypes(prev =>
|
||||
@@ -102,11 +105,28 @@ export function EditCategoryForm({
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<label className="text-sm font-medium">
|
||||
{__("PostHog")}
|
||||
</label>
|
||||
<p className="text-xs text-muted-foreground mb-2">
|
||||
{__("Control PostHog tracking consent based on this category.")}
|
||||
</p>
|
||||
<label className="flex items-center gap-1.5 text-xs cursor-pointer">
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={editPosthogConsent}
|
||||
onChange={() => setEditPosthogConsent(prev => !prev)}
|
||||
className="rounded"
|
||||
/>
|
||||
<span>{__("Opt in/out of PostHog tracking")}</span>
|
||||
</label>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<Button
|
||||
onClick={() => {
|
||||
if (!/^[a-z0-9]+(-[a-z0-9]+)*$/.test(editSlug)) return;
|
||||
onSave(editName, editSlug, editDescription, editGcmTypes);
|
||||
onSave(editName, editSlug, editDescription, editGcmTypes, editPosthogConsent);
|
||||
}}
|
||||
disabled={isUpdating}
|
||||
>
|
||||
|
||||
Reference in New Issue
Block a user