mirror of
https://github.com/rgrgogu/new_starr.git
synced 2026-09-27 00:12:54 +08:00
add: more commits
Signed-off-by: Kenneth Obsequio <k80308392@gmail.com>
This commit is contained in:
@@ -4,7 +4,6 @@ import {
|
||||
Users, Timer,
|
||||
Tag, LockIcon, Check,
|
||||
} from "lucide-react";
|
||||
import { ThemeSwitcher } from "../components/ThemeSwitcher";
|
||||
import AppBreadcrumb from "@/components/generic/Breadcrumb/AppBreadcrumb";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import { Skeleton } from "@/components/ui/skeleton";
|
||||
@@ -131,13 +130,15 @@ const GroupsTable = ({ groups, onView }) => (
|
||||
<TableHead className="w-10 text-center px-4">#</TableHead>
|
||||
<TableHead className="px-4">Group Name</TableHead>
|
||||
<TableHead className="px-4">Code</TableHead>
|
||||
<TableHead className="px-4 w-full">Description</TableHead>
|
||||
<TableHead className="px-4">Description</TableHead>
|
||||
<TableHead className="px-4">Task Lists</TableHead>
|
||||
<TableHead className="px-4" />
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
{groups.map((g, i) => {
|
||||
const isDefault = g.group_code === 'NOGRP';
|
||||
const taskListCount = Number(g.task_list_count ?? g.taskLists?.length ?? 0);
|
||||
return (
|
||||
<TableRow key={g.group_id}>
|
||||
<TableCell className="text-center px-4 text-muted-foreground tabular-nums">
|
||||
@@ -147,12 +148,15 @@ const GroupsTable = ({ groups, onView }) => (
|
||||
<TableCell className="px-4">
|
||||
<Badge variant="outline" className="font-mono text-xs">{g.group_code}</Badge>
|
||||
</TableCell>
|
||||
<TableCell className="px-4 text-muted-foreground">
|
||||
<TableCell className="px-4 text-muted-foreground ">
|
||||
{isDefault
|
||||
? <span className="text-xs italic">Awaiting assignment by admin</span>
|
||||
: (g.description ?? <span className="text-xs text-muted-foreground/50">—</span>)
|
||||
}
|
||||
</TableCell>
|
||||
<TableCell className="px-4">
|
||||
{taskListCount}
|
||||
</TableCell>
|
||||
<TableCell className="px-4 text-right">
|
||||
<Button size="sm" variant="outline" onClick={() => onView(g)}>
|
||||
View
|
||||
@@ -175,6 +179,7 @@ const GroupsTableSkeleton = () => (
|
||||
<TableHead className="px-4">Group Name</TableHead>
|
||||
<TableHead className="px-4">Code</TableHead>
|
||||
<TableHead className="px-4 w-full">Description</TableHead>
|
||||
<TableHead className="px-4 text-center whitespace-nowrap">Task Lists</TableHead>
|
||||
<TableHead className="px-4" />
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
@@ -185,6 +190,7 @@ const GroupsTableSkeleton = () => (
|
||||
<TableCell className="px-4"><Skeleton className="h-4 w-32" /></TableCell>
|
||||
<TableCell className="px-4"><Skeleton className="h-5 w-16 rounded-full" /></TableCell>
|
||||
<TableCell className="px-4"><Skeleton className="h-4 w-48" /></TableCell>
|
||||
<TableCell className="px-4"><Skeleton className="h-4 w-8 mx-auto" /></TableCell>
|
||||
<TableCell className="px-4 text-right"><Skeleton className="h-8 w-14 ml-auto" /></TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
@@ -201,7 +207,7 @@ const Client = () => {
|
||||
const { courses, coursesLoading, getCourses } = useClientCourses();
|
||||
const { myTier, getMyTier, tierMap } = useClientTiers();
|
||||
const { groups, fetchGroups, loading: groupLoading } = useGroup();
|
||||
const { advertisements, loading: adLoading, getActiveAdvertisement, trackClick } = useClientAdvertisements();
|
||||
const { advertisements, loading: adLoading, getActiveAdvertisements, handleAdCtaClick, dismissPopupForever } = useClientAdvertisements();
|
||||
|
||||
const [modalOpen, setModalOpen] = useState(false);
|
||||
const [selectedCourse, setSelectedCourse] = useState(null);
|
||||
@@ -210,8 +216,8 @@ const Client = () => {
|
||||
|
||||
const userTier = myTier?.tier ?? "free";
|
||||
|
||||
const heroAd = advertisements.hero ?? null;
|
||||
const popupAd = advertisements.popup ?? null;
|
||||
const heroAd = advertisements["dashboard.hero"] ?? null;
|
||||
const popupAd = advertisements["dashboard.popup"] ?? null;
|
||||
|
||||
// Show welcome toast on first registration
|
||||
useEffect(() => {
|
||||
@@ -234,24 +240,12 @@ const Client = () => {
|
||||
|
||||
// ── Resolve active hero + popup ads once on mount ────────────────────────
|
||||
useEffect(() => {
|
||||
getActiveAdvertisement("hero");
|
||||
getActiveAdvertisement("popup").then((ad) => {
|
||||
if (ad) setPopupOpen(true);
|
||||
getActiveAdvertisements(["dashboard.hero", "dashboard.popup"]).then((result) => {
|
||||
if (result["dashboard.popup"]) setPopupOpen(true);
|
||||
});
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, []);
|
||||
|
||||
// ── CTA click — track then navigate ───────────────────────────────────────
|
||||
const handleAdCtaClick = (ad, cta) => {
|
||||
trackClick(ad.advertisement_id);
|
||||
if (!cta?.link) return;
|
||||
if (/^https?:\/\//.test(cta.link)) {
|
||||
window.open(cta.link, "_blank", "noopener,noreferrer");
|
||||
} else {
|
||||
navigate(cta.link);
|
||||
}
|
||||
};
|
||||
|
||||
// Show only first 3
|
||||
const featuredCourses = courses.slice(0, 3);
|
||||
|
||||
@@ -277,7 +271,7 @@ const Client = () => {
|
||||
<div className="flex flex-col gap-8 justify-between lg:container lg:mx-auto pt-8 px-16">
|
||||
|
||||
{/* ── Hero Advertisement ── */}
|
||||
{adLoading.hero ? (
|
||||
{adLoading["dashboard.hero"] ? (
|
||||
<HeroSkeleton />
|
||||
) : (
|
||||
<Hero ad={heroAd} onCtaClick={handleAdCtaClick} />
|
||||
@@ -342,6 +336,7 @@ const Client = () => {
|
||||
open={popupOpen}
|
||||
onOpenChange={setPopupOpen}
|
||||
onCtaClick={handleAdCtaClick}
|
||||
onDismissForever={dismissPopupForever}
|
||||
/>
|
||||
|
||||
{/* ── Upsell Modal — only for locked courses ── */}
|
||||
@@ -387,4 +382,4 @@ const Client = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export default Client;
|
||||
export default Client;
|
||||
|
||||
Reference in New Issue
Block a user