Keep author sorting options visible while authors are loading on the page

Wrap Tabs component in a div to maintain its width in Authors.tsx during loading.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: cbacfb18-842a-4116-a907-18c0105ad8ec
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/39b5c689-6e8a-4d5a-9792-69cc81a56534/94b44ce2-af2e-4b59-bb9d-f8907a9baca2.jpg
This commit is contained in:
mukimovd 2025-05-02 00:25:00 +00:00
parent 3a93337390
commit 218c8ff1c1

View File

@ -567,13 +567,15 @@ export default function Authors() {
{/* View controls bar */} {/* View controls bar */}
<div className="flex flex-col sm:flex-row items-start sm:items-center justify-between gap-4 mb-6"> <div className="flex flex-col sm:flex-row items-start sm:items-center justify-between gap-4 mb-6">
<Tabs defaultValue="all" className="w-full sm:w-auto"> <div className="w-full sm:w-auto">
<TabsList className="grid w-full sm:w-auto grid-cols-3"> <Tabs defaultValue="all" className="w-full sm:w-auto">
<TabsTrigger value="all" className="text-sm">All Authors</TabsTrigger> <TabsList className="grid w-full sm:w-auto grid-cols-3">
<TabsTrigger value="alphabetical" className="text-sm">Alphabetical</TabsTrigger> <TabsTrigger value="all" className="text-sm">All Authors</TabsTrigger>
<TabsTrigger value="chronological" className="text-sm">Chronological</TabsTrigger> <TabsTrigger value="alphabetical" className="text-sm">Alphabetical</TabsTrigger>
</TabsList> <TabsTrigger value="chronological" className="text-sm">Chronological</TabsTrigger>
</Tabs> </TabsList>
</Tabs>
</div>
<div className="flex items-center gap-3 w-full sm:w-auto"> <div className="flex items-center gap-3 w-full sm:w-auto">
<div className="flex items-center gap-1 text-sm text-navy/70 dark:text-cream/70"> <div className="flex items-center gap-1 text-sm text-navy/70 dark:text-cream/70">
@ -714,134 +716,37 @@ export default function Authors() {
)} )}
{/* Author grid or list */} {/* Author grid or list */}
<TabsContent value="all" className="mt-0"> {/* Note: Using the first Tabs component that already exists in the view controls */}
{isLoading ? ( {isLoading ? (
<div className={`grid gap-6 ${viewMode === 'grid' ? 'grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4' : 'grid-cols-1'}`}> <div className={`grid gap-6 ${viewMode === 'grid' ? 'grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4' : 'grid-cols-1'}`}>
{Array.from({ length: PAGE_SIZE }).map((_, i) => ( {Array.from({ length: PAGE_SIZE }).map((_, i) => (
<Card key={i} className="bg-cream dark:bg-dark-surface"> <Card key={i} className="bg-cream dark:bg-dark-surface">
<CardContent className="p-6"> <CardContent className="p-6">
<div className="flex items-center gap-4 mb-4"> <div className="flex items-center gap-4 mb-4">
<div className="w-16 h-16 rounded-full bg-navy/10 dark:bg-navy/20 animate-pulse"></div> <div className="w-16 h-16 rounded-full bg-navy/10 dark:bg-navy/20 animate-pulse"></div>
<div className="flex-1"> <div className="flex-1">
<div className="h-5 bg-navy/10 dark:bg-navy/20 rounded-md w-3/4 mb-2 animate-pulse"></div> <div className="h-5 bg-navy/10 dark:bg-navy/20 rounded-md w-3/4 mb-2 animate-pulse"></div>
<div className="h-4 bg-navy/10 dark:bg-navy/20 rounded-md w-1/2 animate-pulse"></div> <div className="h-4 bg-navy/10 dark:bg-navy/20 rounded-md w-1/2 animate-pulse"></div>
</div>
</div> </div>
<div className="h-20 bg-navy/10 dark:bg-navy/20 rounded-md animate-pulse"></div>
</CardContent>
</Card>
))}
</div>
) : (
<>
{viewMode === 'grid' ? (
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-6">
{sortedAuthors.map(author => renderAuthorCard(author))}
</div>
) : (
<div className="space-y-4">
{sortedAuthors.map(author => renderAuthorListItem(author))}
</div>
)}
</>
)}
</TabsContent>
<TabsContent value="alphabetical" className="mt-0">
{isLoading ? (
<div className="animate-pulse space-y-6">
{Array.from({ length: 3 }).map((_, i) => (
<div key={i}>
<div className="h-6 bg-navy/10 dark:bg-navy/20 rounded-md w-12 mb-4"></div>
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-6">
{Array.from({ length: 4 }).map((_, j) => (
<div key={j} className="h-48 bg-navy/5 dark:bg-navy/10 rounded-md"></div>
))}
</div> </div>
</div> <div className="h-20 bg-navy/10 dark:bg-navy/20 rounded-md animate-pulse"></div>
))} </CardContent>
</div> </Card>
) : ( ))}
<> </div>
{/* Alphabet navigation */} ) : (
<div className="sticky top-16 z-10 bg-paper dark:bg-dark-paper py-3 mb-6 border-b border-sage/10 dark:border-sage/5"> <>
<div className="flex flex-wrap gap-1 justify-center"> {viewMode === 'grid' ? (
{[..."ABCDEFGHIJKLMNOPQRSTUVWXYZ"].map(letter => { <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-6">
const hasAuthors = sortedGroupKeys.includes(letter); {sortedAuthors.map(author => renderAuthorCard(author))}
return (
<a
key={letter}
href={hasAuthors ? `#${letter}` : undefined}
className={`w-8 h-8 flex items-center justify-center rounded-full text-sm font-medium transition-colors ${
hasAuthors
? 'bg-navy/10 hover:bg-navy/20 dark:bg-navy/20 dark:hover:bg-navy/30 text-navy dark:text-cream cursor-pointer'
: 'bg-navy/5 dark:bg-navy/10 text-navy/40 dark:text-cream/40 cursor-default'
}`}
>
{letter}
</a>
);
})}
</div>
</div> </div>
) : (
<div className="space-y-10"> <div className="space-y-4">
{sortedGroupKeys.map(letter => ( {sortedAuthors.map(author => renderAuthorListItem(author))}
<div key={letter} id={letter} className="scroll-mt-32">
<h2 className="text-2xl font-serif font-semibold mb-5 text-navy dark:text-cream border-b border-sage/10 dark:border-sage/5 pb-2">
{letter}
</h2>
<div className={`grid gap-6 ${viewMode === 'grid' ? 'grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4' : 'grid-cols-1'}`}>
{groupedAuthors![letter].map(author => (
viewMode === 'grid' ? renderAuthorCard(author) : renderAuthorListItem(author)
))}
</div>
</div>
))}
</div> </div>
</> )}
)} </>
</TabsContent> )}
<TabsContent value="chronological" className="mt-0">
{isLoading ? (
<div className="animate-pulse space-y-6">
{Array.from({ length: 4 }).map((_, i) => (
<div key={i}>
<div className="h-6 bg-navy/10 dark:bg-navy/20 rounded-md w-24 mb-4"></div>
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6">
{Array.from({ length: 3 }).map((_, j) => (
<div key={j} className="h-48 bg-navy/5 dark:bg-navy/10 rounded-md"></div>
))}
</div>
</div>
))}
</div>
) : (
<div className="space-y-10">
{/* Group authors by century */}
{Array.from(new Set(authors?.map(a => Math.floor((a.birthYear || 1800) / 100) * 100))).sort().map(century => {
const centuryLabel = `${century}s`;
const centuryAuthors = authors?.filter(a =>
Math.floor((a.birthYear || 1800) / 100) * 100 === century
);
return (
<div key={century}>
<h2 className="text-2xl font-serif font-semibold mb-5 text-navy dark:text-cream border-b border-sage/10 dark:border-sage/5 pb-2">
{centuryLabel}
</h2>
<div className={`grid gap-6 ${viewMode === 'grid' ? 'grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4' : 'grid-cols-1'}`}>
{centuryAuthors?.map(author => (
viewMode === 'grid' ? renderAuthorCard(author) : renderAuthorListItem(author)
))}
</div>
</div>
);
})}
</div>
)}
</TabsContent>
{/* Pagination */} {/* Pagination */}
{totalPages > 1 && ( {totalPages > 1 && (