Snapgram Top Creators
Task 🎯
Your goal is to show a few creators on the right side
Example 🧩
Visit the Figma Design and see how the feature should look like
Resources đź“–
Must Play ❤️‍🔥
I would recommend all of you to play this Flexbox game. This is really your gateway to building high-class responsive websites. If you master flex, you can flex anything!
Of course, that doesn't mean we won’t grid. Luckily, there is another game on that too. Definitely worth a shot. Do try the Grid Garden
Hint đź’ˇ
Not sure how to get started with this? We’re here for you.
Let’s take it step by step!
First and foremost, ask yourself —
What is expected (The Output)?
We want a sidebar that shows a few users, and clicking on them should lead to their respective profile pages, right?
What do we need in order to build that?
- A sidebar
- User card
- Loader to show the status while doing the fetch
- Appwrite function to get the users
- ….?
So let’s start by implementing the UI first,
- Sidebar
- Quickly bounce back to Figma and see what’s the expected width of it. Use the tailwindcss width utility
w-x
and create it - Examine the direction in which the content inside this sidebar has been laid out. Is it row or column-wise? Yes, column! So can we use flex and its properties that help us change the direction of content in a row or column?
- We would like to show this sidebar only on bigger screens as it’ll be difficult to see both the content together on smaller screens. So how should we remove it?
In CSS, there is a display property. It has many values, from
flex
,grid
,block
tonone
. Thenone
as expected removes that particular element from the DOM. Think about how we can use this property to hide/show the element at some breakpoints. Something like Media Query? Think! Study TailwindCSS display and breakpoint utilities and give it a shot
- Quickly bounce back to Figma and see what’s the expected width of it. Use the tailwindcss width utility
I don’t have to talk about adding that text, do I? Simply take yourself back and find the needed styling properties for the text — “Top Creators”. What are these?
-
Color?
-
Font family?
-
Font size?
-
Line height?
-
…?
-
User card As you can see, we want the content two two-dimensional, meaning two cards per row. Usually, I would have suggested going with flex but over here, for this case, grid is the best choice. Why? Because we would like to have a uniform structure of cards. You can do it with Flex too. There is no one fixed solution. One can try columns as well! So,
- Create a
div
. No, create aui
element and applygrid
properties to it. How many columns do we want? Two? So what should be the grid property? Think! - Again inside the user card, “Think in Layouts”. What’s the direction of content? Centered Coulmn? Good! Now can we use flex here again and use its direction and alignment property?
- For the content, follow the same drill,
- Create an image element and refer to Figma for the expected width and height
- Create the name and username element and add the needed styles by referring it from the Figma design
- Same for the button. But hey, don’t add fixed width and height here. Use spacing (padding)! Why? Because giving fixed width and height would mean the content or the button is fixed. It’s not flexible. If the name of the button changes to something really big like “You should really follow me”, then it’ll break the app. On the other hand, using padding will let the button expand as much as it wants while maintaining the same space around the button text!
- Create a
Now comes the interesting part, and it’s none other than fetching the data from the Appwrite Database
-
Appwrite API We need to fetch only a few users from the user's collection. So how do we do it?
-
Visit the Appwrite docs and see how we can get the list of documents using their API.
-
Visiting will help you know that we have to do a few things:
- Create a new function, say
getUsers
export async function getUsers() {} - Use their API, i.e.,
databases.listDocuments
export async function getUsers() {try {const users = await databases.listDocuments// ...();} catch (error) {console.log(error);}} - Provide the database ID
export async function getUsers() {try {const users = await databases.listDocuments(appwriteConfig.databaseId,// ...);} catch (error) {console.log(error);}}
- Provide the collection ID
export async function getUsers() {try {const users = await databases.listDocuments(appwriteConfig.databaseId,appwriteConfig.userCollectionId,// ...);} catch (error) {console.log(error);}}
- provide queries (to limit the number of elements or others)
export async function getUsers() {try {const users = await databases.listDocuments(appwriteConfig.databaseId,appwriteConfig.userCollectionId,[Query.orderDesc("$createdAt"), Query.limit(10)],);} catch (error) {console.log(error);}}
So can you give it a try? You have paid attention so far and even went through the above document a bit; you’ll know how to do it!
Wait, can you make this reusable? See, on the “People” page, we’ll need to fetch the users and show them in almost the same format.
Can you make this function reusable such that for the “Home” page, it’ll return only a few elements, but on the “People” page, it’ll return all?
Did you make it? I hope you did!!!
Now time to use this function via the React Query so that our data coming through this API will be automatically cached, and we will be able to use other amazing features such as loading and error management.
- Create a new function, say
-
-
Create Query
- Create a new query, say,
useGetUsers
, using theuseQuery
of React Query.export const useGetUsers = () => {return useQuery();// ...}; - Now, we’ll have to provide a query key and query function so our react query will know what it has to call when it is called
export const useGetUsers = (limit?: number) => {return useQuery({queryKey: ["getUsers"],queryFn: getUsers,});};
- Create a new query, say,
And that’s it mostly. We’ll call this useGetUsers
query on our Home page, which will give us many things, but we’ll be mostly interested in getting data
loading
and error
information. Visit the useQuery reference of react query to see what are the things we get from it
const {
data: creators,
isLoading: isUserLoading,
isError: isErrorCreators,
} = useGetUsers();
And now use that info to render the UI accordingly, i.e.,
isUserLoading ? <Loader /> : <UserContent />;
P.S., What we did above with data:creators
is basically assigning the value of data
to a new variable creators
. You can use any name!
How was that? Were you able to do it?
If not, don’t lose hope. Keep trying 🚀
These challenges or features are more logic-oriented, and there may be other solutions. So take your time, think carefully, develop your logical abilities, and give it a try.
We believe in your capabilities ❤️