womp womp
This commit is contained in:
parent
3e95e2d4f2
commit
b96fb0d0e4
4 changed files with 74 additions and 32 deletions
|
|
@ -39,7 +39,14 @@ public class AuthService {
|
|||
user.setName(request.getFirstname() + " " + request.getLastname()); // Populate legacy/fallback fields
|
||||
user.setEmail(request.getEmail());
|
||||
user.setPassword(passwordEncoder.encode(request.getPassword()));
|
||||
user.setPassword(passwordEncoder.encode(request.getPassword()));
|
||||
|
||||
// Auto-assign ADMIN role to the very first user
|
||||
if (userRepository.count() == 0) {
|
||||
user.setRole("ADMIN");
|
||||
} else {
|
||||
user.setRole(request.getRole());
|
||||
}
|
||||
|
||||
if ("RAUMBETREUER".equals(request.getRole()) && request.getRoomIds() != null) {
|
||||
List<Room> rooms = roomRepository.findAllById(request.getRoomIds());
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/com
|
|||
import { ShieldAlert, Users } from "lucide-react"
|
||||
|
||||
export function AdminDashboard() {
|
||||
const { tickets, updateTicketStatus, authHeader } = useAuth()
|
||||
const { tickets, updateTicketStatus, deleteTicket, authHeader } = useAuth()
|
||||
const API_URL = process.env.NEXT_PUBLIC_API_URL + "/api"
|
||||
|
||||
// Admin sees all tickets (logic handled in Backend/TicketService)
|
||||
|
|
@ -62,6 +62,7 @@ export function AdminDashboard() {
|
|||
tickets={tickets}
|
||||
showStatusUpdate
|
||||
onStatusUpdate={updateTicketStatus}
|
||||
onDeleteTicket={deleteTicket}
|
||||
/>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
|
|
|||
|
|
@ -11,7 +11,8 @@ import {
|
|||
SelectTrigger,
|
||||
SelectValue,
|
||||
} from "@/components/ui/select"
|
||||
import { ArrowUpDown, ArrowDown, ArrowUp, Calendar, MapPin, FileText } from "lucide-react"
|
||||
import { ArrowUpDown, ArrowDown, ArrowUp, Calendar, MapPin, FileText, Trash2 } from "lucide-react"
|
||||
import { Button } from "@/components/ui/button"
|
||||
import { Input } from "@/components/ui/input"
|
||||
import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from "@/components/ui/dialog"
|
||||
import { TicketComments } from "./ticket-comments"
|
||||
|
|
@ -20,11 +21,12 @@ interface TicketTableProps {
|
|||
tickets: Ticket[]
|
||||
showStatusUpdate?: boolean
|
||||
onStatusUpdate?: (ticketId: number, status: TicketStatus) => void
|
||||
onDeleteTicket?: (ticketId: number) => void
|
||||
}
|
||||
|
||||
type SortDirection = "asc" | "desc"
|
||||
|
||||
export function TicketTable({ tickets, showStatusUpdate = false, onStatusUpdate }: TicketTableProps) {
|
||||
export function TicketTable({ tickets, showStatusUpdate = false, onStatusUpdate, onDeleteTicket }: TicketTableProps) {
|
||||
const [sortConfig, setSortConfig] = useState<{ key: keyof Ticket | "room" | "owner"; direction: SortDirection }>({ key: "createdAt", direction: "desc" })
|
||||
const [search, setSearch] = useState("")
|
||||
const [statusFilter, setStatusFilter] = useState<TicketStatus | "ALL">("ALL")
|
||||
|
|
@ -133,6 +135,7 @@ export function TicketTable({ tickets, showStatusUpdate = false, onStatusUpdate
|
|||
<TableHead className="font-semibold cursor-pointer" onClick={() => handleSort("status")}>
|
||||
Status {sortConfig.key === "status" && (sortConfig.direction === "asc" ? <ArrowUp className="h-3 w-3" /> : <ArrowDown className="h-3 w-3" />)}
|
||||
</TableHead>
|
||||
{onDeleteTicket && <TableHead className="w-[50px]"></TableHead>}
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
|
|
@ -174,6 +177,23 @@ export function TicketTable({ tickets, showStatusUpdate = false, onStatusUpdate
|
|||
<StatusBadge status={ticket.status} />
|
||||
)}
|
||||
</TableCell>
|
||||
{onDeleteTicket && (
|
||||
<TableCell onClick={(e) => e.stopPropagation()}>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
className="h-8 w-8 text-destructive hover:text-destructive hover:bg-destructive/10"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation()
|
||||
if (confirm("Ticket wirklich löschen?")) {
|
||||
onDeleteTicket(ticket.id)
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Trash2 className="h-4 w-4" />
|
||||
</Button>
|
||||
</TableCell>
|
||||
)}
|
||||
</TableRow>
|
||||
))
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ interface AuthContextType {
|
|||
logout: () => void
|
||||
createTicket: (ticket: { roomId: number; title: string; description: string }) => Promise<void>
|
||||
updateTicketStatus: (ticketId: number, status: TicketStatus) => Promise<void>
|
||||
deleteTicket: (ticketId: number) => Promise<void>
|
||||
updateRooms: (roomIds: number[]) => Promise<void>
|
||||
}
|
||||
|
||||
|
|
@ -174,6 +175,18 @@ export function AuthProvider({ children }: { children: ReactNode }) {
|
|||
if (res.ok) {
|
||||
fetchTickets(authHeader) // Refresh
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
const deleteTicket = useCallback(async (ticketId: number) => {
|
||||
if (!authHeader) return
|
||||
try {
|
||||
const res = await fetch(`${API_URL}/tickets/${ticketId}`, {
|
||||
method: "DELETE",
|
||||
headers: { "Authorization": authHeader }
|
||||
})
|
||||
if (res.ok) {
|
||||
fetchTickets(authHeader)
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
}
|
||||
|
|
@ -191,6 +204,7 @@ export function AuthProvider({ children }: { children: ReactNode }) {
|
|||
logout,
|
||||
createTicket,
|
||||
updateTicketStatus,
|
||||
deleteTicket,
|
||||
updateRooms,
|
||||
}}
|
||||
>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue