-
+
+ {form.getValues().content}
+
{form.getValues().notes && (
diff --git a/client/src/pages/authors/AuthorProfile.tsx b/client/src/pages/authors/AuthorProfile.tsx
index 669c010..b0dcd94 100644
--- a/client/src/pages/authors/AuthorProfile.tsx
+++ b/client/src/pages/authors/AuthorProfile.tsx
@@ -76,9 +76,16 @@ export default function AuthorProfile() {
});
// Get works for the author
- const { data: works, isLoading: worksLoading } = useQuery({
+ const { data: works, isLoading: worksLoading } = useQuery({
queryKey: [`/api/authors/${slug}/works`],
enabled: !!author,
+ select: (data: any[]) =>
+ data.map((work) => ({
+ ...work,
+ tags: work.tags?.map((tag: any) =>
+ typeof tag === "string" ? { name: tag, id: tag, type: "general", createdAt: "" } : tag,
+ ),
+ })),
});
// Get timeline events
@@ -117,7 +124,7 @@ export default function AuthorProfile() {
const genres = Array.from(
new Set(
works
- ?.flatMap((work) => work.tags?.map((tag) => tag.name) || [])
+ ?.flatMap((work) => work.tags?.map((tag: any) => tag.name) || [])
.filter(Boolean)
)
);
@@ -132,7 +139,7 @@ export default function AuthorProfile() {
const filteredWorks = works?.filter((work) => {
if (
selectedGenre &&
- (!work.tags || !work.tags.some((tag) => tag.name === selectedGenre))
+ (!work.tags || !work.tags.some((tag: any) => tag.name === selectedGenre))
) {
return false;
}
diff --git a/client/src/pages/dashboard/BlogEdit.tsx b/client/src/pages/dashboard/BlogEdit.tsx
index a6606eb..92c2403 100644
--- a/client/src/pages/dashboard/BlogEdit.tsx
+++ b/client/src/pages/dashboard/BlogEdit.tsx
@@ -19,6 +19,7 @@ const BlogEdit: React.FC = () => {
useEffect(() => {
async function fetchPost() {
try {
+ if (!id) throw new Error("No ID provided");
const data = await getBlogPost(id);
setPost(data);
} catch {
diff --git a/client/src/pages/dashboard/BlogManagement.tsx b/client/src/pages/dashboard/BlogManagement.tsx
index 74a3dce..c26bd06 100644
--- a/client/src/pages/dashboard/BlogManagement.tsx
+++ b/client/src/pages/dashboard/BlogManagement.tsx
@@ -49,7 +49,7 @@ import type { BlogPostListItem } from "@/lib/types";
export default function BlogManagement() {
const { canManageContent } = useAuth();
const [searchQuery, setSearchQuery] = useState("");
- const [postToDelete, setPostToDelete] = useState(null);
+ const [postToDelete, setPostToDelete] = useState(null);
const queryClient = useQueryClient();
const { toast } = useToast();
@@ -60,10 +60,8 @@ export default function BlogManagement() {
// Delete mutation
const deletePostMutation = useMutation({
- mutationFn: async (postId: number) => {
- return apiRequest(`/api/blog/${postId}`, {
- method: "DELETE",
- });
+ mutationFn: async (postId: string) => {
+ return apiRequest("DELETE", `/api/blog/${postId}`);
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["/api/blog"] });
diff --git a/client/src/pages/dashboard/Dashboard.tsx b/client/src/pages/dashboard/Dashboard.tsx
index bc5ee1e..c578e08 100644
--- a/client/src/pages/dashboard/Dashboard.tsx
+++ b/client/src/pages/dashboard/Dashboard.tsx
@@ -214,7 +214,7 @@ export default function Dashboard() {
))
- : recentWorks?.slice(0, 3).map((work: any) => (
+ : Array.isArray(recentWorks) && recentWorks.slice(0, 3).map((work: any) => (
diff --git a/client/src/pages/user/Profile.tsx b/client/src/pages/user/Profile.tsx
index 44c648c..e452921 100644
--- a/client/src/pages/user/Profile.tsx
+++ b/client/src/pages/user/Profile.tsx
@@ -25,7 +25,6 @@ export default function Profile() {
// Fetch user's bookmarks with work details
const { data: bookmarks, isLoading: bookmarksLoading } = useQuery({
queryKey: [`/api/users/${DEMO_USER_ID}/bookmarks`],
- // @ts-expect-error - Complex type transformation causing inference issues
select: (data: any[]) =>
data.map((bookmark) => ({
...bookmark,
diff --git a/client/src/pages/works/WorkCompare.tsx b/client/src/pages/works/WorkCompare.tsx
deleted file mode 100644
index 56e923a..0000000
--- a/client/src/pages/works/WorkCompare.tsx
+++ /dev/null
@@ -1,216 +0,0 @@
-import type { Translation, Work } from "@shared/schema";
-import { useQuery } from "@tanstack/react-query";
-import { Maximize2, Minimize2 } from "lucide-react";
-import { useState } from "react";
-import { Link, useParams } from "wouter";
-import { PageLayout } from "@/components/layout/PageLayout";
-import { LineNumberedText } from "@/components/reading/LineNumberedText";
-import { Button } from "@/components/ui/button";
-import {
- Select,
- SelectContent,
- SelectItem,
- SelectTrigger,
- SelectValue,
-} from "@/components/ui/select";
-import { Skeleton } from "@/components/ui/skeleton";
-import { useReadingSettings } from "@/hooks/use-reading-settings";
-
-export default function WorkCompare() {
- const { slug, translationId } = useParams();
- const { settings, toggleZenMode } = useReadingSettings();
- const [selectedTranslationId, setSelectedTranslationId] = useState
(
- parseInt(translationId || "0", 10),
- );
- const [highlightedLine, setHighlightedLine] = useState(null);
-
- const { data: work, isLoading: workLoading } = useQuery({
- queryKey: [`/api/works/${slug}`],
- });
-
- const { data: translations, isLoading: translationsLoading } = useQuery<
- Translation[]
- >({
- queryKey: [`/api/works/${slug}/translations`],
- enabled: !!work,
- });
-
- const { data: selectedTranslation, isLoading: translationLoading } =
- useQuery({
- queryKey: [`/api/translations/${selectedTranslationId}`],
- enabled: !!selectedTranslationId,
- });
-
- const handleLineClick = (lineNumber: number) => {
- setHighlightedLine(lineNumber);
-
- // Scroll the corresponding line in the other panel into view
- const otherPanelElement = document.getElementById(
- `line-${lineNumber}-other`,
- );
- if (otherPanelElement) {
- otherPanelElement.scrollIntoView({ behavior: "smooth", block: "center" });
- }
- };
-
- if (workLoading || translationsLoading || translationLoading) {
- return (
-
-
-
-
-
-
-
- {Array.from({ length: 8 }).map((_, i) => (
-
- ))}
-
-
-
-
-
- {Array.from({ length: 8 }).map((_, i) => (
-
- ))}
-
-
-
-
-
- );
- }
-
- if (!work || !translations || !selectedTranslation) {
- return (
-
-
-
Content not found
-
- The work or translation you're looking for could not be found.
-
-
-
-
-
-
- );
- }
-
- return (
-
-
-
-
-
-
- {work.title}{" "}
-
- — Translation Comparison
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {/* Left panel (original) */}
-
-
-
-
-
- {work.language} (Original)
-
-
- {work.author?.name || "Unknown author"},{" "}
- {work.year || "Unknown year"}
-
-
-
-
-
-
-
- {/* Right panel (translation) */}
-
-
-
-
-
- {selectedTranslation.language}
-
-
- Translated by Translator {selectedTranslation.translatorId},{" "}
- {selectedTranslation.year || "Unknown year"}
-
-
-
-
-
-
-
-
-
-
-
-
- );
-}
diff --git a/client/src/pages/works/WorkReading.tsx b/client/src/pages/works/WorkReading.tsx
deleted file mode 100644
index 7739a52..0000000
--- a/client/src/pages/works/WorkReading.tsx
+++ /dev/null
@@ -1,84 +0,0 @@
-import { useQuery } from "@tanstack/react-query";
-import { BookOpen } from "lucide-react";
-import { Link, useParams } from "wouter";
-import { PageLayout } from "@/components/layout/PageLayout";
-import { EnhancedReadingView } from "@/components/reading/EnhancedReadingView";
-import { Button } from "@/components/ui/button";
-import { Skeleton } from "@/components/ui/skeleton";
-import type { TranslationWithDetails, WorkWithDetails } from "@/lib/types";
-
-export default function WorkReading() {
- const { slug } = useParams();
-
- const {
- data: work,
- isLoading: workLoading,
- error: workError,
- } = useQuery({
- queryKey: [`/api/works/${slug}`],
- });
-
- const { data: translations } = useQuery<
- TranslationWithDetails[]
- >({
- queryKey: [`/api/works/${slug}/translations`],
- enabled: !!work,
- });
-
- if (workLoading) {
- return (
-
-
-
- {/* Sidebar skeleton */}
-
-
-
-
-
-
-
- {/* Main content skeleton */}
-
-
-
-
-
- {Array.from({ length: 8 }).map((_, i) => (
-
- ))}
-
-
-
-
-
- );
- }
-
- if (workError || !work) {
- return (
-
-
-
Work not found
-
- The literary work you're looking for could not be found.
-
-
-
-
-
-
-
-
-
- );
- }
-
- return (
-
-
-
- );
-}