feat(compliance): P-01b Mobile/PWA-Zugriff auf Rechtstexte via Einstellungen
Some checks failed
Deploy Development / deploy (push) Successful in 34s
Test Suite / pytest-backend (push) Successful in 32s
Test Suite / lint-backend (push) Successful in 0s
Test Suite / build-frontend (push) Successful in 8s
Test Suite / playwright-tests (push) Failing after 49s
Some checks failed
Deploy Development / deploy (push) Successful in 34s
Test Suite / pytest-backend (push) Successful in 32s
Test Suite / lint-backend (push) Successful in 0s
Test Suite / build-frontend (push) Successful in 8s
Test Suite / playwright-tests (push) Failing after 49s
- SettingsLegalPage.jsx: neue Hub-Seite /settings/legal mit allen 4 Rechtstext-Links - App.jsx: Route /settings/legal in ProtectedLayout registriert - AccountSettingsPage.jsx: Link zu /settings/legal unterhalb System-Info - 3 Playwright-Tests für P-01b (Einstellungen → Rechtliches → Links → Routen) - Version: 0.8.69 → 0.8.70 (backend + frontend) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
75d6a40817
commit
8261fa4420
|
|
@ -1,6 +1,6 @@
|
|||
# Shinkan Jinkendo Version Information
|
||||
|
||||
APP_VERSION = "0.8.69"
|
||||
APP_VERSION = "0.8.70"
|
||||
BUILD_DATE = "2026-05-10"
|
||||
DB_SCHEMA_VERSION = "20260508049"
|
||||
|
||||
|
|
@ -29,6 +29,13 @@ MODULE_VERSIONS = {
|
|||
}
|
||||
|
||||
CHANGELOG = [
|
||||
{
|
||||
"version": "0.8.70",
|
||||
"date": "2026-05-10",
|
||||
"changes": [
|
||||
"Compliance P-01b: Einstellungen/Rechtliches (/settings/legal) fuer mobile/PWA-Darstellung; Hub mit Links zu Impressum, Datenschutz, Nutzungsbedingungen, Medienrichtlinie",
|
||||
],
|
||||
},
|
||||
{
|
||||
"version": "0.8.69",
|
||||
"date": "2026-05-10",
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ import AdminHomeRedirect from './components/AdminHomeRedirect'
|
|||
import PlatformAdminRoute from './components/PlatformAdminRoute'
|
||||
import MediaLibraryPage from './pages/MediaLibraryPage'
|
||||
import LegalPage from './pages/LegalPage'
|
||||
import SettingsLegalPage from './pages/SettingsLegalPage'
|
||||
import ActiveClubSwitcher from './components/ActiveClubSwitcher'
|
||||
import InactiveMembershipBanner from './components/InactiveMembershipBanner'
|
||||
import './app.css'
|
||||
|
|
@ -183,6 +184,7 @@ function AppRoutes() {
|
|||
<Route path="profile" element={<Navigate to="/settings" replace />} />
|
||||
<Route path="settings" element={<AccountSettingsPage />} />
|
||||
<Route path="settings/system" element={<SettingsSystemInfoPage />} />
|
||||
<Route path="settings/legal" element={<SettingsLegalPage />} />
|
||||
<Route path="media" element={<MediaLibraryPage />} />
|
||||
<Route path="exercises">
|
||||
<Route index element={<ExercisesListPage />} />
|
||||
|
|
|
|||
|
|
@ -426,6 +426,10 @@ function AccountSettingsPage() {
|
|||
<Link to="/settings/system">Technische Systeminformationen</Link>
|
||||
{' — App-Version, Build, Umgebung, Datenbankschema'}
|
||||
</p>
|
||||
<p className="muted" style={{ marginTop: '0.6rem', fontSize: '0.875rem', lineHeight: 1.5 }}>
|
||||
<Link to="/settings/legal">Rechtliches</Link>
|
||||
{' — Impressum, Datenschutz, Nutzungsbedingungen, Medienrichtlinie'}
|
||||
</p>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
66
frontend/src/pages/SettingsLegalPage.jsx
Normal file
66
frontend/src/pages/SettingsLegalPage.jsx
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
import { Link } from 'react-router-dom'
|
||||
import { Scale } from 'lucide-react'
|
||||
|
||||
const LEGAL_LINKS = [
|
||||
{ to: '/impressum', label: 'Impressum', description: 'Angaben zum Betreiber und Verantwortlichen' },
|
||||
{ to: '/datenschutz', label: 'Datenschutzerklärung', description: 'Verarbeitung personenbezogener Daten' },
|
||||
{ to: '/nutzungsbedingungen', label: 'Nutzungsbedingungen', description: 'Regeln für die Nutzung der Plattform' },
|
||||
{ to: '/medienrichtlinie', label: 'Medienrichtlinie', description: 'Urheberrecht, Rechte am eigenen Bild, Sichtbarkeit' },
|
||||
]
|
||||
|
||||
function SettingsLegalPage() {
|
||||
return (
|
||||
<div className="page-padding app-page" style={{ padding: '1rem' }}>
|
||||
<p style={{ marginBottom: '0.75rem' }}>
|
||||
<Link to="/settings" style={{ fontSize: '0.9rem' }}>
|
||||
← Zurück zu Einstellungen
|
||||
</Link>
|
||||
</p>
|
||||
|
||||
<h1 style={{ marginBottom: '0.35rem', fontSize: '1.5rem' }}>Rechtliches</h1>
|
||||
<p
|
||||
style={{
|
||||
color: 'var(--text2)',
|
||||
marginBottom: '1.25rem',
|
||||
fontSize: '0.95rem',
|
||||
lineHeight: 1.5,
|
||||
maxWidth: '40rem',
|
||||
}}
|
||||
>
|
||||
Rechtstexte und Richtlinien der Plattform.
|
||||
Die Inhalte befinden sich noch in redaktioneller Prüfung.
|
||||
</p>
|
||||
|
||||
<div className="card" style={{ padding: 0, overflow: 'hidden' }}>
|
||||
{LEGAL_LINKS.map((item, idx) => (
|
||||
<Link
|
||||
key={item.to}
|
||||
to={item.to}
|
||||
style={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: '0.85rem',
|
||||
padding: '1rem 1.1rem',
|
||||
borderBottom: idx < LEGAL_LINKS.length - 1 ? '1px solid var(--border)' : 'none',
|
||||
textDecoration: 'none',
|
||||
color: 'inherit',
|
||||
}}
|
||||
>
|
||||
<Scale size={18} style={{ color: 'var(--text3)', flexShrink: 0 }} />
|
||||
<div>
|
||||
<div style={{ fontWeight: 500, color: 'var(--text1)', fontSize: '0.95rem' }}>
|
||||
{item.label}
|
||||
</div>
|
||||
<div style={{ fontSize: '0.8rem', color: 'var(--text3)', marginTop: '0.15rem' }}>
|
||||
{item.description}
|
||||
</div>
|
||||
</div>
|
||||
<span style={{ marginLeft: 'auto', color: 'var(--text3)', fontSize: '1.1rem' }}>›</span>
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default SettingsLegalPage
|
||||
|
|
@ -1,11 +1,12 @@
|
|||
// Shinkan Jinkendo Frontend Version
|
||||
|
||||
export const APP_VERSION = "0.8.69"
|
||||
export const APP_VERSION = "0.8.70"
|
||||
export const BUILD_DATE = "2026-05-10"
|
||||
|
||||
export const PAGE_VERSIONS = {
|
||||
LoginPage: "1.0.2",
|
||||
LegalPage: "1.0.0",
|
||||
SettingsLegalPage: "1.0.0",
|
||||
Dashboard: "1.0.0",
|
||||
AccountSettingsPage: "1.0.1",
|
||||
ExercisesPage: "1.5.0", // Fokus +/- Regeln, nur ohne Fokusbereich; Filterprefs
|
||||
|
|
|
|||
|
|
@ -230,6 +230,59 @@ test('P-01: Login-Seite enthält Links zu allen vier Rechtstextseiten', async ({
|
|||
console.log('✓ P-01: Login-Seite – alle vier Rechtstext-Links vorhanden');
|
||||
});
|
||||
|
||||
// P-01b: Rechtliches über Einstellungen (Mobile/PWA-Erreichbarkeit)
|
||||
|
||||
test('P-01b: Einstellungen enthält Link zu Rechtliches', async ({ page }) => {
|
||||
await page.setViewportSize({ width: 390, height: 844 });
|
||||
await login(page);
|
||||
await page.waitForLoadState('networkidle');
|
||||
|
||||
await page.goto('/settings');
|
||||
await page.waitForLoadState('networkidle');
|
||||
|
||||
const link = page.locator('a[href="/settings/legal"]');
|
||||
await expect(link).toBeVisible();
|
||||
|
||||
console.log('✓ P-01b: Einstellungen enthält Link zu /settings/legal');
|
||||
});
|
||||
|
||||
test('P-01b: /settings/legal enthält Links zu allen vier Rechtstextseiten', async ({ page }) => {
|
||||
await page.setViewportSize({ width: 390, height: 844 });
|
||||
await login(page);
|
||||
await page.waitForLoadState('networkidle');
|
||||
|
||||
await page.goto('/settings/legal');
|
||||
await page.waitForLoadState('networkidle');
|
||||
|
||||
await expect(page.getByRole('heading', { level: 1 })).toContainText('Rechtliches');
|
||||
|
||||
for (const route of LEGAL_ROUTES) {
|
||||
const link = page.locator(`a[href="${route.path}"]`);
|
||||
await expect(link).toBeVisible();
|
||||
}
|
||||
|
||||
console.log('✓ P-01b: /settings/legal – Überschrift + alle vier Rechtstext-Links vorhanden');
|
||||
});
|
||||
|
||||
test('P-01b: Jeder Rechtstext-Link aus /settings/legal führt zur korrekten Route', async ({ page }) => {
|
||||
await page.setViewportSize({ width: 390, height: 844 });
|
||||
await login(page);
|
||||
await page.waitForLoadState('networkidle');
|
||||
|
||||
for (const route of LEGAL_ROUTES) {
|
||||
await page.goto('/settings/legal');
|
||||
await page.waitForLoadState('networkidle');
|
||||
|
||||
await page.locator(`a[href="${route.path}"]`).click();
|
||||
await page.waitForLoadState('networkidle');
|
||||
|
||||
expect(page.url()).toContain(route.path);
|
||||
await expect(page.getByRole('heading', { level: 1 })).toContainText(route.label);
|
||||
|
||||
console.log(`✓ P-01b: ${route.label} – Link aus /settings/legal korrekt`);
|
||||
}
|
||||
});
|
||||
|
||||
test('8. Keine kritischen Console-Fehler', async ({ page }) => {
|
||||
const errors = [];
|
||||
page.on('console', msg => {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user