From fd86dc15734f3b7126d88f0130897c597100e30a Mon Sep 17 00:00:00 2001 From: polwex Date: Thu, 15 May 2025 20:32:25 +0700 Subject: m --- src/components/Main.tsx | 25 +++++--- src/components/Modal.tsx | 55 +++++++++++++++++ src/components/ui/dialog.tsx | 133 ++++++++++++++++++++++++++++++++++++++++++ src/components/zoom/Entry.tsx | 13 ++--- 4 files changed, 208 insertions(+), 18 deletions(-) create mode 100644 src/components/Modal.tsx create mode 100644 src/components/ui/dialog.tsx (limited to 'src/components') diff --git a/src/components/Main.tsx b/src/components/Main.tsx index 2157a91..3e6f3e7 100644 --- a/src/components/Main.tsx +++ b/src/components/Main.tsx @@ -19,6 +19,7 @@ import { CardTitle, } from "@/components/ui/card"; import { Loader2 } from "lucide-react"; // Loading spinner +import { useRouter } from "waku"; const SorlangPage: React.FC = () => { const [textValue, setTextValue] = useState(""); @@ -82,24 +83,30 @@ const SorlangPage: React.FC = () => { }; }, [handlePaste]); - const handleProcessText = async () => { - setIsAnalyzing(true); - const text = textValue.trim(); - if (!text) { - alert("Text area is empty!"); - return; - } + const router = useRouter(); + async function fetchNLP(text: string, app: "spacy" | "stanza") { const opts = { method: "POST", headers: { "Content-type": "application/json" }, - body: JSON.stringify({ text, app: "spacy" }), + body: JSON.stringify({ text, app }), }; const res = await fetch("/api/nlp", opts); const j = await res.json(); console.log("j", j); if ("ok" in j) { - console.log("good"); + sessionStorage.setItem(`${app}res`, JSON.stringify(j.ok)); + } + } + + const handleProcessText = async () => { + setIsAnalyzing(true); + const text = textValue.trim(); + if (!text) { + alert("Text area is empty!"); + return; } + await Promise.all([fetchNLP(text, "spacy"), fetchNLP(text, "stanza")]); + router.push("/zoom"); setIsAnalyzing(false); }; diff --git a/src/components/Modal.tsx b/src/components/Modal.tsx new file mode 100644 index 0000000..4c52caa --- /dev/null +++ b/src/components/Modal.tsx @@ -0,0 +1,55 @@ +"use client"; + +import { useState, ReactNode, useEffect } from "react"; + +interface ClientModalProps { + isOpen: boolean; + onClose: () => void; + children: ReactNode; // This will receive the Server Component's output + title?: string; +} + +export default function ClientModal({ + isOpen, + onClose, + children, +}: ClientModalProps) { + // Optional: Prevent body scroll when modal is open + useEffect(() => { + if (isOpen) { + document.body.style.overflow = "hidden"; + } else { + document.body.style.overflow = "unset"; + } + return () => { + document.body.style.overflow = "unset"; + }; + }, [isOpen]); + + if (!isOpen) { + return null; + } + + return ( +
+
e.stopPropagation()} // Prevent click from closing modal if clicking inside content + > + +
+ {children} {/* Server Component content will be rendered here */} +
+
+
+ ); +} diff --git a/src/components/ui/dialog.tsx b/src/components/ui/dialog.tsx new file mode 100644 index 0000000..981e999 --- /dev/null +++ b/src/components/ui/dialog.tsx @@ -0,0 +1,133 @@ +import * as React from "react" +import * as DialogPrimitive from "@radix-ui/react-dialog" +import { XIcon } from "lucide-react" + +import { cn } from "@/lib/utils" + +function Dialog({ + ...props +}: React.ComponentProps) { + return +} + +function DialogTrigger({ + ...props +}: React.ComponentProps) { + return +} + +function DialogPortal({ + ...props +}: React.ComponentProps) { + return +} + +function DialogClose({ + ...props +}: React.ComponentProps) { + return +} + +function DialogOverlay({ + className, + ...props +}: React.ComponentProps) { + return ( + + ) +} + +function DialogContent({ + className, + children, + ...props +}: React.ComponentProps) { + return ( + + + + {children} + + + Close + + + + ) +} + +function DialogHeader({ className, ...props }: React.ComponentProps<"div">) { + return ( +
+ ) +} + +function DialogFooter({ className, ...props }: React.ComponentProps<"div">) { + return ( +
+ ) +} + +function DialogTitle({ + className, + ...props +}: React.ComponentProps) { + return ( + + ) +} + +function DialogDescription({ + className, + ...props +}: React.ComponentProps) { + return ( + + ) +} + +export { + Dialog, + DialogClose, + DialogContent, + DialogDescription, + DialogFooter, + DialogHeader, + DialogOverlay, + DialogPortal, + DialogTitle, + DialogTrigger, +} diff --git a/src/components/zoom/Entry.tsx b/src/components/zoom/Entry.tsx index a60c75c..9e6eed9 100644 --- a/src/components/zoom/Entry.tsx +++ b/src/components/zoom/Entry.tsx @@ -1,14 +1,9 @@ -"use client"; -import { Zoom } from "prosody-ui"; +import * as Zoom from "@/zoom"; +import { useEffect, useState } from "react"; import { NLP } from "sortug-ai"; -type Props = { text: string; doc: NLP.Spacy.SpacyRes }; -function ZoomText(props: Props) { - return ( -
- -
- ); +function ZoomText() { + return
; } export default ZoomText; -- cgit v1.2.3