add: more commits

Signed-off-by: Kenneth Obsequio <k80308392@gmail.com>
This commit is contained in:
2026-07-03 21:40:10 +08:00
parent ad48f8add1
commit 72298b86cd
10 changed files with 550 additions and 7 deletions
@@ -0,0 +1,20 @@
// Reference-only registry of {{placeholder}} tokens available per system
// notification type. Purely informational for the admin editor — the backend
// derives the real substitution data from wherever renderNotification({ type,
// data }) is called in code, this just tells the admin what's actually
// available to reference. Mirrors emailTemplatePlaceholders.data.js.
export const NOTIFICATION_TEMPLATE_PLACEHOLDERS = {
task_overdue: ["count", "task_word"],
user_registration: ["groupName", "groupCode", "userEmail"],
nogrp_user_registered: ["userEmail", "regType"],
task_requirements_updated: ["taskName", "taskListId", "groupId"],
user_task_overdue: ["count", "task_label", "task_list_ids"],
task_reminder: ["taskName", "deadline", "taskListId", "groupId"],
course_unlocked: ["courseTitle", "courseUuid"],
course_completed: ["courseTitle", "courseUuid"],
certificate_issued: ["courseTitle", "courseUuid"],
welcome: ["greeting", "group_suffix", "groupName", "groupCode", "accType"],
nogrp_welcome: [],
assessment_updated: ["assessmentTitle", "courseTitle", "courseUuid"],
tier_expired: ["planLabel", "tier", "label", "planId"],
};
@@ -0,0 +1,12 @@
// A template is "sent" once it has a live title/message — that's the only
// content services/notificationTemplate.service.js's renderNotification() ever
// reads on the backend. Editing a sent template writes to draft_title/
// draft_message instead, so "pending changes" means there's a draft sitting on
// top of the live version. Mirrors emailTemplateStatus.data.js.
export const hasPendingChanges = (t) =>
t?.status === "sent" && (t?.draft_title != null || t?.draft_message != null);
export const STATUS_META = {
draft: { label: "Draft", badgeClass: "bg-muted text-muted-foreground border-border" },
sent: { label: "Sent", badgeClass: "bg-emerald-100 text-emerald-700 border-emerald-400 dark:bg-emerald-900/40 dark:text-emerald-400 dark:border-emerald-700" },
};
@@ -0,0 +1,20 @@
import { ListChecks, GraduationCap, Megaphone, ClipboardCheck, CreditCard, UserPlus, Users } from "lucide-react";
// Groups notification templates by the `notify_type` written into the
// delivered notification row — every row here is is_system, so a category
// axis (like email templates' announcement/advertisement/system/other) would
// always resolve to a single value and add nothing. This is the axis that
// actually varies. Mirrors the shape of emailTemplateCategories.data.js.
export const NOTIFICATION_TEMPLATE_TYPES = [
{ value: "task_overdue", label: "Tasks (Admin)", icon: ListChecks },
{ value: "task", label: "Tasks (User)", icon: ListChecks },
{ value: "course", label: "Courses", icon: GraduationCap },
{ value: "announcement", label: "Announcements", icon: Megaphone },
{ value: "assessment", label: "Assessments", icon: ClipboardCheck },
{ value: "tier_expired", label: "Subscriptions", icon: CreditCard },
{ value: "user_registration", label: "New Registrations", icon: UserPlus },
{ value: "nogrp_user_registered", label: "Unaffiliated Users", icon: Users },
];
export const getNotificationTemplateType = (value) =>
NOTIFICATION_TEMPLATE_TYPES.find((t) => t.value === value) ?? null;