Tambahan Admin Di Menu PPID
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
import ApiFetch from "@/lib/api-fetch";
|
||||
import { Prisma } from "@prisma/client";
|
||||
import { toast } from "react-toastify";
|
||||
import { proxy } from "valtio";
|
||||
import { z } from "zod";
|
||||
|
||||
const templateDaftarInformasi = z.object({
|
||||
jenisInformasi: z.string().min(3, "Jenis Informasi minimal 3 karakter"),
|
||||
deskripsi: z.string().min(3, "Deskripsi minimal 3 karakter"),
|
||||
tanggal: z.string().min(3, "Tanggal minimal 3 karakter"),
|
||||
})
|
||||
|
||||
type DaftarInformasi = Prisma.DaftarInformasiPublikGetPayload<{
|
||||
select: {
|
||||
jenisInformasi: true;
|
||||
deskripsi: true;
|
||||
tanggal: true;
|
||||
};
|
||||
}>;
|
||||
|
||||
const daftarInformasi = proxy({
|
||||
create: {
|
||||
form: {} as DaftarInformasi,
|
||||
loading: false,
|
||||
async create() {
|
||||
const cek = templateDaftarInformasi.safeParse(daftarInformasi.create.form);
|
||||
if (!cek.success) {
|
||||
const err = `[${cek.error.issues
|
||||
.map((v) => `${v.path.join(".")}`)
|
||||
.join("\n")}] required`;
|
||||
return toast.error(err);
|
||||
}
|
||||
try {
|
||||
daftarInformasi.create.loading = true;
|
||||
const res = await ApiFetch.api.ppid.daftarinformasipublik["create"].post(daftarInformasi.create.form);
|
||||
if (res.status === 200) {
|
||||
daftarInformasi.findMany.load();
|
||||
return toast.success("success create");
|
||||
}
|
||||
return toast.error("failed create");
|
||||
} catch (error) {
|
||||
console.log((error as Error).message);
|
||||
} finally {
|
||||
daftarInformasi.create.loading = false;
|
||||
}
|
||||
},
|
||||
},
|
||||
findMany: {
|
||||
data: null as
|
||||
| Prisma.DaftarInformasiPublikGetPayload<{ omit: { isActive: true } }>[]
|
||||
| null,
|
||||
async load() {
|
||||
const res = await ApiFetch.api.ppid.daftarinformasipublik["find-many"].get();
|
||||
if (res.status === 200) {
|
||||
daftarInformasi.findMany.data = res.data?.data ?? [];
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const stateDaftarInformasiPublik = proxy({
|
||||
daftarInformasi
|
||||
})
|
||||
|
||||
export default stateDaftarInformasiPublik;
|
||||
@@ -0,0 +1,77 @@
|
||||
import ApiFetch from "@/lib/api-fetch";
|
||||
import { Prisma } from "@prisma/client";
|
||||
import { toast } from "react-toastify";
|
||||
import { proxy } from "valtio";
|
||||
import { z } from "zod";
|
||||
|
||||
const templateGrafikJenisKelamin = z.object({
|
||||
laki: z.string().min(2, "Data laki-laki harus diisi"),
|
||||
perempuan: z.string().min(2, "Data perempuan harus diisi"),
|
||||
});
|
||||
|
||||
type GrafikJenisKelamin = Prisma.GrafikBerdasarkanJenisKelaminGetPayload<{
|
||||
select: {
|
||||
laki: true;
|
||||
perempuan: true;
|
||||
};
|
||||
}>;
|
||||
|
||||
const defaultForm: GrafikJenisKelamin = {
|
||||
laki: "",
|
||||
perempuan: "",
|
||||
};
|
||||
|
||||
const grafikBerdasarkanJenisKelamin = proxy({
|
||||
create: {
|
||||
form: defaultForm,
|
||||
loading: false,
|
||||
async create() {
|
||||
const cek = templateGrafikJenisKelamin.safeParse(
|
||||
grafikBerdasarkanJenisKelamin.create.form
|
||||
);
|
||||
if (!cek.success) {
|
||||
const err = `[${cek.error.issues
|
||||
.map((v) => `${v.path.join(".")}`)
|
||||
.join("\n")}] required`;
|
||||
return toast.error(err);
|
||||
}
|
||||
try {
|
||||
grafikBerdasarkanJenisKelamin.create.loading = true;
|
||||
const res = await ApiFetch.api.ppid.grafikberdasarkanjeniskelamin[
|
||||
"create"
|
||||
].post(grafikBerdasarkanJenisKelamin.create.form);
|
||||
if (res.status === 200) {
|
||||
grafikBerdasarkanJenisKelamin.create.form = defaultForm;
|
||||
grafikBerdasarkanJenisKelamin.findMany.load();
|
||||
return toast.success("success create");
|
||||
}
|
||||
return toast.error("failed create");
|
||||
} catch (error) {
|
||||
console.log((error as Error).message);
|
||||
} finally {
|
||||
grafikBerdasarkanJenisKelamin.create.loading = false;
|
||||
}
|
||||
},
|
||||
},
|
||||
findMany: {
|
||||
data: null as
|
||||
| Prisma.GrafikBerdasarkanJenisKelaminGetPayload<{
|
||||
omit: { isActive: true };
|
||||
}>[]
|
||||
| null,
|
||||
loading: false,
|
||||
async load() {
|
||||
const res = await ApiFetch.api.ppid.grafikberdasarkanjeniskelamin[
|
||||
"find-many"
|
||||
].get();
|
||||
if (res.status === 200) {
|
||||
grafikBerdasarkanJenisKelamin.findMany.data = res.data?.data ?? [];
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const stateGrafikBerdasarkanJenisKelamin = proxy({
|
||||
grafikBerdasarkanJenisKelamin,
|
||||
});
|
||||
export default stateGrafikBerdasarkanJenisKelamin;
|
||||
@@ -0,0 +1,84 @@
|
||||
import ApiFetch from "@/lib/api-fetch";
|
||||
import { Prisma } from "@prisma/client";
|
||||
import { toast } from "react-toastify";
|
||||
import { proxy } from "valtio";
|
||||
import { z } from "zod";
|
||||
|
||||
const templateGrafikResponden = z.object({
|
||||
sangatbaik: z.string().min(1, "Data sangat baik harus diisi"),
|
||||
baik: z.string().min(1, "Data baik harus diisi"),
|
||||
kurangbaik: z.string().min(1, "Data kurang baik harus diisi"),
|
||||
tidakbaik: z.string().min(1, "Data tidak baik harus diisi"),
|
||||
});
|
||||
|
||||
type GrafikResponden = Prisma.GrafikBerdasarkanRespondenGetPayload<{
|
||||
select: {
|
||||
sangatbaik: true;
|
||||
baik: true;
|
||||
kurangbaik: true;
|
||||
tidakbaik: true;
|
||||
};
|
||||
}>;
|
||||
|
||||
const defaultForm: GrafikResponden = {
|
||||
sangatbaik: "",
|
||||
baik: "",
|
||||
kurangbaik: "",
|
||||
tidakbaik: "",
|
||||
};
|
||||
|
||||
const grafikBerdasarkanResponden = proxy({
|
||||
create: {
|
||||
form: defaultForm,
|
||||
loading: false,
|
||||
async create() {
|
||||
const cek = templateGrafikResponden.safeParse(
|
||||
grafikBerdasarkanResponden.create.form
|
||||
);
|
||||
if (!cek.success) {
|
||||
const err = `[${cek.error.issues
|
||||
.map((v) => `${v.path.join(".")}`)
|
||||
.join("\n")}] required`;
|
||||
return toast.error(err);
|
||||
}
|
||||
try {
|
||||
grafikBerdasarkanResponden.create.loading = true;
|
||||
const res = await ApiFetch.api.ppid.grafikberdasarkanresponden[
|
||||
"create"
|
||||
].post(grafikBerdasarkanResponden.create.form);
|
||||
if (res.status === 200) {
|
||||
grafikBerdasarkanResponden.create.form = defaultForm;
|
||||
grafikBerdasarkanResponden.findMany.load();
|
||||
return toast.success("success create");
|
||||
}
|
||||
return toast.error("failed create");
|
||||
} catch (error) {
|
||||
console.log((error as Error).message);
|
||||
} finally {
|
||||
grafikBerdasarkanResponden.create.loading = false;
|
||||
}
|
||||
},
|
||||
},
|
||||
findMany: {
|
||||
data: null as
|
||||
| Prisma.GrafikBerdasarkanRespondenGetPayload<{
|
||||
omit: { isActive: true };
|
||||
}>[]
|
||||
| null,
|
||||
loading: false,
|
||||
async load() {
|
||||
const res = await ApiFetch.api.ppid.grafikberdasarkanresponden[
|
||||
"find-many"
|
||||
].get();
|
||||
if (res.status === 200) {
|
||||
grafikBerdasarkanResponden.findMany.data = res.data?.data ?? [];
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const stateGrafikResponden = proxy({
|
||||
grafikBerdasarkanResponden,
|
||||
});
|
||||
|
||||
export default stateGrafikResponden;
|
||||
@@ -0,0 +1,84 @@
|
||||
import ApiFetch from "@/lib/api-fetch";
|
||||
import { Prisma } from "@prisma/client";
|
||||
import { toast } from "react-toastify";
|
||||
import { proxy } from "valtio";
|
||||
import { z } from "zod";
|
||||
|
||||
const templateGrafikUmur = z.object({
|
||||
remaja: z.string().min(2, "Data remaja harus diisi"),
|
||||
dewasa: z.string().min(2, "Data dewasa harus diisi"),
|
||||
orangtua: z.string().min(2, "Data orangtua harus diisi"),
|
||||
lansia: z.string().min(2, "Data lansia harus diisi"),
|
||||
});
|
||||
|
||||
type GrafikUmur = Prisma.GrafikBerdasarkanUmurGetPayload<{
|
||||
select: {
|
||||
remaja: true;
|
||||
dewasa: true;
|
||||
orangtua: true;
|
||||
lansia: true;
|
||||
};
|
||||
}>;
|
||||
|
||||
const defaultForm: GrafikUmur = {
|
||||
remaja: "",
|
||||
dewasa: "",
|
||||
orangtua: "",
|
||||
lansia: "",
|
||||
};
|
||||
|
||||
const grafikBerdasarkanUmur = proxy({
|
||||
create: {
|
||||
form: defaultForm,
|
||||
loading: false,
|
||||
async create() {
|
||||
const cek = templateGrafikUmur.safeParse(
|
||||
grafikBerdasarkanUmur.create.form
|
||||
);
|
||||
if (!cek.success) {
|
||||
const err = `[${cek.error.issues
|
||||
.map((v) => `${v.path.join(".")}`)
|
||||
.join("\n")}] required`;
|
||||
return toast.error(err);
|
||||
}
|
||||
try {
|
||||
grafikBerdasarkanUmur.create.loading = true;
|
||||
const res = await ApiFetch.api.ppid.grafikberdasarkanumur[
|
||||
"create"
|
||||
].post(grafikBerdasarkanUmur.create.form);
|
||||
if (res.status === 200) {
|
||||
grafikBerdasarkanUmur.create.form = defaultForm;
|
||||
grafikBerdasarkanUmur.findMany.load();
|
||||
return toast.success("success create");
|
||||
}
|
||||
return toast.error("failed create");
|
||||
} catch (error) {
|
||||
console.log((error as Error).message);
|
||||
} finally {
|
||||
grafikBerdasarkanUmur.create.loading = false;
|
||||
}
|
||||
},
|
||||
},
|
||||
findMany: {
|
||||
data: null as
|
||||
| Prisma.GrafikBerdasarkanUmurGetPayload<{
|
||||
omit: { isActive: true };
|
||||
}>[]
|
||||
| null,
|
||||
loading: false,
|
||||
async load() {
|
||||
const res = await ApiFetch.api.ppid.grafikberdasarkanumur[
|
||||
"find-many"
|
||||
].get();
|
||||
if (res.status === 200) {
|
||||
grafikBerdasarkanUmur.findMany.data = res.data?.data ?? [];
|
||||
}
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
const stateGrafikBerdasarkanUmur = proxy({
|
||||
grafikBerdasarkanUmur,
|
||||
})
|
||||
|
||||
export default stateGrafikBerdasarkanUmur;
|
||||
@@ -0,0 +1,76 @@
|
||||
import ApiFetch from "@/lib/api-fetch";
|
||||
import { Prisma } from "@prisma/client";
|
||||
import { toast } from "react-toastify";
|
||||
import { proxy } from "valtio";
|
||||
import { z } from "zod";
|
||||
|
||||
const templateGrafikHasilKepuasanMasyarakat = z.object({
|
||||
label: z.string().min(2, "Label harus diisi"),
|
||||
kepuasan: z.string().min(2, "Kepuasan harus diisi"),
|
||||
});
|
||||
|
||||
type GrafikHasilKepuasanMasyarakat = Prisma.IndeksKepuasanMasyarakatGetPayload<{
|
||||
select: {
|
||||
label: true;
|
||||
kepuasan: true;
|
||||
};
|
||||
}>;
|
||||
|
||||
const defaultForm: GrafikHasilKepuasanMasyarakat = {
|
||||
label: "",
|
||||
kepuasan: "",
|
||||
};
|
||||
|
||||
const grafikHasilKepuasanMasyarakat = proxy({
|
||||
create: {
|
||||
form: defaultForm,
|
||||
loading: false,
|
||||
async create() {
|
||||
const cek = templateGrafikHasilKepuasanMasyarakat.safeParse(
|
||||
grafikHasilKepuasanMasyarakat.create.form
|
||||
);
|
||||
if (!cek.success) {
|
||||
const err = `[${cek.error.issues
|
||||
.map((v) => `${v.path.join(".")}`)
|
||||
.join("\n")}] required`;
|
||||
return toast.error(err);
|
||||
}
|
||||
try {
|
||||
grafikHasilKepuasanMasyarakat.create.loading = true;
|
||||
const res = await ApiFetch.api.ppid.grafikhasilkepuasamanmasyarakat["create"].post(
|
||||
grafikHasilKepuasanMasyarakat.create.form
|
||||
);
|
||||
if (res.status === 200) {
|
||||
grafikHasilKepuasanMasyarakat.create.form = {
|
||||
label: "",
|
||||
kepuasan: ""
|
||||
};
|
||||
grafikHasilKepuasanMasyarakat.findMany.load();
|
||||
return toast.success("success create");
|
||||
}
|
||||
return toast.error("failed create");
|
||||
} catch (error) {
|
||||
console.log((error as Error).message);
|
||||
} finally {
|
||||
grafikHasilKepuasanMasyarakat.create.loading = false;
|
||||
}
|
||||
},
|
||||
},
|
||||
findMany: {
|
||||
data: null as
|
||||
| Prisma.IndeksKepuasanMasyarakatGetPayload<{ omit: { isActive: true } }>[]
|
||||
| null,
|
||||
async load() {
|
||||
const res = await ApiFetch.api.ppid.grafikhasilkepuasamanmasyarakat["find-many"].get();
|
||||
if (res.status === 200) {
|
||||
grafikHasilKepuasanMasyarakat.findMany.data = res.data?.data ?? [];
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const stateGrafikHasilKepuasanMasyarakat = proxy({
|
||||
grafikHasilKepuasanMasyarakat,
|
||||
});
|
||||
|
||||
export default stateGrafikHasilKepuasanMasyarakat;
|
||||
94
src/app/admin/(dashboard)/ppid/_com/ppid_Editor.tsx
Normal file
94
src/app/admin/(dashboard)/ppid/_com/ppid_Editor.tsx
Normal file
@@ -0,0 +1,94 @@
|
||||
'use client'
|
||||
import { Button, Stack } from '@mantine/core';
|
||||
import { Link, RichTextEditor } from '@mantine/tiptap';
|
||||
import Highlight from '@tiptap/extension-highlight';
|
||||
import SubScript from '@tiptap/extension-subscript';
|
||||
import Superscript from '@tiptap/extension-superscript';
|
||||
import TextAlign from '@tiptap/extension-text-align';
|
||||
import Underline from '@tiptap/extension-underline';
|
||||
import { useEditor } from '@tiptap/react';
|
||||
import StarterKit from '@tiptap/starter-kit';
|
||||
|
||||
const content =
|
||||
'<h2 style="text-align: center;">Welcome to Mantine rich text editor</h2><p><code>RichTextEditor</code> component focuses on usability and is designed to be as simple as possible to bring a familiar editing experience to regular users. <code>RichTextEditor</code> is based on <a href="https://tiptap.dev/" rel="noopener noreferrer" target="_blank">Tiptap.dev</a> and supports all of its features:</p><ul><li>General text formatting: <strong>bold</strong>, <em>italic</em>, <u>underline</u>, <s>strike-through</s> </li><li>Headings (h1-h6)</li><li>Sub and super scripts (<sup><sup /></sup> and <sub><sub /></sub> tags)</li><li>Ordered and bullet lists</li><li>Text align </li><li>And all <a href="https://tiptap.dev/extensions" target="_blank" rel="noopener noreferrer">other extensions</a></li></ul>';
|
||||
|
||||
export function PPIDEditor({ onSubmit, onChange, showSubmit = true }: {
|
||||
onSubmit?: (val: string) => void,
|
||||
onChange: (val: string) => void,
|
||||
showSubmit?: boolean }) {
|
||||
const editor = useEditor({
|
||||
extensions: [
|
||||
StarterKit,
|
||||
Underline,
|
||||
Link,
|
||||
Superscript,
|
||||
SubScript,
|
||||
Highlight,
|
||||
TextAlign.configure({ types: ['heading', 'paragraph'] }),
|
||||
],
|
||||
immediatelyRender: false,
|
||||
content,
|
||||
onUpdate : ({editor}) => {
|
||||
onChange(editor.getHTML())
|
||||
}
|
||||
});
|
||||
|
||||
return (
|
||||
<Stack>
|
||||
<RichTextEditor editor={editor}>
|
||||
<RichTextEditor.Toolbar sticky stickyOffset={60}>
|
||||
<RichTextEditor.ControlsGroup>
|
||||
<RichTextEditor.Bold />
|
||||
<RichTextEditor.Italic />
|
||||
<RichTextEditor.Underline />
|
||||
<RichTextEditor.Strikethrough />
|
||||
<RichTextEditor.ClearFormatting />
|
||||
<RichTextEditor.Highlight />
|
||||
<RichTextEditor.Code />
|
||||
</RichTextEditor.ControlsGroup>
|
||||
|
||||
<RichTextEditor.ControlsGroup>
|
||||
<RichTextEditor.H1 />
|
||||
<RichTextEditor.H2 />
|
||||
<RichTextEditor.H3 />
|
||||
<RichTextEditor.H4 />
|
||||
</RichTextEditor.ControlsGroup>
|
||||
|
||||
<RichTextEditor.ControlsGroup>
|
||||
<RichTextEditor.Blockquote />
|
||||
<RichTextEditor.Hr />
|
||||
<RichTextEditor.BulletList />
|
||||
<RichTextEditor.OrderedList />
|
||||
<RichTextEditor.Subscript />
|
||||
<RichTextEditor.Superscript />
|
||||
</RichTextEditor.ControlsGroup>
|
||||
|
||||
<RichTextEditor.ControlsGroup>
|
||||
<RichTextEditor.Link />
|
||||
<RichTextEditor.Unlink />
|
||||
</RichTextEditor.ControlsGroup>
|
||||
|
||||
<RichTextEditor.ControlsGroup>
|
||||
<RichTextEditor.AlignLeft />
|
||||
<RichTextEditor.AlignCenter />
|
||||
<RichTextEditor.AlignJustify />
|
||||
<RichTextEditor.AlignRight />
|
||||
</RichTextEditor.ControlsGroup>
|
||||
|
||||
<RichTextEditor.ControlsGroup>
|
||||
<RichTextEditor.Undo />
|
||||
<RichTextEditor.Redo />
|
||||
</RichTextEditor.ControlsGroup>
|
||||
</RichTextEditor.Toolbar>
|
||||
|
||||
<RichTextEditor.Content />
|
||||
</RichTextEditor>
|
||||
{showSubmit && (
|
||||
<Button onClick={() => {
|
||||
if (!editor) return
|
||||
onSubmit?.(editor?.getHTML())
|
||||
}}>Submit</Button>
|
||||
)}
|
||||
</Stack>
|
||||
);
|
||||
}
|
||||
@@ -1,11 +1,109 @@
|
||||
'use client'
|
||||
import { Box, Button, Group, SimpleGrid, Skeleton, Stack, Table, TableTbody, TableTd, TableTh, TableThead, TableTr, TextInput, Title } from '@mantine/core';
|
||||
import React from 'react';
|
||||
import { useProxy } from 'valtio/utils';
|
||||
import stateDaftarInformasiPublik from '../../_state/ppid/daftar_informasi_publik/daftarInformasiPublik';
|
||||
import { PPIDEditor } from '../_com/ppid_Editor';
|
||||
import colors from '@/con/colors';
|
||||
import { useShallowEffect } from '@mantine/hooks';
|
||||
|
||||
function Page() {
|
||||
const daftarInformasi = useProxy(stateDaftarInformasiPublik.daftarInformasi)
|
||||
const submit = () => {
|
||||
if (daftarInformasi.create.form.jenisInformasi &&
|
||||
daftarInformasi.create.form.deskripsi &&
|
||||
daftarInformasi.create.form.tanggal) {
|
||||
daftarInformasi.create.create()
|
||||
}
|
||||
}
|
||||
return (
|
||||
<div>
|
||||
daftar-informasi-publik-desa-darmasaba
|
||||
</div>
|
||||
<Box>
|
||||
<SimpleGrid cols={{ base: 1, md: 2 }}>
|
||||
<Box>
|
||||
<Stack gap={"xs"}>
|
||||
<Title fw={"bold"} order={3}>Daftar Informasi Publik Desa Darmasaba</Title>
|
||||
<TextInput
|
||||
label="Jenis Informasi"
|
||||
placeholder="masukkan jenis informasi"
|
||||
onChange={(val) => {
|
||||
daftarInformasi.create.form.jenisInformasi = val.target.value
|
||||
}}
|
||||
/>
|
||||
<PPIDEditor
|
||||
showSubmit={false}
|
||||
onChange={(val) => {
|
||||
daftarInformasi.create.form.deskripsi = val
|
||||
}}
|
||||
/>
|
||||
<TextInput
|
||||
label="Tanggal Publikasi"
|
||||
placeholder="masukkan tanggal publikasi"
|
||||
onChange={(val) => {
|
||||
daftarInformasi.create.form.tanggal = val.target.value
|
||||
}}
|
||||
/>
|
||||
<Group>
|
||||
<Button
|
||||
bg={colors['blue-button']}
|
||||
onClick={submit}
|
||||
>Submit</Button>
|
||||
</Group>
|
||||
</Stack>
|
||||
</Box>
|
||||
<Box>
|
||||
<ListDaftarInformasi />
|
||||
</Box>
|
||||
</SimpleGrid>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
function ListDaftarInformasi() {
|
||||
const listData = useProxy(stateDaftarInformasiPublik.daftarInformasi)
|
||||
useShallowEffect(() => {
|
||||
listData.findMany.load()
|
||||
}, [])
|
||||
if (!listData.findMany.data) return <Stack>
|
||||
{Array.from({length: 10}).map((v, k) => <Skeleton key={k} h={40} />)}
|
||||
</Stack>
|
||||
return <Stack gap={"xs"}>
|
||||
<Title fw={"bold"} order={3}>List Daftar Informasi Publik Desa Darmasaba</Title>
|
||||
<Table
|
||||
suppressHydrationWarning
|
||||
striped
|
||||
highlightOnHover
|
||||
withTableBorder
|
||||
withColumnBorders
|
||||
bg={colors['white-1']}
|
||||
>
|
||||
<TableThead>
|
||||
<TableTr>
|
||||
<TableTh>
|
||||
No
|
||||
</TableTh>
|
||||
<TableTh>
|
||||
Jenis Informasi
|
||||
</TableTh>
|
||||
<TableTh>
|
||||
Deskripsi
|
||||
</TableTh>
|
||||
<TableTh>
|
||||
Tanggal Publikasi
|
||||
</TableTh>
|
||||
</TableTr>
|
||||
</TableThead>
|
||||
<TableTbody>
|
||||
{listData.findMany.data?.map((item) => (
|
||||
<TableTr key={item.id}>
|
||||
<TableTd>{item.nomor}</TableTd>
|
||||
<TableTd>{item.jenisInformasi}</TableTd>
|
||||
<TableTd dangerouslySetInnerHTML={{ __html: item.deskripsi }}></TableTd>
|
||||
<TableTd>{item.tanggal}</TableTd>
|
||||
</TableTr>
|
||||
))}
|
||||
</TableTbody>
|
||||
</Table>
|
||||
</Stack>
|
||||
}
|
||||
|
||||
export default Page;
|
||||
|
||||
@@ -0,0 +1,138 @@
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
'use client'
|
||||
import stateGrafikBerdasarkanJenisKelamin from '@/app/admin/(dashboard)/_state/ppid/indeks_kepuasan_masyarakat/grafikBerdasarkanJenisKelamin';
|
||||
import colors from '@/con/colors';
|
||||
import { Box, Button, Center, Flex, Stack, Text, TextInput, Title } from '@mantine/core';
|
||||
import { useShallowEffect } from '@mantine/hooks';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { Cell, Pie, PieChart } from 'recharts';
|
||||
import { useProxy } from 'valtio/utils';
|
||||
|
||||
function GrafikBerdasarkanJenisKelamin() {
|
||||
const grafikBerdasarkanJenisKelamin = useProxy(stateGrafikBerdasarkanJenisKelamin.grafikBerdasarkanJenisKelamin)
|
||||
const [donutData, setDonutData] = useState<any[]>([]);
|
||||
const [mounted, setMounted] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
setMounted(true);
|
||||
}, [])
|
||||
|
||||
const updateChartData = (data: any) => {
|
||||
if (data && data.length > 0) {
|
||||
const totalLaki = data.reduce((acc: number, cur: any) => acc + Number(cur.laki || 0), 0);
|
||||
const totalPerempuan = data.reduce((acc: number, cur: any) => acc + Number(cur.perempuan || 0), 0);
|
||||
|
||||
setDonutData([
|
||||
{ name: 'Laki-laki', value: totalLaki, color: colors['blue-button'], key: 'laki-laki' },
|
||||
{ name: 'Perempuan', value: totalPerempuan, color: '#FF6384', key: 'perempuan' }
|
||||
]);
|
||||
}
|
||||
};
|
||||
|
||||
useShallowEffect(() => {
|
||||
fetchData();
|
||||
}, []);
|
||||
|
||||
const fetchData = async () => {
|
||||
await grafikBerdasarkanJenisKelamin.findMany.load();
|
||||
if (grafikBerdasarkanJenisKelamin.findMany.data) {
|
||||
updateChartData(grafikBerdasarkanJenisKelamin.findMany.data);
|
||||
}
|
||||
};
|
||||
|
||||
const handleSubmit = async () => {
|
||||
try {
|
||||
// Simpan data baru
|
||||
await grafikBerdasarkanJenisKelamin.create.create();
|
||||
|
||||
// Muat ulang data
|
||||
await grafikBerdasarkanJenisKelamin.findMany.load();
|
||||
|
||||
// Update chart dengan data baru
|
||||
if (grafikBerdasarkanJenisKelamin.findMany.data) {
|
||||
updateChartData(grafikBerdasarkanJenisKelamin.findMany.data);
|
||||
}
|
||||
|
||||
// Reset form setelah submit
|
||||
grafikBerdasarkanJenisKelamin.create.form.laki = '';
|
||||
grafikBerdasarkanJenisKelamin.create.form.perempuan = '';
|
||||
} catch (error) {
|
||||
console.error("Error submitting data:", error);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Box>
|
||||
<Box py={15}>
|
||||
<Title order={3}>Grafik Hasil Kepuasan Masyarakat Terhadap Pelayanan Publik</Title>
|
||||
<TextInput
|
||||
w={{ base: '100%', md: '50%' }}
|
||||
label="Laki-laki"
|
||||
placeholder="masukkan jumlah laki-laki"
|
||||
value={grafikBerdasarkanJenisKelamin.create.form.laki}
|
||||
onChange={(val) => {
|
||||
grafikBerdasarkanJenisKelamin.create.form.laki = val.currentTarget.value;
|
||||
}}
|
||||
/>
|
||||
<TextInput
|
||||
w={{ base: '100%', md: '50%' }}
|
||||
label="Perempuan"
|
||||
type="number"
|
||||
placeholder="masukkan jumlah perempuan"
|
||||
value={grafikBerdasarkanJenisKelamin.create.form.perempuan}
|
||||
onChange={(val) => {
|
||||
grafikBerdasarkanJenisKelamin.create.form.perempuan = val.currentTarget.value;
|
||||
}}
|
||||
/>
|
||||
<Button
|
||||
mt={10}
|
||||
bg={colors['blue-button']}
|
||||
onClick={handleSubmit}
|
||||
>
|
||||
Submit
|
||||
</Button>
|
||||
</Box>
|
||||
|
||||
{/* Chart */}
|
||||
<Box>
|
||||
<Stack>
|
||||
<Title pb={10} order={3}>Grafik Berdasarkan Jenis Kelamin Responden</Title>
|
||||
{mounted && donutData.length > 0 && (
|
||||
<Box style={{ width: '100%', height: 'auto', minHeight: 900 }}>
|
||||
<Center>
|
||||
<PieChart
|
||||
width={1000} height={400}
|
||||
data={donutData}
|
||||
>
|
||||
|
||||
<Pie
|
||||
dataKey="value"
|
||||
nameKey="name"
|
||||
data={donutData}
|
||||
innerRadius={120}
|
||||
outerRadius={160}
|
||||
label
|
||||
>
|
||||
{donutData.map((entry, index) => (
|
||||
<Cell key={`cell-${index}`} fill={entry.color} />
|
||||
))}
|
||||
</Pie>
|
||||
</PieChart>
|
||||
</Center>
|
||||
<Flex gap={"md"} align={"center"}>
|
||||
<Box bg={'#FF6384'} w={20} h={20} />
|
||||
<Text>Perempuan: {donutData.find((entry) => entry.name === 'Perempuan')?.value}</Text>
|
||||
</Flex>
|
||||
<Flex gap={"md"} align={"center"}>
|
||||
<Box bg={colors['blue-button']} w={20} h={20} />
|
||||
<Text>Laki-laki: {donutData.find((entry) => entry.name === 'Laki-laki')?.value}</Text>
|
||||
</Flex>
|
||||
</Box>
|
||||
)}
|
||||
</Stack>
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
export default GrafikBerdasarkanJenisKelamin;
|
||||
@@ -0,0 +1,166 @@
|
||||
'use client'
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
import stateGrafikResponden from '@/app/admin/(dashboard)/_state/ppid/indeks_kepuasan_masyarakat/grafikBerdasarkanResponden';
|
||||
import colors from '@/con/colors';
|
||||
import { Box, Button, Center, Flex, Stack, Text, TextInput, Title } from '@mantine/core';
|
||||
import { useShallowEffect } from '@mantine/hooks';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { PieChart, Pie, Cell } from 'recharts';
|
||||
import { useProxy } from 'valtio/utils';
|
||||
|
||||
function GrafikBerdasarkanResponden() {
|
||||
const grafikBerdasarkanResponden = useProxy(stateGrafikResponden.grafikBerdasarkanResponden)
|
||||
const [donutData, setDonutData] = useState<any[]>([]);
|
||||
const [mounted, setMounted] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
setMounted(true);
|
||||
}, [])
|
||||
|
||||
const updateChartData = (data: any) => {
|
||||
if (data && data.length > 0) {
|
||||
const totalSangatBaik = data.reduce((acc: number, cur: any) => acc + Number(cur.sangatbaik || 0), 0);
|
||||
const totalBaik = data.reduce((acc: number, cur: any) => acc + Number(cur.baik || 0), 0);
|
||||
const totalKurangBaik = data.reduce((acc: number, cur: any) => acc + Number(cur.kurangbaik || 0), 0);
|
||||
const totalTidakBaik = data.reduce((acc: number, cur: any) => acc + Number(cur.tidakbaik || 0), 0);
|
||||
setDonutData([
|
||||
{ name: 'sangatbaik', value: totalSangatBaik, color: colors['blue-button'], key: 'sangatbaik' },
|
||||
{ name: 'baik', value: totalBaik, color: '#10A85AFF', key: 'baik' },
|
||||
{ name: 'kurangbaik', value: totalKurangBaik, color: '#B3AA12FF', key: 'kurangbaik' },
|
||||
{ name: 'tidakbaik', value: totalTidakBaik, color: '#B21313FF', key: 'tidakbaik' }
|
||||
]);
|
||||
}
|
||||
};
|
||||
|
||||
useShallowEffect(() => {
|
||||
fetchData();
|
||||
}, []);
|
||||
|
||||
const fetchData = async () => {
|
||||
await grafikBerdasarkanResponden.findMany.load();
|
||||
if (grafikBerdasarkanResponden.findMany.data) {
|
||||
updateChartData(grafikBerdasarkanResponden.findMany.data);
|
||||
}
|
||||
};
|
||||
|
||||
const handleSubmit = async () => {
|
||||
try {
|
||||
// Simpan data baru
|
||||
await grafikBerdasarkanResponden.create.create();
|
||||
|
||||
// Muat ulang data
|
||||
await grafikBerdasarkanResponden.findMany.load();
|
||||
|
||||
// Update chart dengan data baru
|
||||
if (grafikBerdasarkanResponden.findMany.data) {
|
||||
updateChartData(grafikBerdasarkanResponden.findMany.data);
|
||||
}
|
||||
|
||||
// Reset form setelah submit
|
||||
grafikBerdasarkanResponden.create.form.sangatbaik = '';
|
||||
grafikBerdasarkanResponden.create.form.baik = '';
|
||||
grafikBerdasarkanResponden.create.form.kurangbaik = '';
|
||||
grafikBerdasarkanResponden.create.form.tidakbaik = '';
|
||||
} catch (error) {
|
||||
console.error("Error submitting data:", error);
|
||||
}
|
||||
};
|
||||
return (
|
||||
<Box>
|
||||
<Box py={15}>
|
||||
<Title order={3}>Grafik Berdasarkan Responden</Title>
|
||||
<TextInput
|
||||
w={{ base: '100%', md: '50%' }}
|
||||
label="Sangat Baik"
|
||||
value={grafikBerdasarkanResponden.create.form.sangatbaik}
|
||||
placeholder="masukkan jumlah respon sangat baik"
|
||||
onChange={(val) => {
|
||||
grafikBerdasarkanResponden.create.form.sangatbaik = val.currentTarget.value;
|
||||
}}
|
||||
/>
|
||||
<TextInput
|
||||
w={{ base: '100%', md: '50%' }}
|
||||
label="Baik"
|
||||
value={grafikBerdasarkanResponden.create.form.baik}
|
||||
placeholder="masukkan jumlah respon baik"
|
||||
onChange={(val) => {
|
||||
grafikBerdasarkanResponden.create.form.baik = val.currentTarget.value;
|
||||
}}
|
||||
/>
|
||||
<TextInput
|
||||
w={{ base: '100%', md: '50%' }}
|
||||
label="Kurang Baik"
|
||||
value={grafikBerdasarkanResponden.create.form.kurangbaik}
|
||||
placeholder="masukkan jumlah respon kurang baik"
|
||||
onChange={(val) => {
|
||||
grafikBerdasarkanResponden.create.form.kurangbaik = val.currentTarget.value;
|
||||
}}
|
||||
/>
|
||||
<TextInput
|
||||
w={{ base: '100%', md: '50%' }}
|
||||
label="Tidak Baik"
|
||||
value={grafikBerdasarkanResponden.create.form.tidakbaik}
|
||||
placeholder="masukkan jumlah respon tidak baik"
|
||||
onChange={(val) => {
|
||||
grafikBerdasarkanResponden.create.form.tidakbaik = val.currentTarget.value;
|
||||
}}
|
||||
/>
|
||||
<Button
|
||||
mt={10}
|
||||
bg={colors['blue-button']}
|
||||
onClick={handleSubmit}
|
||||
>
|
||||
Submit
|
||||
</Button>
|
||||
</Box>
|
||||
|
||||
{/* Chart */}
|
||||
<Box>
|
||||
<Stack>
|
||||
<Title pb={10} order={3}>Grafik Berdasarkan Responden</Title>
|
||||
{mounted && donutData.length > 0 && (
|
||||
<Box style={{ width: '100%', height: 'auto', minHeight: 900 }}>
|
||||
<Center>
|
||||
<PieChart
|
||||
width={1000} height={400}
|
||||
data={donutData}
|
||||
>
|
||||
<Pie
|
||||
dataKey="value"
|
||||
nameKey="name"
|
||||
data={donutData}
|
||||
innerRadius={120}
|
||||
outerRadius={160}
|
||||
label
|
||||
>
|
||||
{donutData.map((entry, index) => (
|
||||
<Cell key={`cell-${index}`} fill={entry.color} />
|
||||
))}
|
||||
</Pie>
|
||||
</PieChart>
|
||||
</Center>
|
||||
<Flex gap={"md"} align={"center"}>
|
||||
<Box bg={colors['blue-button']} w={20} h={20} />
|
||||
<Text>Sangat Baik: {donutData.find((entry) => entry.name === 'sangatbaik')?.value}</Text>
|
||||
</Flex>
|
||||
<Flex gap={"md"} align={"center"}>
|
||||
<Box bg={'#10A85AFF'} w={20} h={20} />
|
||||
<Text>Baik: {donutData.find((entry) => entry.name === 'baik')?.value}</Text>
|
||||
</Flex>
|
||||
<Flex gap={"md"} align={"center"}>
|
||||
<Box bg={'#B3AA12FF'} w={20} h={20} />
|
||||
<Text>Kurang Baik: {donutData.find((entry) => entry.name === 'kurangbaik')?.value}</Text>
|
||||
</Flex>
|
||||
<Flex gap={"md"} align={"center"}>
|
||||
<Box bg={'#B21313FF'} w={20} h={20} />
|
||||
<Text>Tidak Baik: {donutData.find((entry) => entry.name === 'tidakbaik')?.value}</Text>
|
||||
</Flex>
|
||||
</Box>
|
||||
)}
|
||||
</Stack>
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
export default GrafikBerdasarkanResponden;
|
||||
@@ -0,0 +1,156 @@
|
||||
'use client'
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
import colors from '@/con/colors';
|
||||
import { Box, Button, Center, Flex, Stack, Text, TextInput, Title } from '@mantine/core';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { useProxy } from 'valtio/utils';
|
||||
import stateGrafikBerdasarkanUmur from '@/app/admin/(dashboard)/_state/ppid/indeks_kepuasan_masyarakat/grafikBerdasarkanUmur';
|
||||
import { useShallowEffect } from '@mantine/hooks';
|
||||
import { PieChart, Pie, Cell } from 'recharts';
|
||||
|
||||
function GrafikBerdasarakanUmur() {
|
||||
const grafikBerdasarkanUmur = useProxy(stateGrafikBerdasarkanUmur.grafikBerdasarkanUmur)
|
||||
const [donutData, setDonutData] = useState<any[]>([]);
|
||||
const [mounted, setMounted] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
setMounted(true);
|
||||
}, []);
|
||||
|
||||
const updateChartData = (data: any) => {
|
||||
if (data && data.length > 0) {
|
||||
const totalRemaja = data.reduce((acc: number, cur: any) => acc + Number(cur.remaja || 0), 0);
|
||||
const totalDewasa = data.reduce((acc: number, cur: any) => acc + Number(cur.dewasa || 0), 0);
|
||||
const totalOrangtua = data.reduce((acc: number, cur: any) => acc + Number(cur.orangtua || 0), 0);
|
||||
const totalLansia = data.reduce((acc: number, cur: any) => acc + Number(cur.lansia || 0), 0);
|
||||
|
||||
setDonutData([
|
||||
{ name: 'Remaja', value: totalRemaja, color: colors['blue-button'], key: 'remaja' },
|
||||
{ name: 'Dewasa', value: totalDewasa, color: '#D32711FF', key: 'dewasa' },
|
||||
{ name: 'Orangtua', value: totalOrangtua, color: '#B46B04FF', key: 'orangtua' },
|
||||
{ name: 'Lansia', value: totalLansia, color: '#038617FF', key: 'lansia' }
|
||||
]);
|
||||
}
|
||||
};
|
||||
|
||||
useShallowEffect(() => {
|
||||
fetchData();
|
||||
}, []);
|
||||
|
||||
const fetchData = async () => {
|
||||
await grafikBerdasarkanUmur.findMany.load();
|
||||
if (grafikBerdasarkanUmur.findMany.data) {
|
||||
updateChartData(grafikBerdasarkanUmur.findMany.data);
|
||||
}
|
||||
}
|
||||
|
||||
const handleSubmit = async () => {
|
||||
try {
|
||||
await grafikBerdasarkanUmur.create.create();
|
||||
await grafikBerdasarkanUmur.findMany.load();
|
||||
if (grafikBerdasarkanUmur.findMany.data) {
|
||||
updateChartData(grafikBerdasarkanUmur.findMany.data);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error submitting data:", error);
|
||||
}
|
||||
}
|
||||
return (
|
||||
<Box>
|
||||
<Box py={15}>
|
||||
<Title order={3}>Grafik Berdasarkan Umur Responden</Title>
|
||||
<TextInput
|
||||
w={{ base: '100%', md: '50%' }}
|
||||
label="Remaja"
|
||||
placeholder="masukkan jumlah responden remaja"
|
||||
value={grafikBerdasarkanUmur.create.form.remaja}
|
||||
onChange={(val) => {
|
||||
grafikBerdasarkanUmur.create.form.remaja = val.currentTarget.value;
|
||||
}}
|
||||
/>
|
||||
<TextInput
|
||||
w={{ base: '100%', md: '50%' }}
|
||||
label="Dewasa"
|
||||
placeholder="masukkan jumlah responden dewasa"
|
||||
value={grafikBerdasarkanUmur.create.form.dewasa}
|
||||
onChange={(val) => {
|
||||
grafikBerdasarkanUmur.create.form.dewasa = val.currentTarget.value;
|
||||
}}
|
||||
/>
|
||||
<TextInput
|
||||
w={{ base: '100%', md: '50%' }}
|
||||
label="Orangtua"
|
||||
placeholder="masukkan jumlah responden orangtua"
|
||||
value={grafikBerdasarkanUmur.create.form.orangtua}
|
||||
onChange={(val) => {
|
||||
grafikBerdasarkanUmur.create.form.orangtua = val.currentTarget.value;
|
||||
}}
|
||||
/>
|
||||
<TextInput
|
||||
w={{ base: '100%', md: '50%' }}
|
||||
label="Lansia"
|
||||
placeholder="masukkan jumlah responden lansia"
|
||||
value={grafikBerdasarkanUmur.create.form.lansia}
|
||||
onChange={(val) => {
|
||||
grafikBerdasarkanUmur.create.form.lansia = val.currentTarget.value;
|
||||
}}
|
||||
/>
|
||||
<Button
|
||||
mt={10}
|
||||
bg={colors['blue-button']}
|
||||
onClick={handleSubmit}
|
||||
>
|
||||
Submit
|
||||
</Button>
|
||||
</Box>
|
||||
|
||||
{/* Chart */}
|
||||
<Box>
|
||||
<Stack>
|
||||
<Title pb={10} order={3}>Grafik Berdasarkan Umur Responden</Title>
|
||||
{mounted && donutData.length > 0 && (
|
||||
<Box style={{ width: '100%', height: 'auto', minHeight: 900 }}>
|
||||
<Center>
|
||||
<PieChart
|
||||
width={1000} height={400}
|
||||
data={donutData}
|
||||
>
|
||||
<Pie
|
||||
dataKey="value"
|
||||
nameKey="name"
|
||||
data={donutData}
|
||||
innerRadius={120}
|
||||
outerRadius={160}
|
||||
label
|
||||
>
|
||||
{donutData.map((entry, index) => (
|
||||
<Cell key={`cell-${index}`} fill={entry.color} />
|
||||
))}
|
||||
</Pie>
|
||||
</PieChart>
|
||||
</Center>
|
||||
<Flex gap={"md"} align={"center"}>
|
||||
<Box bg={colors['blue-button']} w={20} h={20} />
|
||||
<Text>17 - 25 tahun: {donutData.find((entry) => entry.name === 'remaja')?.value}</Text>
|
||||
</Flex>
|
||||
<Flex gap={"md"} align={"center"}>
|
||||
<Box bg={'#D32711FF'} w={20} h={20} />
|
||||
<Text>26 - 45 tahun: {donutData.find((entry) => entry.name === 'dewasa')?.value}</Text>
|
||||
</Flex>
|
||||
<Flex gap={"md"} align={"center"}>
|
||||
<Box bg={'#B46B04FF'} w={20} h={20} />
|
||||
<Text>46 - 60 tahun: {donutData.find((entry) => entry.name === 'orangtua')?.value}</Text>
|
||||
</Flex>
|
||||
<Flex gap={"md"} align={"center"}>
|
||||
<Box bg={'#038617FF'} w={20} h={20} />
|
||||
<Text>di atas 60 tahun: {donutData.find((entry) => entry.name === 'lansia')?.value}</Text>
|
||||
</Flex>
|
||||
</Box>
|
||||
)}
|
||||
</Stack>
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
export default GrafikBerdasarakanUmur;
|
||||
@@ -0,0 +1,88 @@
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
'use client'
|
||||
import stateGrafikHasilKepuasanMasyarakat from '@/app/admin/(dashboard)/_state/ppid/indeks_kepuasan_masyarakat/grafikHasilKepuasan';
|
||||
import colors from '@/con/colors';
|
||||
import { Box, Button, TextInput, Title } from '@mantine/core';
|
||||
import { useMediaQuery, useShallowEffect } from '@mantine/hooks';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { Bar, BarChart, Legend, Tooltip, XAxis, YAxis } from 'recharts';
|
||||
import { useProxy } from 'valtio/utils';
|
||||
|
||||
function GrafikHasilKepuasan() {
|
||||
const grafikHasilKepuasan = useProxy(stateGrafikHasilKepuasanMasyarakat.grafikHasilKepuasanMasyarakat)
|
||||
const [chartData, setChartData] = useState<any[]>([]);
|
||||
const [mounted, setMounted] = useState(false);
|
||||
const isTablet = useMediaQuery('(max-width: 1024px)')
|
||||
const isMobile = useMediaQuery('(max-width: 768px)')
|
||||
|
||||
useEffect(() => {
|
||||
setMounted(true);
|
||||
}, [])
|
||||
|
||||
useShallowEffect(() => {
|
||||
const fetchData = async () => {
|
||||
await grafikHasilKepuasan.findMany.load();
|
||||
if (grafikHasilKepuasan.findMany.data && grafikHasilKepuasan.findMany.data.length > 0) {
|
||||
setChartData(grafikHasilKepuasan.findMany.data);
|
||||
}
|
||||
};
|
||||
fetchData();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Box>
|
||||
<Box py={15}>
|
||||
<Title order={3}>Grafik Hasil Kepuasan Masyarakat Terhadap Pelayanan Publik</Title>
|
||||
<TextInput
|
||||
w={{ base: '100%', md: '50%' }}
|
||||
label="Label"
|
||||
placeholder="masukkan label"
|
||||
value={grafikHasilKepuasan.create.form.label}
|
||||
onChange={(val) => {
|
||||
grafikHasilKepuasan.create.form.label = val.currentTarget.value;
|
||||
}}
|
||||
/>
|
||||
<TextInput
|
||||
w={{ base: '100%', md: '50%' }}
|
||||
label="Jumlah Kepuasan"
|
||||
type="number"
|
||||
placeholder="masukkan jumlah kepuasan"
|
||||
value={grafikHasilKepuasan.create.form.kepuasan}
|
||||
onChange={(val) => {
|
||||
grafikHasilKepuasan.create.form.kepuasan = val.currentTarget.value;
|
||||
}}
|
||||
/>
|
||||
<Button
|
||||
mt={10}
|
||||
bg={colors['blue-button']}
|
||||
onClick={async () => {
|
||||
await grafikHasilKepuasan.create.create();
|
||||
await grafikHasilKepuasan.findMany.load();
|
||||
if (grafikHasilKepuasan.findMany.data) {
|
||||
setChartData(grafikHasilKepuasan.findMany.data);
|
||||
}
|
||||
}}
|
||||
>
|
||||
Submit
|
||||
</Button>
|
||||
</Box>
|
||||
|
||||
{/* Chart */}
|
||||
<Box style={{ width: '100%', minWidth: 300, height: 400, minHeight: 300 }}>
|
||||
<Title pb={10} order={3}>Data Kepuasan Masyarakat</Title>
|
||||
{mounted && chartData.length > 0 && (
|
||||
<BarChart width={isMobile ? 450 : isTablet ? 600 : 900} height={380} data={chartData} >
|
||||
<XAxis dataKey="label" />
|
||||
<YAxis />
|
||||
<Tooltip />
|
||||
<Legend />
|
||||
<Bar dataKey="kepuasan" fill={colors['blue-button']} name="Kepuasan" />
|
||||
</BarChart>
|
||||
)}
|
||||
</Box>
|
||||
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
export default GrafikHasilKepuasan;
|
||||
@@ -1,10 +1,44 @@
|
||||
import { Stack, Tabs, TabsList, TabsPanel, TabsTab } from '@mantine/core';
|
||||
import React from 'react';
|
||||
import colors from '@/con/colors';
|
||||
import GrafikHasilKepuasan from './_ui/grafik_hasil_kepuasan_masyarakat/page';
|
||||
import GrafikBerdasarkanJenisKelamin from './_ui/grafik_berdasarkan_jenis_kelamin_responden/page';
|
||||
import GrafikBerdasarkanResponden from './_ui/grafik_berdasarkan_responden/page';
|
||||
import GrafikBerdasarakanUmur from './_ui/grafik_berdasarkan_umur/page';
|
||||
|
||||
function Page() {
|
||||
return (
|
||||
<div>
|
||||
ikm-desa-darmasaba
|
||||
</div>
|
||||
<Stack>
|
||||
<Tabs color={colors['blue-button']} variant='pills' defaultValue={"Grafik Hasil Kepuasan Masyarakat Terhadap Pelayanan Publik"}>
|
||||
<TabsList>
|
||||
<TabsTab value="Grafik Hasil Kepuasan Masyarakat Terhadap Pelayanan Publik">
|
||||
Grafik Hasil Kepuasan Masyarakat Terhadap Pelayanan Publik
|
||||
</TabsTab>
|
||||
<TabsTab value="Grafik Berdasarkan Jenis Kelamin Responden">
|
||||
Grafik Berdasarkan Jenis Kelamin Responden
|
||||
</TabsTab>
|
||||
<TabsTab value="Grafik Berdasarkan Pilihan Responden">
|
||||
Grafik Berdasarkan Pilihan Responden
|
||||
</TabsTab>
|
||||
<TabsTab value="Grafik Berdasarkan Umur Responden">
|
||||
Grafik Berdasarkan Umur Responden
|
||||
</TabsTab>
|
||||
</TabsList>
|
||||
|
||||
<TabsPanel value="Grafik Hasil Kepuasan Masyarakat Terhadap Pelayanan Publik">
|
||||
<GrafikHasilKepuasan/>
|
||||
</TabsPanel>
|
||||
<TabsPanel value="Grafik Berdasarkan Jenis Kelamin Responden">
|
||||
<GrafikBerdasarkanJenisKelamin/>
|
||||
</TabsPanel>
|
||||
<TabsPanel value="Grafik Berdasarkan Pilihan Responden">
|
||||
<GrafikBerdasarkanResponden/>
|
||||
</TabsPanel>
|
||||
<TabsPanel value="Grafik Berdasarkan Umur Responden">
|
||||
<GrafikBerdasarakanUmur/>
|
||||
</TabsPanel>
|
||||
</Tabs>
|
||||
</Stack>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user