From 8edaedc9d5f80cdbbaa3bb4557cc70269aa2f2f0 Mon Sep 17 00:00:00 2001 From: Anang Yusman Date: Fri, 6 Dec 2024 00:02:06 +0700 Subject: [PATCH] feat: add form communication,form task, table communication,table contest --- .../collaboration/create/page.tsx | 16 + .../collabroation-table.tsx | 11 +- .../communication/internal/create/page.tsx | 15 + .../table-internal/internal-table.tsx | 79 ++++- .../contest/table-contest/contest-table.tsx | 72 ++++- .../task/table-task/task-table.tsx | 4 +- app/[locale]/auth/page.tsx | 42 ++- app/[locale]/page.tsx | 4 +- .../form/communication/collaboration-form.tsx | 296 ++++++++++++++++++ .../form/communication/internal-form.tsx | 291 +++++++++++++++++ components/form/task/task-form.tsx | 74 +++-- components/landing-page/Navbar.tsx | 236 +++++++++++--- components/landing-page/new-content.tsx | 282 ++++++++++++++--- lib/utils.ts | 40 +++ package-lock.json | 143 ++++++++- package.json | 3 +- public/assets/mediahub-logo.png | Bin 0 -> 339519 bytes public/assets/vector-login.svg | 103 ++++++ service/auth.ts | 94 ++++++ service/communication/communication.ts | 29 ++ service/contest/contest.ts | 15 + service/http-config/axiosCustom.ts | 17 + service/login-services.ts | 22 +- service/ppid-categories-services.ts | 4 - service/task.ts | 19 +- 25 files changed, 1723 insertions(+), 188 deletions(-) create mode 100644 app/[locale]/(protected)/communication/collaboration/create/page.tsx create mode 100644 app/[locale]/(protected)/communication/internal/create/page.tsx create mode 100644 components/form/communication/collaboration-form.tsx create mode 100644 components/form/communication/internal-form.tsx create mode 100644 public/assets/mediahub-logo.png create mode 100644 public/assets/vector-login.svg create mode 100644 service/auth.ts create mode 100644 service/communication/communication.ts create mode 100644 service/contest/contest.ts create mode 100644 service/http-config/axiosCustom.ts diff --git a/app/[locale]/(protected)/communication/collaboration/create/page.tsx b/app/[locale]/(protected)/communication/collaboration/create/page.tsx new file mode 100644 index 00000000..9c51de4c --- /dev/null +++ b/app/[locale]/(protected)/communication/collaboration/create/page.tsx @@ -0,0 +1,16 @@ +import SiteBreadcrumb from "@/components/site-breadcrumb"; +import FormInternal from "@/components/form/communication/internal-form"; +import FormCollaboration from "@/components/form/communication/collaboration-form"; + +const CollaborationCreatePage = async () => { + return ( +
+ +
+ +
+
+ ); +}; + +export default CollaborationCreatePage; diff --git a/app/[locale]/(protected)/communication/collaboration/table-collaboration/collabroation-table.tsx b/app/[locale]/(protected)/communication/collaboration/table-collaboration/collabroation-table.tsx index b4ad7a59..cd87c78b 100644 --- a/app/[locale]/(protected)/communication/collaboration/table-collaboration/collabroation-table.tsx +++ b/app/[locale]/(protected)/communication/collaboration/table-collaboration/collabroation-table.tsx @@ -56,6 +56,7 @@ export type CompanyData = { import { data } from "./data"; import { Input } from "@/components/ui/input"; import { InputGroup, InputGroupText } from "@/components/ui/input-group"; +import { Link } from "@/components/navigation"; export const columns: ColumnDef[] = [ { @@ -181,10 +182,12 @@ const CollaborationTable = () => {
- + + +
diff --git a/app/[locale]/(protected)/communication/internal/create/page.tsx b/app/[locale]/(protected)/communication/internal/create/page.tsx new file mode 100644 index 00000000..ddb27415 --- /dev/null +++ b/app/[locale]/(protected)/communication/internal/create/page.tsx @@ -0,0 +1,15 @@ +import SiteBreadcrumb from "@/components/site-breadcrumb"; +import FormInternal from "@/components/form/communication/internal-form"; + +const InternalCreatePage = async () => { + return ( +
+ +
+ +
+
+ ); +}; + +export default InternalCreatePage; diff --git a/app/[locale]/(protected)/communication/internal/table-internal/internal-table.tsx b/app/[locale]/(protected)/communication/internal/table-internal/internal-table.tsx index cee3ad8e..db7d14e3 100644 --- a/app/[locale]/(protected)/communication/internal/table-internal/internal-table.tsx +++ b/app/[locale]/(protected)/communication/internal/table-internal/internal-table.tsx @@ -47,16 +47,31 @@ import { } from "@/components/ui/dropdown-menu"; export type CompanyData = { + no: number; title: string; - createBy: string; - sendTo: string; - date: string; + commentFromUserName: string; + commentToUserName: string; + createdAt: string; }; -import { data } from "./data"; import { Input } from "@/components/ui/input"; import { InputGroup, InputGroupText } from "@/components/ui/input-group"; +import { listTicketingInternal } from "@/service/communication/communication"; +import { Link } from "@/components/navigation"; export const columns: ColumnDef[] = [ + { + accessorKey: "no", + header: "No", + cell: ({ row }) => ( +
+
+

+ {row.getValue("no")} +

+
+
+ ), + }, { accessorKey: "title", header: "Pertanyaan", @@ -71,24 +86,28 @@ export const columns: ColumnDef[] = [ ), }, { - accessorKey: "createBy", + accessorKey: "commentFromUserName", header: "Pengirim ", cell: ({ row }) => ( - {row.getValue("createBy")} + + {row.getValue("commentFromUserName")} + ), }, { - accessorKey: "sendTo", + accessorKey: "commentToUserName", header: "Penerima", cell: ({ row }) => ( - {row.getValue("sendTo")} + + {row.getValue("commentToUserName")} + ), }, { - accessorKey: "date", + accessorKey: "createdAt", header: "Waktu ", cell: ({ row }) => ( - {row.getValue("date")} + {row.getValue("createdAt")} ), }, { @@ -129,6 +148,7 @@ export const columns: ColumnDef[] = [ ]; const InternalTable = () => { + const [internalTable, setInternalTable] = React.useState([]); const [sorting, setSorting] = React.useState([]); const [columnFilters, setColumnFilters] = React.useState( [] @@ -140,9 +160,12 @@ const InternalTable = () => { pageIndex: 0, pageSize: 6, }); + const [page, setPage] = React.useState(1); + const [totalPage, setTotalPage] = React.useState(1); + const [limit, setLimit] = React.useState(10); const table = useReactTable({ - data, + data: internalTable, columns, onSortingChange: setSorting, onColumnFiltersChange: setColumnFilters, @@ -162,15 +185,41 @@ const InternalTable = () => { }, }); + React.useEffect(() => { + initState(); + }, [page, limit]); + + async function initState() { + try { + const res = await listTicketingInternal(page); + + const data = res.data.content.map((item: any, index: number) => ({ + no: (page - 1) * limit + index + 1, + title: item.title, + commentFromUserName: item.commentFromUserName, + commentToUserName: item.commentToUserName, + createdAt: item.createdAt, + })); + + setInternalTable(data); + setTotalPage(res.data.totalPages); + console.log(res?.data?.data); + } catch (error) { + console.error("Error fetching tasks:", error); + } + } + return (
- + + +
diff --git a/app/[locale]/(protected)/contest/table-contest/contest-table.tsx b/app/[locale]/(protected)/contest/table-contest/contest-table.tsx index 20ef7936..69d672fc 100644 --- a/app/[locale]/(protected)/contest/table-contest/contest-table.tsx +++ b/app/[locale]/(protected)/contest/table-contest/contest-table.tsx @@ -46,20 +46,36 @@ import { } from "@/components/ui/dropdown-menu"; export type CompanyData = { - code: string; - title: string; + no: number; + hastagCode: string; + theme: string; duration: string; targetOutput: string; - targetParticipant: string; - status: string; + targetParticipantTopLevel: string; + isPublishForAll: string; }; import { data } from "./data"; import { Input } from "@/components/ui/input"; import { InputGroup, InputGroupText } from "@/components/ui/input-group"; +import { listTask } from "@/service/task"; +import { listContest } from "@/service/contest/contest"; export const columns: ColumnDef[] = [ { - accessorKey: "code", + accessorKey: "no", + header: "No", + cell: ({ row }) => ( +
+
+

+ {row.getValue("no")} +

+
+
+ ), + }, + { + accessorKey: "hastagCode", header: "Kode", cell: ({ row }) => (
@@ -68,20 +84,20 @@ export const columns: ColumnDef[] = [ className="text-sm font-bold text-default-600 whitespace-nowrap mb-1" > - {row.getValue("code")} + {row.getValue("hastagCode")}
), }, { - accessorKey: "title", + accessorKey: "theme", header: "Judul", cell: ({ row }) => (

- {row.getValue("title")} + {row.getValue("theme")}

@@ -96,27 +112,27 @@ export const columns: ColumnDef[] = [ }, { accessorKey: "targetOutput", - header: "Tanggal Unggah ", + header: "Target Output ", cell: ({ row }) => ( {row.getValue("targetOutput")} ), }, { - accessorKey: "targetParticipant", + accessorKey: "targetParticipantTopLevel", header: "Tag ", cell: ({ row }) => ( - {row.getValue("targetParticipant")} + {row.getValue("targetParticipantTopLevel")} ), }, { - accessorKey: "status", + accessorKey: "isPublishForAll", header: "Status", cell: ({ row }) => { return ( - {row.getValue("status")} + {row.getValue("isPublishForAll")} ); }, @@ -159,6 +175,7 @@ export const columns: ColumnDef[] = [ ]; const ContestTable = () => { + const [contestTable, setContestTable] = React.useState([]); const [sorting, setSorting] = React.useState([]); const [columnFilters, setColumnFilters] = React.useState( [] @@ -170,9 +187,12 @@ const ContestTable = () => { pageIndex: 0, pageSize: 6, }); + const [page, setPage] = React.useState(1); + const [totalPage, setTotalPage] = React.useState(1); + const [limit, setLimit] = React.useState(10); const table = useReactTable({ - data, + data: contestTable, columns, onSortingChange: setSorting, onColumnFiltersChange: setColumnFilters, @@ -192,6 +212,30 @@ const ContestTable = () => { }, }); + React.useEffect(() => { + initState(); + }, [page, limit]); + + async function initState() { + try { + const res = await listContest(limit, page); + const data = res.data.data.content.map((item: any, index: number) => ({ + no: (page - 1) * limit + index + 1, + hastagCode: item.hastagCode, + theme: item.theme, + targetOutput: item.targetOutput, + targetParticipantTopLevel: item.targetParticipantTopLevel, + duration: item.duration, + isDone: item.isDone, + })); + + setContestTable(data); + setTotalPage(res.data.totalPages); + } catch (error) { + console.error("Error fetching tasks:", error); + } + } + return (
diff --git a/app/[locale]/(protected)/task/table-task/task-table.tsx b/app/[locale]/(protected)/task/table-task/task-table.tsx index 80646b0d..030651cc 100644 --- a/app/[locale]/(protected)/task/table-task/task-table.tsx +++ b/app/[locale]/(protected)/task/table-task/task-table.tsx @@ -47,10 +47,10 @@ import { import { Input } from "@/components/ui/input"; import { InputGroup, InputGroupText } from "@/components/ui/input-group"; import { Link } from "@/components/navigation"; -import { listTask } from "@/service/ppid-categories-services"; import { title } from "process"; import search from "../../app/chat/components/search"; import { format } from "date-fns"; +import { listTask } from "@/service/task"; export type CompanyData = { no: number; @@ -202,7 +202,7 @@ const TaskTable = () => { }); const [page, setPage] = React.useState(1); const [totalPage, setTotalPage] = React.useState(1); - const [limit, setLimit] = React.useState(10); + const [limit, setLimit] = React.useState(100); const [search, setSearch] = React.useState(title); const table = useReactTable({ diff --git a/app/[locale]/auth/page.tsx b/app/[locale]/auth/page.tsx index 091105ab..2d70506e 100644 --- a/app/[locale]/auth/page.tsx +++ b/app/[locale]/auth/page.tsx @@ -22,17 +22,25 @@ const Login = ({ params: { locale } }: { params: { locale: string } }) => { className="lg:block hidden flex-1 overflow-hidden text-[40px] leading-[48px] text-default-600 relative z-[1] bg-default-50" > -
+
- + -

- Unlock your Project - performance -

- +
@@ -43,20 +51,30 @@ const Login = ({ params: { locale } }: { params: { locale: string } }) => {
-
-

Sign in

-
Sign in to your account to start using Dashcode
+
+

+ Silahkan Masuk Ke akun anda terlebih dahulu +

+
+ Belum punya akun?{" "} + registrasi +
-
Or continue with
+
+ Or continue with +
Don’t have an account?{" "} - + Sign up
diff --git a/app/[locale]/page.tsx b/app/[locale]/page.tsx index 8a025143..f9ea7d30 100644 --- a/app/[locale]/page.tsx +++ b/app/[locale]/page.tsx @@ -1,19 +1,17 @@ "use client"; - import SearchSection from "@/components/landing-page/SearchSection"; import NewContent from "@/components/landing-page/new-content"; import PopularContent from "@/components/landing-page/popular-content"; import ContentCategory from "@/components/landing-page/content-category"; import Coverage from "@/components/landing-page/coverage"; import Navbar from "@/components/landing-page/navbar"; -import Hero from "@/components/landing-page/hero"; +import Hero from "@/components/landing-page/Hero"; import Footer from "@/components/landing-page/footer"; const Home = ({ params: { locale } }: { params: { locale: string } }) => { return ( <> - diff --git a/components/form/communication/collaboration-form.tsx b/components/form/communication/collaboration-form.tsx new file mode 100644 index 00000000..768e9cca --- /dev/null +++ b/components/form/communication/collaboration-form.tsx @@ -0,0 +1,296 @@ +"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 { useRouter } from "next/navigation"; + +import { Checkbox } from "@/components/ui/checkbox"; +import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group"; +import JoditEditor from "jodit-react"; +import { type } from "os"; +import loading from "@/app/[locale]/(protected)/app/projects/loading"; +import { request } from "http"; +import { error } from "@/lib/utils"; +import { createTask } from "@/service/task"; +import { options } from "@fullcalendar/core/preact.js"; +import { setOptions } from "leaflet"; +import { + getCuratorUser, + getTicketingPriority, + saveTicketing, + saveTicketingInternal, +} from "@/service/communication/communication"; +import makeAnimated from "react-select/animated"; +import Select from "react-select"; +import { + SelectTrigger, + SelectValue, + SelectContent, + SelectItem, +} from "@radix-ui/react-select"; +import { SelectGroup } from "@/components/ui/select"; + +const taskSchema = z.object({ + title: z.string().min(1, { message: "Judul diperlukan" }), + naration: z.string().min(2, { + message: "Narasi Penugasan harus lebih dari 2 karakter.", + }), +}); + +interface Option { + id: string; + label: string; + value: string; + fullname: string; + userLevel: string; + userLevelId: string; +} + +export default function FormCollaboration() { + const MySwal = withReactContent(Swal); + const router = useRouter(); + const editor = useRef(null); + type TaskSchema = z.infer; + + // State for various form fields + const [taskOutput, setTaskOutput] = useState({ + all: false, + video: false, + audio: false, + image: false, + text: false, + }); + + const [assignmentType, setAssignmentType] = useState("mediahub"); + const [assignmentCategory, setAssignmentCategory] = useState("publication"); + const [mainType, setMainType] = useState(1); // untuk Tipe Penugasan + const [type, setType] = useState("1"); + const [options, setOptions] = useState([]); + const [ticketPriority, setTicketPriority] = useState([]); + const [selectedOption, setSelectedOption] = useState