@@ -507,6 +450,4 @@ const ClientWordDetail = ({ wordId }: WordDetailProps) => {
>
);
-};
-
-export default ClientWordDetail;
+}
diff --git a/src/components/word/ClientWordList.tsx b/src/features/word/ClientWordList.tsx
similarity index 90%
rename from src/components/word/ClientWordList.tsx
rename to src/features/word/ClientWordList.tsx
index 66ad06a..096eacd 100644
--- a/src/components/word/ClientWordList.tsx
+++ b/src/features/word/ClientWordList.tsx
@@ -27,13 +27,13 @@ interface WordType {
antonyms: null;
}
-const ClientWordList = ({
+export default function ClientWordList({
wordList,
level,
}: {
wordList: WordType[];
level: number;
-}) => {
+}) {
const [allWords, setAllWords] = useState([...wordList]);
// const [newWords, setNewWords] = useState([]);
// const [showNewOnly, setShowNewOnly] = useState(false);
@@ -69,7 +69,7 @@ const ClientWordList = ({
// .select('*')
// .eq('level', level)
// .range(0, 999);
-
+ //
// if (error) {
// console.error('신규 단어 조회 실패:', error);
// toast.error('신규 단어 조회 실패. 다시 시도해주세요.');
@@ -78,7 +78,7 @@ const ClientWordList = ({
// setHasLoadedNewWords(true);
// }
// };
-
+ //
// fetchNewWords();
// }
// }, [showNewOnly, level, hasLoadedNewWords]);
@@ -97,18 +97,20 @@ const ClientWordList = ({
{showNewOnly && `(${newWords.length}개)`}
*/}
-
+
{/* {(showNewOnly ? newWords : allWords).map((word, index) => ( */}
{allWords.map((word, index) => (
-
- {word.word}
+
+
+ {word.word}
+
[{word.pinyin}]
-
+
{word.meaning}
({word.part_of_speech})
@@ -120,6 +122,4 @@ const ClientWordList = ({
>
);
-};
-
-export default ClientWordList;
+}
diff --git a/src/components/word/HanziWriter.tsx b/src/features/word/HanziWriter.tsx
similarity index 92%
rename from src/components/word/HanziWriter.tsx
rename to src/features/word/HanziWriter.tsx
index 1049374..96ba5e1 100644
--- a/src/components/word/HanziWriter.tsx
+++ b/src/features/word/HanziWriter.tsx
@@ -2,7 +2,7 @@
import { useEffect } from 'react';
import HanziWriterLib from 'hanzi-writer';
-const HanziWriter = ({ characters }: { characters: string[] }) => {
+export default function HanziWriter({ characters }: { characters: string[] }) {
useEffect(() => {
const run = async () => {
// 모든 한자 writer를 생성하는데
@@ -48,6 +48,4 @@ const HanziWriter = ({ characters }: { characters: string[] }) => {
))}
);
-};
-
-export default HanziWriter;
+}
diff --git a/src/components/word/PlayAudioButton.tsx b/src/features/word/PlayAudioButton.tsx
similarity index 87%
rename from src/components/word/PlayAudioButton.tsx
rename to src/features/word/PlayAudioButton.tsx
index 0f323de..2e1b3df 100644
--- a/src/components/word/PlayAudioButton.tsx
+++ b/src/features/word/PlayAudioButton.tsx
@@ -2,7 +2,7 @@
import { useRef, useState } from 'react';
import { Volume2 } from 'lucide-react';
-const PlayAudioButton = ({ audioUrl }: { audioUrl: string }) => {
+export default function PlayAudioButton({ audioUrl }: { audioUrl: string }) {
const audioRef = useRef
(null);
const [playing, setPlaying] = useState(false);
@@ -26,6 +26,4 @@ const PlayAudioButton = ({ audioUrl }: { audioUrl: string }) => {
/>
);
-};
-
-export default PlayAudioButton;
+}
diff --git a/src/components/word/WordDetailSkeleton.tsx b/src/features/word/WordDetailSkeleton.tsx
similarity index 98%
rename from src/components/word/WordDetailSkeleton.tsx
rename to src/features/word/WordDetailSkeleton.tsx
index 8a97cf2..871266a 100644
--- a/src/components/word/WordDetailSkeleton.tsx
+++ b/src/features/word/WordDetailSkeleton.tsx
@@ -1,7 +1,7 @@
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
import { BookOpen, Link } from 'lucide-react';
-const WordDetailSkeleton = () => {
+export default function WordDetailSkeleton() {
return (
<>
@@ -81,6 +81,4 @@ const WordDetailSkeleton = () => {
>
);
-};
-
-export default WordDetailSkeleton;
+}
diff --git a/src/hooks/useMoal.ts b/src/hooks/useMoal.ts
new file mode 100644
index 0000000..46ae1d8
--- /dev/null
+++ b/src/hooks/useMoal.ts
@@ -0,0 +1,13 @@
+import { create } from 'zustand';
+
+type ModalStore = {
+ loginOpen: boolean;
+ openLoginModal: () => void;
+ closeLoginModal: () => void;
+};
+
+export const useModal = create((set) => ({
+ loginOpen: false,
+ openLoginModal: () => set({ loginOpen: true }),
+ closeLoginModal: () => set({ loginOpen: false }),
+}));
diff --git a/src/lib/supabase/server.ts b/src/lib/supabase/server.ts
index eb87706..64d2e2e 100644
--- a/src/lib/supabase/server.ts
+++ b/src/lib/supabase/server.ts
@@ -15,9 +15,9 @@ export async function createClient() {
cookiesToSet.forEach(({ name, value, options }) => {
cookieStore.set(name, value, options);
});
- } catch (error) {
- // 미들웨어가 처리함
- console.error(error);
+ // 미들웨어가 처리함 - Server Component에서는 쿠키 set 불가하므로 무시
+ } catch {
+ // ignore
}
},
},
diff --git a/src/lib/supabase/userApi.ts b/src/lib/supabase/userApi.ts
index debcc85..7eb11bc 100644
--- a/src/lib/supabase/userApi.ts
+++ b/src/lib/supabase/userApi.ts
@@ -6,7 +6,11 @@ export const fetchCurrentUser = async (): Promise => {
const { data, error } = await supabase.auth.getUser();
if (error) {
- console.error(`[ERROR] SELECT User data: ${error}`);
+ if (error.message?.includes('Auth session missing')) {
+ // 로그인 안 된 상태: 정상, null 반환
+ return null;
+ }
+ console.error('[ERROR] SELECT User data:', error);
throw error;
}
diff --git a/src/types/word.ts b/src/types/word.ts
index 8c9398b..37195b7 100644
--- a/src/types/word.ts
+++ b/src/types/word.ts
@@ -2,3 +2,35 @@ export type WordText = {
id: string;
text: string;
};
+
+export type WordData = {
+ id: string;
+ word: string;
+ pinyin: string;
+ meaning: string;
+ part_of_speech: string;
+ examples: ExampleType[];
+ word_relations: RelationWordType[];
+ is_bookmarked?: boolean;
+};
+
+export type ExampleType = {
+ sentence: string;
+ meaning: string;
+ pinyin: string;
+ context: string;
+};
+
+type RelationType = 'synonym' | 'antonym';
+
+export type RelationWordType = {
+ word: string;
+ meaning: string;
+ pinyin: string;
+ relation_type?: RelationType;
+};
+
+export type WordDetailProps = {
+ wordId: string;
+ initialData: WordData;
+};
diff --git a/tailwind.config.js b/tailwind.config.js
new file mode 100644
index 0000000..8827f67
--- /dev/null
+++ b/tailwind.config.js
@@ -0,0 +1,12 @@
+module.exports = {
+ theme: {
+ screens: {
+ xs: '480px',
+ sm: '640px',
+ md: '768px',
+ lg: '1024px',
+ xl: '1280px',
+ '2xl': '1536px',
+ },
+ },
+};