diff --git a/frontend/src/components/contacts/ContactDetail.tsx b/frontend/src/components/contacts/ContactDetail.tsx index 43410a3..7148a42 100644 --- a/frontend/src/components/contacts/ContactDetail.tsx +++ b/frontend/src/components/contacts/ContactDetail.tsx @@ -15,6 +15,7 @@ import { useAIUIControlStore } from '@/store/aiUIControlStore'; import { PluginPage } from '@/components/plugins/PluginLoader'; import { useAuthStore } from '@/store/authStore'; import { CustomFieldRenderer } from '@/components/contacts/CustomFieldRenderer'; +import { usePermission } from '@/hooks/usePermission'; import { TagBadge } from '@/components/tags/TagBadge'; import { EntityHistoryPanel } from '@/components/common/EntityHistoryPanel'; import { useCustomFields } from '@/api/customFields'; @@ -30,13 +31,19 @@ import { export interface ContactDetailProps { contact: UnifiedContact | null; loading?: boolean; - onEdit: () => void; + onEdit?: () => void; onDeleted: () => void; } -function Field({ label, value }: { label: string; value?: string | null }) { +function Field({ label, value, fieldName }: { label: string; value?: string | null; fieldName?: string }) { + const { hasFieldAccess } = usePermission(); + if (fieldName) { + const access = hasFieldAccess('contacts', fieldName); + if (access === 'hidden') return null; + } + const isReadonly = fieldName ? hasFieldAccess('contacts', fieldName) === 'readonly' : false; return ( -
+
{label}
{value || '—'}
@@ -153,6 +160,7 @@ export function ContactDetail({ contact, loading, onEdit, onDeleted }: ContactDe const { t } = useTranslation(); const toast = useToast(); const deleteMutation = useDeleteUnifiedContact(); + const { hasPermission, hasFieldAccess } = usePermission(); const createPersonMutation = useCreateContactPerson(); const updatePersonMutation = useUpdateContactPerson(); const deletePersonMutation = useDeleteContactPerson(); @@ -286,8 +294,12 @@ export function ContactDetail({ contact, loading, onEdit, onDeleted }: ContactDe
- - + {hasPermission('contacts:write') && onEdit && ( + + )} + {hasPermission('contacts:delete') && ( + + )}
@@ -378,52 +390,52 @@ export function ContactDetail({ contact, loading, onEdit, onDeleted }: ContactDe {/* Communication */}
- - - - - + + + + +
{/* Financial */}
- - - - - - + + + + + +
{/* Discounts */}
- - - - - - + + + + + +
{/* Geo */}
- - + +
{/* Notes & Tags */}
- - - + + +
{t('tags.title')}
diff --git a/frontend/src/pages/ContactDetailPage.tsx b/frontend/src/pages/ContactDetailPage.tsx index bb19519..de1428b 100644 --- a/frontend/src/pages/ContactDetailPage.tsx +++ b/frontend/src/pages/ContactDetailPage.tsx @@ -12,6 +12,7 @@ import { useUnifiedContact, type UnifiedContact } from '@/api/hooks'; import { Button } from '@/components/ui/Button'; import { ChevronLeft } from 'lucide-react'; import { PrintButton } from '@/components/common/PrintButton'; +import { usePermission } from '@/hooks/usePermission'; export function ContactDetailPage() { const { t } = useTranslation(); @@ -19,6 +20,7 @@ export function ContactDetailPage() { const navigate = useNavigate(); const { data: contact, isLoading } = useUnifiedContact(id); const openWindow = useWindowStore((s) => s.openWindow); + const { hasPermission } = usePermission(); const handleEdit = () => { if (contact) { @@ -51,13 +53,13 @@ export function ContactDetailPage() { {t('contacts.title')}
- + {hasPermission('contacts:read') && }
diff --git a/frontend/src/pages/ContactsList.tsx b/frontend/src/pages/ContactsList.tsx index ef04717..f5ddb68 100644 --- a/frontend/src/pages/ContactsList.tsx +++ b/frontend/src/pages/ContactsList.tsx @@ -35,11 +35,13 @@ import { } from '@/api/hooks'; import { useContactFolders } from '@/api/contacts'; import { useCustomFieldDefinitions } from '@/api/customFieldDefinitions'; +import { usePermission } from '@/hooks/usePermission'; const PAGE_SIZE = 25; export function ContactsListPage() { const { t } = useTranslation(); + const { hasPermission } = usePermission(); const [selectedFilter, setSelectedFilter] = useState('all'); const [search, setSearch] = useState(''); @@ -356,7 +358,7 @@ export function ContactsListPage() { useEffect(() => { const items = [ // New contact — ganz links - { + ...(hasPermission('contacts:write') ? [{ id: 'new', plugin: 'contacts', label: t('contacts.create'), @@ -364,7 +366,7 @@ export function ContactsListPage() { group: 'create', icon: , onClick: handleCreate, - }, + }] : []), // View mode dropdown (list / table / cards) { id: 'view-mode', @@ -455,7 +457,7 @@ export function ContactsListPage() { onClick: () => setSavedFiltersOpen(true), }, // Print — icon only, right side - { + ...(hasPermission('contacts:read') ? [{ id: 'print', plugin: 'contacts', label: t('common.print', 'Drucken'), @@ -464,7 +466,7 @@ export function ContactsListPage() { icon: , iconOnly: true, onClick: () => window.print(), - }, + }] : []), // Open standalone — icon only, right side { id: 'open-standalone',