Skip to content

Commit

Permalink
refactor: migrate state management from nanostores to jotai (#1022)
Browse files Browse the repository at this point in the history
Migrate state management from nanostores to jotai
  • Loading branch information
tszhong0411 authored Feb 1, 2025
2 parents 241ef12 + 2d7d390 commit 0abee6b
Show file tree
Hide file tree
Showing 8 changed files with 91 additions and 53 deletions.
3 changes: 1 addition & 2 deletions apps/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
"@auth/drizzle-adapter": "1.7.2",
"@hookform/resolvers": "^3.9.1",
"@icons-pack/react-simple-icons": "10.2.0",
"@nanostores/react": "^0.8.4",
"@normy/react-query": "^0.17.1",
"@number-flow/react": "^0.4.4",
"@octokit/rest": "^21.1.0",
Expand All @@ -49,11 +48,11 @@
"dayjs": "^1.11.13",
"fast-xml-parser": "^4.5.1",
"geist": "^1.3.1",
"jotai": "^2.11.3",
"js-sha512": "^0.9.0",
"lucide-react": "^0.469.0",
"markdown-to-jsx": "^7.7.2",
"motion": "^11.15.0",
"nanostores": "^0.11.3",
"next": "^15.1.3",
"next-auth": "5.0.0-beta.25",
"next-intl": "^3.26.3",
Expand Down
6 changes: 4 additions & 2 deletions apps/web/src/app/[locale]/(main)/guestbook/sign-in.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,20 @@

import { useTranslations } from '@tszhong0411/i18n/client'
import { Button } from '@tszhong0411/ui'
import { useSetAtom } from 'jotai'

import { setDialogs } from '@/store/dialogs'
import { dialogsAtom } from '@/store/dialogs'

const SignIn = () => {
const t = useTranslations()
const setDialogs = useSetAtom(dialogsAtom)

return (
<>
<Button
className='dark:text-foreground bg-linear-to-br inline-block from-[#fcd34d] via-[#ef4444] to-[#ec4899] font-extrabold'
onClick={() => {
setDialogs({ signIn: true })
setDialogs((dialogs) => ({ ...dialogs, signIn: true }))
}}
>
{t('common.sign-in')}
Expand Down
6 changes: 4 additions & 2 deletions apps/web/src/components/admin/admin-profile-dropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,17 @@ import {
DropdownMenuTrigger,
Skeleton
} from '@tszhong0411/ui'
import { useSetAtom } from 'jotai'
import { useSession } from 'next-auth/react'

import { setDialogs } from '@/store/dialogs'
import { dialogsAtom } from '@/store/dialogs'
import { getAvatarAbbreviation } from '@/utils/get-avatar-abbreviation'
import { getDefaultUser } from '@/utils/get-default-user'

const AdminProfileDropdown = () => {
const { data, status } = useSession()
const t = useTranslations()
const setDialogs = useSetAtom(dialogsAtom)

if (status === 'loading') {
return <Skeleton className='size-9 rounded-full' />
Expand All @@ -29,7 +31,7 @@ const AdminProfileDropdown = () => {
<Button
size='sm'
onClick={() => {
setDialogs({ signIn: true })
setDialogs((dialogs) => ({ ...dialogs, signIn: true }))
}}
>
{t('common.sign-in')}
Expand Down
6 changes: 4 additions & 2 deletions apps/web/src/components/command-menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
Kbd,
Logo
} from '@tszhong0411/ui'
import { useSetAtom } from 'jotai'
import { CodeIcon, CommandIcon, LinkIcon, LogInIcon, LogOutIcon } from 'lucide-react'
import { signOut, useSession } from 'next-auth/react'
import { Fragment, useCallback, useEffect, useState } from 'react'
Expand All @@ -28,7 +29,7 @@ import {
SITE_X_URL,
SITE_YOUTUBE_URL
} from '@/lib/constants'
import { setDialogs } from '@/store/dialogs'
import { dialogsAtom } from '@/store/dialogs'

type Groups = Array<{
name: string
Expand All @@ -45,6 +46,7 @@ const CommandMenu = () => {
const [copy] = useCopyToClipboard()
const { status } = useSession()
const t = useTranslations()
const setDialogs = useSetAtom(dialogsAtom)

const isSelectingCommand = [t('common.sign-out'), t('command-menu.actions.copy-link')].includes(
selectingValue
Expand Down Expand Up @@ -88,7 +90,7 @@ const CommandMenu = () => {
icon: <LogInIcon className='mr-3 size-4' />,
onSelect: () => {
setIsOpen(false)
setDialogs({ signIn: true })
setDialogs((dialogs) => ({ ...dialogs, signIn: true }))
}
}
])
Expand Down
6 changes: 4 additions & 2 deletions apps/web/src/components/comments/unauthorized-overlay.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
import { useTranslations } from '@tszhong0411/i18n/client'
import { Button } from '@tszhong0411/ui'
import { useSetAtom } from 'jotai'

import { setDialogs } from '@/store/dialogs'
import { dialogsAtom } from '@/store/dialogs'

const UnauthorizedOverlay = () => {
const t = useTranslations()
const setDialogs = useSetAtom(dialogsAtom)

return (
<div className='absolute inset-0 flex items-center justify-center rounded-lg bg-black/5 backdrop-blur-[0.8px]'>
<Button
size='sm'
onClick={() => {
setDialogs({ signIn: true })
setDialogs((dialogs) => ({ ...dialogs, signIn: true }))
}}
>
{t('common.sign-in')}
Expand Down
10 changes: 5 additions & 5 deletions apps/web/src/components/sign-in-dialog.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
'use client'

import { SiGithub } from '@icons-pack/react-simple-icons'
import { useStore } from '@nanostores/react'
import { useTranslations } from '@tszhong0411/i18n/client'
import {
Button,
Expand All @@ -11,11 +10,12 @@ import {
DialogHeader,
DialogTitle
} from '@tszhong0411/ui'
import { useAtom } from 'jotai'
import { Loader2Icon } from 'lucide-react'
import { signIn } from 'next-auth/react'
import { useState } from 'react'

import { dialogs, setDialogs } from '@/store/dialogs'
import { dialogsAtom } from '@/store/dialogs'

const GoogleIcon = () => {
return (
Expand Down Expand Up @@ -47,16 +47,16 @@ const GoogleIcon = () => {
}

const SignInDialog = () => {
const { signIn: isOpen } = useStore(dialogs)
const [dialogs, setDialogs] = useAtom(dialogsAtom)
const [isGitHubLoading, setIsGitHubLoading] = useState(false)
const [isGoogleLoading, setIsGoogleLoading] = useState(false)
const t = useTranslations()

return (
<Dialog
open={isOpen}
open={dialogs.signIn}
onOpenChange={(v) => {
setDialogs({ signIn: v })
setDialogs((d) => ({ ...d, signIn: v }))
}}
>
<DialogContent className='sm:max-w-[425px]'>
Expand Down
10 changes: 3 additions & 7 deletions apps/web/src/store/dialogs.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
import { atom } from 'nanostores'
import { atom } from 'jotai'

type DialogsState = {
type Dialogs = {
signIn: boolean
}

export const dialogs = atom<DialogsState>({
export const dialogsAtom = atom<Dialogs>({
signIn: false
})

export const setDialogs = (value: DialogsState) => {
dialogs.set({ ...dialogs.get(), ...value })
}
Loading

0 comments on commit 0abee6b

Please sign in to comment.