Open allohamora opened 4 months ago
src/features/AlphabetList/AlphabetList.tsx
'use client';
import React from 'react';
import { useQuery } from '@tanstack/react-query';
import { getAllWords } from '@/app/api/actions';
import { createAlphabet } from './utils';
import Link from 'next/link';
import { Button } from '@/components/ui/button';
import { Loader } from '@/components/Loader';
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
interface AlphabetListProps {}
export const AlphabetList = ({}: AlphabetListProps) => {
const { data = [], isLoading } = useQuery({
queryKey: ['words'],
queryFn: () => getAllWords(),
});
const alphabet = createAlphabet(data);
if (isLoading) {
return <Loader />;
}
if (!alphabet.length) {
return null;
}
return (
<Tabs defaultValue={`${alphabet[0][0]}-tab`}>
<TabsList className="flex flex-wrap h-fit">
{alphabet.map(([letter]) => (
<TabsTrigger key={`${letter}-letter-tabname`} value={`${letter}-tab`}>
{letter}
</TabsTrigger>
))}
</TabsList>
{alphabet.map(([letter, words]) => (
<TabsContent key={`${letter}-tab-content`} value={`${letter}-tab`}>
<ul className="flex flex-wrap">
{words.map((word) => (
<li key={word.id} className="w-fit">
<Link href={`/word/${word.id}`}>
<Button variant="link">
{word.word}
</Button>
</Link>
</li>
))}
</ul>
</TabsContent>
))}
</Tabs>
);
};
'use server';
import React from 'react';
import { getWordDefinitions } from '@/app/api/actions';
import { Card, CardContent } from '@/components/ui/card';
import { VoteBlock } from './VoteBlock';
import { Paragraph } from '@/components/typography';
interface DefinitionsListProps {
wordId: string;
}
export const DefinitionsList = async ({ wordId }: DefinitionsListProps) => {
const definitions = await getWordDefinitions(wordId);
const formattedDefinitions = definitions.map((def) => ({
...def,
rating: def.upvotes_count - def.downvotes_count,
}));
const sortedDefinitions = formattedDefinitions.sort((a, b) => b.rating - a.rating);
return sortedDefinitions.map(({ id, text, upvotes_count, downvotes_count }) => (
<Card key={id} className="py-3 px-5">
<CardContent>
<Paragraph>{text}</Paragraph>
<VoteBlock
definitionId={id}
wordId={wordId}
upvotes={upvotes_count}
downvotes={downvotes_count}
/>
</CardContent>
</Card>
));
};
With the current react-query approach, we need to load data on the client and see the Loader component and layout shifts:
https://github.com/Sifiya/ua-urban/assets/54174661/59207e83-a7d3-47a1-8d84-fa585952aea7
With react server components otherwise, we can make
await
for the data in components with "use server" and have the better user experience:https://github.com/Sifiya/ua-urban/assets/54174661/05103a91-86c1-4fae-89c9-42fffd992a94