This app renders a list of blocks to the screen. It currently does three things:
- Renders blocks by creation time in descending order.
- Allows a user to create a block by providing some content and clicking the
Createbutton. - Allows a user to delete a block by clicking the
Xicon button within it.
Once you're done, please send a link to your fork of this repo to adrien@genei.io.
❗❗ Please spend no more than a total of 4h on this task. If you don't finish, that's fine. We're more interested in how you approach the problem than in the solution itself. ❗❗
Your task is to fulfill this imaginary user's dreams of reordering their blocks:
"As a user I want to be able see my blocks in an order that I choose. In order to reorder my blocks, I expect to be able to drag and drop one block either above or below another. When I come back to the app I expect that my blocks are still in the order I defined."
Implementation details:
- The user-defined ordering should be stored in the database in some shape or form.
- The
listprocedure insrc/server/trpc/router/block.tscurrently accepts asortByproperty that can only be set tocreatedAt. - Add a new
sortByoption called e.g.order. - When
sortByis set toorderinsrc/components/Blocks.tsx, the blocks should be sorted in the user-defined order. - By default (before any blocks have been reordered), sorting by
ordershould look no different than sorting bycreatedAt. - When a new block is created, it should appear at the top when sorting
descbyorder. - When deleting a block, the ordering of the remaining blocks should not change.
- Implement the
reorderprocedure defined insrc/server/trpc/router/block.tsto move one block after another.- The
idis the id of the block that is being moved. - The
afterIdis the id of the block that the source block should be moved after. - If
afterIdisnullthat means the block should be after no block, i.e. it is the first block in the ordering, or in other words it is at the end of the list when sortingdescbyorder.
- The
- When a block is dropped, call the
reorderprocedure with the correctidandafterIdvalues and invalidate thelistprocedure.
If you have time left:
- Animate the drag and drop. When a block is dragged, remove it from the list. When it is dragged between blocks, insert a placeholder to provide feedback to the user about where it will be moved to.
- Implement an optimistic response to the
reorderprocedure so that the UI response on drop is instant.
- Make frequent commits with descriptive commit messages. Again, we're more interested in how you approach the problem than in the solution itself.
- Create a file called NOTES.md, and write up any notes / thoughts you have as you go along.
- It's totally fine, even encouraged, to use Google to explore the problem space and find solutions.
- Feel free to use whichever libraries you like to help you complete the task.
- If you get really stuck or have any additional questions, please send me an email at adrien@genei.io and I will get back to you as soon as possible.
- Prisma ORM
- We use Prisma to interact with our database at Genei.
- tRPC
- Don't worry about this too much. It's just a module that lets you define end-to-end typesafe APIs.
- Refer to
src/components/CreateBlock.tsxandsrc/components/Blocks.tsxto see how it's used in the frontend. - Refer to
src/server/trpc/router/block.tsto see how it's used in the backend.
- Install dependencies
npm i- Instantiate the database. Make sure Docker is running.
docker compose up -d- Run the migrations
npx prisma migrate dev- Run the app
npm run dev- Run type checking
npm run ts:watch