evOo-local/apps/web/src/components/SortableGroup.tsx
Ingo Wagner 4b58776584 feat(web): add Privacy & Data settings section and remove Google Fonts
- Remove unused Google Fonts links from index.html (no external CDN)
- Add Privacy & Data settings section with:
  - Privacy posture indicator (data local, no analytics, no cloud sync)
  - Connection details panel (API, auth, DB, sandbox)
  - Data export button
  - Account deletion with confirmation
- Add ShieldCheck icon to settings nav
- Fix: DataTrustPanel import removed (was not used)
2026-09-23 16:04:19 +00:00

44 lines
1.3 KiB
TypeScript

/**
* Sortable wrapper for a project (space) sidebar group card.
* Accepts an optional `handleSlot` so the parent can render a grip handle
* inside its own title row — this keeps the handle positioned correctly
* relative to the label.
*/
import { CSS } from "@dnd-kit/utilities";
import { useSortable } from "@dnd-kit/sortable";
import { memo, useMemo } from "react";
interface SortableGroupProps {
group: { spaceId: string; key: string; title?: string | null };
/** When provided, rendered alongside children inside the drag node. */
handleSlot?: React.ReactNode;
children: React.ReactNode;
}
export const SortableGroup = memo(function SortableGroup({
group,
handleSlot,
children,
}: SortableGroupProps) {
const { attributes, listeners, setNodeRef, transform, transition, isDragging } = useSortable({
id: group.spaceId,
});
const style: React.CSSProperties = useMemo(
() => ({
transform: CSS.Translate.toString(transform),
transition,
opacity: isDragging ? 0.5 : undefined,
zIndex: isDragging ? 1000 : undefined,
}),
[transform, transition, isDragging],
);
return (
<div ref={setNodeRef} style={style} data-drag-id={group.spaceId} {...attributes} {...listeners}>
{handleSlot}
{children}
</div>
);
});