diff --git a/.gitignore b/.gitignore
index 9132568..9ac7740 100644
--- a/.gitignore
+++ b/.gitignore
@@ -50,3 +50,5 @@ yarn-error.log*
test-results
playwright-report
+
+/scripts/
\ No newline at end of file
diff --git a/__tests__/unit/components/SortDropdown.test.tsx b/__tests__/unit/components/SortDropdown.test.tsx
index 39db4e7..a4399cb 100644
--- a/__tests__/unit/components/SortDropdown.test.tsx
+++ b/__tests__/unit/components/SortDropdown.test.tsx
@@ -1,19 +1,21 @@
-import { describe, it, expect, vi } from 'vitest';
+import { describe, it, expect, vi, beforeEach } from 'vitest';
import { render, screen, fireEvent } from '@testing-library/react';
import { SortDropdown } from '@/components/utils/SortDropdown';
import { useSearchParams } from 'next/navigation';
-import { useRouter, usePathname } from 'next/navigation';
+import { useRouter, usePathname } from '@/i18n/routing';
/* eslint-disable @typescript-eslint/no-explicit-any */
-// Mock next/navigation
+// Mock next/navigation for useSearchParams
vi.mock('next/navigation', () => ({
- useRouter: vi.fn(),
useSearchParams: vi.fn(),
+}));
+
+// Mock @/i18n/routing
+vi.mock('@/i18n/routing', () => ({
+ useRouter: vi.fn(),
usePathname: vi.fn(),
- redirect: vi.fn(),
- permanentRedirect: vi.fn(),
- notFound: vi.fn(),
+ Link: ({ children, href, ...props }: any) => {children},
}));
// Mock next-intl
diff --git a/__tests__/unit/lib/posts.helper.test.ts b/__tests__/unit/lib/posts.helper.test.ts
index 830f890..b519e55 100644
--- a/__tests__/unit/lib/posts.helper.test.ts
+++ b/__tests__/unit/lib/posts.helper.test.ts
@@ -183,7 +183,7 @@ describe('posts.helper - API Response Parsing', () => {
};
const result = extractBlogPostFromPage(mockPage);
- expect(result.language).toBe('ko');
+ expect(result.language).toBe('KR');
});
it('should handle missing translation relation', () => {
diff --git a/playwright.config.ts b/playwright.config.ts
index e2ac87a..4eab76a 100644
--- a/playwright.config.ts
+++ b/playwright.config.ts
@@ -8,13 +8,13 @@ export default defineConfig({
workers: process.env.CI ? 1 : undefined,
reporter: 'html',
webServer: {
- command: 'npm run dev -- -p 3001',
- url: 'http://localhost:3001',
+ command: 'npm run dev -- -p 3000',
+ url: process.env.NEXT_PUBLIC_BASE_URL || 'http://localhost:3000',
reuseExistingServer: !process.env.CI,
timeout: 120 * 1000,
},
use: {
- baseURL: 'http://localhost:3001',
+ baseURL: process.env.NEXT_PUBLIC_BASE_URL || 'http://localhost:3000',
trace: 'on-first-retry',
},
projects: [
diff --git a/src/components/error-fallbacks/CommentErrorFallback.tsx b/src/components/error-fallbacks/CommentErrorFallback.tsx
index 185bc88..9a8abea 100644
--- a/src/components/error-fallbacks/CommentErrorFallback.tsx
+++ b/src/components/error-fallbacks/CommentErrorFallback.tsx
@@ -1,3 +1,5 @@
+'use client';
+
export function CommentErrorFallback() {
return (
diff --git a/src/components/error-fallbacks/PostErrorFallback.tsx b/src/components/error-fallbacks/PostErrorFallback.tsx
index 5bfe704..ade0e13 100644
--- a/src/components/error-fallbacks/PostErrorFallback.tsx
+++ b/src/components/error-fallbacks/PostErrorFallback.tsx
@@ -1,3 +1,5 @@
+'use client';
+
import { Link } from "@/i18n/routing";
export function PostErrorFallback() {
diff --git a/src/components/utils/ActiveFilters.tsx b/src/components/utils/ActiveFilters.tsx
index 88ee53f..dd484ce 100644
--- a/src/components/utils/ActiveFilters.tsx
+++ b/src/components/utils/ActiveFilters.tsx
@@ -1,6 +1,7 @@
'use client';
-import { useRouter, useSearchParams, usePathname } from 'next/navigation';
+import { useSearchParams } from 'next/navigation';
+import { useRouter, usePathname } from '@/i18n/routing';
import { useTranslations } from 'next-intl';
import { X } from 'lucide-react';
diff --git a/src/components/utils/Sidebar.tsx b/src/components/utils/Sidebar.tsx
index d51a81d..bc32a50 100644
--- a/src/components/utils/Sidebar.tsx
+++ b/src/components/utils/Sidebar.tsx
@@ -1,6 +1,7 @@
'use client';
-import { useRouter, useSearchParams, usePathname } from 'next/navigation';
+import { useSearchParams } from 'next/navigation';
+import { useRouter, usePathname } from '@/i18n/routing';
import { useTranslations } from 'next-intl';
import { cn } from "@/lib/utils";
import { SortDropdown } from "./SortDropdown";
diff --git a/src/components/utils/SortDropdown.tsx b/src/components/utils/SortDropdown.tsx
index b12e99f..8dfecd1 100644
--- a/src/components/utils/SortDropdown.tsx
+++ b/src/components/utils/SortDropdown.tsx
@@ -1,6 +1,7 @@
'use client';
-import { useRouter, useSearchParams, usePathname } from 'next/navigation';
+import { useSearchParams } from 'next/navigation';
+import { useRouter, usePathname } from '@/i18n/routing';
import { useTranslations } from 'next-intl';
import { SortOption } from '@/lib/types';
diff --git a/src/lib/services/posts.helper.ts b/src/lib/services/posts.helper.ts
index 9dc3840..7c46fee 100644
--- a/src/lib/services/posts.helper.ts
+++ b/src/lib/services/posts.helper.ts
@@ -62,7 +62,7 @@ export function extractBlogPostFromPage(p: PageObjectResponse): BlogPost {
const groupName = getSelectValue(p.properties.group);
const part = getSelectValue(p.properties.part);
- const language = getSelectValue(p.properties.language) || 'ko';
+ const language = getSelectValue(p.properties.language) || 'KR';
const translationId = getRelationId(p.properties.translation);
const viewCount = getNumberValue(p.properties.view_count);
const commentCount = getNumberValue(p.properties.comment_count);
diff --git a/src/lib/services/posts.service.ts b/src/lib/services/posts.service.ts
index 6661dbd..573a49b 100644
--- a/src/lib/services/posts.service.ts
+++ b/src/lib/services/posts.service.ts
@@ -20,6 +20,12 @@ const getCachedAllPosts = unstable_cache(async (): Promise =>
try {
response = await notion.dataSources.query({
data_source_id: dataSourceId,
+ filter: {
+ property: "published_date",
+ date: {
+ before: new Date().toISOString(),
+ },
+ },
sorts: [
{
timestamp: "created_time",
@@ -37,7 +43,7 @@ const getCachedAllPosts = unstable_cache(async (): Promise =>
.map(extractBlogPostFromPage);
return posts;
-}, ['all-posts-v4'], { revalidate: 3600 });
+}, ['all-posts-v5'], { revalidate: 3600 });
export interface GetPublishedPostsOptions {
tag?: string;
@@ -75,8 +81,15 @@ export const getPublishedPosts = async (options: GetPublishedPostsOptions = {}):
// Filter by locale (Language property)
// Map 'en' locale to 'EN' property value, 'ko' to 'KR' (or whatever is used in Notion)
// Assuming Notion uses 'KR' and 'EN' as select options
- const targetLang = locale === 'ko' ? 'KR' : 'EN';
- if (post.language && post.language !== targetLang) return false;
+ if (post.language) {
+ if (locale === 'ko') {
+ // For Korean locale, accept 'KR', etc.
+ if (post.language !== 'KR') return false;
+ } else {
+ // For English locale, strictly check for 'EN'
+ if (post.language !== 'EN') return false;
+ }
+ }
// Filter by tags (multi-tag AND filtering)
if (selectedTags.length > 0) {