{t('title')}
+
{t('branding.headline')}
- {t('branding.headlineSub')}
+ {t('branding.headlineSub')}
-
- {t('branding.headlineSub')} + {t('branding.headlineSub')}
+
{t('branding.description')}
- {error} + {error ?? routeErrorMessage}
)}
+
{t('branding.headline')}
- {t('branding.headlineSub')}
+ {t('branding.headlineSub')}
-
- {t('branding.headlineSub')} + {t('branding.headlineSub')}
+
{t('branding.description')}
- {t('hasAccount')}?
+ {t('hasAccount')}
{t('loginLink')}
diff --git a/app/[locale]/(dashboard)/brand-profiles/client.tsx b/app/[locale]/(dashboard)/brand-profiles/client.tsx
index b3ea900..253387b 100644
--- a/app/[locale]/(dashboard)/brand-profiles/client.tsx
+++ b/app/[locale]/(dashboard)/brand-profiles/client.tsx
@@ -146,9 +146,9 @@ export function BrandProfilesClient({ initialProfiles, plan }: BrandProfilesClie
{project.platform === 'web' ? tPlatform('web') : project.platform === 'mobile' ? tPlatform('mobile') : tPlatform('all')}
diff --git a/app/[locale]/(dashboard)/projects/actions.ts b/app/[locale]/(dashboard)/projects/actions.ts
index 7ea7a3e..284a528 100644
--- a/app/[locale]/(dashboard)/projects/actions.ts
+++ b/app/[locale]/(dashboard)/projects/actions.ts
@@ -1,14 +1,36 @@
'use server'
import { createClient } from '@/lib/supabase/server'
+import { checkUsage, incrementUsage } from '@/lib/utils/rate-limit'
import type { Project } from '@/types/database'
-export async function duplicateProject(projectId: string): Promise<{ success: boolean; newProjectId?: string; error?: string }> {
+export type DuplicateProjectResult =
+ | { success: true; newProjectId: string }
+ | {
+ success: false
+ error: string
+ code?: 'PROJECT_LIMIT_REACHED' | 'UNAUTHORIZED' | 'NOT_FOUND'
+ current?: number
+ limit?: number
+ }
+
+export async function duplicateProject(projectId: string): Promise
{hasActiveFilter ? t('filters.noResults') : t('empty.description')}
+
{t('subscription.projectsPerMonth')}
@@ -116,7 +116,7 @@ export default async function SettingsPage({
+
{t('subscription.aiHeadlines')}
@@ -124,7 +124,7 @@ export default async function SettingsPage({
+
{t('subscription.brandProfiles')}
{limits.brand_profiles}
@@ -84,7 +102,7 @@ export function DemoClient() {
+
{t('colorPalette')}
+
{t('keywords')}
+
{t('ogPreview')}
{t('downloadDescription')}
{t('freeNote')}
- {t('modal.description')}
-
+ {copy.description}
+
+ 연 ${PLAN_PRICING.pro.yearly.price} 결제 (${PLAN_PRICING.pro.yearly.savings} 절약)
+
diff --git a/components/brand-profile/profile-card.tsx b/components/brand-profile/profile-card.tsx
index f7a8ae1..3710755 100644
--- a/components/brand-profile/profile-card.tsx
+++ b/components/brand-profile/profile-card.tsx
@@ -43,7 +43,7 @@ export function ProfileCard({ profile, onEdit, onDelete }: ProfileCardProps) {
{menuOpen && (
<>
+
{t.subtitle}
{t.thanks} {t.thanksSubtitle} {t.thanks} {t.thanksSubtitle}
+
{t.sentimentLabel}
{project.name}
-
@@ -146,12 +145,19 @@ export default async function ProjectsPage({
{tBilling('planComparison')}
+ {tBilling('planComparison')}
+ {plan === 'free' && (
+
+
{t('title')}
+
{t('downloadTitle')}
- {t('modal.title')}
-
-
{t.title}
-