tambahannya

This commit is contained in:
bipproduction
2025-10-23 17:02:14 +08:00
parent 5b23ef0d8a
commit f045b61717
4 changed files with 44 additions and 38 deletions

View File

@@ -134,6 +134,7 @@ function FlowWaHookForm() {
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const [waPhoneNumberId, setWaPhoneNumberId] = useState(""); const [waPhoneNumberId, setWaPhoneNumberId] = useState("");
const [waToken, setWaToken] = useState(""); const [waToken, setWaToken] = useState("");
const [active, setActive] = useState(false);
useShallowEffect(() => { useShallowEffect(() => {
const loadCredentials = async () => { const loadCredentials = async () => {
@@ -145,6 +146,7 @@ function FlowWaHookForm() {
setFlowToken(data?.data?.flowToken || ""); setFlowToken(data?.data?.flowToken || "");
setWaPhoneNumberId(data?.data?.waPhoneNumberId || ""); setWaPhoneNumberId(data?.data?.waPhoneNumberId || "");
setWaToken(data?.data?.waToken || ""); setWaToken(data?.data?.waToken || "");
setActive(data?.data?.active || false);
} }
}; };
loadCredentials(); loadCredentials();
@@ -156,7 +158,7 @@ function FlowWaHookForm() {
return; return;
} }
setLoading(true); setLoading(true);
const { error } = await apiFetch.api.chatflows["url-token"].put({ flowUrl, flowToken, waPhoneNumberId, waToken }); const { error } = await apiFetch.api.chatflows["url-token"].put({ active, flowUrl, flowToken, waPhoneNumberId, waToken });
if (error) { if (error) {
showNotification({ title: "Error", message: "Failed to update credentials", color: "red" }); showNotification({ title: "Error", message: "Failed to update credentials", color: "red" });
} else { } else {
@@ -174,6 +176,7 @@ function FlowWaHookForm() {
<Card radius="md" p="lg" withBorder> <Card radius="md" p="lg" withBorder>
<Stack gap="lg"> <Stack gap="lg">
<Title order={3}>Flow Credentials</Title> <Title order={3}>Flow Credentials</Title>
<Checkbox label="Active" checked={active} onChange={(e) => setActive(e.currentTarget.checked)} />
<Stack gap="md"> <Stack gap="md">
<TextInput label="Flow URL" placeholder="Enter flow URL" value={flowUrl} onChange={(e) => setFlowUrl(e.currentTarget.value)} /> <TextInput label="Flow URL" placeholder="Enter flow URL" value={flowUrl} onChange={(e) => setFlowUrl(e.currentTarget.value)} />
<PasswordInput <PasswordInput

View File

@@ -105,9 +105,8 @@ export default function WaHookHome() {
<Stack gap="md"> <Stack gap="md">
{data?.data?.list?.length ? ( {data?.data?.list?.length ? (
data.data.list.map((item) => { data.data.list.map((item) => {
const msg = item.data?.entry?.[0]?.changes?.[0]?.value?.messages?.[0]; const parsed = JSON.parse((item.data as any) || "{}");
const contact = item.data?.entry?.[0]?.changes?.[0]?.value?.contacts?.[0];
const answer = (item.data as any)?.answer;
return ( return (
<Card <Card
key={item.id} key={item.id}
@@ -116,77 +115,75 @@ export default function WaHookHome() {
style={{ style={{
background: background:
"linear-gradient(160deg, rgba(45,45,45,0.9) 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(14px)",
border: "1px solid rgba(0,255,200,0.25)", border: "1px solid rgba(0,255,200,0.25)",
boxShadow: "0 0 20px rgba(0,255,200,0.1)",
transition: "all 0.2s ease",
}} }}
> >
<Stack gap={8}> <Stack gap={8}>
{/* Nama & Nomor Pengirim */}
<Group gap="xs" align="center"> <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 Sender"} {parsed.name || "Unknown Sender"} ({parsed.number || "No Number"})
</Text> </Text>
</Group> </Group>
{/* Pertanyaan / Pesan */}
<Group gap="xs" align="center"> <Group gap="xs" align="center">
<IconMessageCircle size={16} color="#00FFFF" /> <IconMessageCircle size={16} color="#00FFFF" />
<Text c="#9A9A9A" fz="sm"> <Text c="#9A9A9A" fz="sm">
{msg?.text?.body || "(No message content)"} {parsed.question || "(No question)"}
</Text> </Text>
</Group> </Group>
{/* ID Record */}
<Group gap="xs" align="center"> <Group gap="xs" align="center">
<IconHash size={16} color="#00FFC8" /> <IconHash size={16} color="#00FFC8" />
<Text c="#9A9A9A" fz="xs"> <Text c="#9A9A9A" fz="xs">
{msg?.id} {item.id}
</Text> </Text>
</Group> </Group>
{/* Timestamp */}
<Group gap="xs" align="center"> <Group gap="xs" align="center">
<IconCalendar size={16} color="#00FFFF" /> <IconCalendar size={16} color="#00FFFF" />
<Text c="#9A9A9A" fz="xs"> <Text c="#9A9A9A" fz="xs">
{dayjs(Number(msg?.timestamp) * 1000).format("YYYY-MM-DD HH:mm:ss")} {dayjs(item.createdAt).format("YYYY-MM-DD HH:mm:ss")}
</Text> </Text>
</Group> </Group>
<Group gap="xs" align="center"> {/* Flow ID */}
<IconCode size={16} color="#B554FF" /> {parsed.flowId && (
<Badge <Group gap="xs" align="center">
color="grape" <IconCode size={16} color="#B554FF" />
radius="sm" <Badge
variant="light" color="grape"
styles={{ radius="sm"
root: { backgroundColor: "rgba(181,84,255,0.15)", color: "#EAEAEA" }, variant="light"
}} styles={{
> root: { backgroundColor: "rgba(181,84,255,0.15)", color: "#EAEAEA" },
{msg?.type || "Unknown"} }}
</Badge> >
</Group> Flow: {parsed.flowId}
</Badge>
</Group>
)}
{answer && ( {/* Jawaban */}
{parsed.answer && (
<Card <Card
p="sm" p="sm"
radius="md" radius="md"
style={{ style={{
backgroundColor: "rgba(45,45,45,0.7)", backgroundColor: "rgba(45,45,45,0.7)",
border: "1px solid rgba(0,255,255,0.15)", border: "1px solid rgba(0,255,255,0.15)",
boxShadow: "inset 0 0 10px rgba(0,255,255,0.1)",
}} }}
> >
<Stack gap={4}> <Stack gap={4}>
<Text c="#EAEAEA" fw={500} fz="sm"> <Text c="#EAEAEA" fw={500} fz="sm">
Flow Response Bot Answer
</Text>
<Text c="#9A9A9A" fz="xs">
id: {answer.flowId}
</Text>
<Text c="#9A9A9A" fz="xs">
type: {answer.type}
</Text> </Text>
<Text c="#EAEAEA" fz="sm"> <Text c="#EAEAEA" fz="sm">
{answer.text} {parsed.answer}
</Text> </Text>
</Stack> </Stack>
</Card> </Card>
@@ -210,6 +207,7 @@ export default function WaHookHome() {
</Text> </Text>
</Card> </Card>
)} )}
</Stack> </Stack>
<Group justify="center" mt="xl"> <Group justify="center" mt="xl">

View File

@@ -8,7 +8,8 @@ export default function WaHookLayout() {
<Container size="xl" w={"100%"}> <Container size="xl" w={"100%"}>
<Group justify="flex-start" p={"md"}> <Group justify="flex-start" p={"md"}>
<Button <Button
size="compact-xs" color="cyan"
size="xs"
radius={"lg"} radius={"lg"}
onClick={() => onClick={() =>
navigate(clientRoutes["/sq/dashboard/wa-hook/flow-wa-hook"]) navigate(clientRoutes["/sq/dashboard/wa-hook/flow-wa-hook"])

View File

@@ -159,12 +159,13 @@ const FlowRoute = new Elysia({
flowToken: true, flowToken: true,
waPhoneNumberId: true, waPhoneNumberId: true,
waToken: true, waToken: true,
active: true,
}, },
}) })
if (!result) { if (!result) {
return { data: { flowUrl: null, flowToken: null, waPhoneNumberId: null, waToken: null } } return { data: null }
} }
return { data: { flowUrl: result.flowUrl, flowToken: result.flowToken, waPhoneNumberId: result.waPhoneNumberId, waToken: result.waToken } } return { data: { active: result.active, flowUrl: result.flowUrl, flowToken: result.flowToken, waPhoneNumberId: result.waPhoneNumberId, waToken: result.waToken } }
}, { }, {
detail: { detail: {
summary: "Get flow url and token", summary: "Get flow url and token",
@@ -174,7 +175,7 @@ const FlowRoute = new Elysia({
.put( .put(
'/url-token', '/url-token',
async ctx => { async ctx => {
const { flowUrl, flowToken, waPhoneNumberId, waToken } = ctx.body const { flowUrl, flowToken, waPhoneNumberId, waToken, active } = ctx.body
const result = await prisma.chatFlows.upsert({ const result = await prisma.chatFlows.upsert({
where: { where: {
id: "1", id: "1",
@@ -184,6 +185,7 @@ const FlowRoute = new Elysia({
flowToken: flowToken, flowToken: flowToken,
waPhoneNumberId: waPhoneNumberId, waPhoneNumberId: waPhoneNumberId,
waToken: waToken, waToken: waToken,
active: active,
}, },
create: { create: {
id: "1", id: "1",
@@ -191,6 +193,7 @@ const FlowRoute = new Elysia({
flowToken: flowToken, flowToken: flowToken,
waPhoneNumberId: waPhoneNumberId, waPhoneNumberId: waPhoneNumberId,
waToken: waToken, waToken: waToken,
active: active,
}, },
}) })
return { data: result } return { data: result }
@@ -201,6 +204,7 @@ const FlowRoute = new Elysia({
flowToken: t.String(), flowToken: t.String(),
waPhoneNumberId: t.String(), waPhoneNumberId: t.String(),
waToken: t.String(), waToken: t.String(),
active: t.Boolean(),
}), }),
detail: { detail: {
summary: "Update flow url and token", summary: "Update flow url and token",