mirror of
https://github.com/Since-3/since3-portal.git
synced 2026-10-12 20:51:17 +00:00
Merge pull request #12 from Since-3/feature/status-change
added status changing for clients and legal stuff
This commit is contained in:
commit
96208249aa
15 changed files with 1188 additions and 35 deletions
505
app/(legal)/agb/page.tsx
Normal file
505
app/(legal)/agb/page.tsx
Normal file
|
|
@ -0,0 +1,505 @@
|
||||||
|
import Image from "next/image"
|
||||||
|
import Link from "next/link"
|
||||||
|
|
||||||
|
const AGB = () => {
|
||||||
|
return (
|
||||||
|
<div className="flex min-h-svh flex-col bg-background p-4 sm:p-6">
|
||||||
|
<Link href="/">
|
||||||
|
<Image
|
||||||
|
src="/pictures/since3-logo.svg" alt=""
|
||||||
|
width={1617}
|
||||||
|
height={332}
|
||||||
|
loading="eager"
|
||||||
|
className="h-5 w-auto self-start md:h-6 dark:hidden"/>
|
||||||
|
</Link>
|
||||||
|
<Link href="/">
|
||||||
|
<Image
|
||||||
|
src="/pictures/since3-logo-weiss.svg" alt=""
|
||||||
|
width={1617}
|
||||||
|
height={332}
|
||||||
|
loading="eager"
|
||||||
|
className="hidden h-5 w-auto self-start md:h-6 dark:block"/>
|
||||||
|
</Link>
|
||||||
|
<div className="flex flex-1 flex-col justify-center py-10">
|
||||||
|
<div className="flex flex-1 flex-col justify-center py-10">
|
||||||
|
<div className="mx-auto w-full max-w-3xl space-y-10">
|
||||||
|
<section>
|
||||||
|
<h1 className="mb-6 text-4xl font-semibold">
|
||||||
|
Allgemeine Geschäftsbedingungen
|
||||||
|
</h1>
|
||||||
|
<p className="leading-7">
|
||||||
|
der Since3 GbR, Sandweg 91, 48565 Steinfurt (nachfolgend
|
||||||
|
„Since3“), für Leistungen und die Nutzung der Kundenplattform
|
||||||
|
app.since3.de. Stand: 01.10.2026 · Version 1.0
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<hr/>
|
||||||
|
|
||||||
|
<section className="space-y-3">
|
||||||
|
<h2 className="text-xl font-semibold">§ 1 Geltungsbereich</h2>
|
||||||
|
<p className="leading-7">
|
||||||
|
(1) Diese Allgemeinen Geschäftsbedingungen (AGB) gelten für alle
|
||||||
|
Verträge, Angebote und Leistungen zwischen Since3 und ihren
|
||||||
|
Kunden, insbesondere für die Konzeption, Gestaltung und Erstellung
|
||||||
|
digitaler Produkte, die Betreuung, Wartung und Pflege sowie die
|
||||||
|
Bereitstellung der Kundenplattform.
|
||||||
|
</p>
|
||||||
|
<p className="leading-7">
|
||||||
|
(2) Unsere Leistungen richten sich ausschließlich an Unternehmer
|
||||||
|
im Sinne von § 14 BGB, juristische Personen des öffentlichen
|
||||||
|
Rechts und öffentlich-rechtliche Sondervermögen. Verbraucher sind
|
||||||
|
vom Vertragsschluss ausgeschlossen.
|
||||||
|
</p>
|
||||||
|
<p className="leading-7">
|
||||||
|
(3) Abweichende oder entgegenstehende Bedingungen des Kunden
|
||||||
|
werden nicht Vertragsbestandteil, auch wenn wir ihnen nicht
|
||||||
|
ausdrücklich widersprechen. Individuelle Vereinbarungen haben
|
||||||
|
Vorrang vor diesen AGB.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<hr/>
|
||||||
|
|
||||||
|
<section className="space-y-3">
|
||||||
|
<h2 className="text-xl font-semibold">§ 2 Vertragsschluss</h2>
|
||||||
|
<p className="leading-7">
|
||||||
|
(1) Unsere Angebote sind freibleibend, sofern sie nicht
|
||||||
|
ausdrücklich als verbindlich bezeichnet sind. Ein Vertrag kommt
|
||||||
|
durch schriftliche oder in Textform erklärte Annahme des Angebots
|
||||||
|
durch den Kunden oder durch unsere Auftragsbestätigung zustande.
|
||||||
|
</p>
|
||||||
|
<p className="leading-7">
|
||||||
|
(2) Der Leistungsumfang ergibt sich aus dem jeweiligen Angebot
|
||||||
|
bzw. der Auftragsbestätigung. Nachträgliche Änderungen oder
|
||||||
|
Erweiterungen bedürfen der Textform und werden gesondert
|
||||||
|
vergütet, sofern nichts anderes vereinbart ist.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<hr/>
|
||||||
|
|
||||||
|
<section className="space-y-3">
|
||||||
|
<h2 className="text-xl font-semibold">
|
||||||
|
§ 3 Kundenplattform und Zugang
|
||||||
|
</h2>
|
||||||
|
<p className="leading-7">
|
||||||
|
(1) Since3 stellt dem Kunden für die Dauer des Vertragsverhältnisses
|
||||||
|
eine webbasierte Plattform unter app.since3.de zur Verfügung. Dort
|
||||||
|
kann der Kunde insbesondere Stammdaten einsehen und ergänzen,
|
||||||
|
Rechnungen einsehen und herunterladen, Informationen zu den von
|
||||||
|
Since3 erstellten Produkten abrufen, Dokumente hochladen und
|
||||||
|
projektbezogene Zugangsdaten verwalten.
|
||||||
|
</p>
|
||||||
|
<p className="leading-7">
|
||||||
|
(2) Die Konten werden von Since3 angelegt. Der Zugang zur Plattform
|
||||||
|
wird erst freigeschaltet, nachdem der Kunde diese AGB in der
|
||||||
|
Plattform ausdrücklich akzeptiert hat. Wir speichern dazu den
|
||||||
|
Zeitpunkt der Zustimmung und die akzeptierte Version der AGB.
|
||||||
|
</p>
|
||||||
|
<p className="leading-7">
|
||||||
|
(3) Der Kunde hält seine Zugangsdaten zur Plattform geheim, nutzt
|
||||||
|
ein sicheres Passwort. Er informiert Since3 unverzüglich,
|
||||||
|
wenn er den Verdacht hat, dass Dritte Kenntnis von seinen
|
||||||
|
Zugangsdaten erlangt haben. Der Kunde ist dafür verantwortlich, dass
|
||||||
|
nur von ihm autorisierte Personen seines Unternehmens die Plattform
|
||||||
|
nutzen, und haftet für deren Handlungen.
|
||||||
|
</p>
|
||||||
|
<p className="leading-7">
|
||||||
|
(4) Wir bemühen uns um eine hohe Verfügbarkeit der Plattform. Ein Anspruch auf
|
||||||
|
ununterbrochene Verfügbarkeit besteht nicht. Wartungsarbeiten,
|
||||||
|
Störungen bei Drittanbietern und Ereignisse außerhalb unseres
|
||||||
|
Einflussbereichs können zu zeitweisen Einschränkungen führen.
|
||||||
|
</p>
|
||||||
|
<p className="leading-7">
|
||||||
|
(5) Die Plattform ist ein ergänzender Service zu unseren
|
||||||
|
Leistungen und kein Datenarchiv. Der Kunde ist selbst dafür
|
||||||
|
verantwortlich, von ihm hochgeladene Dokumente und wichtige
|
||||||
|
Informationen in eigener Kopie vorzuhalten.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<hr/>
|
||||||
|
|
||||||
|
<section className="space-y-3">
|
||||||
|
<h2 className="text-xl font-semibold">
|
||||||
|
§ 4 Hochgeladene Inhalte und Datenschutz
|
||||||
|
</h2>
|
||||||
|
<p className="leading-7">
|
||||||
|
(1) Der Kunde darf Dokumente und Dateien hochladen, soweit sie für
|
||||||
|
die Zusammenarbeit mit Since3 erforderlich sind. Er versichert, dass
|
||||||
|
er zur Nutzung und Weitergabe dieser Inhalte berechtigt ist und
|
||||||
|
dass diese keine Rechte Dritter verletzen und nicht gegen Gesetze
|
||||||
|
verstoßen.
|
||||||
|
</p>
|
||||||
|
<p className="leading-7">
|
||||||
|
(2) Nicht hochgeladen werden dürfen rechtswidrige Inhalte,
|
||||||
|
Schadsoftware sowie besondere Kategorien personenbezogener Daten
|
||||||
|
im Sinne von Art. 9 DSGVO (z. B. Gesundheitsdaten), es sei denn,
|
||||||
|
es wurde vorher ausdrücklich in Textform etwas anderes mit
|
||||||
|
Since3 vereinbart.
|
||||||
|
</p>
|
||||||
|
<p className="leading-7">
|
||||||
|
(3) Soweit Since3 im Rahmen der Leistungserbringung
|
||||||
|
personenbezogene Daten im Auftrag des Kunden verarbeitet, schließen
|
||||||
|
die Parteien einen Vertrag zur Auftragsverarbeitung nach Art. 28
|
||||||
|
DSGVO. Der Vertrag ist Bestandteil der Kundenvereinbarung.
|
||||||
|
Informationen zur Verarbeitung personenbezogener Daten auf der
|
||||||
|
Plattform enthält die Datenschutzerklärung unter
|
||||||
|
app.since3.de/datenschutz.
|
||||||
|
</p>
|
||||||
|
<p className="leading-7">
|
||||||
|
(4) Der Kunde räumt Since3 die für die Vertragserfüllung
|
||||||
|
erforderlichen, nicht ausschließlichen Nutzungsrechte an den
|
||||||
|
hochgeladenen Inhalten ein, insbesondere zum Speichern,
|
||||||
|
Verarbeiten und Einbinden in die vereinbarten Produkte.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<hr/>
|
||||||
|
|
||||||
|
<section className="space-y-3">
|
||||||
|
<h2 className="text-xl font-semibold">
|
||||||
|
§ 5 Zugangsdaten des Kunden zu Drittsystemen
|
||||||
|
</h2>
|
||||||
|
<p className="leading-7">
|
||||||
|
(1) Soweit der Kunde Since3 Zugangsdaten zu eigenen Systemen oder
|
||||||
|
Konten überlässt (z. B. Hosting, Domain, Shop-System, Social Media,
|
||||||
|
Marketing-Tools), erteilt er Since3 hiermit die ausdrückliche
|
||||||
|
Erlaubnis, diese ausschließlich zur Erbringung der vereinbarten
|
||||||
|
Leistungen zu nutzen.
|
||||||
|
</p>
|
||||||
|
<p className="leading-7">
|
||||||
|
(2) Der Kunde sichert zu, dass er zur Weitergabe der Zugangsdaten
|
||||||
|
berechtigt ist und dass dies nicht gegen Nutzungsbedingungen des
|
||||||
|
jeweiligen Anbieters verstößt. Wo die Anbieter dies vorsehen,
|
||||||
|
stellt der Kunde Since3 bevorzugt einen eigenen Benutzer-,
|
||||||
|
Mitarbeiter- oder Partnerzugang bereit, anstatt die Zugangsdaten
|
||||||
|
des Inhaber-Kontos zu übermitteln.
|
||||||
|
</p>
|
||||||
|
<p className="leading-7">
|
||||||
|
(3) Der Kunde hält die hinterlegten Zugangsdaten aktuell und
|
||||||
|
unterstützt bei Bedarf bei Sicherheitsabfragen, etwa der
|
||||||
|
Bereitstellung von Zwei-Faktor-Codes.
|
||||||
|
</p>
|
||||||
|
<p className="leading-7">
|
||||||
|
(4) Since3 speichert hinterlegte Zugangsdaten verschlüsselt und
|
||||||
|
beschränkt den Zugriff auf die Mitarbeiter, die das jeweilige
|
||||||
|
Projekt betreuen. Since3 verwendet die Zugangsdaten nur im
|
||||||
|
vereinbarten Umfang und gibt sie nicht an Dritte weiter, es sei
|
||||||
|
denn, dies ist für die Leistung erforderlich und vertraglich
|
||||||
|
abgesichert.
|
||||||
|
</p>
|
||||||
|
<p className="leading-7">
|
||||||
|
(5) Nach Beendigung des Vertrags oder Abschluss des Projekts
|
||||||
|
löscht Since3 die hinterlegten Zugangsdaten. Der Kunde ist verpflichtet, die Passwörter der betroffenen
|
||||||
|
Konten nach Vertragsende selbst zu ändern und überlassene
|
||||||
|
Benutzerzugänge zu entziehen.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<hr/>
|
||||||
|
|
||||||
|
<section className="space-y-3">
|
||||||
|
<h2 className="text-xl font-semibold">
|
||||||
|
§ 6 Mitwirkungspflichten des Kunden
|
||||||
|
</h2>
|
||||||
|
<p className="leading-7">
|
||||||
|
(1) Der Kunde stellt Since3 alle für die Leistungserbringung
|
||||||
|
erforderlichen Informationen, Texte, Bilder, Logos, Zugänge und
|
||||||
|
sonstigen Materialien rechtzeitig, vollständig und in geeigneter
|
||||||
|
Form zur Verfügung und benennt einen Ansprechpartner, der
|
||||||
|
Entscheidungen treffen kann.
|
||||||
|
</p>
|
||||||
|
<p className="leading-7">
|
||||||
|
(2) Der Kunde ist für die Rechtmäßigkeit der von ihm gelieferten
|
||||||
|
Inhalte verantwortlich (z. B. Urheber-, Marken- und Bildrechte).
|
||||||
|
Er stellt Since3 von Ansprüchen Dritter frei, die auf der
|
||||||
|
Verletzung solcher Rechte durch die vom Kunden gelieferten Inhalte
|
||||||
|
beruhen.
|
||||||
|
</p>
|
||||||
|
<p className="leading-7">
|
||||||
|
(3) Verzögert sich die Leistung, weil der Kunde Mitwirkungspflichten
|
||||||
|
nicht rechtzeitig erfüllt, verschieben sich vereinbarte Termine
|
||||||
|
entsprechend. Mehraufwand kann gesondert berechnet werden.
|
||||||
|
</p>
|
||||||
|
<p className="leading-7">
|
||||||
|
(4) Rechtliche Anforderungen an die Inhalte der fertigen Produkte
|
||||||
|
(z. B. Impressum, Datenschutzerklärung, Widerrufsbelehrung, AGB
|
||||||
|
des Kunden, Cookie-Einwilligung) liegen in der Verantwortung des
|
||||||
|
Kunden, sofern Since3 keine rechtliche Prüfung oder Erstellung
|
||||||
|
ausdrücklich schriftlich zugesagt hat. Since3 erbringt keine
|
||||||
|
Rechtsberatung.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<hr/>
|
||||||
|
|
||||||
|
<section className="space-y-3">
|
||||||
|
<h2 className="text-xl font-semibold">
|
||||||
|
§ 7 Vergütung und Zahlung
|
||||||
|
</h2>
|
||||||
|
<p className="leading-7">
|
||||||
|
(1) Es gelten die im Angebot bzw. in der Auftragsbestätigung
|
||||||
|
genannten Preise. Alle Preise verstehen sich, soweit nicht anders
|
||||||
|
angegeben, zuzüglich der gesetzlichen Umsatzsteuer.
|
||||||
|
</p>
|
||||||
|
<p className="leading-7">
|
||||||
|
(2) Rechnungen werden über die Plattform bereitgestellt oder per
|
||||||
|
E-Mail versendet und sind, sofern nichts anderes vereinbart ist,
|
||||||
|
innerhalb von 14 Tagen ab Rechnungsdatum ohne Abzug zu zahlen.
|
||||||
|
Die Zahlung erfolgt außerhalb der Plattform per Überweisung.
|
||||||
|
</p>
|
||||||
|
<p className="leading-7">
|
||||||
|
(3) Bei größeren Projekten sind wir berechtigt, Abschlagszahlungen
|
||||||
|
oder eine Anzahlung zu verlangen und die Arbeit bis zum
|
||||||
|
Eingang der Zahlung zurückzustellen.
|
||||||
|
</p>
|
||||||
|
<p className="leading-7">
|
||||||
|
(4) Kosten für Drittanbieter (z. B. Domains, Hosting, Lizenzen,
|
||||||
|
Themes, Plug-ins, Shop- und Tool-Abonnements, Werbebudgets) sind
|
||||||
|
nicht im Preis enthalten und trägt der Kunde, sofern nicht
|
||||||
|
ausdrücklich anders vereinbart. Verträge mit diesen Anbietern
|
||||||
|
schließt der Kunde im eigenen Namen, sofern nichts anderes
|
||||||
|
vereinbart ist.
|
||||||
|
</p>
|
||||||
|
<p className="leading-7">
|
||||||
|
(5) Bei Zahlungsverzug gelten die gesetzlichen Regelungen,
|
||||||
|
einschließlich der Verzugszinsen und der Pauschale nach § 288
|
||||||
|
Abs. 5 BGB. Wir sind berechtigt, nach Mahnung weitere Leistungen
|
||||||
|
zurückzuhalten und den Zugang zur Plattform zu sperren. Die
|
||||||
|
Verpflichtung zur Zahlung bleibt davon unberührt.
|
||||||
|
</p>
|
||||||
|
<p className="leading-7">
|
||||||
|
(6) Aufrechnung und Zurückbehaltungsrechte stehen dem Kunden nur
|
||||||
|
wegen unbestrittener oder rechtskräftig festgestellter Forderungen
|
||||||
|
zu.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<hr/>
|
||||||
|
|
||||||
|
<section className="space-y-3">
|
||||||
|
<h2 className="text-xl font-semibold">
|
||||||
|
§ 8 Abnahme und Mängelrechte
|
||||||
|
</h2>
|
||||||
|
<p className="leading-7">
|
||||||
|
(1) Soweit Since3 ein Werk herstellt (z. B. eine Website oder einen
|
||||||
|
Online-Shop), ist der Kunde zur Abnahme verpflichtet. Die Abnahme
|
||||||
|
gilt als erfolgt, wenn der Kunde das Werk produktiv nutzt.
|
||||||
|
</p>
|
||||||
|
<p className="leading-7">
|
||||||
|
(2) Mängel meldet der Kunde unverzüglich und nachvollziehbar
|
||||||
|
beschrieben in Textform. Wir beseitigen berechtigte Mängel
|
||||||
|
innerhalb angemessener Frist nach unserer Wahl durch
|
||||||
|
Nachbesserung oder Neuherstellung. Schlägt die Nacherfüllung
|
||||||
|
fehl, gelten die gesetzlichen Rechte.
|
||||||
|
</p>
|
||||||
|
<p className="leading-7">
|
||||||
|
(3) Mängelansprüche verjähren nach drei Monaten ab Abnahme. Dies
|
||||||
|
gilt nicht bei Vorsatz, Arglist und in den in § 11 Abs. 2
|
||||||
|
genannten Fällen.
|
||||||
|
</p>
|
||||||
|
<p className="leading-7">
|
||||||
|
(4) Keine Mängel sind Abweichungen, die auf Änderungen durch den
|
||||||
|
Kunden oder Dritte, auf Updates von Drittsystemen (z. B.
|
||||||
|
Shop-System, Browser, Plug-ins) oder auf unterschiedliche
|
||||||
|
Darstellung in Endgeräten im üblichen Rahmen beruhen.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<hr/>
|
||||||
|
|
||||||
|
<section className="space-y-3">
|
||||||
|
<h2 className="text-xl font-semibold">
|
||||||
|
§ 9 Nutzungsrechte und Referenzen
|
||||||
|
</h2>
|
||||||
|
<p className="leading-7">
|
||||||
|
(1) Mit vollständiger Zahlung der vereinbarten Vergütung erhält
|
||||||
|
der Kunde an den von Since3 erstellten Arbeitsergebnissen
|
||||||
|
(Designs, Texte, Grafiken, Code) ein einfaches, zeitlich und
|
||||||
|
räumlich unbeschränktes Nutzungsrecht für den vereinbarten Zweck.
|
||||||
|
Bis dahin dürfen die Arbeitsergebnisse nur zur Ansicht und
|
||||||
|
Abstimmung genutzt werden.
|
||||||
|
</p>
|
||||||
|
<p className="leading-7">
|
||||||
|
(2) Nicht erfasst sind Rechte an Open-Source-Komponenten,
|
||||||
|
Lizenzsoftware und Inhalten Dritter. Hier gelten die jeweiligen
|
||||||
|
Lizenzbedingungen. Since3 weist auf diese auf Anfrage hin.
|
||||||
|
</p>
|
||||||
|
<p className="leading-7">
|
||||||
|
(3) Since3 bleibt berechtigt, Methoden, Werkzeuge und allgemeines
|
||||||
|
Know-how, das bei der Erstellung entsteht, weiter zu verwenden.
|
||||||
|
</p>
|
||||||
|
<p className="leading-7">
|
||||||
|
(4) Since3 darf das Projekt, sofern der Kunde nicht in Textform
|
||||||
|
widerspricht, unter Nennung des Kunden als Referenz (Logo,
|
||||||
|
Screenshots, Link) in der eigenen Werbung nennen.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<hr/>
|
||||||
|
|
||||||
|
<section className="space-y-3">
|
||||||
|
<h2 className="text-xl font-semibold">
|
||||||
|
§ 10 Laufzeit und Kündigung
|
||||||
|
</h2>
|
||||||
|
<p className="leading-7">
|
||||||
|
(1) Projektverträge enden mit vollständiger Leistungserbringung
|
||||||
|
und Abnahme.
|
||||||
|
</p>
|
||||||
|
<p className="leading-7">
|
||||||
|
(2) Dauerschuldverhältnisse (z. B. Wartung, Betreuung, Hosting,
|
||||||
|
laufende Marketingleistungen) haben die im Angebot genannte
|
||||||
|
Mindestlaufzeit. Sie verlängern sich jeweils um den dort genannten
|
||||||
|
Zeitraum, wenn sie nicht mit einer Frist von ein Monat zum Ende
|
||||||
|
der Laufzeit in Textform gekündigt werden.
|
||||||
|
</p>
|
||||||
|
<p className="leading-7">
|
||||||
|
(3) Das Recht zur außerordentlichen Kündigung aus wichtigem Grund
|
||||||
|
bleibt unberührt. Ein wichtiger Grund für Since3 liegt
|
||||||
|
insbesondere vor, wenn der Kunde trotz Mahnung in Zahlungsverzug
|
||||||
|
ist oder gegen § 4 Abs. 2 oder § 5 Abs. 2 verstößt.
|
||||||
|
</p>
|
||||||
|
<p className="leading-7">
|
||||||
|
(4) Mit Vertragsende wird der Zugang zur Plattform gesperrt.
|
||||||
|
Since3 stellt dem Kunden auf Anfrage innerhalb von 30 Tagen nach
|
||||||
|
Vertragsende einen Export seiner hochgeladenen Dokumente bereit.
|
||||||
|
Anschließend werden Daten nach Maßgabe der Datenschutzerklärung
|
||||||
|
und des Vertrags zur Auftragsverarbeitung gelöscht. Gesetzliche
|
||||||
|
Aufbewahrungspflichten, insbesondere für Rechnungen, bleiben
|
||||||
|
unberührt.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<hr/>
|
||||||
|
|
||||||
|
<section className="space-y-3">
|
||||||
|
<h2 className="text-xl font-semibold">§ 11 Haftung</h2>
|
||||||
|
<p className="leading-7">
|
||||||
|
(1) Since3 haftet unbeschränkt bei Vorsatz und grober
|
||||||
|
Fahrlässigkeit sowie für Schäden aus der Verletzung von Leben,
|
||||||
|
Körper oder Gesundheit.
|
||||||
|
</p>
|
||||||
|
<p className="leading-7">
|
||||||
|
(2) Bei leicht fahrlässiger Verletzung einer wesentlichen
|
||||||
|
Vertragspflicht (Kardinalpflicht), also einer Pflicht, deren
|
||||||
|
Erfüllung die ordnungsgemäße Durchführung des Vertrags überhaupt
|
||||||
|
erst ermöglicht und auf deren Einhaltung der Kunde regelmäßig
|
||||||
|
vertrauen darf, ist die Haftung auf den vorhersehbaren,
|
||||||
|
vertragstypischen Schaden begrenzt. Die Haftung ist je Schadensfall
|
||||||
|
begrenzt.
|
||||||
|
</p>
|
||||||
|
<p className="leading-7">
|
||||||
|
(3) Im Übrigen ist die Haftung bei leichter Fahrlässigkeit
|
||||||
|
ausgeschlossen.
|
||||||
|
</p>
|
||||||
|
<p className="leading-7">
|
||||||
|
(4) Die Haftung nach dem Produkthaftungsgesetz, für arglistig
|
||||||
|
verschwiegene Mängel und aus übernommenen Garantien bleibt
|
||||||
|
unberührt.
|
||||||
|
</p>
|
||||||
|
<p className="leading-7">
|
||||||
|
(5) Für Schäden an Daten haftet Since3 nur in Höhe des Aufwands,
|
||||||
|
der bei regelmäßiger und gefahrentsprechender Datensicherung durch
|
||||||
|
den Kunden für die Wiederherstellung entstanden wäre.
|
||||||
|
</p>
|
||||||
|
<p className="leading-7">
|
||||||
|
(6) Since3 haftet nicht für Ausfälle, Änderungen oder Sperrungen
|
||||||
|
bei Drittanbietern (z. B. Hosting, Shop-Systeme, soziale
|
||||||
|
Netzwerke) und nicht für Schäden, die dadurch entstehen, dass der
|
||||||
|
Kunde seine Mitwirkungs- und Sicherheitspflichten (§§ 3, 5, 6)
|
||||||
|
verletzt, etwa durch die Weitergabe von Zugangsdaten an Dritte.
|
||||||
|
</p>
|
||||||
|
<p className="leading-7">
|
||||||
|
(7) Die Haftungsbeschränkungen gelten auch zugunsten der
|
||||||
|
Gesellschafter, Mitarbeiter und Erfüllungsgehilfen von Since3.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<hr/>
|
||||||
|
|
||||||
|
<section className="space-y-3">
|
||||||
|
<h2 className="text-xl font-semibold">§ 12 Vertraulichkeit</h2>
|
||||||
|
<p className="leading-7">
|
||||||
|
Die Parteien behandeln alle im Rahmen der Zusammenarbeit
|
||||||
|
bekanntgewordenen vertraulichen Informationen der jeweils anderen
|
||||||
|
Partei (insbesondere Zugangsdaten, Geschäftsgeheimnisse und
|
||||||
|
Kundendaten) vertraulich und nutzen sie nur zur Vertragserfüllung.
|
||||||
|
Die Pflicht besteht über das Vertragsende hinaus fort.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<hr/>
|
||||||
|
|
||||||
|
<section className="space-y-3">
|
||||||
|
<h2 className="text-xl font-semibold">
|
||||||
|
§ 13 Änderungen dieser AGB
|
||||||
|
</h2>
|
||||||
|
<p className="leading-7">
|
||||||
|
(1) Wir können diese AGB mit Wirkung für die Zukunft ändern, wenn
|
||||||
|
dafür ein sachlicher Grund besteht (z. B. Gesetzesänderung,
|
||||||
|
neue Funktionen der Plattform oder eine Anpassung der
|
||||||
|
Leistungen) und die Änderung für den Kunden zumutbar ist.
|
||||||
|
</p>
|
||||||
|
<p className="leading-7">
|
||||||
|
(2) Über Änderungen informieren wir den Kunden in Textform und
|
||||||
|
über die Plattform. Die geänderten AGB gelten erst, wenn der
|
||||||
|
Kunde ihnen in der Plattform ausdrücklich zustimmt. Stimmt er nicht
|
||||||
|
zu, gelten die bisherigen AGB für bestehende Verträge fort. Wir
|
||||||
|
behalten uns das Recht vor, den Zugang zur Plattform
|
||||||
|
einzuschränken, wenn der Betrieb nach den bisherigen AGB nicht
|
||||||
|
mehr möglich ist.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<hr/>
|
||||||
|
|
||||||
|
<section className="space-y-3">
|
||||||
|
<h2 className="text-xl font-semibold">§ 14 Schlussbestimmungen</h2>
|
||||||
|
<p className="leading-7">
|
||||||
|
(1) Es gilt das Recht der Bundesrepublik Deutschland unter
|
||||||
|
Ausschluss des UN-Kaufrechts (CISG).
|
||||||
|
</p>
|
||||||
|
<p className="leading-7">
|
||||||
|
(2) Ist der Kunde Kaufmann, juristische Person des öffentlichen
|
||||||
|
Rechts oder öffentlich-rechtliches Sondervermögen, ist
|
||||||
|
ausschließlicher Gerichtsstand Steinfurt für alle Streitigkeiten aus dem Vertragsverhältnis.
|
||||||
|
Since3 ist berechtigt, den Kunden auch an seinem allgemeinen
|
||||||
|
Gerichtsstand zu verklagen.
|
||||||
|
</p>
|
||||||
|
<p className="leading-7">
|
||||||
|
(3) Änderungen und Ergänzungen des Vertrags bedürfen der Textform.
|
||||||
|
Das gilt auch für die Aufhebung dieses Textformerfordernisses.
|
||||||
|
</p>
|
||||||
|
<p className="leading-7">
|
||||||
|
(4) Sollten einzelne Bestimmungen dieser AGB ganz oder teilweise
|
||||||
|
unwirksam sein oder werden, bleibt die Wirksamkeit der übrigen
|
||||||
|
Bestimmungen unberührt. An die Stelle der unwirksamen Regelung
|
||||||
|
tritt die gesetzliche Regelung.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<hr/>
|
||||||
|
|
||||||
|
<section className="space-y-3">
|
||||||
|
<h2 className="text-xl font-semibold">Kontakt</h2>
|
||||||
|
<p className="leading-7">
|
||||||
|
Bei Fragen zu diesen AGB erreichen Sie uns unter{" "}
|
||||||
|
<a
|
||||||
|
href="mailto:info@since3.de"
|
||||||
|
className="underline underline-offset-2"
|
||||||
|
>
|
||||||
|
info@since3.de
|
||||||
|
</a>
|
||||||
|
.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default AGB
|
||||||
439
app/(legal)/datenschutz/page.tsx
Normal file
439
app/(legal)/datenschutz/page.tsx
Normal file
|
|
@ -0,0 +1,439 @@
|
||||||
|
import Image from "next/image"
|
||||||
|
import Link from "next/link"
|
||||||
|
|
||||||
|
const Datenschutz = () => {
|
||||||
|
return (
|
||||||
|
<div className="flex min-h-svh flex-col bg-background p-4 sm:p-6">
|
||||||
|
<Link href="/">
|
||||||
|
<Image
|
||||||
|
src="/pictures/since3-logo.svg" alt=""
|
||||||
|
width={1617}
|
||||||
|
height={332}
|
||||||
|
loading="eager"
|
||||||
|
className="h-5 w-auto self-start md:h-6 dark:hidden"/>
|
||||||
|
</Link>
|
||||||
|
<Link href="/">
|
||||||
|
<Image
|
||||||
|
src="/pictures/since3-logo-weiss.svg" alt=""
|
||||||
|
width={1617}
|
||||||
|
height={332}
|
||||||
|
loading="eager"
|
||||||
|
className="hidden h-5 w-auto self-start md:h-6 dark:block"/>
|
||||||
|
</Link>
|
||||||
|
<div className="flex flex-1 flex-col justify-center py-10">
|
||||||
|
<div className="flex flex-1 flex-col justify-center py-10">
|
||||||
|
<div className="mx-auto w-full max-w-3xl space-y-10">
|
||||||
|
<section>
|
||||||
|
<h1 className="mb-6 text-4xl font-semibold">Datenschutzerklärung</h1>
|
||||||
|
<p className="leading-7">
|
||||||
|
Diese Datenschutzerklärung gilt für die Kundenplattform
|
||||||
|
app.since3.de. Informationen zur Marketing-Website since3.de
|
||||||
|
finden Sie in der Datenschutzerklärung unter since3.de/datenschutz.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<hr/>
|
||||||
|
|
||||||
|
{/* ---------------------------------------------------------------- */}
|
||||||
|
{/* VERANTWORTLICHE STELLE */}
|
||||||
|
{/* ---------------------------------------------------------------- */}
|
||||||
|
<section className="space-y-3">
|
||||||
|
<h2 className="text-2xl font-semibold">Verantwortliche Stelle</h2>
|
||||||
|
<p className="leading-7">
|
||||||
|
Verantwortlich für die Datenverarbeitung ist:
|
||||||
|
</p>
|
||||||
|
<div className="space-y-1">
|
||||||
|
<p className="font-medium">Since3 GbR</p>
|
||||||
|
<p>Sandweg 91</p>
|
||||||
|
<p>48565 Steinfurt</p>
|
||||||
|
<p>Vertreten durch: Ben Dalhoff, Rajpreet Singh</p>
|
||||||
|
</div>
|
||||||
|
<div className="space-y-1">
|
||||||
|
<p>
|
||||||
|
<span className="font-medium">Telefon:</span>{" "}
|
||||||
|
+49 176 47601638
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<span className="font-medium">E-Mail:</span>{" "}
|
||||||
|
<a
|
||||||
|
href="mailto:info@since3.de"
|
||||||
|
className="underline underline-offset-2"
|
||||||
|
>
|
||||||
|
info@since3.de
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<p className="leading-7">
|
||||||
|
Verantwortliche Stelle ist die natürliche oder juristische Person,
|
||||||
|
die allein oder gemeinsam mit anderen über die Zwecke und Mittel
|
||||||
|
der Verarbeitung von personenbezogenen Daten (z. B. Namen,
|
||||||
|
E-Mail-Adressen o. Ä.) entscheidet.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<hr/>
|
||||||
|
|
||||||
|
{/* ================================================================ */}
|
||||||
|
{/* TEIL B: APP */}
|
||||||
|
{/* ================================================================ */}
|
||||||
|
<section className="space-y-8">
|
||||||
|
<h2 className="text-3xl font-semibold">
|
||||||
|
Datenverarbeitung auf der Plattform
|
||||||
|
</h2>
|
||||||
|
|
||||||
|
<div className="space-y-3">
|
||||||
|
<h3 className="text-xl font-semibold">Zweck der Plattform</h3>
|
||||||
|
<p className="leading-7">
|
||||||
|
Über die Plattform stellen wir unseren Kunden einen
|
||||||
|
persönlichen Zugang bereit. Dort können Kunden ihre
|
||||||
|
Stammdaten einsehen und ergänzen, Rechnungen einsehen und
|
||||||
|
herunterladen, Informationen zu den von uns erstellten
|
||||||
|
Produkten abrufen, Dokumente hochladen und Zugangsdaten
|
||||||
|
verwalten, die für die Umsetzung ihrer Projekte erforderlich
|
||||||
|
sind.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="space-y-3">
|
||||||
|
<h3 className="text-xl font-semibold">
|
||||||
|
Kontoanlage durch uns (Information nach Art. 14 DSGVO)
|
||||||
|
</h3>
|
||||||
|
<p className="leading-7">
|
||||||
|
Die Konten werden von uns angelegt. Wenn Sie als Mitarbeiter
|
||||||
|
oder Ansprechpartner eines Unternehmens einen Zugang erhalten,
|
||||||
|
haben wir Ihre Kontaktdaten (Name, geschäftliche E-Mail-Adresse,
|
||||||
|
ggf. Funktion) in der Regel von Ihrem Arbeitgeber bzw. dem
|
||||||
|
Auftraggeber erhalten. Wir verarbeiten sie, um Ihnen den Zugang
|
||||||
|
einzurichten und den Vertrag mit Ihrem Unternehmen
|
||||||
|
durchzuführen (Art. 6 Abs. 1 lit. b bzw. lit. f DSGVO).
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="space-y-3">
|
||||||
|
<h3 className="text-xl font-semibold">
|
||||||
|
Verarbeitete Daten, Zwecke und Rechtsgrundlagen
|
||||||
|
</h3>
|
||||||
|
<ul className="list-disc space-y-2 pl-6 leading-7">
|
||||||
|
<li>
|
||||||
|
<span className="font-medium">Stammdaten und Kontaktdaten</span>{" "}
|
||||||
|
(z. B. Name, Firma, Anschrift, E-Mail, Telefon, USt-IdNr.):
|
||||||
|
Vertragsabwicklung und Kommunikation, Art. 6 Abs. 1 lit. b
|
||||||
|
DSGVO.
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<span className="font-medium">Rechnungen und Abrechnungsdaten:</span>{" "}
|
||||||
|
Vertragsabwicklung und gesetzliche Aufbewahrungspflichten,
|
||||||
|
Art. 6 Abs. 1 lit. b und c DSGVO. Zahlungen werden nicht
|
||||||
|
über die Plattform abgewickelt.
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<span className="font-medium">Produkt- und Projektinformationen:</span>{" "}
|
||||||
|
Bereitstellung der von uns erstellten Leistungen, Art. 6
|
||||||
|
Abs. 1 lit. b DSGVO.
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<span className="font-medium">Hochgeladene Dokumente:</span>{" "}
|
||||||
|
Dateien, die Sie zur Projektabwicklung hochladen, Art. 6
|
||||||
|
Abs. 1 lit. b DSGVO.
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<span className="font-medium">Zugangsdaten für Projekte</span>{" "}
|
||||||
|
(z. B. Hosting- oder Shop-Zugänge): ausschließlich zur
|
||||||
|
Durchführung des vereinbarten Projekts, Art. 6 Abs. 1 lit. b
|
||||||
|
DSGVO.
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<span className="font-medium">Login- und Nutzungsdaten</span>{" "}
|
||||||
|
(Anmeldedaten, Zeitpunkt der Anmeldung, IP-Adresse,
|
||||||
|
Zugriffsprotokolle): Betrieb und Sicherheit der Plattform,
|
||||||
|
Art. 6 Abs. 1 lit. f DSGVO.
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="space-y-3">
|
||||||
|
<h3 className="text-xl font-semibold">
|
||||||
|
Unsere Rolle: Verantwortlicher und Auftragsverarbeiter
|
||||||
|
</h3>
|
||||||
|
<p className="leading-7">
|
||||||
|
Bei Ihren Stammdaten, Rechnungen und Login-Daten sind wir
|
||||||
|
Verantwortlicher im Sinne der DSGVO. Enthalten hochgeladene
|
||||||
|
Dokumente oder die Systeme, für die Sie uns Zugangsdaten
|
||||||
|
überlassen (z. B. Shop, Website, Hosting), personenbezogene Daten
|
||||||
|
Dritter, etwa Ihrer Mitarbeiter oder Endkunden, verarbeiten wir
|
||||||
|
diese in Ihrem Auftrag. Dafür schließen wir mit Ihnen einen
|
||||||
|
Vertrag über Auftragsverarbeitung nach Art. 28 DSGVO. Als
|
||||||
|
Auftraggeber sind Sie für die Rechtmäßigkeit dieser
|
||||||
|
Verarbeitung verantwortlich.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="space-y-3">
|
||||||
|
<h3 className="text-xl font-semibold">
|
||||||
|
Login, Session-Cookies und Protokollierung
|
||||||
|
</h3>
|
||||||
|
<p className="leading-7">
|
||||||
|
Für die Anmeldung setzen wir technisch notwendige Cookies bzw.
|
||||||
|
Speicherelemente ein (z. B. Session- und Authentifizierungs-Token).
|
||||||
|
Sie sind erforderlich, damit Sie eingeloggt bleiben und die
|
||||||
|
Plattform sicher nutzen können (§ 25 Abs. 2 Nr. 2 TDDDG). Eine
|
||||||
|
Einwilligung ist dafür nicht erforderlich.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="space-y-3">
|
||||||
|
<h3 className="text-xl font-semibold">
|
||||||
|
Schutz gespeicherter Zugangsdaten
|
||||||
|
</h3>
|
||||||
|
<p className="leading-7">
|
||||||
|
Zugangsdaten, die Sie in der Plattform hinterlegen, speichern wir
|
||||||
|
verschlüsselt. Der Zugriff ist auf Mitarbeiter beschränkt, die
|
||||||
|
das jeweilige Projekt betreuen. Wir empfehlen, uns wo möglich keine
|
||||||
|
Inhaber-Passwörter zu überlassen, sondern einen eigenen
|
||||||
|
Zugang (z. B. Mitarbeiter- oder Partnerzugang) einzurichten,
|
||||||
|
den Sie jederzeit selbst entziehen können.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="space-y-3">
|
||||||
|
<h3 className="text-xl font-semibold">Empfänger und Dienstleister</h3>
|
||||||
|
<p className="leading-7">
|
||||||
|
Wir geben Daten nur weiter, soweit dies zur Vertragserfüllung
|
||||||
|
erforderlich ist, wir gesetzlich dazu verpflichtet sind oder
|
||||||
|
eine Rechtsgrundlage besteht. Für den Betrieb der Plattform
|
||||||
|
setzen wir folgende Auftragsverarbeiter ein, mit denen jeweils
|
||||||
|
ein Vertrag nach Art. 28 DSGVO besteht:
|
||||||
|
</p>
|
||||||
|
<ul className="list-disc space-y-2 pl-6 leading-7">
|
||||||
|
<li>
|
||||||
|
<span className="font-medium">Supabase</span> (Datenbank,
|
||||||
|
Authentifizierung, Dateispeicher und Verschlüsselung von
|
||||||
|
Zugangsdaten). Hosting in der Region EU-Frankfurt. Anbieter: Supabase PTE LTD. 65 Chulia Street #38-02/03, OCBC, Centre, Singapore 049513
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<span className="font-medium">Vercel Inc.</span> (Hosting der
|
||||||
|
Anwendung), 440 Barranca Ave #4133, Covina, CA 91723, USA.
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<span className="font-medium">Plus Five Five Inc.</span>{" "}
|
||||||
|
2261 Market Street #5039 San Francisco, CA 94114
|
||||||
|
(Versand von Einladungs- und Benachrichtigungs-E-Mails).
|
||||||
|
</li>
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
<p className="leading-7">
|
||||||
|
Soweit Dienstleister ihren Sitz in den USA haben oder dort
|
||||||
|
Daten verarbeiten, stützt sich die Übermittlung auf EU-US Data
|
||||||
|
Privacy Framework.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="space-y-3">
|
||||||
|
<h3 className="text-xl font-semibold">Speicherdauer</h3>
|
||||||
|
<ul className="list-disc space-y-2 pl-6 leading-7">
|
||||||
|
<li>
|
||||||
|
<span className="font-medium">Rechnungen und Buchungsbelege:</span>{" "}
|
||||||
|
werden entsprechend den gesetzlichen Aufbewahrungsfristen
|
||||||
|
aufbewahrt. Nach
|
||||||
|
Vertragsende werden diese Daten für andere Zwecke gesperrt.
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<span className="font-medium">Stammdaten:</span> für die
|
||||||
|
Dauer der Geschäftsbeziehung, danach nur noch soweit
|
||||||
|
gesetzliche Aufbewahrungspflichten bestehen oder die Daten
|
||||||
|
zur Geltendmachung oder Abwehr von Rechtsansprüchen
|
||||||
|
erforderlich sind.
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<span className="font-medium">Hochgeladene Dokumente, Produktinformationen und Zugangsdaten:</span>{" "}
|
||||||
|
werden spätestens nach Vertragsende oder Projektabschluss
|
||||||
|
gelöscht, sofern Sie nichts anderes mit uns vereinbaren.
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<span className="font-medium">Backups:</span> Gelöschte
|
||||||
|
Daten können noch bis zu 24h in Sicherungen vorhanden sein und werden danach
|
||||||
|
endgültig entfernt.
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="space-y-3">
|
||||||
|
<h3 className="text-xl font-semibold">
|
||||||
|
Erforderlichkeit der Daten
|
||||||
|
</h3>
|
||||||
|
<p className="leading-7">
|
||||||
|
Die Bereitstellung der Stammdaten und Kontaktdaten ist für den
|
||||||
|
Abschluss und die Durchführung des Vertrags erforderlich.
|
||||||
|
Ohne diese Daten können wir die Plattform nicht bereitstellen
|
||||||
|
und unsere Leistungen nicht erbringen. Hochgeladene Dokumente
|
||||||
|
und Zugangsdaten stellen Sie freiwillig bereit, sie sind aber
|
||||||
|
je nach Projekt für die Umsetzung notwendig.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="space-y-3">
|
||||||
|
<h3 className="text-xl font-semibold">
|
||||||
|
Auskunft und Datenexport
|
||||||
|
</h3>
|
||||||
|
<p className="leading-7">
|
||||||
|
Die meisten Ihrer Daten können Sie direkt in der Plattform
|
||||||
|
einsehen. Für eine vollständige Auskunft, einen Export oder die
|
||||||
|
Löschung Ihrer Daten schreiben Sie uns an{" "}
|
||||||
|
<a
|
||||||
|
href="mailto:info@since3.de"
|
||||||
|
className="underline underline-offset-2"
|
||||||
|
>
|
||||||
|
info@since3.de
|
||||||
|
</a>
|
||||||
|
.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<hr/>
|
||||||
|
|
||||||
|
{/* ================================================================ */}
|
||||||
|
{/* TEIL C: ALLGEMEIN */}
|
||||||
|
{/* ================================================================ */}
|
||||||
|
<section className="space-y-8">
|
||||||
|
<h2 className="text-3xl font-semibold">
|
||||||
|
Allgemeine Hinweise
|
||||||
|
</h2>
|
||||||
|
|
||||||
|
<div className="space-y-3">
|
||||||
|
<h3 className="text-xl font-semibold">
|
||||||
|
Ihre Rechte
|
||||||
|
</h3>
|
||||||
|
<p className="leading-7">
|
||||||
|
Sie haben im Rahmen der gesetzlichen Bestimmungen jederzeit das
|
||||||
|
Recht auf unentgeltliche Auskunft über Ihre gespeicherten
|
||||||
|
personenbezogenen Daten, deren Herkunft und Empfänger und den
|
||||||
|
Zweck der Verarbeitung (Art. 15 DSGVO) sowie auf Berichtigung
|
||||||
|
(Art. 16), Löschung (Art. 17), Einschränkung der Verarbeitung
|
||||||
|
(Art. 18) und Datenübertragbarkeit (Art. 20). Wenden Sie sich
|
||||||
|
dazu jederzeit an uns.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="space-y-3">
|
||||||
|
<h3 className="text-xl font-semibold">
|
||||||
|
Widerruf Ihrer Einwilligung
|
||||||
|
</h3>
|
||||||
|
<p className="leading-7">
|
||||||
|
Viele Verarbeitungsvorgänge sind nur mit Ihrer Einwilligung
|
||||||
|
möglich. Eine erteilte Einwilligung können Sie jederzeit mit
|
||||||
|
Wirkung für die Zukunft widerrufen. Die Rechtmäßigkeit der bis
|
||||||
|
zum Widerruf erfolgten Verarbeitung bleibt unberührt.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="space-y-3">
|
||||||
|
<h3 className="text-xl font-semibold">
|
||||||
|
Widerspruchsrecht (Art. 21 DSGVO)
|
||||||
|
</h3>
|
||||||
|
<p className="text-sm leading-7 uppercase">
|
||||||
|
Wenn die Datenverarbeitung auf Grundlage von Art. 6 Abs. 1 lit.
|
||||||
|
e oder f DSGVO erfolgt, haben Sie jederzeit das Recht, aus
|
||||||
|
Gründen, die sich aus Ihrer besonderen Situation ergeben, gegen
|
||||||
|
die Verarbeitung Ihrer personenbezogenen Daten Widerspruch
|
||||||
|
einzulegen. Wir verarbeiten die betroffenen Daten dann nicht
|
||||||
|
mehr, es sei denn, wir können zwingende schutzwürdige Gründe
|
||||||
|
für die Verarbeitung nachweisen, die Ihre Interessen, Rechte
|
||||||
|
und Freiheiten überwiegen, oder die Verarbeitung dient der
|
||||||
|
Geltendmachung, Ausübung oder Verteidigung von
|
||||||
|
Rechtsansprüchen.
|
||||||
|
</p>
|
||||||
|
<p className="text-sm leading-7 uppercase">
|
||||||
|
Werden Ihre personenbezogenen Daten verarbeitet, um
|
||||||
|
Direktwerbung zu betreiben, haben Sie das Recht, jederzeit
|
||||||
|
Widerspruch gegen die Verarbeitung Sie betreffender
|
||||||
|
personenbezogener Daten zum Zwecke derartiger Werbung
|
||||||
|
einzulegen.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="space-y-3">
|
||||||
|
<h3 className="text-xl font-semibold">
|
||||||
|
Recht auf Einschränkung der Verarbeitung
|
||||||
|
</h3>
|
||||||
|
<p className="leading-7">
|
||||||
|
Sie können die Einschränkung der Verarbeitung Ihrer
|
||||||
|
personenbezogenen Daten verlangen, insbesondere wenn:
|
||||||
|
</p>
|
||||||
|
<ul className="list-disc space-y-2 pl-6 leading-7">
|
||||||
|
<li>Sie die Richtigkeit der Daten bestreiten (für die Dauer der Prüfung).</li>
|
||||||
|
<li>
|
||||||
|
die Verarbeitung unrechtmäßig ist und Sie statt der
|
||||||
|
Löschung die Einschränkung verlangen.
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
wir die Daten nicht mehr benötigen, Sie sie aber zur
|
||||||
|
Geltendmachung, Ausübung oder Verteidigung von
|
||||||
|
Rechtsansprüchen brauchen.
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
Sie Widerspruch nach Art. 21 Abs. 1 DSGVO eingelegt haben und
|
||||||
|
noch nicht feststeht, wessen Interessen überwiegen.
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="space-y-3">
|
||||||
|
<h3 className="text-xl font-semibold">
|
||||||
|
Beschwerderecht bei der Aufsichtsbehörde
|
||||||
|
</h3>
|
||||||
|
<p className="leading-7">
|
||||||
|
Im Falle von Verstößen gegen die DSGVO steht Ihnen ein
|
||||||
|
Beschwerderecht bei einer Aufsichtsbehörde zu, insbesondere in
|
||||||
|
dem Mitgliedstaat Ihres gewöhnlichen Aufenthalts, Ihres
|
||||||
|
Arbeitsplatzes oder des Orts des mutmaßlichen Verstoßes. Für uns
|
||||||
|
zuständig ist die Landesbeauftragte für Datenschutz und
|
||||||
|
Informationsfreiheit Nordrhein-Westfalen, Kavalleriestraße 2–4,
|
||||||
|
40213 Düsseldorf
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="space-y-3">
|
||||||
|
<h3 className="text-xl font-semibold">
|
||||||
|
SSL- bzw. TLS-Verschlüsselung
|
||||||
|
</h3>
|
||||||
|
<p className="leading-7">
|
||||||
|
Diese Plattform nutzt aus Sicherheitsgründen und
|
||||||
|
zum Schutz der Übertragung vertraulicher Inhalte eine SSL- bzw.
|
||||||
|
TLS-Verschlüsselung. Eine verschlüsselte Verbindung erkennen Sie
|
||||||
|
daran, dass die Adresszeile des Browsers von „http://“ auf
|
||||||
|
„https://“ wechselt und am Schloss-Symbol in Ihrer Browserzeile.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="space-y-3">
|
||||||
|
<h3 className="text-xl font-semibold">Stand und Änderungen</h3>
|
||||||
|
<p className="leading-7">
|
||||||
|
Stand: 01 Okt 2026. Wir passen diese Datenschutzerklärung
|
||||||
|
an, wenn sich unsere Verarbeitungen oder die rechtlichen
|
||||||
|
Vorgaben ändern.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<hr/>
|
||||||
|
|
||||||
|
<p className="text-sm">
|
||||||
|
Quelle:{" "}
|
||||||
|
<a
|
||||||
|
href="https://www.e-recht24.de"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
className="underline underline-offset-2"
|
||||||
|
>
|
||||||
|
e-recht24.de
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Datenschutz
|
||||||
107
app/(legal)/impressum/page.tsx
Normal file
107
app/(legal)/impressum/page.tsx
Normal file
|
|
@ -0,0 +1,107 @@
|
||||||
|
import Image from "next/image"
|
||||||
|
import Link from "next/link"
|
||||||
|
|
||||||
|
const Impressum = () => {
|
||||||
|
return (
|
||||||
|
<div className="flex min-h-svh flex-col bg-background p-4 sm:p-6">
|
||||||
|
<Link href="/">
|
||||||
|
<Image
|
||||||
|
src="/pictures/since3-logo.svg" alt=""
|
||||||
|
width={1617}
|
||||||
|
height={332}
|
||||||
|
loading="eager"
|
||||||
|
className="h-5 w-auto self-start md:h-6 dark:hidden"/>
|
||||||
|
</Link>
|
||||||
|
<Link href="/">
|
||||||
|
<Image
|
||||||
|
src="/pictures/since3-logo-weiss.svg" alt=""
|
||||||
|
width={1617}
|
||||||
|
height={332}
|
||||||
|
loading="eager"
|
||||||
|
className="hidden h-5 w-auto self-start md:h-6 dark:block"/>
|
||||||
|
</Link>
|
||||||
|
<div className="flex flex-1 flex-col justify-center py-10">
|
||||||
|
<div className="mx-auto w-full max-w-3xl space-y-10">
|
||||||
|
<section>
|
||||||
|
<h1 className="mb-6 text-4xl font-semibold">Impressum</h1>
|
||||||
|
|
||||||
|
<div className="space-y-1">
|
||||||
|
<p className="font-medium">Since3 GbR</p>
|
||||||
|
<p>Sandweg 91</p>
|
||||||
|
<p>48565 Steinfurt</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="mt-5">
|
||||||
|
<p className="font-medium">Vertreten durch:</p>
|
||||||
|
<p>Ben Dalhoff, Rajpreet Singh</p>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<hr/>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<h2 className="mb-3 text-xl font-semibold">Kontakt</h2>
|
||||||
|
|
||||||
|
<div className="space-y-1">
|
||||||
|
<p>
|
||||||
|
<span className="font-medium">Telefon:</span>{" "}
|
||||||
|
+49 176 47601638
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<span className="font-medium">E-Mail:</span>{" "}
|
||||||
|
<a
|
||||||
|
href="mailto:info@since3.de"
|
||||||
|
className="underline underline-offset-2 "
|
||||||
|
>
|
||||||
|
info@since3.de
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<hr/>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<h2 className="mb-3 text-xl font-semibold">
|
||||||
|
Redaktionell verantwortlich
|
||||||
|
</h2>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Ben Dalhoff, Rajpreet Singh
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<hr/>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<h2 className="mb-3 text-xl font-semibold">
|
||||||
|
Verbraucherstreitbeilegung / Universalschlichtungsstelle
|
||||||
|
</h2>
|
||||||
|
|
||||||
|
<p className="leading-7">
|
||||||
|
Wir sind nicht bereit oder verpflichtet, an
|
||||||
|
Streitbeilegungsverfahren vor einer
|
||||||
|
Verbraucherschlichtungsstelle teilzunehmen.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<hr/>
|
||||||
|
|
||||||
|
<p className="text-sm ">
|
||||||
|
Quelle:{" "}
|
||||||
|
<a
|
||||||
|
href="https://www.e-recht24.de"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
className="underline underline-offset-2 "
|
||||||
|
>
|
||||||
|
e-recht24.de
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Impressum
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
const TermsPage = () => {
|
|
||||||
return (
|
|
||||||
<div className="mx-auto max-w-2xl px-4 py-8 sm:p-8">
|
|
||||||
<h1 className="mb-4 text-2xl font-semibold">Nutzungsbedingungen</h1>
|
|
||||||
<p className="text-muted-foreground">
|
|
||||||
TODO: Nutzungsbedingungen einfügen.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default TermsPage
|
|
||||||
7
lib/supabase/migrations/20261001100000_client_status.sql
Normal file
7
lib/supabase/migrations/20261001100000_client_status.sql
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
-- Projektstatus pro Client, wird vom Admin in der Clients-Übersicht gesetzt.
|
||||||
|
-- Ändern dürfen nur Admins (bestehende Policy profiles_admin_update).
|
||||||
|
|
||||||
|
create type public.client_status as enum ('upcoming', 'current', 'done');
|
||||||
|
|
||||||
|
alter table public.profiles
|
||||||
|
add column if not exists status public.client_status not null default 'upcoming';
|
||||||
|
|
@ -7,6 +7,7 @@ import { createClient } from "@/lib/supabase/server";
|
||||||
import { verifySession } from "@/lib/supabase/dal";
|
import { verifySession } from "@/lib/supabase/dal";
|
||||||
import { generatePassword } from "@/lib/generate-password";
|
import { generatePassword } from "@/lib/generate-password";
|
||||||
import { MIN_PASSWORD_LENGTH } from "@/modules/admin/lib/constants";
|
import { MIN_PASSWORD_LENGTH } from "@/modules/admin/lib/constants";
|
||||||
|
import { CLIENT_STATUSES } from "@/modules/admin/lib/client-status";
|
||||||
|
|
||||||
export type ResetPasswordState = { error: string } | { success: true; password: string } | undefined;
|
export type ResetPasswordState = { error: string } | { success: true; password: string } | undefined;
|
||||||
export type UpdateClientState = { error: string } | { success: true } | undefined;
|
export type UpdateClientState = { error: string } | { success: true } | undefined;
|
||||||
|
|
@ -88,3 +89,21 @@ export async function updateClientAccount(_prev: UpdateClientState, formData: Fo
|
||||||
revalidatePath(`/admin/clients/${profileId}`, "layout");
|
revalidatePath(`/admin/clients/${profileId}`, "layout");
|
||||||
return { success: true };
|
return { success: true };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const StatusSchema = z.enum(CLIENT_STATUSES, { error: "Bitte einen gültigen Status wählen." });
|
||||||
|
|
||||||
|
export async function updateClientStatus(_prev: UpdateClientState, formData: FormData): Promise<UpdateClientState> {
|
||||||
|
const profileId = String(formData.get("profileId") ?? "");
|
||||||
|
const denied = await assertClientTarget(profileId);
|
||||||
|
if (denied) return denied;
|
||||||
|
|
||||||
|
const parsed = StatusSchema.safeParse(formData.get("status"));
|
||||||
|
if (!parsed.success) return { error: parsed.error.issues[0]?.message ?? "Ungültige Eingabe." };
|
||||||
|
|
||||||
|
const supabase = await createClient();
|
||||||
|
const { error } = await supabase.from("profiles").update({ status: parsed.data }).eq("id", profileId);
|
||||||
|
if (error) return { error: "Status konnte nicht gespeichert werden." };
|
||||||
|
|
||||||
|
revalidatePath("/admin/clients");
|
||||||
|
return { success: true };
|
||||||
|
}
|
||||||
|
|
|
||||||
9
modules/admin/lib/client-status.ts
Normal file
9
modules/admin/lib/client-status.ts
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
export const CLIENT_STATUSES = ["upcoming", "current", "done"] as const;
|
||||||
|
|
||||||
|
export type ClientStatus = (typeof CLIENT_STATUSES)[number];
|
||||||
|
|
||||||
|
export const CLIENT_STATUS_CONFIG: Record<ClientStatus, { label: string; variant: "neutral" | "warning" | "success" }> = {
|
||||||
|
upcoming: { label: "Upcoming", variant: "neutral" },
|
||||||
|
current: { label: "Current", variant: "warning" },
|
||||||
|
done: { label: "Done", variant: "success" },
|
||||||
|
};
|
||||||
|
|
@ -1,15 +1,16 @@
|
||||||
import "server-only"
|
import "server-only"
|
||||||
import { createAdminClient } from "@/lib/supabase/admin"
|
import { createAdminClient } from "@/lib/supabase/admin"
|
||||||
|
import type { ClientStatus } from "@/modules/admin/lib/client-status"
|
||||||
|
|
||||||
export async function getClients() {
|
export async function getClients() {
|
||||||
const supabase = createAdminClient()
|
const supabase = createAdminClient()
|
||||||
const { data, error } = await supabase
|
const { data, error } = await supabase
|
||||||
.from("profiles")
|
.from("profiles")
|
||||||
.select("id, name, email")
|
.select("id, name, email, status")
|
||||||
.eq("role", "client")
|
.eq("role", "client")
|
||||||
.order("name")
|
.order("name")
|
||||||
|
|
||||||
if (error) throw new Error(`Failed to load clients: ${error.message}`)
|
if (error) throw new Error(`Failed to load clients: ${error.message}`)
|
||||||
|
|
||||||
return data
|
return data as { id: string; name: string; email: string; status: ClientStatus }[]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,19 @@
|
||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { useActionState, useState } from "react";
|
import { useActionState, useState } from "react";
|
||||||
import { KeyRoundIcon, MoreHorizontalIcon, PencilIcon } from "lucide-react";
|
import { Info, KeyRoundIcon, MoreHorizontalIcon, PencilIcon } from "lucide-react";
|
||||||
|
import { Badge } from "@/components/ui/badge";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from "@/components/ui/dialog";
|
import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from "@/components/ui/dialog";
|
||||||
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "@/components/ui/dropdown-menu";
|
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "@/components/ui/dropdown-menu";
|
||||||
import { Field, FieldDescription, FieldGroup, FieldLabel } from "@/components/ui/field";
|
import { Field, FieldDescription, FieldGroup, FieldLabel } from "@/components/ui/field";
|
||||||
import { Input } from "@/components/ui/input";
|
import { Input } from "@/components/ui/input";
|
||||||
import { resetClientPassword, updateClientAccount } from "@/modules/admin/actions/manage-client";
|
import { resetClientPassword, updateClientAccount, updateClientStatus } from "@/modules/admin/actions/manage-client";
|
||||||
|
import { CLIENT_STATUSES, CLIENT_STATUS_CONFIG, type ClientStatus } from "@/modules/admin/lib/client-status";
|
||||||
import { MIN_PASSWORD_LENGTH } from "@/modules/admin/lib/constants";
|
import { MIN_PASSWORD_LENGTH } from "@/modules/admin/lib/constants";
|
||||||
import { CopyField } from "./copy-field";
|
import { CopyField } from "./copy-field";
|
||||||
|
|
||||||
type Client = { id: string; name: string; email: string };
|
type Client = { id: string; name: string; email: string; status: ClientStatus };
|
||||||
|
|
||||||
function ResetPasswordContent({ client, onDone }: { client: Client; onDone: () => void }) {
|
function ResetPasswordContent({ client, onDone }: { client: Client; onDone: () => void }) {
|
||||||
const [mode, setMode] = useState<"generate" | "manual">("generate");
|
const [mode, setMode] = useState<"generate" | "manual">("generate");
|
||||||
|
|
@ -133,8 +135,60 @@ function EditClientContent({ client, onDone }: { client: Client; onDone: () => v
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function StatusClientContent({ client, onDone }: { client: Client; onDone: () => void }) {
|
||||||
|
const [status, setStatus] = useState<ClientStatus>(client.status);
|
||||||
|
|
||||||
|
async function run(prev: Parameters<typeof updateClientStatus>[0], formData: FormData) {
|
||||||
|
const result = await updateClientStatus(prev, formData);
|
||||||
|
if (result && "success" in result) onDone();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
const [state, formAction, pending] = useActionState(run, undefined);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<DialogHeader className="mb-4">
|
||||||
|
<DialogTitle>Status ändern</DialogTitle>
|
||||||
|
<DialogDescription>
|
||||||
|
Projektstatus von <span className="font-medium text-foreground">{client.name}</span>.
|
||||||
|
</DialogDescription>
|
||||||
|
</DialogHeader>
|
||||||
|
<form action={formAction}>
|
||||||
|
<input type="hidden" name="profileId" value={client.id} />
|
||||||
|
<FieldGroup>
|
||||||
|
<div role="radiogroup" aria-label="Status" className="grid gap-2">
|
||||||
|
{CLIENT_STATUSES.map((value) => (
|
||||||
|
<label
|
||||||
|
key={value}
|
||||||
|
className="flex cursor-pointer items-center gap-3 rounded-md border border-border px-3 py-2.5 text-sm has-checked:border-primary has-checked:bg-surface"
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
type="radio"
|
||||||
|
name="status"
|
||||||
|
value={value}
|
||||||
|
checked={status === value}
|
||||||
|
onChange={() => setStatus(value)}
|
||||||
|
className="accent-primary"
|
||||||
|
/>
|
||||||
|
<Badge variant={CLIENT_STATUS_CONFIG[value].variant}>{CLIENT_STATUS_CONFIG[value].label}</Badge>
|
||||||
|
</label>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
{state && "error" in state && <p className="text-sm text-destructive">{state.error}</p>}
|
||||||
|
</FieldGroup>
|
||||||
|
<DialogFooter className="mt-6">
|
||||||
|
<Button type="submit" disabled={pending || status === client.status}>
|
||||||
|
{pending ? "Wird gespeichert..." : "Speichern"}
|
||||||
|
</Button>
|
||||||
|
</DialogFooter>
|
||||||
|
</form>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export function ClientActionsMenu({ client }: { client: Client }) {
|
export function ClientActionsMenu({ client }: { client: Client }) {
|
||||||
const [dialog, setDialog] = useState<"password" | "edit" | null>(null);
|
const [dialog, setDialog] = useState<"password" | "edit" | "status" | null>(null);
|
||||||
const [instanceKey, setInstanceKey] = useState(0);
|
const [instanceKey, setInstanceKey] = useState(0);
|
||||||
|
|
||||||
function close() {
|
function close() {
|
||||||
|
|
@ -149,6 +203,9 @@ export function ClientActionsMenu({ client }: { client: Client }) {
|
||||||
<MoreHorizontalIcon />
|
<MoreHorizontalIcon />
|
||||||
</DropdownMenuTrigger>
|
</DropdownMenuTrigger>
|
||||||
<DropdownMenuContent align="end" className="w-52">
|
<DropdownMenuContent align="end" className="w-52">
|
||||||
|
<DropdownMenuItem onClick={() => setDialog("status")}>
|
||||||
|
<Info/> Status ändern
|
||||||
|
</DropdownMenuItem>
|
||||||
<DropdownMenuItem onClick={() => setDialog("edit")}>
|
<DropdownMenuItem onClick={() => setDialog("edit")}>
|
||||||
<PencilIcon /> Bearbeiten
|
<PencilIcon /> Bearbeiten
|
||||||
</DropdownMenuItem>
|
</DropdownMenuItem>
|
||||||
|
|
@ -162,6 +219,7 @@ export function ClientActionsMenu({ client }: { client: Client }) {
|
||||||
<DialogContent>
|
<DialogContent>
|
||||||
{dialog === "password" && <ResetPasswordContent key={instanceKey} client={client} onDone={close} />}
|
{dialog === "password" && <ResetPasswordContent key={instanceKey} client={client} onDone={close} />}
|
||||||
{dialog === "edit" && <EditClientContent key={instanceKey} client={client} onDone={close} />}
|
{dialog === "edit" && <EditClientContent key={instanceKey} client={client} onDone={close} />}
|
||||||
|
{dialog === "status" && <StatusClientContent key={instanceKey} client={client} onDone={close}/> }
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
</>
|
</>
|
||||||
|
|
|
||||||
|
|
@ -16,26 +16,16 @@ import { Badge } from "@/components/ui/badge";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { InputGroup, InputGroupAddon, InputGroupInput } from "@/components/ui/input-group";
|
import { InputGroup, InputGroupAddon, InputGroupInput } from "@/components/ui/input-group";
|
||||||
import { AddClientDialog } from "./add-client-dialog";
|
import { AddClientDialog } from "./add-client-dialog";
|
||||||
|
import { CLIENT_STATUS_CONFIG, type ClientStatus } from "@/modules/admin/lib/client-status";
|
||||||
import { ClientActionsMenu } from "./client-actions-menu";
|
import { ClientActionsMenu } from "./client-actions-menu";
|
||||||
|
|
||||||
type Client = {
|
type Client = {
|
||||||
id: string;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
email: string;
|
email: string;
|
||||||
|
status: ClientStatus;
|
||||||
};
|
};
|
||||||
|
|
||||||
const STATUS_CONFIG = {
|
|
||||||
current: { label: "Current", variant: "warning" as const },
|
|
||||||
done: { label: "Done", variant: "success" as const },
|
|
||||||
upcoming: { label: "Upcoming", variant: "neutral" as const },
|
|
||||||
};
|
|
||||||
|
|
||||||
// TODO: Status kommt aktuell nicht aus der DB, sobald Projekte existieren durch echten Wert ersetzen.
|
|
||||||
function getPlaceholderStatus(index: number): keyof typeof STATUS_CONFIG {
|
|
||||||
const statuses: (keyof typeof STATUS_CONFIG)[] = ["current", "done", "upcoming"];
|
|
||||||
return statuses[index % statuses.length];
|
|
||||||
}
|
|
||||||
|
|
||||||
export function ClientsTable({ clients }: { clients: Client[] }) {
|
export function ClientsTable({ clients }: { clients: Client[] }) {
|
||||||
const [query, setQuery] = useState("");
|
const [query, setQuery] = useState("");
|
||||||
|
|
||||||
|
|
@ -81,8 +71,7 @@ export function ClientsTable({ clients }: { clients: Client[] }) {
|
||||||
</TableHeader>
|
</TableHeader>
|
||||||
<TableBody>
|
<TableBody>
|
||||||
{filteredClients.map((client) => {
|
{filteredClients.map((client) => {
|
||||||
const index = clients.indexOf(client);
|
const status = CLIENT_STATUS_CONFIG[client.status];
|
||||||
const status = STATUS_CONFIG[getPlaceholderStatus(index)];
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TableRow key={client.id}>
|
<TableRow key={client.id}>
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ import { Input } from "@/components/ui/input"
|
||||||
import Image from "next/image"
|
import Image from "next/image"
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { login } from "../../actions/auth";
|
import { login } from "../../actions/auth";
|
||||||
|
import Link from "next/link";
|
||||||
|
|
||||||
const LoginPageView = () => {
|
const LoginPageView = () => {
|
||||||
const [showPassword, setShowPassword] = useState(false)
|
const [showPassword, setShowPassword] = useState(false)
|
||||||
|
|
@ -72,8 +73,13 @@ const LoginPageView = () => {
|
||||||
</FieldGroup>
|
</FieldGroup>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div className="w-full flex items-center justify-between">
|
||||||
<p className="text-center text-muted-foreground text-sm sm:text-left">Bei Fragen: <a href="mailto:info@since3.de" className="underline">info@since3.de</a></p>
|
<p className="text-center text-muted-foreground text-sm sm:text-left">Bei Fragen: <a href="mailto:info@since3.de" className="underline">info@since3.de</a></p>
|
||||||
|
<div className="flex gap-4 text-sm">
|
||||||
|
<Link href="/impressum" className="hover:underline cursor-pointer">Impressum</Link>
|
||||||
|
<Link href="/datenschutz" className="hover:underline cursor-pointer">Datenschutz</Link>
|
||||||
|
<Link href="/agb" className="hover:underline cursor-pointer">AGB</Link>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ import { LogoutButton } from "./logout-button";
|
||||||
import { SidebarMenuLink } from "./sidebar-menu-link";
|
import { SidebarMenuLink } from "./sidebar-menu-link";
|
||||||
import { ThemeToggle } from "./theme-toggle";
|
import { ThemeToggle } from "./theme-toggle";
|
||||||
import UserBadge from "./user-badge";
|
import UserBadge from "./user-badge";
|
||||||
|
import LegalButton from "./legal-button";
|
||||||
|
|
||||||
export function AppSidebar({ session }: { session: Session }) {
|
export function AppSidebar({ session }: { session: Session }) {
|
||||||
const menu = session.isAdmin ? adminMenu : clientMenu;
|
const menu = session.isAdmin ? adminMenu : clientMenu;
|
||||||
|
|
@ -60,6 +61,7 @@ export function AppSidebar({ session }: { session: Session }) {
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<LogoutButton />
|
<LogoutButton />
|
||||||
<ThemeToggle />
|
<ThemeToggle />
|
||||||
|
<LegalButton/>
|
||||||
</div>
|
</div>
|
||||||
</SidebarFooter>
|
</SidebarFooter>
|
||||||
<SidebarRail />
|
<SidebarRail />
|
||||||
|
|
|
||||||
23
modules/shared/ui/components/legal-button.tsx
Normal file
23
modules/shared/ui/components/legal-button.tsx
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
import { Button } from "@/components/ui/button"
|
||||||
|
import { DropdownMenu, DropdownMenuContent, DropdownMenuGroup, DropdownMenuLabel, DropdownMenuTrigger } from "@/components/ui/dropdown-menu"
|
||||||
|
import { Scale } from "lucide-react"
|
||||||
|
import Link from "next/link"
|
||||||
|
|
||||||
|
const LegalButton = () => {
|
||||||
|
return (
|
||||||
|
<DropdownMenu>
|
||||||
|
<DropdownMenuTrigger render={<Button variant="outline"/>}>
|
||||||
|
<Scale/>
|
||||||
|
</DropdownMenuTrigger>
|
||||||
|
<DropdownMenuContent>
|
||||||
|
<DropdownMenuGroup>
|
||||||
|
<DropdownMenuLabel><Link href="/impressum" className="hover:underline hover:text-black">Impressum</Link></DropdownMenuLabel>
|
||||||
|
<DropdownMenuLabel><Link href="/datenschutz" className="hover:underline hover:text-black">Datenschutz</Link></DropdownMenuLabel>
|
||||||
|
<DropdownMenuLabel><Link href="/agb" className="hover:underline hover:text-black">AGB</Link></DropdownMenuLabel>
|
||||||
|
</DropdownMenuGroup>
|
||||||
|
</DropdownMenuContent>
|
||||||
|
</DropdownMenu>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default LegalButton
|
||||||
|
|
@ -40,7 +40,7 @@ export function TermsDialog() {
|
||||||
<DialogTitle>Nutzungsbedingungen</DialogTitle>
|
<DialogTitle>Nutzungsbedingungen</DialogTitle>
|
||||||
<DialogDescription>
|
<DialogDescription>
|
||||||
Bitte lies unsere{" "}
|
Bitte lies unsere{" "}
|
||||||
<a href="/terms" target="_blank" rel="noopener noreferrer">
|
<a href="/agb" target="_blank" rel="noopener noreferrer" className="underline">
|
||||||
Nutzungsbedingungen
|
Nutzungsbedingungen
|
||||||
</a>{" "}
|
</a>{" "}
|
||||||
und akzeptiere sie, um fortzufahren.
|
und akzeptiere sie, um fortzufahren.
|
||||||
|
|
|
||||||
2
proxy.ts
2
proxy.ts
|
|
@ -2,7 +2,7 @@ import { NextRequest, NextResponse } from "next/server";
|
||||||
import { createClient } from "./lib/supabase/proxy";
|
import { createClient } from "./lib/supabase/proxy";
|
||||||
|
|
||||||
|
|
||||||
const publicRoutes = ["/"]
|
const publicRoutes = ["/", "/impressum", "/datenschutz", "/agb"]
|
||||||
|
|
||||||
export default async function proxy(request: NextRequest) {
|
export default async function proxy(request: NextRequest) {
|
||||||
const { supabase, response } = createClient(request)
|
const { supabase, response } = createClient(request)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue