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