wip
This commit is contained in:
@@ -21,9 +21,11 @@ import {
|
||||
Building2,
|
||||
LogOut,
|
||||
LogIn,
|
||||
TrendingUp,
|
||||
Award,
|
||||
} from 'lucide-react';
|
||||
|
||||
type DemoNotificationType = 'protest_filed' | 'defense_requested' | 'vote_required';
|
||||
type DemoNotificationType = 'protest_filed' | 'defense_requested' | 'vote_required' | 'race_performance_summary' | 'race_final_results';
|
||||
type DemoUrgency = 'silent' | 'toast' | 'modal';
|
||||
|
||||
interface NotificationOption {
|
||||
@@ -63,6 +65,20 @@ const notificationOptions: NotificationOption[] = [
|
||||
icon: Vote,
|
||||
color: 'text-primary-blue',
|
||||
},
|
||||
{
|
||||
type: 'race_performance_summary',
|
||||
label: 'Race Performance Summary',
|
||||
description: 'Immediate results after main race',
|
||||
icon: TrendingUp,
|
||||
color: 'text-primary-blue',
|
||||
},
|
||||
{
|
||||
type: 'race_final_results',
|
||||
label: 'Race Final Results',
|
||||
description: 'Final results after stewarding closes',
|
||||
icon: Award,
|
||||
color: 'text-warning-amber',
|
||||
},
|
||||
];
|
||||
|
||||
const urgencyOptions: UrgencyOption[] = [
|
||||
@@ -81,7 +97,7 @@ const urgencyOptions: UrgencyOption[] = [
|
||||
{
|
||||
urgency: 'modal',
|
||||
label: 'Modal',
|
||||
description: 'Shows blocking modal (must respond)',
|
||||
description: 'Shows blocking modal (may require response)',
|
||||
icon: AlertCircle,
|
||||
},
|
||||
];
|
||||
@@ -193,7 +209,7 @@ export default function DevToolbar() {
|
||||
|
||||
let title: string;
|
||||
let body: string;
|
||||
let notificationType: 'protest_filed' | 'protest_defense_requested' | 'protest_vote_required';
|
||||
let notificationType: 'protest_filed' | 'protest_defense_requested' | 'protest_vote_required' | 'race_performance_summary' | 'race_final_results';
|
||||
let actionUrl: string;
|
||||
|
||||
switch (selectedType) {
|
||||
@@ -224,14 +240,38 @@ export default function DevToolbar() {
|
||||
actionUrl = leagueId ? `/leagues/${leagueId}/stewarding` : '/leagues';
|
||||
break;
|
||||
}
|
||||
case 'race_performance_summary': {
|
||||
const raceId = primaryRace?.id;
|
||||
const leagueId = primaryLeague?.id;
|
||||
title = '🏁 Race Complete: Performance Summary';
|
||||
body =
|
||||
'Your Monza Grand Prix race is finished! You finished P1 with 0 incidents. Provisional rating: +25 points. View full results and standings.';
|
||||
notificationType = 'race_performance_summary';
|
||||
actionUrl = raceId ? `/races/${raceId}` : '/races';
|
||||
break;
|
||||
}
|
||||
case 'race_final_results': {
|
||||
const leagueId = primaryLeague?.id;
|
||||
title = '🏆 Final Results: Monza Grand Prix';
|
||||
body =
|
||||
'Stewarding is now closed. Your final result: P1 (+25 rating). No penalties were applied. View championship standings.';
|
||||
notificationType = 'race_final_results';
|
||||
actionUrl = leagueId ? `/leagues/${leagueId}/standings` : '/leagues';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const actions =
|
||||
selectedUrgency === 'modal'
|
||||
? [
|
||||
{ label: 'View Protest', type: 'primary' as const, href: actionUrl, actionId: 'view' },
|
||||
{ label: 'Dismiss', type: 'secondary' as const, actionId: 'dismiss' },
|
||||
]
|
||||
? selectedType.startsWith('race_')
|
||||
? [
|
||||
{ label: selectedType === 'race_performance_summary' ? '🏁 View Race Results' : '🏆 View Standings', type: 'primary' as const, href: actionUrl, actionId: 'view' },
|
||||
{ label: '🎉 Share Achievement', type: 'secondary' as const, actionId: 'share' },
|
||||
]
|
||||
: [
|
||||
{ label: 'View Protest', type: 'primary' as const, href: actionUrl, actionId: 'view' },
|
||||
{ label: 'Dismiss', type: 'secondary' as const, actionId: 'dismiss' },
|
||||
]
|
||||
: [];
|
||||
|
||||
await sendNotification.execute({
|
||||
@@ -241,13 +281,25 @@ export default function DevToolbar() {
|
||||
body,
|
||||
actionUrl,
|
||||
urgency: selectedUrgency as NotificationUrgency,
|
||||
requiresResponse: selectedUrgency === 'modal',
|
||||
requiresResponse: selectedUrgency === 'modal' && !selectedType.startsWith('race_'),
|
||||
actions,
|
||||
data: {
|
||||
protestId: `demo-protest-${Date.now()}`,
|
||||
...(selectedType.startsWith('protest_') ? {
|
||||
protestId: `demo-protest-${Date.now()}`,
|
||||
} : {}),
|
||||
...(selectedType.startsWith('race_') ? {
|
||||
raceEventId: `demo-race-event-${Date.now()}`,
|
||||
sessionId: `demo-session-${Date.now()}`,
|
||||
position: 1,
|
||||
positionChange: 0,
|
||||
incidents: 0,
|
||||
provisionalRatingChange: 25,
|
||||
finalRatingChange: 25,
|
||||
hadPenaltiesApplied: false,
|
||||
} : {}),
|
||||
raceId: primaryRace?.id ?? '',
|
||||
leagueId: primaryLeague?.id ?? '',
|
||||
...(notificationDeadline ? { deadline: notificationDeadline } : {}),
|
||||
...(notificationDeadline && selectedType.startsWith('protest_') ? { deadline: notificationDeadline } : {}),
|
||||
},
|
||||
});
|
||||
|
||||
@@ -315,7 +367,7 @@ export default function DevToolbar() {
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-3 gap-1">
|
||||
<div className="grid grid-cols-2 gap-1">
|
||||
{notificationOptions.map((option) => {
|
||||
const Icon = option.icon;
|
||||
const isSelected = selectedType === option.type;
|
||||
@@ -436,7 +488,7 @@ export default function DevToolbar() {
|
||||
<p className="text-[10px] text-gray-500">
|
||||
<strong className="text-gray-400">Silent:</strong> Notification center only<br/>
|
||||
<strong className="text-gray-400">Toast:</strong> Temporary popup (auto-dismisses)<br/>
|
||||
<strong className="text-gray-400">Modal:</strong> Blocking popup (requires action)
|
||||
<strong className="text-gray-400">Modal:</strong> Blocking popup (may require action)
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user