From a3f24ea79b14394b24c4b60a010651eb29eeb872 Mon Sep 17 00:00:00 2001 From: polwex Date: Thu, 29 May 2025 12:10:22 +0700 Subject: glorious new db --- src/components/Flashcard/ServerCard.tsx | 43 +++++++---- src/components/Flashcard/Syllable.tsx | 44 ++++++++++++ src/components/Flashcard/SyllableModal.tsx | 110 +++++++++++++++++++++++++++++ src/components/Flashcard/SyllableSpan.tsx | 45 ++++++++++++ 4 files changed, 230 insertions(+), 12 deletions(-) create mode 100644 src/components/Flashcard/Syllable.tsx create mode 100644 src/components/Flashcard/SyllableModal.tsx create mode 100644 src/components/Flashcard/SyllableSpan.tsx (limited to 'src/components/Flashcard') diff --git a/src/components/Flashcard/ServerCard.tsx b/src/components/Flashcard/ServerCard.tsx index d377dce..df37ba8 100644 --- a/src/components/Flashcard/ServerCard.tsx +++ b/src/components/Flashcard/ServerCard.tsx @@ -23,13 +23,21 @@ import { WordData, } from "@/zoom/logic/types"; import { CardResponse } from "@/lib/types/cards"; -import { thaiData } from "@/pages/api/nlp"; +import { thaiData } from "@/lib/calls/nlp"; import { getRandomHexColor } from "@/lib/utils"; import { BookmarkIconito } from "./BookmarkButton"; +import SyllableSpan from "./SyllableSpan"; +import SyllableCard from "./Syllable"; -export async function CardFront({ data }: { data: CardResponse }) { +export async function CardFront({ + data, + needFetch = true, +}: { + data: CardResponse; + needFetch?: boolean; +}) { // const extraData = data.expression.lang - const extraData = await thaiData(data.expression.spelling); + const extraData = needFetch ? await thaiData(data.expression.spelling) : []; // console.log({ extraData }); return ( @@ -42,15 +50,26 @@ export async function CardFront({ data }: { data: CardResponse }) { } >

- {extraData[0]?.syllables.map((syl, i) => ( - - {syl} - - ))} + {needFetch ? ( + extraData[0]?.syllables.map((syl, i) => ( + // + // {syl} + // + + )) + ) : ( +

+ {data.expression.spelling} +

+ )}

diff --git a/src/components/Flashcard/Syllable.tsx b/src/components/Flashcard/Syllable.tsx new file mode 100644 index 0000000..e470a4b --- /dev/null +++ b/src/components/Flashcard/Syllable.tsx @@ -0,0 +1,44 @@ +"use client"; + +import { syllableAction, thaiAnalysis } from "@/actions/lang"; +import { CardResponse } from "@/lib/types/cards"; +import { ReactNode, useState, useTransition } from "react"; +import { Spinner } from "../ui/spinner"; +import Modal from "@/components/Modal"; +import { getRandomHexColor } from "@/lib/utils"; + +const SyllableCard: React.FC<{ data: CardResponse }> = ({ data }) => { + return ( +
+

+ {data.expression.spelling} +

+ +
+ ); +}; + +export default SyllableCard; + +const IpaDisplay = ({ + ipaEntries, +}: { + ipaEntries: Array<{ ipa: string; tags?: string[] }>; +}) => { + if (!ipaEntries || ipaEntries.length === 0) return null; + return ( +
+ {ipaEntries.map((entry, index) => { + const tags = entry.tags ? entry.tags : []; + return ( + + {entry.ipa}{" "} + {tags.length > 0 && ( + ({tags.join(", ")}) + )} + + ); + })} +
+ ); +}; diff --git a/src/components/Flashcard/SyllableModal.tsx b/src/components/Flashcard/SyllableModal.tsx new file mode 100644 index 0000000..a00fd10 --- /dev/null +++ b/src/components/Flashcard/SyllableModal.tsx @@ -0,0 +1,110 @@ +// This is a Server Component +import React from "react"; +import db from "@/lib/db"; +import { + Card, + CardHeader, + CardDescription, + CardContent, + CardFooter, + CardTitle, +} from "@/components/ui/card"; +import { NLP } from "sortug-ai"; +import { + BookOpen, + Volume2, + Link as LinkIcon, + ChevronDown, + ChevronUp, + Search, + Info, + MessageSquareQuote, + Tags, + ListTree, + Lightbulb, +} from "lucide-react"; +import { + Example, + SubSense, + RelatedEntry, + Sense, + WordData, +} from "@/zoom/logic/types"; +import { isTonal } from "@/lib/lang/utils"; + +type WordProps = { text: string; lang: string }; +export default async function (props: WordProps) { + const { text, lang } = props; + const data = db.fetchWordBySpelling(text, lang); + + if (!data) return

oh...

; + console.log(data.senses[0]); + return ( + + + +

{text}

+
+ + + +
+ + {isTonal(text) ? : } + + +
+ ); + // return ( + //
+ //

{word}

+ //

${word.}

+ //

{word}

+ //

+ // Content rendered on the server at: {new Date().toLocaleTimeString()} + //

+ //
+ // ); +} + +// Helper component for IPA display +const IpaDisplay = ({ + ipaEntries, +}: { + ipaEntries: Array<{ ipa: string; tags?: string[] }>; +}) => { + if (!ipaEntries || ipaEntries.length === 0) return null; + return ( +
+ {ipaEntries.map((entry, index) => { + const tags = entry.tags ? entry.tags : []; + return ( + + {entry.ipa}{" "} + {tags.length > 0 && ( + ({tags.join(", ")}) + )} + + ); + })} + +
+ ); +}; + +function Tones({ text, lang }: WordProps) { + return
; +} +function NotTones({ text, lang }: WordProps) { + return
; +} diff --git a/src/components/Flashcard/SyllableSpan.tsx b/src/components/Flashcard/SyllableSpan.tsx new file mode 100644 index 0000000..445895e --- /dev/null +++ b/src/components/Flashcard/SyllableSpan.tsx @@ -0,0 +1,45 @@ +"use client"; + +import { syllableAction, thaiAnalysis } from "@/actions/lang"; +import { CardResponse } from "@/lib/types/cards"; +import { ReactNode, useState, useTransition } from "react"; +import { Spinner } from "../ui/spinner"; +import Modal from "@/components/Modal"; +import { getRandomHexColor } from "@/lib/utils"; + +const SyllableSpan: React.FC<{ spelling: string; lang: string }> = ({ + spelling, + lang, +}) => { + const [modalContent, setModalContent] = useState(null); + + const closeModal = () => setModalContent(null); + + const [isPending, startTransition] = useTransition(); + const handleClick = (e: React.MouseEvent) => { + e.stopPropagation(); + startTransition(async () => { + const modal = await syllableAction(spelling, lang); + setModalContent(modal); + }); + }; + + return ( + <> + + {spelling} + + {modalContent && ( + + {modalContent} + + )} + + ); +}; + +export default SyllableSpan; -- cgit v1.2.3