feat: timeline multi-select, demand popover, resource hover card, merged tooltips, dark mode fixes
Major timeline enhancements: - Right-click drag multi-selection with floating action bar (batch delete/assign) - DemandPopover for demand strip details (replaces broken "Loading" modal) - ResourceHoverCard on name hover showing skills, rates, role, chapter - Merged heatmap+vacation tooltips into unified TimelineTooltip component - Fixed overbooking blink animation (date normalization, z-index ordering) - Fixed dark mode sticky column bleed-through in project view - System roles admin page, notification task management, performance review docs Co-Authored-By: claude-flow <ruv@ruv.net>
This commit is contained in:
@@ -3,8 +3,10 @@
|
||||
import { useState } from "react";
|
||||
import { useSearchParams } from "next/navigation";
|
||||
import { trpc } from "~/lib/trpc/client.js";
|
||||
import { usePermissions } from "~/hooks/usePermissions.js";
|
||||
import { TaskCard } from "./TaskCard.js";
|
||||
import { ReminderModal } from "./ReminderModal.js";
|
||||
import { CreateTaskModal } from "./CreateTaskModal.js";
|
||||
|
||||
type TabKey = "all" | "notifications" | "tasks" | "reminders" | "approvals";
|
||||
|
||||
@@ -27,6 +29,8 @@ export function NotificationCenterClient() {
|
||||
const searchParams = useSearchParams();
|
||||
const initialTab = (searchParams.get("tab") as TabKey) || "all";
|
||||
const [activeTab, setActiveTab] = useState<TabKey>(initialTab);
|
||||
const { canEdit } = usePermissions();
|
||||
const [showTaskModal, setShowTaskModal] = useState(false);
|
||||
const [reminderModal, setReminderModal] = useState<{
|
||||
open: boolean;
|
||||
reminder: {
|
||||
@@ -124,6 +128,18 @@ export function NotificationCenterClient() {
|
||||
<div className="flex items-center justify-between mb-6">
|
||||
<h1 className="text-2xl font-bold text-gray-900 dark:text-gray-50">Notification Center</h1>
|
||||
<div className="flex items-center gap-3">
|
||||
{canEdit && activeTab === "tasks" && (
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setShowTaskModal(true)}
|
||||
className="inline-flex items-center gap-1.5 rounded-lg bg-brand-600 px-3 py-1.5 text-sm font-medium text-white hover:bg-brand-700 transition-colors"
|
||||
>
|
||||
<svg className="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 4v16m8-8H4" />
|
||||
</svg>
|
||||
Create Task
|
||||
</button>
|
||||
)}
|
||||
{activeTab === "reminders" && (
|
||||
<button
|
||||
type="button"
|
||||
@@ -389,6 +405,14 @@ export function NotificationCenterClient() {
|
||||
onSuccess={() => setReminderModal({ open: false, reminder: null })}
|
||||
/>
|
||||
)}
|
||||
|
||||
{/* Create Task Modal */}
|
||||
{showTaskModal && (
|
||||
<CreateTaskModal
|
||||
onClose={() => setShowTaskModal(false)}
|
||||
onSuccess={() => setShowTaskModal(false)}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user