mirror of
https://github.com/Since-3/Kuma.git
synced 2026-10-12 20:41:16 +00:00
Merge pull request #53 from Since-3/refactor/added-deletion-process-in-edit
added deletion process in edit and abstracted deletion process
This commit is contained in:
commit
885cf3c20e
9 changed files with 312 additions and 134 deletions
|
|
@ -127,10 +127,7 @@ const ResetPasswordView = () => {
|
|||
|
||||
<div className="flex flex-col sm:flex-row gap-2 items-center mt-8 text-sm">
|
||||
<p>Zurück zum</p>
|
||||
<p
|
||||
className="text-yellow hover:underline cursor-pointer"
|
||||
onClick={() => router.push("/login")}
|
||||
>
|
||||
<p className="text-blue underline cursor-pointer" onClick={() => router.push("/login")}>
|
||||
Login
|
||||
</p>
|
||||
</div>
|
||||
|
|
|
|||
48
src/modules/courses/hooks/useDeleteCourse.ts
Normal file
48
src/modules/courses/hooks/useDeleteCourse.ts
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
"use client";
|
||||
import { useState } from "react";
|
||||
import { deleteCourse } from "../actions/course-actions";
|
||||
import { toast } from "sonner";
|
||||
|
||||
interface UseDeleteCourseOptions {
|
||||
onSuccess?: (deletedId: string) => void;
|
||||
}
|
||||
|
||||
export function useDeleteCourse({ onSuccess }: UseDeleteCourseOptions = {}) {
|
||||
const [deleteDialogOpen, setDeleteDialogOpen] = useState(false);
|
||||
const [courseToDelete, setCourseToDelete] = useState<{ id: string; name: string } | null>(null);
|
||||
const [isDeleting, setIsDeleting] = useState(false);
|
||||
|
||||
const handleDeleteClick = (id: string, name: string) => {
|
||||
setCourseToDelete({ id, name });
|
||||
setDeleteDialogOpen(true);
|
||||
};
|
||||
|
||||
const handleDeleteConfirm = async () => {
|
||||
if (!courseToDelete) return;
|
||||
|
||||
setIsDeleting(true);
|
||||
const result = await deleteCourse(courseToDelete.id);
|
||||
setIsDeleting(false);
|
||||
setDeleteDialogOpen(false);
|
||||
|
||||
if (result.success) {
|
||||
toast.success(result.message);
|
||||
const deletedId = courseToDelete.id;
|
||||
setCourseToDelete(null);
|
||||
onSuccess?.(deletedId);
|
||||
} else {
|
||||
setCourseToDelete(null);
|
||||
toast.error(result.error || "Fehler beim Löschen des Kurses");
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
deleteDialogOpen,
|
||||
setDeleteDialogOpen,
|
||||
courseToDelete,
|
||||
setCourseToDelete,
|
||||
isDeleting,
|
||||
handleDeleteClick,
|
||||
handleDeleteConfirm,
|
||||
};
|
||||
}
|
||||
|
|
@ -12,6 +12,9 @@ import { createCourse, updateCourse } from "../../actions/course-actions";
|
|||
import { getMyRooms } from "@/src/modules/rooms/actions/room-actions";
|
||||
import { toast } from "sonner";
|
||||
import { Course } from "../../types/course.types";
|
||||
import { Trash2 } from "lucide-react";
|
||||
import DeleteDialog from "@/src/components/layout/DeleteDialog";
|
||||
import { useDeleteCourse } from "../../hooks/useDeleteCourse";
|
||||
|
||||
const TRAINERS = [
|
||||
{ value: "trainer1", label: "Max Mustermann" },
|
||||
|
|
@ -82,6 +85,18 @@ const CourseCreateView = ({
|
|||
const [rooms, setRooms] = useState<Array<{ value: string; label: string }>>([]);
|
||||
const [isLoadingRooms, setIsLoadingRooms] = useState(true);
|
||||
|
||||
const {
|
||||
deleteDialogOpen,
|
||||
setDeleteDialogOpen,
|
||||
courseToDelete,
|
||||
setCourseToDelete,
|
||||
isDeleting,
|
||||
handleDeleteClick,
|
||||
handleDeleteConfirm,
|
||||
} = useDeleteCourse({
|
||||
onSuccess: () => router.push("/courses"),
|
||||
});
|
||||
|
||||
// Load rooms from database
|
||||
useEffect(() => {
|
||||
const loadRooms = async () => {
|
||||
|
|
@ -246,12 +261,23 @@ const CourseCreateView = ({
|
|||
|
||||
return (
|
||||
<div>
|
||||
<h1 className="text-3xl font-bold">{mode === "edit" ? "Kurs bearbeiten" : "Kurs anlegen"}</h1>
|
||||
<p className="text-xl mt-2">
|
||||
{mode === "edit"
|
||||
? "Ändern Sie die Kursdetails und speichern Sie Ihre Änderungen"
|
||||
: "Alle Kurse können nach dem Speichern angepasst oder gelöscht werden"}
|
||||
</p>
|
||||
<div className="w-full flex items-center justify-between">
|
||||
<div>
|
||||
<h1 className="text-3xl font-bold">
|
||||
{mode === "edit" ? "Kurs bearbeiten" : "Kurs anlegen"}
|
||||
</h1>
|
||||
<p className="text-xl mt-2">
|
||||
{mode === "edit"
|
||||
? "Ändern Sie die Kursdetails und speichern Sie Ihre Änderungen"
|
||||
: "Alle Kurse können nach dem Speichern angepasst oder gelöscht werden"}
|
||||
</p>
|
||||
</div>
|
||||
{mode === "edit" && (
|
||||
<Button variant="destructive" onClick={() => handleDeleteClick(courseId!, courseName)}>
|
||||
<Trash2 className="mb-1" /> Löschen
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
<div className="mt-6 flex flex-col gap-4 max-w-xl">
|
||||
<div>
|
||||
<InputComponent
|
||||
|
|
@ -473,6 +499,18 @@ const CourseCreateView = ({
|
|||
{mode === "edit" ? "Als Entwurf speichern" : "Entwurf speichern"}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<DeleteDialog
|
||||
open={deleteDialogOpen}
|
||||
onOpenChange={(open) => {
|
||||
setDeleteDialogOpen(open);
|
||||
if (!open) setCourseToDelete(null);
|
||||
}}
|
||||
itemName={courseToDelete?.name}
|
||||
topicName="Kurs"
|
||||
onConfirm={handleDeleteConfirm}
|
||||
isLoading={isDeleting}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
"use client";
|
||||
import { useEffect, useState } from "react";
|
||||
import { getMyCourses, deleteCourse } from "../../actions/course-actions";
|
||||
import { getMyCourses } from "../../actions/course-actions";
|
||||
import { useDeleteCourse } from "../../hooks/useDeleteCourse";
|
||||
import { getAllRooms } from "@/src/modules/rooms/actions/room-actions";
|
||||
import { Button } from "@/src/components/ui/button";
|
||||
import { toast } from "sonner";
|
||||
|
|
@ -52,11 +53,24 @@ const CourseListView = () => {
|
|||
const [priceMin, setPriceMin] = useState<number | null>(null);
|
||||
const [priceMax, setPriceMax] = useState<number | null>(null);
|
||||
const [deleteMode, setDeleteMode] = useState(false);
|
||||
const [deleteDialogOpen, setDeleteDialogOpen] = useState(false);
|
||||
const [courseToDelete, setCourseToDelete] = useState<{ id: string; name: string } | null>(null);
|
||||
const [isDeleting, setIsDeleting] = useState(false);
|
||||
const [roomsMap, setRoomsMap] = useState<Record<string, string>>({});
|
||||
|
||||
const {
|
||||
deleteDialogOpen,
|
||||
setDeleteDialogOpen,
|
||||
courseToDelete,
|
||||
setCourseToDelete,
|
||||
isDeleting,
|
||||
handleDeleteClick,
|
||||
handleDeleteConfirm,
|
||||
} = useDeleteCourse({
|
||||
onSuccess: async () => {
|
||||
if (loadedDateFrom && loadedDateTo) {
|
||||
await loadCourses({ dateFrom: loadedDateFrom, dateTo: loadedDateTo }, "initial");
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
// Date range state for infinite scroll
|
||||
const [loadedDateFrom, setLoadedDateFrom] = useState<Date | null>(null);
|
||||
const [loadedDateTo, setLoadedDateTo] = useState<Date | null>(null);
|
||||
|
|
@ -228,33 +242,6 @@ const CourseListView = () => {
|
|||
setIsLoadingNewer(false);
|
||||
};
|
||||
|
||||
const requestDelete = (courseId: string, courseName: string) => {
|
||||
setCourseToDelete({ id: courseId, name: courseName });
|
||||
setDeleteDialogOpen(true);
|
||||
};
|
||||
|
||||
const confirmDelete = async () => {
|
||||
if (!courseToDelete) return;
|
||||
|
||||
setIsDeleting(true);
|
||||
|
||||
const result = await deleteCourse(courseToDelete.id);
|
||||
|
||||
setIsDeleting(false);
|
||||
setDeleteDialogOpen(false);
|
||||
setCourseToDelete(null);
|
||||
|
||||
if (result.success) {
|
||||
toast.success(result.message);
|
||||
// Reload courses with the current date range
|
||||
if (loadedDateFrom && loadedDateTo) {
|
||||
await loadCourses({ dateFrom: loadedDateFrom, dateTo: loadedDateTo }, "initial");
|
||||
}
|
||||
} else {
|
||||
toast.error(result.error || "Fehler beim Löschen");
|
||||
}
|
||||
};
|
||||
|
||||
const formatDate = (date: Date) => {
|
||||
return new Date(date).toLocaleDateString("de-DE", {
|
||||
weekday: "long",
|
||||
|
|
@ -515,7 +502,7 @@ const CourseListView = () => {
|
|||
status={course.status}
|
||||
isPast={isPastCourse(course.date)}
|
||||
showDeleteIcon={deleteMode}
|
||||
onDelete={() => requestDelete(course.id, course.name)}
|
||||
onDelete={() => handleDeleteClick(course.id, course.name)}
|
||||
onEdit={() => router.push(`/courses/edit/${course.id}`)}
|
||||
/>
|
||||
))}
|
||||
|
|
@ -543,10 +530,13 @@ const CourseListView = () => {
|
|||
|
||||
<DeleteDialog
|
||||
open={deleteDialogOpen}
|
||||
onOpenChange={setDeleteDialogOpen}
|
||||
onOpenChange={(open) => {
|
||||
setDeleteDialogOpen(open);
|
||||
if (!open) setCourseToDelete(null);
|
||||
}}
|
||||
itemName={courseToDelete?.name}
|
||||
topicName="Kurs"
|
||||
onConfirm={confirmDelete}
|
||||
onConfirm={handleDeleteConfirm}
|
||||
isLoading={isDeleting}
|
||||
/>
|
||||
</div>
|
||||
|
|
|
|||
50
src/modules/employee/hooks/useDeleteEmployee.ts
Normal file
50
src/modules/employee/hooks/useDeleteEmployee.ts
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
"use client";
|
||||
import { useState } from "react";
|
||||
import { deleteEmployee } from "../actions/employee-actions";
|
||||
import { toast } from "sonner";
|
||||
|
||||
interface UseDeleteEmployeeOptions {
|
||||
onSuccess?: (deletedId: string) => void;
|
||||
}
|
||||
|
||||
export function useDeleteEmployee({ onSuccess }: UseDeleteEmployeeOptions = {}) {
|
||||
const [deleteDialogOpen, setDeleteDialogOpen] = useState(false);
|
||||
const [employeeToDelete, setEmployeeToDelete] = useState<{ id: string; name: string } | null>(
|
||||
null
|
||||
);
|
||||
const [isDeleting, setIsDeleting] = useState(false);
|
||||
|
||||
const handleDeleteClick = (id: string, name: string) => {
|
||||
setEmployeeToDelete({ id, name });
|
||||
setDeleteDialogOpen(true);
|
||||
};
|
||||
|
||||
const handleDeleteConfirm = async () => {
|
||||
if (!employeeToDelete) return;
|
||||
|
||||
setIsDeleting(true);
|
||||
const result = await deleteEmployee(employeeToDelete.id);
|
||||
setIsDeleting(false);
|
||||
setDeleteDialogOpen(false);
|
||||
|
||||
if (result.success) {
|
||||
toast.success(result.message);
|
||||
const deletedId = employeeToDelete.id;
|
||||
setEmployeeToDelete(null);
|
||||
onSuccess?.(deletedId);
|
||||
} else {
|
||||
setEmployeeToDelete(null);
|
||||
toast.error(result.error || "Fehler beim Löschen des Mitarbeiters");
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
deleteDialogOpen,
|
||||
setDeleteDialogOpen,
|
||||
employeeToDelete,
|
||||
setEmployeeToDelete,
|
||||
isDeleting,
|
||||
handleDeleteClick,
|
||||
handleDeleteConfirm,
|
||||
};
|
||||
}
|
||||
|
|
@ -1,10 +1,11 @@
|
|||
import { Button } from "@/src/components/ui/button";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { useEffect, useState } from "react";
|
||||
import { getMyEmployees, deleteEmployee } from "../../actions/employee-actions";
|
||||
import { getMyEmployees } from "../../actions/employee-actions";
|
||||
import EmployeeListItem from "../components/EmployeeListItem";
|
||||
import { toast } from "sonner";
|
||||
import DeleteDialog from "@/src/components/layout/DeleteDialog";
|
||||
import { useDeleteEmployee } from "../../hooks/useDeleteEmployee";
|
||||
|
||||
type Employee = {
|
||||
id: string;
|
||||
|
|
@ -26,11 +27,18 @@ const EmployeeListView = () => {
|
|||
const [employees, setEmployees] = useState<Employee[]>([]);
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
const [deleteMode, setDeleteMode] = useState(false);
|
||||
const [deleteDialogOpen, setDeleteDialogOpen] = useState(false);
|
||||
const [employeeToDelete, setEmployeeToDelete] = useState<{ id: string; name: string } | null>(
|
||||
null
|
||||
);
|
||||
const [isDeleting, setIsDeleting] = useState(false);
|
||||
|
||||
const {
|
||||
deleteDialogOpen,
|
||||
setDeleteDialogOpen,
|
||||
employeeToDelete,
|
||||
setEmployeeToDelete,
|
||||
isDeleting,
|
||||
handleDeleteClick,
|
||||
handleDeleteConfirm,
|
||||
} = useDeleteEmployee({
|
||||
onSuccess: (deletedId) => setEmployees((prev) => prev.filter((e) => e.id !== deletedId)),
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
const loadEmployees = async () => {
|
||||
|
|
@ -47,34 +55,6 @@ const EmployeeListView = () => {
|
|||
loadEmployees();
|
||||
}, []);
|
||||
|
||||
const requestDelete = (employeeId: string, employeeName: string) => {
|
||||
setEmployeeToDelete({ id: employeeId, name: employeeName });
|
||||
setDeleteDialogOpen(true);
|
||||
};
|
||||
|
||||
const confirmDelete = async () => {
|
||||
if (!employeeToDelete) return;
|
||||
|
||||
setIsDeleting(true);
|
||||
|
||||
const result = await deleteEmployee(employeeToDelete.id);
|
||||
|
||||
setIsDeleting(false);
|
||||
setDeleteDialogOpen(false);
|
||||
setEmployeeToDelete(null);
|
||||
|
||||
if (result.success) {
|
||||
toast.success(result.message);
|
||||
// Reload employees
|
||||
const reloadResult = await getMyEmployees();
|
||||
if (reloadResult.success) {
|
||||
setEmployees(reloadResult.employees);
|
||||
}
|
||||
} else {
|
||||
toast.error(result.error || "Fehler beim Löschen");
|
||||
}
|
||||
};
|
||||
|
||||
const getEmployeeName = (employee: Employee) => {
|
||||
if (employee.firstName && employee.lastName) {
|
||||
return `${employee.firstName} ${employee.lastName}`;
|
||||
|
|
@ -131,7 +111,7 @@ const EmployeeListView = () => {
|
|||
status={employee.status || "draft"}
|
||||
isOnboarded={employee.isOnboarded}
|
||||
showDeleteIcon={deleteMode}
|
||||
onDelete={() => requestDelete(employee.id, getEmployeeName(employee))}
|
||||
onDelete={() => handleDeleteClick(employee.id, getEmployeeName(employee))}
|
||||
onEdit={() => router.push(`/employee/edit/${employee.id}`)}
|
||||
/>
|
||||
))}
|
||||
|
|
@ -140,10 +120,13 @@ const EmployeeListView = () => {
|
|||
|
||||
<DeleteDialog
|
||||
open={deleteDialogOpen}
|
||||
onOpenChange={setDeleteDialogOpen}
|
||||
onOpenChange={(open) => {
|
||||
setDeleteDialogOpen(open);
|
||||
if (!open) setEmployeeToDelete(null);
|
||||
}}
|
||||
itemName={employeeToDelete?.name}
|
||||
topicName="Mitarbeiter"
|
||||
onConfirm={confirmDelete}
|
||||
onConfirm={handleDeleteConfirm}
|
||||
isLoading={isDeleting}
|
||||
/>
|
||||
</div>
|
||||
|
|
|
|||
67
src/modules/rooms/hooks/useDeleteRoom.ts
Normal file
67
src/modules/rooms/hooks/useDeleteRoom.ts
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
"use client";
|
||||
import { useState } from "react";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { deleteRoom } from "../actions/room-actions";
|
||||
import { toast } from "sonner";
|
||||
|
||||
interface UseDeleteRoomOptions {
|
||||
onSuccess?: (deletedId: string) => void;
|
||||
}
|
||||
|
||||
export function useDeleteRoom({ onSuccess }: UseDeleteRoomOptions = {}) {
|
||||
const router = useRouter();
|
||||
const [deleteDialogOpen, setDeleteDialogOpen] = useState(false);
|
||||
const [roomToDelete, setRoomToDelete] = useState<{ id: string; name: string } | null>(null);
|
||||
const [isDeleting, setIsDeleting] = useState(false);
|
||||
|
||||
const handleDeleteClick = (id: string, name: string) => {
|
||||
setRoomToDelete({ id, name });
|
||||
setDeleteDialogOpen(true);
|
||||
};
|
||||
|
||||
const handleDeleteConfirm = async () => {
|
||||
if (!roomToDelete) return;
|
||||
|
||||
setIsDeleting(true);
|
||||
const result = await deleteRoom(roomToDelete.id);
|
||||
|
||||
if (result.success) {
|
||||
toast.success(result.message);
|
||||
setDeleteDialogOpen(false);
|
||||
const deletedId = roomToDelete.id;
|
||||
setRoomToDelete(null);
|
||||
onSuccess?.(deletedId);
|
||||
} else if (result.hasActiveCourses) {
|
||||
setDeleteDialogOpen(false);
|
||||
setRoomToDelete(null);
|
||||
toast.error(result.error, {
|
||||
duration: 8000,
|
||||
style: { maxWidth: "680px" },
|
||||
action: {
|
||||
label: "Kurse anzeigen",
|
||||
onClick: () => router.push(`/courses?room=${encodeURIComponent(result.roomName)}`),
|
||||
},
|
||||
actionButtonStyle: {
|
||||
backgroundColor: "#F4C00C",
|
||||
color: "#1E293B",
|
||||
fontWeight: "600",
|
||||
padding: "8px 14px",
|
||||
borderRadius: "6px",
|
||||
},
|
||||
});
|
||||
} else {
|
||||
toast.error(result.error || "Fehler beim Löschen des Raumes");
|
||||
}
|
||||
setIsDeleting(false);
|
||||
};
|
||||
|
||||
return {
|
||||
deleteDialogOpen,
|
||||
setDeleteDialogOpen,
|
||||
roomToDelete,
|
||||
setRoomToDelete,
|
||||
isDeleting,
|
||||
handleDeleteClick,
|
||||
handleDeleteConfirm,
|
||||
};
|
||||
}
|
||||
|
|
@ -6,6 +6,9 @@ import { Button } from "@/src/components/ui/button";
|
|||
import { createRoom, updateRoom } from "../../actions/room-actions";
|
||||
import { toast } from "sonner";
|
||||
import { Room } from "../../types/room.types";
|
||||
import { Trash2 } from "lucide-react";
|
||||
import DeleteDialog from "@/src/components/layout/DeleteDialog";
|
||||
import { useDeleteRoom } from "../../hooks/useDeleteRoom";
|
||||
|
||||
interface RoomsCreateViewProps {
|
||||
mode?: "create" | "edit";
|
||||
|
|
@ -19,6 +22,18 @@ const RoomsCreateView = ({ mode = "create", roomId, initialData }: RoomsCreateVi
|
|||
const [errors, setErrors] = useState<Record<string, string>>({});
|
||||
const [isSubmitting, setIsSubmitting] = useState(false);
|
||||
|
||||
const {
|
||||
deleteDialogOpen,
|
||||
setDeleteDialogOpen,
|
||||
roomToDelete,
|
||||
setRoomToDelete,
|
||||
isDeleting,
|
||||
handleDeleteClick,
|
||||
handleDeleteConfirm,
|
||||
} = useDeleteRoom({
|
||||
onSuccess: () => router.push("/rooms"),
|
||||
});
|
||||
|
||||
// Load initial data when in edit mode
|
||||
useEffect(() => {
|
||||
if (mode === "edit" && initialData) {
|
||||
|
|
@ -80,12 +95,23 @@ const RoomsCreateView = ({ mode = "create", roomId, initialData }: RoomsCreateVi
|
|||
|
||||
return (
|
||||
<div>
|
||||
<h1 className="text-3xl font-bold">{mode === "edit" ? "Raum bearbeiten" : "Raum anlegen"}</h1>
|
||||
<p className="text-xl mt-2">
|
||||
{mode === "edit"
|
||||
? "Ändern Sie den Raumnamen und speichern Sie Ihre Änderungen"
|
||||
: "Alle Räume können nach dem Speichern angepasst oder gelöscht werden"}
|
||||
</p>
|
||||
<div className="flex w-full items-center justify-between">
|
||||
<div>
|
||||
<h1 className="text-3xl font-bold">
|
||||
{mode === "edit" ? "Raum bearbeiten" : "Raum anlegen"}
|
||||
</h1>
|
||||
<p className="text-xl mt-2">
|
||||
{mode === "edit"
|
||||
? "Ändern Sie den Raumnamen und speichern Sie Ihre Änderungen"
|
||||
: "Alle Räume können nach dem Speichern angepasst oder gelöscht werden"}
|
||||
</p>
|
||||
</div>
|
||||
{mode === "edit" && (
|
||||
<Button variant="destructive" onClick={() => handleDeleteClick(roomId!, roomName)}>
|
||||
<Trash2 size={20} className="mb-1" /> Löschen
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
<div className="mt-6 flex flex-col gap-4 max-w-xl">
|
||||
<div>
|
||||
<InputComponent
|
||||
|
|
@ -111,6 +137,18 @@ const RoomsCreateView = ({ mode = "create", roomId, initialData }: RoomsCreateVi
|
|||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<DeleteDialog
|
||||
open={deleteDialogOpen}
|
||||
onOpenChange={(open) => {
|
||||
setDeleteDialogOpen(open);
|
||||
if (!open) setRoomToDelete(null);
|
||||
}}
|
||||
itemName={roomToDelete?.name}
|
||||
topicName="Raum"
|
||||
onConfirm={handleDeleteConfirm}
|
||||
isLoading={isDeleting}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
"use client";
|
||||
import { useEffect, useState } from "react";
|
||||
import { getMyRooms, deleteRoom } from "../../actions/room-actions";
|
||||
import { getMyRooms } from "../../actions/room-actions";
|
||||
import { toast } from "sonner";
|
||||
import { useRouter } from "next/navigation";
|
||||
import RoomsListItem from "../components/RoomsListItem";
|
||||
import DeleteDialog from "@/src/components/layout/DeleteDialog";
|
||||
import { useDeleteRoom } from "../../hooks/useDeleteRoom";
|
||||
|
||||
type Room = {
|
||||
id: string;
|
||||
|
|
@ -22,9 +23,18 @@ const RoomsListView = ({ deleteMode }: RoomsListViewProps) => {
|
|||
const router = useRouter();
|
||||
const [rooms, setRooms] = useState<Room[]>([]);
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
const [deleteDialogOpen, setDeleteDialogOpen] = useState(false);
|
||||
const [roomToDelete, setRoomToDelete] = useState<{ id: string; name: string } | null>(null);
|
||||
const [isDeleting, setIsDeleting] = useState(false);
|
||||
|
||||
const {
|
||||
deleteDialogOpen,
|
||||
setDeleteDialogOpen,
|
||||
roomToDelete,
|
||||
setRoomToDelete,
|
||||
isDeleting,
|
||||
handleDeleteClick,
|
||||
handleDeleteConfirm,
|
||||
} = useDeleteRoom({
|
||||
onSuccess: (deletedId) => setRooms((prev) => prev.filter((room) => room.id !== deletedId)),
|
||||
});
|
||||
|
||||
// Load rooms
|
||||
const loadRooms = async () => {
|
||||
|
|
@ -46,49 +56,6 @@ const RoomsListView = ({ deleteMode }: RoomsListViewProps) => {
|
|||
fetchRooms();
|
||||
}, []);
|
||||
|
||||
// Handle delete click
|
||||
const handleDeleteClick = (id: string, name: string) => {
|
||||
setRoomToDelete({ id, name });
|
||||
setDeleteDialogOpen(true);
|
||||
};
|
||||
|
||||
// Confirm delete
|
||||
const handleDeleteConfirm = async () => {
|
||||
if (!roomToDelete) return;
|
||||
|
||||
setIsDeleting(true);
|
||||
const result = await deleteRoom(roomToDelete.id);
|
||||
|
||||
if (result.success) {
|
||||
toast.success(result.message);
|
||||
// Remove the deleted room from the list
|
||||
setRooms((prev) => prev.filter((room) => room.id !== roomToDelete.id));
|
||||
setDeleteDialogOpen(false);
|
||||
setRoomToDelete(null);
|
||||
} else if (result.hasActiveCourses) {
|
||||
setDeleteDialogOpen(false);
|
||||
setRoomToDelete(null);
|
||||
toast.error(result.error, {
|
||||
duration: 8000,
|
||||
style: { maxWidth: "680px" },
|
||||
action: {
|
||||
label: "Kurse anzeigen",
|
||||
onClick: () => router.push(`/courses?room=${encodeURIComponent(result.roomName)}`),
|
||||
},
|
||||
actionButtonStyle: {
|
||||
backgroundColor: "#F4C00C",
|
||||
color: "#1E293B",
|
||||
fontWeight: "600",
|
||||
padding: "8px 14px",
|
||||
borderRadius: "6px",
|
||||
},
|
||||
});
|
||||
} else {
|
||||
toast.error(result.error || "Fehler beim Löschen des Raumes");
|
||||
}
|
||||
setIsDeleting(false);
|
||||
};
|
||||
|
||||
// Handle edit click
|
||||
const handleEditClick = (id: string) => {
|
||||
router.push(`/rooms/edit/${id}`);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue