mirror of
https://github.com/rgrgogu/new_starr.git
synced 2026-09-27 00:12:54 +08:00
wip: course layout and func to context
Signed-off-by: Kenneth Obsequio <k80308392@gmail.com>
This commit is contained in:
@@ -0,0 +1,38 @@
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
|
||||
export const columnPinning = {
|
||||
left: ["select", "title"],
|
||||
right: ["actions"],
|
||||
};
|
||||
|
||||
export function buildDataColumns(attributes, rowActions) {
|
||||
const base = [
|
||||
{
|
||||
accessorKey: "title",
|
||||
header: "Title",
|
||||
cell: ({ row }) => (
|
||||
<span className="font-medium">{row.original.title}</span>
|
||||
),
|
||||
},
|
||||
{
|
||||
accessorKey: "description",
|
||||
header: "Description",
|
||||
cell: ({ row }) => (
|
||||
<span className="text-muted-foreground text-sm truncate max-w-xs block">
|
||||
{row.original.description ?? "—"}
|
||||
</span>
|
||||
),
|
||||
},
|
||||
{
|
||||
accessorKey: "order",
|
||||
header: "Order",
|
||||
cell: ({ row }) => (
|
||||
<Badge variant="outline" className="text-xs">
|
||||
{row.original.order}
|
||||
</Badge>
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
return rowActions ? [...base, rowActions] : base;
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
|
||||
export const columnPinning = {
|
||||
left: ["select", "title"],
|
||||
right: ["actions"],
|
||||
};
|
||||
|
||||
export function buildDataColumns(attributes, rowActions) {
|
||||
const base = [
|
||||
{
|
||||
accessorKey: "title",
|
||||
header: "Title",
|
||||
cell: ({ row }) => (
|
||||
<span className="font-medium">{row.original.title}</span>
|
||||
),
|
||||
},
|
||||
{
|
||||
accessorKey: "description",
|
||||
header: "Description",
|
||||
cell: ({ row }) => (
|
||||
<span className="text-muted-foreground text-sm truncate max-w-xs block">
|
||||
{row.original.description ?? "—"}
|
||||
</span>
|
||||
),
|
||||
},
|
||||
{
|
||||
accessorKey: "order",
|
||||
header: "Order",
|
||||
cell: ({ row }) => (
|
||||
<Badge variant="outline" className="text-xs">
|
||||
{row.original.order}
|
||||
</Badge>
|
||||
),
|
||||
},
|
||||
{
|
||||
accessorKey: "page",
|
||||
header: "Content",
|
||||
cell: ({ row }) => {
|
||||
const blocks = row.original.page?.blocks ?? [];
|
||||
return blocks.length ? (
|
||||
<Badge variant="secondary" className="text-xs">
|
||||
{blocks.length} block{blocks.length !== 1 ? "s" : ""}
|
||||
</Badge>
|
||||
) : (
|
||||
<span className="text-xs text-muted-foreground">No content</span>
|
||||
);
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
return rowActions ? [...base, rowActions] : base;
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
// config/courses/lessons/rowActions.config.jsx
|
||||
|
||||
import { Eye, Pencil, Trash2 } from "lucide-react";
|
||||
|
||||
export function buildRowActions({ onView, onEdit, onArchive }) {
|
||||
return {
|
||||
id: "actions",
|
||||
header: "",
|
||||
cell: ({ row }) => (
|
||||
<div className="flex items-center justify-end gap-1">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => onView(row.original)}
|
||||
className="p-1.5 rounded hover:bg-muted transition-colors text-muted-foreground hover:text-foreground"
|
||||
>
|
||||
<Eye className="h-4 w-4" />
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => onEdit(row.original)}
|
||||
className="p-1.5 rounded hover:bg-muted transition-colors text-muted-foreground hover:text-foreground"
|
||||
>
|
||||
<Pencil className="h-4 w-4" />
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => onArchive(row.original)}
|
||||
className="p-1.5 rounded hover:bg-muted transition-colors text-muted-foreground hover:text-destructive"
|
||||
>
|
||||
<Trash2 className="h-4 w-4" />
|
||||
</button>
|
||||
</div>
|
||||
),
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
// config/courses/lessons/toolbar.config.jsx
|
||||
|
||||
import { Plus, RefreshCw, Download } from "lucide-react";
|
||||
import { exportTableToExcel } from "@/utils/excel.util";
|
||||
|
||||
export function buildToolbarActions({
|
||||
fetchLessons,
|
||||
pagination,
|
||||
exportConfig,
|
||||
navigate,
|
||||
courseId,
|
||||
unitId,
|
||||
getFilters,
|
||||
getSort,
|
||||
getTableInstance,
|
||||
}) {
|
||||
return [
|
||||
{
|
||||
key: "refresh",
|
||||
type: "button",
|
||||
label: "Refresh",
|
||||
icon: <RefreshCw className="h-3.5 w-3.5" />,
|
||||
variant: "outline",
|
||||
onClick: () => fetchLessons({
|
||||
page: 1,
|
||||
limit: pagination?.limit ?? 10,
|
||||
filters: getFilters(),
|
||||
sort: getSort(),
|
||||
}),
|
||||
},
|
||||
{
|
||||
key: "export",
|
||||
type: "button",
|
||||
label: "Export",
|
||||
icon: <Download className="h-3.5 w-3.5" />,
|
||||
variant: "outline",
|
||||
onClick: () => exportTableToExcel({
|
||||
...exportConfig,
|
||||
tableInstance: getTableInstance(),
|
||||
}),
|
||||
},
|
||||
{
|
||||
key: "create",
|
||||
type: "button",
|
||||
label: "New Lesson",
|
||||
icon: <Plus className="h-3.5 w-3.5" />,
|
||||
variant: "default",
|
||||
onClick: () => navigate(
|
||||
`/admin/courses/${courseId}/units/${unitId}/lessons/create`
|
||||
),
|
||||
},
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
import { Eye, Pencil, Trash2 } from "lucide-react";
|
||||
|
||||
export function buildRowActions({ onView, onEdit, onArchive }) {
|
||||
return {
|
||||
id: "actions",
|
||||
header: "",
|
||||
cell: ({ row }) => (
|
||||
<div className="flex items-center justify-end gap-1">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => onView(row.original)}
|
||||
className="p-1.5 rounded hover:bg-muted transition-colors text-muted-foreground hover:text-foreground"
|
||||
>
|
||||
<Eye className="h-4 w-4" />
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => onEdit(row.original)}
|
||||
className="p-1.5 rounded hover:bg-muted transition-colors text-muted-foreground hover:text-foreground"
|
||||
>
|
||||
<Pencil className="h-4 w-4" />
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => onArchive(row.original)}
|
||||
className="p-1.5 rounded hover:bg-muted transition-colors text-muted-foreground hover:text-destructive"
|
||||
>
|
||||
<Trash2 className="h-4 w-4" />
|
||||
</button>
|
||||
</div>
|
||||
),
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
import { Download } from "lucide-react";
|
||||
import { exportTableToExcel } from "@/utils/excel.util";
|
||||
|
||||
export function buildSelectionActions({ exportConfig, getTableInstance }) {
|
||||
return [
|
||||
{
|
||||
key: "export-selected",
|
||||
label: "Export",
|
||||
icon: <Download className="h-3.5 w-3.5" />,
|
||||
onClick: (rows, table) =>
|
||||
exportTableToExcel({
|
||||
...exportConfig,
|
||||
selectedRows: rows,
|
||||
tableInstance: table ?? getTableInstance(),
|
||||
}),
|
||||
},
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
import { Plus, RefreshCw, Download } from "lucide-react";
|
||||
import { exportTableToExcel } from "@/utils/excel.util";
|
||||
|
||||
export function buildToolbarActions({
|
||||
fetchCourses,
|
||||
pagination,
|
||||
exportConfig,
|
||||
navigate,
|
||||
getFilters,
|
||||
getSort,
|
||||
getTableInstance,
|
||||
}) {
|
||||
return [
|
||||
{
|
||||
key: "refresh",
|
||||
type: "button",
|
||||
label: "Refresh",
|
||||
icon: <RefreshCw className="h-3.5 w-3.5" />,
|
||||
variant: "outline",
|
||||
onClick: () => fetchCourses({
|
||||
page: 1,
|
||||
limit: pagination?.limit ?? 10,
|
||||
filters: getFilters(),
|
||||
sort: getSort(),
|
||||
}),
|
||||
},
|
||||
{
|
||||
key: "export",
|
||||
type: "button",
|
||||
label: "Export",
|
||||
icon: <Download className="h-3.5 w-3.5" />,
|
||||
variant: "outline",
|
||||
onClick: () => exportTableToExcel({
|
||||
...exportConfig,
|
||||
tableInstance: getTableInstance(),
|
||||
}),
|
||||
},
|
||||
{
|
||||
key: "create",
|
||||
type: "button",
|
||||
label: "New Course",
|
||||
icon: <Plus className="h-3.5 w-3.5" />,
|
||||
variant: "default",
|
||||
onClick: () => navigate("/admin/courses/create"),
|
||||
},
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
// config/courses/units/columns.config.jsx
|
||||
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
|
||||
export const columnPinning = {
|
||||
left: ["select", "title"],
|
||||
right: ["actions"],
|
||||
};
|
||||
|
||||
export function buildDataColumns(attributes, rowActions) {
|
||||
const base = [
|
||||
{
|
||||
accessorKey: "title",
|
||||
header: "Title",
|
||||
cell: ({ row }) => (
|
||||
<span className="font-medium">{row.original.title}</span>
|
||||
),
|
||||
},
|
||||
{
|
||||
accessorKey: "description",
|
||||
header: "Description",
|
||||
cell: ({ row }) => (
|
||||
<span className="text-muted-foreground text-sm truncate max-w-xs block">
|
||||
{row.original.description ?? "—"}
|
||||
</span>
|
||||
),
|
||||
},
|
||||
{
|
||||
accessorKey: "order",
|
||||
header: "Order",
|
||||
cell: ({ row }) => (
|
||||
<Badge variant="outline" className="text-xs">
|
||||
{row.original.order}
|
||||
</Badge>
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
return rowActions ? [...base, rowActions] : base;
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
import { Eye, Pencil, Trash2 } from "lucide-react";
|
||||
|
||||
export function buildRowActions({ onView, onEdit, onArchive }) {
|
||||
return {
|
||||
id: "actions",
|
||||
header: "",
|
||||
cell: ({ row }) => (
|
||||
<div className="flex items-center justify-end gap-1">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => onView(row.original)}
|
||||
className="p-1.5 rounded hover:bg-muted transition-colors text-muted-foreground hover:text-foreground"
|
||||
>
|
||||
<Eye className="h-4 w-4" />
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => onEdit(row.original)}
|
||||
className="p-1.5 rounded hover:bg-muted transition-colors text-muted-foreground hover:text-foreground"
|
||||
>
|
||||
<Pencil className="h-4 w-4" />
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => onArchive(row.original)}
|
||||
className="p-1.5 rounded hover:bg-muted transition-colors text-muted-foreground hover:text-destructive"
|
||||
>
|
||||
<Trash2 className="h-4 w-4" />
|
||||
</button>
|
||||
</div>
|
||||
),
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
import { Plus, RefreshCw, Download } from "lucide-react";
|
||||
import { exportTableToExcel } from "@/utils/excel.util";
|
||||
|
||||
export function buildToolbarActions({
|
||||
fetchUnits,
|
||||
pagination,
|
||||
exportConfig,
|
||||
navigate,
|
||||
courseId,
|
||||
getFilters,
|
||||
getSort,
|
||||
getTableInstance,
|
||||
}) {
|
||||
return [
|
||||
{
|
||||
key: "refresh",
|
||||
type: "button",
|
||||
label: "Refresh",
|
||||
icon: <RefreshCw className="h-3.5 w-3.5" />,
|
||||
variant: "outline",
|
||||
onClick: () => fetchUnits({
|
||||
page: 1,
|
||||
limit: pagination?.limit ?? 10,
|
||||
filters: getFilters(),
|
||||
sort: getSort(),
|
||||
}),
|
||||
},
|
||||
{
|
||||
key: "export",
|
||||
type: "button",
|
||||
label: "Export",
|
||||
icon: <Download className="h-3.5 w-3.5" />,
|
||||
variant: "outline",
|
||||
onClick: () => exportTableToExcel({
|
||||
...exportConfig,
|
||||
tableInstance: getTableInstance(),
|
||||
}),
|
||||
},
|
||||
{
|
||||
key: "create",
|
||||
type: "button",
|
||||
label: "New Unit",
|
||||
icon: <Plus className="h-3.5 w-3.5" />,
|
||||
variant: "default",
|
||||
onClick: () => navigate(`/admin/courses/${courseId}/units/create`),
|
||||
},
|
||||
];
|
||||
}
|
||||
Reference in New Issue
Block a user