fix: fixing bugs report friday
This commit is contained in:
parent
5b6ec0342b
commit
2b545ec51a
|
|
@ -71,7 +71,7 @@ const TableCategories = () => {
|
|||
{
|
||||
accessorKey: "statusId",
|
||||
header: "Status",
|
||||
cell: ({ row }) => (row.original.isPublish ? "Publish" : "Draft"),
|
||||
cell: ({ row }) => (row.original.isActive ? "Active" : "Draft"),
|
||||
},
|
||||
{
|
||||
id: "actions",
|
||||
|
|
|
|||
|
|
@ -6,12 +6,12 @@ import TableImage from "./table-image";
|
|||
import PendingApprovalTable from "./pending-approval-table";
|
||||
|
||||
const ImageTabs = () => {
|
||||
const [activeTab, setActiveTab] = React.useState("pending");
|
||||
const [activeTab, setActiveTab] = React.useState("submitted");
|
||||
|
||||
return (
|
||||
<div className="w-full">
|
||||
<Tabs value={activeTab} onValueChange={setActiveTab} className="w-full">
|
||||
<div className="flex items-center justify-between mb-6">
|
||||
{/* <div className="flex items-center justify-between mb-6">
|
||||
<TabsList className="inline-flex h-10 bg-gray-50 border border-gray-200 p-1 rounded-lg shadow-sm">
|
||||
<TabsTrigger
|
||||
value="pending"
|
||||
|
|
@ -33,18 +33,18 @@ const ImageTabs = () => {
|
|||
</TabsTrigger>
|
||||
</TabsList>
|
||||
</div>
|
||||
|
||||
*/}
|
||||
<TabsContent value="submitted" className="mt-0">
|
||||
<div className="bg-white rounded-lg border border-gray-200 shadow-sm">
|
||||
<TableImage />
|
||||
</div>
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="pending" className="mt-0">
|
||||
{/* <TabsContent value="pending" className="mt-0">
|
||||
<div className="bg-white rounded-lg border border-gray-200 shadow-sm">
|
||||
<PendingApprovalTable typeId={1} />
|
||||
</div>
|
||||
</TabsContent>
|
||||
</TabsContent> */}
|
||||
</Tabs>
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -290,9 +290,9 @@ const TableImage = () => {
|
|||
return (
|
||||
<div className="w-full overflow-x-auto">
|
||||
<div className="flex flex-col md:flex-row lg:flex-row md:justify-between lg:justify-between items-center md:px-5 lg:px-5">
|
||||
<div className="relative w-full md:w-[200px] lg:w-[200px] px-2">
|
||||
<Search className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-gray-400 dark:text-white" />
|
||||
<Input
|
||||
<div className="relative w-full md:w-[200px] lg:w-[200px] px-2 border border-slate-200">
|
||||
<Search className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 " />
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Search Judul..."
|
||||
className="pl-9 bg-transparent dark:border-secondary dark:placeholder-white/80 dark:focus:border-secondary dark:text-white"
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ const ImageCreatePage = async () => {
|
|||
return (
|
||||
<div>
|
||||
<SiteBreadcrumb />
|
||||
<div className="space-y-4 bg-slate-100">
|
||||
<div className="space-y-4 bg-slate-100 dark:bg-default-50">
|
||||
<FormImage />
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ const AudioVisualTabs = () => {
|
|||
return (
|
||||
<div className="w-full">
|
||||
<Tabs value={activeTab} onValueChange={setActiveTab} className="w-full">
|
||||
<div className="flex items-center justify-between mb-6">
|
||||
{/* <div className="flex items-center justify-between mb-6">
|
||||
<TabsList className="inline-flex h-10 bg-gray-50 border border-gray-200 p-1 rounded-lg shadow-sm">
|
||||
<TabsTrigger
|
||||
value="submitted"
|
||||
|
|
@ -32,7 +32,7 @@ const AudioVisualTabs = () => {
|
|||
</div>
|
||||
</TabsTrigger>
|
||||
</TabsList>
|
||||
</div>
|
||||
</div> */}
|
||||
|
||||
<TabsContent value="submitted" className="mt-0">
|
||||
<div className="bg-white rounded-lg border border-gray-200 shadow-sm">
|
||||
|
|
@ -40,11 +40,11 @@ const AudioVisualTabs = () => {
|
|||
</div>
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="pending" className="mt-0">
|
||||
{/* <TabsContent value="pending" className="mt-0">
|
||||
<div className="bg-white rounded-lg border border-gray-200 shadow-sm">
|
||||
<PendingApprovalTable typeId={2} />
|
||||
</div>
|
||||
</TabsContent>
|
||||
</TabsContent> */}
|
||||
</Tabs>
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ export default function AdminPage() {
|
|||
|
||||
return (
|
||||
<motion.div
|
||||
className="h-full overflow-auto bg-gray-50 dark:bg-black"
|
||||
className="h-full overflow-auto"
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
transition={{ duration: 0.3 }}
|
||||
|
|
|
|||
|
|
@ -204,7 +204,7 @@ function TenantSettingsContentTable() {
|
|||
Manage approval workflows and user levels for your tenant
|
||||
</p>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
{/* <div className="flex items-center gap-2">
|
||||
<SettingsIcon className="h-6 w-6 text-gray-500" />
|
||||
<Button variant="outline" size="sm" onClick={checkWorkflowStatus}>
|
||||
Check Workflow Status
|
||||
|
|
@ -217,7 +217,7 @@ function TenantSettingsContentTable() {
|
|||
>
|
||||
Test Modal
|
||||
</Button>
|
||||
</div>
|
||||
</div> */}
|
||||
</div>
|
||||
|
||||
<Tabs value={activeTab} onValueChange={setActiveTab} className="w-full">
|
||||
|
|
@ -266,7 +266,8 @@ function TenantSettingsContentTable() {
|
|||
)}
|
||||
</div>
|
||||
|
||||
{isEditingWorkflow && workflow && workflow.workflow?.id ? (
|
||||
{/* {isEditingWorkflow && workflow && workflow.workflow?.id ? ( */}
|
||||
{isEditingWorkflow ? (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle className="flex items-center justify-between">
|
||||
|
|
@ -281,8 +282,8 @@ function TenantSettingsContentTable() {
|
|||
</CardHeader>
|
||||
<CardContent>
|
||||
<ApprovalWorkflowForm
|
||||
key={workflow.workflow.id}
|
||||
workflowId={workflow.workflow.id}
|
||||
key={workflow?.workflow.id}
|
||||
workflowId={workflow?.workflow.id}
|
||||
initialData={
|
||||
workflow
|
||||
? {
|
||||
|
|
@ -362,21 +363,21 @@ function TenantSettingsContentTable() {
|
|||
</p>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4 mb-6">
|
||||
<div className="text-center p-4 bg-gray-50 rounded-lg">
|
||||
<div className="text-center p-4 bg-gray-50 dark:bg-gray-300 rounded-lg">
|
||||
<div className="text-2xl font-bold text-blue-600">
|
||||
{workflow.workflow.totalSteps}
|
||||
</div>
|
||||
<div className="text-sm text-gray-600">Total Steps</div>
|
||||
</div>
|
||||
|
||||
<div className="text-center p-4 bg-gray-50 rounded-lg">
|
||||
<div className="text-center p-4 bg-gray-50 dark:bg-gray-300 rounded-lg">
|
||||
<div className="text-2xl font-bold text-green-600">
|
||||
{workflow.workflow.activeSteps}
|
||||
</div>
|
||||
<div className="text-sm text-gray-600">Active Steps</div>
|
||||
</div>
|
||||
|
||||
<div className="text-center p-4 bg-gray-50 rounded-lg">
|
||||
<div className="text-center p-4 bg-gray-50 dark:bg-gray-300 rounded-lg">
|
||||
<div
|
||||
className={`text-2xl font-bold ${
|
||||
// workflow.workflow.requiresApproval
|
||||
|
|
@ -387,9 +388,7 @@ function TenantSettingsContentTable() {
|
|||
>
|
||||
{
|
||||
// workflow.workflow.requiresApproval
|
||||
workflow.clientSettings.requiresApproval
|
||||
? "Yes"
|
||||
: "No"
|
||||
workflow.clientSettings.requiresApproval ? "Yes" : "No"
|
||||
}
|
||||
</div>
|
||||
<div className="text-sm text-gray-600">
|
||||
|
|
@ -397,7 +396,7 @@ function TenantSettingsContentTable() {
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div className="text-center p-4 bg-gray-50 rounded-lg">
|
||||
<div className="text-center p-4 bg-gray-50 dark:bg-gray-300 rounded-lg">
|
||||
<div
|
||||
className={`text-2xl font-bold ${
|
||||
// workflow.workflow.autoPublish
|
||||
|
|
@ -425,14 +424,14 @@ function TenantSettingsContentTable() {
|
|||
{workflow.steps.map((step: any, index: number) => (
|
||||
<div
|
||||
key={index}
|
||||
className="flex items-center justify-between p-3 bg-gray-50 rounded-lg"
|
||||
className="flex items-center justify-between p-3 bg-gray-50 dark:bg-gray-300 rounded-lg"
|
||||
>
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="w-8 h-8 bg-blue-100 text-blue-600 rounded-full flex items-center justify-center text-sm font-medium">
|
||||
{step.stepOrder}
|
||||
</div>
|
||||
<div>
|
||||
<div className="font-medium dark:text-black">{step.stepName}</div>
|
||||
<div className="font-medium text-black">{step.stepName}</div>
|
||||
<div className="text-sm text-gray-500">
|
||||
{step.conditionType &&
|
||||
`Condition: ${step.conditionType}`}
|
||||
|
|
@ -480,7 +479,7 @@ function TenantSettingsContentTable() {
|
|||
<div className="mb-6">
|
||||
<h4 className="text-lg font-medium mb-3">Client Settings</h4>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
<div className="p-3 bg-gray-50 rounded-lg">
|
||||
<div className="p-3 bg-gray-50 dark:bg-gray-300 rounded-lg">
|
||||
<div className="text-sm font-medium text-gray-700 mb-1">
|
||||
Default Workflow
|
||||
</div>
|
||||
|
|
@ -488,7 +487,7 @@ function TenantSettingsContentTable() {
|
|||
{workflow.clientSettings.defaultWorkflowName}
|
||||
</div>
|
||||
</div>
|
||||
<div className="p-3 bg-gray-50 rounded-lg">
|
||||
<div className="p-3 bg-gray-50 dark:bg-gray-300 rounded-lg">
|
||||
<div className="text-sm font-medium text-gray-700 mb-1">
|
||||
Auto Publish Articles
|
||||
</div>
|
||||
|
|
@ -504,7 +503,7 @@ function TenantSettingsContentTable() {
|
|||
: "No"}
|
||||
</div>
|
||||
</div>
|
||||
<div className="p-3 bg-gray-50 rounded-lg">
|
||||
<div className="p-3 bg-gray-50 dark:bg-gray-300 rounded-lg">
|
||||
<div className="text-sm font-medium text-gray-700 mb-1">
|
||||
Requires Approval
|
||||
</div>
|
||||
|
|
@ -520,7 +519,7 @@ function TenantSettingsContentTable() {
|
|||
: "No"}
|
||||
</div>
|
||||
</div>
|
||||
<div className="p-3 bg-gray-50 rounded-lg">
|
||||
<div className="p-3 bg-gray-50 dark:bg-gray-300 rounded-lg">
|
||||
<div className="text-sm font-medium text-gray-700 mb-1">
|
||||
Settings Active
|
||||
</div>
|
||||
|
|
@ -543,7 +542,7 @@ function TenantSettingsContentTable() {
|
|||
Workflow Statistics
|
||||
</h4>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
|
||||
<div className="p-3 bg-gray-50 rounded-lg">
|
||||
<div className="p-3 bg-gray-50 dark:bg-gray-300 rounded-lg">
|
||||
<div className="text-sm font-medium text-gray-700 mb-1">
|
||||
Total Articles Processed
|
||||
</div>
|
||||
|
|
@ -551,7 +550,7 @@ function TenantSettingsContentTable() {
|
|||
{workflow.statistics.totalArticlesProcessed}
|
||||
</div>
|
||||
</div>
|
||||
<div className="p-3 bg-gray-50 rounded-lg">
|
||||
<div className="p-3 bg-gray-50 dark:bg-gray-300 rounded-lg">
|
||||
<div className="text-sm font-medium text-gray-700 mb-1">
|
||||
Pending Articles
|
||||
</div>
|
||||
|
|
@ -559,7 +558,7 @@ function TenantSettingsContentTable() {
|
|||
{workflow.statistics.pendingArticles}
|
||||
</div>
|
||||
</div>
|
||||
<div className="p-3 bg-gray-50 rounded-lg">
|
||||
<div className="p-3 bg-gray-50 dark:bg-gray-300 rounded-lg">
|
||||
<div className="text-sm font-medium text-gray-700 mb-1">
|
||||
Approved Articles
|
||||
</div>
|
||||
|
|
@ -567,7 +566,7 @@ function TenantSettingsContentTable() {
|
|||
{workflow.statistics.approvedArticles}
|
||||
</div>
|
||||
</div>
|
||||
<div className="p-3 bg-gray-50 rounded-lg">
|
||||
<div className="p-3 bg-gray-50 dark:bg-gray-300 rounded-lg">
|
||||
<div className="text-sm font-medium text-gray-700 mb-1">
|
||||
Rejected Articles
|
||||
</div>
|
||||
|
|
@ -575,7 +574,7 @@ function TenantSettingsContentTable() {
|
|||
{workflow.statistics.rejectedArticles}
|
||||
</div>
|
||||
</div>
|
||||
<div className="p-3 bg-gray-50 rounded-lg">
|
||||
<div className="p-3 bg-gray-50 dark:bg-gray-300 rounded-lg">
|
||||
<div className="text-sm font-medium text-gray-700 mb-1">
|
||||
Average Processing Time
|
||||
</div>
|
||||
|
|
@ -583,7 +582,7 @@ function TenantSettingsContentTable() {
|
|||
{workflow.statistics.averageProcessingTime}h
|
||||
</div>
|
||||
</div>
|
||||
<div className="p-3 bg-gray-50 rounded-lg">
|
||||
<div className="p-3 bg-gray-50 dark:bg-gray-300 rounded-lg">
|
||||
<div className="text-sm font-medium text-gray-700 mb-1">
|
||||
Most Active Step
|
||||
</div>
|
||||
|
|
@ -600,7 +599,7 @@ function TenantSettingsContentTable() {
|
|||
Workflow Information
|
||||
</h4>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
<div className="p-3 bg-gray-50 rounded-lg">
|
||||
<div className="p-3 bg-gray-50 dark:bg-gray-300 rounded-lg">
|
||||
<div className="text-sm font-medium text-gray-700 mb-1">
|
||||
Client ID
|
||||
</div>
|
||||
|
|
@ -608,7 +607,7 @@ function TenantSettingsContentTable() {
|
|||
{workflow.workflow.clientId}
|
||||
</div>
|
||||
</div>
|
||||
<div className="p-3 bg-gray-50 rounded-lg">
|
||||
<div className="p-3 bg-gray-50 dark:bg-gray-300 rounded-lg">
|
||||
<div className="text-sm font-medium text-gray-700 mb-1">
|
||||
Created At
|
||||
</div>
|
||||
|
|
@ -616,7 +615,7 @@ function TenantSettingsContentTable() {
|
|||
{new Date(workflow.workflow.createdAt).toLocaleString()}
|
||||
</div>
|
||||
</div>
|
||||
<div className="p-3 bg-gray-50 rounded-lg">
|
||||
<div className="p-3 bg-gray-50 dark:bg-gray-300 rounded-lg">
|
||||
<div className="text-sm font-medium text-gray-700 mb-1">
|
||||
Updated At
|
||||
</div>
|
||||
|
|
@ -624,7 +623,7 @@ function TenantSettingsContentTable() {
|
|||
{new Date(workflow.workflow.updatedAt).toLocaleString()}
|
||||
</div>
|
||||
</div>
|
||||
<div className="p-3 bg-gray-50 rounded-lg">
|
||||
<div className="p-3 bg-gray-50 dark:bg-gray-300 rounded-lg">
|
||||
<div className="text-sm font-medium text-gray-700 mb-1">
|
||||
Workflow ID
|
||||
</div>
|
||||
|
|
@ -632,7 +631,7 @@ function TenantSettingsContentTable() {
|
|||
{workflow.workflow.id}
|
||||
</div>
|
||||
</div>
|
||||
<div className="p-3 bg-gray-50 rounded-lg">
|
||||
<div className="p-3 bg-gray-50 dark:bg-gray-300 rounded-lg">
|
||||
<div className="text-sm font-medium text-gray-700 mb-1">
|
||||
Has Branches
|
||||
</div>
|
||||
|
|
@ -646,7 +645,7 @@ function TenantSettingsContentTable() {
|
|||
{workflow.workflow.hasBranches ? "Yes" : "No"}
|
||||
</div>
|
||||
</div>
|
||||
<div className="p-3 bg-gray-50 rounded-lg">
|
||||
<div className="p-3 bg-gray-50 dark:bg-gray-300 rounded-lg">
|
||||
<div className="text-sm font-medium text-gray-700 mb-1">
|
||||
Max Step Order
|
||||
</div>
|
||||
|
|
@ -751,7 +750,7 @@ function TenantSettingsContentTable() {
|
|||
onOpenChange={setIsHierarchyExpanded}
|
||||
>
|
||||
<CollapsibleTrigger asChild>
|
||||
<CardHeader className="cursor-pointer hover:bg-gray-50 transition-colors">
|
||||
<CardHeader className="cursor-pointer hover:bg-gray-50 dark:hover:bg-black transition-colors">
|
||||
<CardTitle className="flex items-center justify-between">
|
||||
<div className="flex items-center gap-2">
|
||||
<UsersIcon className="h-5 w-5" />
|
||||
|
|
@ -769,7 +768,7 @@ function TenantSettingsContentTable() {
|
|||
<CardContent>
|
||||
<div className="space-y-3">
|
||||
{userLevels
|
||||
.filter((ul) => !ul.parentLevelId) // Root levels
|
||||
.filter((ul) => !ul.parentLevelId)
|
||||
.sort((a, b) => a.levelNumber - b.levelNumber)
|
||||
.map((rootLevel) => (
|
||||
<div key={rootLevel.id} className="space-y-2">
|
||||
|
|
@ -779,7 +778,7 @@ function TenantSettingsContentTable() {
|
|||
{rootLevel.levelNumber}
|
||||
</div>
|
||||
<div className="flex-1">
|
||||
<div className="font-medium">
|
||||
<div className="font-medium text-black">
|
||||
{rootLevel.name}
|
||||
</div>
|
||||
<div className="text-sm text-gray-500">
|
||||
|
|
@ -814,7 +813,7 @@ function TenantSettingsContentTable() {
|
|||
{childLevel.levelNumber}
|
||||
</div>
|
||||
<div className="flex-1">
|
||||
<div className="font-medium text-sm">
|
||||
<div className="font-medium text-sm text-black">
|
||||
{childLevel.name}
|
||||
</div>
|
||||
<div className="text-xs text-gray-500">
|
||||
|
|
@ -846,7 +845,7 @@ function TenantSettingsContentTable() {
|
|||
)}
|
||||
|
||||
<Table className="overflow-hidden mt-3 mx-3">
|
||||
<TableHeader className="sticky top-0 bg-white shadow-sm z-10">
|
||||
<TableHeader className="sticky top-0 bg-white dark:bg-default-50 shadow-sm z-10">
|
||||
{table.getHeaderGroups().map((headerGroup) => (
|
||||
<TableRow key={headerGroup.id} className="bg-default-200">
|
||||
{headerGroup.headers.map((header) => (
|
||||
|
|
|
|||
|
|
@ -1223,7 +1223,7 @@ export const UserLevelsForm: React.FC<UserLevelsFormProps> = ({
|
|||
{menus.map((menu) => (
|
||||
<label
|
||||
key={menu.id}
|
||||
className="flex items-start gap-3 p-3 border rounded-lg hover:bg-gray-50 cursor-pointer"
|
||||
className="flex items-start gap-3 p-3 border rounded-lg hover:bg-gray-50 dark:hover:bg-black cursor-pointer"
|
||||
>
|
||||
<input
|
||||
type="checkbox"
|
||||
|
|
@ -1312,7 +1312,7 @@ export const UserLevelsForm: React.FC<UserLevelsFormProps> = ({
|
|||
{actions.map((action) => (
|
||||
<label
|
||||
key={action.id}
|
||||
className="flex items-start gap-3 p-2 border rounded-lg hover:bg-gray-50 cursor-pointer"
|
||||
className="flex items-start gap-3 p-2 border rounded-lg hover:bg-gray-50 dark:hover:bg-black cursor-pointer"
|
||||
>
|
||||
<input
|
||||
type="checkbox"
|
||||
|
|
|
|||
|
|
@ -61,10 +61,10 @@ export default function CategoriesDetailForm() {
|
|||
</div>
|
||||
|
||||
{/* Slug */}
|
||||
<div className="space-y-2 py-3">
|
||||
{/* <div className="space-y-2 py-3">
|
||||
<Label>Slug</Label>
|
||||
<Input type="text" value={detail.slug || "-"} readOnly />
|
||||
</div>
|
||||
</div> */}
|
||||
|
||||
{/* Description */}
|
||||
<div className="space-y-2 py-3">
|
||||
|
|
@ -89,7 +89,7 @@ export default function CategoriesDetailForm() {
|
|||
</div>
|
||||
|
||||
{/* Tags */}
|
||||
<div className="space-y-2 py-3 ">
|
||||
{/* <div className="space-y-2 py-3 ">
|
||||
<Label>Tags</Label>
|
||||
<div className="flex flex-wrap gap-2 p-4 border rounded-sm">
|
||||
{detail?.tags?.length > 0 ? (
|
||||
|
|
@ -102,7 +102,7 @@ export default function CategoriesDetailForm() {
|
|||
<span className="text-slate-400 text-sm">No tags</span>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div> */}
|
||||
</Card>
|
||||
|
||||
{/* SIDEBAR */}
|
||||
|
|
@ -122,7 +122,7 @@ export default function CategoriesDetailForm() {
|
|||
<div>
|
||||
<Label>Status</Label>
|
||||
<p className="text-sm text-slate-600">
|
||||
{detail.isPublish ? "Published" : "Draft"} |{" "}
|
||||
{/* {detail.isPublish ? "Published" : "Draft"} |{" "} */}
|
||||
{detail.isActive ? "Active" : "Inactive"}
|
||||
</p>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ export default function CategoriesUpdateForm() {
|
|||
}, [id]);
|
||||
|
||||
const handleChange = (
|
||||
e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>
|
||||
e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>,
|
||||
) => {
|
||||
const { name, value } = e.target;
|
||||
setFormData((prev) => (prev ? { ...prev, [name]: value } : prev));
|
||||
|
|
@ -94,7 +94,7 @@ export default function CategoriesUpdateForm() {
|
|||
MySwal.fire(
|
||||
"Error",
|
||||
res?.message || "Gagal mengunggah thumbnail",
|
||||
"error"
|
||||
"error",
|
||||
);
|
||||
return null;
|
||||
}
|
||||
|
|
@ -186,7 +186,7 @@ export default function CategoriesUpdateForm() {
|
|||
</div>
|
||||
|
||||
{/* Thumbnail Upload */}
|
||||
<div className="space-y-2 py-3">
|
||||
{/* <div className="space-y-2 py-3">
|
||||
<Label>Thumbnail</Label>
|
||||
{thumbnailPreview && (
|
||||
<img
|
||||
|
|
@ -203,18 +203,25 @@ export default function CategoriesUpdateForm() {
|
|||
{isUploading && (
|
||||
<p className="text-sm text-blue-500 mt-1">Mengunggah...</p>
|
||||
)}
|
||||
</div>
|
||||
</div> */}
|
||||
|
||||
{/* Status */}
|
||||
<div className="flex items-center gap-4 py-3">
|
||||
<div className="flex items-center gap-2">
|
||||
<Checkbox
|
||||
{/* <Checkbox
|
||||
checked={formData.isActive}
|
||||
onCheckedChange={(checked) =>
|
||||
handleCheckboxChange("isActive", Boolean(checked))
|
||||
}
|
||||
/> */}
|
||||
{/* <input
|
||||
type="checkbox"
|
||||
checked={formData.isActive}
|
||||
onChange={(e) =>
|
||||
handleCheckboxChange("isActive", e.target.checked)
|
||||
}
|
||||
/>
|
||||
<Label>Active</Label>
|
||||
<Label>Active</Label> */}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -362,7 +362,7 @@ const CustomEditor = dynamic(
|
|||
() => {
|
||||
return import("@/components/editor/custom-editor");
|
||||
},
|
||||
{ ssr: false }
|
||||
{ ssr: false },
|
||||
);
|
||||
|
||||
interface FileWithPreview extends File {
|
||||
|
|
@ -412,11 +412,11 @@ export default function FormVideo() {
|
|||
const [isGeneratedArticle, setIsGeneratedArticle] = useState(false);
|
||||
const [articleBody, setArticleBody] = useState<string>("");
|
||||
const [selectedArticleId, setSelectedArticleId] = useState<string | null>(
|
||||
null
|
||||
null,
|
||||
);
|
||||
const [selectedMainKeyword, setSelectedMainKeyword] = useState("");
|
||||
const [publishedForError, setPublishedForError] = useState<string | null>(
|
||||
null
|
||||
null,
|
||||
);
|
||||
const userId = Cookies.get("userId");
|
||||
const [selectedSize, setSelectedSize] = useState("");
|
||||
|
|
@ -478,7 +478,7 @@ export default function FormVideo() {
|
|||
}
|
||||
|
||||
const filesWithPreview = acceptedFiles.map((file) =>
|
||||
Object.assign(file, { preview: URL.createObjectURL(file) })
|
||||
Object.assign(file, { preview: URL.createObjectURL(file) }),
|
||||
);
|
||||
|
||||
setFiles((prev) => {
|
||||
|
|
@ -503,12 +503,12 @@ export default function FormVideo() {
|
|||
files.every(
|
||||
(file: File) =>
|
||||
["video/mp4", "video/mov", "video/avi"].includes(file.type) &&
|
||||
file.size <= 100 * 1024 * 1024
|
||||
file.size <= 100 * 1024 * 1024,
|
||||
),
|
||||
{
|
||||
message:
|
||||
"Hanya file .mp4, .mov, .avi, maksimal 100MB yang diperbolehkan.",
|
||||
}
|
||||
},
|
||||
),
|
||||
categoryId: z.string().min(1, { message: "Kategori wajib dipilih." }),
|
||||
tags: z
|
||||
|
|
@ -722,7 +722,7 @@ export default function FormVideo() {
|
|||
const articleData = await waitForStatusUpdate();
|
||||
const cleanArticleBody = articleData?.articleBody?.replace(
|
||||
/<img[^>]*>/g,
|
||||
""
|
||||
"",
|
||||
);
|
||||
const articleImagesData = articleData?.imagesUrl?.split(",");
|
||||
setArticleBody(cleanArticleBody || "");
|
||||
|
|
@ -798,7 +798,7 @@ export default function FormVideo() {
|
|||
|
||||
if (scheduleId && scheduleType === "3") {
|
||||
const findCategory = resCategory.find((o) =>
|
||||
o.name.toLowerCase().includes("pers rilis")
|
||||
o.name.toLowerCase().includes("pers rilis"),
|
||||
);
|
||||
|
||||
if (findCategory) {
|
||||
|
|
@ -829,7 +829,7 @@ export default function FormVideo() {
|
|||
setPublishedFor(
|
||||
options
|
||||
.filter((opt: any) => opt.id !== "all")
|
||||
.map((opt: any) => opt.id)
|
||||
.map((opt: any) => opt.id),
|
||||
);
|
||||
}
|
||||
} else {
|
||||
|
|
@ -866,8 +866,8 @@ export default function FormVideo() {
|
|||
const finalDescription = isSwitchOn
|
||||
? data.description
|
||||
: selectedFileType === "rewrite"
|
||||
? data.rewriteDescription
|
||||
: data.descriptionOri;
|
||||
? data.rewriteDescription
|
||||
: data.descriptionOri;
|
||||
|
||||
if (!finalDescription?.trim()) {
|
||||
MySwal.fire("Error", "Deskripsi tidak boleh kosong.", "error");
|
||||
|
|
@ -959,7 +959,7 @@ export default function FormVideo() {
|
|||
MySwal.fire(
|
||||
"Error",
|
||||
response.message || "Failed to create article",
|
||||
"error"
|
||||
"error",
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
|
@ -987,7 +987,7 @@ export default function FormVideo() {
|
|||
MySwal.fire(
|
||||
"Error",
|
||||
uploadResponse.message || "Failed to upload files",
|
||||
"error"
|
||||
"error",
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
|
@ -1003,17 +1003,17 @@ export default function FormVideo() {
|
|||
try {
|
||||
const thumbnailResponse = await uploadArticleThumbnail(
|
||||
articleId,
|
||||
thumbnailFormData
|
||||
thumbnailFormData,
|
||||
);
|
||||
if (thumbnailResponse?.error) {
|
||||
console.warn(
|
||||
"Thumbnail upload failed:",
|
||||
thumbnailResponse.message
|
||||
thumbnailResponse.message,
|
||||
);
|
||||
} else {
|
||||
console.log(
|
||||
"Thumbnail uploaded successfully:",
|
||||
thumbnailResponse
|
||||
thumbnailResponse,
|
||||
);
|
||||
}
|
||||
} catch (thumbnailError) {
|
||||
|
|
@ -1025,7 +1025,7 @@ export default function FormVideo() {
|
|||
MySwal.fire(
|
||||
"Error",
|
||||
"Failed to upload files. Please try again.",
|
||||
"error"
|
||||
"error",
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
|
@ -1076,7 +1076,7 @@ export default function FormVideo() {
|
|||
idx: number,
|
||||
id: string,
|
||||
file: any,
|
||||
duration: string
|
||||
duration: string,
|
||||
) {
|
||||
console.log(idx, id, file, duration);
|
||||
|
||||
|
|
@ -1112,7 +1112,7 @@ export default function FormVideo() {
|
|||
onChunkComplete: (
|
||||
chunkSize: any,
|
||||
bytesAccepted: any,
|
||||
bytesTotal: any
|
||||
bytesTotal: any,
|
||||
) => {
|
||||
const uploadPersen = Math.floor((bytesAccepted / bytesTotal) * 100);
|
||||
progressInfo[idx].percentage = uploadPersen;
|
||||
|
|
@ -1356,14 +1356,43 @@ export default function FormVideo() {
|
|||
<div className="flex flex-row items-center gap-3 py-2">
|
||||
<Label>Ai Assistance</Label>
|
||||
<div className="flex items-center gap-3">
|
||||
<Switch
|
||||
<label className="relative inline-flex items-center cursor-pointer">
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={isSwitchOn}
|
||||
onChange={(e) => setIsSwitchOn(e.target.checked)}
|
||||
className="sr-only peer"
|
||||
/>
|
||||
<div
|
||||
className="
|
||||
w-11 h-6
|
||||
bg-gray-300
|
||||
rounded-full
|
||||
peer
|
||||
peer-checked:bg-blue-600
|
||||
transition-colors
|
||||
after:content-['']
|
||||
after:absolute
|
||||
after:top-[2px]
|
||||
after:left-[2px]
|
||||
after:bg-white
|
||||
after:rounded-full
|
||||
after:h-5
|
||||
after:w-5
|
||||
after:transition-transform
|
||||
peer-checked:after:translate-x-5
|
||||
"
|
||||
/>
|
||||
</label>
|
||||
|
||||
{/* <Switch
|
||||
defaultChecked={isSwitchOn}
|
||||
color="primary"
|
||||
id="c2"
|
||||
onCheckedChange={(checked: boolean) =>
|
||||
setIsSwitchOn(checked)
|
||||
}
|
||||
/>
|
||||
/> */}
|
||||
</div>
|
||||
</div>
|
||||
{isSwitchOn && (
|
||||
|
|
@ -1622,14 +1651,12 @@ export default function FormVideo() {
|
|||
|
||||
<p className="text-sm font-semibold">Content Rewrite</p>
|
||||
<div className="my-2">
|
||||
<Button
|
||||
size="sm"
|
||||
type="button"
|
||||
<button type="button"
|
||||
onClick={handleRewriteClick}
|
||||
className="bg-blue-500 text-white py-2 px-4 rounded"
|
||||
>
|
||||
Content Rewrite
|
||||
</Button>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{showRewriteEditor && (
|
||||
|
|
@ -1814,7 +1841,7 @@ export default function FormVideo() {
|
|||
type="button"
|
||||
onClick={() => {
|
||||
const updatedTags = field.value.filter(
|
||||
(_, i) => i !== index
|
||||
(_, i) => i !== index,
|
||||
);
|
||||
field.onChange(updatedTags);
|
||||
}}
|
||||
|
|
@ -1852,19 +1879,19 @@ export default function FormVideo() {
|
|||
? isAllChecked
|
||||
: field.value.includes(option.id);
|
||||
|
||||
const handleChange = () => {
|
||||
const handleChange = (checked: boolean) => {
|
||||
let updated: string[] = [];
|
||||
|
||||
if (option.id === "all") {
|
||||
updated = isAllChecked
|
||||
? []
|
||||
: options
|
||||
updated = checked
|
||||
? options
|
||||
.filter((opt: any) => opt.id !== "all")
|
||||
.map((opt: any) => opt.id);
|
||||
.map((opt: any) => opt.id)
|
||||
: [];
|
||||
} else {
|
||||
updated = isChecked
|
||||
? field.value.filter((val) => val !== option.id)
|
||||
: [...field.value, option.id];
|
||||
updated = checked
|
||||
? [...field.value, option.id]
|
||||
: field.value.filter((val) => val !== option.id);
|
||||
|
||||
if (isAllChecked && option.id !== "all") {
|
||||
updated = updated.filter((val) => val !== "all");
|
||||
|
|
@ -1875,17 +1902,47 @@ export default function FormVideo() {
|
|||
setPublishedFor(updated);
|
||||
};
|
||||
|
||||
// const handleChange = () => {
|
||||
// let updated: string[] = [];
|
||||
|
||||
// if (option.id === "all") {
|
||||
// updated = isAllChecked
|
||||
// ? []
|
||||
// : options
|
||||
// .filter((opt: any) => opt.id !== "all")
|
||||
// .map((opt: any) => opt.id);
|
||||
// } else {
|
||||
// updated = isChecked
|
||||
// ? field.value.filter((val) => val !== option.id)
|
||||
// : [...field.value, option.id];
|
||||
|
||||
// if (isAllChecked && option.id !== "all") {
|
||||
// updated = updated.filter((val) => val !== "all");
|
||||
// }
|
||||
// }
|
||||
|
||||
// field.onChange(updated);
|
||||
// setPublishedFor(updated);
|
||||
// };
|
||||
|
||||
return (
|
||||
<div
|
||||
key={option.id}
|
||||
className="flex gap-2 items-center"
|
||||
>
|
||||
<Checkbox
|
||||
<input
|
||||
type="checkbox"
|
||||
id={option.id}
|
||||
checked={isChecked}
|
||||
onChange={(e) => handleChange(e.target.checked)}
|
||||
className="h-4 w-4 border border-gray-300 rounded text-blue-600 focus:ring-blue-500"
|
||||
/>
|
||||
{/* <Checkbox
|
||||
id={option.id}
|
||||
checked={isChecked}
|
||||
onCheckedChange={handleChange}
|
||||
className="border"
|
||||
/>
|
||||
/> */}
|
||||
<Label htmlFor={option.id}>{option.label}</Label>
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ const CustomEditor = dynamic(
|
|||
() => {
|
||||
return import("@/components/editor/custom-editor");
|
||||
},
|
||||
{ ssr: false }
|
||||
{ ssr: false },
|
||||
);
|
||||
|
||||
export default function FormImage() {
|
||||
|
|
@ -113,7 +113,7 @@ export default function FormImage() {
|
|||
const [isGeneratedArticle, setIsGeneratedArticle] = useState(false);
|
||||
const [articleBody, setArticleBody] = useState<string>("");
|
||||
const [selectedArticleId, setSelectedArticleId] = useState<string | null>(
|
||||
null
|
||||
null,
|
||||
);
|
||||
const [selectedMainKeyword, setSelectedMainKeyword] = useState("");
|
||||
const [selectedWritingStyle, setSelectedWritingStyle] =
|
||||
|
|
@ -169,17 +169,17 @@ export default function FormImage() {
|
|||
.filter(
|
||||
(file) =>
|
||||
["image/jpeg", "image/png", "image/jpg"].includes(file.type) &&
|
||||
file.size <= MAX_FILE_SIZE
|
||||
file.size <= MAX_FILE_SIZE,
|
||||
)
|
||||
.map((file) =>
|
||||
Object.assign(file, {
|
||||
preview: URL.createObjectURL(file),
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
||||
if (validFiles.length === 0) {
|
||||
toast.error(
|
||||
"File tidak valid. Hanya .jpg, .jpeg, .png maksimal 100MB yang diperbolehkan."
|
||||
"File tidak valid. Hanya .jpg, .jpeg, .png maksimal 100MB yang diperbolehkan.",
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
|
@ -209,12 +209,12 @@ export default function FormImage() {
|
|||
files.every(
|
||||
(file: File) =>
|
||||
["image/jpeg", "image/png", "image/jpg"].includes(file.type) &&
|
||||
file.size <= 100 * 1024 * 1024
|
||||
file.size <= 100 * 1024 * 1024,
|
||||
),
|
||||
{
|
||||
message:
|
||||
"Hanya file .jpg, .jpeg, .png, maksimal 100MB yang diperbolehkan.",
|
||||
}
|
||||
},
|
||||
),
|
||||
categoryId: z.string().min(1, { message: "Kategori wajib dipilih." }),
|
||||
tags: z
|
||||
|
|
@ -431,7 +431,7 @@ export default function FormImage() {
|
|||
const articleData = await waitForStatusUpdate();
|
||||
const cleanArticleBody = articleData?.articleBody?.replace(
|
||||
/<img[^>]*>/g,
|
||||
""
|
||||
"",
|
||||
);
|
||||
const articleImagesData = articleData?.imagesUrl?.split(",");
|
||||
setArticleBody(cleanArticleBody || "");
|
||||
|
|
@ -504,7 +504,7 @@ export default function FormImage() {
|
|||
|
||||
if (scheduleId && scheduleType === "3") {
|
||||
const findCategory = resCategory.find((o) =>
|
||||
o.name.toLowerCase().includes("pers rilis")
|
||||
o.name.toLowerCase().includes("pers rilis"),
|
||||
);
|
||||
|
||||
if (findCategory) {
|
||||
|
|
@ -535,7 +535,7 @@ export default function FormImage() {
|
|||
setPublishedFor(
|
||||
options
|
||||
.filter((opt: any) => opt.id !== "all")
|
||||
.map((opt: any) => opt.id)
|
||||
.map((opt: any) => opt.id),
|
||||
);
|
||||
}
|
||||
} else {
|
||||
|
|
@ -572,8 +572,8 @@ export default function FormImage() {
|
|||
const finalDescription = isSwitchOn
|
||||
? data.description
|
||||
: selectedFileType === "rewrite"
|
||||
? data.rewriteDescription
|
||||
: data.descriptionOri;
|
||||
? data.rewriteDescription
|
||||
: data.descriptionOri;
|
||||
|
||||
if (!finalDescription?.trim()) {
|
||||
MySwal.fire("Error", "Deskripsi tidak boleh kosong.", "error");
|
||||
|
|
@ -628,7 +628,7 @@ export default function FormImage() {
|
|||
MySwal.fire(
|
||||
"Error",
|
||||
response.message || "Failed to create article",
|
||||
"error"
|
||||
"error",
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
|
@ -647,7 +647,7 @@ export default function FormImage() {
|
|||
MySwal.fire(
|
||||
"Error",
|
||||
uploadResponse.message || "Failed to upload files",
|
||||
"error"
|
||||
"error",
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
|
@ -663,7 +663,7 @@ export default function FormImage() {
|
|||
MySwal.fire(
|
||||
"Error",
|
||||
"Failed to upload files. Please try again.",
|
||||
"error"
|
||||
"error",
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
|
@ -705,7 +705,7 @@ export default function FormImage() {
|
|||
idx: number,
|
||||
id: string,
|
||||
file: any,
|
||||
duration: string
|
||||
duration: string,
|
||||
) {
|
||||
console.log(idx, id, file, duration);
|
||||
|
||||
|
|
@ -741,7 +741,7 @@ export default function FormImage() {
|
|||
onChunkComplete: (
|
||||
chunkSize: any,
|
||||
bytesAccepted: any,
|
||||
bytesTotal: any
|
||||
bytesTotal: any,
|
||||
) => {
|
||||
const uploadPersen = Math.floor((bytesAccepted / bytesTotal) * 100);
|
||||
progressInfo[idx].percentage = uploadPersen;
|
||||
|
|
@ -996,14 +996,43 @@ export default function FormImage() {
|
|||
<div className="flex flex-row items-center gap-3 py-3 ">
|
||||
<Label>Ai Assistance</Label>
|
||||
<div className="flex items-center gap-3">
|
||||
<Switch
|
||||
<label className="relative inline-flex items-center cursor-pointer">
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={isSwitchOn}
|
||||
onChange={(e) => setIsSwitchOn(e.target.checked)}
|
||||
className="sr-only peer"
|
||||
/>
|
||||
<div
|
||||
className="
|
||||
w-11 h-6
|
||||
bg-gray-300
|
||||
rounded-full
|
||||
peer
|
||||
peer-checked:bg-blue-600
|
||||
transition-colors
|
||||
after:content-['']
|
||||
after:absolute
|
||||
after:top-[2px]
|
||||
after:left-[2px]
|
||||
after:bg-white
|
||||
after:rounded-full
|
||||
after:h-5
|
||||
after:w-5
|
||||
after:transition-transform
|
||||
peer-checked:after:translate-x-5
|
||||
"
|
||||
/>
|
||||
</label>
|
||||
|
||||
{/* <Switch
|
||||
defaultChecked={isSwitchOn}
|
||||
color="primary"
|
||||
id="c2"
|
||||
onCheckedChange={(checked: boolean) =>
|
||||
setIsSwitchOn(checked)
|
||||
}
|
||||
/>
|
||||
/> */}
|
||||
</div>
|
||||
</div>
|
||||
{isSwitchOn && (
|
||||
|
|
@ -1262,14 +1291,13 @@ export default function FormImage() {
|
|||
|
||||
<p className="text-sm font-semibold">Content Rewrite</p>
|
||||
<div className="my-2">
|
||||
<Button
|
||||
size="sm"
|
||||
<button
|
||||
type="button"
|
||||
onClick={handleRewriteClick}
|
||||
className="bg-blue-500 text-white py-2 px-4 rounded"
|
||||
className="bg-blue-500 text-white py-2 px-3 rounded hover:bg-black"
|
||||
>
|
||||
Content Rewrite
|
||||
</Button>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{showRewriteEditor && (
|
||||
|
|
@ -1498,20 +1526,20 @@ export default function FormImage() {
|
|||
option.id === "all"
|
||||
? isAllChecked
|
||||
: field.value.includes(option.id);
|
||||
|
||||
const handleChange = () => {
|
||||
|
||||
const handleChange = (checked: boolean) => {
|
||||
let updated: string[] = [];
|
||||
|
||||
if (option.id === "all") {
|
||||
updated = isAllChecked
|
||||
? []
|
||||
: options
|
||||
updated = checked
|
||||
? options
|
||||
.filter((opt: any) => opt.id !== "all")
|
||||
.map((opt: any) => opt.id);
|
||||
.map((opt: any) => opt.id)
|
||||
: [];
|
||||
} else {
|
||||
updated = isChecked
|
||||
? field.value.filter((val) => val !== option.id)
|
||||
: [...field.value, option.id];
|
||||
updated = checked
|
||||
? [...field.value, option.id]
|
||||
: field.value.filter((val) => val !== option.id);
|
||||
|
||||
if (isAllChecked && option.id !== "all") {
|
||||
updated = updated.filter((val) => val !== "all");
|
||||
|
|
@ -1522,17 +1550,48 @@ export default function FormImage() {
|
|||
setPublishedFor(updated);
|
||||
};
|
||||
|
||||
// const handleChange = () => {
|
||||
// let updated: string[] = [];
|
||||
|
||||
// if (option.id === "all") {
|
||||
// updated = isAllChecked
|
||||
// ? []
|
||||
// : options
|
||||
// .filter((opt: any) => opt.id !== "all")
|
||||
// .map((opt: any) => opt.id);
|
||||
// } else {
|
||||
// updated = isChecked
|
||||
// ? field.value.filter((val) => val !== option.id)
|
||||
// : [...field.value, option.id];
|
||||
|
||||
// if (isAllChecked && option.id !== "all") {
|
||||
// updated = updated.filter((val) => val !== "all");
|
||||
// }
|
||||
// }
|
||||
|
||||
// field.onChange(updated);
|
||||
// setPublishedFor(updated);
|
||||
// };
|
||||
|
||||
return (
|
||||
<div
|
||||
key={option.id}
|
||||
className="flex gap-2 items-center"
|
||||
>
|
||||
<Checkbox
|
||||
<input
|
||||
type="checkbox"
|
||||
id={option.id}
|
||||
checked={isChecked}
|
||||
onChange={(e) => handleChange(e.target.checked)}
|
||||
className="h-4 w-4 border border-gray-300 rounded text-blue-600 focus:ring-blue-500"
|
||||
/>
|
||||
|
||||
{/* <Checkbox
|
||||
id={option.id}
|
||||
checked={isChecked}
|
||||
onCheckedChange={handleChange}
|
||||
className="border"
|
||||
/>
|
||||
/> */}
|
||||
<Label htmlFor={option.id}>{option.label}</Label>
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import { Link } from "@/i18n/routing";
|
|||
import { DynamicLogoTenant } from "./dynamic-logo-tenant";
|
||||
import { useTranslations } from "next-intl";
|
||||
import LocalSwitcher from "../partials/header/locale-switcher";
|
||||
import ThemeSwitcher from "../partials/header/theme-switcher";
|
||||
|
||||
export default function Navbar() {
|
||||
const t = useTranslations("Navbar");
|
||||
|
|
@ -121,7 +122,7 @@ export default function Navbar() {
|
|||
isDropdownOpen ||
|
||||
pathname.startsWith("/public/publication")
|
||||
? "text-black"
|
||||
: ""
|
||||
: "",
|
||||
)}
|
||||
>
|
||||
{item.label}
|
||||
|
|
@ -131,7 +132,7 @@ export default function Navbar() {
|
|||
isDropdownOpen ||
|
||||
pathname.startsWith("/public/publication")
|
||||
? "opacity-100"
|
||||
: "opacity-0"
|
||||
: "opacity-0",
|
||||
)}
|
||||
/>
|
||||
</button>
|
||||
|
|
@ -156,7 +157,7 @@ export default function Navbar() {
|
|||
onClick={handleClick}
|
||||
className={cn(
|
||||
"relative text-gray-500 hover:text-black transition-colors",
|
||||
isActive && "text-black"
|
||||
isActive && "text-black",
|
||||
)}
|
||||
>
|
||||
{item.label}
|
||||
|
|
@ -170,6 +171,10 @@ export default function Navbar() {
|
|||
})}
|
||||
</nav>
|
||||
|
||||
{/* <div className="hidden custom-lg-button:flex text-left">
|
||||
<ThemeSwitcher />
|
||||
</div> */}
|
||||
|
||||
{/* 🔹 PROFILE / LOGIN SECTION */}
|
||||
<nav className="hidden md:flex items-center gap-3 z-10 relative">
|
||||
{!isLoggedIn ? (
|
||||
|
|
@ -180,7 +185,9 @@ export default function Navbar() {
|
|||
</Button>
|
||||
</Link>
|
||||
<Link href="/auth">
|
||||
<Button className="bg-red-700 text-white cursor-pointer hover:bg-white hover:border hover:border-red-700 hover:text-red-700">{t("login")}</Button>
|
||||
<Button className="bg-red-700 text-white cursor-pointer hover:bg-white hover:border hover:border-red-700 hover:text-red-700">
|
||||
{t("login")}
|
||||
</Button>
|
||||
</Link>
|
||||
</>
|
||||
) : (
|
||||
|
|
|
|||
|
|
@ -125,7 +125,7 @@ export default function DashboardContainer() {
|
|||
return (
|
||||
<div className="space-y-8">
|
||||
{/* Stats Cards */}
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-6 gap-4">
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-6 gap-4 p-2">
|
||||
{/* User Profile Card */}
|
||||
<motion.div
|
||||
className="col-span-1 md:col-span-2 bg-white rounded-2xl shadow-md border border-gray-200 p-4 hover:shadow-lg transition-all duration-300"
|
||||
|
|
@ -135,11 +135,11 @@ export default function DashboardContainer() {
|
|||
>
|
||||
<div className="flex justify-between items-start">
|
||||
<div className="space-y-2">
|
||||
<p className="text-gray-600 font-medium">Welcome back,</p>
|
||||
<p className="text-xl font-semibold text-gray-900">{username}</p>
|
||||
<p className="text-sm text-gray-500">Admin Dashboard</p>
|
||||
<p className="text-gray-600 dark:text-black font-medium">Welcome back,</p>
|
||||
<p className="text-xl font-semibold text-gray-900 dark:text-black ">{username}</p>
|
||||
<p className="text-sm text-gray-500 dark:text-black ">Admin Dashboard</p>
|
||||
</div>
|
||||
<div className="p-3 bg-gradient-to-br from-blue-50 to-purple-50 rounded-xl">
|
||||
<div className="p-3 bg-gradient-to-br from-blue-50 to-purple-50 rounded-xl dark:text-black ">
|
||||
<DashboardUserIcon size={60} />
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -153,7 +153,7 @@ export default function DashboardContainer() {
|
|||
transition={{ delay: 0.2 }}
|
||||
>
|
||||
<div className="flex flex-col items-center text-center space-y-3">
|
||||
<div className="p-3 bg-gradient-to-br from-green-50 to-emerald-50 rounded-xl">
|
||||
<div className="p-3 bg-gradient-to-br from-green-50 to-emerald-50 rounded-xl dark:text-black">
|
||||
<DashboardSpeecIcon />
|
||||
</div>
|
||||
<div>
|
||||
|
|
@ -173,7 +173,7 @@ export default function DashboardContainer() {
|
|||
transition={{ delay: 0.3 }}
|
||||
>
|
||||
<div className="flex flex-col items-center text-center space-y-3">
|
||||
<div className="p-3 bg-gradient-to-br from-blue-50 to-cyan-50 rounded-xl">
|
||||
<div className="p-3 bg-gradient-to-br from-blue-50 to-cyan-50 rounded-xl dark:text-black">
|
||||
<DashboardConnectIcon />
|
||||
</div>
|
||||
<div>
|
||||
|
|
@ -193,7 +193,7 @@ export default function DashboardContainer() {
|
|||
transition={{ delay: 0.4 }}
|
||||
>
|
||||
<div className="flex flex-col items-center text-center space-y-3">
|
||||
<div className="p-3 bg-gradient-to-br from-purple-50 to-pink-50 rounded-xl">
|
||||
<div className="p-3 bg-gradient-to-br from-purple-50 to-pink-50 rounded-xl dark:text-black">
|
||||
<DashboardShareIcon />
|
||||
</div>
|
||||
<div>
|
||||
|
|
@ -213,7 +213,7 @@ export default function DashboardContainer() {
|
|||
transition={{ delay: 0.5 }}
|
||||
>
|
||||
<div className="flex flex-col items-center text-center space-y-3">
|
||||
<div className="p-3 bg-gradient-to-br from-orange-50 to-red-50 rounded-xl">
|
||||
<div className="p-3 bg-gradient-to-br from-orange-50 to-red-50 rounded-xl dark:text-black">
|
||||
<DashboardCommentIcon size={40} />
|
||||
</div>
|
||||
<div>
|
||||
|
|
@ -227,7 +227,7 @@ export default function DashboardContainer() {
|
|||
</div>
|
||||
|
||||
{/* Content Section */}
|
||||
<div className="grid grid-cols-1 lg:grid-cols-2 gap-4">
|
||||
<div className="grid grid-cols-1 lg:grid-cols-2 gap-4 p-2">
|
||||
{/* Analytics Chart */}
|
||||
<motion.div
|
||||
className="bg-white rounded-2xl shadow-md border border-gray-200 p-4"
|
||||
|
|
@ -306,12 +306,12 @@ export default function DashboardContainer() {
|
|||
))}
|
||||
</div>
|
||||
|
||||
<div className="mt-6 flex justify-center">
|
||||
{/* <div className="mt-6 flex justify-center">
|
||||
<CustomPagination
|
||||
totalPage={totalPage}
|
||||
onPageChange={(data) => setPage(data)}
|
||||
/>
|
||||
</div>
|
||||
</div> */}
|
||||
</motion.div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import axios from "axios";
|
||||
|
||||
const baseURL = "https://disestages.com/api";
|
||||
const baseURL = "https://new.disestages.com/api";
|
||||
|
||||
const axiosNulisAIInstance = axios.create({
|
||||
baseURL,
|
||||
|
|
|
|||
Loading…
Reference in New Issue