feat: quiz

This commit is contained in:
gosangam
2026-10-15 19:40:28 +05:30
parent 3f3fa9a720
commit 111485a43e
20 changed files with 2178 additions and 224 deletions
+21 -12
View File
@@ -22,8 +22,10 @@ import { Input } from "@/components/ui/input";
import { RichTextarea } from "@/components/ui/rich-textarea";
import { fmtDate } from "@/lib/utils";
import { DiscipleLinkModal } from "./disciple-link-modal";
import { useStaff } from "@/components/staff-context";
export default function UsersPage() {
const { can } = useStaff();
const [q, setQ] = useState("");
const fetcher = useCallback(
(limit: number, offset: number) => api.users(q, limit, offset),
@@ -79,22 +81,29 @@ export default function UsersPage() {
}
function menuItems(u: AdminUser): MenuItem[] {
const items: MenuItem[] = [
{ label: "Send notification", onClick: () => setNotify(u) },
{ label: "Edit limits", onClick: () => setLimitsUser(u) },
{
// Only what this role may do. The BFF refuses the rest regardless.
const items: MenuItem[] = [];
if (can("users:notify")) {
items.push({ label: "Send notification", onClick: () => setNotify(u) });
}
if (can("users:limits")) {
items.push({ label: "Edit limits", onClick: () => setLimitsUser(u) });
}
if (can("disciples:manage")) {
items.push({
label: u.disciple_id ? "Change disciple link" : "Link direct disciple",
onClick: () => setDiscipleUser(u),
},
];
if (u.disciple_id) {
items.push({
label: "Remove disciple link",
onClick: () => removeDiscipleLink(u),
});
if (u.disciple_id) {
items.push({
label: "Remove disciple link",
onClick: () => removeDiscipleLink(u),
});
}
}
// No ban option for fellow admins (avoid locking each other out).
if (u.role !== "admin") {
// No ban option for staff: removing a staff member is a superadmin job,
// done from the Staff page — and the BFF refuses it from here anyway.
if (can("users:ban") && !u.admin_role) {
items.push({
label: u.banned_at ? "Unban account" : "Ban account",
onClick: () => toggleBan(u),