neuer demo tenant switcher + demo tenants mit eigenem artisan command. Event Admin überarbeitet, aber das ist nur ein Zwischenstand.
This commit is contained in:
@@ -40,6 +40,7 @@ import {
|
||||
} from '../api';
|
||||
import { isAuthError } from '../auth/tokens';
|
||||
import { useAuth } from '../auth/context';
|
||||
import { useEventContext } from '../context/EventContext';
|
||||
import {
|
||||
adminPath,
|
||||
ADMIN_HOME_PATH,
|
||||
@@ -82,6 +83,7 @@ export default function DashboardPage() {
|
||||
const navigate = useNavigate();
|
||||
const location = useLocation();
|
||||
const { user } = useAuth();
|
||||
const { events: ctxEvents, activeEvent: ctxActiveEvent } = useEventContext();
|
||||
const { progress, markStep } = useOnboardingProgress();
|
||||
const { t, i18n } = useTranslation('dashboard', { keyPrefix: 'dashboard' });
|
||||
const { t: tc } = useTranslation('common');
|
||||
@@ -132,7 +134,7 @@ export default function DashboardPage() {
|
||||
try {
|
||||
const [summary, events, packages] = await Promise.all([
|
||||
getDashboardSummary().catch(() => null),
|
||||
getEvents().catch(() => [] as TenantEvent[]),
|
||||
getEvents({ force: true }).catch(() => [] as TenantEvent[]),
|
||||
getTenantPackagesOverview().catch(() => ({ packages: [], activePackage: null })),
|
||||
]);
|
||||
|
||||
@@ -141,11 +143,12 @@ export default function DashboardPage() {
|
||||
}
|
||||
|
||||
const fallbackSummary = buildSummaryFallback(events, packages.activePackage);
|
||||
const primaryEvent = events[0] ?? null;
|
||||
const eventPool = events.length ? events : ctxEvents;
|
||||
const primaryEvent = ctxActiveEvent ?? eventPool[0] ?? null;
|
||||
const primaryEventName = primaryEvent ? resolveEventName(primaryEvent.name, primaryEvent.slug) : null;
|
||||
|
||||
setReadiness({
|
||||
hasEvent: events.length > 0,
|
||||
hasEvent: eventPool.length > 0,
|
||||
hasTasks: primaryEvent ? (Number(primaryEvent.tasks_count ?? 0) > 0) : false,
|
||||
hasQrInvites: primaryEvent
|
||||
? Number(
|
||||
@@ -162,7 +165,7 @@ export default function DashboardPage() {
|
||||
|
||||
setState({
|
||||
summary: summary ?? fallbackSummary,
|
||||
events,
|
||||
events: eventPool,
|
||||
activePackage: packages.activePackage,
|
||||
loading: false,
|
||||
errorKey: null,
|
||||
@@ -217,12 +220,21 @@ export default function DashboardPage() {
|
||||
const subtitle = translate('welcome.subtitle');
|
||||
const errorMessage = errorKey ? translate(`errors.${errorKey}`) : null;
|
||||
const dateLocale = i18n.language?.startsWith('en') ? 'en-GB' : 'de-DE';
|
||||
const canCreateEvent = React.useMemo(() => {
|
||||
if (!activePackage) {
|
||||
return true;
|
||||
}
|
||||
if (activePackage.remaining_events === null || activePackage.remaining_events === undefined) {
|
||||
return true;
|
||||
}
|
||||
return activePackage.remaining_events > 0;
|
||||
}, [activePackage]);
|
||||
|
||||
const upcomingEvents = getUpcomingEvents(events);
|
||||
const publishedEvents = events.filter((event) => event.status === 'published');
|
||||
const primaryEvent = events[0] ?? null;
|
||||
const upcomingEvents = getUpcomingEvents(ctxEvents.length ? ctxEvents : events);
|
||||
const publishedEvents = (ctxEvents.length ? ctxEvents : events).filter((event) => event.status === 'published');
|
||||
const primaryEvent = ctxActiveEvent ?? (ctxEvents[0] ?? events[0] ?? null);
|
||||
const primaryEventName = primaryEvent ? resolveEventName(primaryEvent.name, primaryEvent.slug) : null;
|
||||
const singleEvent = events.length === 1 ? events[0] : null;
|
||||
const singleEvent = ctxEvents.length === 1 ? ctxEvents[0] : (events.length === 1 ? events[0] : null);
|
||||
const singleEventName = singleEvent ? resolveEventName(singleEvent.name, singleEvent.slug) : null;
|
||||
const singleEventDateLabel = singleEvent?.event_date ? formatDate(singleEvent.event_date, dateLocale) : null;
|
||||
const primaryEventLimits = primaryEvent?.limits ?? null;
|
||||
@@ -468,7 +480,15 @@ export default function DashboardPage() {
|
||||
label: translate('quickActions.createEvent.label'),
|
||||
description: translate('quickActions.createEvent.description'),
|
||||
icon: <Plus className="h-5 w-5" />,
|
||||
onClick: () => navigate(ADMIN_EVENT_CREATE_PATH),
|
||||
onClick: () => {
|
||||
if (!canCreateEvent) {
|
||||
toast.error(tc('errors.eventLimit', 'Dein aktuelles Paket enthält keine freien Event-Slots mehr.'));
|
||||
navigate(ADMIN_BILLING_PATH);
|
||||
return;
|
||||
}
|
||||
navigate(ADMIN_EVENT_CREATE_PATH);
|
||||
},
|
||||
disabled: !canCreateEvent,
|
||||
},
|
||||
{
|
||||
key: 'photos',
|
||||
@@ -559,7 +579,7 @@ export default function DashboardPage() {
|
||||
);
|
||||
|
||||
return (
|
||||
<AdminLayout title={adminTitle} subtitle={adminSubtitle} actions={layoutActions} tabs={dashboardTabs} currentTabKey={currentDashboardTab}>
|
||||
<AdminLayout title={adminTitle} subtitle={adminSubtitle} tabs={dashboardTabs} currentTabKey={currentDashboardTab}>
|
||||
{errorMessage && (
|
||||
<Alert variant="destructive">
|
||||
<AlertTitle>{t('dashboard.alerts.errorTitle')}</AlertTitle>
|
||||
|
||||
Reference in New Issue
Block a user