diff --git a/backend/main.py b/backend/main.py
index 1a0b16a..327b54f 100644
--- a/backend/main.py
+++ b/backend/main.py
@@ -298,8 +298,8 @@ def bulk_delete_students(payload: DeleteUsersRequest, session: Session = Depends
user = session.get(models.User, uid)
if user:
# Delete associated records manually since foreign key cascade might not be configured in sqlmodel by default
- session.exec(delete(models.Attempt).where(models.Attempt.user_id == uid))
session.exec(delete(models.Mistake).where(models.Mistake.user_id == uid))
+ session.exec(delete(models.Attempt).where(models.Attempt.user_id == uid))
session.exec(delete(models.Transaction).where(models.Transaction.user_id == uid))
session.exec(delete(models.Subscription).where(models.Subscription.user_id == uid))
session.exec(delete(models.StudyPlan).where(models.StudyPlan.user_id == uid))
diff --git a/src/app/admin/page.tsx b/src/app/admin/page.tsx
index 0bcefe6..a1dc207 100644
--- a/src/app/admin/page.tsx
+++ b/src/app/admin/page.tsx
@@ -1,20 +1,8 @@
-"use client"
+"use client"
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
-import { Badge } from "@/components/ui/badge"
import { Button } from "@/components/ui/button"
import { Terminal, Users, Database, Activity, RefreshCw } from "lucide-react"
-import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer, AreaChart, Area } from 'recharts'
-
-const data = [
- { name: 'Mon', accuracy: 88, tokens: 1.2 },
- { name: 'Tue', accuracy: 90, tokens: 1.5 },
- { name: 'Wed', accuracy: 89, tokens: 1.8 },
- { name: 'Thu', accuracy: 92, tokens: 2.1 },
- { name: 'Fri', accuracy: 95, tokens: 2.4 },
- { name: 'Sat', accuracy: 94, tokens: 2.2 },
- { name: 'Sun', accuracy: 96, tokens: 2.8 },
-];
export default function AdminDashboard() {
return (
@@ -22,14 +10,14 @@ export default function AdminDashboard() {
- {/* KPI Stats */}
+ {/* KPI Stats Placeholder */}
@@ -37,8 +25,8 @@ export default function AdminDashboard() {
- ₹12.4M
- +14.2% from last month
+ --
+ No live data available
@@ -47,18 +35,18 @@ export default function AdminDashboard() {
- 45,231
- +2,401 this week
+ --
+ Manage from Students tab
- AI Agent Accuracy
+ System Status
- 96.4%
- Based on 1.2M interactions
+ Online
+ All services operational
@@ -67,134 +55,16 @@ export default function AdminDashboard() {
- 142k
- 1.2k added today
+ --
+ Manage from Tests tab
-
- {/* Charts */}
-
-
- AI Token Usage vs Accuracy
-
-
-
-
-
-
-
-
-
-
-
-
- `${value}M`} />
-
-
-
-
-
-
-
- {/* Live Agent Status */}
-
-
- Live Agent Status
-
-
-
-
-
-
-
-
-
-
DPP Generator
-
Latency: 142ms
-
-
-
Healthy
-
-
-
-
-
-
-
-
-
-
Tutor Agent
-
Latency: 840ms
-
-
-
Healthy
-
-
-
-
-
-
-
-
-
Evaluator Node
-
Latency: 2100ms
-
-
-
Degraded
-
-
-
+
+
Welcome to the Admin Portal
+
Use the sidebar to navigate to Students, Tests, Questions, and System Settings. Live analytics charts will be available here in the future.
-
- {/* Question Bank Manager Preview */}
-
-
-
- Recent Question Uploads
-
-
-
-
-
-
-
-
- | ID |
- Subject |
- Topic |
- Preview |
- Actions |
-
-
-
-
- | #Q-8942 |
- Physics |
- Thermodynamics |
- An ideal gas undergoes an isothermal expansion... |
-
-
- |
-
-
- | #Q-8941 |
- Math |
- Calculus |
- Evaluate the integral of e^x sin(x) dx... |
-
-
- |
-
-
-
-
-
-
)
}
diff --git a/src/app/dashboard/layout.tsx b/src/app/dashboard/layout.tsx
index dc40dc6..71262e2 100644
--- a/src/app/dashboard/layout.tsx
+++ b/src/app/dashboard/layout.tsx
@@ -12,7 +12,6 @@ import { StreakCounter } from "@/components/StreakCounter"
import { AITutorChat } from "@/components/AI/AITutorChat"
import { useActiveUser, DEMO_USERS, isDemoUser } from "@/hooks/useActiveUser"
import { StreakOnboardingModal } from "@/components/Dashboard/StreakOnboardingModal"
-import { BulkUserPasswordModal } from "@/components/Dashboard/BulkUserPasswordModal"
import { Badge } from "@/components/ui/badge"
import MaintenanceScreen from "@/components/MaintenanceScreen"
@@ -320,6 +319,9 @@ export default function DashboardLayout({ children }: { children: ReactNode }) {
Edit Profile
+
+ Change Password
+
{isDemoUser(userId) && (
*/}
-
-
- Change Password
- Update your account password
-
-
-
-
-
- setCurrentPassword(e.target.value)}
- className="w-full bg-secondary/50 border border-border rounded-lg px-4 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-[var(--cyan-ai)]"
- placeholder="Enter current password"
- />
-
-
-
-
- setNewPassword(e.target.value)}
- className="w-full bg-secondary/50 border border-border rounded-lg px-4 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-[var(--cyan-ai)]"
- placeholder="Enter new password"
- />
-
-
-
- setConfirmPassword(e.target.value)}
- className="w-full bg-secondary/50 border border-border rounded-lg px-4 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-[var(--cyan-ai)]"
- placeholder="Confirm new password"
- />
-
-
-
-
-
-
-
+
diff --git a/src/app/dashboard/settings/password/page.tsx b/src/app/dashboard/settings/password/page.tsx
new file mode 100644
index 0000000..cdeea22
--- /dev/null
+++ b/src/app/dashboard/settings/password/page.tsx
@@ -0,0 +1,115 @@
+"use client";
+
+import { fetchWithAuth } from "@/lib/apiClient";
+import { useState } from "react";
+import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
+import { Button } from "@/components/ui/button";
+import { Lock } from "lucide-react";
+
+export default function PasswordPage() {
+ const [currentPassword, setCurrentPassword] = useState("");
+ const [newPassword, setNewPassword] = useState("");
+ const [confirmPassword, setConfirmPassword] = useState("");
+ const [passwordSaving, setPasswordSaving] = useState(false);
+
+ const handleChangePassword = async () => {
+ if (newPassword !== confirmPassword) {
+ alert("New passwords do not match.");
+ return;
+ }
+ setPasswordSaving(true);
+ try {
+ const res = await fetchWithAuth("/api/auth/change-password", {
+ method: "POST",
+ headers: { "Content-Type": "application/json" },
+ body: JSON.stringify({
+ current_password: currentPassword,
+ new_password: newPassword,
+ }),
+ });
+ const data = await res.json();
+ if (res.ok) {
+ alert(data.message || "Password updated successfully!");
+ setCurrentPassword("");
+ setNewPassword("");
+ setConfirmPassword("");
+ } else {
+ alert("Failed to change password: " + (data.detail || "Unknown error"));
+ }
+ } catch (err) {
+ console.error(err);
+ alert("Network error. Could not change password.");
+ } finally {
+ setPasswordSaving(false);
+ }
+ };
+
+ return (
+
+
+
+
+
+
+
+ Change Password
+
+
+ Update your account password securely.
+
+
+
+
+
+
+ Change Password
+ Update your account password
+
+
+
+
+
+ setCurrentPassword(e.target.value)}
+ className="w-full bg-secondary/50 border border-border rounded-lg px-4 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-[var(--cyan-ai)]"
+ placeholder="Enter current password"
+ />
+
+
+
+
+ setNewPassword(e.target.value)}
+ className="w-full bg-secondary/50 border border-border rounded-lg px-4 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-[var(--cyan-ai)]"
+ placeholder="Enter new password"
+ />
+
+
+
+ setConfirmPassword(e.target.value)}
+ className="w-full bg-secondary/50 border border-border rounded-lg px-4 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-[var(--cyan-ai)]"
+ placeholder="Confirm new password"
+ />
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/src/components/Dashboard/BulkUserPasswordModal.tsx b/src/components/Dashboard/BulkUserPasswordModal.tsx
deleted file mode 100644
index 659e0c5..0000000
--- a/src/components/Dashboard/BulkUserPasswordModal.tsx
+++ /dev/null
@@ -1,129 +0,0 @@
-"use client";
-
-import { useState } from "react";
-import { Lock, Eye, EyeOff } from "lucide-react";
-import { fetchWithAuth } from "@/lib/apiClient";
-import { Button } from "@/components/ui/button";
-
-interface BulkUserPasswordModalProps {
- isOpen: boolean;
- onSuccess: () => void;
-}
-
-export function BulkUserPasswordModal({ isOpen, onSuccess }: BulkUserPasswordModalProps) {
- const [currentPassword, setCurrentPassword] = useState("");
- const [newPassword, setNewPassword] = useState("");
- const [confirmPassword, setConfirmPassword] = useState("");
- const [showCurrent, setShowCurrent] = useState(false);
- const [showNew, setShowNew] = useState(false);
- const [showConfirm, setShowConfirm] = useState(false);
- const [saving, setSaving] = useState(false);
- const [error, setError] = useState("");
-
- if (!isOpen) return null;
-
- const handleSubmit = async (e: React.FormEvent) => {
- e.preventDefault();
- if (newPassword !== confirmPassword) {
- setError("New passwords do not match.");
- return;
- }
-
- setSaving(true);
- setError("");
- try {
- const res = await fetchWithAuth("/api/auth/change-password", {
- method: "POST",
- headers: { "Content-Type": "application/json" },
- body: JSON.stringify({
- current_password: currentPassword,
- new_password: newPassword,
- }),
- });
- const data = await res.json();
- if (res.ok) {
- onSuccess();
- } else {
- setError("Failed: " + (data.detail || "Unknown error"));
- }
- } catch (err) {
- setError("Network error. Could not update password.");
- } finally {
- setSaving(false);
- }
- };
-
- return (
-
-
-
-
-
-
-
Set Your Password
-
- Welcome! Since your account was created by the admin, please set a new personal password to continue.
-
-
-
- {error &&
{error}
}
-
-
-
-
- );
-}