feat(sprint8): Phase 4 — Dokumentenarchiv + Vorstandsverwaltung
Backend: - V20 migration: documents table with category, access_level, file storage - V21 migration: board_positions + board_members with term tracking - Document entity + DocumentCategory/DocumentAccessLevel enums - BoardPosition + BoardMember entities - Extended AuditEventType (DOCUMENT_UPLOADED/DELETED, BOARD_MEMBER_ELECTED/REMOVED) - Extended StaffPermission (MANAGE_DOCUMENTS) - Extended NotificationType (BOARD_TERM_EXPIRING) - DocumentService: upload, list, download, delete, storage usage - BoardService: positions CRUD, elect/remove members, current/history - DocumentController: multipart upload, filtered list, download, delete, portal - BoardController: positions, elect, remove, current board, history, portal Frontend: - documents.ts + board.ts service layers - Admin /documents page: grouped by category, upload dialog, filter, download/delete - Admin /board page: current board cards, position management, elect member dialog - Navigation: added Dokumente + Vorstand to sidebar - i18n: documents.* + board.* keys in de.json + en.json
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
import { apiClient } from "@/lib/api-client"
|
||||
|
||||
export interface BoardPosition {
|
||||
id: string
|
||||
title: string
|
||||
description: string | null
|
||||
sortOrder: number
|
||||
isActive: boolean
|
||||
createdAt: string
|
||||
}
|
||||
|
||||
export interface BoardMember {
|
||||
id: string
|
||||
clubId: string
|
||||
positionId: string
|
||||
memberId: string
|
||||
electedAt: string
|
||||
termStart: string
|
||||
termEnd: string | null
|
||||
isCurrent: boolean
|
||||
electedInAssemblyId: string | null
|
||||
createdAt: string
|
||||
}
|
||||
|
||||
export interface CreatePositionRequest {
|
||||
title: string
|
||||
description?: string
|
||||
sortOrder?: number
|
||||
}
|
||||
|
||||
export interface ElectBoardMemberRequest {
|
||||
positionId: string
|
||||
memberId: string
|
||||
electedAt: string
|
||||
termStart: string
|
||||
termEnd?: string
|
||||
assemblyId?: string
|
||||
}
|
||||
|
||||
export function createPosition(
|
||||
clubId: string,
|
||||
data: CreatePositionRequest
|
||||
): Promise<BoardPosition> {
|
||||
return apiClient<BoardPosition>(`/board/positions?clubId=${clubId}`, {
|
||||
method: "POST",
|
||||
body: data,
|
||||
})
|
||||
}
|
||||
|
||||
export function getPositions(clubId: string): Promise<BoardPosition[]> {
|
||||
return apiClient<BoardPosition[]>(`/board/positions?clubId=${clubId}`)
|
||||
}
|
||||
|
||||
export function updatePosition(
|
||||
id: string,
|
||||
data: Partial<CreatePositionRequest & { isActive: boolean }>
|
||||
): Promise<BoardPosition> {
|
||||
return apiClient<BoardPosition>(`/board/positions/${id}`, {
|
||||
method: "PUT",
|
||||
body: data,
|
||||
})
|
||||
}
|
||||
|
||||
export function electBoardMember(
|
||||
clubId: string,
|
||||
data: ElectBoardMemberRequest
|
||||
): Promise<BoardMember> {
|
||||
return apiClient<BoardMember>(`/board/members?clubId=${clubId}`, {
|
||||
method: "POST",
|
||||
body: data,
|
||||
})
|
||||
}
|
||||
|
||||
export function getCurrentBoard(clubId: string): Promise<BoardMember[]> {
|
||||
return apiClient<BoardMember[]>(`/board?clubId=${clubId}`)
|
||||
}
|
||||
|
||||
export function getBoardHistory(clubId: string): Promise<BoardMember[]> {
|
||||
return apiClient<BoardMember[]>(`/board/history?clubId=${clubId}`)
|
||||
}
|
||||
|
||||
export function removeBoardMember(id: string, clubId: string): Promise<void> {
|
||||
return apiClient<void>(`/board/members/${id}?clubId=${clubId}`, {
|
||||
method: "DELETE",
|
||||
})
|
||||
}
|
||||
|
||||
export function getPortalBoard(clubId: string): Promise<BoardMember[]> {
|
||||
return apiClient<BoardMember[]>(`/portal/board?clubId=${clubId}`)
|
||||
}
|
||||
Reference in New Issue
Block a user