This commit is contained in:
2026-03-04 14:13:16 +01:00
parent b7d826e29c
commit 56ea3348d6
41 changed files with 846 additions and 162 deletions

View File

@@ -2,7 +2,6 @@
import { auth, getSanitizedHeaders } from '@/lib/auth'
import { prisma } from '@innungsapp/shared'
import { redirect } from 'next/navigation'
// @ts-ignore
import { hashPassword } from 'better-auth/crypto'
@@ -25,7 +24,6 @@ export async function changePasswordAndDisableMustChange(prevState: any, formDat
}
const userId = session.user.id
const slug = formData.get('slug') as string
// Hash and save new password directly — user is already authenticated so no old password needed
const newHash = await hashPassword(newPassword)
@@ -64,5 +62,9 @@ export async function changePasswordAndDisableMustChange(prevState: any, formDat
// ignore
}
redirect(`/login?message=password_changed&callbackUrl=/${slug}/dashboard`)
return {
success: true,
error: '',
redirectTo: `/login?message=password_changed&callbackUrl=/dashboard`,
}
}

View File

@@ -1,10 +1,17 @@
'use client'
import { useEffect } from 'react'
import { useActionState } from 'react'
import { changePasswordAndDisableMustChange } from '../actions'
export function ForcePasswordChange({ slug }: { slug: string }) {
const [state, action, isPending] = useActionState(changePasswordAndDisableMustChange, { success: false, error: '' })
const [state, action, isPending] = useActionState(changePasswordAndDisableMustChange, { success: false, error: '', redirectTo: '' })
useEffect(() => {
if (state?.success && state?.redirectTo) {
window.location.href = state.redirectTo
}
}, [state?.success, state?.redirectTo])
return (
<div className="bg-white border rounded-xl p-8 max-w-md w-full shadow-sm">

View File

@@ -2,6 +2,24 @@ import { prisma } from '@innungsapp/shared'
import { notFound } from 'next/navigation'
import Link from 'next/link'
function jsonToText(value: unknown): string {
if (value == null) {
return ''
}
if (typeof value === 'string') {
return value
}
if (Array.isArray(value)) {
return value
.map((item) => (typeof item === 'string' ? item : JSON.stringify(item)))
.join('\n')
}
return JSON.stringify(value)
}
export default async function TenantLandingPage({
params,
}: {
@@ -26,8 +44,8 @@ export default async function TenantLandingPage({
const secondaryColor = org.secondaryColor || undefined
const title = org.landingPageTitle || org.name || 'Zukunft durch Handwerk'
const text = org.landingPageText || 'Wir sind Ihre lokale Vertretung des Handwerks. Mit starker Gemeinschaft und klaren Zielen setzen wir uns für die Betriebe in unserer Region ein.'
const features = org.landingPageFeatures || '✅ Exzellente Ausbildung\n✅ Starke Gemeinschaft\n✅ Politische Interessenvertretung'
const footer = org.landingPageFooter || `© ${new Date().getFullYear()} ${org.name}`
const features = jsonToText(org.landingPageFeatures) || '✅ Exzellente Ausbildung\n✅ Starke Gemeinschaft\n✅ Politische Interessenvertretung'
const footer = jsonToText(org.landingPageFooter) || `© ${new Date().getFullYear()} ${org.name}`
const sectionTitle = org.landingPageSectionTitle || `${org.name || 'Ihre Innung'} Gemeinsam stark fürs Handwerk`
const buttonText = org.landingPageButtonText || 'Jetzt App laden'