Skip to content

Commit

Permalink
chore: 🔖 release new app version
Browse files Browse the repository at this point in the history
chore: 🔖 release new app version
  • Loading branch information
emiliosheinz authored Feb 24, 2023
2 parents ba1d310 + 56f6f44 commit 8e6d7bf
Show file tree
Hide file tree
Showing 32 changed files with 619 additions and 272 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
"next": "13.1.1",
"next-auth": "^4.18.3",
"next-superjson-plugin": "^0.5.4",
"nextjs-progressbar": "^0.0.16",
"react": "18.2.0",
"react-dom": "18.2.0",
"react-hook-form": "^7.41.5",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
Warnings:
- You are about to drop the `Upvote` table. If the table is not empty, all the data it contains will be lost.
*/
-- DropForeignKey
ALTER TABLE "Upvote" DROP CONSTRAINT "Upvote_deckId_fkey";

-- DropForeignKey
ALTER TABLE "Upvote" DROP CONSTRAINT "Upvote_userId_fkey";

-- DropTable
DROP TABLE "Upvote";

-- CreateTable
CREATE TABLE "Favorite" (
"id" TEXT NOT NULL,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"userId" TEXT NOT NULL,
"deckId" TEXT NOT NULL,

CONSTRAINT "Favorite_pkey" PRIMARY KEY ("id")
);

-- CreateIndex
CREATE UNIQUE INDEX "Favorite_userId_deckId_key" ON "Favorite"("userId", "deckId");

-- AddForeignKey
ALTER TABLE "Favorite" ADD CONSTRAINT "Favorite_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE "Favorite" ADD CONSTRAINT "Favorite_deckId_fkey" FOREIGN KEY ("deckId") REFERENCES "Deck"("id") ON DELETE CASCADE ON UPDATE CASCADE;
6 changes: 3 additions & 3 deletions prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ model User {
sessions Session[]
decks Deck[]
studySessions StudySession[]
upvotes Upvote[]
favorites Favorite[]
description String?
topics Topic[]
}
Expand Down Expand Up @@ -75,7 +75,7 @@ model Deck {
topics Topic[]
cards Card[]
studySessions StudySession[]
upvotes Upvote[]
favorites Favorite[]
}

