diff --git a/.replit b/.replit
index c806144..10e1957 100644
--- a/.replit
+++ b/.replit
@@ -40,3 +40,4 @@ args = "npm run dev"
waitForPort = 5000
[agent]
+integrations = ["javascript_database==1.0.0", "javascript_log_in_with_replit==1.0.0", "javascript_object_storage==1.0.0"]
diff --git a/client/src/App.tsx b/client/src/App.tsx
index 747e541..ef9e63a 100644
--- a/client/src/App.tsx
+++ b/client/src/App.tsx
@@ -8,6 +8,7 @@ import VideoPage from "@/pages/VideoPage";
import FolxStadlPage from "@/pages/FolxStadlPage";
import GeschichteLiedPage from "@/pages/GeschichteLiedPage";
import GipfelstammtischPage from "@/pages/GipfelstammtischPage";
+import AdminPage from "@/pages/admin";
import NotFound from "@/pages/not-found";
function Router() {
@@ -18,6 +19,7 @@ function Router() {
+
);
diff --git a/client/src/components/loading-spinner.tsx b/client/src/components/loading-spinner.tsx
index b41497d..d0a5138 100644
--- a/client/src/components/loading-spinner.tsx
+++ b/client/src/components/loading-spinner.tsx
@@ -4,7 +4,7 @@ interface LoadingSpinnerProps {
className?: string;
}
-export default function LoadingSpinner({ size = 'md', text = 'Loading...', className = '' }: LoadingSpinnerProps) {
+export function LoadingSpinner({ size = 'md', text = 'Loading...', className = '' }: LoadingSpinnerProps) {
const sizeClasses = {
sm: 'w-6 h-6',
md: 'w-10 h-10',
@@ -25,4 +25,6 @@ export default function LoadingSpinner({ size = 'md', text = 'Loading...', class
{text}
);
-}
\ No newline at end of file
+}
+
+export default LoadingSpinner;
\ No newline at end of file
diff --git a/client/src/hooks/useAuth.ts b/client/src/hooks/useAuth.ts
new file mode 100644
index 0000000..d87fe27
--- /dev/null
+++ b/client/src/hooks/useAuth.ts
@@ -0,0 +1,16 @@
+import { useQuery } from "@tanstack/react-query";
+
+export function useAuth() {
+ const { data: user, isLoading } = useQuery({
+ queryKey: ["/api/auth/user"],
+ retry: false,
+ });
+
+ return {
+ user,
+ isLoading,
+ isAuthenticated: !!user,
+ isAdmin: user?.isAdmin || false,
+ isSuperAdmin: user?.isSuperAdmin || false,
+ };
+}
\ No newline at end of file
diff --git a/client/src/pages/admin.tsx b/client/src/pages/admin.tsx
new file mode 100644
index 0000000..2c26030
--- /dev/null
+++ b/client/src/pages/admin.tsx
@@ -0,0 +1,354 @@
+import { useState } from "react";
+import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
+import { useAuth } from "@/hooks/useAuth";
+import { Button } from "@/components/ui/button";
+import { Input } from "@/components/ui/input";
+import { Label } from "@/components/ui/label";
+import { Textarea } from "@/components/ui/textarea";
+import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
+import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
+import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger } from "@/components/ui/dialog";
+import { Badge } from "@/components/ui/badge";
+import { useToast } from "@/hooks/use-toast";
+import { LoadingSpinner } from "@/components/loading-spinner";
+import { apiRequest } from "@/lib/queryClient";
+import type { Video } from "@shared/schema";
+import { Shield, Edit, Upload, Search, Filter, Save, X } from "lucide-react";
+
+export default function AdminPage() {
+ const { user, isLoading: authLoading, isAuthenticated, isAdmin } = useAuth();
+ const { toast } = useToast();
+ const queryClient = useQueryClient();
+
+ const [search, setSearch] = useState("");
+ const [selectedVideo, setSelectedVideo] = useState