tambahan
This commit is contained in:
@@ -12,58 +12,78 @@ import {
|
|||||||
Badge,
|
Badge,
|
||||||
ScrollArea,
|
ScrollArea,
|
||||||
Tooltip,
|
Tooltip,
|
||||||
|
Divider,
|
||||||
} from "@mantine/core";
|
} from "@mantine/core";
|
||||||
import { useLocalStorage, useShallowEffect } from "@mantine/hooks";
|
import { useLocalStorage, useShallowEffect } from "@mantine/hooks";
|
||||||
import { showNotification } from "@mantine/notifications";
|
import { showNotification } from "@mantine/notifications";
|
||||||
import { IconRefresh, IconMessageCircle, IconUser, IconCalendar, IconHash, IconCode } from "@tabler/icons-react";
|
import {
|
||||||
|
IconRefresh,
|
||||||
|
IconMessageCircle,
|
||||||
|
IconUser,
|
||||||
|
IconCalendar,
|
||||||
|
IconHash,
|
||||||
|
IconCode,
|
||||||
|
} from "@tabler/icons-react";
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
import useSWR from "swr";
|
import useSWR from "swr";
|
||||||
|
|
||||||
export default function WaHookHome() {
|
export default function WaHookHome() {
|
||||||
const [page, setPage] = useLocalStorage({ key: "wa-hook-page", defaultValue: 1 });
|
const [page, setPage] = useLocalStorage({ key: "wa-hook-page", defaultValue: 1 });
|
||||||
const { data, error, isLoading, mutate } = useSWR(
|
const { data, error, isLoading, mutate } = useSWR(
|
||||||
"/wa-hook",
|
`/wa-hook?page=${page}`,
|
||||||
() => apiFetch["wa-hook"].list.get({ query: { page, limit: 10 } }),
|
() => apiFetch["wa-hook"].list.get({ query: { page, limit: 10 } }),
|
||||||
{
|
{
|
||||||
refreshInterval: 4000,
|
refreshInterval: 4000,
|
||||||
revalidateOnFocus: true,
|
revalidateOnFocus: true,
|
||||||
revalidateOnReconnect: true,
|
|
||||||
dedupingInterval: 3000,
|
dedupingInterval: 3000,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
useShallowEffect(() => {
|
useShallowEffect(() => {
|
||||||
mutate();
|
mutate();
|
||||||
setPage(data?.data?.list?.length || 1);
|
}, [page]);
|
||||||
}, []);
|
|
||||||
|
|
||||||
async function handleReset() {
|
async function handleReset() {
|
||||||
await apiFetch["wa-hook"].reset.post();
|
await apiFetch["wa-hook"].reset.post();
|
||||||
mutate();
|
mutate();
|
||||||
showNotification({
|
showNotification({
|
||||||
title: "Reset Completed",
|
title: "Reset Completed",
|
||||||
message: "WhatsApp Hook data has been successfully reset.",
|
message: "All WhatsApp Hook data has been cleared.",
|
||||||
color: "teal",
|
color: "teal",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isLoading) return <Skeleton height={500} radius="lg" />;
|
if (isLoading) return <Skeleton height={600} radius="lg" />;
|
||||||
if (error)
|
if (error)
|
||||||
return (
|
return (
|
||||||
<Container p="xl">
|
<Container p="xl">
|
||||||
<Text c="red.5" ta="center" fz="lg" fw={500}>
|
<Text c="red.5" ta="center" fz="lg" fw={500}>
|
||||||
Failed to load data: {error.message}
|
Failed to load webhook data.
|
||||||
</Text>
|
</Text>
|
||||||
</Container>
|
</Container>
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container size="lg" p="lg" style={{ backgroundColor: "#191919", borderRadius: 20 }}>
|
<Container
|
||||||
|
size="lg"
|
||||||
|
p="xl"
|
||||||
|
style={{
|
||||||
|
background: "linear-gradient(145deg, #1a1a1a 0%, #111 100%)",
|
||||||
|
borderRadius: 24,
|
||||||
|
border: "1px solid rgba(0,255,200,0.15)",
|
||||||
|
boxShadow: "0 0 30px rgba(0,255,200,0.1)",
|
||||||
|
}}
|
||||||
|
>
|
||||||
<Stack gap="xl">
|
<Stack gap="xl">
|
||||||
<Group justify="space-between" align="center">
|
<Group justify="space-between" align="center">
|
||||||
<Title order={2} c="#EAEAEA" fw={700} style={{ letterSpacing: 0.5 }}>
|
<Stack gap={2}>
|
||||||
WhatsApp Hook Monitor
|
<Title order={2} c="#EAEAEA" fw={700} style={{ letterSpacing: 0.5 }}>
|
||||||
</Title>
|
WhatsApp Hook Monitor
|
||||||
|
</Title>
|
||||||
|
<Text c="#9A9A9A" fz="sm">
|
||||||
|
Real-time webhook activity and message tracking
|
||||||
|
</Text>
|
||||||
|
</Stack>
|
||||||
<Tooltip label="Reset all webhook data" withArrow color="teal">
|
<Tooltip label="Reset all webhook data" withArrow color="teal">
|
||||||
<Button
|
<Button
|
||||||
onClick={handleReset}
|
onClick={handleReset}
|
||||||
@@ -71,13 +91,16 @@ export default function WaHookHome() {
|
|||||||
variant="gradient"
|
variant="gradient"
|
||||||
gradient={{ from: "#00FFC8", to: "#00FFFF", deg: 45 }}
|
gradient={{ from: "#00FFC8", to: "#00FFFF", deg: 45 }}
|
||||||
radius="xl"
|
radius="xl"
|
||||||
|
size="md"
|
||||||
>
|
>
|
||||||
Reset
|
Reset Data
|
||||||
</Button>
|
</Button>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</Group>
|
</Group>
|
||||||
|
|
||||||
<ScrollArea style={{ height: 600 }}>
|
<Divider color="rgba(0,255,200,0.2)" />
|
||||||
|
|
||||||
|
<ScrollArea h={600} type="always" scrollHideDelay={0}>
|
||||||
<Stack gap="md">
|
<Stack gap="md">
|
||||||
{data?.data?.list?.length ? (
|
{data?.data?.list?.length ? (
|
||||||
data.data.list.map((item) => {
|
data.data.list.map((item) => {
|
||||||
@@ -88,44 +111,55 @@ export default function WaHookHome() {
|
|||||||
<Card
|
<Card
|
||||||
key={item.id}
|
key={item.id}
|
||||||
radius="lg"
|
radius="lg"
|
||||||
|
p="lg"
|
||||||
style={{
|
style={{
|
||||||
background:
|
background:
|
||||||
"linear-gradient(145deg, rgba(45,45,45,0.8) 0%, rgba(25,25,25,0.95) 100%)",
|
"linear-gradient(160deg, rgba(45,45,45,0.9) 0%, rgba(25,25,25,0.95) 100%)",
|
||||||
backdropFilter: "blur(12px)",
|
backdropFilter: "blur(14px)",
|
||||||
border: "1px solid rgba(0,255,200,0.2)",
|
border: "1px solid rgba(0,255,200,0.25)",
|
||||||
boxShadow: "0 0 10px rgba(0,255,200,0.15)",
|
boxShadow: "0 0 20px rgba(0,255,200,0.1)",
|
||||||
|
transition: "all 0.2s ease",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Stack gap={6}>
|
<Stack gap={8}>
|
||||||
<Group gap="xs">
|
<Group gap="xs" align="center">
|
||||||
<IconUser size={16} color="#00FFC8" />
|
<IconUser size={16} color="#00FFC8" />
|
||||||
<Text c="#EAEAEA" fw={500}>
|
<Text c="#EAEAEA" fw={500}>
|
||||||
{contact?.profile?.name || "Unknown"}
|
{contact?.profile?.name || "Unknown Sender"}
|
||||||
</Text>
|
</Text>
|
||||||
</Group>
|
</Group>
|
||||||
|
|
||||||
<Group gap="xs">
|
<Group gap="xs" align="center">
|
||||||
<IconMessageCircle size={16} color="#00FFFF" />
|
<IconMessageCircle size={16} color="#00FFFF" />
|
||||||
<Text c="#9A9A9A">{msg?.text?.body || "(No message body)"}</Text>
|
<Text c="#9A9A9A" fz="sm">
|
||||||
|
{msg?.text?.body || "(No message content)"}
|
||||||
|
</Text>
|
||||||
</Group>
|
</Group>
|
||||||
|
|
||||||
<Group gap="xs">
|
<Group gap="xs" align="center">
|
||||||
<IconHash size={16} color="#00FFC8" />
|
<IconHash size={16} color="#00FFC8" />
|
||||||
<Text c="#9A9A9A" fz="sm">
|
<Text c="#9A9A9A" fz="xs">
|
||||||
{msg?.id}
|
{msg?.id}
|
||||||
</Text>
|
</Text>
|
||||||
</Group>
|
</Group>
|
||||||
|
|
||||||
<Group gap="xs">
|
<Group gap="xs" align="center">
|
||||||
<IconCalendar size={16} color="#00FFFF" />
|
<IconCalendar size={16} color="#00FFFF" />
|
||||||
<Text c="#9A9A9A" fz="sm">
|
<Text c="#9A9A9A" fz="xs">
|
||||||
{dayjs(Number(msg?.timestamp) * 1000).format("YYYY-MM-DD HH:mm:ss")}
|
{dayjs(Number(msg?.timestamp) * 1000).format("YYYY-MM-DD HH:mm:ss")}
|
||||||
</Text>
|
</Text>
|
||||||
</Group>
|
</Group>
|
||||||
|
|
||||||
<Group gap="xs">
|
<Group gap="xs" align="center">
|
||||||
<IconCode size={16} color="#B554FF" />
|
<IconCode size={16} color="#B554FF" />
|
||||||
<Badge color="grape" radius="sm" variant="light">
|
<Badge
|
||||||
|
color="grape"
|
||||||
|
radius="sm"
|
||||||
|
variant="light"
|
||||||
|
styles={{
|
||||||
|
root: { backgroundColor: "rgba(181,84,255,0.15)", color: "#EAEAEA" },
|
||||||
|
}}
|
||||||
|
>
|
||||||
{msg?.type || "Unknown"}
|
{msg?.type || "Unknown"}
|
||||||
</Badge>
|
</Badge>
|
||||||
</Group>
|
</Group>
|
||||||
@@ -135,13 +169,25 @@ export default function WaHookHome() {
|
|||||||
p="sm"
|
p="sm"
|
||||||
radius="md"
|
radius="md"
|
||||||
style={{
|
style={{
|
||||||
backgroundColor: "#2D2D2D",
|
backgroundColor: "rgba(45,45,45,0.7)",
|
||||||
border: "1px solid rgba(0,255,255,0.1)",
|
border: "1px solid rgba(0,255,255,0.15)",
|
||||||
|
boxShadow: "inset 0 0 10px rgba(0,255,255,0.1)",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Text c="#EAEAEA" fz="sm">
|
<Stack gap={4}>
|
||||||
{JSON.stringify(answer, null, 2)}
|
<Text c="#EAEAEA" fw={500} fz="sm">
|
||||||
</Text>
|
Flow Response
|
||||||
|
</Text>
|
||||||
|
<Text c="#9A9A9A" fz="xs">
|
||||||
|
id: {answer.id}
|
||||||
|
</Text>
|
||||||
|
<Text c="#9A9A9A" fz="xs">
|
||||||
|
type: {answer.type}
|
||||||
|
</Text>
|
||||||
|
<Text c="#EAEAEA" fz="sm">
|
||||||
|
{answer.text}
|
||||||
|
</Text>
|
||||||
|
</Stack>
|
||||||
</Card>
|
</Card>
|
||||||
)}
|
)}
|
||||||
</Stack>
|
</Stack>
|
||||||
@@ -155,21 +201,21 @@ export default function WaHookHome() {
|
|||||||
backgroundColor: "#2D2D2D",
|
backgroundColor: "#2D2D2D",
|
||||||
border: "1px solid rgba(0,255,255,0.1)",
|
border: "1px solid rgba(0,255,255,0.1)",
|
||||||
textAlign: "center",
|
textAlign: "center",
|
||||||
padding: 40,
|
padding: 60,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Text c="#9A9A9A" fz="lg">
|
<Text c="#9A9A9A" fz="lg">
|
||||||
No webhook data available yet.
|
No webhook activity detected yet.
|
||||||
</Text>
|
</Text>
|
||||||
</Card>
|
</Card>
|
||||||
)}
|
)}
|
||||||
</Stack>
|
</Stack>
|
||||||
</ScrollArea>
|
</ScrollArea>
|
||||||
|
|
||||||
<Group justify="center" mt="md">
|
<Group justify="center" mt="xl">
|
||||||
<Pagination
|
<Pagination
|
||||||
value={page}
|
value={page}
|
||||||
total={data?.data?.count || 1}
|
total={Math.ceil((data?.data?.count || 1) / 10)}
|
||||||
onChange={(value) => {
|
onChange={(value) => {
|
||||||
setPage(value);
|
setPage(value);
|
||||||
mutate();
|
mutate();
|
||||||
@@ -177,6 +223,14 @@ export default function WaHookHome() {
|
|||||||
radius="xl"
|
radius="xl"
|
||||||
withEdges
|
withEdges
|
||||||
color="teal"
|
color="teal"
|
||||||
|
size="md"
|
||||||
|
styles={{
|
||||||
|
control: {
|
||||||
|
backgroundColor: "#2D2D2D",
|
||||||
|
border: "1px solid rgba(0,255,200,0.15)",
|
||||||
|
color: "#EAEAEA",
|
||||||
|
},
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</Group>
|
</Group>
|
||||||
</Stack>
|
</Stack>
|
||||||
|
|||||||
Reference in New Issue
Block a user