Merge pull request #422 from bipproduction/amalia/16-apr-25

Amalia/16 apr 25
This commit is contained in:
Amalia
2025-04-16 12:17:02 +08:00
committed by GitHub
9 changed files with 117 additions and 9 deletions

View File

@@ -92,4 +92,34 @@ export async function PUT(request: Request, context: { params: { id: string } })
console.error(error);
return NextResponse.json({ success: false, message: "Gagal mendapatkan notifikasi, coba lagi nanti (error: 500)", reason: (error as Error).message, }, { status: 500 });
}
}
// UPDATE READ ALL NOTIFICATION
export async function POST(request: Request) {
try {
const user = await funGetUserByCookies()
if (user.id == undefined) {
return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 401 });
}
const upd = await prisma.notifications.updateMany({
where: {
idUserTo: user.id,
isRead: false
},
data: {
isRead: true
}
})
// create log user
const log = await createLogUser({ act: 'UPDATE', desc: 'User menandai semua notifikasi', table: 'notifications', data: '' })
return NextResponse.json({ success: true, message: "Berhasil mengupdate notifikasi", }, { status: 200 });
} catch (error) {
console.error(error);
return NextResponse.json({ success: false, message: "Gagal mengupdate notifikasi, coba lagi nanti (error: 500)", reason: (error as Error).message, }, { status: 500 });
}
}

View File

@@ -2,7 +2,7 @@ import { NextResponse } from "next/server";
export async function GET(request: Request) {
try {
return NextResponse.json({ success: true, version: "1.3.2", tahap: "beta", update: "- update baru : menampilkan notifikasi pengumuman setelah login (fixed tampilan); - fix random nomer kode otp 4 digit" }, { status: 200 });
return NextResponse.json({ success: true, version: "1.3.3", tahap: "beta", update: "- update baru : menampilkan notifikasi pengumuman setelah login (fixed tampilan); - rich text di pengumuman (tambah dan edit); - fitur tandai dibaca semua notifikasi" }, { status: 200 });
} catch (error) {
console.error(error);
return NextResponse.json({ success: false, version: "Gagal mendapatkan version, coba lagi nanti (error: 500)", reason: (error as Error).message, }, { status: 500 });

View File

@@ -317,7 +317,7 @@ export default function EditAnnouncement() {
))
:
<>
<Box pb={50}>
<Text c={tema.get().utama} mb={10}>Divisi Terpilih</Text>
{
memberGroup.get().length == 0 ? <Text c="dimmed" ta={"center"} fs={"italic"}>Belum ada divisi yang dipilih</Text> :
@@ -343,7 +343,7 @@ export default function EditAnnouncement() {
})
}
</>
</Box>
}

View File

@@ -1,5 +1,6 @@
import { funGetHome } from "./lib/api_home";
import { globalParamJumlahNotif } from "./lib/val_home";
import DrawerNotification from "./ui/drawer_notification";
import NotificationAnnouncement from "./ui/notification_announcement";
import ViewDetailFeature from "./ui/view_detail_feature";
import ViewHome from "./ui/view_home";
@@ -12,4 +13,5 @@ export { ViewSearch }
export { ViewNotification }
export { funGetHome }
export { globalParamJumlahNotif }
export { NotificationAnnouncement }
export { NotificationAnnouncement }
export { DrawerNotification }

View File

@@ -15,4 +15,11 @@ export const funReadNotification = async (data: { id: string }) => {
export const funGetOneNotificationAnnouncement = async (path?: string) => {
const response = await fetch(`/api/notification${(path) ? path : ''}`, { next: { tags: ['notification'] } });
return await response.json().catch(() => null);
}
export const funReadAllNotification = async () => {
const response = await fetch(`/api/home/notification`, {
method: "POST",
});
return await response.json().catch(() => null);
}

View File

@@ -1,3 +1,4 @@
import { hookstate } from "@hookstate/core";
export const globalParamJumlahNotif = hookstate<boolean>(false)
export const globalRefreshNotif = hookstate<boolean>(false)

View File

@@ -0,0 +1,49 @@
"use client"
import { TEMA } from '@/module/_global';
import { useHookstate } from '@hookstate/core';
import { Box, Flex, SimpleGrid, Stack, Text } from '@mantine/core';
import toast from 'react-hot-toast';
import { LuCheckCheck } from 'react-icons/lu';
import { funReadAllNotification } from '../lib/api_notification';
import { globalRefreshNotif } from '../lib/val_home';
export default function DrawerNotification({ onDone }: { onDone: () => void }) {
const tema = useHookstate(TEMA)
const reloadNotif = useHookstate(globalRefreshNotif)
async function handleReadAll() {
try {
const res = await funReadAllNotification()
if (res.success) {
toast.success(res.message)
reloadNotif.set(!reloadNotif.get())
} else {
toast.error(res.message)
}
} catch (error) {
console.error(error)
toast.error("Gagal mengupdate notifikasi, coba lagi nanti")
} finally {
onDone()
}
}
return (
<Box>
<Stack pt={10}>
<SimpleGrid
cols={{ base: 3, sm: 3, lg: 3 }}
>
<Flex onClick={() => { handleReadAll() }} justify={'center'} align={'center'} direction={'column'} >
<Box>
<LuCheckCheck size={30} color={tema.get().utama} />
</Box>
<Box>
<Text c={tema.get().utama} ta={"center"}>Tandai Dibaca Semua</Text>
</Box>
</Flex>
</SimpleGrid>
</Stack>
</Box>
);
}

View File

@@ -9,6 +9,7 @@ import toast from "react-hot-toast";
import { FaBell } from "react-icons/fa6";
import { funGetAllNotification, funReadNotification, } from "../lib/api_notification";
import { IListNotification } from "../lib/type_notification";
import { globalRefreshNotif } from "../lib/val_home";
export default function ListNotification() {
const router = useRouter();
@@ -19,6 +20,7 @@ export default function ListNotification() {
const { value: containerRef } = useHookstate(currentScroll);
const [isPage, setPage] = useState(1);
const [loading, setLoading] = useState(true);
const reloadNotif = useHookstate(globalRefreshNotif)
async function fetchData(loading: boolean) {
try {
@@ -47,7 +49,7 @@ export default function ListNotification() {
useShallowEffect(() => {
fetchData(false);
}, [isPage]);
}, [isPage, reloadNotif.get()]);
useEffect(() => {
const handleScroll = async () => {

View File

@@ -1,15 +1,32 @@
import { LayoutNavbarNew } from '@/module/_global'
import { Box, } from '@mantine/core'
import React from 'react'
'use client'
import { LayoutDrawer, LayoutNavbarNew, TEMA } from '@/module/_global'
import { ActionIcon, Box, } from '@mantine/core'
import { useState } from 'react'
import { HiMenu } from 'react-icons/hi'
import DrawerNotification from './drawer_notification'
import ListNotification from './list_notification'
export default function ViewNotification() {
const [isOpen, setOpen] = useState(false)
return (
<Box>
<LayoutNavbarNew back='/home' title='Notifikasi' menu={<></>} />
<LayoutNavbarNew
back='/home'
title='Notifikasi'
menu={
<ActionIcon onClick={() => setOpen(true)} variant="light" bg={TEMA.get().bgIcon} size="lg" radius="lg" aria-label="Settings">
<HiMenu size={20} color='white' />
</ActionIcon>
}
/>
<Box p={20}>
<ListNotification />
</Box>
<LayoutDrawer opened={isOpen} title={'Menu'} onClose={() => setOpen(false)}>
<DrawerNotification onDone={() => setOpen(false)} />
</LayoutDrawer>
</Box>
)
}