Initial commit: breakpilot-compliance - Compliance SDK Platform

Services: Admin-Compliance, Backend-Compliance,
AI-Compliance-SDK, Consent-SDK, Developer-Portal,
PCA-Platform, DSMS

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Benjamin Boenisch
2026-02-11 23:47:28 +01:00
commit 4435e7ea0a
734 changed files with 251369 additions and 0 deletions

View File

@@ -0,0 +1,277 @@
'use client'
import React, { useState } from 'react'
import { SDKDocsSidebar } from '@/components/SDKDocsSidebar'
import { Copy, Check } from 'lucide-react'
function CopyButton({ text }: { text: string }) {
const [copied, setCopied] = useState(false)
const handleCopy = async () => {
await navigator.clipboard.writeText(text)
setCopied(true)
setTimeout(() => setCopied(false), 2000)
}
return (
<button onClick={handleCopy} className="p-2 hover:bg-gray-700 rounded transition-colors">
{copied ? <Check className="w-4 h-4 text-green-400" /> : <Copy className="w-4 h-4 text-gray-400" />}
</button>
)
}
function CodeBlock({ code, filename }: { code: string; filename?: string }) {
return (
<div className="bg-gray-900 rounded-lg overflow-hidden">
{filename && (
<div className="px-4 py-2 bg-gray-800 text-gray-400 text-xs border-b border-gray-700">
{filename}
</div>
)}
<div className="relative">
<div className="absolute top-2 right-2">
<CopyButton text={code} />
</div>
<pre className="p-4 text-sm text-gray-300 font-mono overflow-x-auto">
<code>{code}</code>
</pre>
</div>
</div>
)
}
export default function VueIntegrationPage() {
return (
<div className="min-h-screen bg-gray-50 flex">
<SDKDocsSidebar />
<main className="flex-1 ml-64">
<div className="max-w-4xl mx-auto px-8 py-12">
<div className="flex items-center gap-3 mb-2">
<div className="w-10 h-10 rounded-lg bg-emerald-500 flex items-center justify-center">
<span className="text-white font-bold">V</span>
</div>
<h1 className="text-3xl font-bold text-gray-900">Vue 3 Integration</h1>
</div>
<p className="text-lg text-gray-600 mb-8">
Composables und Plugin fuer Vue 3 und Nuxt Projekte.
</p>
{/* Installation */}
<section className="mb-12">
<h2 className="text-xl font-semibold text-gray-900 mb-4">Installation</h2>
<CodeBlock code="npm install @breakpilot/consent-sdk" />
</section>
{/* Plugin Setup */}
<section className="mb-12">
<h2 className="text-xl font-semibold text-gray-900 mb-4">Plugin Setup</h2>
<CodeBlock
filename="main.ts"
code={`import { createApp } from 'vue';
import App from './App.vue';
import { ConsentPlugin } from '@breakpilot/consent-sdk/vue';
const app = createApp(App);
app.use(ConsentPlugin, {
apiEndpoint: import.meta.env.VITE_CONSENT_API,
siteId: 'my-site',
debug: import.meta.env.DEV,
});
app.mount('#app');`}
/>
</section>
{/* Composable */}
<section className="mb-12">
<h2 className="text-xl font-semibold text-gray-900 mb-4">useConsent Composable</h2>
<CodeBlock
filename="components/Analytics.vue"
code={`<script setup lang="ts">
import { useConsent } from '@breakpilot/consent-sdk/vue';
const { hasConsent, acceptAll, rejectAll } = useConsent();
</script>
<template>
<div v-if="hasConsent('analytics')">
<!-- Analytics Code hier -->
</div>
</template>`}
/>
</section>
{/* Cookie Banner */}
<section className="mb-12">
<h2 className="text-xl font-semibold text-gray-900 mb-4">Cookie Banner Component</h2>
<CodeBlock
filename="components/CookieBanner.vue"
code={`<script setup lang="ts">
import { useConsent } from '@breakpilot/consent-sdk/vue';
const {
isBannerVisible,
acceptAll,
rejectAll,
showSettings,
} = useConsent();
</script>
<template>
<Transition name="slide">
<div
v-if="isBannerVisible"
class="fixed bottom-0 inset-x-0 bg-white border-t shadow-lg p-4 z-50"
>
<div class="max-w-4xl mx-auto flex items-center justify-between">
<p class="text-sm text-gray-600">
Wir verwenden Cookies um Ihr Erlebnis zu verbessern.
</p>
<div class="flex gap-2">
<button
@click="rejectAll"
class="px-4 py-2 text-sm border rounded hover:bg-gray-50"
>
Ablehnen
</button>
<button
@click="showSettings"
class="px-4 py-2 text-sm border rounded hover:bg-gray-50"
>
Einstellungen
</button>
<button
@click="acceptAll"
class="px-4 py-2 text-sm bg-blue-600 text-white rounded hover:bg-blue-700"
>
Alle akzeptieren
</button>
</div>
</div>
</div>
</Transition>
</template>
<style scoped>
.slide-enter-active,
.slide-leave-active {
transition: transform 0.3s ease;
}
.slide-enter-from,
.slide-leave-to {
transform: translateY(100%);
}
</style>`}
/>
</section>
{/* ConsentGate */}
<section className="mb-12">
<h2 className="text-xl font-semibold text-gray-900 mb-4">ConsentGate Component</h2>
<CodeBlock
filename="components/YouTubeEmbed.vue"
code={`<script setup lang="ts">
import { ConsentGate } from '@breakpilot/consent-sdk/vue';
defineProps<{
videoId: string;
}>();
</script>
<template>
<ConsentGate category="social">
<template #default>
<iframe
:src="\`https://www.youtube.com/embed/\${videoId}\`"
width="560"
height="315"
allowfullscreen
/>
</template>
<template #fallback>
<div class="bg-gray-100 p-4 rounded-lg text-center">
<p>Video erfordert Ihre Zustimmung.</p>
<button class="mt-2 px-4 py-2 bg-blue-600 text-white rounded">
Zustimmen
</button>
</div>
</template>
</ConsentGate>
</template>`}
/>
</section>
{/* Nuxt */}
<section className="mb-12">
<h2 className="text-xl font-semibold text-gray-900 mb-4">Nuxt 3 Setup</h2>
<CodeBlock
filename="plugins/consent.client.ts"
code={`import { ConsentPlugin } from '@breakpilot/consent-sdk/vue';
export default defineNuxtPlugin((nuxtApp) => {
nuxtApp.vueApp.use(ConsentPlugin, {
apiEndpoint: useRuntimeConfig().public.consentApi,
siteId: 'my-site',
});
});`}
/>
</section>
{/* Composable API */}
<section>
<h2 className="text-xl font-semibold text-gray-900 mb-4">Composable API</h2>
<div className="bg-white rounded-xl border border-gray-200 overflow-hidden">
<table className="min-w-full divide-y divide-gray-200">
<thead className="bg-gray-50">
<tr>
<th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase">
Property
</th>
<th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase">
Typ
</th>
<th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase">
Beschreibung
</th>
</tr>
</thead>
<tbody className="divide-y divide-gray-200">
<tr>
<td className="px-6 py-4"><code className="text-violet-600">hasConsent</code></td>
<td className="px-6 py-4"><code className="text-gray-500">(category) =&gt; boolean</code></td>
<td className="px-6 py-4 text-sm text-gray-600">Reaktive Consent-Pruefung</td>
</tr>
<tr>
<td className="px-6 py-4"><code className="text-violet-600">consent</code></td>
<td className="px-6 py-4"><code className="text-gray-500">Ref&lt;ConsentState&gt;</code></td>
<td className="px-6 py-4 text-sm text-gray-600">Reaktiver Consent-Status</td>
</tr>
<tr>
<td className="px-6 py-4"><code className="text-violet-600">isBannerVisible</code></td>
<td className="px-6 py-4"><code className="text-gray-500">Ref&lt;boolean&gt;</code></td>
<td className="px-6 py-4 text-sm text-gray-600">Reaktive Banner-Sichtbarkeit</td>
</tr>
<tr>
<td className="px-6 py-4"><code className="text-violet-600">acceptAll</code></td>
<td className="px-6 py-4"><code className="text-gray-500">() =&gt; Promise</code></td>
<td className="px-6 py-4 text-sm text-gray-600">Akzeptiert alle</td>
</tr>
<tr>
<td className="px-6 py-4"><code className="text-violet-600">rejectAll</code></td>
<td className="px-6 py-4"><code className="text-gray-500">() =&gt; Promise</code></td>
<td className="px-6 py-4 text-sm text-gray-600">Lehnt alle ab</td>
</tr>
<tr>
<td className="px-6 py-4"><code className="text-violet-600">setConsent</code></td>
<td className="px-6 py-4"><code className="text-gray-500">(input) =&gt; Promise</code></td>
<td className="px-6 py-4 text-sm text-gray-600">Setzt spezifische Kategorien</td>
</tr>
</tbody>
</table>
</div>
</section>
</div>
</main>
</div>
)
}