model Topic {
Expand Down Expand Up @@ -144,7 +144,7 @@ model StudySessionAttempt {
studySessionBoxCard StudySessionBoxCard @relation(fields: [studySessionBoxCardId], references: [id], onDelete: Cascade)
}

model Upvote {
model Favorite {
id String @id @default(cuid())
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { useState } from 'react'

import { HeartIcon as EmptyHeartIcon } from '@heroicons/react/24/outline'
import { HeartIcon as FilledHeartIcon } from '@heroicons/react/24/solid'
import { useSession } from 'next-auth/react'

import { api } from '~/utils/api'
import { notify } from '~/utils/toast'

import type { FavoriteButtonProps } from '../types/deck-card-list.types'

export function InnerFavoriteButton(props: FavoriteButtonProps) {
const { deck } = props

const { data: user } = useSession()
const apiContext = api.useContext()

const invalidateDeckQueries = () => {
apiContext.decks.invalidate()
}

const { mutate: addFavorite } = api.decks.addFavorite.useMutation({
onSuccess: invalidateDeckQueries,
})
const { mutate: removeFavorite } = api.decks.removeFavorite.useMutation({
onSuccess: invalidateDeckQueries,
})

const [isFavorite, setIsFavorite] = useState(deck.isFavorite)
const [favorites, setFavorites] = useState(deck.favorites)

const Icon = isFavorite ? FilledHeartIcon : EmptyHeartIcon

const handleButtonClick = () => {
if (!user) {
notify.warning('Você precisa estar logado para executar essa ação!')
return
}

const toggleFavorite = isFavorite ? removeFavorite : addFavorite
toggleFavorite({ deckId: deck.id })
setIsFavorite(!isFavorite)
setFavorites(favorites + (isFavorite ? -1 : 1))
}

return (
<button
onClick={handleButtonClick}
className='absolute bottom-0 right-0 flex items-center gap-2 p-2'
>
<span>{favorites}</span>
<Icon className='h-8 w-8 text-primary-900' />
</button>
)
}

export function FavoriteButton(props: FavoriteButtonProps) {
return (
<InnerFavoriteButton
{...props}
/**
* Add key so the component gets updated when favorites or isFavorite changes
*/
key={`${props.deck.isFavorite}-${props.deck.favorites}`}
/>
)
}

This file was deleted.

4 changes: 2 additions & 2 deletions src/components/deck-card-list/deck-card-list.component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import { Image } from '~/components/image'
import { routes } from '~/utils/navigation'

import { Error } from './components/error.component'
import { FavoriteButton } from './components/favorite-button.component'
import { Loading } from './components/loading.component'
import { UpvoteButton } from './components/upvote-button.component'
import type { DeckCardListProps } from './types/deck-card-list.types'

export function DeckCardList(props: DeckCardListProps) {
Expand Down Expand Up @@ -52,7 +52,7 @@ export function DeckCardList(props: DeckCardListProps) {
<p className='mb-3 font-normal'>{deck.description}</p>
</div>
</Link>
<UpvoteButton deck={deck} />
<FavoriteButton deck={deck} />
</div>
))}
</div>
Expand Down
1 change: 1 addition & 0 deletions src/components/deck-card-list/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export { DeckCardList } from './deck-card-list.component'
export { DecksToBeReviewed } from './decks-to-be-reviewed.component'
export { UserFavoriteDecks } from './user-favorite-decks.component'
4 changes: 2 additions & 2 deletions src/components/deck-card-list/types/deck-card-list.types.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import type { Deck } from '@prisma/client'

export type DeckCardListProps = {
decks: Array<Deck & { isUpvoted: boolean; upvotes: number }>
decks: Array<Deck & { isFavorite: boolean; favorites: number }>
}

export type ErrorProps = {
onRetryPress: () => void
}

export type UpvoteButtonProps = {
export type FavoriteButtonProps = {
deck: DeckCardListProps['decks'][number]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export type UserFavoriteDecksProps = {
isVisible?: boolean
}
58 changes: 58 additions & 0 deletions src/components/deck-card-list/user-favorite-decks.component.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { InView } from 'react-intersection-observer'

import { api } from '~/utils/api'

import { Loader } from '../loader'
import { DeckCardList } from './deck-card-list.component'
import type { UserFavoriteDecksProps } from './types/user-favorite-decks.types'

export function UserFavoriteDecks(props: UserFavoriteDecksProps) {
const { isVisible = true } = props

const {
data,
isError,
refetch,
isLoading,
hasNextPage,
fetchNextPage,
isFetchingNextPage,
} = api.decks.favorites.useInfiniteQuery(
{},
{
getNextPageParam: lastPage => lastPage.nextCursor,
keepPreviousData: true,
enabled: isVisible,
},
)

const decks = data?.pages.flatMap(page => page.decks) ?? []
const hasLoadedDecks = decks.length > 0

const renderContent = () => {
if (isLoading) return <DeckCardList.Loading />

if (!hasLoadedDecks && isError) {
return <DeckCardList.Error onRetryPress={refetch} />
}

return <DeckCardList decks={decks} />
}

return (
<div className='flex flex-col items-center'>
{renderContent()}
<InView
as='div'
className='mt-5 flex w-full items-center justify-center'
onChange={inView => {
if (inView && hasNextPage && !isError && !isFetchingNextPage) {
fetchNextPage()
}
}}
>
{isFetchingNextPage ? <Loader /> : null}
</InView>
</div>
)
}
6 changes: 1 addition & 5 deletions src/components/full-screen-loader/full-screen-load.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,15 @@ import { Dialog, Transition } from '@headlessui/react'
import { useAtomValue } from 'jotai'
import noop from 'lodash/noop'

import { useDebounce } from '~/hooks/use-debounce'
import { useRouteChangeLoader } from '~/hooks/use-route-change-loader'
import { fullScreenLoaderAtom } from '~/utils/atoms'

import { Loader } from '../loader'

export function FullScreenLoader() {
const isLoading = useAtomValue(fullScreenLoaderAtom)
const debouncedIsLoading = useDebounce(isLoading, 200)
useRouteChangeLoader()

return (
<Transition appear show={debouncedIsLoading} as={Fragment}>
<Transition appear show={isLoading} as={Fragment}>
<Dialog as='div' className='relative z-40' onClose={noop}>
<Transition.Child
as={Fragment}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import {
ClockIcon,
StarIcon,
FireIcon,
HeartIcon,
PlusCircleIcon,
UserCircleIcon,
WrenchIcon,
FireIcon,
} from '@heroicons/react/24/outline'
import { useSession } from 'next-auth/react'

Expand All @@ -29,21 +29,21 @@ export function useMenuOptions() {
isAuthRequired: true,
},
{
label: 'Mais Votados',
label: 'Mais Favoritados',
icon: StarIcon,
href: routes.mostUpvotedDecks(),
href: routes.mostFavoriteDecks(),
isAuthRequired: false,
},
{
label: 'Mais Recentes',
icon: FireIcon,
href: '#',
isAuthRequired: false,
label: 'Meus Favoritos',
icon: HeartIcon,
href: routes.favorites(),
isAuthRequired: true,
},
{
label: 'Para Você',
icon: HeartIcon,
href: '#',
label: 'Recomendados',
icon: FireIcon,
href: routes.decksForYou(),
isAuthRequired: true,
},
{
Expand Down
2 changes: 1 addition & 1 deletion src/constants/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,5 @@ export const STUDY_SESSION_BOXES = [
{ reviewGapInHours: 24 * 3 },
{ reviewGapInHours: 24 * 7 },
{ reviewGapInHours: 24 * 15 },
{ reviewGapInHours: 24 * 20 },
{ reviewGapInHours: 24 * 30 },
]
1 change: 0 additions & 1 deletion src/hooks/use-debounce/index.ts

This file was deleted.

Loading

1 comment on commit 8e6d7bf

@vercel
Copy link

@vercel vercel bot commented on 8e6d7bf Feb 24, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

briskly – ./

briskly-emiliosheinz.vercel.app
briskly.app
briskly-git-main-emiliosheinz.vercel.app

Please sign in to comment.