diff options
author | polwex <polwex@sortug.com> | 2025-05-29 12:10:22 +0700 |
---|---|---|
committer | polwex <polwex@sortug.com> | 2025-05-29 12:10:22 +0700 |
commit | a3f24ea79b14394b24c4b60a010651eb29eeb872 (patch) | |
tree | cb1c4937084116f66a59727ee752afd974714c8e /src/zoom/ServerSyllable.tsx | |
parent | 7abf2227438362ad30820ee236405ec1b57a40b6 (diff) |
glorious new db
Diffstat (limited to 'src/zoom/ServerSyllable.tsx')
-rw-r--r-- | src/zoom/ServerSyllable.tsx | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/src/zoom/ServerSyllable.tsx b/src/zoom/ServerSyllable.tsx new file mode 100644 index 0000000..907b956 --- /dev/null +++ b/src/zoom/ServerSyllable.tsx @@ -0,0 +1,84 @@ +// This is a Server Component +import React, { Suspense } from "react"; +import db from "@/lib/db"; +import { + Card, + CardHeader, + CardDescription, + CardContent, + CardFooter, + CardTitle, +} from "@/components/ui/card"; +import { NLP } from "sortug-ai"; +import { Volume2, Link as LinkIcon } from "lucide-react"; +import { isTonal } from "@/lib/lang/utils"; +import { CardResponse, SyllableToken } from "@/lib/types/cards"; +import { deconstructSyllable } from "@/lib/calls/nlp"; + +export default async function (props: { data: CardResponse }) { + const { expression } = props.data; + const { result } = await deconstructSyllable(expression.spelling); + + return ( + <div className="absolute w-full h-full bg-white dark:bg-slate-800 rounded-xl backface-hidden flex flex-col justify-center gap-8 items-center p-6"> + <p className="text-5xl cursor-pointer hover:text-blue-700 font-semibold text-slate-800 dark:text-slate-100 text-center"> + {expression.spelling} + </p> + <Suspense fallback={<IpaDisplay ipaEntries={expression.ipa} />}> + <Deconstructed syl={result} /> + </Suspense> + </div> + ); +} + +function Deconstructed({ syl }: { syl: SyllableToken[] }) { + return ( + <div> + {syl.map((tok) => ( + <span></span> + ))} + </div> + ); +} + +// Helper component for IPA display +const IpaDisplay = ({ + ipaEntries, +}: { + ipaEntries: Array<{ ipa: string; tags?: string[] }>; +}) => { + if (!ipaEntries || ipaEntries.length === 0) return null; + return ( + <div className="flex items-center space-x-2 flex-wrap"> + {ipaEntries.map((entry, index) => { + const tags = entry.tags ? entry.tags : []; + return ( + <span key={index} className="text-lg text-blue-600 font-serif"> + {entry.ipa}{" "} + {tags.length > 0 && ( + <span className="text-xs text-gray-500">({tags.join(", ")})</span> + )} + </span> + ); + })} + <button + className="p-1 text-blue-500 hover:text-blue-700 transition-colors" + title="Pronounce" + // onClick={() => { + // /* Pronunciation logic would be client-side or a server roundtrip for audio file. */ alert( + // "Pronunciation feature not implemented for server component.", + // ); + // }} + > + <Volume2 size={20} /> + </button> + </div> + ); +}; + +function Tones({ text, lang }: WordProps) { + return <div></div>; +} +function NotTones({ text, lang }: WordProps) { + return <div></div>; +} |