Fix QC Kak Inno Admin, Fix QC Keano UI User, Fix QC Pak jun tabel apbdes
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
import { useState, useEffect } from "react";
|
||||
import { Box, Paper, Text, Group, CloseButton, Badge, ActionIcon, Stack, Transition } from "@mantine/core";
|
||||
import { IconBell, IconChevronRight } from "@tabler/icons-react";
|
||||
import { usePathname, useRouter } from "next/navigation"; // 👉 tambahkan ini
|
||||
import { usePathname, useRouter } from "next/navigation";
|
||||
|
||||
interface NewsItem {
|
||||
id: string | number;
|
||||
@@ -31,7 +31,7 @@ export default function ModernNewsNotification({
|
||||
news = [],
|
||||
autoShowDelay = 2000
|
||||
}: ModernNewsNotificationProps) {
|
||||
const router = useRouter(); // 👉 router Next.js
|
||||
const router = useRouter();
|
||||
const [toastVisible, setToastVisible] = useState(false);
|
||||
const [widgetOpen, setWidgetOpen] = useState(false);
|
||||
const [hasNewNotifications, setHasNewNotifications] = useState(true);
|
||||
@@ -39,8 +39,7 @@ export default function ModernNewsNotification({
|
||||
const [iconVisible, setIconVisible] = useState(true);
|
||||
const pathname = usePathname();
|
||||
|
||||
|
||||
|
||||
// Auto show toast on page load
|
||||
useEffect(() => {
|
||||
if (news.length > 0 && !toastVisible && !hasShownToast) {
|
||||
const timer = setTimeout(() => {
|
||||
@@ -51,6 +50,7 @@ export default function ModernNewsNotification({
|
||||
}
|
||||
}, [news.length, autoShowDelay, toastVisible, hasShownToast]);
|
||||
|
||||
// Auto hide toast after 8 seconds
|
||||
useEffect(() => {
|
||||
if (toastVisible) {
|
||||
const timer = setTimeout(() => {
|
||||
@@ -60,22 +60,26 @@ export default function ModernNewsNotification({
|
||||
}
|
||||
}, [toastVisible]);
|
||||
|
||||
// Ganti useEffect scroll yang lama dengan versi berikut:
|
||||
|
||||
// Enhanced scroll handler with better thresholds
|
||||
useEffect(() => {
|
||||
let lastScrollY = window.scrollY;
|
||||
const HIDE_THRESHOLD = 100; // Mulai hide saat scroll > 100px
|
||||
const SHOW_THRESHOLD = 50; // Hanya show ketika benar-benar di atas (< 50px)
|
||||
|
||||
const handleScroll = () => {
|
||||
const currentScrollY = window.scrollY;
|
||||
const scrollDirection = currentScrollY > lastScrollY ? 'down' : 'up';
|
||||
|
||||
// Kontrol ikon lonceng
|
||||
if (currentScrollY > lastScrollY && currentScrollY > 100) {
|
||||
// Logic untuk hide/show icon
|
||||
if (scrollDirection === 'down' && currentScrollY > HIDE_THRESHOLD) {
|
||||
// Scroll ke bawah dan sudah melewati threshold → hide
|
||||
setIconVisible(false);
|
||||
} else if (currentScrollY < lastScrollY) {
|
||||
} else if (scrollDirection === 'up' && currentScrollY < SHOW_THRESHOLD) {
|
||||
// Scroll ke atas dan sudah di posisi paling atas → show
|
||||
setIconVisible(true);
|
||||
}
|
||||
|
||||
// 🔴 BARU: Sembunyikan toast saat scroll ke bawah melewati 150px
|
||||
// Hide toast saat scroll ke bawah melewati 150px
|
||||
if (currentScrollY > 150 && toastVisible) {
|
||||
setToastVisible(false);
|
||||
}
|
||||
@@ -85,11 +89,11 @@ export default function ModernNewsNotification({
|
||||
|
||||
window.addEventListener('scroll', handleScroll, { passive: true });
|
||||
return () => window.removeEventListener('scroll', handleScroll);
|
||||
}, [toastVisible]); // 👈 tambahkan toastVisible sebagai dependency
|
||||
}, [toastVisible]);
|
||||
|
||||
const currentNews = news[0];
|
||||
|
||||
// 👉 Fungsi baru untuk handle klik notifikasi
|
||||
// Handle notification click
|
||||
const handleNotificationClick = (item: NewsItem) => {
|
||||
setWidgetOpen(false);
|
||||
if (item.type === "berita") {
|
||||
@@ -105,13 +109,14 @@ export default function ModernNewsNotification({
|
||||
setHasNewNotifications(false);
|
||||
};
|
||||
|
||||
// Ganti dengan path landing page Anda
|
||||
// Only show on landing page
|
||||
if (pathname !== '/darmasaba') {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
{/* Floating Bell Icon */}
|
||||
<Transition mounted={iconVisible} transition="slide-down" duration={200}>
|
||||
{(transitionStyles) => (
|
||||
<Box
|
||||
@@ -119,7 +124,8 @@ export default function ModernNewsNotification({
|
||||
...transitionStyles,
|
||||
position: "fixed",
|
||||
bottom: "24px",
|
||||
right: "24px"
|
||||
right: "24px",
|
||||
zIndex: 1000,
|
||||
}}
|
||||
>
|
||||
<ActionIcon
|
||||
@@ -161,6 +167,7 @@ export default function ModernNewsNotification({
|
||||
)}
|
||||
</Transition>
|
||||
|
||||
{/* Widget Panel */}
|
||||
<Transition mounted={widgetOpen} transition="slide-up" duration={300}>
|
||||
{(styles) => (
|
||||
<Paper
|
||||
@@ -187,7 +194,7 @@ export default function ModernNewsNotification({
|
||||
<Group justify="space-between">
|
||||
<Group gap="xs">
|
||||
<IconBell size={20} />
|
||||
<Text c={"white"} fw={600} size="md">Berita & Pengumuman</Text>
|
||||
<Text c="white" fw={600} size="md">Berita & Pengumuman</Text>
|
||||
</Group>
|
||||
<CloseButton
|
||||
onClick={() => setWidgetOpen(false)}
|
||||
@@ -257,6 +264,7 @@ export default function ModernNewsNotification({
|
||||
)}
|
||||
</Transition>
|
||||
|
||||
{/* Toast Notification */}
|
||||
<Transition mounted={toastVisible && !!currentNews} transition="slide-left" duration={300}>
|
||||
{(styles) => (
|
||||
<Paper
|
||||
@@ -299,7 +307,10 @@ export default function ModernNewsNotification({
|
||||
{currentNews?.type === "berita" ? "Berita Terbaru" : "Pengumuman"}
|
||||
</Badge>
|
||||
<CloseButton
|
||||
onClick={() => setToastVisible(false)}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
setToastVisible(false);
|
||||
}}
|
||||
size="sm"
|
||||
/>
|
||||
</Group>
|
||||
|
||||
@@ -339,7 +339,7 @@ function Kepuasan() {
|
||||
label="Nama"
|
||||
type='text'
|
||||
placeholder="Masukkan nama"
|
||||
defaultValue={state.create.form.name}
|
||||
value={state.create.form.name}
|
||||
onChange={(val) => {
|
||||
state.create.form.name = val.currentTarget.value;
|
||||
}}
|
||||
@@ -348,7 +348,7 @@ function Kepuasan() {
|
||||
label="Tanggal"
|
||||
type="date"
|
||||
placeholder="masukkan tanggal"
|
||||
defaultValue={state.create.form.tanggal}
|
||||
value={state.create.form.tanggal}
|
||||
onChange={(val) => {
|
||||
state.create.form.tanggal = val.currentTarget.value;
|
||||
}}
|
||||
@@ -357,7 +357,7 @@ function Kepuasan() {
|
||||
key={"jenisKelamin"}
|
||||
label={"Jenis Kelamin"}
|
||||
placeholder={indeksKepuasanState.jenisKelaminResponden.findMany.loading ? 'Memuat...' : 'Pilih jenis kelamin'}
|
||||
defaultValue={state.create.form.jenisKelaminId || ""}
|
||||
value={state.create.form.jenisKelaminId || ""}
|
||||
onChange={(val) => {
|
||||
state.create.form.jenisKelaminId = val ?? "";
|
||||
}}
|
||||
@@ -375,7 +375,7 @@ function Kepuasan() {
|
||||
key={"rating_responden"}
|
||||
label={"Rating"}
|
||||
placeholder={indeksKepuasanState.pilihanRatingResponden.findMany.loading ? 'Memuat...' : 'Pilih rating'}
|
||||
defaultValue={state.create.form.ratingId || ""}
|
||||
value={state.create.form.ratingId || ""}
|
||||
onChange={(val) => {
|
||||
state.create.form.ratingId = val ?? "";
|
||||
}}
|
||||
@@ -393,7 +393,7 @@ function Kepuasan() {
|
||||
key={"kelompokUmur"}
|
||||
label={"Kelompok Umur"}
|
||||
placeholder={indeksKepuasanState.kelompokUmurResponden.findMany.loading ? 'Memuat...' : 'Pilih kelompok umur'}
|
||||
defaultValue={state.create.form.kelompokUmurId || ""}
|
||||
value={state.create.form.kelompokUmurId || ""}
|
||||
onChange={(val) => {
|
||||
state.create.form.kelompokUmurId = val ?? "";
|
||||
}}
|
||||
@@ -611,7 +611,7 @@ function Kepuasan() {
|
||||
label="Nama"
|
||||
type='text'
|
||||
placeholder="masukkan nama"
|
||||
defaultValue={state.create.form.name}
|
||||
value={state.create.form.name}
|
||||
onChange={(val) => {
|
||||
state.create.form.name = val.currentTarget.value;
|
||||
}}
|
||||
@@ -620,7 +620,7 @@ function Kepuasan() {
|
||||
label="Tanggal Pengisian"
|
||||
type="date"
|
||||
placeholder="masukkan tanggal"
|
||||
defaultValue={state.create.form.tanggal}
|
||||
value={state.create.form.tanggal}
|
||||
onChange={(val) => {
|
||||
state.create.form.tanggal = val.currentTarget.value;
|
||||
}}
|
||||
@@ -629,7 +629,7 @@ function Kepuasan() {
|
||||
key={"jenisKelamin"}
|
||||
label={"Jenis Kelamin"}
|
||||
placeholder={indeksKepuasanState.jenisKelaminResponden.findMany.loading ? 'Memuat...' : 'Pilih jenis kelamin'}
|
||||
defaultValue={state.create.form.jenisKelaminId || ""}
|
||||
value={state.create.form.jenisKelaminId || ""}
|
||||
onChange={(val) => {
|
||||
state.create.form.jenisKelaminId = val ?? "";
|
||||
}}
|
||||
@@ -647,7 +647,7 @@ function Kepuasan() {
|
||||
key={"rating_responden"}
|
||||
label={"Rating"}
|
||||
placeholder={indeksKepuasanState.pilihanRatingResponden.findMany.loading ? 'Memuat...' : 'Pilih rating'}
|
||||
defaultValue={state.create.form.ratingId || ""}
|
||||
value={state.create.form.ratingId || ""}
|
||||
onChange={(val) => {
|
||||
state.create.form.ratingId = val ?? "";
|
||||
}}
|
||||
@@ -665,7 +665,7 @@ function Kepuasan() {
|
||||
key={"kelompokUmur"}
|
||||
label={"Kelompok Umur"}
|
||||
placeholder={indeksKepuasanState.kelompokUmurResponden.findMany.loading ? 'Memuat...' : 'Pilih kelompok umur'}
|
||||
defaultValue={state.create.form.kelompokUmurId || ""}
|
||||
value={state.create.form.kelompokUmurId || ""}
|
||||
onChange={(val) => {
|
||||
state.create.form.kelompokUmurId = val ?? "";
|
||||
}}
|
||||
|
||||
@@ -18,14 +18,10 @@ import {
|
||||
} from "@mantine/core";
|
||||
import { Prisma } from "@prisma/client";
|
||||
import { IconCalendarTime, IconInfoCircle } from "@tabler/icons-react";
|
||||
import { useEffect, useMemo, useState } from "react";
|
||||
import { useEffect, useState } from "react";
|
||||
import ModuleView from "./ModuleView";
|
||||
import ProfileView from "./ProfileView";
|
||||
import SosmedView from "./SosmedView";
|
||||
import { useProxy } from "valtio/utils";
|
||||
import stateDashboardBerita from "@/app/admin/(dashboard)/_state/desa/berita";
|
||||
import stateDesaPengumuman from "@/app/admin/(dashboard)/_state/desa/pengumuman";
|
||||
import ModernNewsNotification from "../../ModernNeewsNotification";
|
||||
|
||||
const getDayOfWeek = () => {
|
||||
const days = ["Minggu", "Senin", "Selasa", "Rabu", "Kamis", "Jumat", "Sabtu"];
|
||||
@@ -72,57 +68,7 @@ function LandingPage() {
|
||||
>(null);
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
|
||||
const featured = useProxy(stateDashboardBerita.berita.findFirst);
|
||||
const loadingFeatured = featured.loading;
|
||||
const pengumuman = useProxy(stateDesaPengumuman.pengumuman.findFirst);
|
||||
const loadingPengumuman = pengumuman.loading;
|
||||
|
||||
useEffect(() => {
|
||||
if (!featured.data && !loadingFeatured) {
|
||||
stateDashboardBerita.berita.findFirst.load();
|
||||
}
|
||||
}, [featured.data, loadingFeatured]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!pengumuman.data && !loadingPengumuman) {
|
||||
stateDesaPengumuman.pengumuman.findFirst.load();
|
||||
}
|
||||
}, [pengumuman.data, loadingPengumuman]);
|
||||
|
||||
// Transform data untuk notification system
|
||||
const newsData = useMemo(() => {
|
||||
const items = [];
|
||||
|
||||
if (featured.data) {
|
||||
items.push({
|
||||
id: String(featured.data.id || "berita-1"),
|
||||
type: "berita" as const,
|
||||
title: String(featured.data.judul || "Berita Terbaru"),
|
||||
content: String(featured.data.content || ""),
|
||||
timestamp: featured.data.createdAt
|
||||
? (typeof featured.data.createdAt === 'string'
|
||||
? featured.data.createdAt
|
||||
: new Date(featured.data.createdAt).toISOString())
|
||||
: new Date().toISOString(),
|
||||
});
|
||||
}
|
||||
|
||||
if (pengumuman.data) {
|
||||
items.push({
|
||||
id: String(pengumuman.data.id || "pengumuman-1"),
|
||||
type: "pengumuman" as const,
|
||||
title: String(pengumuman.data.judul || "Pengumuman Penting"),
|
||||
content: String(pengumuman.data.content || ""),
|
||||
timestamp: pengumuman.data.createdAt
|
||||
? (typeof pengumuman.data.createdAt === 'string'
|
||||
? pengumuman.data.createdAt
|
||||
: new Date(pengumuman.data.createdAt).toISOString())
|
||||
: new Date().toISOString(),
|
||||
});
|
||||
}
|
||||
|
||||
return items;
|
||||
}, [featured.data, pengumuman.data]);
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
const fetchSocialMedia = async () => {
|
||||
@@ -272,11 +218,6 @@ function LandingPage() {
|
||||
)}
|
||||
</Flex>
|
||||
|
||||
{/* Modern Notification System */}
|
||||
<ModernNewsNotification
|
||||
news={newsData}
|
||||
autoShowDelay={2000} // Muncul 2 detik setelah load
|
||||
/>
|
||||
</Stack>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user