mirror of
https://github.com/SamyRai/tercul-frontend.git
synced 2025-12-27 04:51:34 +00:00
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:
parent
3a93337390
commit
218c8ff1c1
@ -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 && (
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user