[QUDO-57,QUDO-56] feat:Check update profil pengguna,Check form register dan ubah password
This commit is contained in:
parent
12994688a1
commit
1b924d1790
|
|
@ -207,7 +207,7 @@ const MediaOnlineTable = () => {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex justify-between ">
|
<div className="flex justify-between ">
|
||||||
<Link href="/admin/broadcast/campaign-list">
|
<Link href="/admin/media-tracking/media-online/create">
|
||||||
<Button color="primary" size="md" className="text-sm mr-3">
|
<Button color="primary" size="md" className="text-sm mr-3">
|
||||||
Tambah Media Online
|
Tambah Media Online
|
||||||
</Button>
|
</Button>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
import { Card, CardContent } from "@/components/ui/card";
|
||||||
|
import SiteBreadcrumb from "@/components/site-breadcrumb";
|
||||||
|
import FormTaskTa from "@/components/form/task-ta/task-ta-form";
|
||||||
|
import FormAskExpert from "@/components/form/shared/ask-expert-form";
|
||||||
|
import FormDoItYourself from "@/components/form/shared/do-it-yourself-form";
|
||||||
|
import FormMediaOnline from "@/components/form/media-tracking/media-tracking-form";
|
||||||
|
|
||||||
|
const MediaOnlineCreatePage = () => {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<SiteBreadcrumb />
|
||||||
|
<div className="space-y-4">
|
||||||
|
<FormMediaOnline />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default MediaOnlineCreatePage;
|
||||||
|
|
@ -43,16 +43,42 @@ const columns: ColumnDef<any>[] = [
|
||||||
header: "Tanggal",
|
header: "Tanggal",
|
||||||
cell: ({ row }) => <span>{row.getValue("categoryName")}</span>,
|
cell: ({ row }) => <span>{row.getValue("categoryName")}</span>,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
accessorKey: "title",
|
|
||||||
header: "Media Online",
|
|
||||||
cell: ({ row }) => <span>{row.getValue("title")}</span>,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
accessorKey: "link",
|
accessorKey: "link",
|
||||||
header: "Link Berita",
|
header: "Link Berita",
|
||||||
cell: ({ row }) => <span>{row.getValue("categoryName")}</span>,
|
cell: ({ row }) => <span>{row.getValue("categoryName")}</span>,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: "actions",
|
||||||
|
accessorKey: "action",
|
||||||
|
header: "Aksi",
|
||||||
|
enableHiding: false,
|
||||||
|
cell: ({ row }) => {
|
||||||
|
return (
|
||||||
|
<DropdownMenu>
|
||||||
|
<DropdownMenuTrigger asChild>
|
||||||
|
<Button
|
||||||
|
size="icon"
|
||||||
|
className="bg-transparent ring-offset-transparent hover:bg-transparent hover:ring-0 hover:ring-transparent"
|
||||||
|
>
|
||||||
|
<span className="sr-only">Open menu</span>
|
||||||
|
<MoreVertical className="h-4 w-4 text-default-800" />
|
||||||
|
</Button>
|
||||||
|
</DropdownMenuTrigger>
|
||||||
|
<DropdownMenuContent className="p-0" align="end">
|
||||||
|
<Link
|
||||||
|
href={`/admin/media-tracking/tb-news/detail/${row.original.id}`}
|
||||||
|
>
|
||||||
|
<DropdownMenuItem className="p-2 border-b text-default-700 group focus:bg-default focus:text-primary-foreground rounded-none">
|
||||||
|
<Eye className="w-4 h-4 me-1.5" />
|
||||||
|
View
|
||||||
|
</DropdownMenuItem>
|
||||||
|
</Link>
|
||||||
|
</DropdownMenuContent>
|
||||||
|
</DropdownMenu>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
export default columns;
|
export default columns;
|
||||||
|
|
|
||||||
|
|
@ -66,6 +66,15 @@ import { Checkbox } from "@/components/ui/checkbox";
|
||||||
import { close, loading } from "@/config/swal";
|
import { close, loading } from "@/config/swal";
|
||||||
import { Link } from "@/i18n/routing";
|
import { Link } from "@/i18n/routing";
|
||||||
import { Label } from "@/components/ui/label";
|
import { Label } from "@/components/ui/label";
|
||||||
|
import {
|
||||||
|
Dialog,
|
||||||
|
DialogContent,
|
||||||
|
DialogFooter,
|
||||||
|
DialogHeader,
|
||||||
|
DialogTitle,
|
||||||
|
DialogTrigger,
|
||||||
|
} from "@/components/ui/dialog";
|
||||||
|
import { link } from "fs";
|
||||||
|
|
||||||
const NewsTable = () => {
|
const NewsTable = () => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
@ -80,6 +89,7 @@ const NewsTable = () => {
|
||||||
[]
|
[]
|
||||||
);
|
);
|
||||||
const [showTable, setShowTable] = React.useState(false);
|
const [showTable, setShowTable] = React.useState(false);
|
||||||
|
const [link, setLink] = React.useState("");
|
||||||
const [columnVisibility, setColumnVisibility] =
|
const [columnVisibility, setColumnVisibility] =
|
||||||
React.useState<VisibilityState>({});
|
React.useState<VisibilityState>({});
|
||||||
const [rowSelection, setRowSelection] = React.useState({});
|
const [rowSelection, setRowSelection] = React.useState({});
|
||||||
|
|
@ -204,100 +214,99 @@ const NewsTable = () => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="w-full overflow-x-auto bg-white p-4 rounded-sm space-y-3 border">
|
<div className="w-full overflow-x-auto bg-white p-4 rounded-sm space-y-3 border">
|
||||||
<div className="flex justify-between mb-10 items-center">
|
<div className="flex justify-between items-center">
|
||||||
<p className="text-xl font-medium text-default-900">
|
<p className="text-xl font-medium text-default-900">
|
||||||
Tracking Berita hari ini!
|
Tracking Berita hari ini!
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<Dialog>
|
||||||
<Label>
|
<DialogTrigger asChild>
|
||||||
Masukan Link <span className="text-red-500">*</span>
|
<Button className="bg-blue-600" size="md">
|
||||||
</Label>
|
|
||||||
<Input></Input>
|
|
||||||
<p className="text-sm">Sisa kuota harian: 30 Artikel</p>
|
|
||||||
</div>
|
|
||||||
{!showTable && (
|
|
||||||
<div className="flex justify-end">
|
|
||||||
<Button
|
|
||||||
color="primary"
|
|
||||||
size="md"
|
|
||||||
className="text-sm mr-3"
|
|
||||||
variant="outline"
|
|
||||||
>
|
|
||||||
Batal
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
color="primary"
|
|
||||||
size="md"
|
|
||||||
className="text-sm mr-3"
|
|
||||||
onClick={() => setShowTable(true)}
|
|
||||||
>
|
|
||||||
Tracking Berita
|
Tracking Berita
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</DialogTrigger>
|
||||||
)}
|
<DialogContent className="sm:max-w-md">
|
||||||
{showTable && (
|
<DialogHeader>
|
||||||
<>
|
<DialogTitle>Form Tracking Berita</DialogTitle>
|
||||||
<Table className="overflow-hidden mt-4">
|
</DialogHeader>
|
||||||
<TableHeader>
|
|
||||||
{table.getHeaderGroups().map((headerGroup) => (
|
<div className="grid gap-4 py-4">
|
||||||
<TableRow key={headerGroup.id} className="bg-default-200">
|
<div className="space-y-2">
|
||||||
{headerGroup.headers.map((header) => (
|
<Label htmlFor="link" className="text-sm font-medium">
|
||||||
<TableHead key={header.id}>
|
Masukkan Link <span className="text-red-500">*</span>
|
||||||
{header.isPlaceholder
|
</Label>
|
||||||
? null
|
<Input
|
||||||
: flexRender(
|
id="link"
|
||||||
header.column.columnDef.header,
|
placeholder="Masukkan Link disini!"
|
||||||
header.getContext()
|
value={link}
|
||||||
)}
|
onChange={(e) => setLink(e.target.value)}
|
||||||
</TableHead>
|
/>
|
||||||
))}
|
<p className="text-sm text-muted-foreground mt-1">
|
||||||
</TableRow>
|
Sisa Kuota Harian: 5 Kata Kunci
|
||||||
))}
|
</p>
|
||||||
</TableHeader>
|
</div>
|
||||||
<TableBody>
|
|
||||||
{table.getRowModel().rows?.length ? (
|
|
||||||
table.getRowModel().rows.map((row) => (
|
|
||||||
<TableRow key={row.id} className="h-[75px]">
|
|
||||||
{row.getVisibleCells().map((cell) => (
|
|
||||||
<TableCell key={cell.id}>
|
|
||||||
{flexRender(
|
|
||||||
cell.column.columnDef.cell,
|
|
||||||
cell.getContext()
|
|
||||||
)}
|
|
||||||
</TableCell>
|
|
||||||
))}
|
|
||||||
</TableRow>
|
|
||||||
))
|
|
||||||
) : (
|
|
||||||
<TableRow>
|
|
||||||
<TableCell
|
|
||||||
colSpan={columns.length}
|
|
||||||
className="h-24 text-center"
|
|
||||||
>
|
|
||||||
No results.
|
|
||||||
</TableCell>
|
|
||||||
</TableRow>
|
|
||||||
)}
|
|
||||||
</TableBody>
|
|
||||||
</Table>
|
|
||||||
<TablePagination
|
|
||||||
table={table}
|
|
||||||
totalData={totalData}
|
|
||||||
totalPage={totalPage}
|
|
||||||
/>
|
|
||||||
<div className="flex justify-end mt-4">
|
|
||||||
<Button
|
|
||||||
color="primary"
|
|
||||||
size="md"
|
|
||||||
className="text-sm mr-3"
|
|
||||||
onClick={() => setShowTable(false)}
|
|
||||||
>
|
|
||||||
Tracking Berita Baru
|
|
||||||
</Button>
|
|
||||||
</div>
|
</div>
|
||||||
</>
|
|
||||||
)}
|
<DialogFooter className="flex justify-end gap-2">
|
||||||
|
<Button variant="outline">Batal</Button>
|
||||||
|
<Button className="bg-blue-600 text-white">Tracking Berita</Button>
|
||||||
|
</DialogFooter>
|
||||||
|
</DialogContent>
|
||||||
|
</Dialog>
|
||||||
|
<Table className="overflow-hidden mt-4">
|
||||||
|
<TableHeader>
|
||||||
|
{table.getHeaderGroups().map((headerGroup) => (
|
||||||
|
<TableRow key={headerGroup.id} className="bg-default-200">
|
||||||
|
{headerGroup.headers.map((header) => (
|
||||||
|
<TableHead key={header.id}>
|
||||||
|
{header.isPlaceholder
|
||||||
|
? null
|
||||||
|
: flexRender(
|
||||||
|
header.column.columnDef.header,
|
||||||
|
header.getContext()
|
||||||
|
)}
|
||||||
|
</TableHead>
|
||||||
|
))}
|
||||||
|
</TableRow>
|
||||||
|
))}
|
||||||
|
</TableHeader>
|
||||||
|
<TableBody>
|
||||||
|
{table.getRowModel().rows?.length ? (
|
||||||
|
table.getRowModel().rows.map((row) => (
|
||||||
|
<TableRow key={row.id} className="h-[75px]">
|
||||||
|
{row.getVisibleCells().map((cell) => (
|
||||||
|
<TableCell key={cell.id}>
|
||||||
|
{flexRender(cell.column.columnDef.cell, cell.getContext())}
|
||||||
|
</TableCell>
|
||||||
|
))}
|
||||||
|
</TableRow>
|
||||||
|
))
|
||||||
|
) : (
|
||||||
|
<TableRow>
|
||||||
|
<TableCell colSpan={columns.length} className="h-24 text-center">
|
||||||
|
No results.
|
||||||
|
</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
)}
|
||||||
|
</TableBody>
|
||||||
|
</Table>
|
||||||
|
<TablePagination
|
||||||
|
table={table}
|
||||||
|
totalData={totalData}
|
||||||
|
totalPage={totalPage}
|
||||||
|
/>
|
||||||
|
<div className="flex justify-end mt-4">
|
||||||
|
<Button
|
||||||
|
color="primary"
|
||||||
|
size="md"
|
||||||
|
className="text-sm mr-3"
|
||||||
|
onClick={() => setShowTable(false)}
|
||||||
|
>
|
||||||
|
Tracking Berita Baru
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
{/* </>
|
||||||
|
)} */}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
import SiteBreadcrumb from "@/components/site-breadcrumb";
|
||||||
|
import NewsTable from "../../component/table";
|
||||||
|
import NewsDetailTable from "../component/table";
|
||||||
|
|
||||||
|
export default function DetailNews() {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<SiteBreadcrumb />
|
||||||
|
<NewsDetailTable />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,53 @@
|
||||||
|
import * as React from "react";
|
||||||
|
import { ColumnDef } from "@tanstack/react-table";
|
||||||
|
|
||||||
|
import { Eye, MoreVertical, SquarePen, Trash2 } from "lucide-react";
|
||||||
|
import { cn } from "@/lib/utils";
|
||||||
|
import {
|
||||||
|
DropdownMenu,
|
||||||
|
DropdownMenuContent,
|
||||||
|
DropdownMenuTrigger,
|
||||||
|
DropdownMenuItem,
|
||||||
|
} from "@/components/ui/dropdown-menu";
|
||||||
|
import { Button } from "@/components/ui/button";
|
||||||
|
import { Badge } from "@/components/ui/badge";
|
||||||
|
import {
|
||||||
|
formatDateToIndonesian,
|
||||||
|
getOnlyDate,
|
||||||
|
htmlToString,
|
||||||
|
} from "@/utils/globals";
|
||||||
|
import { Link, useRouter } from "@/i18n/routing";
|
||||||
|
import {
|
||||||
|
Accordion,
|
||||||
|
AccordionContent,
|
||||||
|
AccordionItem,
|
||||||
|
AccordionTrigger,
|
||||||
|
} from "@/components/ui/accordion";
|
||||||
|
import {
|
||||||
|
Dialog,
|
||||||
|
DialogContent,
|
||||||
|
DialogHeader,
|
||||||
|
DialogTitle,
|
||||||
|
DialogTrigger,
|
||||||
|
} from "@/components/ui/dialog";
|
||||||
|
import { Collapsible, CollapsibleContent } from "@/components/ui/collapsible";
|
||||||
|
|
||||||
|
const columns: ColumnDef<any>[] = [
|
||||||
|
{
|
||||||
|
accessorKey: "no",
|
||||||
|
header: "No",
|
||||||
|
cell: ({ row }) => <span>{row.getValue("no")}</span>,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: "mediaOnline",
|
||||||
|
header: "Media Online",
|
||||||
|
cell: ({ row }) => <span>{row.getValue("categoryName")}</span>,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: "link",
|
||||||
|
header: "Link Berita",
|
||||||
|
cell: ({ row }) => <span>{row.getValue("categoryName")}</span>,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
export default columns;
|
||||||
|
|
@ -0,0 +1,263 @@
|
||||||
|
"use client";
|
||||||
|
|
||||||
|
import * as React from "react";
|
||||||
|
import {
|
||||||
|
ColumnDef,
|
||||||
|
ColumnFiltersState,
|
||||||
|
PaginationState,
|
||||||
|
SortingState,
|
||||||
|
VisibilityState,
|
||||||
|
flexRender,
|
||||||
|
getCoreRowModel,
|
||||||
|
getFilteredRowModel,
|
||||||
|
getPaginationRowModel,
|
||||||
|
getSortedRowModel,
|
||||||
|
useReactTable,
|
||||||
|
} from "@tanstack/react-table";
|
||||||
|
import { Button } from "@/components/ui/button";
|
||||||
|
|
||||||
|
import {
|
||||||
|
Table,
|
||||||
|
TableBody,
|
||||||
|
TableCell,
|
||||||
|
TableHead,
|
||||||
|
TableHeader,
|
||||||
|
TableRow,
|
||||||
|
} from "@/components/ui/table";
|
||||||
|
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
|
||||||
|
import {
|
||||||
|
ChevronLeft,
|
||||||
|
ChevronRight,
|
||||||
|
Eye,
|
||||||
|
MoreVertical,
|
||||||
|
Search,
|
||||||
|
SquarePen,
|
||||||
|
Trash2,
|
||||||
|
TrendingDown,
|
||||||
|
TrendingUp,
|
||||||
|
UserIcon,
|
||||||
|
} from "lucide-react";
|
||||||
|
import { cn } from "@/lib/utils";
|
||||||
|
import {
|
||||||
|
DropdownMenu,
|
||||||
|
DropdownMenuContent,
|
||||||
|
DropdownMenuItem,
|
||||||
|
DropdownMenuRadioGroup,
|
||||||
|
DropdownMenuRadioItem,
|
||||||
|
DropdownMenuTrigger,
|
||||||
|
} from "@/components/ui/dropdown-menu";
|
||||||
|
import { Input } from "@/components/ui/input";
|
||||||
|
import { InputGroup, InputGroupText } from "@/components/ui/input-group";
|
||||||
|
import { paginationBlog } from "@/service/blog/blog";
|
||||||
|
import { ticketingPagination } from "@/service/ticketing/ticketing";
|
||||||
|
import { Badge } from "@/components/ui/badge";
|
||||||
|
import { useRouter, useSearchParams } from "next/navigation";
|
||||||
|
import TablePagination from "@/components/table/table-pagination";
|
||||||
|
import columns from "./column";
|
||||||
|
import { getPlanningPagination } from "@/service/agenda-setting/agenda-setting";
|
||||||
|
import {
|
||||||
|
Popover,
|
||||||
|
PopoverContent,
|
||||||
|
PopoverTrigger,
|
||||||
|
} from "@/components/ui/popover";
|
||||||
|
import { listDataMedia } from "@/service/broadcast/broadcast";
|
||||||
|
import { listEnableCategory } from "@/service/content/content";
|
||||||
|
import { Checkbox } from "@/components/ui/checkbox";
|
||||||
|
import { close, loading } from "@/config/swal";
|
||||||
|
import { Link } from "@/i18n/routing";
|
||||||
|
import { Label } from "@/components/ui/label";
|
||||||
|
import {
|
||||||
|
Dialog,
|
||||||
|
DialogContent,
|
||||||
|
DialogFooter,
|
||||||
|
DialogHeader,
|
||||||
|
DialogTitle,
|
||||||
|
DialogTrigger,
|
||||||
|
} from "@/components/ui/dialog";
|
||||||
|
import { link } from "fs";
|
||||||
|
|
||||||
|
const NewsDetailTable = () => {
|
||||||
|
const router = useRouter();
|
||||||
|
const searchParams = useSearchParams();
|
||||||
|
const [search, setSearch] = React.useState("");
|
||||||
|
const [showData, setShowData] = React.useState("10");
|
||||||
|
const [categories, setCategories] = React.useState<any>();
|
||||||
|
const [dataTable, setDataTable] = React.useState<any[]>([]);
|
||||||
|
const [totalData, setTotalData] = React.useState<number>(1);
|
||||||
|
const [sorting, setSorting] = React.useState<SortingState>([]);
|
||||||
|
const [columnFilters, setColumnFilters] = React.useState<ColumnFiltersState>(
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
const [showTable, setShowTable] = React.useState(false);
|
||||||
|
const [link, setLink] = React.useState("");
|
||||||
|
const [columnVisibility, setColumnVisibility] =
|
||||||
|
React.useState<VisibilityState>({});
|
||||||
|
const [rowSelection, setRowSelection] = React.useState({});
|
||||||
|
const [pagination, setPagination] = React.useState<PaginationState>({
|
||||||
|
pageIndex: 0,
|
||||||
|
pageSize: Number(showData),
|
||||||
|
});
|
||||||
|
const [categoryFilter, setCategoryFilter] = React.useState<number[]>([]);
|
||||||
|
const [statusFilter, setStatusFilter] = React.useState<number[]>([]);
|
||||||
|
const [page, setPage] = React.useState(1);
|
||||||
|
const [totalPage, setTotalPage] = React.useState(1);
|
||||||
|
const table = useReactTable({
|
||||||
|
data: dataTable,
|
||||||
|
columns,
|
||||||
|
onSortingChange: setSorting,
|
||||||
|
onColumnFiltersChange: setColumnFilters,
|
||||||
|
getCoreRowModel: getCoreRowModel(),
|
||||||
|
getPaginationRowModel: getPaginationRowModel(),
|
||||||
|
getSortedRowModel: getSortedRowModel(),
|
||||||
|
getFilteredRowModel: getFilteredRowModel(),
|
||||||
|
onColumnVisibilityChange: setColumnVisibility,
|
||||||
|
onRowSelectionChange: setRowSelection,
|
||||||
|
onPaginationChange: setPagination,
|
||||||
|
state: {
|
||||||
|
sorting,
|
||||||
|
columnFilters,
|
||||||
|
columnVisibility,
|
||||||
|
rowSelection,
|
||||||
|
pagination,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
let typingTimer: any;
|
||||||
|
const doneTypingInterval = 1500;
|
||||||
|
|
||||||
|
// const handleKeyUp = () => {
|
||||||
|
// clearTimeout(typingTimer);
|
||||||
|
// typingTimer = setTimeout(doneTyping, doneTypingInterval);
|
||||||
|
// };
|
||||||
|
|
||||||
|
const handleKeyDown = () => {
|
||||||
|
clearTimeout(typingTimer);
|
||||||
|
};
|
||||||
|
|
||||||
|
// async function doneTyping() {
|
||||||
|
// fetchData();
|
||||||
|
// }
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
const pageFromUrl = searchParams?.get("page");
|
||||||
|
if (pageFromUrl) {
|
||||||
|
setPage(Number(pageFromUrl));
|
||||||
|
}
|
||||||
|
}, [searchParams]);
|
||||||
|
|
||||||
|
// React.useEffect(() => {
|
||||||
|
// fetchData();
|
||||||
|
// setPagination({
|
||||||
|
// pageIndex: 0,
|
||||||
|
// pageSize: Number(showData),
|
||||||
|
// });
|
||||||
|
// }, [page, showData]);
|
||||||
|
|
||||||
|
// async function fetchData() {
|
||||||
|
// try {
|
||||||
|
// loading();
|
||||||
|
// const res = await listDataMedia(
|
||||||
|
// page - 1,
|
||||||
|
// showData,
|
||||||
|
// search,
|
||||||
|
// categoryFilter?.sort().join(","),
|
||||||
|
// statusFilter?.sort().join(",")
|
||||||
|
// );
|
||||||
|
// const data = res?.data?.data;
|
||||||
|
// const contentData = data?.content;
|
||||||
|
// contentData.forEach((item: any, index: number) => {
|
||||||
|
// item.no = (page - 1) * Number(showData) + index + 1;
|
||||||
|
// });
|
||||||
|
|
||||||
|
// console.log("contentData : ", data);
|
||||||
|
|
||||||
|
// setDataTable(contentData);
|
||||||
|
// setTotalData(data?.totalElements);
|
||||||
|
// setTotalPage(data?.totalPages);
|
||||||
|
// close();
|
||||||
|
// } catch (error) {
|
||||||
|
// console.error("Error fetching tasks:", error);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
getCategories();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
async function getCategories() {
|
||||||
|
const category = await listEnableCategory("");
|
||||||
|
const resCategory = category?.data?.data?.content;
|
||||||
|
setCategories(resCategory);
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleChange = (type: string, id: number, checked: boolean) => {
|
||||||
|
if (type === "category") {
|
||||||
|
if (checked) {
|
||||||
|
const temp: number[] = [...categoryFilter];
|
||||||
|
temp.push(id);
|
||||||
|
setCategoryFilter(temp);
|
||||||
|
} else {
|
||||||
|
const temp = categoryFilter.filter((a) => a !== id);
|
||||||
|
setCategoryFilter(temp);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (checked) {
|
||||||
|
const temp: number[] = [...statusFilter];
|
||||||
|
temp.push(id);
|
||||||
|
setStatusFilter(temp);
|
||||||
|
} else {
|
||||||
|
const temp = statusFilter.filter((a) => a !== id);
|
||||||
|
setStatusFilter(temp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="w-full overflow-x-auto bg-white p-4 rounded-sm space-y-3 border">
|
||||||
|
<Table className="overflow-hidden mt-4">
|
||||||
|
<TableHeader>
|
||||||
|
{table.getHeaderGroups().map((headerGroup) => (
|
||||||
|
<TableRow key={headerGroup.id} className="bg-default-200">
|
||||||
|
{headerGroup.headers.map((header) => (
|
||||||
|
<TableHead key={header.id}>
|
||||||
|
{header.isPlaceholder
|
||||||
|
? null
|
||||||
|
: flexRender(
|
||||||
|
header.column.columnDef.header,
|
||||||
|
header.getContext()
|
||||||
|
)}
|
||||||
|
</TableHead>
|
||||||
|
))}
|
||||||
|
</TableRow>
|
||||||
|
))}
|
||||||
|
</TableHeader>
|
||||||
|
<TableBody>
|
||||||
|
{table.getRowModel().rows?.length ? (
|
||||||
|
table.getRowModel().rows.map((row) => (
|
||||||
|
<TableRow key={row.id} className="h-[75px]">
|
||||||
|
{row.getVisibleCells().map((cell) => (
|
||||||
|
<TableCell key={cell.id}>
|
||||||
|
{flexRender(cell.column.columnDef.cell, cell.getContext())}
|
||||||
|
</TableCell>
|
||||||
|
))}
|
||||||
|
</TableRow>
|
||||||
|
))
|
||||||
|
) : (
|
||||||
|
<TableRow>
|
||||||
|
<TableCell colSpan={columns.length} className="h-24 text-center">
|
||||||
|
No results.
|
||||||
|
</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
)}
|
||||||
|
</TableBody>
|
||||||
|
</Table>
|
||||||
|
<TablePagination
|
||||||
|
table={table}
|
||||||
|
totalData={totalData}
|
||||||
|
totalPage={totalPage}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default NewsDetailTable;
|
||||||
|
|
@ -10,13 +10,14 @@ import * as z from "zod";
|
||||||
import Swal from "sweetalert2";
|
import Swal from "sweetalert2";
|
||||||
import { getBlog, postBlog } from "@/service/blog/blog";
|
import { getBlog, postBlog } from "@/service/blog/blog";
|
||||||
import { id } from "date-fns/locale";
|
import { id } from "date-fns/locale";
|
||||||
import router from "next/router";
|
|
||||||
import { getInfoProfile, saveUser, setupPassword } from "@/service/auth";
|
import { getInfoProfile, saveUser, setupPassword } from "@/service/auth";
|
||||||
import withReactContent from "sweetalert2-react-content";
|
import withReactContent from "sweetalert2-react-content";
|
||||||
import { Textarea } from "@/components/ui/textarea";
|
import { Textarea } from "@/components/ui/textarea";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { Link } from "@/components/navigation";
|
import { Link } from "@/components/navigation";
|
||||||
import { useTranslations } from "next-intl";
|
import { useTranslations } from "next-intl";
|
||||||
|
import { useRouter } from "next/navigation";
|
||||||
|
import { close, error, loading } from "@/lib/swal";
|
||||||
|
|
||||||
const profileSchema = z.object({
|
const profileSchema = z.object({
|
||||||
password: z.string().min(1, { message: "Judul diperlukan" }),
|
password: z.string().min(1, { message: "Judul diperlukan" }),
|
||||||
|
|
@ -31,6 +32,7 @@ type Detail = {
|
||||||
};
|
};
|
||||||
|
|
||||||
const ChangePassword: React.FC = () => {
|
const ChangePassword: React.FC = () => {
|
||||||
|
const router = useRouter();
|
||||||
const MySwal = withReactContent(Swal);
|
const MySwal = withReactContent(Swal);
|
||||||
const [detail, setDetail] = useState<Detail>();
|
const [detail, setDetail] = useState<Detail>();
|
||||||
const [refresh, setRefresh] = useState(false);
|
const [refresh, setRefresh] = useState(false);
|
||||||
|
|
@ -59,26 +61,52 @@ const ChangePassword: React.FC = () => {
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const save = async (data: ProfileSchema) => {
|
const save = async (data: ProfileSchema) => {
|
||||||
const requestData = {
|
if (data.password != null && data.password == data.retypePassword) {
|
||||||
...data,
|
loading();
|
||||||
// userId: detail?.userKeycloakId,
|
const newData = {
|
||||||
password: data.password,
|
// userId: detail?.userKeycloakId,
|
||||||
retypePassword: detail?.retypePassword,
|
password: data.password,
|
||||||
};
|
retypePassword: detail?.retypePassword,
|
||||||
|
};
|
||||||
|
|
||||||
const response = await setupPassword(requestData);
|
const response = await setupPassword(newData);
|
||||||
console.log("Form Data Submitted:", requestData);
|
|
||||||
console.log("response", response);
|
|
||||||
|
|
||||||
MySwal.fire({
|
close();
|
||||||
title: "Sukses",
|
if (response?.error) {
|
||||||
text: "Data berhasil disimpan.",
|
error(response.message);
|
||||||
icon: "success",
|
return false;
|
||||||
confirmButtonColor: "#3085d6",
|
}
|
||||||
confirmButtonText: "OK",
|
|
||||||
}).then(() => {
|
MySwal.fire({
|
||||||
router.push("/en/auth");
|
title: "Sukses",
|
||||||
});
|
text: "Data berhasil disimpan.",
|
||||||
|
icon: "success",
|
||||||
|
confirmButtonColor: "#3085d6",
|
||||||
|
confirmButtonText: "OK",
|
||||||
|
}).then(() => {
|
||||||
|
router.push("/in/auth");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// const requestData = {
|
||||||
|
// ...data,
|
||||||
|
// // userId: detail?.userKeycloakId,
|
||||||
|
// password: data.password,
|
||||||
|
// retypePassword: detail?.retypePassword,
|
||||||
|
// };
|
||||||
|
|
||||||
|
// const response = await setupPassword(requestData);
|
||||||
|
// console.log("Form Data Submitted:", requestData);
|
||||||
|
// console.log("response", response);
|
||||||
|
|
||||||
|
// MySwal.fire({
|
||||||
|
// title: "Sukses",
|
||||||
|
// text: "Data berhasil disimpan.",
|
||||||
|
// icon: "success",
|
||||||
|
// confirmButtonColor: "#3085d6",
|
||||||
|
// confirmButtonText: "OK",
|
||||||
|
// }).then(() => {
|
||||||
|
// router.push("/in/auth");
|
||||||
|
// });
|
||||||
};
|
};
|
||||||
|
|
||||||
const onSubmit = (data: ProfileSchema) => {
|
const onSubmit = (data: ProfileSchema) => {
|
||||||
|
|
@ -107,13 +135,19 @@ const ChangePassword: React.FC = () => {
|
||||||
|
|
||||||
<div className="flex justify-center gap-4 mb-8">
|
<div className="flex justify-center gap-4 mb-8">
|
||||||
<Link href={"/profile"}>
|
<Link href={"/profile"}>
|
||||||
<button className="border border-red-700 text-red-700 px-4 py-2 rounded">{t("userProfile")}</button>
|
<button className="border border-red-700 text-red-700 px-4 py-2 rounded">
|
||||||
|
{t("userProfile")}
|
||||||
|
</button>
|
||||||
</Link>
|
</Link>
|
||||||
<Link href={"/profile/change-profile"}>
|
<Link href={"/profile/change-profile"}>
|
||||||
<button className="border border-red-700 text-red-700 px-4 py-2 rounded">{t("changePhoto")}</button>
|
<button className="border border-red-700 text-red-700 px-4 py-2 rounded">
|
||||||
|
{t("changePhoto")}
|
||||||
|
</button>
|
||||||
</Link>
|
</Link>
|
||||||
<Link href={"/profile/change-password"}>
|
<Link href={"/profile/change-password"}>
|
||||||
<button className="bg-red-700 text-white px-4 py-2 rounded">{t("changePass")}</button>
|
<button className="bg-red-700 text-white px-4 py-2 rounded">
|
||||||
|
{t("changePass")}
|
||||||
|
</button>
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -126,20 +160,55 @@ const ChangePassword: React.FC = () => {
|
||||||
{t("password")}
|
{t("password")}
|
||||||
<span className="text-red-500">*</span>
|
<span className="text-red-500">*</span>
|
||||||
</Label>
|
</Label>
|
||||||
<Controller control={control} name="password" render={({ field }) => <Input size="md" type="password" defaultValue={field.value} onChange={field.onChange} placeholder={t("inputPass")} />} />
|
<Controller
|
||||||
{errors.password?.message && <p className="text-red-400 text-sm">{errors.password.message}</p>}
|
control={control}
|
||||||
|
name="password"
|
||||||
|
render={({ field }) => (
|
||||||
|
<Input
|
||||||
|
size="md"
|
||||||
|
type="password"
|
||||||
|
defaultValue={field.value}
|
||||||
|
onChange={field.onChange}
|
||||||
|
placeholder={t("inputPass")}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
{errors.password?.message && (
|
||||||
|
<p className="text-red-400 text-sm">
|
||||||
|
{errors.password.message}
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className="mb-4">
|
<div className="mb-4">
|
||||||
<Label>
|
<Label>
|
||||||
{t("confirmPass")}
|
{t("confirmPass")}
|
||||||
<span className="text-red-500">*</span>
|
<span className="text-red-500">*</span>
|
||||||
</Label>
|
</Label>
|
||||||
<Controller control={control} name="retypePassword" render={({ field }) => <Input size="md" type="password" defaultValue={field.value} onChange={field.onChange} placeholder={t("samePass")} />} />
|
<Controller
|
||||||
{errors.retypePassword?.message && <p className="text-red-400 text-sm">{errors.retypePassword.message}</p>}
|
control={control}
|
||||||
|
name="retypePassword"
|
||||||
|
render={({ field }) => (
|
||||||
|
<Input
|
||||||
|
size="md"
|
||||||
|
type="password"
|
||||||
|
defaultValue={field.value}
|
||||||
|
onChange={field.onChange}
|
||||||
|
placeholder={t("samePass")}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
{errors.retypePassword?.message && (
|
||||||
|
<p className="text-red-400 text-sm">
|
||||||
|
{errors.retypePassword.message}
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className="text-right">
|
<div className="text-right">
|
||||||
<div className="mt-4">
|
<div className="mt-4">
|
||||||
<button type="submit" className="bg-red-700 text-white px-6 py-2 rounded hover:bg-red-800 focus:outline-none focus:ring focus:ring-red-300">
|
<button
|
||||||
|
type="submit"
|
||||||
|
className="bg-red-700 text-white px-6 py-2 rounded hover:bg-red-800 focus:outline-none focus:ring focus:ring-red-300"
|
||||||
|
>
|
||||||
{t("save")}
|
{t("save")}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,256 @@
|
||||||
|
"use client";
|
||||||
|
import React, { useEffect, useRef, useState } from "react";
|
||||||
|
import { useForm, Controller } from "react-hook-form";
|
||||||
|
import { Input } from "@/components/ui/input";
|
||||||
|
import { Button } from "@/components/ui/button";
|
||||||
|
import { Label } from "@/components/ui/label";
|
||||||
|
import { Card } from "@/components/ui/card";
|
||||||
|
import { zodResolver } from "@hookform/resolvers/zod";
|
||||||
|
import * as z from "zod";
|
||||||
|
import Swal from "sweetalert2";
|
||||||
|
import withReactContent from "sweetalert2-react-content";
|
||||||
|
import { useParams, useRouter } from "next/navigation";
|
||||||
|
import {
|
||||||
|
Select,
|
||||||
|
SelectContent,
|
||||||
|
SelectItem,
|
||||||
|
SelectTrigger,
|
||||||
|
SelectValue,
|
||||||
|
} from "@/components/ui/select";
|
||||||
|
import { Checkbox } from "@/components/ui/checkbox";
|
||||||
|
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group";
|
||||||
|
import JoditEditor from "jodit-react";
|
||||||
|
import {
|
||||||
|
createTask,
|
||||||
|
createTaskTa,
|
||||||
|
getTask,
|
||||||
|
getUserLevelForAssignments,
|
||||||
|
getUserLevelForExpert,
|
||||||
|
} from "@/service/task";
|
||||||
|
import {
|
||||||
|
Dialog,
|
||||||
|
DialogContent,
|
||||||
|
DialogHeader,
|
||||||
|
DialogTitle,
|
||||||
|
DialogTrigger,
|
||||||
|
} from "@/components/ui/dialog";
|
||||||
|
import { CalendarIcon, ChevronDown, ChevronUp, Trash2 } from "lucide-react";
|
||||||
|
import { AudioRecorder } from "react-audio-voice-recorder";
|
||||||
|
import FileUploader from "@/components/form/shared/file-uploader";
|
||||||
|
import { Upload } from "tus-js-client";
|
||||||
|
import { error } from "@/config/swal";
|
||||||
|
import { getCsrfToken } from "@/service/auth";
|
||||||
|
import { loading } from "@/lib/swal";
|
||||||
|
import { useTranslations } from "next-intl";
|
||||||
|
import dynamic from "next/dynamic";
|
||||||
|
import { cn } from "@/lib/utils";
|
||||||
|
import {
|
||||||
|
Popover,
|
||||||
|
PopoverContent,
|
||||||
|
PopoverTrigger,
|
||||||
|
} from "@/components/ui/popover";
|
||||||
|
import { Calendar } from "@/components/ui/calendar";
|
||||||
|
import { addDays, format, setDate } from "date-fns";
|
||||||
|
import { DateRange } from "react-day-picker";
|
||||||
|
import TimePicker from "react-time-picker";
|
||||||
|
import "react-time-picker/dist/TimePicker.css";
|
||||||
|
import "react-clock/dist/Clock.css";
|
||||||
|
import {
|
||||||
|
AdministrationLevelList,
|
||||||
|
getListCompetencies,
|
||||||
|
getListExperiences,
|
||||||
|
} from "@/service/management-user/management-user";
|
||||||
|
import { Link } from "@/i18n/routing";
|
||||||
|
|
||||||
|
const taskSchema = z.object({
|
||||||
|
title: z.string().min(1, { message: "Judul diperlukan" }),
|
||||||
|
url: z.string().min(2, {
|
||||||
|
message: "Narasi Penugasan harus lebih dari 2 karakter.",
|
||||||
|
}),
|
||||||
|
assign: z.string().min(1, { message: "Judul diperlukan" }),
|
||||||
|
});
|
||||||
|
|
||||||
|
interface FileWithPreview extends File {
|
||||||
|
preview: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type taskDetail = {
|
||||||
|
id: number;
|
||||||
|
title: string;
|
||||||
|
fileTypeOutput: string;
|
||||||
|
assignedToTopLevel: string;
|
||||||
|
url: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
const CustomEditor = dynamic(
|
||||||
|
() => {
|
||||||
|
return import("@/components/editor/custom-editor");
|
||||||
|
},
|
||||||
|
{ ssr: false }
|
||||||
|
);
|
||||||
|
|
||||||
|
export default function FormMediaOnline() {
|
||||||
|
const MySwal = withReactContent(Swal);
|
||||||
|
const router = useRouter();
|
||||||
|
const editor = useRef(null);
|
||||||
|
type TaskSchema = z.infer<typeof taskSchema>;
|
||||||
|
const { id } = useParams() as { id: string };
|
||||||
|
console.log(id);
|
||||||
|
const [taskType, setTaskType] = useState<string>("atensi-khusus");
|
||||||
|
const [broadcastType, setBroadcastType] = useState<string>("");
|
||||||
|
const [type, setType] = useState<string>("1");
|
||||||
|
const [selectedTarget, setSelectedTarget] = useState("3,4");
|
||||||
|
const [detail, setDetail] = useState<taskDetail>();
|
||||||
|
const [listExpert, setListExpert] = useState<any[]>([]);
|
||||||
|
const [checkedLevels, setCheckedLevels] = useState<Set<number>>(new Set());
|
||||||
|
const [expandedPolda, setExpandedPolda] = useState([{}]);
|
||||||
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
|
const [audioFile, setAudioFile] = useState<File | null>(null);
|
||||||
|
const [isRecording, setIsRecording] = useState(false);
|
||||||
|
const [timer, setTimer] = useState<number>(120);
|
||||||
|
|
||||||
|
const t = useTranslations("Form");
|
||||||
|
|
||||||
|
const {
|
||||||
|
register,
|
||||||
|
control,
|
||||||
|
setValue,
|
||||||
|
handleSubmit,
|
||||||
|
formState: { errors },
|
||||||
|
} = useForm<TaskSchema>({
|
||||||
|
resolver: zodResolver(taskSchema),
|
||||||
|
mode: "all",
|
||||||
|
});
|
||||||
|
|
||||||
|
// };
|
||||||
|
|
||||||
|
const save = async (data: TaskSchema) => {
|
||||||
|
const requestData: {
|
||||||
|
id?: number;
|
||||||
|
title: string;
|
||||||
|
assignedToUsers: any;
|
||||||
|
url: any;
|
||||||
|
} = {
|
||||||
|
...data,
|
||||||
|
assignedToUsers: data.assign,
|
||||||
|
url: data.url,
|
||||||
|
title: data.title,
|
||||||
|
};
|
||||||
|
|
||||||
|
const response = await createTaskTa(requestData);
|
||||||
|
|
||||||
|
console.log("Form Data Submitted:", requestData);
|
||||||
|
console.log("response", response);
|
||||||
|
|
||||||
|
const id = response?.data?.data.id;
|
||||||
|
};
|
||||||
|
|
||||||
|
const onSubmit = (data: TaskSchema) => {
|
||||||
|
MySwal.fire({
|
||||||
|
title: "Simpan Data",
|
||||||
|
text: "Apakah Anda yakin ingin menyimpan data ini?",
|
||||||
|
icon: "warning",
|
||||||
|
showCancelButton: true,
|
||||||
|
cancelButtonColor: "#d33",
|
||||||
|
confirmButtonColor: "#3085d6",
|
||||||
|
confirmButtonText: "Simpan",
|
||||||
|
}).then((result) => {
|
||||||
|
if (result.isConfirmed) {
|
||||||
|
save(data);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const successSubmit = (redirect: string) => {
|
||||||
|
MySwal.fire({
|
||||||
|
title: "Sukses",
|
||||||
|
text: "Data berhasil disimpan.",
|
||||||
|
icon: "success",
|
||||||
|
confirmButtonColor: "#3085d6",
|
||||||
|
confirmButtonText: "OK",
|
||||||
|
}).then(() => {
|
||||||
|
router.push(redirect);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Card>
|
||||||
|
<div className="px-6 py-6">
|
||||||
|
<p className="text-xl mb-3">{t("data-media")}</p>
|
||||||
|
<p className="text-lg font-semibold mb-3">{t("form-media")}</p>
|
||||||
|
|
||||||
|
<form onSubmit={handleSubmit(onSubmit)}>
|
||||||
|
<div className="gap-5 mb-5">
|
||||||
|
{/* Input Title */}
|
||||||
|
<div className="space-y-2">
|
||||||
|
<Label>{t("title-media-online")}</Label>
|
||||||
|
<Controller
|
||||||
|
control={control}
|
||||||
|
name="title"
|
||||||
|
render={({ field }) => (
|
||||||
|
<Input
|
||||||
|
size="md"
|
||||||
|
type="text"
|
||||||
|
value={detail?.title}
|
||||||
|
onChange={field.onChange}
|
||||||
|
placeholder="Enter Title"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
{errors.title?.message && (
|
||||||
|
<p className="text-red-400 text-sm">{errors.title.message}</p>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="mt-5 space-y-2">
|
||||||
|
<Label>{t("url")}</Label>
|
||||||
|
<Controller
|
||||||
|
control={control}
|
||||||
|
name="url"
|
||||||
|
render={({ field }) => (
|
||||||
|
<Input
|
||||||
|
size="md"
|
||||||
|
type="text"
|
||||||
|
value={detail?.url}
|
||||||
|
onChange={field.onChange}
|
||||||
|
placeholder="Enter Title"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
{errors.title?.message && (
|
||||||
|
<p className="text-red-400 text-sm">{errors.title.message}</p>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<div className="mt-5 space-y-2">
|
||||||
|
<Label>{t("coverage-area")}</Label>
|
||||||
|
<Select onValueChange={setSelectedTarget}>
|
||||||
|
<SelectTrigger size="md">
|
||||||
|
<SelectValue placeholder="Choose" />
|
||||||
|
</SelectTrigger>
|
||||||
|
<SelectContent>
|
||||||
|
<SelectItem value="3,4">Semua Pengguna</SelectItem>
|
||||||
|
<SelectItem value="4">Kontributor</SelectItem>
|
||||||
|
<SelectItem value="3">Approver</SelectItem>
|
||||||
|
</SelectContent>
|
||||||
|
</Select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="flex flex-row items-center justify-end gap-3">
|
||||||
|
<div className="mt-4 ">
|
||||||
|
<Link href={"/admin/media-tracking/media-online"}>
|
||||||
|
<Button color="primary" variant={"outline"}>
|
||||||
|
{t("cancel")}
|
||||||
|
</Button>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
<div className="mt-4">
|
||||||
|
<Button type="submit" color="primary">
|
||||||
|
{t("submit")}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</Card>
|
||||||
|
);
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,5 +1,5 @@
|
||||||
"use client";
|
"use client";
|
||||||
import React, { useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { Checkbox } from "@/components/ui/checkbox";
|
import { Checkbox } from "@/components/ui/checkbox";
|
||||||
import { Input } from "@/components/ui/input";
|
import { Input } from "@/components/ui/input";
|
||||||
|
|
@ -9,7 +9,7 @@ import { Icon } from "@/components/ui/icon";
|
||||||
import { useForm, SubmitHandler } from "react-hook-form";
|
import { useForm, SubmitHandler } from "react-hook-form";
|
||||||
import { zodResolver } from "@hookform/resolvers/zod";
|
import { zodResolver } from "@hookform/resolvers/zod";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { cn, setCookiesEncrypt } from "@/lib/utils";
|
import { cn, getCookiesDecrypt, setCookiesEncrypt } from "@/lib/utils";
|
||||||
import { Eye, EyeOff, Loader2 } from "lucide-react";
|
import { Eye, EyeOff, Loader2 } from "lucide-react";
|
||||||
import {
|
import {
|
||||||
getProfile,
|
getProfile,
|
||||||
|
|
@ -32,6 +32,13 @@ import {
|
||||||
} from "@/components/ui/input-otp";
|
} from "@/components/ui/input-otp";
|
||||||
import { error, loading } from "@/config/swal";
|
import { error, loading } from "@/config/swal";
|
||||||
import { data } from "jquery";
|
import { data } from "jquery";
|
||||||
|
import {
|
||||||
|
Dialog,
|
||||||
|
DialogContent,
|
||||||
|
DialogFooter,
|
||||||
|
DialogTrigger,
|
||||||
|
} from "@/components/ui/dialog";
|
||||||
|
import { getUserNotifications, listRole } from "@/service/landing/landing";
|
||||||
|
|
||||||
// Schema validasi menggunakan zod
|
// Schema validasi menggunakan zod
|
||||||
const schema = z.object({
|
const schema = z.object({
|
||||||
|
|
@ -58,11 +65,16 @@ const LoginForm = () => {
|
||||||
const [userIdentity] = useState();
|
const [userIdentity] = useState();
|
||||||
const [email, setEmail] = useState();
|
const [email, setEmail] = useState();
|
||||||
const [category, setCategory] = useState("5");
|
const [category, setCategory] = useState("5");
|
||||||
|
const roleId = getCookiesDecrypt("urie");
|
||||||
|
|
||||||
const [username, setUsername] = useState("");
|
const [username, setUsername] = useState("");
|
||||||
const [password, setPassword] = useState("");
|
const [password, setPassword] = useState("");
|
||||||
const [oldEmail, setOldEmail] = useState("");
|
const [oldEmail, setOldEmail] = useState("");
|
||||||
const [oldEmailValidate, setOldEmailValidate] = useState("");
|
const [oldEmailValidate, setOldEmailValidate] = useState("");
|
||||||
|
const [role, setRole] = useState<any>();
|
||||||
|
const [menuActive, setMenuActive] = useState<string>();
|
||||||
|
const [notifications, setNotifications] = useState([]);
|
||||||
|
const [notificationsUpdate, setNotificationsUpdate] = useState([]);
|
||||||
const [newEmail, setNewEmail] = useState("");
|
const [newEmail, setNewEmail] = useState("");
|
||||||
const [newEmailValidate, setNewEmailValidate] = useState("");
|
const [newEmailValidate, setNewEmailValidate] = useState("");
|
||||||
const [otpValidate, setOtpValidate] = useState("");
|
const [otpValidate, setOtpValidate] = useState("");
|
||||||
|
|
@ -341,6 +353,36 @@ const LoginForm = () => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let menu = "";
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
async function initState() {
|
||||||
|
setMenuActive(menu);
|
||||||
|
const res = await listRole();
|
||||||
|
setRole(res?.data?.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getNotif() {
|
||||||
|
if (roleId != undefined) {
|
||||||
|
const response = await getUserNotifications(0, 2);
|
||||||
|
setNotifications(response?.data?.data?.content);
|
||||||
|
console.log("respon:", response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getNotifUpdate() {
|
||||||
|
if (roleId != undefined) {
|
||||||
|
const response = await getUserNotifications(0, 3);
|
||||||
|
setNotificationsUpdate(response?.data?.data?.content);
|
||||||
|
console.log("Notiffff:", response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
initState();
|
||||||
|
getNotif();
|
||||||
|
getNotifUpdate();
|
||||||
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<form onSubmit={handleSubmit(onSubmit)} className="mt-5 2xl:mt-7 space-y-4">
|
<form onSubmit={handleSubmit(onSubmit)} className="mt-5 2xl:mt-7 space-y-4">
|
||||||
{step === 1 ? (
|
{step === 1 ? (
|
||||||
|
|
@ -350,7 +392,50 @@ const LoginForm = () => {
|
||||||
{t("logInPlease")}
|
{t("logInPlease")}
|
||||||
</h4>
|
</h4>
|
||||||
<div className="text-default-500 text-base">
|
<div className="text-default-500 text-base">
|
||||||
{t("acc")} <span className="text-red-500">{t("reg")}</span>
|
{t("acc")}
|
||||||
|
<Dialog>
|
||||||
|
<DialogTrigger asChild>
|
||||||
|
<span className="w-full lg:w-fit px-2 h-8 text-red-500 hover:cursor-pointer">
|
||||||
|
{t("register")}
|
||||||
|
</span>
|
||||||
|
</DialogTrigger>
|
||||||
|
<DialogContent size="sm" className="sm:max-w-[425px]">
|
||||||
|
<div className="flex flex-col w-full gap-1">
|
||||||
|
<p className="text-lg font-semibold text-center">
|
||||||
|
{t("categoryReg")}
|
||||||
|
</p>
|
||||||
|
<p className="text-base text-center">{t("selectOne")}</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
{role?.map((row: any) => (
|
||||||
|
<div key={row.id}>
|
||||||
|
<input
|
||||||
|
type="radio"
|
||||||
|
id={`category${row.id}`}
|
||||||
|
name="category"
|
||||||
|
className=""
|
||||||
|
value={row.id}
|
||||||
|
checked={category == `${row.id}`}
|
||||||
|
onChange={(event) => setCategory(event.target.value)}
|
||||||
|
/>
|
||||||
|
<label className="ml-2" htmlFor={`category${row.id}`}>
|
||||||
|
{row.name}
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
<div className="border-b-2 border-black"></div>
|
||||||
|
<DialogFooter>
|
||||||
|
<Link
|
||||||
|
href={`/auth/registration?category=${category}`}
|
||||||
|
className="flex justify-center bg-red-500 px-4 py-1 rounded-md border border-black text-white"
|
||||||
|
type="submit"
|
||||||
|
>
|
||||||
|
{t("next")}{" "}
|
||||||
|
</Link>
|
||||||
|
</DialogFooter>
|
||||||
|
</DialogContent>
|
||||||
|
</Dialog>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
|
|
|
||||||
|
|
@ -762,6 +762,11 @@
|
||||||
"sent": "Sent",
|
"sent": "Sent",
|
||||||
"accepted": "Accepted",
|
"accepted": "Accepted",
|
||||||
"assignment-status-details": "Assignment Status Details",
|
"assignment-status-details": "Assignment Status Details",
|
||||||
"unique-code": "Unique Code"
|
"unique-code": "Unique Code",
|
||||||
|
"form-media": "Form Add Media",
|
||||||
|
"data-media": "please complete the data! ",
|
||||||
|
"title-media-online": "Online Media Name",
|
||||||
|
"url": "Url",
|
||||||
|
"coverage-area": "Coverage Area"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -762,6 +762,11 @@
|
||||||
"sent": "Terkirim",
|
"sent": "Terkirim",
|
||||||
"accepted": "Diterima",
|
"accepted": "Diterima",
|
||||||
"assignment-status-details": "Detail Status Penugasan",
|
"assignment-status-details": "Detail Status Penugasan",
|
||||||
"unique-code": "Kode Unik"
|
"unique-code": "Kode Unik",
|
||||||
|
"form-media": "Form Tambah Media",
|
||||||
|
"data-media": "Silahkan Lengkapi Data!",
|
||||||
|
"title-media-online": "Nama Media Online",
|
||||||
|
"url": "Url",
|
||||||
|
"coverage-area": "Cakupan Wilayah"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue