Major League Baguette logo
Published on

IndiesReadIt Development Diary - Week 6

Authors
Table of Contents

IndiesReadIt Development Diary - Week 6

09/01 - 3h+ - Improved Favorites functionality and Dashboard organization.

  • Added a very basic “add to fav” function to the inactive Heart button from card
  • Like I designed in DB schema, fav are in fact a reading list
  • Triggering the fav button will create a new Favorites list or create it if it doesn’t exist and add or remove the book from it, simple handling, maybe not the best but sufficient for now to move on
  • I once again copied entire table comp folder to gain time but this time I found that changing columns definitions was enough for basic stuff, 1st step to simplifying refactor.
  • Reorganized dashboard to display reading lists table by default as it’ll be the main purpose of dashboard page
  • Weirdly lost a lot of time on hover Fav button, went from a terrible:
className={
              userFavs?.find((fav: Books) => fav.slug === book.slug) ||
              isPending
                ? "text-primary hover:text-inherit"
                : "hover:text-primary"
            }
  • to a Switch className (use Switch more often it’s better that unreadable if-else hell) :
const getHeartClass = () => {
  switch (true) {
    case bookIsFav !== undefined && isPending:
      return 'text-inherit hover:text-primary';
    case bookIsFav === undefined && isPending:
      return 'text-primary hover:text-inherit';
    case bookIsFav !== undefined:
      return 'text-primary hover:text-inherit';
    default:
      return 'text-inherit hover:text-primary';
  }
};

10/01 - 2h+ - Adding rating feature

  • Added book rating from home in a satisfying short time, thanks to already written api route that I copied/updated easily
  • Setting rating will a rating exist for this book AND from this user and add or update it, nothing fancy
  • Had to replace @smastrom/react-rating by react-simple-star-rating as the first wouldn’t let me to set fraction if not in ReadOnly mode… (why?)
  • RSSR is good but isn’t very customizing easily and has some kind of conflict with Tailwind it seems (it displays vertically), fixed it with this SGVstyle
<Rating
  initialValue={bookAverageRating || 0}
  allowFraction
  size={24}
  SVGstyle={{ display: 'inline-flex' }}
  onClick={(value: any) => handleRating(value)}
/>

11/01 - 2.5h - Improved re-renders, toast feedback, and feature promotion.

  • Adding or updating own rating wouldn’t re-render the card, I lost a shitload of time on this one…
  • I found out that I was requesting books from main page to send it to useBook hook and the provide it to context, which is stupid. I moved the fetching to the hook directly and set some simple useEffect to trigger the cards re-render
const { data: initialBooks } = useQuery({
  queryKey: ['books'],
  queryFn: async () => {
    const res = await fetch('/api/books');
    return res.json();
  },
});
const [books, setBooks] = useState([] as ExtendedBooks[]);

useEffect(() => {
  if (initialBooks) {
    setBooks(initialBooks);
  }
}, [initialBooks]);

useEffect(() => {
  if (updatedBooks) {
    setBooks(updatedBooks);
  }
}, [updatedBooks]);
  • Added toast feedback for fav and rating with nice action for Fav one :
action: bookIsFav ? (
          <Button onClick={() => favMutation()}>Undo</Button>
        ) : (
          <Button asChild variant="outline">
            <Link href="/dashboard">View Fav</Link>
          </Button>
        ),
  • Added better loading information by adding Skeletons where Combobox and Cards would display

  • Made a X post to announce the new features to not lose momentum for IndiesReadIt, I feel like a improve my copywriting skills, will see if it reflects on stats

    IndiesReadIt Posthog

    12/01 - 3h - Refactored hook, improved code, fixed Prisma.

  • Started refactoring the useBooks custom hook to centralize all logic in it, went from

export default function Category({ params }: { params: { slug: string } }) {
  const {
    isLoading,
    error,
    data: booksByCategory,
  } = useQuery({
    queryKey: [`category-${params.slug}`],
    queryFn: async () => {
      const res = await fetch(`/api/categories/${params.slug}`);
      return res.json();
    },
  });
  return (
    !isLoading &&
    !error && (
      <BooksProvider updatedBooks={booksByCategory.books}>
			 <div className="z-10 w-full max-w-[1440px]">
				...

to

export default function Category() {
  const { category } = useBooks();

  return (
    <div className="z-10 w-full max-w-[1440px]">
			...
  • It makes the code way cleaner, easier to modify and reuse and avoid some conflicts…
  • Had this weird error warn(prisma-client) Already 10 Prisma Clients are actively running.
  • Found out it was because I was starting new Prisma client each time I had use of prisma… Obvious bad design, I deleted all “const prisma = new PrismaClient()” and simply called it form prisma.ts
import { PrismaClient } from '@prisma/client';

declare global {
  var prisma: PrismaClient | undefined;
}

const prisma = global.prisma || new PrismaClient();

if (process.env.NODE_ENV === 'development') global.prisma = prisma;

export default prisma;

13/01 - 30min - Received feedback, addressed display and scrolling issues.

Some things I saw: it loads on the development tab and shows books but if switching to marketing then back to development it’s empty

Footer jumps high when switching filters

The scroll bar deactivates and forced to refresh page after switching filters

  • Had hard times finding why the drawer was disabling scrolling, it was simply supposed to be “nested”
  • I didn’t really found this by reading the doc or googling, I just tried all props 😂
<Drawer open={open} onOpenChange={setOpen} nested>

14/01 - 1h - Balanced work during a personal trip, optimized search logic.

  • I had to see someone I miss a lot this day, 2+ hour trip mainly on highway.
  • I managed to work 1 hour while chatting with my wife and daughter with the car on autopilot (my wife was at the wheel of course.)
  • I love technology 😎
  • I moved all the search logic to useBooks, it freed 30lines on the client component and made everything way more readable and maintenable, again.
  • Custom hooks are very a powerful tool, I can feel I gain xp with these
  • Another advantage moving logic to 1 hook is that avoid conflict, now in a book category, I can search, erase it and still get the category books (I was getting all books before) IndiesReadIt Posthog
  • (I drove back, I’m not a tyrant)

Week 6 Summary

IndiesReadIt saw significant improvements this week, including enhanced Favorites and a new book rating feature. Refactoring efforts streamlined code for better maintainability, while user interaction was boosted with toast feedback and improved UI. Overall, the focus on functionality and user feedback shaped a polished IndiesReadIt experience.


Submit your favorite indie books to IndiesReadIt and help build this collaborative directory.

Stay tuned for more updates!