fix: fixing bugs report friday

This commit is contained in:
Sabda Yagra 2026-02-02 11:31:13 +07:00
parent 5b6ec0342b
commit 2b545ec51a
15 changed files with 279 additions and 150 deletions

View File

@ -71,7 +71,7 @@ const TableCategories = () => {
{ {
accessorKey: "statusId", accessorKey: "statusId",
header: "Status", header: "Status",
cell: ({ row }) => (row.original.isPublish ? "Publish" : "Draft"), cell: ({ row }) => (row.original.isActive ? "Active" : "Draft"),
}, },
{ {
id: "actions", id: "actions",

View File

@ -6,12 +6,12 @@ import TableImage from "./table-image";
import PendingApprovalTable from "./pending-approval-table"; import PendingApprovalTable from "./pending-approval-table";
const ImageTabs = () => { const ImageTabs = () => {
const [activeTab, setActiveTab] = React.useState("pending"); const [activeTab, setActiveTab] = React.useState("submitted");
return ( return (
<div className="w-full"> <div className="w-full">
<Tabs value={activeTab} onValueChange={setActiveTab} 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"> <TabsList className="inline-flex h-10 bg-gray-50 border border-gray-200 p-1 rounded-lg shadow-sm">
<TabsTrigger <TabsTrigger
value="pending" value="pending"
@ -33,18 +33,18 @@ const ImageTabs = () => {
</TabsTrigger> </TabsTrigger>
</TabsList> </TabsList>
</div> </div>
*/}
<TabsContent value="submitted" className="mt-0"> <TabsContent value="submitted" className="mt-0">
<div className="bg-white rounded-lg border border-gray-200 shadow-sm"> <div className="bg-white rounded-lg border border-gray-200 shadow-sm">
<TableImage /> <TableImage />
</div> </div>
</TabsContent> </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"> <div className="bg-white rounded-lg border border-gray-200 shadow-sm">
<PendingApprovalTable typeId={1} /> <PendingApprovalTable typeId={1} />
</div> </div>
</TabsContent> </TabsContent> */}
</Tabs> </Tabs>
</div> </div>
); );

View File

@ -290,9 +290,9 @@ const TableImage = () => {
return ( return (
<div className="w-full overflow-x-auto"> <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="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"> <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 text-gray-400 dark:text-white" /> <Search className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 " />
<Input <input
type="text" type="text"
placeholder="Search Judul..." placeholder="Search Judul..."
className="pl-9 bg-transparent dark:border-secondary dark:placeholder-white/80 dark:focus:border-secondary dark:text-white" className="pl-9 bg-transparent dark:border-secondary dark:placeholder-white/80 dark:focus:border-secondary dark:text-white"

View File

@ -5,7 +5,7 @@ const ImageCreatePage = async () => {
return ( return (
<div> <div>
<SiteBreadcrumb /> <SiteBreadcrumb />
<div className="space-y-4 bg-slate-100"> <div className="space-y-4 bg-slate-100 dark:bg-default-50">
<FormImage /> <FormImage />
</div> </div>
</div> </div>

View File

@ -11,7 +11,7 @@ const AudioVisualTabs = () => {
return ( return (
<div className="w-full"> <div className="w-full">
<Tabs value={activeTab} onValueChange={setActiveTab} 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"> <TabsList className="inline-flex h-10 bg-gray-50 border border-gray-200 p-1 rounded-lg shadow-sm">
<TabsTrigger <TabsTrigger
value="submitted" value="submitted"
@ -32,7 +32,7 @@ const AudioVisualTabs = () => {
</div> </div>
</TabsTrigger> </TabsTrigger>
</TabsList> </TabsList>
</div> </div> */}
<TabsContent value="submitted" className="mt-0"> <TabsContent value="submitted" className="mt-0">
<div className="bg-white rounded-lg border border-gray-200 shadow-sm"> <div className="bg-white rounded-lg border border-gray-200 shadow-sm">
@ -40,11 +40,11 @@ const AudioVisualTabs = () => {
</div> </div>
</TabsContent> </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"> <div className="bg-white rounded-lg border border-gray-200 shadow-sm">
<PendingApprovalTable typeId={2} /> <PendingApprovalTable typeId={2} />
</div> </div>
</TabsContent> </TabsContent> */}
</Tabs> </Tabs>
</div> </div>
); );

View File

@ -21,7 +21,7 @@ export default function AdminPage() {
return ( return (
<motion.div <motion.div
className="h-full overflow-auto bg-gray-50 dark:bg-black" className="h-full overflow-auto"
initial={{ opacity: 0 }} initial={{ opacity: 0 }}
animate={{ opacity: 1 }} animate={{ opacity: 1 }}
transition={{ duration: 0.3 }} transition={{ duration: 0.3 }}

View File

@ -204,7 +204,7 @@ function TenantSettingsContentTable() {
Manage approval workflows and user levels for your tenant Manage approval workflows and user levels for your tenant
</p> </p>
</div> </div>
<div className="flex items-center gap-2"> {/* <div className="flex items-center gap-2">
<SettingsIcon className="h-6 w-6 text-gray-500" /> <SettingsIcon className="h-6 w-6 text-gray-500" />
<Button variant="outline" size="sm" onClick={checkWorkflowStatus}> <Button variant="outline" size="sm" onClick={checkWorkflowStatus}>
Check Workflow Status Check Workflow Status
@ -217,7 +217,7 @@ function TenantSettingsContentTable() {
> >
Test Modal Test Modal
</Button> </Button>
</div> </div> */}
</div> </div>
<Tabs value={activeTab} onValueChange={setActiveTab} className="w-full"> <Tabs value={activeTab} onValueChange={setActiveTab} className="w-full">
@ -266,7 +266,8 @@ function TenantSettingsContentTable() {
)} )}
</div> </div>
{isEditingWorkflow && workflow && workflow.workflow?.id ? ( {/* {isEditingWorkflow && workflow && workflow.workflow?.id ? ( */}
{isEditingWorkflow ? (
<Card> <Card>
<CardHeader> <CardHeader>
<CardTitle className="flex items-center justify-between"> <CardTitle className="flex items-center justify-between">
@ -281,8 +282,8 @@ function TenantSettingsContentTable() {
</CardHeader> </CardHeader>
<CardContent> <CardContent>
<ApprovalWorkflowForm <ApprovalWorkflowForm
key={workflow.workflow.id} key={workflow?.workflow.id}
workflowId={workflow.workflow.id} workflowId={workflow?.workflow.id}
initialData={ initialData={
workflow workflow
? { ? {
@ -362,21 +363,21 @@ function TenantSettingsContentTable() {
</p> </p>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4 mb-6"> <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"> <div className="text-2xl font-bold text-blue-600">
{workflow.workflow.totalSteps} {workflow.workflow.totalSteps}
</div> </div>
<div className="text-sm text-gray-600">Total Steps</div> <div className="text-sm text-gray-600">Total Steps</div>
</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"> <div className="text-2xl font-bold text-green-600">
{workflow.workflow.activeSteps} {workflow.workflow.activeSteps}
</div> </div>
<div className="text-sm text-gray-600">Active Steps</div> <div className="text-sm text-gray-600">Active Steps</div>
</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 <div
className={`text-2xl font-bold ${ className={`text-2xl font-bold ${
// workflow.workflow.requiresApproval // workflow.workflow.requiresApproval
@ -387,9 +388,7 @@ function TenantSettingsContentTable() {
> >
{ {
// workflow.workflow.requiresApproval // workflow.workflow.requiresApproval
workflow.clientSettings.requiresApproval workflow.clientSettings.requiresApproval ? "Yes" : "No"
? "Yes"
: "No"
} }
</div> </div>
<div className="text-sm text-gray-600"> <div className="text-sm text-gray-600">
@ -397,7 +396,7 @@ function TenantSettingsContentTable() {
</div> </div>
</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 <div
className={`text-2xl font-bold ${ className={`text-2xl font-bold ${
// workflow.workflow.autoPublish // workflow.workflow.autoPublish
@ -425,14 +424,14 @@ function TenantSettingsContentTable() {
{workflow.steps.map((step: any, index: number) => ( {workflow.steps.map((step: any, index: number) => (
<div <div
key={index} 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="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"> <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} {step.stepOrder}
</div> </div>
<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"> <div className="text-sm text-gray-500">
{step.conditionType && {step.conditionType &&
`Condition: ${step.conditionType}`} `Condition: ${step.conditionType}`}
@ -480,7 +479,7 @@ function TenantSettingsContentTable() {
<div className="mb-6"> <div className="mb-6">
<h4 className="text-lg font-medium mb-3">Client Settings</h4> <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="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"> <div className="text-sm font-medium text-gray-700 mb-1">
Default Workflow Default Workflow
</div> </div>
@ -488,7 +487,7 @@ function TenantSettingsContentTable() {
{workflow.clientSettings.defaultWorkflowName} {workflow.clientSettings.defaultWorkflowName}
</div> </div>
</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"> <div className="text-sm font-medium text-gray-700 mb-1">
Auto Publish Articles Auto Publish Articles
</div> </div>
@ -504,7 +503,7 @@ function TenantSettingsContentTable() {
: "No"} : "No"}
</div> </div>
</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"> <div className="text-sm font-medium text-gray-700 mb-1">
Requires Approval Requires Approval
</div> </div>
@ -520,7 +519,7 @@ function TenantSettingsContentTable() {
: "No"} : "No"}
</div> </div>
</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"> <div className="text-sm font-medium text-gray-700 mb-1">
Settings Active Settings Active
</div> </div>
@ -543,7 +542,7 @@ function TenantSettingsContentTable() {
Workflow Statistics Workflow Statistics
</h4> </h4>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4"> <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"> <div className="text-sm font-medium text-gray-700 mb-1">
Total Articles Processed Total Articles Processed
</div> </div>
@ -551,7 +550,7 @@ function TenantSettingsContentTable() {
{workflow.statistics.totalArticlesProcessed} {workflow.statistics.totalArticlesProcessed}
</div> </div>
</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"> <div className="text-sm font-medium text-gray-700 mb-1">
Pending Articles Pending Articles
</div> </div>
@ -559,7 +558,7 @@ function TenantSettingsContentTable() {
{workflow.statistics.pendingArticles} {workflow.statistics.pendingArticles}
</div> </div>
</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"> <div className="text-sm font-medium text-gray-700 mb-1">
Approved Articles Approved Articles
</div> </div>
@ -567,7 +566,7 @@ function TenantSettingsContentTable() {
{workflow.statistics.approvedArticles} {workflow.statistics.approvedArticles}
</div> </div>
</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"> <div className="text-sm font-medium text-gray-700 mb-1">
Rejected Articles Rejected Articles
</div> </div>
@ -575,7 +574,7 @@ function TenantSettingsContentTable() {
{workflow.statistics.rejectedArticles} {workflow.statistics.rejectedArticles}
</div> </div>
</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"> <div className="text-sm font-medium text-gray-700 mb-1">
Average Processing Time Average Processing Time
</div> </div>
@ -583,7 +582,7 @@ function TenantSettingsContentTable() {
{workflow.statistics.averageProcessingTime}h {workflow.statistics.averageProcessingTime}h
</div> </div>
</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"> <div className="text-sm font-medium text-gray-700 mb-1">
Most Active Step Most Active Step
</div> </div>
@ -600,7 +599,7 @@ function TenantSettingsContentTable() {
Workflow Information Workflow Information
</h4> </h4>
<div className="grid grid-cols-1 md:grid-cols-2 gap-4"> <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"> <div className="text-sm font-medium text-gray-700 mb-1">
Client ID Client ID
</div> </div>
@ -608,7 +607,7 @@ function TenantSettingsContentTable() {
{workflow.workflow.clientId} {workflow.workflow.clientId}
</div> </div>
</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"> <div className="text-sm font-medium text-gray-700 mb-1">
Created At Created At
</div> </div>
@ -616,7 +615,7 @@ function TenantSettingsContentTable() {
{new Date(workflow.workflow.createdAt).toLocaleString()} {new Date(workflow.workflow.createdAt).toLocaleString()}
</div> </div>
</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"> <div className="text-sm font-medium text-gray-700 mb-1">
Updated At Updated At
</div> </div>
@ -624,7 +623,7 @@ function TenantSettingsContentTable() {
{new Date(workflow.workflow.updatedAt).toLocaleString()} {new Date(workflow.workflow.updatedAt).toLocaleString()}
</div> </div>
</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"> <div className="text-sm font-medium text-gray-700 mb-1">
Workflow ID Workflow ID
</div> </div>
@ -632,7 +631,7 @@ function TenantSettingsContentTable() {
{workflow.workflow.id} {workflow.workflow.id}
</div> </div>
</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"> <div className="text-sm font-medium text-gray-700 mb-1">
Has Branches Has Branches
</div> </div>
@ -646,7 +645,7 @@ function TenantSettingsContentTable() {
{workflow.workflow.hasBranches ? "Yes" : "No"} {workflow.workflow.hasBranches ? "Yes" : "No"}
</div> </div>
</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"> <div className="text-sm font-medium text-gray-700 mb-1">
Max Step Order Max Step Order
</div> </div>
@ -751,7 +750,7 @@ function TenantSettingsContentTable() {
onOpenChange={setIsHierarchyExpanded} onOpenChange={setIsHierarchyExpanded}
> >
<CollapsibleTrigger asChild> <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"> <CardTitle className="flex items-center justify-between">
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<UsersIcon className="h-5 w-5" /> <UsersIcon className="h-5 w-5" />
@ -769,7 +768,7 @@ function TenantSettingsContentTable() {
<CardContent> <CardContent>
<div className="space-y-3"> <div className="space-y-3">
{userLevels {userLevels
.filter((ul) => !ul.parentLevelId) // Root levels .filter((ul) => !ul.parentLevelId)
.sort((a, b) => a.levelNumber - b.levelNumber) .sort((a, b) => a.levelNumber - b.levelNumber)
.map((rootLevel) => ( .map((rootLevel) => (
<div key={rootLevel.id} className="space-y-2"> <div key={rootLevel.id} className="space-y-2">
@ -779,7 +778,7 @@ function TenantSettingsContentTable() {
{rootLevel.levelNumber} {rootLevel.levelNumber}
</div> </div>
<div className="flex-1"> <div className="flex-1">
<div className="font-medium"> <div className="font-medium text-black">
{rootLevel.name} {rootLevel.name}
</div> </div>
<div className="text-sm text-gray-500"> <div className="text-sm text-gray-500">
@ -814,7 +813,7 @@ function TenantSettingsContentTable() {
{childLevel.levelNumber} {childLevel.levelNumber}
</div> </div>
<div className="flex-1"> <div className="flex-1">
<div className="font-medium text-sm"> <div className="font-medium text-sm text-black">
{childLevel.name} {childLevel.name}
</div> </div>
<div className="text-xs text-gray-500"> <div className="text-xs text-gray-500">
@ -846,7 +845,7 @@ function TenantSettingsContentTable() {
)} )}
<Table className="overflow-hidden mt-3 mx-3"> <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) => ( {table.getHeaderGroups().map((headerGroup) => (
<TableRow key={headerGroup.id} className="bg-default-200"> <TableRow key={headerGroup.id} className="bg-default-200">
{headerGroup.headers.map((header) => ( {headerGroup.headers.map((header) => (

View File

@ -1223,7 +1223,7 @@ export const UserLevelsForm: React.FC<UserLevelsFormProps> = ({
{menus.map((menu) => ( {menus.map((menu) => (
<label <label
key={menu.id} 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 <input
type="checkbox" type="checkbox"
@ -1312,7 +1312,7 @@ export const UserLevelsForm: React.FC<UserLevelsFormProps> = ({
{actions.map((action) => ( {actions.map((action) => (
<label <label
key={action.id} 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 <input
type="checkbox" type="checkbox"

View File

@ -61,10 +61,10 @@ export default function CategoriesDetailForm() {
</div> </div>
{/* Slug */} {/* Slug */}
<div className="space-y-2 py-3"> {/* <div className="space-y-2 py-3">
<Label>Slug</Label> <Label>Slug</Label>
<Input type="text" value={detail.slug || "-"} readOnly /> <Input type="text" value={detail.slug || "-"} readOnly />
</div> </div> */}
{/* Description */} {/* Description */}
<div className="space-y-2 py-3"> <div className="space-y-2 py-3">
@ -89,7 +89,7 @@ export default function CategoriesDetailForm() {
</div> </div>
{/* Tags */} {/* Tags */}
<div className="space-y-2 py-3 "> {/* <div className="space-y-2 py-3 ">
<Label>Tags</Label> <Label>Tags</Label>
<div className="flex flex-wrap gap-2 p-4 border rounded-sm"> <div className="flex flex-wrap gap-2 p-4 border rounded-sm">
{detail?.tags?.length > 0 ? ( {detail?.tags?.length > 0 ? (
@ -102,7 +102,7 @@ export default function CategoriesDetailForm() {
<span className="text-slate-400 text-sm">No tags</span> <span className="text-slate-400 text-sm">No tags</span>
)} )}
</div> </div>
</div> </div> */}
</Card> </Card>
{/* SIDEBAR */} {/* SIDEBAR */}
@ -122,7 +122,7 @@ export default function CategoriesDetailForm() {
<div> <div>
<Label>Status</Label> <Label>Status</Label>
<p className="text-sm text-slate-600"> <p className="text-sm text-slate-600">
{detail.isPublish ? "Published" : "Draft"} |{" "} {/* {detail.isPublish ? "Published" : "Draft"} |{" "} */}
{detail.isActive ? "Active" : "Inactive"} {detail.isActive ? "Active" : "Inactive"}
</p> </p>
</div> </div>

View File

@ -60,7 +60,7 @@ export default function CategoriesUpdateForm() {
}, [id]); }, [id]);
const handleChange = ( const handleChange = (
e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement> e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>,
) => { ) => {
const { name, value } = e.target; const { name, value } = e.target;
setFormData((prev) => (prev ? { ...prev, [name]: value } : prev)); setFormData((prev) => (prev ? { ...prev, [name]: value } : prev));
@ -94,7 +94,7 @@ export default function CategoriesUpdateForm() {
MySwal.fire( MySwal.fire(
"Error", "Error",
res?.message || "Gagal mengunggah thumbnail", res?.message || "Gagal mengunggah thumbnail",
"error" "error",
); );
return null; return null;
} }
@ -186,7 +186,7 @@ export default function CategoriesUpdateForm() {
</div> </div>
{/* Thumbnail Upload */} {/* Thumbnail Upload */}
<div className="space-y-2 py-3"> {/* <div className="space-y-2 py-3">
<Label>Thumbnail</Label> <Label>Thumbnail</Label>
{thumbnailPreview && ( {thumbnailPreview && (
<img <img
@ -203,18 +203,25 @@ export default function CategoriesUpdateForm() {
{isUploading && ( {isUploading && (
<p className="text-sm text-blue-500 mt-1">Mengunggah...</p> <p className="text-sm text-blue-500 mt-1">Mengunggah...</p>
)} )}
</div> </div> */}
{/* Status */} {/* Status */}
<div className="flex items-center gap-4 py-3"> <div className="flex items-center gap-4 py-3">
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<Checkbox {/* <Checkbox
checked={formData.isActive} checked={formData.isActive}
onCheckedChange={(checked) => onCheckedChange={(checked) =>
handleCheckboxChange("isActive", Boolean(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>
</div> </div>

View File

@ -362,7 +362,7 @@ const CustomEditor = dynamic(
() => { () => {
return import("@/components/editor/custom-editor"); return import("@/components/editor/custom-editor");
}, },
{ ssr: false } { ssr: false },
); );
interface FileWithPreview extends File { interface FileWithPreview extends File {
@ -412,11 +412,11 @@ export default function FormVideo() {
const [isGeneratedArticle, setIsGeneratedArticle] = useState(false); const [isGeneratedArticle, setIsGeneratedArticle] = useState(false);
const [articleBody, setArticleBody] = useState<string>(""); const [articleBody, setArticleBody] = useState<string>("");
const [selectedArticleId, setSelectedArticleId] = useState<string | null>( const [selectedArticleId, setSelectedArticleId] = useState<string | null>(
null null,
); );
const [selectedMainKeyword, setSelectedMainKeyword] = useState(""); const [selectedMainKeyword, setSelectedMainKeyword] = useState("");
const [publishedForError, setPublishedForError] = useState<string | null>( const [publishedForError, setPublishedForError] = useState<string | null>(
null null,
); );
const userId = Cookies.get("userId"); const userId = Cookies.get("userId");
const [selectedSize, setSelectedSize] = useState(""); const [selectedSize, setSelectedSize] = useState("");
@ -478,7 +478,7 @@ export default function FormVideo() {
} }
const filesWithPreview = acceptedFiles.map((file) => const filesWithPreview = acceptedFiles.map((file) =>
Object.assign(file, { preview: URL.createObjectURL(file) }) Object.assign(file, { preview: URL.createObjectURL(file) }),
); );
setFiles((prev) => { setFiles((prev) => {
@ -503,12 +503,12 @@ export default function FormVideo() {
files.every( files.every(
(file: File) => (file: File) =>
["video/mp4", "video/mov", "video/avi"].includes(file.type) && ["video/mp4", "video/mov", "video/avi"].includes(file.type) &&
file.size <= 100 * 1024 * 1024 file.size <= 100 * 1024 * 1024,
), ),
{ {
message: message:
"Hanya file .mp4, .mov, .avi, maksimal 100MB yang diperbolehkan.", "Hanya file .mp4, .mov, .avi, maksimal 100MB yang diperbolehkan.",
} },
), ),
categoryId: z.string().min(1, { message: "Kategori wajib dipilih." }), categoryId: z.string().min(1, { message: "Kategori wajib dipilih." }),
tags: z tags: z
@ -722,7 +722,7 @@ export default function FormVideo() {
const articleData = await waitForStatusUpdate(); const articleData = await waitForStatusUpdate();
const cleanArticleBody = articleData?.articleBody?.replace( const cleanArticleBody = articleData?.articleBody?.replace(
/<img[^>]*>/g, /<img[^>]*>/g,
"" "",
); );
const articleImagesData = articleData?.imagesUrl?.split(","); const articleImagesData = articleData?.imagesUrl?.split(",");
setArticleBody(cleanArticleBody || ""); setArticleBody(cleanArticleBody || "");
@ -798,7 +798,7 @@ export default function FormVideo() {
if (scheduleId && scheduleType === "3") { if (scheduleId && scheduleType === "3") {
const findCategory = resCategory.find((o) => const findCategory = resCategory.find((o) =>
o.name.toLowerCase().includes("pers rilis") o.name.toLowerCase().includes("pers rilis"),
); );
if (findCategory) { if (findCategory) {
@ -829,7 +829,7 @@ export default function FormVideo() {
setPublishedFor( setPublishedFor(
options options
.filter((opt: any) => opt.id !== "all") .filter((opt: any) => opt.id !== "all")
.map((opt: any) => opt.id) .map((opt: any) => opt.id),
); );
} }
} else { } else {
@ -959,7 +959,7 @@ export default function FormVideo() {
MySwal.fire( MySwal.fire(
"Error", "Error",
response.message || "Failed to create article", response.message || "Failed to create article",
"error" "error",
); );
return false; return false;
} }
@ -987,7 +987,7 @@ export default function FormVideo() {
MySwal.fire( MySwal.fire(
"Error", "Error",
uploadResponse.message || "Failed to upload files", uploadResponse.message || "Failed to upload files",
"error" "error",
); );
return false; return false;
} }
@ -1003,17 +1003,17 @@ export default function FormVideo() {
try { try {
const thumbnailResponse = await uploadArticleThumbnail( const thumbnailResponse = await uploadArticleThumbnail(
articleId, articleId,
thumbnailFormData thumbnailFormData,
); );
if (thumbnailResponse?.error) { if (thumbnailResponse?.error) {
console.warn( console.warn(
"Thumbnail upload failed:", "Thumbnail upload failed:",
thumbnailResponse.message thumbnailResponse.message,
); );
} else { } else {
console.log( console.log(
"Thumbnail uploaded successfully:", "Thumbnail uploaded successfully:",
thumbnailResponse thumbnailResponse,
); );
} }
} catch (thumbnailError) { } catch (thumbnailError) {
@ -1025,7 +1025,7 @@ export default function FormVideo() {
MySwal.fire( MySwal.fire(
"Error", "Error",
"Failed to upload files. Please try again.", "Failed to upload files. Please try again.",
"error" "error",
); );
return false; return false;
} }
@ -1076,7 +1076,7 @@ export default function FormVideo() {
idx: number, idx: number,
id: string, id: string,
file: any, file: any,
duration: string duration: string,
) { ) {
console.log(idx, id, file, duration); console.log(idx, id, file, duration);
@ -1112,7 +1112,7 @@ export default function FormVideo() {
onChunkComplete: ( onChunkComplete: (
chunkSize: any, chunkSize: any,
bytesAccepted: any, bytesAccepted: any,
bytesTotal: any bytesTotal: any,
) => { ) => {
const uploadPersen = Math.floor((bytesAccepted / bytesTotal) * 100); const uploadPersen = Math.floor((bytesAccepted / bytesTotal) * 100);
progressInfo[idx].percentage = uploadPersen; progressInfo[idx].percentage = uploadPersen;
@ -1356,14 +1356,43 @@ export default function FormVideo() {
<div className="flex flex-row items-center gap-3 py-2"> <div className="flex flex-row items-center gap-3 py-2">
<Label>Ai Assistance</Label> <Label>Ai Assistance</Label>
<div className="flex items-center gap-3"> <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} defaultChecked={isSwitchOn}
color="primary" color="primary"
id="c2" id="c2"
onCheckedChange={(checked: boolean) => onCheckedChange={(checked: boolean) =>
setIsSwitchOn(checked) setIsSwitchOn(checked)
} }
/> /> */}
</div> </div>
</div> </div>
{isSwitchOn && ( {isSwitchOn && (
@ -1622,14 +1651,12 @@ export default function FormVideo() {
<p className="text-sm font-semibold">Content Rewrite</p> <p className="text-sm font-semibold">Content Rewrite</p>
<div className="my-2"> <div className="my-2">
<Button <button type="button"
size="sm"
type="button"
onClick={handleRewriteClick} onClick={handleRewriteClick}
className="bg-blue-500 text-white py-2 px-4 rounded" className="bg-blue-500 text-white py-2 px-4 rounded"
> >
Content Rewrite Content Rewrite
</Button> </button>
</div> </div>
{showRewriteEditor && ( {showRewriteEditor && (
@ -1814,7 +1841,7 @@ export default function FormVideo() {
type="button" type="button"
onClick={() => { onClick={() => {
const updatedTags = field.value.filter( const updatedTags = field.value.filter(
(_, i) => i !== index (_, i) => i !== index,
); );
field.onChange(updatedTags); field.onChange(updatedTags);
}} }}
@ -1852,19 +1879,19 @@ export default function FormVideo() {
? isAllChecked ? isAllChecked
: field.value.includes(option.id); : field.value.includes(option.id);
const handleChange = () => { const handleChange = (checked: boolean) => {
let updated: string[] = []; let updated: string[] = [];
if (option.id === "all") { if (option.id === "all") {
updated = isAllChecked updated = checked
? [] ? options
: options
.filter((opt: any) => opt.id !== "all") .filter((opt: any) => opt.id !== "all")
.map((opt: any) => opt.id); .map((opt: any) => opt.id)
: [];
} else { } else {
updated = isChecked updated = checked
? field.value.filter((val) => val !== option.id) ? [...field.value, option.id]
: [...field.value, option.id]; : field.value.filter((val) => val !== option.id);
if (isAllChecked && option.id !== "all") { if (isAllChecked && option.id !== "all") {
updated = updated.filter((val) => val !== "all"); updated = updated.filter((val) => val !== "all");
@ -1875,17 +1902,47 @@ export default function FormVideo() {
setPublishedFor(updated); 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 ( return (
<div <div
key={option.id} key={option.id}
className="flex gap-2 items-center" 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} id={option.id}
checked={isChecked} checked={isChecked}
onCheckedChange={handleChange} onCheckedChange={handleChange}
className="border" className="border"
/> /> */}
<Label htmlFor={option.id}>{option.label}</Label> <Label htmlFor={option.id}>{option.label}</Label>
</div> </div>
); );

View File

@ -80,7 +80,7 @@ const CustomEditor = dynamic(
() => { () => {
return import("@/components/editor/custom-editor"); return import("@/components/editor/custom-editor");
}, },
{ ssr: false } { ssr: false },
); );
export default function FormImage() { export default function FormImage() {
@ -113,7 +113,7 @@ export default function FormImage() {
const [isGeneratedArticle, setIsGeneratedArticle] = useState(false); const [isGeneratedArticle, setIsGeneratedArticle] = useState(false);
const [articleBody, setArticleBody] = useState<string>(""); const [articleBody, setArticleBody] = useState<string>("");
const [selectedArticleId, setSelectedArticleId] = useState<string | null>( const [selectedArticleId, setSelectedArticleId] = useState<string | null>(
null null,
); );
const [selectedMainKeyword, setSelectedMainKeyword] = useState(""); const [selectedMainKeyword, setSelectedMainKeyword] = useState("");
const [selectedWritingStyle, setSelectedWritingStyle] = const [selectedWritingStyle, setSelectedWritingStyle] =
@ -169,17 +169,17 @@ export default function FormImage() {
.filter( .filter(
(file) => (file) =>
["image/jpeg", "image/png", "image/jpg"].includes(file.type) && ["image/jpeg", "image/png", "image/jpg"].includes(file.type) &&
file.size <= MAX_FILE_SIZE file.size <= MAX_FILE_SIZE,
) )
.map((file) => .map((file) =>
Object.assign(file, { Object.assign(file, {
preview: URL.createObjectURL(file), preview: URL.createObjectURL(file),
}) }),
); );
if (validFiles.length === 0) { if (validFiles.length === 0) {
toast.error( 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; return;
} }
@ -209,12 +209,12 @@ export default function FormImage() {
files.every( files.every(
(file: File) => (file: File) =>
["image/jpeg", "image/png", "image/jpg"].includes(file.type) && ["image/jpeg", "image/png", "image/jpg"].includes(file.type) &&
file.size <= 100 * 1024 * 1024 file.size <= 100 * 1024 * 1024,
), ),
{ {
message: message:
"Hanya file .jpg, .jpeg, .png, maksimal 100MB yang diperbolehkan.", "Hanya file .jpg, .jpeg, .png, maksimal 100MB yang diperbolehkan.",
} },
), ),
categoryId: z.string().min(1, { message: "Kategori wajib dipilih." }), categoryId: z.string().min(1, { message: "Kategori wajib dipilih." }),
tags: z tags: z
@ -431,7 +431,7 @@ export default function FormImage() {
const articleData = await waitForStatusUpdate(); const articleData = await waitForStatusUpdate();
const cleanArticleBody = articleData?.articleBody?.replace( const cleanArticleBody = articleData?.articleBody?.replace(
/<img[^>]*>/g, /<img[^>]*>/g,
"" "",
); );
const articleImagesData = articleData?.imagesUrl?.split(","); const articleImagesData = articleData?.imagesUrl?.split(",");
setArticleBody(cleanArticleBody || ""); setArticleBody(cleanArticleBody || "");
@ -504,7 +504,7 @@ export default function FormImage() {
if (scheduleId && scheduleType === "3") { if (scheduleId && scheduleType === "3") {
const findCategory = resCategory.find((o) => const findCategory = resCategory.find((o) =>
o.name.toLowerCase().includes("pers rilis") o.name.toLowerCase().includes("pers rilis"),
); );
if (findCategory) { if (findCategory) {
@ -535,7 +535,7 @@ export default function FormImage() {
setPublishedFor( setPublishedFor(
options options
.filter((opt: any) => opt.id !== "all") .filter((opt: any) => opt.id !== "all")
.map((opt: any) => opt.id) .map((opt: any) => opt.id),
); );
} }
} else { } else {
@ -628,7 +628,7 @@ export default function FormImage() {
MySwal.fire( MySwal.fire(
"Error", "Error",
response.message || "Failed to create article", response.message || "Failed to create article",
"error" "error",
); );
return false; return false;
} }
@ -647,7 +647,7 @@ export default function FormImage() {
MySwal.fire( MySwal.fire(
"Error", "Error",
uploadResponse.message || "Failed to upload files", uploadResponse.message || "Failed to upload files",
"error" "error",
); );
return false; return false;
} }
@ -663,7 +663,7 @@ export default function FormImage() {
MySwal.fire( MySwal.fire(
"Error", "Error",
"Failed to upload files. Please try again.", "Failed to upload files. Please try again.",
"error" "error",
); );
return false; return false;
} }
@ -705,7 +705,7 @@ export default function FormImage() {
idx: number, idx: number,
id: string, id: string,
file: any, file: any,
duration: string duration: string,
) { ) {
console.log(idx, id, file, duration); console.log(idx, id, file, duration);
@ -741,7 +741,7 @@ export default function FormImage() {
onChunkComplete: ( onChunkComplete: (
chunkSize: any, chunkSize: any,
bytesAccepted: any, bytesAccepted: any,
bytesTotal: any bytesTotal: any,
) => { ) => {
const uploadPersen = Math.floor((bytesAccepted / bytesTotal) * 100); const uploadPersen = Math.floor((bytesAccepted / bytesTotal) * 100);
progressInfo[idx].percentage = uploadPersen; progressInfo[idx].percentage = uploadPersen;
@ -996,14 +996,43 @@ export default function FormImage() {
<div className="flex flex-row items-center gap-3 py-3 "> <div className="flex flex-row items-center gap-3 py-3 ">
<Label>Ai Assistance</Label> <Label>Ai Assistance</Label>
<div className="flex items-center gap-3"> <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} defaultChecked={isSwitchOn}
color="primary" color="primary"
id="c2" id="c2"
onCheckedChange={(checked: boolean) => onCheckedChange={(checked: boolean) =>
setIsSwitchOn(checked) setIsSwitchOn(checked)
} }
/> /> */}
</div> </div>
</div> </div>
{isSwitchOn && ( {isSwitchOn && (
@ -1262,14 +1291,13 @@ export default function FormImage() {
<p className="text-sm font-semibold">Content Rewrite</p> <p className="text-sm font-semibold">Content Rewrite</p>
<div className="my-2"> <div className="my-2">
<Button <button
size="sm"
type="button" type="button"
onClick={handleRewriteClick} 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 Content Rewrite
</Button> </button>
</div> </div>
{showRewriteEditor && ( {showRewriteEditor && (
@ -1499,19 +1527,19 @@ export default function FormImage() {
? isAllChecked ? isAllChecked
: field.value.includes(option.id); : field.value.includes(option.id);
const handleChange = () => { const handleChange = (checked: boolean) => {
let updated: string[] = []; let updated: string[] = [];
if (option.id === "all") { if (option.id === "all") {
updated = isAllChecked updated = checked
? [] ? options
: options
.filter((opt: any) => opt.id !== "all") .filter((opt: any) => opt.id !== "all")
.map((opt: any) => opt.id); .map((opt: any) => opt.id)
: [];
} else { } else {
updated = isChecked updated = checked
? field.value.filter((val) => val !== option.id) ? [...field.value, option.id]
: [...field.value, option.id]; : field.value.filter((val) => val !== option.id);
if (isAllChecked && option.id !== "all") { if (isAllChecked && option.id !== "all") {
updated = updated.filter((val) => val !== "all"); updated = updated.filter((val) => val !== "all");
@ -1522,17 +1550,48 @@ export default function FormImage() {
setPublishedFor(updated); 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 ( return (
<div <div
key={option.id} key={option.id}
className="flex gap-2 items-center" 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} id={option.id}
checked={isChecked} checked={isChecked}
onCheckedChange={handleChange} onCheckedChange={handleChange}
className="border" className="border"
/> /> */}
<Label htmlFor={option.id}>{option.label}</Label> <Label htmlFor={option.id}>{option.label}</Label>
</div> </div>
); );

View File

@ -13,6 +13,7 @@ import { Link } from "@/i18n/routing";
import { DynamicLogoTenant } from "./dynamic-logo-tenant"; import { DynamicLogoTenant } from "./dynamic-logo-tenant";
import { useTranslations } from "next-intl"; import { useTranslations } from "next-intl";
import LocalSwitcher from "../partials/header/locale-switcher"; import LocalSwitcher from "../partials/header/locale-switcher";
import ThemeSwitcher from "../partials/header/theme-switcher";
export default function Navbar() { export default function Navbar() {
const t = useTranslations("Navbar"); const t = useTranslations("Navbar");
@ -121,7 +122,7 @@ export default function Navbar() {
isDropdownOpen || isDropdownOpen ||
pathname.startsWith("/public/publication") pathname.startsWith("/public/publication")
? "text-black" ? "text-black"
: "" : "",
)} )}
> >
{item.label} {item.label}
@ -131,7 +132,7 @@ export default function Navbar() {
isDropdownOpen || isDropdownOpen ||
pathname.startsWith("/public/publication") pathname.startsWith("/public/publication")
? "opacity-100" ? "opacity-100"
: "opacity-0" : "opacity-0",
)} )}
/> />
</button> </button>
@ -156,7 +157,7 @@ export default function Navbar() {
onClick={handleClick} onClick={handleClick}
className={cn( className={cn(
"relative text-gray-500 hover:text-black transition-colors", "relative text-gray-500 hover:text-black transition-colors",
isActive && "text-black" isActive && "text-black",
)} )}
> >
{item.label} {item.label}
@ -170,6 +171,10 @@ export default function Navbar() {
})} })}
</nav> </nav>
{/* <div className="hidden custom-lg-button:flex text-left">
<ThemeSwitcher />
</div> */}
{/* 🔹 PROFILE / LOGIN SECTION */} {/* 🔹 PROFILE / LOGIN SECTION */}
<nav className="hidden md:flex items-center gap-3 z-10 relative"> <nav className="hidden md:flex items-center gap-3 z-10 relative">
{!isLoggedIn ? ( {!isLoggedIn ? (
@ -180,7 +185,9 @@ export default function Navbar() {
</Button> </Button>
</Link> </Link>
<Link href="/auth"> <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> </Link>
</> </>
) : ( ) : (

View File

@ -125,7 +125,7 @@ export default function DashboardContainer() {
return ( return (
<div className="space-y-8"> <div className="space-y-8">
{/* Stats Cards */} {/* 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 */} {/* User Profile Card */}
<motion.div <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" 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="flex justify-between items-start">
<div className="space-y-2"> <div className="space-y-2">
<p className="text-gray-600 font-medium">Welcome back,</p> <p className="text-gray-600 dark:text-black font-medium">Welcome back,</p>
<p className="text-xl font-semibold text-gray-900">{username}</p> <p className="text-xl font-semibold text-gray-900 dark:text-black ">{username}</p>
<p className="text-sm text-gray-500">Admin Dashboard</p> <p className="text-sm text-gray-500 dark:text-black ">Admin Dashboard</p>
</div> </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} /> <DashboardUserIcon size={60} />
</div> </div>
</div> </div>
@ -153,7 +153,7 @@ export default function DashboardContainer() {
transition={{ delay: 0.2 }} transition={{ delay: 0.2 }}
> >
<div className="flex flex-col items-center text-center space-y-3"> <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 /> <DashboardSpeecIcon />
</div> </div>
<div> <div>
@ -173,7 +173,7 @@ export default function DashboardContainer() {
transition={{ delay: 0.3 }} transition={{ delay: 0.3 }}
> >
<div className="flex flex-col items-center text-center space-y-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 /> <DashboardConnectIcon />
</div> </div>
<div> <div>
@ -193,7 +193,7 @@ export default function DashboardContainer() {
transition={{ delay: 0.4 }} transition={{ delay: 0.4 }}
> >
<div className="flex flex-col items-center text-center space-y-3"> <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 /> <DashboardShareIcon />
</div> </div>
<div> <div>
@ -213,7 +213,7 @@ export default function DashboardContainer() {
transition={{ delay: 0.5 }} transition={{ delay: 0.5 }}
> >
<div className="flex flex-col items-center text-center space-y-3"> <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} /> <DashboardCommentIcon size={40} />
</div> </div>
<div> <div>
@ -227,7 +227,7 @@ export default function DashboardContainer() {
</div> </div>
{/* Content Section */} {/* 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 */} {/* Analytics Chart */}
<motion.div <motion.div
className="bg-white rounded-2xl shadow-md border border-gray-200 p-4" className="bg-white rounded-2xl shadow-md border border-gray-200 p-4"
@ -306,12 +306,12 @@ export default function DashboardContainer() {
))} ))}
</div> </div>
<div className="mt-6 flex justify-center"> {/* <div className="mt-6 flex justify-center">
<CustomPagination <CustomPagination
totalPage={totalPage} totalPage={totalPage}
onPageChange={(data) => setPage(data)} onPageChange={(data) => setPage(data)}
/> />
</div> </div> */}
</motion.div> </motion.div>
</div> </div>
</div> </div>

View File

@ -1,6 +1,6 @@
import axios from "axios"; import axios from "axios";
const baseURL = "https://disestages.com/api"; const baseURL = "https://new.disestages.com/api";
const axiosNulisAIInstance = axios.create({ const axiosNulisAIInstance = axios.create({
baseURL, baseURL,