API Profile Desa aman, tinggal Profil Perbekel
UI Profile Desa aman, tinggal Profil Perbekel
This commit is contained in:
@@ -23,7 +23,7 @@
|
||||
"@mantine/charts": "^7.17.1",
|
||||
"@mantine/core": "^7.17.4",
|
||||
"@mantine/dates": "^8.1.0",
|
||||
"@mantine/dropzone": "^7.17.0",
|
||||
"@mantine/dropzone": "^8.1.1",
|
||||
"@mantine/form": "^8.1.0",
|
||||
"@mantine/hooks": "^7.17.4",
|
||||
"@mantine/tiptap": "^7.17.4",
|
||||
|
||||
BIN
public/bungapudak.png
Normal file
BIN
public/bungapudak.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 221 KiB |
BIN
public/klimakstari.png
Normal file
BIN
public/klimakstari.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 217 KiB |
BIN
public/pohonpudak.png
Normal file
BIN
public/pohonpudak.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 253 KiB |
|
Before Width: | Height: | Size: 195 KiB After Width: | Height: | Size: 195 KiB |
BIN
public/tarisekar.png
Normal file
BIN
public/tarisekar.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 208 KiB |
@@ -38,13 +38,13 @@ const sejarahDesa = proxy({
|
||||
this.error = null;
|
||||
|
||||
try {
|
||||
const response = await fetch(`/api/desa/profile/sejarah-desa/${id}`);
|
||||
|
||||
const response = await fetch(`/api/desa/profile/sejarah/${id}`);
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! status: ${response.status}`);
|
||||
}
|
||||
const result = await response.json();
|
||||
|
||||
|
||||
if (result.success) {
|
||||
this.data = result.data;
|
||||
return result.data;
|
||||
@@ -91,64 +91,69 @@ const sejarahDesa = proxy({
|
||||
},
|
||||
|
||||
async submit() {
|
||||
// Validate form
|
||||
const validation = sejarahDesaForm.safeParse(this.form);
|
||||
|
||||
if (!validation.success) {
|
||||
const errors = validation.error.issues
|
||||
.map((issue) => `${issue.path.join(".")}: ${issue.message}`)
|
||||
.join(", ");
|
||||
toast.error(`Form tidak valid: ${errors}`);
|
||||
return false;
|
||||
// Validate form
|
||||
const validation = sejarahDesaForm.safeParse(this.form);
|
||||
|
||||
if (!validation.success) {
|
||||
const errors = validation.error.issues
|
||||
.map((issue) => `${issue.path.join(".")}: ${issue.message}`)
|
||||
.join(", ");
|
||||
toast.error(`Form tidak valid: ${errors}`);
|
||||
return false;
|
||||
}
|
||||
|
||||
this.loading = true;
|
||||
this.error = null;
|
||||
|
||||
try {
|
||||
const response = await fetch(
|
||||
`/api/desa/profile/sejarah/${this.id}`,
|
||||
{
|
||||
method: "PUT",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify(this.form),
|
||||
}
|
||||
|
||||
this.loading = true;
|
||||
this.error = null;
|
||||
|
||||
try {
|
||||
const response = await fetch(`/api/desa/profile/sejarah-desa/${this.id}`, {
|
||||
method: "PUT",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify(this.form),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json().catch(() => ({}));
|
||||
throw new Error(errorData.message || `HTTP error! status: ${response.status}`);
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
if (result.success) {
|
||||
toast.success("Berhasil update profile");
|
||||
// Refresh profile data
|
||||
await sejarahDesa.findUnique.load(this.id);
|
||||
return true;
|
||||
} else {
|
||||
throw new Error(result.message || "Gagal update profile");
|
||||
}
|
||||
} catch (error) {
|
||||
const errorMessage = (error as Error).message;
|
||||
this.error = errorMessage;
|
||||
console.error("Update profile error:", errorMessage);
|
||||
toast.error("Terjadi kesalahan saat update profile");
|
||||
return false;
|
||||
} finally {
|
||||
this.loading = false;
|
||||
}
|
||||
},
|
||||
|
||||
// Reset form
|
||||
reset() {
|
||||
this.id = "";
|
||||
this.form = { ...sejarahDesaDefaultForm };
|
||||
this.error = null;
|
||||
this.loading = false;
|
||||
this.isReadOnly = false;
|
||||
);
|
||||
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json().catch(() => ({}));
|
||||
throw new Error(
|
||||
errorData.message || `HTTP error! status: ${response.status}`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
if (result.success) {
|
||||
toast.success("Berhasil update profile");
|
||||
// Refresh profile data
|
||||
await sejarahDesa.findUnique.load(this.id);
|
||||
return true;
|
||||
} else {
|
||||
throw new Error(result.message || "Gagal update profile");
|
||||
}
|
||||
} catch (error) {
|
||||
const errorMessage = (error as Error).message;
|
||||
this.error = errorMessage;
|
||||
console.error("Update profile error:", errorMessage);
|
||||
toast.error("Terjadi kesalahan saat update profile");
|
||||
return false;
|
||||
} finally {
|
||||
this.loading = false;
|
||||
}
|
||||
},
|
||||
|
||||
// Reset form
|
||||
reset() {
|
||||
this.id = "";
|
||||
this.form = { ...sejarahDesaDefaultForm };
|
||||
this.error = null;
|
||||
this.loading = false;
|
||||
this.isReadOnly = false;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
// ========================================= VISI MISI DESA ========================================= //
|
||||
@@ -187,12 +192,12 @@ const visiMisiDesa = proxy({
|
||||
|
||||
try {
|
||||
const response = await fetch(`/api/desa/profile/visi-misi/${id}`);
|
||||
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! status: ${response.status}`);
|
||||
}
|
||||
const result = await response.json();
|
||||
|
||||
|
||||
if (result.success) {
|
||||
this.data = result.data;
|
||||
return result.data;
|
||||
@@ -239,64 +244,66 @@ const visiMisiDesa = proxy({
|
||||
},
|
||||
|
||||
async submit() {
|
||||
// Validate form
|
||||
const validation = visiMisiDesaForm.safeParse(this.form);
|
||||
|
||||
if (!validation.success) {
|
||||
const errors = validation.error.issues
|
||||
.map((issue) => `${issue.path.join(".")}: ${issue.message}`)
|
||||
.join(", ");
|
||||
toast.error(`Form tidak valid: ${errors}`);
|
||||
return false;
|
||||
}
|
||||
|
||||
this.loading = true;
|
||||
this.error = null;
|
||||
|
||||
try {
|
||||
const response = await fetch(`/api/desa/profile/visi-misi/${this.id}`, {
|
||||
method: "PUT",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify(this.form),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json().catch(() => ({}));
|
||||
throw new Error(errorData.message || `HTTP error! status: ${response.status}`);
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
if (result.success) {
|
||||
toast.success("Berhasil update visi misi desa");
|
||||
// Refresh profile data
|
||||
await visiMisiDesa.findUnique.load(this.id);
|
||||
return true;
|
||||
} else {
|
||||
throw new Error(result.message || "Gagal update visi misi desa");
|
||||
}
|
||||
} catch (error) {
|
||||
const errorMessage = (error as Error).message;
|
||||
this.error = errorMessage;
|
||||
console.error("Update visi misi desa error:", errorMessage);
|
||||
toast.error("Terjadi kesalahan saat update visi misi desa");
|
||||
return false;
|
||||
} finally {
|
||||
this.loading = false;
|
||||
}
|
||||
},
|
||||
|
||||
// Reset form
|
||||
reset() {
|
||||
this.id = "";
|
||||
this.form = { ...visiMisiDesaDefaultForm };
|
||||
this.error = null;
|
||||
this.loading = false;
|
||||
this.isReadOnly = false;
|
||||
// Validate form
|
||||
const validation = visiMisiDesaForm.safeParse(this.form);
|
||||
|
||||
if (!validation.success) {
|
||||
const errors = validation.error.issues
|
||||
.map((issue) => `${issue.path.join(".")}: ${issue.message}`)
|
||||
.join(", ");
|
||||
toast.error(`Form tidak valid: ${errors}`);
|
||||
return false;
|
||||
}
|
||||
|
||||
this.loading = true;
|
||||
this.error = null;
|
||||
|
||||
try {
|
||||
const response = await fetch(`/api/desa/profile/visi-misi/${this.id}`, {
|
||||
method: "PUT",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify(this.form),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json().catch(() => ({}));
|
||||
throw new Error(
|
||||
errorData.message || `HTTP error! status: ${response.status}`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
if (result.success) {
|
||||
toast.success("Berhasil update visi misi desa");
|
||||
// Refresh profile data
|
||||
await visiMisiDesa.findUnique.load(this.id);
|
||||
return true;
|
||||
} else {
|
||||
throw new Error(result.message || "Gagal update visi misi desa");
|
||||
}
|
||||
} catch (error) {
|
||||
const errorMessage = (error as Error).message;
|
||||
this.error = errorMessage;
|
||||
console.error("Update visi misi desa error:", errorMessage);
|
||||
toast.error("Terjadi kesalahan saat update visi misi desa");
|
||||
return false;
|
||||
} finally {
|
||||
this.loading = false;
|
||||
}
|
||||
},
|
||||
|
||||
// Reset form
|
||||
reset() {
|
||||
this.id = "";
|
||||
this.form = { ...visiMisiDesaDefaultForm };
|
||||
this.error = null;
|
||||
this.loading = false;
|
||||
this.isReadOnly = false;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
// ========================================= LAMBANG DESA ========================================= //
|
||||
@@ -334,13 +341,13 @@ const lambangDesa = proxy({
|
||||
this.error = null;
|
||||
|
||||
try {
|
||||
const response = await fetch(`/api/desa/profile/lambang-desa/${id}`);
|
||||
|
||||
const response = await fetch(`/api/desa/profile/lambang/${id}`);
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! status: ${response.status}`);
|
||||
}
|
||||
const result = await response.json();
|
||||
|
||||
|
||||
if (result.success) {
|
||||
this.data = result.data;
|
||||
return result.data;
|
||||
@@ -387,64 +394,69 @@ const lambangDesa = proxy({
|
||||
},
|
||||
|
||||
async submit() {
|
||||
// Validate form
|
||||
const validation = lambangDesaForm.safeParse(this.form);
|
||||
|
||||
if (!validation.success) {
|
||||
const errors = validation.error.issues
|
||||
.map((issue) => `${issue.path.join(".")}: ${issue.message}`)
|
||||
.join(", ");
|
||||
toast.error(`Form tidak valid: ${errors}`);
|
||||
return false;
|
||||
// Validate form
|
||||
const validation = lambangDesaForm.safeParse(this.form);
|
||||
|
||||
if (!validation.success) {
|
||||
const errors = validation.error.issues
|
||||
.map((issue) => `${issue.path.join(".")}: ${issue.message}`)
|
||||
.join(", ");
|
||||
toast.error(`Form tidak valid: ${errors}`);
|
||||
return false;
|
||||
}
|
||||
|
||||
this.loading = true;
|
||||
this.error = null;
|
||||
|
||||
try {
|
||||
const response = await fetch(
|
||||
`/api/desa/profile/lambang/${this.id}`,
|
||||
{
|
||||
method: "PUT",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify(this.form),
|
||||
}
|
||||
|
||||
this.loading = true;
|
||||
this.error = null;
|
||||
|
||||
try {
|
||||
const response = await fetch(`/api/desa/profile/lambang-desa/${this.id}`, {
|
||||
method: "PUT",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify(this.form),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json().catch(() => ({}));
|
||||
throw new Error(errorData.message || `HTTP error! status: ${response.status}`);
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
if (result.success) {
|
||||
toast.success("Berhasil update lambang desa");
|
||||
// Refresh profile data
|
||||
await lambangDesa.findUnique.load(this.id);
|
||||
return true;
|
||||
} else {
|
||||
throw new Error(result.message || "Gagal update lambang desa");
|
||||
}
|
||||
} catch (error) {
|
||||
const errorMessage = (error as Error).message;
|
||||
this.error = errorMessage;
|
||||
console.error("Update lambang desa error:", errorMessage);
|
||||
toast.error("Terjadi kesalahan saat update lambang desa");
|
||||
return false;
|
||||
} finally {
|
||||
this.loading = false;
|
||||
}
|
||||
},
|
||||
|
||||
// Reset form
|
||||
reset() {
|
||||
this.id = "";
|
||||
this.form = { ...lambangDesaDefaultForm };
|
||||
this.error = null;
|
||||
this.loading = false;
|
||||
this.isReadOnly = false;
|
||||
);
|
||||
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json().catch(() => ({}));
|
||||
throw new Error(
|
||||
errorData.message || `HTTP error! status: ${response.status}`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
if (result.success) {
|
||||
toast.success("Berhasil update lambang desa");
|
||||
// Refresh profile data
|
||||
await lambangDesa.findUnique.load(this.id);
|
||||
return true;
|
||||
} else {
|
||||
throw new Error(result.message || "Gagal update lambang desa");
|
||||
}
|
||||
} catch (error) {
|
||||
const errorMessage = (error as Error).message;
|
||||
this.error = errorMessage;
|
||||
console.error("Update lambang desa error:", errorMessage);
|
||||
toast.error("Terjadi kesalahan saat update lambang desa");
|
||||
return false;
|
||||
} finally {
|
||||
this.loading = false;
|
||||
}
|
||||
},
|
||||
|
||||
// Reset form
|
||||
reset() {
|
||||
this.id = "";
|
||||
this.form = { ...lambangDesaDefaultForm };
|
||||
this.error = null;
|
||||
this.loading = false;
|
||||
this.isReadOnly = false;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
// ========================================= MASKOT DESA ========================================= //
|
||||
@@ -502,7 +514,7 @@ const maskotDesa = proxy({
|
||||
this.error = null;
|
||||
|
||||
try {
|
||||
const response = await fetch(`/api/desa/profile/maskot-desa/${id}`);
|
||||
const response = await fetch(`/api/desa/profile/maskot/${id}`);
|
||||
const result = await response.json();
|
||||
|
||||
if (response.ok && result.success) {
|
||||
@@ -577,7 +589,7 @@ const maskotDesa = proxy({
|
||||
|
||||
try {
|
||||
const response = await fetch(
|
||||
`/api/desa/profile/maskot-desa/${this.id}`,
|
||||
`/api/desa/profile/maskot/${this.id}`,
|
||||
{
|
||||
method: "PUT",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
@@ -806,11 +818,12 @@ const profilPerbekel = proxy({
|
||||
},
|
||||
});
|
||||
|
||||
const stateProfileDesa = {
|
||||
const stateProfileDesa = proxy({
|
||||
lambangDesa,
|
||||
maskotDesa,
|
||||
profilPerbekel,
|
||||
visiMisiDesa,
|
||||
sejarahDesa,
|
||||
};
|
||||
});
|
||||
|
||||
export default stateProfileDesa;
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
import colors from '@/con/colors';
|
||||
import { Box, SimpleGrid, Paper, Stack, Title, Group, Button, Text } from '@mantine/core';
|
||||
import React from 'react';
|
||||
import { DesaEditor } from '../../../_com/desaEditor';
|
||||
|
||||
function LambangDesa() {
|
||||
return (
|
||||
<Box py={10}>
|
||||
<SimpleGrid cols={{ base: 1, md: 2 }}>
|
||||
<Box>
|
||||
<Paper bg={colors['white-1']} p={'md'}>
|
||||
<Stack>
|
||||
<Title order={3}>Lambang Desa</Title>
|
||||
<Text fw={"bold"}>Deskripsi Lambang Desa</Text>
|
||||
<DesaEditor showSubmit={false} />
|
||||
<Group>
|
||||
<Button
|
||||
mt={10}
|
||||
bg={colors['blue-button']}
|
||||
>
|
||||
Submit
|
||||
</Button>
|
||||
</Group>
|
||||
</Stack>
|
||||
</Paper>
|
||||
</Box>
|
||||
<Box>
|
||||
<Paper bg={colors['white-1']} p={'md'}>
|
||||
<Stack>
|
||||
<Title order={3}>List Lambang Desa</Title>
|
||||
</Stack>
|
||||
</Paper>
|
||||
</Box>
|
||||
</SimpleGrid>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
export default LambangDesa;
|
||||
@@ -1,13 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import LayoutTabsEdit from "../_lib/layoutTabsEdit"
|
||||
|
||||
function Layout({children}: {children: React.ReactNode}) {
|
||||
return (
|
||||
<LayoutTabsEdit>
|
||||
{children}
|
||||
</LayoutTabsEdit>
|
||||
);
|
||||
}
|
||||
|
||||
export default Layout;
|
||||
@@ -1,39 +0,0 @@
|
||||
import colors from '@/con/colors';
|
||||
import { Box, SimpleGrid, Paper, Stack, Title, Group, Button, Text } from '@mantine/core';
|
||||
import React from 'react';
|
||||
import { DesaEditor } from '../../../_com/desaEditor';
|
||||
|
||||
function MaskotDesa() {
|
||||
return (
|
||||
<Box py={10}>
|
||||
<SimpleGrid cols={{ base: 1, md: 2 }}>
|
||||
<Box>
|
||||
<Paper bg={colors['white-1']} p={'md'}>
|
||||
<Stack>
|
||||
<Title order={3}>Maskot Desa</Title>
|
||||
<Text fw={"bold"}>Deskripsi Maskot Desa</Text>
|
||||
<DesaEditor showSubmit={false} />
|
||||
<Group>
|
||||
<Button
|
||||
mt={10}
|
||||
bg={colors['blue-button']}
|
||||
>
|
||||
Submit
|
||||
</Button>
|
||||
</Group>
|
||||
</Stack>
|
||||
</Paper>
|
||||
</Box>
|
||||
<Box>
|
||||
<Paper bg={colors['white-1']} p={'md'}>
|
||||
<Stack>
|
||||
<Title order={3}>List Maskot Desa</Title>
|
||||
</Stack>
|
||||
</Paper>
|
||||
</Box>
|
||||
</SimpleGrid>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
export default MaskotDesa;
|
||||
@@ -1,34 +0,0 @@
|
||||
'use client'
|
||||
import colors from '@/con/colors';
|
||||
import { Box, Button, Group, Paper, SimpleGrid, Stack, Text, Title } from '@mantine/core';
|
||||
|
||||
|
||||
|
||||
function SejarahDesa() {
|
||||
|
||||
|
||||
return (
|
||||
<Box py={10}>
|
||||
<SimpleGrid cols={{ base: 1, md: 2 }}>
|
||||
<Box>
|
||||
<Paper bg={colors['white-1']} p={'md'}>
|
||||
<Stack>
|
||||
<Title order={3}>Sejarah Desa</Title>
|
||||
<Text fw={"bold"}>Deskripsi Sejarah Desa</Text>
|
||||
<Group>
|
||||
<Button
|
||||
mt={10}
|
||||
bg={colors['blue-button']}
|
||||
>
|
||||
Submit
|
||||
</Button>
|
||||
</Group>
|
||||
</Stack>
|
||||
</Paper>
|
||||
</Box>
|
||||
</SimpleGrid>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
export default SejarahDesa;
|
||||
@@ -1,25 +0,0 @@
|
||||
import colors from '@/con/colors';
|
||||
import { Box, Paper, Stack } from '@mantine/core';
|
||||
|
||||
function Page() {
|
||||
return (
|
||||
<Paper bg={colors['white-1']} p={'md'} radius={10}>
|
||||
<Stack gap={"22"}>
|
||||
<Box>
|
||||
<Stack gap={'lg'}>
|
||||
<Paper p={"xl"} bg={colors['BG-trans']}>
|
||||
{/* <Box px={{ base: 0, md: 30 }}>
|
||||
<Text ta={"center"} fz={{ base: "h3", md: "h2" }} fw={"bold"} dangerouslySetInnerHTML={{ __html: listDasarHukum.findById.data.judul }} />
|
||||
</Box>
|
||||
<Box px={{ base: 0, md: 30 }}>
|
||||
<Text fz={{ base: "md", md: "h3" }} ta={"justify"} dangerouslySetInnerHTML={{ __html: listDasarHukum.findById.data.content }} />
|
||||
</Box> */}
|
||||
</Paper>
|
||||
</Stack>
|
||||
</Box>
|
||||
</Stack>
|
||||
</Paper>
|
||||
);
|
||||
}
|
||||
|
||||
export default Page;
|
||||
@@ -1,64 +0,0 @@
|
||||
import colors from '@/con/colors';
|
||||
import { Box, Button, Group, Paper, SimpleGrid, Stack, Text, Title } from '@mantine/core';
|
||||
import { DesaEditor } from '../../../_com/desaEditor';
|
||||
|
||||
function VisiMisiDesa() {
|
||||
return (
|
||||
<Box py={10}>
|
||||
<SimpleGrid cols={{ base: 1, md: 2 }}>
|
||||
<Box>
|
||||
<Paper bg={colors['white-1']} p={'md'}>
|
||||
<Stack>
|
||||
<Title order={3}>Visi Desa</Title>
|
||||
<Text fw={"bold"}>Deskripsi Visi Desa</Text>
|
||||
<DesaEditor showSubmit={false} />
|
||||
<Group>
|
||||
<Button
|
||||
mt={10}
|
||||
bg={colors['blue-button']}
|
||||
>
|
||||
Submit
|
||||
</Button>
|
||||
</Group>
|
||||
</Stack>
|
||||
</Paper>
|
||||
</Box>
|
||||
<Box>
|
||||
<Paper bg={colors['white-1']} p={'md'}>
|
||||
<Stack>
|
||||
<Title order={3}>List Visi Desa</Title>
|
||||
</Stack>
|
||||
</Paper>
|
||||
</Box>
|
||||
</SimpleGrid>
|
||||
<SimpleGrid py={30} cols={{ base: 1, md: 2 }}>
|
||||
<Box>
|
||||
<Paper bg={colors['white-1']} p={'md'}>
|
||||
<Stack>
|
||||
<Title order={3}>Misi Desa</Title>
|
||||
<Text fw={"bold"}>Deskripsi Misi Desa</Text>
|
||||
<DesaEditor showSubmit={false}/>
|
||||
<Group>
|
||||
<Button
|
||||
mt={10}
|
||||
bg={colors['blue-button']}
|
||||
>
|
||||
Submit
|
||||
</Button>
|
||||
</Group>
|
||||
</Stack>
|
||||
</Paper>
|
||||
</Box>
|
||||
<Box>
|
||||
<Paper bg={colors['white-1']} p={'md'}>
|
||||
<Stack>
|
||||
<Title order={3}>List Misi Desa</Title>
|
||||
</Stack>
|
||||
</Paper>
|
||||
</Box>
|
||||
</SimpleGrid>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
export default VisiMisiDesa;
|
||||
@@ -0,0 +1,126 @@
|
||||
/* eslint-disable react-hooks/exhaustive-deps */
|
||||
'use client'
|
||||
import EditEditor from '@/app/admin/(dashboard)/_com/editEditor';
|
||||
import stateProfileDesa from '@/app/admin/(dashboard)/_state/desa/profile';
|
||||
import colors from '@/con/colors';
|
||||
import { Box, Button, Center, Group, Paper, Stack, Text, TextInput, Title } from '@mantine/core';
|
||||
import { IconArrowBack } from '@tabler/icons-react';
|
||||
import { useParams, useRouter } from 'next/navigation';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { toast } from 'react-toastify';
|
||||
import { useProxy } from 'valtio/utils';
|
||||
|
||||
function Page() {
|
||||
const lambangState = useProxy(stateProfileDesa.lambangDesa)
|
||||
const router = useRouter()
|
||||
const params = useParams()
|
||||
const [isSubmitting, setIsSubmitting] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
const loadData = async () => {
|
||||
const id = params?.id as string;
|
||||
if (!id) {
|
||||
toast.error("ID tidak valid");
|
||||
router.push("/admin/desa/profile/profile-desa");
|
||||
return;
|
||||
}
|
||||
|
||||
const data = await lambangState.findUnique.load(id);
|
||||
if (data) {
|
||||
lambangState.update.initialize(data);
|
||||
}
|
||||
};
|
||||
|
||||
loadData();
|
||||
|
||||
return () => {
|
||||
lambangState.update.reset();
|
||||
lambangState.findUnique.reset(); // opsional: reset juga data lama
|
||||
};
|
||||
}, [params?.id, router]);
|
||||
|
||||
|
||||
const handleSubmit = async () => {
|
||||
if (isSubmitting || !lambangState.update.form.judul.trim()) {
|
||||
toast.error("Judul wajib diisi");
|
||||
return;
|
||||
}
|
||||
setIsSubmitting(true)
|
||||
try {
|
||||
const success = await lambangState.update.submit()
|
||||
if (success) {
|
||||
toast.success("Data berhasil disimpan");
|
||||
router.push("/admin/desa/profile/profile-desa");
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error update lambang desa:", error);
|
||||
toast.error("Terjadi kesalahan saat update lambang desa");
|
||||
} finally {
|
||||
setIsSubmitting(false);
|
||||
}
|
||||
}
|
||||
|
||||
const handleBack = () => {
|
||||
router.back()
|
||||
}
|
||||
|
||||
if (
|
||||
lambangState.findUnique.loading ||
|
||||
!lambangState.findUnique.data ||
|
||||
lambangState.update.loading
|
||||
) {
|
||||
return (
|
||||
<Box>
|
||||
<Center h={400}>
|
||||
<Text>Memuat data...</Text>
|
||||
</Center>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<Box>
|
||||
<Stack gap={'xs'}>
|
||||
<Group>
|
||||
<Button variant="subtle" onClick={handleBack}>
|
||||
<IconArrowBack color={colors['blue-button']} size={20} />
|
||||
</Button>
|
||||
</Group>
|
||||
<Paper bg={colors['white-1']} p={'xs'} w={{ base: '100%', md: '50%' }}>
|
||||
<Stack gap={'xs'}>
|
||||
<Box>
|
||||
<Box>
|
||||
<Stack>
|
||||
<Title order={4}>Edit Lambang Desa</Title>
|
||||
<TextInput
|
||||
label={<Text fz={"md"} fw={"bold"}>Judul</Text>}
|
||||
placeholder="Judul"
|
||||
value={lambangState.update.form.judul}
|
||||
onChange={(e) => lambangState.update.form.judul = e.currentTarget.value}
|
||||
error={!lambangState.update.form.judul && "Judul wajib diisi"}
|
||||
/>
|
||||
<Box>
|
||||
<Text fz={"md"} fw={"bold"}>Deskripsi</Text>
|
||||
<EditEditor
|
||||
value={lambangState.update.form.deskripsi}
|
||||
onChange={(val) => lambangState.update.form.deskripsi = val}
|
||||
/>
|
||||
</Box>
|
||||
<Group>
|
||||
<Button
|
||||
onClick={handleSubmit}
|
||||
bg={colors['blue-button']}
|
||||
>
|
||||
Submit
|
||||
</Button>
|
||||
</Group>
|
||||
</Stack>
|
||||
</Box>
|
||||
</Box>
|
||||
</Stack>
|
||||
</Paper>
|
||||
</Stack>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
export default Page;
|
||||
@@ -0,0 +1,244 @@
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
/* eslint-disable react-hooks/exhaustive-deps */
|
||||
'use client'
|
||||
import EditEditor from '@/app/admin/(dashboard)/_com/editEditor';
|
||||
import stateProfileDesa from '@/app/admin/(dashboard)/_state/desa/profile';
|
||||
import colors from '@/con/colors';
|
||||
import ApiFetch from '@/lib/api-fetch';
|
||||
import { Box, Button, Group, Image, Paper, SimpleGrid, Stack, Text, TextInput, Title } from '@mantine/core';
|
||||
import { Dropzone } from '@mantine/dropzone';
|
||||
import { IconArrowBack, IconPhoto, IconUpload, IconX } from '@tabler/icons-react';
|
||||
import { useParams, useRouter } from 'next/navigation';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { toast } from 'react-toastify';
|
||||
import { useProxy } from 'valtio/utils';
|
||||
|
||||
function Page() {
|
||||
const maskotState = useProxy(stateProfileDesa.maskotDesa)
|
||||
const router = useRouter()
|
||||
const params = useParams()
|
||||
|
||||
const [images, setImages] = useState<
|
||||
Array<{ file: File; preview: string; label: string }>
|
||||
>([]);
|
||||
|
||||
const [formData, setFormData] = useState({
|
||||
judul: maskotState.update.form.judul || '',
|
||||
deskripsi: maskotState.update.form.deskripsi || '',
|
||||
images: [] as Array<{ label: string; imageId: string }>
|
||||
})
|
||||
|
||||
useEffect(() => {
|
||||
const loadData = async () => {
|
||||
const id = params?.id as string;
|
||||
if (!id) return;
|
||||
|
||||
try {
|
||||
const data = await maskotState.findUnique.load(id);
|
||||
if (data) {
|
||||
// 🔥 INI YANG KURANG!
|
||||
maskotState.update.initialize(data);
|
||||
|
||||
setFormData({
|
||||
judul: data.judul || '',
|
||||
deskripsi: data.deskripsi || '',
|
||||
images: (data.images || []).map((img: any) => ({
|
||||
label: img.label,
|
||||
imageId: img.image?.id ?? '',
|
||||
})),
|
||||
});
|
||||
|
||||
if (data?.images?.length > 0 && data.images[0].image?.link) {
|
||||
setImages(data.images.map((img: any) => ({
|
||||
file: null,
|
||||
preview: img.image.link,
|
||||
label: img.label,
|
||||
})));
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error loading berita:", error);
|
||||
toast.error("Gagal memuat data berita");
|
||||
}
|
||||
};
|
||||
|
||||
loadData();
|
||||
}, [params?.id]);
|
||||
|
||||
|
||||
const handleBack = () => {
|
||||
router.back()
|
||||
}
|
||||
|
||||
const handleSubmit = async () => {
|
||||
try {
|
||||
const uploadedImages = [];
|
||||
|
||||
// Upload semua gambar baru
|
||||
for (const img of images) {
|
||||
if (!img.file || !(img.file instanceof File)) {
|
||||
toast.error("File tidak valid untuk di-upload");
|
||||
continue; // atau return kalau kamu mau hentikan semua
|
||||
}
|
||||
|
||||
const res = await ApiFetch.api.fileStorage.create.post({
|
||||
file: img.file,
|
||||
name: img.file.name,
|
||||
});
|
||||
|
||||
const uploaded = res.data?.data;
|
||||
if (!uploaded?.id) {
|
||||
toast.error("Gagal upload salah satu gambar");
|
||||
return;
|
||||
}
|
||||
|
||||
uploadedImages.push({
|
||||
imageId: uploaded.id,
|
||||
label: img.label || 'main',
|
||||
});
|
||||
}
|
||||
|
||||
// Update ke global state
|
||||
maskotState.update.updateField("judul", formData.judul);
|
||||
maskotState.update.updateField("deskripsi", formData.deskripsi);
|
||||
maskotState.update.updateField("images", uploadedImages);
|
||||
|
||||
const success = await maskotState.update.submit();
|
||||
|
||||
if (success) {
|
||||
toast.success("Maskot berhasil diperbarui!");
|
||||
router.push("/admin/desa/profile/profile-desa");
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error("Error update maskot:", error);
|
||||
toast.error("Gagal update maskot");
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Box>
|
||||
<Stack gap={'xs'}>
|
||||
<Group>
|
||||
<Button variant="subtle" onClick={handleBack}>
|
||||
<IconArrowBack color={colors['blue-button']} size={20} />
|
||||
</Button>
|
||||
</Group>
|
||||
<Paper bg={colors['white-1']} p={'xs'} w={{ base: '100%', md: '100%' }}>
|
||||
<Stack gap={'xs'}>
|
||||
<Box>
|
||||
<Box>
|
||||
<Stack>
|
||||
<Title order={4}>Edit Maskot Desa</Title>
|
||||
<TextInput
|
||||
w={{ base: '100%', md: '50%' }}
|
||||
label={<Text fz={"md"} fw={"bold"}>Judul</Text>}
|
||||
placeholder="Masukkan judul"
|
||||
value={formData.judul}
|
||||
onChange={(val) => setFormData({ ...formData, judul: val.currentTarget.value })}
|
||||
/>
|
||||
<Box w={{ base: '100%', md: '50%' }}>
|
||||
<Text fz={"md"} fw={"bold"}>Deskripsi</Text>
|
||||
<EditEditor
|
||||
value={formData.deskripsi}
|
||||
onChange={(val) => setFormData({ ...formData, deskripsi: val })}
|
||||
/>
|
||||
</Box>
|
||||
<Box>
|
||||
<Text fz={"md"} fw={"bold"}>Gambar</Text>
|
||||
<Box w={{ base: '100%', md: '50%' }}>
|
||||
<Dropzone
|
||||
|
||||
onDrop={(files) => {
|
||||
const newImages = files.map((file) => ({
|
||||
file,
|
||||
preview: URL.createObjectURL(file),
|
||||
label: '',
|
||||
}));
|
||||
setImages((prev) => [...prev, ...newImages]);
|
||||
}}
|
||||
>
|
||||
<Group justify="center" gap="xl" mih={220} style={{ pointerEvents: 'none' }}>
|
||||
<Dropzone.Accept>
|
||||
<IconUpload size={52} color="var(--mantine-color-blue-6)" stroke={1.5} />
|
||||
</Dropzone.Accept>
|
||||
<Dropzone.Reject>
|
||||
<IconX size={52} color="var(--mantine-color-red-6)" stroke={1.5} />
|
||||
</Dropzone.Reject>
|
||||
<Dropzone.Idle>
|
||||
<IconPhoto size={52} color="var(--mantine-color-dimmed)" stroke={1.5} />
|
||||
</Dropzone.Idle>
|
||||
|
||||
<div>
|
||||
<Text size="xl" inline>
|
||||
Drag images here or click to select files
|
||||
</Text>
|
||||
<Text size="sm" c="dimmed" inline mt={7}>
|
||||
Attach as many files as you like, each file should not exceed 5mb
|
||||
</Text>
|
||||
</div>
|
||||
</Group>
|
||||
</Dropzone>
|
||||
</Box>
|
||||
</Box>
|
||||
<SimpleGrid cols={{ base: 2, md: 4 }} >
|
||||
{images.map((img, index) => (
|
||||
<Box key={index} mb="md">
|
||||
<Paper p="sm" radius="md" withBorder style={{ position: 'relative', maxWidth: 300 }}>
|
||||
<Stack gap={'xs'}>
|
||||
<Group>
|
||||
<Button
|
||||
size="xs"
|
||||
color="red"
|
||||
variant="light"
|
||||
onClick={() => {
|
||||
const updated = [...images];
|
||||
updated.splice(index, 1);
|
||||
setImages(updated);
|
||||
}}
|
||||
>
|
||||
Hapus
|
||||
</Button>
|
||||
</Group>
|
||||
<Image
|
||||
src={img.preview}
|
||||
alt={`Preview ${index}`}
|
||||
width={280}
|
||||
height={180}
|
||||
fit="cover"
|
||||
radius="sm"
|
||||
/>
|
||||
<TextInput
|
||||
label={`Label Gambar ${index + 1}`}
|
||||
placeholder="Contoh: Logo, Maskot, Dll"
|
||||
value={img.label}
|
||||
onChange={(e) => {
|
||||
const updated = [...images];
|
||||
updated[index].label = e.currentTarget.value;
|
||||
setImages(updated);
|
||||
}}
|
||||
/>
|
||||
</Stack>
|
||||
</Paper>
|
||||
</Box>
|
||||
))}
|
||||
</SimpleGrid>
|
||||
<Group>
|
||||
<Button
|
||||
onClick={handleSubmit}
|
||||
bg={colors['blue-button']}
|
||||
>
|
||||
Submit
|
||||
</Button>
|
||||
</Group>
|
||||
</Stack>
|
||||
</Box>
|
||||
</Box>
|
||||
</Stack>
|
||||
</Paper>
|
||||
</Stack>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
export default Page;
|
||||
@@ -0,0 +1,126 @@
|
||||
/* eslint-disable react-hooks/exhaustive-deps */
|
||||
'use client'
|
||||
import EditEditor from '@/app/admin/(dashboard)/_com/editEditor';
|
||||
import stateProfileDesa from '@/app/admin/(dashboard)/_state/desa/profile';
|
||||
import colors from '@/con/colors';
|
||||
import { Box, Button, Center, Group, Paper, Stack, Text, TextInput, Title } from '@mantine/core';
|
||||
import { IconArrowBack } from '@tabler/icons-react';
|
||||
import { useParams, useRouter } from 'next/navigation';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { toast } from 'react-toastify';
|
||||
import { useProxy } from 'valtio/utils';
|
||||
|
||||
function Page() {
|
||||
const sejarahState = useProxy(stateProfileDesa.sejarahDesa)
|
||||
const router = useRouter()
|
||||
const params = useParams()
|
||||
const [isSubmitting, setIsSubmitting] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
const loadData = async () => {
|
||||
const id = params?.id as string;
|
||||
if (!id) {
|
||||
toast.error("ID tidak valid");
|
||||
router.push("/admin/desa/profile/profile-desa");
|
||||
return;
|
||||
}
|
||||
|
||||
const data = await sejarahState.findUnique.load(id);
|
||||
if (data) {
|
||||
sejarahState.update.initialize(data);
|
||||
}
|
||||
};
|
||||
|
||||
loadData();
|
||||
|
||||
return () => {
|
||||
sejarahState.update.reset();
|
||||
sejarahState.findUnique.reset(); // opsional: reset juga data lama
|
||||
};
|
||||
}, [params?.id, router]);
|
||||
|
||||
|
||||
const handleSubmit = async () => {
|
||||
if (isSubmitting || !sejarahState.update.form.judul.trim()) {
|
||||
toast.error("Judul wajib diisi");
|
||||
return;
|
||||
}
|
||||
setIsSubmitting(true)
|
||||
try {
|
||||
const success = await sejarahState.update.submit()
|
||||
if (success) {
|
||||
toast.success("Data berhasil disimpan");
|
||||
router.push("/admin/desa/profile/profile-desa");
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error update sejarah desa:", error);
|
||||
toast.error("Terjadi kesalahan saat update sejarah desa");
|
||||
} finally {
|
||||
setIsSubmitting(false);
|
||||
}
|
||||
}
|
||||
|
||||
const handleBack = () => {
|
||||
router.back()
|
||||
}
|
||||
|
||||
if (
|
||||
sejarahState.findUnique.loading ||
|
||||
!sejarahState.findUnique.data ||
|
||||
sejarahState.update.loading
|
||||
) {
|
||||
return (
|
||||
<Box>
|
||||
<Center h={400}>
|
||||
<Text>Memuat data...</Text>
|
||||
</Center>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<Box>
|
||||
<Stack gap={'xs'}>
|
||||
<Group>
|
||||
<Button variant="subtle" onClick={handleBack}>
|
||||
<IconArrowBack color={colors['blue-button']} size={20} />
|
||||
</Button>
|
||||
</Group>
|
||||
<Paper bg={colors['white-1']} p={'xs'} w={{ base: '100%', md: '50%' }}>
|
||||
<Stack gap={'xs'}>
|
||||
<Box>
|
||||
<Box>
|
||||
<Stack>
|
||||
<Title order={4}>Edit Sejarah Desa</Title>
|
||||
<TextInput
|
||||
label={<Text fz={"md"} fw={"bold"}>Judul</Text>}
|
||||
placeholder="Judul"
|
||||
value={sejarahState.update.form.judul}
|
||||
onChange={(e) => sejarahState.update.form.judul = e.currentTarget.value}
|
||||
error={!sejarahState.update.form.judul && "Judul wajib diisi"}
|
||||
/>
|
||||
<Box>
|
||||
<Text fz={"md"} fw={"bold"}>Deskripsi</Text>
|
||||
<EditEditor
|
||||
value={sejarahState.update.form.deskripsi}
|
||||
onChange={(val) => sejarahState.update.form.deskripsi = val}
|
||||
/>
|
||||
</Box>
|
||||
<Group>
|
||||
<Button
|
||||
onClick={handleSubmit}
|
||||
bg={colors['blue-button']}
|
||||
>
|
||||
Submit
|
||||
</Button>
|
||||
</Group>
|
||||
</Stack>
|
||||
</Box>
|
||||
</Box>
|
||||
</Stack>
|
||||
</Paper>
|
||||
</Stack>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
export default Page;
|
||||
@@ -0,0 +1,124 @@
|
||||
/* eslint-disable react-hooks/exhaustive-deps */
|
||||
'use client'
|
||||
import EditEditor from '@/app/admin/(dashboard)/_com/editEditor';
|
||||
import stateProfileDesa from '@/app/admin/(dashboard)/_state/desa/profile';
|
||||
import colors from '@/con/colors';
|
||||
import { Box, Button, Center, Group, Paper, Stack, Text, Title } from '@mantine/core';
|
||||
import { IconArrowBack } from '@tabler/icons-react';
|
||||
import { useParams, useRouter } from 'next/navigation';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { toast } from 'react-toastify';
|
||||
import { useProxy } from 'valtio/utils';
|
||||
|
||||
function Page() {
|
||||
const visiMisiState = useProxy(stateProfileDesa.visiMisiDesa)
|
||||
const router = useRouter()
|
||||
const params = useParams()
|
||||
const [isSubmitting, setIsSubmitting] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
const loadData = async () => {
|
||||
const id = params?.id as string;
|
||||
if (!id) {
|
||||
toast.error("ID tidak valid");
|
||||
router.push("/admin/desa/profile/profile-desa");
|
||||
return;
|
||||
}
|
||||
|
||||
const data = await visiMisiState.findUnique.load(id);
|
||||
if (data) {
|
||||
visiMisiState.update.initialize(data);
|
||||
}
|
||||
};
|
||||
|
||||
loadData();
|
||||
|
||||
return () => {
|
||||
visiMisiState.update.reset();
|
||||
visiMisiState.findUnique.reset(); // opsional: reset juga data lama
|
||||
};
|
||||
}, [params?.id, router]);
|
||||
|
||||
|
||||
const handleSubmit = async () => {
|
||||
if (isSubmitting || !visiMisiState.update.form.visi.trim()) {
|
||||
toast.error("Visi wajib diisi");
|
||||
return;
|
||||
}
|
||||
setIsSubmitting(true)
|
||||
try {
|
||||
const success = await visiMisiState.update.submit()
|
||||
if (success) {
|
||||
toast.success("Data berhasil disimpan");
|
||||
router.push("/admin/desa/profile/profile-desa");
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error update sejarah desa:", error);
|
||||
toast.error("Terjadi kesalahan saat update sejarah desa");
|
||||
} finally {
|
||||
setIsSubmitting(false);
|
||||
}
|
||||
}
|
||||
|
||||
const handleBack = () => {
|
||||
router.back()
|
||||
}
|
||||
|
||||
if (
|
||||
visiMisiState.findUnique.loading ||
|
||||
!visiMisiState.findUnique.data ||
|
||||
visiMisiState.update.loading
|
||||
) {
|
||||
return (
|
||||
<Box>
|
||||
<Center h={400}>
|
||||
<Text>Memuat data...</Text>
|
||||
</Center>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<Box>
|
||||
<Stack gap={'xs'}>
|
||||
<Group>
|
||||
<Button variant="subtle" onClick={handleBack}>
|
||||
<IconArrowBack color={colors['blue-button']} size={20} />
|
||||
</Button>
|
||||
</Group>
|
||||
<Paper bg={colors['white-1']} p={'xs'} w={{ base: '100%', md: '50%' }}>
|
||||
<Stack gap={'xs'}>
|
||||
<Box>
|
||||
<Box>
|
||||
<Stack>
|
||||
<Title order={4}>Edit Visi Misi Desa</Title>
|
||||
<Text fz={"md"} fw={"bold"}>Visi</Text>
|
||||
<EditEditor
|
||||
value={visiMisiState.update.form.visi}
|
||||
onChange={(val) => visiMisiState.update.form.visi = val}
|
||||
/>
|
||||
<Box>
|
||||
<Text fz={"md"} fw={"bold"}>Misi</Text>
|
||||
<EditEditor
|
||||
value={visiMisiState.update.form.misi}
|
||||
onChange={(val) => visiMisiState.update.form.misi = val}
|
||||
/>
|
||||
</Box>
|
||||
<Group>
|
||||
<Button
|
||||
onClick={handleSubmit}
|
||||
bg={colors['blue-button']}
|
||||
>
|
||||
Submit
|
||||
</Button>
|
||||
</Group>
|
||||
</Stack>
|
||||
</Box>
|
||||
</Box>
|
||||
</Stack>
|
||||
</Paper>
|
||||
</Stack>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
export default Page;
|
||||
@@ -1,131 +1,168 @@
|
||||
'use client'
|
||||
|
||||
import colors from '@/con/colors';
|
||||
import { Paper, Stack, Grid, GridCol, Title, Button, Box, Text, Center, Image, SimpleGrid } from '@mantine/core';
|
||||
import { Box, Button, Card, Center, Grid, GridCol, Group, Image, Paper, Stack, Text, Title } from '@mantine/core';
|
||||
import { useSnapshot } from 'valtio';
|
||||
import stateProfileDesa from '../../../_state/desa/profile';
|
||||
import { useEffect } from 'react';
|
||||
import { IconEdit } from '@tabler/icons-react';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import React from 'react';
|
||||
|
||||
function Page() {
|
||||
const router = useRouter()
|
||||
const router = useRouter();
|
||||
const snap = useSnapshot(stateProfileDesa);
|
||||
|
||||
// Panggil load data sekali saat komponen mount
|
||||
useEffect(() => {
|
||||
stateProfileDesa.sejarahDesa.findUnique.load("1");
|
||||
stateProfileDesa.visiMisiDesa.findUnique.load("1");
|
||||
stateProfileDesa.lambangDesa.findUnique.load("1");
|
||||
stateProfileDesa.maskotDesa.findUnique.load("1");
|
||||
}, []);
|
||||
|
||||
const sejarah = snap.sejarahDesa.findUnique.data;
|
||||
const visiMisi = snap.visiMisiDesa.findUnique.data;
|
||||
const lambang = snap.lambangDesa.findUnique.data;
|
||||
const maskot = snap.maskotDesa.findUnique.data;
|
||||
|
||||
return (
|
||||
<Paper bg={colors['white-1']} p={'md'} radius={10}>
|
||||
<Stack gap={"22"}>
|
||||
<Grid>
|
||||
<GridCol span={{ base: 12, md: 11 }}>
|
||||
<Title order={2}>Preview Profile Desa</Title>
|
||||
</GridCol>
|
||||
<GridCol span={{ base: 12, md: 1 }}>
|
||||
<Button bg={colors['blue-button']} onClick={() => router.push('/admin/desa/profile/edit/sejarah_desa')}>
|
||||
<IconEdit size={16} />
|
||||
</Button>
|
||||
</GridCol>
|
||||
</Grid>
|
||||
<Paper bg={colors['white-1']} p={'md'}>
|
||||
<Stack gap={"lg"}>
|
||||
<Title order={2}>Preview Profile Desa</Title>
|
||||
{/* Sejarah Desa */}
|
||||
<Box>
|
||||
<Stack gap={'lg'}>
|
||||
<Paper p={"xl"} bg={colors['BG-trans']}>
|
||||
<Box pb={30}>
|
||||
<Center>
|
||||
<Image src={"/darmasaba-icon.png"} alt="" w={{ base: 200, md: 300 }} />
|
||||
</Center>
|
||||
<Text c={colors['blue-button']} ta={"center"} fw={"bold"} fz={"2.5rem"}>Sejarah Desa</Text>
|
||||
</Box>
|
||||
<Paper p={"xl"} bg={colors['white-trans-1']} w={{ base: "100%", md: "100%" }}>
|
||||
<Text fz={{ base: "md", md: "h3" }} ta={"justify"}>
|
||||
Test
|
||||
</Text>
|
||||
{sejarah && (
|
||||
<Box>
|
||||
<Stack gap={'lg'}>
|
||||
<Paper p={"md"} bg={colors['BG-trans']}>
|
||||
<Grid>
|
||||
<GridCol span={{ base: 12, md: 11 }}>
|
||||
<Title order={2}>Preview Sejarah Desa</Title>
|
||||
</GridCol>
|
||||
<GridCol span={{ base: 12, md: 1 }}>
|
||||
<Button bg={colors['blue-button']} onClick={() => router.push(`/admin/desa/profile/profile-desa/${sejarah.id}/sejarah_desa`)}>
|
||||
<IconEdit size={20} />
|
||||
</Button>
|
||||
</GridCol>
|
||||
</Grid>
|
||||
<Box pb={30}>
|
||||
<Center>
|
||||
<Image src={"/darmasaba-icon.png"} alt="" w={{ base: 200, md: 300 }} />
|
||||
</Center>
|
||||
<Text c={colors['blue-button']} ta={"center"} fw={"bold"} fz={"2.5rem"}>{sejarah.judul}</Text>
|
||||
</Box>
|
||||
<Paper p={"xl"} bg={colors['white-trans-1']}>
|
||||
<Text fz={{ base: "md", md: "h3" }} ta={"justify"} dangerouslySetInnerHTML={{ __html: sejarah.deskripsi }} />
|
||||
</Paper>
|
||||
</Paper>
|
||||
</Paper>
|
||||
</Stack>
|
||||
</Box>
|
||||
</Stack>
|
||||
</Box>
|
||||
)}
|
||||
|
||||
{/* Visi Misi Desa */}
|
||||
<Box>
|
||||
<Stack gap={'lg'}>
|
||||
<Paper p={"xl"} bg={colors['BG-trans']}>
|
||||
<Box pb={30}>
|
||||
<Center>
|
||||
<Image src={"/darmasaba-icon.png"} alt="" w={{ base: 200, md: 300 }} />
|
||||
</Center>
|
||||
</Box>
|
||||
<Paper p={"xl"} bg={colors['white-trans-1']} w={{ base: "100%", md: "100%" }}>
|
||||
<Text c={colors['blue-button']} ta={"center"} fw={"bold"} fz={"2.5rem"}>Visi Desa</Text>
|
||||
<Text fz={{ base: "md", md: "h3" }} ta={"justify"}>
|
||||
Test
|
||||
</Text>
|
||||
{visiMisi && (
|
||||
<Box>
|
||||
<Stack gap={'lg'}>
|
||||
<Paper p={"md"} bg={colors['BG-trans']}>
|
||||
<Grid>
|
||||
<GridCol span={{ base: 12, md: 11 }}>
|
||||
<Title order={2}>Preview Visi Misi Desa</Title>
|
||||
</GridCol>
|
||||
<GridCol span={{ base: 12, md: 1 }}>
|
||||
<Button onClick={() => router.push(`/admin/desa/profile/profile-desa/${visiMisi.id}/visi_misi_desa`)} bg={colors['blue-button']}>
|
||||
<IconEdit size={20} />
|
||||
</Button>
|
||||
</GridCol>
|
||||
</Grid>
|
||||
<Box pb={30}>
|
||||
<Center>
|
||||
<Image src={"/darmasaba-icon.png"} alt="" w={{ base: 200, md: 300 }} />
|
||||
</Center>
|
||||
<Text c={colors['blue-button']} ta={"center"} fw={"bold"} fz={"2.5rem"}>Visi Misi Desa</Text>
|
||||
</Box>
|
||||
<Paper p={"xl"} bg={colors['white-trans-1']}>
|
||||
<Text fw={"bold"} fz={{ base: "lg", md: "h2" }}>Visi Desa</Text>
|
||||
<Text fz={{ base: "md", md: "h3" }} ta={"justify"} dangerouslySetInnerHTML={{ __html: visiMisi.visi }} />
|
||||
<Text fw={"bold"} fz={{ base: "lg", md: "h2" }}>Misi Desa</Text>
|
||||
<Text fz={{ base: "md", md: "h3" }} ta={"justify"} dangerouslySetInnerHTML={{ __html: visiMisi.misi }} />
|
||||
</Paper>
|
||||
</Paper>
|
||||
<Paper p={"xl"} bg={colors['white-trans-1']} w={{ base: "100%", md: "100%" }}>
|
||||
<Text c={colors['blue-button']} ta={"center"} fw={"bold"} fz={"2.5rem"}>Misi Desa</Text>
|
||||
<Text fz={{ base: "md", md: "h3" }} ta={"justify"}>
|
||||
Test
|
||||
</Text>
|
||||
</Paper>
|
||||
</Paper>
|
||||
</Stack>
|
||||
</Box>
|
||||
</Stack>
|
||||
</Box>
|
||||
)}
|
||||
|
||||
{/* Lambang Desa */}
|
||||
<Box>
|
||||
<Stack gap={'lg'}>
|
||||
<Paper p={"xl"} bg={colors['BG-trans']}>
|
||||
<Box pb={30}>
|
||||
<Center>
|
||||
<Image src={"/darmasaba-icon.png"} alt="" w={{ base: 200, md: 300 }} />
|
||||
</Center>
|
||||
<Text c={colors['blue-button']} ta={"center"} fw={"bold"} fz={"2.5rem"}>Lambang Desa</Text>
|
||||
</Box>
|
||||
<Paper p={"xl"} bg={colors['white-trans-1']} w={{ base: "100%", md: "100%" }}>
|
||||
<Text fz={{ base: "md", md: "h3" }} ta={"justify"}>
|
||||
Test
|
||||
</Text>
|
||||
{lambang && (
|
||||
<Box>
|
||||
<Stack gap={'lg'}>
|
||||
<Paper p={"md"} bg={colors['BG-trans']}>
|
||||
<Grid>
|
||||
<GridCol span={{ base: 12, md: 11 }}>
|
||||
<Title order={2}>Preview Lambang Desa</Title>
|
||||
</GridCol>
|
||||
<GridCol span={{ base: 12, md: 1 }}>
|
||||
<Button onClick={() => router.push(`/admin/desa/profile/profile-desa/${lambang.id}/lambang_desa`)} bg={colors['blue-button']}>
|
||||
<IconEdit size={20} />
|
||||
</Button>
|
||||
</GridCol>
|
||||
</Grid>
|
||||
<Box pb={30}>
|
||||
<Center>
|
||||
<Image src={"/darmasaba-icon.png"} alt="" w={{ base: 200, md: 300 }} />
|
||||
</Center>
|
||||
<Text c={colors['blue-button']} ta={"center"} fw={"bold"} fz={"2.5rem"}>Lambang Desa</Text>
|
||||
</Box>
|
||||
<Paper p={"xl"} bg={colors['white-trans-1']}>
|
||||
<Text fz={{ base: "md", md: "h3" }} ta={"justify"} dangerouslySetInnerHTML={{ __html: lambang.deskripsi }} />
|
||||
</Paper>
|
||||
</Paper>
|
||||
</Paper>
|
||||
</Stack>
|
||||
</Box>
|
||||
</Stack>
|
||||
</Box>
|
||||
)}
|
||||
|
||||
{/* Maskot Desa */}
|
||||
<Box>
|
||||
<Stack gap={'lg'}>
|
||||
<Paper p={"xl"} bg={colors['BG-trans']}>
|
||||
<Box pb={30}>
|
||||
<Center>
|
||||
<Image src={"/darmasaba-icon.png"} alt="" w={{ base: 200, md: 300 }} />
|
||||
</Center>
|
||||
<Text c={colors['blue-button']} ta={"center"} fw={"bold"} fz={"2.5rem"}>Maskot Desa</Text>
|
||||
</Box>
|
||||
<Paper p={"xl"} bg={colors['white-trans-1']} w={{ base: "100%", md: "100%" }}>
|
||||
<Text fz={{ base: "md", md: "h3" }} ta={"justify"}>
|
||||
Test
|
||||
</Text>
|
||||
{maskot && (
|
||||
<Box>
|
||||
<Stack gap={'lg'}>
|
||||
<Paper p={"md"} bg={colors['BG-trans']}>
|
||||
<Grid>
|
||||
<GridCol span={{ base: 12, md: 11 }}>
|
||||
<Title order={2}>Preview Maskot Desa</Title>
|
||||
</GridCol>
|
||||
<GridCol span={{ base: 12, md: 1 }}>
|
||||
<Button onClick={() => router.push(`/admin/desa/profile/profile-desa/${maskot.id}/maskot_desa`)} bg={colors['blue-button']}>
|
||||
<IconEdit size={20} />
|
||||
</Button>
|
||||
</GridCol>
|
||||
</Grid>
|
||||
<Box pb={30}>
|
||||
<Center>
|
||||
<Image src={"/pudak-icon.png"} alt="" w={{ base: 200, md: 300 }} />
|
||||
</Center>
|
||||
<Text c={colors['blue-button']} ta={"center"} fw={"bold"} fz={"2.5rem"}>Maskot Desa</Text>
|
||||
</Box>
|
||||
<Paper p={"xl"} bg={colors['white-trans-1']}>
|
||||
<Text fz={{ base: "md", md: "h3" }} ta={"justify"} dangerouslySetInnerHTML={{ __html: maskot.deskripsi }} />
|
||||
<Group wrap="wrap" gap="md">
|
||||
{maskot.images.map((img, index) => (
|
||||
<Card key={index} p="xs" w={220}>
|
||||
<Image
|
||||
src={img.image.link}
|
||||
alt={img.label}
|
||||
w={200}
|
||||
h={200}
|
||||
fit="cover"
|
||||
radius="md"
|
||||
style={{ border: '1px solid #ccc', objectFit: 'cover' }}
|
||||
/>
|
||||
<Text ta="center" mt="xs" fw="bold">{img.label}</Text>
|
||||
</Card>
|
||||
))}
|
||||
</Group>
|
||||
</Paper>
|
||||
</Paper>
|
||||
<SimpleGrid
|
||||
cols={{
|
||||
base: 1,
|
||||
md: 2,
|
||||
}}
|
||||
>
|
||||
<Center>
|
||||
<Box>
|
||||
<Paper p={"lg"}>
|
||||
<Image src={"/api/img/pohonpudak.png"} alt="" w={{ base: 150, md: 250 }} />
|
||||
<Text ta={"center"} fw={"bold"} c={colors["blue-button"]} fz={{ base: "md", md: "h3" }}>Pohon Pudak</Text>
|
||||
</Paper>
|
||||
</Box>
|
||||
</Center>
|
||||
<Center>
|
||||
<Box>
|
||||
<Paper p={"lg"}>
|
||||
<Image src={"/api/img/bungapudak.png"} alt="" w={{ base: 150, md: 250 }} />
|
||||
<Text ta={"center"} fw={"bold"} c={colors["blue-button"]} fz={{ base: "md", md: "h3" }}>Bunga Pudak</Text>
|
||||
</Paper>
|
||||
</Box>
|
||||
</Center>
|
||||
</SimpleGrid>
|
||||
<Paper p={"xl"} bg={colors['white-trans-1']} w={{ base: "100%", md: "100%" }}>
|
||||
<Text fz={{ base: "md", md: "h3" }} ta={"justify"}>
|
||||
Test
|
||||
</Text>
|
||||
</Paper>
|
||||
</Paper>
|
||||
</Stack>
|
||||
</Box>
|
||||
</Stack>
|
||||
</Box>
|
||||
)}
|
||||
</Stack>
|
||||
</Paper>
|
||||
);
|
||||
|
||||
@@ -3,10 +3,10 @@ import maskotDesaFindById from "./find-by-id";
|
||||
import Elysia, { t } from "elysia";
|
||||
|
||||
const MaskotDesa = new Elysia({
|
||||
prefix: "/maskot",
|
||||
tags: ["Desa/Profile"],
|
||||
prefix: "/maskot",
|
||||
tags: ["Desa/Profile"],
|
||||
})
|
||||
.get("/:id", async (context) => {
|
||||
.get("/:id", async (context) => {
|
||||
const response = await maskotDesaFindById(new Request(context.request));
|
||||
return response;
|
||||
})
|
||||
@@ -18,7 +18,8 @@ const MaskotDesa = new Elysia({
|
||||
},
|
||||
{
|
||||
body: t.Object({
|
||||
maskot: t.String(),
|
||||
judul: t.String(),
|
||||
deskripsi: t.String(),
|
||||
images: t.Array(
|
||||
t.Object({
|
||||
imageId: t.String(),
|
||||
@@ -27,5 +28,5 @@ const MaskotDesa = new Elysia({
|
||||
),
|
||||
}),
|
||||
}
|
||||
)
|
||||
export default MaskotDesa;
|
||||
);
|
||||
export default MaskotDesa;
|
||||
|
||||
@@ -11,6 +11,7 @@ import '@mantine/charts/styles.css';
|
||||
import '@mantine/dates/styles.css';
|
||||
import '@mantine/tiptap/styles.css';
|
||||
|
||||
|
||||
import LoadDataFirstClient from "@/app/darmasaba/_com/LoadDataFirstClient";
|
||||
import {
|
||||
ColorSchemeScript,
|
||||
|
||||
Reference in New Issue
Block a user