Merge remote-tracking branch 'origin/main' into cloudflare
This commit is contained in:
commit
62eb4124be
@ -181,8 +181,9 @@ FAL_API_KEY=""
|
||||
FIREWORKS_API_KEY=""
|
||||
OPENAI_API_KEY=""
|
||||
REPLICATE_API_TOKEN=""
|
||||
GOOGLE_API_KEY=""
|
||||
GOOGLE_GENERATIVE_AI_API_KEY=""
|
||||
DEEPSEEK_API_KEY=""
|
||||
OPENROUTER_API_KEY=""
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Web Content Analyzer (Firecrawl)
|
||||
|
24
package.json
24
package.json
@ -25,13 +25,12 @@
|
||||
"knip": "knip"
|
||||
},
|
||||
"dependencies": {
|
||||
"@ai-sdk/deepseek": "^0.2.16",
|
||||
"@ai-sdk/fal": "^0.1.12",
|
||||
"@ai-sdk/fireworks": "^0.2.14",
|
||||
"@ai-sdk/google": "^1.2.22",
|
||||
"@ai-sdk/google-vertex": "^2.2.24",
|
||||
"@ai-sdk/openai": "^1.1.13",
|
||||
"@ai-sdk/replicate": "^0.2.8",
|
||||
"@ai-sdk/deepseek": "^1.0.0",
|
||||
"@ai-sdk/fal": "^1.0.0",
|
||||
"@ai-sdk/fireworks": "^1.0.0",
|
||||
"@ai-sdk/google": "^2.0.0",
|
||||
"@ai-sdk/openai": "^2.0.0",
|
||||
"@ai-sdk/replicate": "^1.0.0",
|
||||
"@base-ui-components/react": "1.0.0-beta.0",
|
||||
"@better-fetch/fetch": "^1.1.18",
|
||||
"@dnd-kit/core": "^6.3.1",
|
||||
@ -43,6 +42,7 @@
|
||||
"@mendable/firecrawl-js": "^1.29.1",
|
||||
"@next/third-parties": "^15.3.0",
|
||||
"@openpanel/nextjs": "^1.0.7",
|
||||
"@openrouter/ai-sdk-provider": "^1.0.0-beta.6",
|
||||
"@orama/orama": "^3.1.4",
|
||||
"@orama/tokenizers": "^3.1.4",
|
||||
"@radix-ui/react-accordion": "^1.2.3",
|
||||
@ -83,7 +83,7 @@
|
||||
"@vercel/analytics": "^1.5.0",
|
||||
"@vercel/speed-insights": "^1.2.0",
|
||||
"@widgetbot/react-embed": "^1.9.0",
|
||||
"ai": "^4.1.45",
|
||||
"ai": "^5.0.0",
|
||||
"better-auth": "^1.1.19",
|
||||
"canvas-confetti": "^1.9.3",
|
||||
"class-variance-authority": "^0.7.1",
|
||||
@ -98,9 +98,9 @@
|
||||
"drizzle-orm": "^0.39.3",
|
||||
"embla-carousel-react": "^8.5.2",
|
||||
"framer-motion": "^12.4.7",
|
||||
"fumadocs-core": "^15.5.3",
|
||||
"fumadocs-mdx": "^11.6.8",
|
||||
"fumadocs-ui": "^15.5.3",
|
||||
"fumadocs-core": "^15.6.7",
|
||||
"fumadocs-mdx": "^11.7.3",
|
||||
"fumadocs-ui": "^15.6.7",
|
||||
"inngest": "^3.40.1",
|
||||
"input-otp": "^1.4.2",
|
||||
"lucide-react": "^0.483.0",
|
||||
@ -133,7 +133,7 @@
|
||||
"use-intl": "^3.26.5",
|
||||
"use-media": "^1.5.0",
|
||||
"vaul": "^1.1.2",
|
||||
"zod": "^3.24.2",
|
||||
"zod": "^4.0.14",
|
||||
"zustand": "^5.0.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
959
pnpm-lock.yaml
generated
959
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@ -9,7 +9,7 @@ const actionClient = createSafeActionClient();
|
||||
|
||||
// Newsletter schema for validation
|
||||
const newsletterSchema = z.object({
|
||||
email: z.string().email({ message: 'Please enter a valid email address' }),
|
||||
email: z.email({ error: 'Please enter a valid email address' }),
|
||||
});
|
||||
|
||||
// Create a safe action to check if a user is subscribed to the newsletter
|
||||
|
@ -18,10 +18,10 @@ const actionClient = createSafeActionClient();
|
||||
// Checkout schema for validation
|
||||
// metadata is optional, and may contain referral information if you need
|
||||
const checkoutSchema = z.object({
|
||||
userId: z.string().min(1, { message: 'User ID is required' }),
|
||||
planId: z.string().min(1, { message: 'Plan ID is required' }),
|
||||
priceId: z.string().min(1, { message: 'Price ID is required' }),
|
||||
metadata: z.record(z.string()).optional(),
|
||||
userId: z.string().min(1, { error: 'User ID is required' }),
|
||||
planId: z.string().min(1, { error: 'Plan ID is required' }),
|
||||
priceId: z.string().min(1, { error: 'Price ID is required' }),
|
||||
metadata: z.record(z.string(), z.string()).optional(),
|
||||
});
|
||||
|
||||
/**
|
||||
|
@ -18,10 +18,10 @@ const actionClient = createSafeActionClient();
|
||||
// Credit checkout schema for validation
|
||||
// metadata is optional, and may contain referral information if you need
|
||||
const creditCheckoutSchema = z.object({
|
||||
userId: z.string().min(1, { message: 'User ID is required' }),
|
||||
packageId: z.string().min(1, { message: 'Package ID is required' }),
|
||||
priceId: z.string().min(1, { message: 'Price ID is required' }),
|
||||
metadata: z.record(z.string()).optional(),
|
||||
userId: z.string().min(1, { error: 'User ID is required' }),
|
||||
packageId: z.string().min(1, { error: 'Package ID is required' }),
|
||||
priceId: z.string().min(1, { error: 'Price ID is required' }),
|
||||
metadata: z.record(z.string(), z.string()).optional(),
|
||||
});
|
||||
|
||||
/**
|
||||
|
@ -16,10 +16,10 @@ const actionClient = createSafeActionClient();
|
||||
|
||||
// Portal schema for validation
|
||||
const portalSchema = z.object({
|
||||
userId: z.string().min(1, { message: 'User ID is required' }),
|
||||
userId: z.string().min(1, { error: 'User ID is required' }),
|
||||
returnUrl: z
|
||||
.string()
|
||||
.url({ message: 'Return URL must be a valid URL' })
|
||||
.url({ error: 'Return URL must be a valid URL' })
|
||||
.optional(),
|
||||
});
|
||||
|
||||
|
@ -10,7 +10,7 @@ const actionClient = createSafeActionClient();
|
||||
|
||||
// Input schema
|
||||
const schema = z.object({
|
||||
userId: z.string().min(1, { message: 'User ID is required' }),
|
||||
userId: z.string().min(1, { error: 'User ID is required' }),
|
||||
});
|
||||
|
||||
/**
|
||||
@ -47,6 +47,18 @@ export const getActiveSubscriptionAction = actionClient
|
||||
};
|
||||
}
|
||||
|
||||
// Check if Stripe environment variables are configured
|
||||
const stripeSecretKey = process.env.STRIPE_SECRET_KEY;
|
||||
const stripeWebhookSecret = process.env.STRIPE_WEBHOOK_SECRET;
|
||||
|
||||
if (!stripeSecretKey || !stripeWebhookSecret) {
|
||||
console.log('Stripe environment variables not configured, return');
|
||||
return {
|
||||
success: true,
|
||||
data: null, // No subscription = free plan
|
||||
};
|
||||
}
|
||||
|
||||
try {
|
||||
// Find the user's most recent active subscription
|
||||
const subscriptions = await getSubscriptions({
|
||||
|
@ -14,7 +14,7 @@ const actionClient = createSafeActionClient();
|
||||
|
||||
// Input schema
|
||||
const schema = z.object({
|
||||
userId: z.string().min(1, { message: 'User ID is required' }),
|
||||
userId: z.string().min(1, { error: 'User ID is required' }),
|
||||
});
|
||||
|
||||
/**
|
||||
|
@ -17,13 +17,13 @@ const actionClient = createSafeActionClient();
|
||||
const contactFormSchema = z.object({
|
||||
name: z
|
||||
.string()
|
||||
.min(3, { message: 'Name must be at least 3 characters' })
|
||||
.max(30, { message: 'Name must not exceed 30 characters' }),
|
||||
email: z.string().email({ message: 'Please enter a valid email address' }),
|
||||
.min(3, { error: 'Name must be at least 3 characters' })
|
||||
.max(30, { error: 'Name must not exceed 30 characters' }),
|
||||
email: z.email({ error: 'Please enter a valid email address' }),
|
||||
message: z
|
||||
.string()
|
||||
.min(10, { message: 'Message must be at least 10 characters' })
|
||||
.max(500, { message: 'Message must not exceed 500 characters' }),
|
||||
.min(10, { error: 'Message must be at least 10 characters' })
|
||||
.max(500, { error: 'Message must not exceed 500 characters' }),
|
||||
});
|
||||
|
||||
// Create a safe action for contact form submission
|
||||
|
@ -11,7 +11,7 @@ const actionClient = createSafeActionClient();
|
||||
|
||||
// Newsletter schema for validation
|
||||
const newsletterSchema = z.object({
|
||||
email: z.string().email({ message: 'Please enter a valid email address' }),
|
||||
email: z.email({ error: 'Please enter a valid email address' }),
|
||||
});
|
||||
|
||||
// Create a safe action for newsletter subscription
|
||||
|
@ -10,7 +10,7 @@ const actionClient = createSafeActionClient();
|
||||
|
||||
// Newsletter schema for validation
|
||||
const newsletterSchema = z.object({
|
||||
email: z.string().email({ message: 'Please enter a valid email address' }),
|
||||
email: z.email({ error: 'Please enter a valid email address' }),
|
||||
});
|
||||
|
||||
// Create a safe action for newsletter unsubscription
|
||||
|
@ -9,7 +9,7 @@ const actionClient = createSafeActionClient();
|
||||
|
||||
// Captcha validation schema
|
||||
const captchaSchema = z.object({
|
||||
captchaToken: z.string().min(1, { message: 'Captcha token is required' }),
|
||||
captchaToken: z.string().min(1, { error: 'Captcha token is required' }),
|
||||
});
|
||||
|
||||
// Create a safe action for captcha validation
|
||||
|
@ -61,7 +61,6 @@ export function ImagePlayground({
|
||||
|
||||
const providerToModel = {
|
||||
replicate: selectedModels.replicate,
|
||||
// vertex: selectedModels.vertex,
|
||||
openai: selectedModels.openai,
|
||||
fireworks: selectedModels.fireworks,
|
||||
fal: selectedModels.fal,
|
||||
|
@ -15,7 +15,6 @@ import {
|
||||
FireworksIcon,
|
||||
OpenAIIcon,
|
||||
ReplicateIcon,
|
||||
// VertexIcon,
|
||||
falAILogo,
|
||||
} from '../lib/logos';
|
||||
import type { ProviderKey } from '../lib/provider-config';
|
||||
@ -40,7 +39,6 @@ interface ModelSelectProps {
|
||||
const PROVIDER_ICONS = {
|
||||
openai: OpenAIIcon,
|
||||
replicate: ReplicateIcon,
|
||||
// vertex: VertexIcon,
|
||||
fireworks: FireworksIcon,
|
||||
fal: falAILogo,
|
||||
} as const;
|
||||
@ -48,7 +46,6 @@ const PROVIDER_ICONS = {
|
||||
const PROVIDER_LINKS = {
|
||||
openai: 'openai',
|
||||
replicate: 'replicate',
|
||||
// vertex: 'google-vertex',
|
||||
fireworks: 'fireworks',
|
||||
fal: 'fal',
|
||||
} as const;
|
||||
|
@ -62,55 +62,6 @@ export const ReplicateIcon = ({ size = 16 }) => {
|
||||
);
|
||||
};
|
||||
|
||||
export const VertexIcon = ({ size = 16 }) => {
|
||||
return (
|
||||
<svg
|
||||
height={size}
|
||||
width={size}
|
||||
viewBox="0 0 512 512"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
style={{ color: 'currentcolor' }}
|
||||
>
|
||||
<g transform="scale(0.8) translate(65,65)">
|
||||
<path
|
||||
d="M128,249c-8.8,0-16-7.2-16-16v-105c0-8.8,7.2-16,16-16s16,7.2,16,16v105c0,8.8-7.2,16-16,16Z"
|
||||
fill="white"
|
||||
/>
|
||||
<path
|
||||
d="M256,464c-3,0-6-.8-8.6-2.5l-176-112c-7.5-4.7-9.7-14.6-4.9-22.1,4.8-7.5,14.6-9.6,22.1-4.9l167.4,106.5,167.4-106.5c7.5-4.7,17.3-2.5,22.1,4.9,4.7,7.5,2.5,17.3-4.9,22.1l-176,112c-2.6,1.7-5.6,2.5-8.6,2.5h0Z"
|
||||
fill="white"
|
||||
/>
|
||||
<path
|
||||
d="M256,394c-8.8,0-16-7.2-16-16v-73.1c0-8.8,7.2-16,16-16s16,7.2,16,16v73.1c0,8.8-7.2,16-16,16Z"
|
||||
fill="white"
|
||||
/>
|
||||
<circle cx="128" cy="64" r="16" fill="white" />
|
||||
<circle cx="128" cy="297" r="16" fill="white" />
|
||||
<path
|
||||
d="M384.2,314c-8.8,0-16-7.1-16-16l-.2-106c0-8.8,7.1-16,16-16h0c8.8,0,16,7.1,16,16l.2,106c0,8.8-7.1,16-16,16h0Z"
|
||||
fill="white"
|
||||
/>
|
||||
<circle cx="384" cy="64" r="16" fill="white" />
|
||||
<circle cx="384" cy="128" r="16" fill="white" />
|
||||
<path
|
||||
d="M320,225c-8.8,0-16-7.2-16-16v-103c0-8.8,7.2-16,16-16s16,7.2,16,16v103c0,8.8-7.2,16-16,16Z"
|
||||
fill="white"
|
||||
/>
|
||||
<circle cx="256" cy="177" r="16" fill="white" />
|
||||
<circle cx="256" cy="241" r="16" fill="white" />
|
||||
<circle cx="320" cy="273" r="16" fill="white" />
|
||||
<circle cx="320" cy="337" r="16" fill="white" />
|
||||
<path
|
||||
d="M192,225c-8.8,0-16-7.2-16-16v-103c0-8.8,7.2-16,16-16s16,7.2,16,16v103c0,8.8-7.2,16-16,16Z"
|
||||
fill="white"
|
||||
/>
|
||||
<circle cx="192" cy="273" r="16" fill="white" />
|
||||
<circle cx="192" cy="337" r="16" fill="white" />
|
||||
</g>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
|
||||
export const falAILogo = ({ size = 16 }: { size: number }) => {
|
||||
return (
|
||||
<svg
|
||||
|
@ -1,9 +1,4 @@
|
||||
export type ProviderKey =
|
||||
| 'replicate'
|
||||
// | 'vertex'
|
||||
| 'openai'
|
||||
| 'fireworks'
|
||||
| 'fal';
|
||||
export type ProviderKey = 'replicate' | 'openai' | 'fireworks' | 'fal';
|
||||
export type ModelMode = 'performance' | 'quality';
|
||||
|
||||
export const PROVIDERS: Record<
|
||||
@ -37,12 +32,6 @@ export const PROVIDERS: Record<
|
||||
'stability-ai/stable-diffusion-3.5-large-turbo',
|
||||
],
|
||||
},
|
||||
// vertex: {
|
||||
// displayName: 'Vertex AI',
|
||||
// iconPath: '/provider-icons/vertex.svg',
|
||||
// color: 'from-green-500 to-emerald-500',
|
||||
// models: ['imagen-3.0-generate-001', 'imagen-3.0-fast-generate-001'],
|
||||
// },
|
||||
// https://ai-sdk.dev/providers/ai-sdk-providers/openai#image-models
|
||||
openai: {
|
||||
displayName: 'OpenAI',
|
||||
@ -92,14 +81,12 @@ export const PROVIDERS: Record<
|
||||
export const MODEL_CONFIGS: Record<ModelMode, Record<ProviderKey, string>> = {
|
||||
performance: {
|
||||
replicate: 'black-forest-labs/flux-1.1-pro',
|
||||
// vertex: 'imagen-3.0-fast-generate-001',
|
||||
openai: 'dall-e-3',
|
||||
fireworks: 'accounts/fireworks/models/flux-1-schnell-fp8',
|
||||
fal: 'fal-ai/flux/dev',
|
||||
},
|
||||
quality: {
|
||||
replicate: 'stability-ai/stable-diffusion-3.5-large',
|
||||
// vertex: 'imagen-3.0-generate-001',
|
||||
openai: 'dall-e-3',
|
||||
fireworks: 'accounts/fireworks/models/flux-1-dev-fp8',
|
||||
fal: 'fal-ai/flux-pro/v1.1-ultra',
|
||||
@ -108,7 +95,6 @@ export const MODEL_CONFIGS: Record<ModelMode, Record<ProviderKey, string>> = {
|
||||
|
||||
export const PROVIDER_ORDER: ProviderKey[] = [
|
||||
'replicate',
|
||||
// 'vertex',
|
||||
'openai',
|
||||
'fireworks',
|
||||
'fal',
|
||||
|
@ -40,7 +40,7 @@ import { useDebounce } from '../utils/performance';
|
||||
|
||||
// Form schema for URL input
|
||||
const urlFormSchema = z.object({
|
||||
url: z.string().url().optional(), // Allow empty string for initial state
|
||||
url: z.url().optional(), // Allow empty string for initial state
|
||||
});
|
||||
|
||||
type UrlFormData = z.infer<typeof urlFormSchema>;
|
||||
@ -164,6 +164,7 @@ export function UrlInputForm({
|
||||
<SelectItem value="openai">OpenAI GPT-4o</SelectItem>
|
||||
<SelectItem value="gemini">Google Gemini</SelectItem>
|
||||
<SelectItem value="deepseek">DeepSeek</SelectItem>
|
||||
<SelectItem value="openrouter">OpenRouter</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
|
@ -117,6 +117,13 @@ export const webContentAnalyzerConfig = {
|
||||
temperature: 0.1,
|
||||
maxTokens: 2000,
|
||||
},
|
||||
openrouter: {
|
||||
model: 'openrouter/horizon-beta',
|
||||
// model: 'x-ai/grok-3-beta',
|
||||
// model: 'openai/gpt-4o-mini',
|
||||
temperature: 0.1,
|
||||
maxTokens: 2000,
|
||||
},
|
||||
} as const;
|
||||
|
||||
/**
|
||||
|
@ -97,9 +97,8 @@ export interface LoadingStatesProps {
|
||||
|
||||
// URL Validation Schema
|
||||
export const urlSchema = z
|
||||
.string()
|
||||
.url()
|
||||
.min(1, 'URL is required')
|
||||
.url('Please enter a valid URL')
|
||||
.refine(
|
||||
(url) => url.startsWith('http://') || url.startsWith('https://'),
|
||||
'URL must start with http:// or https://'
|
||||
@ -114,13 +113,13 @@ export const analysisResultsSchema = z.object({
|
||||
pricing: z.string().default('Not specified'),
|
||||
useCases: z.array(z.string()).default([]),
|
||||
url: urlSchema,
|
||||
analyzedAt: z.string().datetime(),
|
||||
analyzedAt: z.iso.datetime(),
|
||||
});
|
||||
|
||||
// API Request Schema
|
||||
export const analyzeContentRequestSchema = z.object({
|
||||
url: urlSchema,
|
||||
modelProvider: z.enum(['openai', 'gemini', 'deepseek']),
|
||||
modelProvider: z.enum(['openai', 'gemini', 'deepseek', 'openrouter']),
|
||||
});
|
||||
|
||||
// API Response Schema
|
||||
|
@ -1,12 +1,17 @@
|
||||
import { UpdateAvatarCard } from '@/components/settings/profile/update-avatar-card';
|
||||
import { UpdateNameCard } from '@/components/settings/profile/update-name-card';
|
||||
import { websiteConfig } from '@/config/website';
|
||||
|
||||
export default function ProfilePage() {
|
||||
const enableUpdateAvatar = websiteConfig.features.enableUpdateAvatar;
|
||||
|
||||
return (
|
||||
<div className="flex flex-col gap-8">
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-8">
|
||||
<UpdateAvatarCard />
|
||||
</div>
|
||||
{enableUpdateAvatar && (
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-8">
|
||||
<UpdateAvatarCard />
|
||||
</div>
|
||||
)}
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-8">
|
||||
<UpdateNameCard />
|
||||
</div>
|
||||
|
@ -1,10 +1,10 @@
|
||||
'use client';
|
||||
|
||||
import { ActiveThemeProvider } from '@/components/layout/active-theme-provider';
|
||||
import { CreditsProvider } from '@/components/layout/credits-provider';
|
||||
import { PaymentProvider } from '@/components/layout/payment-provider';
|
||||
import { TooltipProvider } from '@/components/ui/tooltip';
|
||||
import { websiteConfig } from '@/config/website';
|
||||
import { CreditsProvider } from '@/providers/credits-provider';
|
||||
import type { Translations } from 'fumadocs-ui/i18n';
|
||||
import { RootProvider } from 'fumadocs-ui/provider';
|
||||
import { useTranslations } from 'next-intl';
|
||||
|
@ -23,6 +23,7 @@ import { createDeepSeek } from '@ai-sdk/deepseek';
|
||||
import { createGoogleGenerativeAI } from '@ai-sdk/google';
|
||||
import { createOpenAI } from '@ai-sdk/openai';
|
||||
import FirecrawlApp from '@mendable/firecrawl-js';
|
||||
import { createOpenRouter } from '@openrouter/ai-sdk-provider';
|
||||
import { generateObject } from 'ai';
|
||||
import { type NextRequest, NextResponse } from 'next/server';
|
||||
import { z } from 'zod';
|
||||
@ -218,7 +219,7 @@ async function analyzeContent(
|
||||
break;
|
||||
case 'gemini':
|
||||
model = createGoogleGenerativeAI({
|
||||
apiKey: process.env.GOOGLE_API_KEY,
|
||||
apiKey: process.env.GOOGLE_GENERATIVE_AI_API_KEY,
|
||||
}).chat(webContentAnalyzerConfig.gemini.model);
|
||||
temperature = webContentAnalyzerConfig.gemini.temperature;
|
||||
maxTokens = webContentAnalyzerConfig.gemini.maxTokens;
|
||||
@ -230,6 +231,13 @@ async function analyzeContent(
|
||||
temperature = webContentAnalyzerConfig.deepseek.temperature;
|
||||
maxTokens = webContentAnalyzerConfig.deepseek.maxTokens;
|
||||
break;
|
||||
case 'openrouter':
|
||||
model = createOpenRouter({
|
||||
apiKey: process.env.OPENROUTER_API_KEY,
|
||||
}).chat(webContentAnalyzerConfig.openrouter.model);
|
||||
temperature = webContentAnalyzerConfig.openrouter.temperature;
|
||||
maxTokens = webContentAnalyzerConfig.openrouter.maxTokens;
|
||||
break;
|
||||
default:
|
||||
throw new WebContentAnalyzerError(
|
||||
ErrorType.VALIDATION,
|
||||
@ -254,7 +262,7 @@ async function analyzeContent(
|
||||
- Ensure the title and description are meaningful and based on the actual content
|
||||
`,
|
||||
temperature,
|
||||
maxTokens,
|
||||
maxOutputTokens: maxTokens,
|
||||
});
|
||||
|
||||
return {
|
||||
@ -336,7 +344,7 @@ export async function POST(req: NextRequest) {
|
||||
if (!urlValidation.success) {
|
||||
const urlError = new WebContentAnalyzerError(
|
||||
ErrorType.VALIDATION,
|
||||
urlValidation.error.errors[0]?.message || 'Invalid URL',
|
||||
urlValidation.error.issues[0]?.message || 'Invalid URL',
|
||||
'Please enter a valid URL starting with http:// or https://',
|
||||
ErrorSeverity.MEDIUM,
|
||||
false
|
||||
|
@ -32,7 +32,7 @@ export const ForgotPasswordForm = ({ className }: { className?: string }) => {
|
||||
const searchParams = useSearchParams();
|
||||
|
||||
const ForgotPasswordSchema = z.object({
|
||||
email: z.string().email({
|
||||
email: z.email({
|
||||
message: t('emailRequired'),
|
||||
}),
|
||||
});
|
||||
|
@ -69,7 +69,7 @@ export const LoginForm = ({
|
||||
: z.string().optional();
|
||||
|
||||
const LoginSchema = z.object({
|
||||
email: z.string().email({
|
||||
email: z.email({
|
||||
message: t('emailRequired'),
|
||||
}),
|
||||
password: z.string().min(1, {
|
||||
|
@ -64,7 +64,7 @@ export const RegisterForm = ({
|
||||
: z.string().optional();
|
||||
|
||||
const RegisterSchema = z.object({
|
||||
email: z.string().email({
|
||||
email: z.email({
|
||||
message: t('emailRequired'),
|
||||
}),
|
||||
password: z.string().min(1, {
|
||||
|
@ -40,7 +40,7 @@ export function ContactFormCard() {
|
||||
// Create a schema for contact form validation
|
||||
const formSchema = z.object({
|
||||
name: z.string().min(3, t('nameMinLength')).max(30, t('nameMaxLength')),
|
||||
email: z.string().email(t('emailValidation')),
|
||||
email: z.email(t('emailValidation')),
|
||||
message: z
|
||||
.string()
|
||||
.min(10, t('messageMinLength'))
|
||||
|
@ -29,7 +29,7 @@ export function NewsletterForm() {
|
||||
|
||||
// newsletter schema
|
||||
const NewsletterFormSchema = z.object({
|
||||
email: z.string().email({
|
||||
email: z.email({
|
||||
message: t('emailValidation'),
|
||||
}),
|
||||
});
|
||||
|
@ -38,7 +38,7 @@ export function WaitlistFormCard() {
|
||||
|
||||
// Create a schema for waitlist form validation
|
||||
const formSchema = z.object({
|
||||
email: z.string().email({ message: t('emailValidation') }),
|
||||
email: z.email({ message: t('emailValidation') }),
|
||||
});
|
||||
|
||||
// Initialize the form
|
||||
|
@ -36,6 +36,7 @@ export const websiteConfig: WebsiteConfig = {
|
||||
enableDiscordWidget: false,
|
||||
enableCrispChat: process.env.NEXT_PUBLIC_DEMO_WEBSITE === 'true',
|
||||
enableUpgradeCard: true,
|
||||
enableUpdateAvatar: true,
|
||||
enableAffonsoAffiliate: false,
|
||||
enablePromotekitAffiliate: false,
|
||||
enableDatafastRevenueTrack: false,
|
||||
|
1
src/types/index.d.ts
vendored
1
src/types/index.d.ts
vendored
@ -71,6 +71,7 @@ export interface FeaturesConfig {
|
||||
enableDiscordWidget?: boolean; // Whether to enable the discord widget, deprecated
|
||||
enableCrispChat?: boolean; // Whether to enable the crisp chat
|
||||
enableUpgradeCard?: boolean; // Whether to enable the upgrade card in the sidebar
|
||||
enableUpdateAvatar?: boolean; // Whether to enable the update avatar in settings
|
||||
enableAffonsoAffiliate?: boolean; // Whether to enable affonso affiliate
|
||||
enablePromotekitAffiliate?: boolean; // Whether to enable promotekit affiliate
|
||||
enableDatafastRevenueTrack?: boolean; // Whether to enable datafast revenue tracking
|
||||
|
Loading…
Reference in New Issue
Block a user