- QC User & Admin Menu Lingkungan
- Fix SubMenu : Edukasi Lingkungan & Konservasi Adat Bali dibagian User - Fix SUbMenu : Gotong Royong User ( Tabs kategori menyesuaikan dengan data kategori kegiatan )
This commit is contained in:
@@ -0,0 +1,9 @@
|
|||||||
|
[
|
||||||
|
{ "id": "cmghqwjs4000404l8c5uvc300", "nama": "PAUD" },
|
||||||
|
{ "id": "cmghqwjs4000404l8c5uvc301", "nama": "TK" },
|
||||||
|
{ "id": "cmghqwjs4000404l8c5uvc302", "nama": "SD" },
|
||||||
|
{ "id": "cmghqwjs4000404l8c5uvc303", "nama": "SMP" },
|
||||||
|
{ "id": "cmghqwjs4000404l8c5uvc304", "nama": "SMA" },
|
||||||
|
{ "id": "cmghqwjs4000404l8c5uvc305", "nama": "SMK" }
|
||||||
|
]
|
||||||
|
|
||||||
@@ -56,6 +56,7 @@ import tujuanProgram from "./data/pendidikan/program-pendidikan-anak/tujuan-prog
|
|||||||
import roles from "./data/user/roles.json";
|
import roles from "./data/user/roles.json";
|
||||||
import users from "./data/user/users.json";
|
import users from "./data/user/users.json";
|
||||||
import fileStorage from "./data/file-storage.json";
|
import fileStorage from "./data/file-storage.json";
|
||||||
|
import jenjangPendidikan from "./data/pendidikan/info-sekolah/jenjang-pendidikan.json";
|
||||||
import seedAssets from "./seed_assets";
|
import seedAssets from "./seed_assets";
|
||||||
import { safeSeedUnique } from "./safeseedUnique";
|
import { safeSeedUnique } from "./safeseedUnique";
|
||||||
|
|
||||||
@@ -1164,6 +1165,22 @@ import { safeSeedUnique } from "./safeseedUnique";
|
|||||||
"✅ fasilitas bimbingan belajar desa seeded (editable later via UI)"
|
"✅ fasilitas bimbingan belajar desa seeded (editable later via UI)"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
for (const j of jenjangPendidikan) {
|
||||||
|
await prisma.jenjangPendidikan.upsert({
|
||||||
|
where: {
|
||||||
|
id: j.id || undefined,
|
||||||
|
},
|
||||||
|
update: {
|
||||||
|
nama: j.nama,
|
||||||
|
},
|
||||||
|
create: {
|
||||||
|
nama: j.nama,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("✅ Jenjang Pendidikan seeded successfully");
|
||||||
|
|
||||||
// seed assets
|
// seed assets
|
||||||
await seedAssets();
|
await seedAssets();
|
||||||
|
|
||||||
|
|||||||
@@ -332,7 +332,7 @@ const keunggulanProgram = proxy({
|
|||||||
].post(keunggulanProgram.create.form);
|
].post(keunggulanProgram.create.form);
|
||||||
if (res.status === 200) {
|
if (res.status === 200) {
|
||||||
keunggulanProgram.findMany.load();
|
keunggulanProgram.findMany.load();
|
||||||
return toast.success("Data Berhasil Dibuat, Silahkan Menunggu Konfirmasi dari Admin di WhatsApp");
|
return toast.success("Data Berhasil Dibuat");
|
||||||
}
|
}
|
||||||
console.log(res);
|
console.log(res);
|
||||||
return toast.error("failed create");
|
return toast.error("failed create");
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/* eslint-disable react-hooks/exhaustive-deps */
|
/* eslint-disable react-hooks/exhaustive-deps */
|
||||||
'use client'
|
'use client'
|
||||||
import colors from '@/con/colors';
|
import colors from '@/con/colors';
|
||||||
import { Stack, Tabs, TabsList, TabsPanel, TabsTab, Title, Tooltip } from '@mantine/core';
|
import { ScrollArea, Stack, Tabs, TabsList, TabsPanel, TabsTab, Title, Tooltip } from '@mantine/core';
|
||||||
import { usePathname, useRouter } from 'next/navigation';
|
import { usePathname, useRouter } from 'next/navigation';
|
||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import { IconSchool, IconStar } from '@tabler/icons-react';
|
import { IconSchool, IconStar } from '@tabler/icons-react';
|
||||||
@@ -58,36 +58,38 @@ function LayoutTabs({ children }: { children: React.ReactNode }) {
|
|||||||
radius="lg"
|
radius="lg"
|
||||||
keepMounted={false}
|
keepMounted={false}
|
||||||
>
|
>
|
||||||
<TabsList
|
<ScrollArea type="auto" offsetScrollbars>
|
||||||
p="sm"
|
<TabsList
|
||||||
style={{
|
p="sm"
|
||||||
background: "linear-gradient(135deg, #e7ebf7, #f9faff)",
|
style={{
|
||||||
borderRadius: "1rem",
|
background: "linear-gradient(135deg, #e7ebf7, #f9faff)",
|
||||||
boxShadow: "inset 0 0 10px rgba(0,0,0,0.05)",
|
borderRadius: "1rem",
|
||||||
}}
|
boxShadow: "inset 0 0 10px rgba(0,0,0,0.05)",
|
||||||
>
|
}}
|
||||||
{tabs.map((tab, i) => (
|
>
|
||||||
<Tooltip
|
{tabs.map((tab, i) => (
|
||||||
key={i}
|
<Tooltip
|
||||||
label={tab.tooltip}
|
key={i}
|
||||||
position="bottom"
|
label={tab.tooltip}
|
||||||
withArrow
|
position="bottom"
|
||||||
transitionProps={{ transition: 'pop', duration: 200 }}
|
withArrow
|
||||||
>
|
transitionProps={{ transition: 'pop', duration: 200 }}
|
||||||
<TabsTab
|
|
||||||
value={tab.value}
|
|
||||||
leftSection={tab.icon}
|
|
||||||
style={{
|
|
||||||
fontWeight: 600,
|
|
||||||
fontSize: "0.9rem",
|
|
||||||
transition: "all 0.2s ease",
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
{tab.label}
|
<TabsTab
|
||||||
</TabsTab>
|
value={tab.value}
|
||||||
</Tooltip>
|
leftSection={tab.icon}
|
||||||
))}
|
style={{
|
||||||
</TabsList>
|
fontWeight: 600,
|
||||||
|
fontSize: "0.9rem",
|
||||||
|
transition: "all 0.2s ease",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{tab.label}
|
||||||
|
</TabsTab>
|
||||||
|
</Tooltip>
|
||||||
|
))}
|
||||||
|
</TabsList>
|
||||||
|
</ScrollArea>
|
||||||
|
|
||||||
{tabs.map((tab, i) => (
|
{tabs.map((tab, i) => (
|
||||||
<TabsPanel
|
<TabsPanel
|
||||||
|
|||||||
@@ -99,22 +99,22 @@ function ListKeunggulanProgram({ search }: { search: string }) {
|
|||||||
<Table highlightOnHover>
|
<Table highlightOnHover>
|
||||||
<TableThead>
|
<TableThead>
|
||||||
<TableTr>
|
<TableTr>
|
||||||
<TableTh style={{ width: '30%' }}>Nama Keunggulan Program</TableTh>
|
<TableTh style={{ minWidth: 200 }}>Nama Keunggulan Program</TableTh>
|
||||||
<TableTh style={{ width: '35%' }}>Deskripsi</TableTh>
|
<TableTh style={{ minWidth: 200 }}>Deskripsi</TableTh>
|
||||||
<TableTh style={{ width: '15%' }}>Edit</TableTh>
|
<TableTh style={{ minWidth: 200 }}>Edit</TableTh>
|
||||||
<TableTh style={{ width: '15%' }}>Delete</TableTh>
|
<TableTh style={{ minWidth: 200 }}>Delete</TableTh>
|
||||||
</TableTr>
|
</TableTr>
|
||||||
</TableThead>
|
</TableThead>
|
||||||
<TableTbody>
|
<TableTbody>
|
||||||
{filteredData.length > 0 ? (
|
{filteredData.length > 0 ? (
|
||||||
filteredData.map((item) => (
|
filteredData.map((item) => (
|
||||||
<TableTr key={item.id}>
|
<TableTr key={item.id}>
|
||||||
<TableTd>
|
<TableTd style={{ minWidth: 200 }}>
|
||||||
<Text fw={500} truncate="end" lineClamp={1}>
|
<Text fw={500} truncate="end" lineClamp={1}>
|
||||||
{item.judul}
|
{item.judul}
|
||||||
</Text>
|
</Text>
|
||||||
</TableTd>
|
</TableTd>
|
||||||
<TableTd>
|
<TableTd style={{ minWidth: 200 }}>
|
||||||
<Text
|
<Text
|
||||||
fw={500}
|
fw={500}
|
||||||
truncate="end"
|
truncate="end"
|
||||||
@@ -122,7 +122,7 @@ function ListKeunggulanProgram({ search }: { search: string }) {
|
|||||||
dangerouslySetInnerHTML={{ __html: item.deskripsi }}
|
dangerouslySetInnerHTML={{ __html: item.deskripsi }}
|
||||||
/>
|
/>
|
||||||
</TableTd>
|
</TableTd>
|
||||||
<TableTd>
|
<TableTd style={{ minWidth: 200 }}>
|
||||||
<Tooltip label="Edit" withArrow>
|
<Tooltip label="Edit" withArrow>
|
||||||
<Button
|
<Button
|
||||||
variant="light"
|
variant="light"
|
||||||
@@ -138,7 +138,7 @@ function ListKeunggulanProgram({ search }: { search: string }) {
|
|||||||
</Button>
|
</Button>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</TableTd>
|
</TableTd>
|
||||||
<TableTd>
|
<TableTd style={{ minWidth: 200 }}>
|
||||||
<Tooltip label="Hapus" withArrow>
|
<Tooltip label="Hapus" withArrow>
|
||||||
<Button
|
<Button
|
||||||
variant="light"
|
variant="light"
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/* eslint-disable react-hooks/exhaustive-deps */
|
/* eslint-disable react-hooks/exhaustive-deps */
|
||||||
'use client'
|
'use client'
|
||||||
import colors from '@/con/colors';
|
import colors from '@/con/colors';
|
||||||
import { Stack, Tabs, TabsList, TabsPanel, TabsTab, Title, Tooltip } from '@mantine/core';
|
import { ScrollArea, Stack, Tabs, TabsList, TabsPanel, TabsTab, Title, Tooltip } from '@mantine/core';
|
||||||
import { usePathname, useRouter } from 'next/navigation';
|
import { usePathname, useRouter } from 'next/navigation';
|
||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import { IconSchool, IconCalendar, IconBuildingCommunity } from '@tabler/icons-react';
|
import { IconSchool, IconCalendar, IconBuildingCommunity } from '@tabler/icons-react';
|
||||||
@@ -65,36 +65,38 @@ function LayoutTabs({ children }: { children: React.ReactNode }) {
|
|||||||
radius="lg"
|
radius="lg"
|
||||||
keepMounted={false}
|
keepMounted={false}
|
||||||
>
|
>
|
||||||
<TabsList
|
<ScrollArea type="auto" offsetScrollbars>
|
||||||
p="sm"
|
<TabsList
|
||||||
style={{
|
p="sm"
|
||||||
background: "linear-gradient(135deg, #e7ebf7, #f9faff)",
|
style={{
|
||||||
borderRadius: "1rem",
|
background: "linear-gradient(135deg, #e7ebf7, #f9faff)",
|
||||||
boxShadow: "inset 0 0 10px rgba(0,0,0,0.05)",
|
borderRadius: "1rem",
|
||||||
}}
|
boxShadow: "inset 0 0 10px rgba(0,0,0,0.05)",
|
||||||
>
|
}}
|
||||||
{tabs.map((tab, i) => (
|
>
|
||||||
<Tooltip
|
{tabs.map((tab, i) => (
|
||||||
key={i}
|
<Tooltip
|
||||||
label={tab.tooltip}
|
key={i}
|
||||||
position="bottom"
|
label={tab.tooltip}
|
||||||
withArrow
|
position="bottom"
|
||||||
transitionProps={{ transition: 'pop', duration: 200 }}
|
withArrow
|
||||||
>
|
transitionProps={{ transition: 'pop', duration: 200 }}
|
||||||
<TabsTab
|
|
||||||
value={tab.value}
|
|
||||||
leftSection={tab.icon}
|
|
||||||
style={{
|
|
||||||
fontWeight: 600,
|
|
||||||
fontSize: "0.9rem",
|
|
||||||
transition: "all 0.2s ease",
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
{tab.label}
|
<TabsTab
|
||||||
</TabsTab>
|
value={tab.value}
|
||||||
</Tooltip>
|
leftSection={tab.icon}
|
||||||
))}
|
style={{
|
||||||
</TabsList>
|
fontWeight: 600,
|
||||||
|
fontSize: "0.9rem",
|
||||||
|
transition: "all 0.2s ease",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{tab.label}
|
||||||
|
</TabsTab>
|
||||||
|
</Tooltip>
|
||||||
|
))}
|
||||||
|
</TabsList>
|
||||||
|
</ScrollArea>
|
||||||
|
|
||||||
{tabs.map((tab, i) => (
|
{tabs.map((tab, i) => (
|
||||||
<TabsPanel
|
<TabsPanel
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/* eslint-disable react-hooks/exhaustive-deps */
|
/* eslint-disable react-hooks/exhaustive-deps */
|
||||||
'use client'
|
'use client'
|
||||||
import colors from '@/con/colors';
|
import colors from '@/con/colors';
|
||||||
import { Stack, Tabs, TabsList, TabsPanel, TabsTab, Title, Tooltip } from '@mantine/core';
|
import { ScrollArea, Stack, Tabs, TabsList, TabsPanel, TabsTab, Title, Tooltip } from '@mantine/core';
|
||||||
import { IconBuilding, IconChalkboard, IconMicroscope, IconSchool } from '@tabler/icons-react';
|
import { IconBuilding, IconChalkboard, IconMicroscope, IconSchool } from '@tabler/icons-react';
|
||||||
import { usePathname, useRouter } from 'next/navigation';
|
import { usePathname, useRouter } from 'next/navigation';
|
||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
@@ -72,30 +72,32 @@ function LayoutTabs({ children }: { children: React.ReactNode }) {
|
|||||||
radius="lg"
|
radius="lg"
|
||||||
keepMounted={false}
|
keepMounted={false}
|
||||||
>
|
>
|
||||||
<TabsList
|
<ScrollArea type="auto" offsetScrollbars>
|
||||||
p="sm"
|
<TabsList
|
||||||
style={{
|
p="sm"
|
||||||
background: "linear-gradient(135deg, #e7ebf7, #f9faff)",
|
style={{
|
||||||
borderRadius: "1rem",
|
background: "linear-gradient(135deg, #e7ebf7, #f9faff)",
|
||||||
boxShadow: "inset 0 0 10px rgba(0,0,0,0.05)",
|
borderRadius: "1rem",
|
||||||
}}
|
boxShadow: "inset 0 0 10px rgba(0,0,0,0.05)",
|
||||||
>
|
}}
|
||||||
{tabs.map((tab, i) => (
|
>
|
||||||
<Tooltip key={i} label={tab.tooltip} position="bottom" withArrow transitionProps={{ transition: 'pop', duration: 200 }}>
|
{tabs.map((tab, i) => (
|
||||||
<TabsTab
|
<Tooltip key={i} label={tab.tooltip} position="bottom" withArrow transitionProps={{ transition: 'pop', duration: 200 }}>
|
||||||
value={tab.value}
|
<TabsTab
|
||||||
leftSection={tab.icon}
|
value={tab.value}
|
||||||
style={{
|
leftSection={tab.icon}
|
||||||
fontWeight: 600,
|
style={{
|
||||||
fontSize: "0.9rem",
|
fontWeight: 600,
|
||||||
transition: "all 0.2s ease",
|
fontSize: "0.9rem",
|
||||||
}}
|
transition: "all 0.2s ease",
|
||||||
>
|
}}
|
||||||
{tab.label}
|
>
|
||||||
</TabsTab>
|
{tab.label}
|
||||||
</Tooltip>
|
</TabsTab>
|
||||||
))}
|
</Tooltip>
|
||||||
</TabsList>
|
))}
|
||||||
|
</TabsList>
|
||||||
|
</ScrollArea>
|
||||||
|
|
||||||
{tabs.map((tab, i) => (
|
{tabs.map((tab, i) => (
|
||||||
<TabsPanel
|
<TabsPanel
|
||||||
@@ -106,6 +108,7 @@ function LayoutTabs({ children }: { children: React.ReactNode }) {
|
|||||||
background: "linear-gradient(180deg, #ffffff, #f5f6fa)",
|
background: "linear-gradient(180deg, #ffffff, #f5f6fa)",
|
||||||
borderRadius: "1rem",
|
borderRadius: "1rem",
|
||||||
boxShadow: "0 4px 16px rgba(0,0,0,0.05)",
|
boxShadow: "0 4px 16px rgba(0,0,0,0.05)",
|
||||||
|
minHeight: "60vh",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
@@ -121,4 +124,3 @@ export default LayoutTabs;
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
/* eslint-disable react-hooks/exhaustive-deps */
|
/* eslint-disable react-hooks/exhaustive-deps */
|
||||||
'use client'
|
'use client'
|
||||||
import colors from '@/con/colors';
|
import colors from '@/con/colors';
|
||||||
import { Stack, Tabs, TabsList, TabsPanel, TabsTab, Title, Tooltip } from '@mantine/core';
|
import { ScrollArea, Stack, Tabs, TabsList, TabsPanel, TabsTab, Title, Tooltip } from '@mantine/core';
|
||||||
import { usePathname, useRouter } from 'next/navigation';
|
import { usePathname, useRouter } from 'next/navigation';
|
||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import { IconSchool, IconMapPin, IconBook2 } from '@tabler/icons-react';
|
import { IconSchool, IconMapPin, IconBook2 } from '@tabler/icons-react';
|
||||||
@@ -66,36 +66,38 @@ function LayoutTabs({ children }: { children: React.ReactNode }) {
|
|||||||
radius="lg"
|
radius="lg"
|
||||||
keepMounted={false}
|
keepMounted={false}
|
||||||
>
|
>
|
||||||
<TabsList
|
<ScrollArea type="auto" offsetScrollbars>
|
||||||
p="sm"
|
<TabsList
|
||||||
style={{
|
p="sm"
|
||||||
background: "linear-gradient(135deg, #e7ebf7, #f9faff)",
|
style={{
|
||||||
borderRadius: "1rem",
|
background: "linear-gradient(135deg, #e7ebf7, #f9faff)",
|
||||||
boxShadow: "inset 0 0 10px rgba(0,0,0,0.05)",
|
borderRadius: "1rem",
|
||||||
}}
|
boxShadow: "inset 0 0 10px rgba(0,0,0,0.05)",
|
||||||
>
|
}}
|
||||||
{tabs.map((tab, i) => (
|
>
|
||||||
<Tooltip
|
{tabs.map((tab, i) => (
|
||||||
key={i}
|
<Tooltip
|
||||||
label={tab.tooltip}
|
key={i}
|
||||||
position="bottom"
|
label={tab.tooltip}
|
||||||
withArrow
|
position="bottom"
|
||||||
transitionProps={{ transition: 'pop', duration: 200 }}
|
withArrow
|
||||||
>
|
transitionProps={{ transition: 'pop', duration: 200 }}
|
||||||
<TabsTab
|
|
||||||
value={tab.value}
|
|
||||||
leftSection={tab.icon}
|
|
||||||
style={{
|
|
||||||
fontWeight: 600,
|
|
||||||
fontSize: "0.9rem",
|
|
||||||
transition: "all 0.2s ease",
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
{tab.label}
|
<TabsTab
|
||||||
</TabsTab>
|
value={tab.value}
|
||||||
</Tooltip>
|
leftSection={tab.icon}
|
||||||
))}
|
style={{
|
||||||
</TabsList>
|
fontWeight: 600,
|
||||||
|
fontSize: "0.9rem",
|
||||||
|
transition: "all 0.2s ease",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{tab.label}
|
||||||
|
</TabsTab>
|
||||||
|
</Tooltip>
|
||||||
|
))}
|
||||||
|
</TabsList>
|
||||||
|
</ScrollArea>
|
||||||
|
|
||||||
{tabs.map((tab, i) => (
|
{tabs.map((tab, i) => (
|
||||||
<TabsPanel
|
<TabsPanel
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/* eslint-disable react-hooks/exhaustive-deps */
|
/* eslint-disable react-hooks/exhaustive-deps */
|
||||||
'use client'
|
'use client'
|
||||||
import colors from '@/con/colors';
|
import colors from '@/con/colors';
|
||||||
import { Stack, Tabs, TabsList, TabsPanel, TabsTab, Title, Tooltip } from '@mantine/core';
|
import { ScrollArea, Stack, Tabs, TabsList, TabsPanel, TabsTab, Title, Tooltip } from '@mantine/core';
|
||||||
import { usePathname, useRouter } from 'next/navigation';
|
import { usePathname, useRouter } from 'next/navigation';
|
||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import { IconBook2, IconCategory } from '@tabler/icons-react';
|
import { IconBook2, IconCategory } from '@tabler/icons-react';
|
||||||
@@ -58,36 +58,38 @@ function LayoutTabs({ children }: { children: React.ReactNode }) {
|
|||||||
radius="lg"
|
radius="lg"
|
||||||
keepMounted={false}
|
keepMounted={false}
|
||||||
>
|
>
|
||||||
<TabsList
|
<ScrollArea type="auto" offsetScrollbars>
|
||||||
p="sm"
|
<TabsList
|
||||||
style={{
|
p="sm"
|
||||||
background: "linear-gradient(135deg, #e7ebf7, #f9faff)",
|
style={{
|
||||||
borderRadius: "1rem",
|
background: "linear-gradient(135deg, #e7ebf7, #f9faff)",
|
||||||
boxShadow: "inset 0 0 10px rgba(0,0,0,0.05)",
|
borderRadius: "1rem",
|
||||||
}}
|
boxShadow: "inset 0 0 10px rgba(0,0,0,0.05)",
|
||||||
>
|
}}
|
||||||
{tabs.map((tab, i) => (
|
>
|
||||||
<Tooltip
|
{tabs.map((tab, i) => (
|
||||||
key={i}
|
<Tooltip
|
||||||
label={tab.tooltip}
|
key={i}
|
||||||
position="bottom"
|
label={tab.tooltip}
|
||||||
withArrow
|
position="bottom"
|
||||||
transitionProps={{ transition: 'pop', duration: 200 }}
|
withArrow
|
||||||
>
|
transitionProps={{ transition: 'pop', duration: 200 }}
|
||||||
<TabsTab
|
|
||||||
value={tab.value}
|
|
||||||
leftSection={tab.icon}
|
|
||||||
style={{
|
|
||||||
fontWeight: 600,
|
|
||||||
fontSize: "0.9rem",
|
|
||||||
transition: "all 0.2s ease",
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
{tab.label}
|
<TabsTab
|
||||||
</TabsTab>
|
value={tab.value}
|
||||||
</Tooltip>
|
leftSection={tab.icon}
|
||||||
))}
|
style={{
|
||||||
</TabsList>
|
fontWeight: 600,
|
||||||
|
fontSize: "0.9rem",
|
||||||
|
transition: "all 0.2s ease",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{tab.label}
|
||||||
|
</TabsTab>
|
||||||
|
</Tooltip>
|
||||||
|
))}
|
||||||
|
</TabsList>
|
||||||
|
</ScrollArea>
|
||||||
|
|
||||||
{tabs.map((tab, i) => (
|
{tabs.map((tab, i) => (
|
||||||
<TabsPanel
|
<TabsPanel
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/* eslint-disable react-hooks/exhaustive-deps */
|
/* eslint-disable react-hooks/exhaustive-deps */
|
||||||
'use client'
|
'use client'
|
||||||
import colors from '@/con/colors';
|
import colors from '@/con/colors';
|
||||||
import { Stack, Tabs, TabsList, TabsPanel, TabsTab, Title, Tooltip } from '@mantine/core';
|
import { ScrollArea, Stack, Tabs, TabsList, TabsPanel, TabsTab, Title, Tooltip } from '@mantine/core';
|
||||||
import { usePathname, useRouter } from 'next/navigation';
|
import { usePathname, useRouter } from 'next/navigation';
|
||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import { IconSchool, IconTarget } from '@tabler/icons-react';
|
import { IconSchool, IconTarget } from '@tabler/icons-react';
|
||||||
@@ -11,13 +11,6 @@ function LayoutTabs({ children }: { children: React.ReactNode }) {
|
|||||||
const pathname = usePathname();
|
const pathname = usePathname();
|
||||||
|
|
||||||
const tabs = [
|
const tabs = [
|
||||||
{
|
|
||||||
label: "Program Unggulan",
|
|
||||||
value: "program-unggulan",
|
|
||||||
href: "/admin/pendidikan/program-pendidikan-anak/program-unggulan",
|
|
||||||
icon: <IconSchool size={18} stroke={1.8} />,
|
|
||||||
tooltip: "Lihat dan kelola program unggulan pendidikan anak",
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
label: "Tujuan Program",
|
label: "Tujuan Program",
|
||||||
value: "tujuan-program",
|
value: "tujuan-program",
|
||||||
@@ -25,6 +18,13 @@ function LayoutTabs({ children }: { children: React.ReactNode }) {
|
|||||||
icon: <IconTarget size={18} stroke={1.8} />,
|
icon: <IconTarget size={18} stroke={1.8} />,
|
||||||
tooltip: "Atur tujuan program pendidikan anak",
|
tooltip: "Atur tujuan program pendidikan anak",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
label: "Program Unggulan",
|
||||||
|
value: "program-unggulan",
|
||||||
|
href: "/admin/pendidikan/program-pendidikan-anak/program-unggulan",
|
||||||
|
icon: <IconSchool size={18} stroke={1.8} />,
|
||||||
|
tooltip: "Lihat dan kelola program unggulan pendidikan anak",
|
||||||
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
const currentTab = tabs.find(tab => tab.href === pathname);
|
const currentTab = tabs.find(tab => tab.href === pathname);
|
||||||
@@ -59,36 +59,38 @@ function LayoutTabs({ children }: { children: React.ReactNode }) {
|
|||||||
radius="lg"
|
radius="lg"
|
||||||
keepMounted={false}
|
keepMounted={false}
|
||||||
>
|
>
|
||||||
<TabsList
|
<ScrollArea type="auto" offsetScrollbars>
|
||||||
p="sm"
|
<TabsList
|
||||||
style={{
|
p="sm"
|
||||||
background: "linear-gradient(135deg, #e7ebf7, #f9faff)",
|
style={{
|
||||||
borderRadius: "1rem",
|
background: "linear-gradient(135deg, #e7ebf7, #f9faff)",
|
||||||
boxShadow: "inset 0 0 10px rgba(0,0,0,0.05)",
|
borderRadius: "1rem",
|
||||||
}}
|
boxShadow: "inset 0 0 10px rgba(0,0,0,0.05)",
|
||||||
>
|
}}
|
||||||
{tabs.map((tab, i) => (
|
>
|
||||||
<Tooltip
|
{tabs.map((tab, i) => (
|
||||||
key={i}
|
<Tooltip
|
||||||
label={tab.tooltip}
|
key={i}
|
||||||
position="bottom"
|
label={tab.tooltip}
|
||||||
withArrow
|
position="bottom"
|
||||||
transitionProps={{ transition: 'pop', duration: 200 }}
|
withArrow
|
||||||
>
|
transitionProps={{ transition: 'pop', duration: 200 }}
|
||||||
<TabsTab
|
|
||||||
value={tab.value}
|
|
||||||
leftSection={tab.icon}
|
|
||||||
style={{
|
|
||||||
fontWeight: 600,
|
|
||||||
fontSize: "0.9rem",
|
|
||||||
transition: "all 0.2s ease",
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
{tab.label}
|
<TabsTab
|
||||||
</TabsTab>
|
value={tab.value}
|
||||||
</Tooltip>
|
leftSection={tab.icon}
|
||||||
))}
|
style={{
|
||||||
</TabsList>
|
fontWeight: 600,
|
||||||
|
fontSize: "0.9rem",
|
||||||
|
transition: "all 0.2s ease",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{tab.label}
|
||||||
|
</TabsTab>
|
||||||
|
</Tooltip>
|
||||||
|
))}
|
||||||
|
</TabsList>
|
||||||
|
</ScrollArea>
|
||||||
|
|
||||||
{tabs.map((tab, i) => (
|
{tabs.map((tab, i) => (
|
||||||
<TabsPanel
|
<TabsPanel
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
'use client'
|
'use client'
|
||||||
import beasiswaDesaState from '@/app/admin/(dashboard)/_state/pendidikan/beasiswa-desa';
|
import beasiswaDesaState from '@/app/admin/(dashboard)/_state/pendidikan/beasiswa-desa';
|
||||||
import colors from '@/con/colors';
|
import colors from '@/con/colors';
|
||||||
import { Box, Button, Center, Group, Image, Modal, Paper, Select, SimpleGrid, Stack, Stepper, StepperStep, Text, TextInput, Title } from '@mantine/core';
|
import { Box, Button, Center, Group, Image, Modal, Pagination, Paper, Select, SimpleGrid, Skeleton, Stack, Stepper, StepperStep, Text, TextInput, Title } from '@mantine/core';
|
||||||
import { useDisclosure } from '@mantine/hooks';
|
import { useDisclosure, useShallowEffect } from '@mantine/hooks';
|
||||||
import { IconArrowRight, IconCoin, IconInfoCircle, IconSchool, IconUsers } from '@tabler/icons-react';
|
import { IconArrowRight, IconCoin, IconInfoCircle, IconSchool, IconUsers } from '@tabler/icons-react';
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { useProxy } from 'valtio/utils';
|
import { useProxy } from 'valtio/utils';
|
||||||
import BackButton from '../../desa/layanan/_com/BackButto';
|
import BackButton from '../../desa/layanan/_com/BackButto';
|
||||||
|
import { useTransitionRouter } from 'next-view-transitions';
|
||||||
|
|
||||||
const dataBeasiswa = [
|
const dataBeasiswa = [
|
||||||
{ id: 1, nama: 'Penerima Beasiswa', jumlah: '250+', icon: IconUsers },
|
{ id: 1, nama: 'Penerima Beasiswa', jumlah: '250+', icon: IconUsers },
|
||||||
@@ -14,15 +15,11 @@ const dataBeasiswa = [
|
|||||||
{ id: 3, nama: 'Dana Tersalurkan', jumlah: '1.5M', icon: IconCoin },
|
{ id: 3, nama: 'Dana Tersalurkan', jumlah: '1.5M', icon: IconCoin },
|
||||||
];
|
];
|
||||||
|
|
||||||
const dataProgram = [
|
|
||||||
{ id: 1, judul: "Pelatihan SoftSkill", deskripsi: "Pengembangan diri untuk mempersiapkan karir masa depan." },
|
|
||||||
{ id: 2, judul: "Peningkatan Akses Pendidikan", deskripsi: "Memberi kesempatan bagi masyarakat kurang mampu untuk tetap sekolah." },
|
|
||||||
{ id: 3, judul: "Pendampingan Intensif", deskripsi: "Bimbingan dari mentor berpengalaman untuk mendukung akademik." },
|
|
||||||
];
|
|
||||||
|
|
||||||
function Page() {
|
function Page() {
|
||||||
const beasiswaDesa = useProxy(beasiswaDesaState.beasiswaPendaftar)
|
const beasiswaDesa = useProxy(beasiswaDesaState.beasiswaPendaftar)
|
||||||
|
const ungggulanDesa = useProxy(beasiswaDesaState.keunggulanProgram)
|
||||||
const [opened, { open, close }] = useDisclosure(false);
|
const [opened, { open, close }] = useDisclosure(false);
|
||||||
|
const router = useTransitionRouter()
|
||||||
const resetForm = () => {
|
const resetForm = () => {
|
||||||
beasiswaDesa.create.form = {
|
beasiswaDesa.create.form = {
|
||||||
namaLengkap: "",
|
namaLengkap: "",
|
||||||
@@ -41,6 +38,12 @@ function Page() {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const { data, page, totalPages, loading, load } = ungggulanDesa.findMany;
|
||||||
|
|
||||||
|
useShallowEffect(() => {
|
||||||
|
load(page, 3, "");
|
||||||
|
}, [page])
|
||||||
|
|
||||||
const handleSubmit = async () => {
|
const handleSubmit = async () => {
|
||||||
await beasiswaDesa.create.create();
|
await beasiswaDesa.create.create();
|
||||||
resetForm();
|
resetForm();
|
||||||
@@ -51,6 +54,14 @@ function Page() {
|
|||||||
const nextStep = () => setActive((current) => (current < 5 ? current + 1 : current));
|
const nextStep = () => setActive((current) => (current < 5 ? current + 1 : current));
|
||||||
const prevStep = () => setActive((current) => (current > 0 ? current - 1 : current));
|
const prevStep = () => setActive((current) => (current > 0 ? current - 1 : current));
|
||||||
|
|
||||||
|
if (loading || !data) {
|
||||||
|
return (
|
||||||
|
<Stack py={10}>
|
||||||
|
<Skeleton height={200} radius="md" />
|
||||||
|
</Stack>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Stack pos="relative" bg={colors.Bg} py="xl" gap={40}>
|
<Stack pos="relative" bg={colors.Bg} py="xl" gap={40}>
|
||||||
<Box px={{ base: 'md', md: 100 }}>
|
<Box px={{ base: 'md', md: 100 }}>
|
||||||
@@ -70,13 +81,13 @@ function Page() {
|
|||||||
<Button size="lg" radius="xl" bg={colors['blue-button']} rightSection={<IconArrowRight size={20} />} onClick={open}>
|
<Button size="lg" radius="xl" bg={colors['blue-button']} rightSection={<IconArrowRight size={20} />} onClick={open}>
|
||||||
Daftar Sekarang
|
Daftar Sekarang
|
||||||
</Button>
|
</Button>
|
||||||
<Button size="lg" radius="xl" variant="light" color={colors['blue-button']} rightSection={<IconInfoCircle size={20} />}>
|
<Button onClick={() => router.push('/darmasaba/pendidikan/beasiswa-desa/pelajari-lebih-lanjut')} size="lg" radius="xl" variant="light" color={colors['blue-button']} rightSection={<IconInfoCircle size={20} />}>
|
||||||
Pelajari Lebih Lanjut
|
Pelajari Lebih Lanjut
|
||||||
</Button>
|
</Button>
|
||||||
</Group>
|
</Group>
|
||||||
</Box>
|
</Box>
|
||||||
<Box>
|
<Box>
|
||||||
<Image alt="Beasiswa Desa" src="/beasiswa-siswa.png" radius="lg" loading="lazy"/>
|
<Image alt="Beasiswa Desa" src="/beasiswa-siswa.png" radius="lg" loading="lazy" />
|
||||||
</Box>
|
</Box>
|
||||||
</SimpleGrid>
|
</SimpleGrid>
|
||||||
|
|
||||||
@@ -101,14 +112,29 @@ function Page() {
|
|||||||
Keunggulan Program
|
Keunggulan Program
|
||||||
</Title>
|
</Title>
|
||||||
<SimpleGrid cols={{ base: 1, md: 3 }} spacing="lg">
|
<SimpleGrid cols={{ base: 1, md: 3 }} spacing="lg">
|
||||||
{dataProgram.map((v, k) => (
|
{data.map((v, k) => (
|
||||||
<Paper key={k} p="xl" radius="xl" shadow="sm" bg={colors['white-trans-1']}>
|
<Paper key={k} p="xl" radius="xl" shadow="sm" bg={colors['white-trans-1']}>
|
||||||
<Title order={3} fw={700} c={colors['blue-button']} mb="xs">{v.judul}</Title>
|
<Title order={3} fw={700} c={colors['blue-button']} mb="xs">{v.judul}</Title>
|
||||||
<Text fz="sm" c="dimmed">{v.deskripsi}</Text>
|
<Text fz="sm" c="dimmed" style={{ wordBreak: "break-word", whiteSpace: "normal" }} dangerouslySetInnerHTML={{ __html: v.deskripsi }}/>
|
||||||
</Paper>
|
</Paper>
|
||||||
))}
|
))}
|
||||||
</SimpleGrid>
|
</SimpleGrid>
|
||||||
|
|
||||||
|
<Center>
|
||||||
|
<Pagination
|
||||||
|
value={page}
|
||||||
|
onChange={(newPage) => {
|
||||||
|
load(newPage, 10);
|
||||||
|
window.scrollTo({ top: 0, behavior: 'smooth' });
|
||||||
|
}}
|
||||||
|
total={totalPages}
|
||||||
|
mt="md"
|
||||||
|
mb="md"
|
||||||
|
color="blue"
|
||||||
|
radius="md"
|
||||||
|
/>
|
||||||
|
</Center>
|
||||||
|
|
||||||
<Title py={40} ta="center" order={1} fw={900} c={colors['blue-button']}>
|
<Title py={40} ta="center" order={1} fw={900} c={colors['blue-button']}>
|
||||||
Timeline Pendaftaran
|
Timeline Pendaftaran
|
||||||
</Title>
|
</Title>
|
||||||
@@ -142,66 +168,66 @@ function Page() {
|
|||||||
>
|
>
|
||||||
<Paper p="lg" radius="xl" withBorder shadow="sm">
|
<Paper p="lg" radius="xl" withBorder shadow="sm">
|
||||||
<Stack gap="sm">
|
<Stack gap="sm">
|
||||||
<TextInput
|
<TextInput
|
||||||
label="Nama Lengkap"
|
label="Nama Lengkap"
|
||||||
placeholder="Masukkan nama lengkap"
|
placeholder="Masukkan nama lengkap"
|
||||||
onChange={(val) => { beasiswaDesa.create.form.namaLengkap = val.target.value }} />
|
onChange={(val) => { beasiswaDesa.create.form.namaLengkap = val.target.value }} />
|
||||||
<TextInput
|
<TextInput
|
||||||
type="number"
|
type="number"
|
||||||
label="NIK"
|
label="NIK"
|
||||||
placeholder="Masukkan NIK"
|
placeholder="Masukkan NIK"
|
||||||
onChange={(val) => { beasiswaDesa.create.form.nik = val.target.value }} />
|
onChange={(val) => { beasiswaDesa.create.form.nik = val.target.value }} />
|
||||||
<TextInput
|
<TextInput
|
||||||
label="Tempat Lahir"
|
label="Tempat Lahir"
|
||||||
placeholder="Masukkan tempat lahir"
|
placeholder="Masukkan tempat lahir"
|
||||||
onChange={(val) => { beasiswaDesa.create.form.tempatLahir = val.target.value }} />
|
onChange={(val) => { beasiswaDesa.create.form.tempatLahir = val.target.value }} />
|
||||||
<TextInput
|
<TextInput
|
||||||
type="date"
|
type="date"
|
||||||
label="Tanggal Lahir"
|
label="Tanggal Lahir"
|
||||||
placeholder="Pilih tanggal lahir"
|
placeholder="Pilih tanggal lahir"
|
||||||
onChange={(val) => { beasiswaDesa.create.form.tanggalLahir = val.target.value }} />
|
onChange={(val) => { beasiswaDesa.create.form.tanggalLahir = val.target.value }} />
|
||||||
<Select
|
<Select
|
||||||
label="Jenis Kelamin"
|
label="Jenis Kelamin"
|
||||||
placeholder="Pilih jenis kelamin"
|
placeholder="Pilih jenis kelamin"
|
||||||
data={[{ value: "LAKI_LAKI", label: "Laki-laki" }, { value: "PEREMPUAN", label: "Perempuan" }]}
|
data={[{ value: "LAKI_LAKI", label: "Laki-laki" }, { value: "PEREMPUAN", label: "Perempuan" }]}
|
||||||
onChange={(val) => { if (val) beasiswaDesa.create.form.jenisKelamin = val }} />
|
onChange={(val) => { if (val) beasiswaDesa.create.form.jenisKelamin = val }} />
|
||||||
<TextInput
|
<TextInput
|
||||||
label="Kewarganegaraan"
|
label="Kewarganegaraan"
|
||||||
placeholder="Masukkan kewarganegaraan"
|
placeholder="Masukkan kewarganegaraan"
|
||||||
onChange={(val) => { beasiswaDesa.create.form.kewarganegaraan = val.target.value }} />
|
onChange={(val) => { beasiswaDesa.create.form.kewarganegaraan = val.target.value }} />
|
||||||
<Select
|
<Select
|
||||||
label="Agama"
|
label="Agama"
|
||||||
placeholder="Pilih agama"
|
placeholder="Pilih agama"
|
||||||
data={[{ value: "ISLAM", label: "Islam" }, { value: "KRISTEN_PROTESTAN", label: "Kristen Protestan" }, { value: "KRISTEN_KATOLIK", label: "Kristen Katolik" }, { value: "HINDU", label: "Hindu" }, { value: "BUDDHA", label: "Buddha" }, { value: "KONGHUCU", label: "Konghucu" }, { value: "LAINNYA", label: "Lainnya" }]}
|
data={[{ value: "ISLAM", label: "Islam" }, { value: "KRISTEN_PROTESTAN", label: "Kristen Protestan" }, { value: "KRISTEN_KATOLIK", label: "Kristen Katolik" }, { value: "HINDU", label: "Hindu" }, { value: "BUDDHA", label: "Buddha" }, { value: "KONGHUCU", label: "Konghucu" }, { value: "LAINNYA", label: "Lainnya" }]}
|
||||||
onChange={(val) => { if (val) beasiswaDesa.create.form.agama = val }} />
|
onChange={(val) => { if (val) beasiswaDesa.create.form.agama = val }} />
|
||||||
<TextInput
|
<TextInput
|
||||||
label="Alamat KTP"
|
label="Alamat KTP"
|
||||||
placeholder="Masukkan alamat sesuai KTP"
|
placeholder="Masukkan alamat sesuai KTP"
|
||||||
onChange={(val) => { beasiswaDesa.create.form.alamatKTP = val.target.value }} />
|
onChange={(val) => { beasiswaDesa.create.form.alamatKTP = val.target.value }} />
|
||||||
<TextInput
|
<TextInput
|
||||||
label="Alamat Domisili"
|
label="Alamat Domisili"
|
||||||
placeholder="Masukkan alamat domisili"
|
placeholder="Masukkan alamat domisili"
|
||||||
onChange={(val) => { beasiswaDesa.create.form.alamatDomisili = val.target.value }} />
|
onChange={(val) => { beasiswaDesa.create.form.alamatDomisili = val.target.value }} />
|
||||||
<TextInput
|
<TextInput
|
||||||
type="number"
|
type="number"
|
||||||
label="Nomor HP"
|
label="Nomor HP"
|
||||||
placeholder="Masukkan nomor HP"
|
placeholder="Masukkan nomor HP"
|
||||||
onChange={(val) => { beasiswaDesa.create.form.noHp = val.target.value }} />
|
onChange={(val) => { beasiswaDesa.create.form.noHp = val.target.value }} />
|
||||||
<TextInput
|
<TextInput
|
||||||
type="email"
|
type="email"
|
||||||
label="Email"
|
label="Email"
|
||||||
placeholder="Masukkan alamat email"
|
placeholder="Masukkan alamat email"
|
||||||
onChange={(val) => { beasiswaDesa.create.form.email = val.target.value }} />
|
onChange={(val) => { beasiswaDesa.create.form.email = val.target.value }} />
|
||||||
<Select
|
<Select
|
||||||
label="Status Pernikahan"
|
label="Status Pernikahan"
|
||||||
placeholder="Pilih status pernikahan"
|
placeholder="Pilih status pernikahan"
|
||||||
data={[{ value: "BELUM_MENIKAH", label: "Belum Menikah" }, { value: "MENIKAH", label: "Menikah" }, { value: "JANDA_DUDA", label: "Janda/Duda" }]}
|
data={[{ value: "BELUM_MENIKAH", label: "Belum Menikah" }, { value: "MENIKAH", label: "Menikah" }, { value: "JANDA_DUDA", label: "Janda/Duda" }]}
|
||||||
onChange={(val) => { if (val) beasiswaDesa.create.form.statusPernikahan = val }} />
|
onChange={(val) => { if (val) beasiswaDesa.create.form.statusPernikahan = val }} />
|
||||||
<Select
|
<Select
|
||||||
label="Ukuran Baju"
|
label="Ukuran Baju"
|
||||||
placeholder="Pilih ukuran baju"
|
placeholder="Pilih ukuran baju"
|
||||||
data={[{ value: "S", label: "S" }, { value: "M", label: "M" }, { value: "L", label: "L" }, { value: "XL", label: "XL" }, { value: "XXL", label: "XXL" }, { value: "LAINNYA", label: "Lainnya" }]}
|
data={[{ value: "S", label: "S" }, { value: "M", label: "M" }, { value: "L", label: "L" }, { value: "XL", label: "XL" }, { value: "XXL", label: "XXL" }, { value: "LAINNYA", label: "Lainnya" }]}
|
||||||
onChange={(val) => { if (val) beasiswaDesa.create.form.ukuranBaju = val }} />
|
onChange={(val) => { if (val) beasiswaDesa.create.form.ukuranBaju = val }} />
|
||||||
<Group justify="flex-end" mt="md">
|
<Group justify="flex-end" mt="md">
|
||||||
<Button variant="default" radius="xl" onClick={close}>Batal</Button>
|
<Button variant="default" radius="xl" onClick={close}>Batal</Button>
|
||||||
<Button radius="xl" bg={colors['blue-button']} onClick={handleSubmit}>Kirim</Button>
|
<Button radius="xl" bg={colors['blue-button']} onClick={handleSubmit}>Kirim</Button>
|
||||||
|
|||||||
@@ -0,0 +1,278 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import {
|
||||||
|
Box,
|
||||||
|
Button,
|
||||||
|
Container,
|
||||||
|
Group,
|
||||||
|
Modal,
|
||||||
|
Paper,
|
||||||
|
Select,
|
||||||
|
SimpleGrid,
|
||||||
|
Stack,
|
||||||
|
Text,
|
||||||
|
TextInput,
|
||||||
|
Timeline,
|
||||||
|
Title
|
||||||
|
} from '@mantine/core';
|
||||||
|
import { IconArrowLeft } from '@tabler/icons-react';
|
||||||
|
import { useRouter } from 'next/navigation';
|
||||||
|
import { useDisclosure } from '@mantine/hooks';
|
||||||
|
import { useProxy } from 'valtio/utils';
|
||||||
|
import beasiswaDesaState from '@/app/admin/(dashboard)/_state/pendidikan/beasiswa-desa';
|
||||||
|
import colors from '@/con/colors';
|
||||||
|
|
||||||
|
|
||||||
|
export default function BeasiswaPage() {
|
||||||
|
const router = useRouter();
|
||||||
|
const beasiswaDesa = useProxy(beasiswaDesaState.beasiswaPendaftar)
|
||||||
|
const [opened, { open, close }] = useDisclosure(false);
|
||||||
|
const resetForm = () => {
|
||||||
|
beasiswaDesa.create.form = {
|
||||||
|
namaLengkap: "",
|
||||||
|
nik: "",
|
||||||
|
tempatLahir: "",
|
||||||
|
tanggalLahir: "",
|
||||||
|
jenisKelamin: "",
|
||||||
|
kewarganegaraan: "",
|
||||||
|
agama: "",
|
||||||
|
alamatKTP: "",
|
||||||
|
alamatDomisili: "",
|
||||||
|
noHp: "",
|
||||||
|
email: "",
|
||||||
|
statusPernikahan: "",
|
||||||
|
ukuranBaju: "",
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSubmit = async () => {
|
||||||
|
await beasiswaDesa.create.create();
|
||||||
|
resetForm();
|
||||||
|
close();
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box bg="#f1f5fb" pb="xl" pt="md">
|
||||||
|
{/* Tombol Kembali */}
|
||||||
|
<Container size="lg">
|
||||||
|
<Button
|
||||||
|
variant="subtle"
|
||||||
|
color="blue"
|
||||||
|
leftSection={<IconArrowLeft size={18} />}
|
||||||
|
onClick={() => router.back()}
|
||||||
|
mb="lg"
|
||||||
|
>
|
||||||
|
Kembali
|
||||||
|
</Button>
|
||||||
|
</Container>
|
||||||
|
|
||||||
|
{/* Hero Section */}
|
||||||
|
<Container size="lg" py="xl">
|
||||||
|
<Stack gap="md" maw={600}>
|
||||||
|
<Title order={2} c="blue.9">
|
||||||
|
Program Beasiswa Pendidikan Desa Darmasaba
|
||||||
|
</Title>
|
||||||
|
<Text c="dimmed">
|
||||||
|
Program ini bertujuan untuk mendukung pendidikan generasi muda di Desa Darmasaba
|
||||||
|
agar dapat melanjutkan studi ke jenjang lebih tinggi dengan dukungan finansial dan pendampingan.
|
||||||
|
</Text>
|
||||||
|
</Stack>
|
||||||
|
</Container>
|
||||||
|
|
||||||
|
{/* Tentang Program */}
|
||||||
|
<Container size="lg" py="xl">
|
||||||
|
<Title order={3} mb="sm">
|
||||||
|
Tentang Program
|
||||||
|
</Title>
|
||||||
|
<Text>
|
||||||
|
Program Beasiswa Desa Darmasaba adalah inisiatif pemerintah desa untuk meningkatkan akses
|
||||||
|
pendidikan bagi siswa berprestasi dan kurang mampu. Melalui program ini, desa memberikan bantuan
|
||||||
|
biaya sekolah, bimbingan akademik, serta pelatihan soft skill bagi peserta terpilih.
|
||||||
|
</Text>
|
||||||
|
</Container>
|
||||||
|
|
||||||
|
{/* Syarat dan Ketentuan */}
|
||||||
|
<Container size="lg" py="xl">
|
||||||
|
<Title order={3} mb="sm">
|
||||||
|
Syarat Pendaftaran
|
||||||
|
</Title>
|
||||||
|
|
||||||
|
<SimpleGrid cols={{ base: 1, sm: 2, md: 3 }} spacing="lg">
|
||||||
|
<Paper shadow="sm" p="md" radius="lg" withBorder>
|
||||||
|
<Text fw={500}>Domisili Desa Darmasaba</Text>
|
||||||
|
<Text c="dimmed" fz="sm">
|
||||||
|
Peserta harus merupakan warga desa yang berdomisili minimal 2 tahun.
|
||||||
|
</Text>
|
||||||
|
</Paper>
|
||||||
|
|
||||||
|
<Paper shadow="sm" p="md" radius="lg" withBorder>
|
||||||
|
<Text fw={500}>Nilai Akademik</Text>
|
||||||
|
<Text c="dimmed" fz="sm">
|
||||||
|
Rata-rata nilai raport minimal 80 atau setara.
|
||||||
|
</Text>
|
||||||
|
</Paper>
|
||||||
|
|
||||||
|
<Paper shadow="sm" p="md" radius="lg" withBorder>
|
||||||
|
<Text fw={500}>Surat Rekomendasi</Text>
|
||||||
|
<Text c="dimmed" fz="sm">
|
||||||
|
Diperlukan surat rekomendasi dari sekolah atau guru wali kelas.
|
||||||
|
</Text>
|
||||||
|
</Paper>
|
||||||
|
</SimpleGrid>
|
||||||
|
</Container>
|
||||||
|
|
||||||
|
{/* Proses Seleksi */}
|
||||||
|
<Container size="lg" py="xl">
|
||||||
|
<Title order={3} mb="sm">
|
||||||
|
Proses Seleksi
|
||||||
|
</Title>
|
||||||
|
|
||||||
|
<Timeline active={4} bulletSize={24} lineWidth={2}>
|
||||||
|
<Timeline.Item title="Pendaftaran Online">
|
||||||
|
<Text c="dimmed" size="sm">
|
||||||
|
Calon peserta mengisi formulir pendaftaran dan mengunggah dokumen pendukung.
|
||||||
|
</Text>
|
||||||
|
</Timeline.Item>
|
||||||
|
|
||||||
|
<Timeline.Item title="Seleksi Administrasi">
|
||||||
|
<Text c="dimmed" size="sm">
|
||||||
|
Panitia memverifikasi kelengkapan dan validitas berkas.
|
||||||
|
</Text>
|
||||||
|
</Timeline.Item>
|
||||||
|
|
||||||
|
<Timeline.Item title="Wawancara dan Penilaian">
|
||||||
|
<Text c="dimmed" size="sm">
|
||||||
|
Peserta yang lolos administrasi akan diundang untuk wawancara langsung dengan tim seleksi.
|
||||||
|
</Text>
|
||||||
|
</Timeline.Item>
|
||||||
|
|
||||||
|
<Timeline.Item title="Pengumuman Penerima">
|
||||||
|
<Text c="dimmed" size="sm">
|
||||||
|
Daftar penerima beasiswa diumumkan melalui website resmi Desa Darmasaba.
|
||||||
|
</Text>
|
||||||
|
</Timeline.Item>
|
||||||
|
</Timeline>
|
||||||
|
</Container>
|
||||||
|
|
||||||
|
{/* Testimoni */}
|
||||||
|
<Container size="lg" py="xl">
|
||||||
|
<Title order={3} mb="sm">
|
||||||
|
Cerita Sukses Penerima Beasiswa
|
||||||
|
</Title>
|
||||||
|
|
||||||
|
<SimpleGrid cols={{ base: 1, sm: 2 }} spacing="lg">
|
||||||
|
<Paper shadow="md" p="lg" radius="lg">
|
||||||
|
<Text fs={'italic'}>
|
||||||
|
“Program ini sangat membantu saya melanjutkan kuliah di Universitas Udayana. Terima kasih Desa Darmasaba!”
|
||||||
|
</Text>
|
||||||
|
<Text mt="sm" fw={600}>
|
||||||
|
– Ni Kadek Ayu S., Penerima Beasiswa 2024
|
||||||
|
</Text>
|
||||||
|
</Paper>
|
||||||
|
|
||||||
|
<Paper shadow="md" p="lg" radius="lg">
|
||||||
|
<Text fs={'italic'}>
|
||||||
|
“Selain bantuan dana, kami juga mendapatkan pelatihan komputer dan bahasa Inggris.”
|
||||||
|
</Text>
|
||||||
|
<Text mt="sm" fw={600}>
|
||||||
|
– I Made Gede A., Penerima Beasiswa 2023
|
||||||
|
</Text>
|
||||||
|
</Paper>
|
||||||
|
</SimpleGrid>
|
||||||
|
</Container>
|
||||||
|
|
||||||
|
{/* CTA Akhir */}
|
||||||
|
<Container size="lg" py="xl" ta="center">
|
||||||
|
<Title order={3}>Siap Bergabung dengan Program Ini?</Title>
|
||||||
|
<Text c="dimmed" mb="md">
|
||||||
|
Segera daftar dan wujudkan mimpimu bersama Desa Darmasaba.
|
||||||
|
</Text>
|
||||||
|
<Button onClick={open} size="lg" radius="xl" color="blue">
|
||||||
|
Daftar Sekarang
|
||||||
|
</Button>
|
||||||
|
</Container>
|
||||||
|
|
||||||
|
<Modal
|
||||||
|
opened={opened}
|
||||||
|
onClose={close}
|
||||||
|
radius="xl"
|
||||||
|
size="lg"
|
||||||
|
transitionProps={{ transition: 'fade', duration: 200 }}
|
||||||
|
title={
|
||||||
|
<Text fz="xl" fw={800} c={colors['blue-button']}>
|
||||||
|
Formulir Beasiswa
|
||||||
|
</Text>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Paper p="lg" radius="xl" withBorder shadow="sm">
|
||||||
|
<Stack gap="sm">
|
||||||
|
<TextInput
|
||||||
|
label="Nama Lengkap"
|
||||||
|
placeholder="Masukkan nama lengkap"
|
||||||
|
onChange={(val) => { beasiswaDesa.create.form.namaLengkap = val.target.value }} />
|
||||||
|
<TextInput
|
||||||
|
type="number"
|
||||||
|
label="NIK"
|
||||||
|
placeholder="Masukkan NIK"
|
||||||
|
onChange={(val) => { beasiswaDesa.create.form.nik = val.target.value }} />
|
||||||
|
<TextInput
|
||||||
|
label="Tempat Lahir"
|
||||||
|
placeholder="Masukkan tempat lahir"
|
||||||
|
onChange={(val) => { beasiswaDesa.create.form.tempatLahir = val.target.value }} />
|
||||||
|
<TextInput
|
||||||
|
type="date"
|
||||||
|
label="Tanggal Lahir"
|
||||||
|
placeholder="Pilih tanggal lahir"
|
||||||
|
onChange={(val) => { beasiswaDesa.create.form.tanggalLahir = val.target.value }} />
|
||||||
|
<Select
|
||||||
|
label="Jenis Kelamin"
|
||||||
|
placeholder="Pilih jenis kelamin"
|
||||||
|
data={[{ value: "LAKI_LAKI", label: "Laki-laki" }, { value: "PEREMPUAN", label: "Perempuan" }]}
|
||||||
|
onChange={(val) => { if (val) beasiswaDesa.create.form.jenisKelamin = val }} />
|
||||||
|
<TextInput
|
||||||
|
label="Kewarganegaraan"
|
||||||
|
placeholder="Masukkan kewarganegaraan"
|
||||||
|
onChange={(val) => { beasiswaDesa.create.form.kewarganegaraan = val.target.value }} />
|
||||||
|
<Select
|
||||||
|
label="Agama"
|
||||||
|
placeholder="Pilih agama"
|
||||||
|
data={[{ value: "ISLAM", label: "Islam" }, { value: "KRISTEN_PROTESTAN", label: "Kristen Protestan" }, { value: "KRISTEN_KATOLIK", label: "Kristen Katolik" }, { value: "HINDU", label: "Hindu" }, { value: "BUDDHA", label: "Buddha" }, { value: "KONGHUCU", label: "Konghucu" }, { value: "LAINNYA", label: "Lainnya" }]}
|
||||||
|
onChange={(val) => { if (val) beasiswaDesa.create.form.agama = val }} />
|
||||||
|
<TextInput
|
||||||
|
label="Alamat KTP"
|
||||||
|
placeholder="Masukkan alamat sesuai KTP"
|
||||||
|
onChange={(val) => { beasiswaDesa.create.form.alamatKTP = val.target.value }} />
|
||||||
|
<TextInput
|
||||||
|
label="Alamat Domisili"
|
||||||
|
placeholder="Masukkan alamat domisili"
|
||||||
|
onChange={(val) => { beasiswaDesa.create.form.alamatDomisili = val.target.value }} />
|
||||||
|
<TextInput
|
||||||
|
type="number"
|
||||||
|
label="Nomor HP"
|
||||||
|
placeholder="Masukkan nomor HP"
|
||||||
|
onChange={(val) => { beasiswaDesa.create.form.noHp = val.target.value }} />
|
||||||
|
<TextInput
|
||||||
|
type="email"
|
||||||
|
label="Email"
|
||||||
|
placeholder="Masukkan alamat email"
|
||||||
|
onChange={(val) => { beasiswaDesa.create.form.email = val.target.value }} />
|
||||||
|
<Select
|
||||||
|
label="Status Pernikahan"
|
||||||
|
placeholder="Pilih status pernikahan"
|
||||||
|
data={[{ value: "BELUM_MENIKAH", label: "Belum Menikah" }, { value: "MENIKAH", label: "Menikah" }, { value: "JANDA_DUDA", label: "Janda/Duda" }]}
|
||||||
|
onChange={(val) => { if (val) beasiswaDesa.create.form.statusPernikahan = val }} />
|
||||||
|
<Select
|
||||||
|
label="Ukuran Baju"
|
||||||
|
placeholder="Pilih ukuran baju"
|
||||||
|
data={[{ value: "S", label: "S" }, { value: "M", label: "M" }, { value: "L", label: "L" }, { value: "XL", label: "XL" }, { value: "XXL", label: "XXL" }, { value: "LAINNYA", label: "Lainnya" }]}
|
||||||
|
onChange={(val) => { if (val) beasiswaDesa.create.form.ukuranBaju = val }} />
|
||||||
|
<Group justify="flex-end" mt="md">
|
||||||
|
<Button variant="default" radius="xl" onClick={close}>Batal</Button>
|
||||||
|
<Button radius="xl" bg={colors['blue-button']} onClick={handleSubmit}>Kirim</Button>
|
||||||
|
</Group>
|
||||||
|
</Stack>
|
||||||
|
</Paper>
|
||||||
|
</Modal>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -51,7 +51,7 @@ function Page() {
|
|||||||
<Stack gap="sm">
|
<Stack gap="sm">
|
||||||
<Box>
|
<Box>
|
||||||
<Badge variant="gradient" gradient={{ from: colors['blue-button'], to: 'cyan' }} size="lg" radius="sm" mb="sm">
|
<Badge variant="gradient" gradient={{ from: colors['blue-button'], to: 'cyan' }} size="lg" radius="sm" mb="sm">
|
||||||
Tujuan Program
|
{stateTujuanProgram.findById.data?.judul}
|
||||||
</Badge>
|
</Badge>
|
||||||
<Tooltip label="Gambaran manfaat utama program" position="top-start" withArrow>
|
<Tooltip label="Gambaran manfaat utama program" position="top-start" withArrow>
|
||||||
<Box>
|
<Box>
|
||||||
@@ -66,7 +66,7 @@ function Page() {
|
|||||||
<Stack gap="sm">
|
<Stack gap="sm">
|
||||||
<Box>
|
<Box>
|
||||||
<Badge variant="gradient" gradient={{ from: colors['blue-button'], to: 'cyan' }} size="lg" radius="sm" mb="sm">
|
<Badge variant="gradient" gradient={{ from: colors['blue-button'], to: 'cyan' }} size="lg" radius="sm" mb="sm">
|
||||||
Lokasi & Jadwal
|
{stateLokasiDanJadwal.findById.data?.judul}
|
||||||
</Badge>
|
</Badge>
|
||||||
<Tooltip label="Tempat dan waktu pelaksanaan" position="top-start" withArrow>
|
<Tooltip label="Tempat dan waktu pelaksanaan" position="top-start" withArrow>
|
||||||
<Box>
|
<Box>
|
||||||
@@ -81,7 +81,7 @@ function Page() {
|
|||||||
<Stack gap="sm">
|
<Stack gap="sm">
|
||||||
<Box>
|
<Box>
|
||||||
<Badge variant="gradient" gradient={{ from: colors['blue-button'], to: 'cyan' }} size="lg" radius="sm" mb="sm">
|
<Badge variant="gradient" gradient={{ from: colors['blue-button'], to: 'cyan' }} size="lg" radius="sm" mb="sm">
|
||||||
Fasilitas
|
{stateFasilitas.findById.data?.judul}
|
||||||
</Badge>
|
</Badge>
|
||||||
<Tooltip label="Sarana yang disediakan untuk peserta" position="top-start" withArrow>
|
<Tooltip label="Sarana yang disediakan untuk peserta" position="top-start" withArrow>
|
||||||
<Box>
|
<Box>
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ function Page() {
|
|||||||
<Tooltip label="Fokus utama program" withArrow>
|
<Tooltip label="Fokus utama program" withArrow>
|
||||||
<Title order={2} fw="bold" c={colors['blue-button']} mb="xs" flex="center">
|
<Title order={2} fw="bold" c={colors['blue-button']} mb="xs" flex="center">
|
||||||
<IconTarget size={28} style={{ marginRight: 8 }} />
|
<IconTarget size={28} style={{ marginRight: 8 }} />
|
||||||
Tujuan Program
|
{stateTujuanPendidikanNonFormal.findById.data?.judul}
|
||||||
</Title>
|
</Title>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
<Text fz="md" lh={1.7} c="dark" style={{wordBreak: "break-word", whiteSpace: "normal"}} dangerouslySetInnerHTML={{ __html: stateTujuanPendidikanNonFormal.findById.data?.deskripsi }} />
|
<Text fz="md" lh={1.7} c="dark" style={{wordBreak: "break-word", whiteSpace: "normal"}} dangerouslySetInnerHTML={{ __html: stateTujuanPendidikanNonFormal.findById.data?.deskripsi }} />
|
||||||
@@ -79,7 +79,7 @@ function Page() {
|
|||||||
<Tooltip label="Lokasi pelaksanaan kegiatan" withArrow>
|
<Tooltip label="Lokasi pelaksanaan kegiatan" withArrow>
|
||||||
<Title order={2} fw="bold" c={colors['blue-button']} mb="xs" flex="center">
|
<Title order={2} fw="bold" c={colors['blue-button']} mb="xs" flex="center">
|
||||||
<IconMapPin size={28} style={{ marginRight: 8 }} />
|
<IconMapPin size={28} style={{ marginRight: 8 }} />
|
||||||
Tempat Kegiatan
|
{stateTempatKegiatan.findById.data?.judul}
|
||||||
</Title>
|
</Title>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
<Text fz="md" style={{wordBreak: "break-word", whiteSpace: "normal"}} lh={1.7} c="dark" dangerouslySetInnerHTML={{ __html: stateTempatKegiatan.findById.data?.deskripsi }} />
|
<Text fz="md" style={{wordBreak: "break-word", whiteSpace: "normal"}} lh={1.7} c="dark" dangerouslySetInnerHTML={{ __html: stateTempatKegiatan.findById.data?.deskripsi }} />
|
||||||
@@ -98,7 +98,7 @@ function Page() {
|
|||||||
<Tooltip label="Ragam jenis program yang tersedia" withArrow>
|
<Tooltip label="Ragam jenis program yang tersedia" withArrow>
|
||||||
<Title order={2} fw="bold" c={colors['blue-button']} mb="xs" flex="center">
|
<Title order={2} fw="bold" c={colors['blue-button']} mb="xs" flex="center">
|
||||||
<IconBook2 size={28} style={{ marginRight: 8 }} />
|
<IconBook2 size={28} style={{ marginRight: 8 }} />
|
||||||
Jenis Program yang Diselenggarakan
|
{stateJenisProgram.findById.data?.judul}
|
||||||
</Title>
|
</Title>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
<Text fz="md" lh={1.7} c="dark" style={{wordBreak: "break-word", whiteSpace: "normal"}} dangerouslySetInnerHTML={{ __html: stateJenisProgram.findById.data?.deskripsi }} />
|
<Text fz="md" lh={1.7} c="dark" style={{wordBreak: "break-word", whiteSpace: "normal"}} dangerouslySetInnerHTML={{ __html: stateJenisProgram.findById.data?.deskripsi }} />
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ function Page() {
|
|||||||
<Group gap="sm">
|
<Group gap="sm">
|
||||||
<IconTargetArrow size={28} color={colors['blue-button']} />
|
<IconTargetArrow size={28} color={colors['blue-button']} />
|
||||||
<Title order={2} fw="bold" c={colors['blue-button']}>
|
<Title order={2} fw="bold" c={colors['blue-button']}>
|
||||||
Tujuan Program
|
{stateTujuan.findById.data?.judul}
|
||||||
</Title>
|
</Title>
|
||||||
</Group>
|
</Group>
|
||||||
<Tooltip label="Detail tujuan program pendidikan anak" position="top-start" withArrow>
|
<Tooltip label="Detail tujuan program pendidikan anak" position="top-start" withArrow>
|
||||||
@@ -83,7 +83,7 @@ function Page() {
|
|||||||
<Group gap="sm">
|
<Group gap="sm">
|
||||||
<IconBook2 size={28} color={colors['blue-button']} />
|
<IconBook2 size={28} color={colors['blue-button']} />
|
||||||
<Title order={2} fw="bold" c={colors['blue-button']}>
|
<Title order={2} fw="bold" c={colors['blue-button']}>
|
||||||
Program Unggulan
|
{stateUnggulan.findById.data?.judul}
|
||||||
</Title>
|
</Title>
|
||||||
</Group>
|
</Group>
|
||||||
<Tooltip label="Detail program unggulan yang sedang berjalan" position="top-start" withArrow>
|
<Tooltip label="Detail program unggulan yang sedang berjalan" position="top-start" withArrow>
|
||||||
|
|||||||
Reference in New Issue
Block a user