add: more things

Signed-off-by: Kenneth Obsequio <k80308392@gmail.com>
This commit is contained in:
2026-07-06 15:21:36 +08:00
parent 41e98bb602
commit 244aa607f7
71 changed files with 2998 additions and 1014 deletions
+1 -1
View File
@@ -17,7 +17,7 @@ import { AdminProvider } from "@/contexts/provider/AdminProvider" // ← add
import { TooltipProvider } from "@/components/ui/tooltip"
import { Badge } from "@/components/ui/badge"
import { Toaster } from "sonner"
import { Toaster } from "@/components/ui/sonner"
import { cn } from "@/lib/utils"
import UserMenu from "@/components/generic/UserMenu"
@@ -248,7 +248,12 @@ export default function CourseAssessment() {
setLocalAssessment(result);
} catch (err) {
if (err?.response?.status !== 404) {
toast.error(err?.response?.data?.message ?? "Could not load assessment.");
toast(err?.response?.data?.message ?? "Could not load assessment.", {
action: {
label: "Close",
onClick: () => {}
}
});
}
} finally {
setInitializing(false);
@@ -355,7 +355,12 @@ export default function ViewAssessment() {
setLocalAssessment(data?.data?.data ?? null);
} catch (err) {
if (err?.response?.status !== 404) {
toast.error(err?.response?.data?.message ?? "Could not load assessment.");
toast(err?.response?.data?.message ?? "Could not load assessment.", {
action: {
label: "Close",
onClick: () => {}
}
});
}
}
})();
@@ -240,7 +240,12 @@ export default function ModifyQuiz() {
setLocalQuiz(result);
} catch (err) {
if (err?.response?.status !== 404) {
toast.error(err?.response?.data?.message ?? "Could not load quiz.");
toast(err?.response?.data?.message ?? "Could not load quiz.", {
action: {
label: "Close",
onClick: () => {}
}
});
}
// 404 → no quiz yet, stay in create mode with localQuiz = null
} finally {
@@ -41,7 +41,12 @@ export default function NotificationSettings() {
const { data } = await api.get("/admin/notification-settings");
setSettings(data?.data ?? []);
} catch (err) {
toast.error(err?.response?.data?.message ?? "Failed to load notification settings.");
toast(err?.response?.data?.message ?? "Failed to load notification settings.", {
action: {
label: "Close",
onClick: () => {}
}
});
} finally {
setLoading(false);
}
@@ -58,9 +63,22 @@ export default function NotificationSettings() {
});
const updated = data?.data?.data;
setSettings((prev) => prev.map((s) => (s.job_name === jobName ? { ...s, ...updated } : s)));
toast.success(`${JOB_LABELS[jobName]?.label ?? jobName} ${enabled ? "enabled" : "disabled"}.`);
toast(
`${JOB_LABELS[jobName]?.label ?? jobName} ${enabled ? "enabled" : "disabled"}.`,
{
action: {
label: "Close",
onClick: () => {}
}
}
);
} catch (err) {
toast.error(err?.response?.data?.message ?? "Failed to update setting.");
toast(err?.response?.data?.message ?? "Failed to update setting.", {
action: {
label: "Close",
onClick: () => {}
}
});
} finally {
setSavingJob(null);
}
@@ -75,9 +93,19 @@ export default function NotificationSettings() {
});
const updated = data?.data?.data;
setSettings((prev) => prev.map((s) => (s.job_name === jobName ? { ...s, ...updated, preset } : s)));
toast.success("Schedule updated — took effect immediately, no restart needed.");
toast("Schedule updated — took effect immediately, no restart needed.", {
action: {
label: "Close",
onClick: () => {}
}
});
} catch (err) {
toast.error(err?.response?.data?.message ?? "Failed to update schedule.");
toast(err?.response?.data?.message ?? "Failed to update schedule.", {
action: {
label: "Close",
onClick: () => {}
}
});
} finally {
setSavingJob(null);
}
@@ -100,10 +100,20 @@ export default function PaymentPolicy() {
},
promo_rules: promoRules,
});
toast.success("Payment policy saved.");
toast("Payment policy saved.", {
action: {
label: "Close",
onClick: () => {}
}
});
navigate("/admin/tiers/plans");
} catch (err) {
toast.error(err?.response?.data?.message ?? "Could not save payment policy.");
toast(err?.response?.data?.message ?? "Could not save payment policy.", {
action: {
label: "Close",
onClick: () => {}
}
});
} finally {
setSaving(false);
}
@@ -113,10 +123,25 @@ export default function PaymentPolicy() {
const handleAddPromo = () => {
const code = addForm.code.trim().toUpperCase();
if (!code) { toast.error("Code is required."); return; }
if (!addForm.value || Number(addForm.value) <= 0) { toast.error("Value must be greater than 0."); return; }
if (!code) { toast("Code is required.", {
action: {
label: "Close",
onClick: () => {}
}
}); return; }
if (!addForm.value || Number(addForm.value) <= 0) { toast("Value must be greater than 0.", {
action: {
label: "Close",
onClick: () => {}
}
}); return; }
if (promoRules.some((r) => r.code.toUpperCase() === code)) {
toast.error("A rule with this code already exists."); return;
toast("A rule with this code already exists.", {
action: {
label: "Close",
onClick: () => {}
}
}); return;
}
const rule = {
+30 -5
View File
@@ -220,9 +220,19 @@ function PaymentPolicyTab({ planId, plan }) {
},
promo_rules: promoRules,
});
toast.success("Payment policy saved.");
toast("Payment policy saved.", {
action: {
label: "Close",
onClick: () => {}
}
});
} catch (err) {
toast.error(err?.response?.data?.message ?? "Could not save payment policy.");
toast(err?.response?.data?.message ?? "Could not save payment policy.", {
action: {
label: "Close",
onClick: () => {}
}
});
} finally {
setSaving(false);
}
@@ -230,9 +240,24 @@ function PaymentPolicyTab({ planId, plan }) {
const handleAddPromo = () => {
const code = addForm.code.trim().toUpperCase();
if (!code) { toast.error("Code is required."); return; }
if (!addForm.value || Number(addForm.value) <= 0) { toast.error("Value must be greater than 0."); return; }
if (promoRules.some((r) => r.code.toUpperCase() === code)) { toast.error("A rule with this code already exists."); return; }
if (!code) { toast("Code is required.", {
action: {
label: "Close",
onClick: () => {}
}
}); return; }
if (!addForm.value || Number(addForm.value) <= 0) { toast("Value must be greater than 0.", {
action: {
label: "Close",
onClick: () => {}
}
}); return; }
if (promoRules.some((r) => r.code.toUpperCase() === code)) { toast("A rule with this code already exists.", {
action: {
label: "Close",
onClick: () => {}
}
}); return; }
const rule = {
code,
+12 -2
View File
@@ -151,10 +151,20 @@ export default function EditUser() {
const res = await updateUser(id, payload);
if (res) {
toast.success("User updated successfully.");
toast("User updated successfully.", {
action: {
label: "Close",
onClick: () => {}
}
});
navigate(`../view/${id}`);
} else {
toast.error("Failed to update user.");
toast("Failed to update user.", {
action: {
label: "Close",
onClick: () => {}
}
});
}
};