diff --git a/package.json b/package.json index 20a9087..761289c 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,6 @@ "class-variance-authority": "^0.7.0", "clsx": "^2.1.1", "eslint-plugin-simple-import-sort": "^12.1.0", - "js-cookie": "^3.0.5", "lucide-react": "^0.390.0", "next": "14.2.3", "next-auth": "5.0.0-beta.20", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4f038f0..377c6e6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -35,9 +35,6 @@ importers: eslint-plugin-simple-import-sort: specifier: ^12.1.0 version: 12.1.0(eslint@8.57.0) - js-cookie: - specifier: ^3.0.5 - version: 3.0.5 lucide-react: specifier: ^0.390.0 version: 0.390.0(react@18.3.1) @@ -2747,14 +2744,6 @@ packages: jquery@3.7.1: resolution: {integrity: sha512-m4avr8yL8kmFN8psrbFFFmB/If14iN5o9nw/NgnnM+kybDJpRsAynV2BsfpTYrTRysYUdADVD7CkUUizgkpLfg==} - js-cookie@3.0.5: - resolution: {integrity: sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==} - engines: {node: '>=14'} - - js-library-detector@6.7.0: - resolution: {integrity: sha512-c80Qupofp43y4cJ7+8TTDN/AsDwLi5oOm/plBrWI+iQt485vKXCco+yVmOwEgdo9VOdsYTuV0UlTeetVPTriXA==} - engines: {node: '>=12'} - js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} @@ -7543,10 +7532,6 @@ snapshots: jquery@3.7.1: {} - js-cookie@3.0.5: {} - - js-library-detector@6.7.0: {} - js-tokens@4.0.0: {} js-yaml@3.14.1: diff --git a/src/app/_component/LoginButton.tsx b/src/app/_component/LoginButton.tsx index af101a8..8aad52f 100644 --- a/src/app/_component/LoginButton.tsx +++ b/src/app/_component/LoginButton.tsx @@ -2,8 +2,8 @@ import { signIn } from "next-auth/react" -import Button from "@/common/Button" import Icon from "@/common/Icon" +import SquareButton from "@/common/SquareButton" const LoginButton = () => { const handleSignIn = async () => { @@ -11,12 +11,12 @@ const LoginButton = () => { } return ( - + ) } diff --git a/src/app/album/[id]/_component/Dialog.tsx b/src/app/album/[id]/_component/Dialog.tsx index fc16725..7bccf21 100644 --- a/src/app/album/[id]/_component/Dialog.tsx +++ b/src/app/album/[id]/_component/Dialog.tsx @@ -1,4 +1,4 @@ -import Button from "@/common/Button" +import SquareButton from "@/common/SquareButton" interface DeleteDialogProps { title: string @@ -23,22 +23,22 @@ export const Dialog = ({

{desc}

- - +
diff --git a/src/app/album/[id]/_component/ImageDetail.tsx b/src/app/album/[id]/_component/ImageDetail.tsx index ce83f3f..b7d7fc6 100644 --- a/src/app/album/[id]/_component/ImageDetail.tsx +++ b/src/app/album/[id]/_component/ImageDetail.tsx @@ -4,8 +4,8 @@ import Image from "next/image" import { useState } from "react" import Slider from "react-slick" -import Button from "@/common/Button" import Icon from "@/common/Icon" +import SquareButton from "@/common/SquareButton" import { fullDateStr } from "@/utils" import { PhotoInfo } from "../../types" @@ -71,12 +71,9 @@ export const ImageDetail = ({
- + {idx + 1} / {photos.length} @@ -101,13 +98,13 @@ export const ImageDetail = ({
- +
diff --git a/src/app/album/[id]/_component/PhotoAddButton.tsx b/src/app/album/[id]/_component/PhotoAddButton.tsx index 4e669bd..30197f2 100644 --- a/src/app/album/[id]/_component/PhotoAddButton.tsx +++ b/src/app/album/[id]/_component/PhotoAddButton.tsx @@ -2,6 +2,7 @@ import { useRouter } from "next/navigation" +import Button from "@/common/Button" import Icon from "@/common/Icon" interface PhotoAddButtonProps { @@ -15,10 +16,12 @@ export const PhotoAddButton = ({ albumId }: PhotoAddButtonProps) => { } return ( - + ) } diff --git a/src/app/album/_component/NewAlbumButton.tsx b/src/app/album/_component/NewAlbumButton.tsx index b2cd263..73cc0dc 100644 --- a/src/app/album/_component/NewAlbumButton.tsx +++ b/src/app/album/_component/NewAlbumButton.tsx @@ -1,5 +1,6 @@ import Link from "next/link" +import Button from "@/common/Button" import Icon from "@/common/Icon" export const NewAlbumButton = () => { @@ -8,10 +9,12 @@ export const NewAlbumButton = () => { href="/album/create" aria-label="새 앨범 만들기" className="fixed bottom-[114px] left-[calc(100%/2-79px)]"> -
- 새 앨범 만들기 - -
+ ) } diff --git a/src/app/album/create/_components/AlbumEditSection.tsx b/src/app/album/create/_components/AlbumEditSection.tsx index 154646f..5e44a7c 100644 --- a/src/app/album/create/_components/AlbumEditSection.tsx +++ b/src/app/album/create/_components/AlbumEditSection.tsx @@ -4,7 +4,7 @@ import { useSearchParams } from "next/navigation" import { useState } from "react" import AlbumItem from "@/common/AlbumItem" -import Button from "@/common/Button" +import SquareButton from "@/common/SquareButton" import { AlbumType, AlbumValue } from "../../types" import { usePostAlbum } from "../hooks/useAlbum" @@ -56,12 +56,12 @@ export function AlbumEditSection({
- +
) diff --git a/src/app/album/create/_components/Header.tsx b/src/app/album/create/_components/Header.tsx index 79dfbe9..92f1cca 100644 --- a/src/app/album/create/_components/Header.tsx +++ b/src/app/album/create/_components/Header.tsx @@ -33,6 +33,8 @@ function Back() { const router = useRouter() return ( - router.back()} /> + ) } diff --git a/src/app/album/create/hooks/useAlbum.ts b/src/app/album/create/hooks/useAlbum.ts index a2fec44..ff6155b 100644 --- a/src/app/album/create/hooks/useAlbum.ts +++ b/src/app/album/create/hooks/useAlbum.ts @@ -3,13 +3,13 @@ import { useRouter } from "next/navigation" import { postAlbum } from "@/app/api/photo" import { getQueryClient } from "@/common/QueryProviders" -import { useAlert } from "@/store/AlertContext" +import { useAlertStore } from "@/store/alert" import { usePatchPhotoAlbum } from "../../../scanner/hooks/usePhoto" import type { AlbumType } from "../../types" export const usePostAlbum = () => { - const { showAlert } = useAlert() + const { showAlert } = useAlertStore() const router = useRouter() const { patchPhotoAlbum } = usePatchPhotoAlbum() diff --git a/src/app/api/myfetch/index.ts b/src/app/api/myfetch/index.ts index 7e5552d..dd2f0cc 100644 --- a/src/app/api/myfetch/index.ts +++ b/src/app/api/myfetch/index.ts @@ -1,4 +1,4 @@ -import { getAccessToken } from "@/libs" +import { useAuthStore } from "@/store/auth" import customFetch from "./customFetch" @@ -13,10 +13,12 @@ export const myFetch = customFetch({ request: async ([url, options], fetch) => { // 요청 인터셉터 로직 추가 (예: 로깅, 인증 토큰 추가) // console.log("Request Interceptor:", url, options) - const token = getAccessToken() - if (token && options) { + + const { accessToken } = useAuthStore.getState() + + if (accessToken && options) { const headers = new Headers(options.headers || {}) - headers.set("Authorization", `Bearer ${token}`) + headers.set("Authorization", `Bearer ${accessToken}`) options.headers = headers } return [url, options] diff --git a/src/app/layout.tsx b/src/app/layout.tsx index b224372..28cd6e5 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -1,12 +1,15 @@ import "@/styles/main.css" import type { Metadata } from "next" +import { cookies } from "next/headers" -import AuthProvider from "@/common/AuthProvider" import ErrorHandlingWrapper from "@/common/ErrorHandlingWrapper" +import NextAuthProvider from "@/common/NextAuthProvider" import { QueryProviders } from "@/common/QueryProviders" +import { ACCESS_TOKEN_KEY } from "@/constants" import { pretendard } from "@/font" -import AlertContainer from "@/store/AlertContext" +import { AlertProvider } from "@/store/alert" +import { AuthProvider } from "@/store/auth" export const metadata: Metadata = { title: "마푸-네컷사진 전용 앨범", @@ -41,17 +44,20 @@ export default function RootLayout({ }: Readonly<{ children: React.ReactNode }>) { + const accessToken = cookies().get(ACCESS_TOKEN_KEY)?.value || null + return ( - + - + + {children} - + ) diff --git a/src/app/profile/_components/ListItem.tsx b/src/app/profile/_components/ListItem.tsx index 9e3ae6e..fcecc2b 100644 --- a/src/app/profile/_components/ListItem.tsx +++ b/src/app/profile/_components/ListItem.tsx @@ -6,7 +6,7 @@ import Button from "@/common/Button" import Icon from "@/common/Icon" import { LIST_ITEM_INFO } from "@/constants" import { isExternalLink, isInternalLink } from "@/libs" -import { useAlert } from "@/store/AlertContext" +import { useAlertStore } from "@/store/alert" interface ItemButtonType { label: string @@ -21,7 +21,7 @@ export interface ListItemProps { const ListItem = () => { const router = useRouter() - const { showAlert } = useAlert() + const { showAlert } = useAlertStore() const handleClick = async (item: ItemButtonType) => { if (item.action) { @@ -50,11 +50,11 @@ const ListItem = () => { {items.map((item, index) => (
  • -
  • ))} diff --git a/src/app/scanner/_component/PhotoModal.tsx b/src/app/scanner/_component/PhotoModal.tsx index 767db5b..acdc62c 100644 --- a/src/app/scanner/_component/PhotoModal.tsx +++ b/src/app/scanner/_component/PhotoModal.tsx @@ -4,8 +4,8 @@ import { useRouter } from "next/navigation" import { useState } from "react" import { PostQrCodeResponse } from "@/app/api/photo" -import Button from "@/common/Button" import Icon from "@/common/Icon" +import SquareButton from "@/common/SquareButton" interface PhotoModalProps { scanInfo: PostQrCodeResponse @@ -55,15 +55,15 @@ export const PhotoModal = ({ scanInfo, onClose }: PhotoModalProps) => { priority />
    - - +
    { - const { showAlert } = useAlert() + const { showAlert } = useAlertStore() const { data, mutate, isPending } = useMutation({ mutationFn: (code: string) => postQrCode(code), diff --git a/src/app/scanner/select-album/_component/Header.tsx b/src/app/scanner/select-album/_component/Header.tsx index ff8d1d9..412d9c6 100644 --- a/src/app/scanner/select-album/_component/Header.tsx +++ b/src/app/scanner/select-album/_component/Header.tsx @@ -7,12 +7,9 @@ export const Header = () => { const router = useRouter() return (
    - router.back()} - /> +
    ) } diff --git a/src/app/scanner/select-album/page.tsx b/src/app/scanner/select-album/page.tsx index 742f3e1..f2b15d9 100644 --- a/src/app/scanner/select-album/page.tsx +++ b/src/app/scanner/select-album/page.tsx @@ -7,7 +7,7 @@ import { useEffect, useState } from "react" import { AlbumValue } from "@/app/album/types" import { getAlbums, patchPhotoAlbum } from "@/app/api/photo" import AlbumItem from "@/common/AlbumItem" -import Button from "@/common/Button" +import SquareButton from "@/common/SquareButton" import { Header } from "./_component/Header" @@ -84,13 +84,13 @@ const ScannerSelectAlbumPage = () => {
    {selectedAlbum ? ( - + ) : ( - + )}
    diff --git a/src/auth.ts b/src/auth.ts index 420e977..4668915 100644 --- a/src/auth.ts +++ b/src/auth.ts @@ -5,6 +5,8 @@ import KakaoProvider from "next-auth/providers/kakao" import { authLogin } from "@/app/api/signIn" import { ACCESS_TOKEN_KEY } from "@/constants" +import { useAuthStore } from "./store/auth" + export const { handlers: { GET, POST }, auth, @@ -26,7 +28,12 @@ export const { if (account?.access_token) { const authResponse = await authLogin(account.access_token) - cookies().set(ACCESS_TOKEN_KEY, authResponse.accessToken) + cookies().set(ACCESS_TOKEN_KEY, authResponse.accessToken, { + httpOnly: true, + sameSite: "lax", + path: "/", + maxAge: 30 * 24 * 60 * 60, // 30일 + }) const updatedAccount = { ...account, @@ -58,6 +65,7 @@ export const { events: { signOut() { cookies().delete(ACCESS_TOKEN_KEY) + useAuthStore.getState().clearAuth() return }, }, diff --git a/src/common/AlbumItem.tsx b/src/common/AlbumItem.tsx index 1ee3b0a..6545cf0 100644 --- a/src/common/AlbumItem.tsx +++ b/src/common/AlbumItem.tsx @@ -60,7 +60,11 @@ function AlbumItem({ return (
    + className={cn( + albumItemVariants({ type, isEditable }), + !isEditable && "group", + className + )}> {isEditable ? ( <> 사진 {photoCount}장
    +
    - {isSelected && ( -
    - )} {isNew && ( New! )} diff --git a/src/common/Alert.tsx b/src/common/Alert.tsx index a97dc68..2a1168c 100644 --- a/src/common/Alert.tsx +++ b/src/common/Alert.tsx @@ -1,6 +1,6 @@ import ReactDOM from "react-dom" -import Button from "./Button" +import SquareButton from "./SquareButton" interface AlertProps { title: string @@ -18,7 +18,7 @@ const Alert = ({ title, description, onClose }: AlertProps) => { {description}

    - + 확인
    , document.body diff --git a/src/common/AuthProvider.tsx b/src/common/AuthProvider.tsx deleted file mode 100644 index ba872d8..0000000 --- a/src/common/AuthProvider.tsx +++ /dev/null @@ -1,18 +0,0 @@ -"use client" - -import { SessionProvider } from "next-auth/react" -import React from "react" - -interface Props { - children: React.ReactNode -} - -const AuthProvider = ({ children }: Props) => { - return ( - - {children} - - ) -} - -export default AuthProvider diff --git a/src/common/BottomBar.tsx b/src/common/BottomBar.tsx index a23d04a..266fd65 100644 --- a/src/common/BottomBar.tsx +++ b/src/common/BottomBar.tsx @@ -5,9 +5,13 @@ import Link from "next/link" import Icon from "@/common/Icon" import { bottomBarVariants } from "@/styles/variants" +import Button from "./Button" + interface BottomBarProps { variant: "album" | "scanner" | "profile" } +const TAB_ITEM_CLASSNAME = + "flex h-[54px] w-[54px] flex-col items-center justify-center gap-[2px]" export const BottomBar = ({ variant }: BottomBarProps) => { return ( @@ -22,20 +26,24 @@ export const BottomBar = ({ variant }: BottomBarProps) => { const Album = () => { return ( <> - + -
    - -
    + - + ) @@ -45,21 +53,25 @@ const Scanner = () => { return ( <> - + - + - + ) @@ -69,22 +81,26 @@ const Profile = () => { return ( <> - + -
    - -
    + - - - + + ) } diff --git a/src/common/Button.tsx b/src/common/Button.tsx index 967384a..e9bb625 100644 --- a/src/common/Button.tsx +++ b/src/common/Button.tsx @@ -13,32 +13,19 @@ export interface ButtonProps } const Button = forwardRef( - ( - { - className, - variant, - size, - theme, - disabled, - type = "button", - asChild = false, - children, - ...props - }, - ref - ) => { + ({ className, disabled, asChild = false, children, ...props }, ref) => { const Comp = asChild ? Slot : "button" return ( +
    {children} ) diff --git a/src/common/Fallback.tsx b/src/common/Fallback.tsx index b7b1bd0..df6acca 100644 --- a/src/common/Fallback.tsx +++ b/src/common/Fallback.tsx @@ -3,9 +3,9 @@ import { useRouter } from "next/navigation" import { ComponentType } from "react" -import Button from "./Button" import { FallbackProps } from "./ErrorBoundary" import Icon from "./Icon" +import SquareButton from "./SquareButton" const Fallback: ComponentType = ({ resetErrorBoundary }) => { const router = useRouter() @@ -28,15 +28,15 @@ const Fallback: ComponentType = ({ resetErrorBoundary }) => {
    - - + + 새로고침하기
    diff --git a/src/common/FloatingButton.tsx b/src/common/FloatingButton.tsx deleted file mode 100644 index 6d1828b..0000000 --- a/src/common/FloatingButton.tsx +++ /dev/null @@ -1,7 +0,0 @@ -import Button, { ButtonProps as FloatingButtonProps } from "./Button" - -const FloatingButton = ({ className, ...props }: FloatingButtonProps) => { - return