Moshavereh sazmani
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
import { NextResponse } from 'next/server'
|
||||
|
||||
const TELEGRAM_API = 'https://api.telegram.org'
|
||||
|
||||
export interface ConsultingRequestBody {
|
||||
fullName: string
|
||||
organization: string
|
||||
phone: string
|
||||
area: string
|
||||
description?: string
|
||||
}
|
||||
|
||||
function escapeForTelegram(text: string): string {
|
||||
return text
|
||||
.replace(/&/g, '&')
|
||||
.replace(/</g, '<')
|
||||
.replace(/>/g, '>')
|
||||
}
|
||||
|
||||
export async function POST(request: Request) {
|
||||
const token = process.env.TELEGRAM_BOT_TOKEN
|
||||
const chatId = process.env.TELEGRAM_CHAT_ID
|
||||
|
||||
if (!token || !chatId) {
|
||||
return NextResponse.json(
|
||||
{ error: 'تلگرام پیکربندی نشده است. TELEGRAM_BOT_TOKEN و TELEGRAM_CHAT_ID را در .env.local تنظیم کنید.' },
|
||||
{ status: 500 }
|
||||
)
|
||||
}
|
||||
|
||||
let body: ConsultingRequestBody
|
||||
try {
|
||||
body = await request.json()
|
||||
} catch {
|
||||
return NextResponse.json({ error: 'بدنه درخواست نامعتبر است' }, { status: 400 })
|
||||
}
|
||||
|
||||
const { fullName, organization, phone, area, description } = body
|
||||
if (!fullName?.trim() || !organization?.trim() || !phone?.trim() || !area?.trim()) {
|
||||
return NextResponse.json({ error: 'فیلدهای الزامی خالی است' }, { status: 400 })
|
||||
}
|
||||
|
||||
const lines = [
|
||||
'📩 <b>درخواست جدید مشاوره سازمانی</b>',
|
||||
'',
|
||||
`<b>نام و نام خانوادگی:</b> ${escapeForTelegram(fullName.trim())}`,
|
||||
`<b>نام سازمان:</b> ${escapeForTelegram(organization.trim())}`,
|
||||
`<b>شماره تماس:</b> ${escapeForTelegram(phone.trim())}`,
|
||||
`<b>حوزه مشاوره:</b> ${escapeForTelegram(area.trim())}`,
|
||||
]
|
||||
if (description?.trim()) {
|
||||
lines.push('', `<b>توضیحات:</b>`, escapeForTelegram(description.trim()))
|
||||
}
|
||||
|
||||
const text = lines.join('\n')
|
||||
|
||||
try {
|
||||
const res = await fetch(`${TELEGRAM_API}/bot${token}/sendMessage`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
chat_id: chatId,
|
||||
text,
|
||||
parse_mode: 'HTML',
|
||||
}),
|
||||
})
|
||||
|
||||
const data = await res.json().catch(() => ({}))
|
||||
if (!res.ok) {
|
||||
return NextResponse.json(
|
||||
{ error: data.description || 'ارسال به تلگرام ناموفق بود' },
|
||||
{ status: 502 }
|
||||
)
|
||||
}
|
||||
return NextResponse.json({ ok: true })
|
||||
} catch (err) {
|
||||
return NextResponse.json(
|
||||
{ error: 'خطا در ارتباط با تلگرام' },
|
||||
{ status: 502 }
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,292 @@
|
||||
import { AspectRatio } from '@/components/ui/aspect-ratio'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { Card, CardContent } from '@/components/ui/card'
|
||||
import { Badge } from '@/components/ui/badge'
|
||||
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar'
|
||||
import {
|
||||
Accordion,
|
||||
AccordionContent,
|
||||
AccordionItem,
|
||||
AccordionTrigger,
|
||||
} from '@/components/ui/accordion'
|
||||
import { ConsultingForm } from '@/components/consulting-form'
|
||||
import {
|
||||
Plug2,
|
||||
Sparkles,
|
||||
Database,
|
||||
Gauge,
|
||||
Shield,
|
||||
Layout,
|
||||
BarChart3,
|
||||
HelpCircle,
|
||||
} from 'lucide-react'
|
||||
import Link from 'next/link'
|
||||
|
||||
const consultants = [
|
||||
{
|
||||
name: 'مشاور ارشد اینتگریشن',
|
||||
expertise: ['اینتگریشن سیستمها', 'API', 'اتوماسیون'],
|
||||
description:
|
||||
'بیش از ده سال تجربه در طراحی و پیادهسازی راهکارهای یکپارچهسازی برای سازمانهای بزرگ.',
|
||||
image: '/assets/logo.svg',
|
||||
fallback: 'م۱',
|
||||
},
|
||||
{
|
||||
name: 'مشاور هوشمندسازی و RAG',
|
||||
expertise: ['RAG', 'هوش مصنوعی', 'پردازش زبان طبیعی'],
|
||||
description:
|
||||
'تخصص در طراحی سامانههای مبتنی بر دانش و هوشمندسازی فرآیندهای سازمانی.',
|
||||
image: '/assets/logo.svg',
|
||||
fallback: 'م۲',
|
||||
},
|
||||
{
|
||||
name: 'مشاور عملکرد و معماری',
|
||||
expertise: ['Performance', 'معماری نرمافزار', 'مقیاسپذیری'],
|
||||
description:
|
||||
'بهینهسازی عملکرد سامانهها و طراحی معماری مقیاسپذیر و پایدار.',
|
||||
image: '/assets/logo.svg',
|
||||
fallback: 'م۳',
|
||||
},
|
||||
]
|
||||
|
||||
const domains = [
|
||||
{
|
||||
title: 'اینتگریشن',
|
||||
description: 'اتصال سیستمها، APIها و یکپارچهسازی دادهها و فرآیندها',
|
||||
icon: Plug2,
|
||||
},
|
||||
{
|
||||
title: 'هوشمندسازی',
|
||||
description: 'اتوماسیون و هوشمندسازی فرآیندهای کسبوکار',
|
||||
icon: Sparkles,
|
||||
},
|
||||
{
|
||||
title: 'RAG',
|
||||
description: 'سامانههای بازیابی و تولید پاسخ مبتنی بر دانش',
|
||||
icon: Database,
|
||||
},
|
||||
{
|
||||
title: 'Performance',
|
||||
description: 'بهینهسازی عملکرد، مقیاسپذیری و پاسخگویی',
|
||||
icon: Gauge,
|
||||
},
|
||||
{
|
||||
title: 'امنیت',
|
||||
description: 'امنیت داده، احراز هویت و کنترل دسترسی',
|
||||
icon: Shield,
|
||||
},
|
||||
{
|
||||
title: 'معماری نرمافزار',
|
||||
description: 'طراحی معماری، میکروسرویس و طراحی سیستم',
|
||||
icon: Layout,
|
||||
},
|
||||
{
|
||||
title: 'داده و تحلیل',
|
||||
description: 'تحلیل داده، گزارشگیری و دشبوردهای تحلیلی',
|
||||
icon: BarChart3,
|
||||
},
|
||||
]
|
||||
|
||||
const faqItems = [
|
||||
{
|
||||
id: 'faq-1',
|
||||
question: 'مشاوره سازمانی چیست؟',
|
||||
answer:
|
||||
'مشاوره سازمانی خدمتی است که در آن متخصصان با بررسی وضعیت فعلی سازمان، چالشها و اهداف شما، راهکارهای فنی و فرآیندی پیشنهاد میدهند. این مشاوره میتواند در حوزههای اینتگریشن، هوشمندسازی، RAG، بهینهسازی عملکرد و معماری نرمافزار باشد.',
|
||||
},
|
||||
{
|
||||
id: 'faq-2',
|
||||
question: 'چه زمانی میتوانم انتظار تماس داشته باشم؟',
|
||||
answer:
|
||||
'پس از ثبت درخواست، تیم ما در سریعترین زمان ممکن (معمولاً حداکثر ۲۴ تا ۴۸ ساعت کاری) با شما تماس میگیرد تا نیازتان را دقیقتر بررسی کنیم و زمان جلسه مشاوره را هماهنگ کنیم.',
|
||||
},
|
||||
{
|
||||
id: 'faq-3',
|
||||
question: 'آیا مشاوره اولیه رایگان است؟',
|
||||
answer:
|
||||
'جلسه اول شناخت و تعیین scope معمولاً به صورت رایگان یا با هزینه نمادین انجام میشود. جزئیات بسته به نوع درخواست و حجم کار در اولین تماس به شما اعلام میشود.',
|
||||
},
|
||||
{
|
||||
id: 'faq-4',
|
||||
question: 'برای چه اندازهای از سازمانها مناسب است؟',
|
||||
answer:
|
||||
'خدمات مشاوره ما برای استارتاپها، شرکتهای کوچک و متوسط و سازمانهای بزرگ طراحی شده است. محتوای جلسات و پیشنهادها متناسب با اندازه و نیاز هر سازمان تنظیم میشود.',
|
||||
},
|
||||
]
|
||||
|
||||
export const metadata = {
|
||||
title: 'مشاوره سازمانی | فیپ',
|
||||
description:
|
||||
'مشاوره تخصصی در حوزه اینتگریشن، هوشمندسازی، RAG، Performance و معماری نرمافزار. در سریعترین زمان با شما تماس میگیریم.',
|
||||
}
|
||||
|
||||
export default function ConsultingPage() {
|
||||
return (
|
||||
<>
|
||||
{/* Section 1: Hero - مشاوره سازمانی */}
|
||||
<section className="bg-background pt-28 pb-16 md:pt-36 md:pb-24">
|
||||
<div className="mx-auto max-w-6xl px-4 md:px-6">
|
||||
<div className="grid gap-12 lg:grid-cols-2 lg:gap-16 items-center">
|
||||
<div className="space-y-8 order-2 lg:order-1">
|
||||
<div className="space-y-4">
|
||||
<h1 className="text-4xl font-bold tracking-tight md:text-5xl lg:text-6xl">
|
||||
مشاوره سازمانی
|
||||
</h1>
|
||||
<p className="text-lg text-muted-foreground leading-relaxed max-w-xl">
|
||||
مشاوره سازمانی به معنای همراهی تخصصی با سازمان شما برای شناسایی چالشها،
|
||||
انتخاب راهکارهای فنی مناسب و برنامهریزی برای پیادهسازی است. ما در حوزههای
|
||||
اینتگریشن، هوشمندسازی، RAG و بهینهسازی عملکرد در کنار شما هستیم.
|
||||
</p>
|
||||
<p className="text-muted-foreground leading-relaxed max-w-xl">
|
||||
شرایط همکاری: پس از ثبت درخواست، تیم ما با شما تماس میگیرد؛ جلسه اول برای
|
||||
شناخت نیازها و تعیین دامنه کار است و در ادامه پیشنهاد و برنامه اجرا ارائه
|
||||
میشود.
|
||||
</p>
|
||||
</div>
|
||||
<div className="flex flex-wrap gap-3">
|
||||
<Button asChild size="lg">
|
||||
<Link href="#consulting-form">ثبت درخواست مشاوره</Link>
|
||||
</Button>
|
||||
<Button asChild variant="outline" size="lg">
|
||||
<Link href="#domains">حوزههای مشاوره</Link>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="relative order-1 lg:order-2">
|
||||
<div className="grid gap-4">
|
||||
<AspectRatio ratio={4 / 3} className="overflow-hidden rounded-2xl bg-muted">
|
||||
<div className="flex h-full w-full items-center justify-center bg-gradient-to-br from-primary/10 to-primary/5">
|
||||
<HelpCircle className="size-24 text-primary/40" />
|
||||
</div>
|
||||
</AspectRatio>
|
||||
<AspectRatio ratio={16 / 9} className="overflow-hidden rounded-2xl bg-muted -mt-8 mr-8 border shadow-lg">
|
||||
<div className="flex h-full w-full items-center justify-center bg-muted/80" />
|
||||
</AspectRatio>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Section 2: مشاوران */}
|
||||
<section className="bg-muted/30 py-16 md:py-24" id="consultants">
|
||||
<div className="mx-auto max-w-6xl px-4 md:px-6">
|
||||
<div className="mx-auto max-w-2xl text-center mb-12">
|
||||
<h2 className="text-3xl font-bold md:text-4xl">چه کسانی مشاوره میدهند؟</h2>
|
||||
<p className="mt-4 text-muted-foreground">
|
||||
تیم مشاوره ما متشکل از متخصصان با تجربه در حوزههای مختلف فناوری است.
|
||||
</p>
|
||||
</div>
|
||||
<div className="grid gap-8 md:grid-cols-3">
|
||||
{consultants.map((person) => (
|
||||
<Card key={person.fallback} className="overflow-hidden">
|
||||
<CardContent className="pt-6">
|
||||
<div className="flex flex-col items-center text-center space-y-4">
|
||||
<Avatar className="h-24 w-24">
|
||||
<AvatarImage src={person.image} alt={person.name} />
|
||||
<AvatarFallback className="text-xl">{person.fallback}</AvatarFallback>
|
||||
</Avatar>
|
||||
<div>
|
||||
<h3 className="font-bold text-lg">{person.name}</h3>
|
||||
<div className="flex flex-wrap justify-center gap-1.5 mt-2">
|
||||
{person.expertise.map((e) => (
|
||||
<Badge key={e} variant="secondary" className="text-xs">
|
||||
{e}
|
||||
</Badge>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<p className="text-sm text-muted-foreground leading-relaxed">
|
||||
{person.description}
|
||||
</p>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Section 3: حوزههای مشاوره */}
|
||||
<section className="bg-background py-16 md:py-24" id="domains">
|
||||
<div className="mx-auto max-w-6xl px-4 md:px-6">
|
||||
<div className="mx-auto max-w-2xl text-center mb-12">
|
||||
<h2 className="text-3xl font-bold md:text-4xl">در چه حوزههایی مشاوره میدهیم؟</h2>
|
||||
<p className="mt-4 text-muted-foreground">
|
||||
از اینتگریشن و هوشمندسازی تا RAG و بهینهسازی عملکرد
|
||||
</p>
|
||||
</div>
|
||||
<div className="grid gap-6 sm:grid-cols-2 lg:grid-cols-3">
|
||||
{domains.map((domain) => {
|
||||
const Icon = domain.icon
|
||||
return (
|
||||
<Card key={domain.title} className="overflow-hidden transition-all hover:shadow-md">
|
||||
<CardContent className="pt-6">
|
||||
<div className="flex gap-4">
|
||||
<div className="flex h-12 w-12 shrink-0 items-center justify-center rounded-lg bg-primary/10 text-primary">
|
||||
<Icon className="size-6" />
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-bold">{domain.title}</h3>
|
||||
<p className="text-sm text-muted-foreground mt-1 leading-relaxed">
|
||||
{domain.description}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Section 4: فرم درخواست مشاوره */}
|
||||
<section className="bg-muted/30 py-16 md:py-24" id="consulting-form">
|
||||
<div className="mx-auto max-w-6xl px-4 md:px-6">
|
||||
<div className="mx-auto max-w-xl">
|
||||
<div className="text-center mb-10">
|
||||
<h2 className="text-3xl font-bold md:text-4xl">درخواست مشاوره</h2>
|
||||
<p className="mt-4 text-muted-foreground">
|
||||
فرم زیر را پر کنید؛ در سریعترین زمان ممکن با شما تماس میگیریم.
|
||||
</p>
|
||||
</div>
|
||||
<Card className="p-6 md:p-8">
|
||||
<CardContent className="p-0">
|
||||
<ConsultingForm />
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Section 5: سوالات متداول */}
|
||||
<section className="bg-background py-16 md:py-24">
|
||||
<div className="mx-auto max-w-3xl px-4 md:px-6">
|
||||
<div className="mx-auto max-w-xl text-center mb-12">
|
||||
<h2 className="text-3xl font-bold md:text-4xl">سوالات متداول</h2>
|
||||
<p className="mt-4 text-muted-foreground">
|
||||
پاسخ سوالات رایج درباره مشاوره سازمانی
|
||||
</p>
|
||||
</div>
|
||||
<Accordion type="single" collapsible className="w-full rounded-2xl border bg-muted/30 p-1">
|
||||
{faqItems.map((item) => (
|
||||
<AccordionItem
|
||||
key={item.id}
|
||||
value={item.id}
|
||||
className="rounded-xl border-none px-4 data-[state=open]:bg-card data-[state=open]:shadow-sm"
|
||||
>
|
||||
<AccordionTrigger className="text-start hover:no-underline py-5">
|
||||
{item.question}
|
||||
</AccordionTrigger>
|
||||
<AccordionContent>
|
||||
<p className="text-muted-foreground leading-relaxed pb-2">{item.answer}</p>
|
||||
</AccordionContent>
|
||||
</AccordionItem>
|
||||
))}
|
||||
</Accordion>
|
||||
</div>
|
||||
</section>
|
||||
</>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
'use client'
|
||||
|
||||
import { useEffect } from 'react'
|
||||
import Link from 'next/link'
|
||||
import { Button } from '@/components/ui/button'
|
||||
|
||||
export default function Error({
|
||||
error,
|
||||
reset,
|
||||
}: {
|
||||
error: Error & { digest?: string }
|
||||
reset: () => void
|
||||
}) {
|
||||
useEffect(() => {
|
||||
console.error(error)
|
||||
}, [error])
|
||||
|
||||
return (
|
||||
<div className="flex min-h-[60vh] flex-col items-center justify-center gap-6 px-4 text-center">
|
||||
<h2 className="text-xl font-semibold text-foreground">خطایی رخ داد</h2>
|
||||
<p className="text-muted-foreground max-w-md text-sm">
|
||||
لطفاً دوباره تلاش کنید یا به صفحه اصلی برگردید.
|
||||
</p>
|
||||
<div className="flex flex-wrap gap-3 justify-center">
|
||||
<Button onClick={() => reset()}>تلاش مجدد</Button>
|
||||
<Button asChild variant="outline">
|
||||
<Link href="/">صفحه اصلی</Link>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
import './globals.css'
|
||||
|
||||
export const metadata = {
|
||||
title: '۴۰۴ | صفحه یافت نشد',
|
||||
description: 'صفحهای که دنبال آن هستید وجود ندارد.',
|
||||
}
|
||||
|
||||
export default function GlobalNotFound() {
|
||||
return (
|
||||
<html lang="fa" dir="rtl" suppressHydrationWarning>
|
||||
<body className="antialiased min-h-svh flex flex-col items-center justify-center gap-6 px-4 bg-background text-foreground">
|
||||
<h1 className="text-4xl font-bold">۴۰۴</h1>
|
||||
<p className="text-muted-foreground">این صفحه وجود ندارد.</p>
|
||||
<a
|
||||
href="/"
|
||||
className="rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground hover:opacity-90"
|
||||
>
|
||||
بازگشت به صفحه اصلی
|
||||
</a>
|
||||
</body>
|
||||
</html>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
import Link from 'next/link'
|
||||
import { Button } from '@/components/ui/button'
|
||||
|
||||
export default function NotFound() {
|
||||
return (
|
||||
<div className="flex min-h-[60vh] flex-col items-center justify-center gap-6 px-4 text-center">
|
||||
<h1 className="text-4xl font-bold text-foreground">۴۰۴</h1>
|
||||
<p className="text-muted-foreground max-w-md">
|
||||
صفحهای که دنبال آن هستید یافت نشد.
|
||||
</p>
|
||||
<div className="flex flex-wrap gap-3 justify-center">
|
||||
<Button asChild>
|
||||
<Link href="/">صفحه اصلی</Link>
|
||||
</Button>
|
||||
<Button asChild variant="outline">
|
||||
<Link href="/consulting">مشاوره سازمانی</Link>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
+2
-3
@@ -2,7 +2,6 @@ import ContentSection from "@/components/content-1";
|
||||
import Features from "@/components/features-12";
|
||||
import { FeaturedPostsGrid } from "@/components/featured-posts-grid";
|
||||
import { getPosts } from "@/lib/wp-api";
|
||||
import { HeroHeader } from "@/components/header";
|
||||
import HeroSection from "@/components/hero-section";
|
||||
|
||||
const FEATURED_CATEGORY_ID = 3;
|
||||
@@ -17,9 +16,9 @@ export default async function Home() {
|
||||
orderby: "date",
|
||||
order: "desc",
|
||||
});
|
||||
featuredPosts = result.posts;
|
||||
featuredPosts = result?.posts ?? [];
|
||||
} catch {
|
||||
// بدون پست هم صفحه رندر میشود
|
||||
featuredPosts = [];
|
||||
}
|
||||
|
||||
return (
|
||||
|
||||
@@ -0,0 +1,200 @@
|
||||
'use client'
|
||||
|
||||
import { useState } from 'react'
|
||||
import { useForm } from 'react-hook-form'
|
||||
import { zodResolver } from '@hookform/resolvers/zod'
|
||||
import { z } from 'zod'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { Input } from '@/components/ui/input'
|
||||
import { Textarea } from '@/components/ui/textarea'
|
||||
import {
|
||||
Form,
|
||||
FormControl,
|
||||
FormField,
|
||||
FormItem,
|
||||
FormLabel,
|
||||
FormMessage,
|
||||
} from '@/components/ui/form'
|
||||
import {
|
||||
Select,
|
||||
SelectContent,
|
||||
SelectItem,
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
} from '@/components/ui/select'
|
||||
import { Alert, AlertDescription } from '@/components/ui/alert'
|
||||
import { CheckCircle2, Loader2 } from 'lucide-react'
|
||||
|
||||
const consultingAreas = [
|
||||
'اینتگریشن',
|
||||
'هوشمندسازی',
|
||||
'RAG',
|
||||
'Performance',
|
||||
'امنیت',
|
||||
'معماری نرمافزار',
|
||||
'داده و تحلیل',
|
||||
'سایر',
|
||||
] as const
|
||||
|
||||
const formSchema = z.object({
|
||||
fullName: z.string().min(2, 'نام و نام خانوادگی الزامی است'),
|
||||
organization: z.string().min(1, 'نام سازمان الزامی است'),
|
||||
phone: z.string().min(10, 'شماره تماس معتبر وارد کنید'),
|
||||
area: z.string().min(1, 'حوزه مشاوره را انتخاب کنید'),
|
||||
description: z.string().optional(),
|
||||
})
|
||||
|
||||
type FormValues = z.infer<typeof formSchema>
|
||||
|
||||
export function ConsultingForm() {
|
||||
const [submitted, setSubmitted] = useState(false)
|
||||
const [isSubmitting, setIsSubmitting] = useState(false)
|
||||
const [submitError, setSubmitError] = useState<string | null>(null)
|
||||
|
||||
const form = useForm<FormValues>({
|
||||
resolver: zodResolver(formSchema),
|
||||
defaultValues: {
|
||||
fullName: '',
|
||||
organization: '',
|
||||
phone: '',
|
||||
area: '',
|
||||
description: '',
|
||||
},
|
||||
})
|
||||
|
||||
async function onSubmit(data: FormValues) {
|
||||
setSubmitError(null)
|
||||
setIsSubmitting(true)
|
||||
try {
|
||||
const res = await fetch('/api/consulting', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(data),
|
||||
})
|
||||
const json = await res.json().catch(() => ({}))
|
||||
if (!res.ok) {
|
||||
setSubmitError(json.error || 'ارسال درخواست ناموفق بود. لطفاً دوباره تلاش کنید.')
|
||||
return
|
||||
}
|
||||
setSubmitted(true)
|
||||
form.reset()
|
||||
} catch {
|
||||
setSubmitError('خطا در ارتباط با سرور. لطفاً دوباره تلاش کنید.')
|
||||
} finally {
|
||||
setIsSubmitting(false)
|
||||
}
|
||||
}
|
||||
|
||||
if (submitted) {
|
||||
return (
|
||||
<Alert className="border-primary/50 bg-primary/5 text-center">
|
||||
<CheckCircle2 className="h-5 w-5 text-primary" />
|
||||
<AlertDescription className="text-base font-medium">
|
||||
در سریعترین زمان ممکن با شما تماس میگیریم.
|
||||
</AlertDescription>
|
||||
</Alert>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<Form {...form}>
|
||||
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-6">
|
||||
{submitError && (
|
||||
<Alert variant="destructive">
|
||||
<AlertDescription>{submitError}</AlertDescription>
|
||||
</Alert>
|
||||
)}
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="fullName"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>نام و نام خانوادگی</FormLabel>
|
||||
<FormControl>
|
||||
<Input placeholder="نام و نام خانوادگی" {...field} className="h-11" />
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="organization"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>نام سازمان</FormLabel>
|
||||
<FormControl>
|
||||
<Input placeholder="نام سازمان یا شرکت" {...field} className="h-11" />
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="phone"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>شماره تماس</FormLabel>
|
||||
<FormControl>
|
||||
<Input type="tel" placeholder="۰۹۱۲۳۴۵۶۷۸۹" {...field} className="h-11" />
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="area"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>در چه حوزهای مشاوره میخواهید؟</FormLabel>
|
||||
<Select onValueChange={field.onChange} value={field.value}>
|
||||
<FormControl>
|
||||
<SelectTrigger className="h-11 w-full">
|
||||
<SelectValue placeholder="انتخاب حوزه" />
|
||||
</SelectTrigger>
|
||||
</FormControl>
|
||||
<SelectContent>
|
||||
{consultingAreas.map((area) => (
|
||||
<SelectItem key={area} value={area}>
|
||||
{area}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="description"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>توضیحات (اختیاری)</FormLabel>
|
||||
<FormControl>
|
||||
<Textarea
|
||||
placeholder="در صورت نیاز توضیح بیشتری بنویسید..."
|
||||
className="min-h-24"
|
||||
{...field}
|
||||
/>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
<Button type="submit" size="lg" className="w-full" disabled={isSubmitting}>
|
||||
{isSubmitting ? (
|
||||
<>
|
||||
<Loader2 className="size-5 animate-spin" aria-hidden />
|
||||
در حال ارسال...
|
||||
</>
|
||||
) : (
|
||||
'ثبت درخواست'
|
||||
)}
|
||||
</Button>
|
||||
</form>
|
||||
</Form>
|
||||
)
|
||||
}
|
||||
@@ -10,13 +10,16 @@ export default function ContentSection() {
|
||||
<div className="grid gap-6 sm:grid-cols-2 md:gap-12 lg:gap-24">
|
||||
<div className="relative mb-6 sm:mb-0">
|
||||
<div className="bg-linear-to-b aspect-76/59 relative rounded-2xl from-zinc-300 to-transparent p-px dark:from-zinc-700">
|
||||
<Image
|
||||
src="/assets/Echosystem.png"
|
||||
className="rounded-[15px] object-cover"
|
||||
alt="اکوسیستم یکپارچه فیپ"
|
||||
width={1207}
|
||||
height={929}
|
||||
/>
|
||||
<div className="relative aspect-[1207/929] w-full overflow-hidden rounded-[15px] bg-muted flex items-center justify-center">
|
||||
<Image
|
||||
src="/assets/Echosystem.png"
|
||||
className="rounded-[15px] object-cover"
|
||||
alt="اکوسیستم یکپارچه فیپ"
|
||||
width={1207}
|
||||
height={929}
|
||||
unoptimized
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ const menuItems = [
|
||||
{ name: 'صفحه اصلی', href: '/' },
|
||||
{ name: 'دانشنامه', href: '/blog' },
|
||||
{ name: 'راه حلها', href: '/solutions' },
|
||||
{ name: 'مشاوره سازمانی', href: '/consulting' },
|
||||
// { name: 'قیمتگذاری', href: '/pricing' },
|
||||
{ name: 'درباره ما', href: '/about' },
|
||||
]
|
||||
|
||||
@@ -2,6 +2,9 @@ import type { NextConfig } from "next";
|
||||
|
||||
const nextConfig: NextConfig = {
|
||||
output: 'standalone',
|
||||
experimental: {
|
||||
globalNotFound: true,
|
||||
},
|
||||
images: {
|
||||
remotePatterns: [
|
||||
{
|
||||
|
||||
Generated
+339
-40
@@ -36,15 +36,17 @@
|
||||
"@radix-ui/react-toggle": "^1.1.10",
|
||||
"@radix-ui/react-toggle-group": "^1.1.11",
|
||||
"@radix-ui/react-tooltip": "^1.2.8",
|
||||
"cheerio": "^1.0.0",
|
||||
"class-variance-authority": "^0.7.1",
|
||||
"clsx": "^2.1.1",
|
||||
"cmdk": "^1.1.1",
|
||||
"date-fns": "^4.1.0",
|
||||
"date-fns-jalali": "^4.1.0-0",
|
||||
"embla-carousel-react": "^8.6.0",
|
||||
"input-otp": "^1.4.2",
|
||||
"lucide-react": "^0.555.0",
|
||||
"motion": "^12.23.25",
|
||||
"next": "16.0.6",
|
||||
"next": "16.0.10",
|
||||
"next-themes": "^0.4.6",
|
||||
"react": "19.2.0",
|
||||
"react-day-picker": "^9.11.3",
|
||||
@@ -1167,9 +1169,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@next/env": {
|
||||
"version": "16.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@next/env/-/env-16.0.6.tgz",
|
||||
"integrity": "sha512-PFTK/G/vM3UJwK5XDYMFOqt8QW42mmhSgdKDapOlCqBUAOfJN2dyOnASR/xUR/JRrro0pLohh/zOJ77xUQWQAg==",
|
||||
"version": "16.0.10",
|
||||
"resolved": "https://registry.npmjs.org/@next/env/-/env-16.0.10.tgz",
|
||||
"integrity": "sha512-8tuaQkyDVgeONQ1MeT9Mkk8pQmZapMKFh5B+OrFUlG3rVmYTXcXlBetBgTurKXGaIZvkoqRT9JL5K3phXcgang==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@next/eslint-plugin-next": {
|
||||
@@ -1183,9 +1185,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@next/swc-darwin-arm64": {
|
||||
"version": "16.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-16.0.6.tgz",
|
||||
"integrity": "sha512-AGzKiPlDiui+9JcPRHLI4V9WFTTcKukhJTfK9qu3e0tz+Y/88B7vo5yZoO7UaikplJEHORzG3QaBFQfkjhnL0Q==",
|
||||
"version": "16.0.10",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-16.0.10.tgz",
|
||||
"integrity": "sha512-4XgdKtdVsaflErz+B5XeG0T5PeXKDdruDf3CRpnhN+8UebNa5N2H58+3GDgpn/9GBurrQ1uWW768FfscwYkJRg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -1199,9 +1201,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@next/swc-darwin-x64": {
|
||||
"version": "16.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-16.0.6.tgz",
|
||||
"integrity": "sha512-LlLLNrK9WCIUkq2GciWDcquXYIf7vLxX8XE49gz7EncssZGL1vlHwgmURiJsUZAvk0HM1a8qb1ABDezsjAE/jw==",
|
||||
"version": "16.0.10",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-16.0.10.tgz",
|
||||
"integrity": "sha512-spbEObMvRKkQ3CkYVOME+ocPDFo5UqHb8EMTS78/0mQ+O1nqE8toHJVioZo4TvebATxgA8XMTHHrScPrn68OGw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -1215,9 +1217,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@next/swc-linux-arm64-gnu": {
|
||||
"version": "16.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-16.0.6.tgz",
|
||||
"integrity": "sha512-r04NzmLSGGfG8EPXKVK72N5zDNnq9pa9el78LhdtqIC3zqKh74QfKHnk24DoK4PEs6eY7sIK/CnNpt30oc59kg==",
|
||||
"version": "16.0.10",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-16.0.10.tgz",
|
||||
"integrity": "sha512-uQtWE3X0iGB8apTIskOMi2w/MKONrPOUCi5yLO+v3O8Mb5c7K4Q5KD1jvTpTF5gJKa3VH/ijKjKUq9O9UhwOYw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -1231,9 +1233,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@next/swc-linux-arm64-musl": {
|
||||
"version": "16.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-16.0.6.tgz",
|
||||
"integrity": "sha512-hfB/QV0hA7lbD1OJxp52wVDlpffUMfyxUB5ysZbb/pBC5iuhyLcEKSVQo56PFUUmUQzbMsAtUu6k2Gh9bBtWXA==",
|
||||
"version": "16.0.10",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-16.0.10.tgz",
|
||||
"integrity": "sha512-llA+hiDTrYvyWI21Z0L1GiXwjQaanPVQQwru5peOgtooeJ8qx3tlqRV2P7uH2pKQaUfHxI/WVarvI5oYgGxaTw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -1247,9 +1249,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@next/swc-linux-x64-gnu": {
|
||||
"version": "16.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-16.0.6.tgz",
|
||||
"integrity": "sha512-PZJushBgfvKhJBy01yXMdgL+l5XKr7uSn5jhOQXQXiH3iPT2M9iG64yHpPNGIKitKrHJInwmhPVGogZBAJOCPw==",
|
||||
"version": "16.0.10",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-16.0.10.tgz",
|
||||
"integrity": "sha512-AK2q5H0+a9nsXbeZ3FZdMtbtu9jxW4R/NgzZ6+lrTm3d6Zb7jYrWcgjcpM1k8uuqlSy4xIyPR2YiuUr+wXsavA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -1263,9 +1265,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@next/swc-linux-x64-musl": {
|
||||
"version": "16.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-16.0.6.tgz",
|
||||
"integrity": "sha512-LqY76IojrH9yS5fyATjLzlOIOgwyzBuNRqXwVxcGfZ58DWNQSyfnLGlfF6shAEqjwlDNLh4Z+P0rnOI87Y9jEw==",
|
||||
"version": "16.0.10",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-16.0.10.tgz",
|
||||
"integrity": "sha512-1TDG9PDKivNw5550S111gsO4RGennLVl9cipPhtkXIFVwo31YZ73nEbLjNC8qG3SgTz/QZyYyaFYMeY4BKZR/g==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -1279,9 +1281,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@next/swc-win32-arm64-msvc": {
|
||||
"version": "16.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-16.0.6.tgz",
|
||||
"integrity": "sha512-eIfSNNqAkj0tqKRf0u7BVjqylJCuabSrxnpSENY3YKApqwDMeAqYPmnOwmVe6DDl3Lvkbe7cJAyP6i9hQ5PmmQ==",
|
||||
"version": "16.0.10",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-16.0.10.tgz",
|
||||
"integrity": "sha512-aEZIS4Hh32xdJQbHz121pyuVZniSNoqDVx1yIr2hy+ZwJGipeqnMZBJHyMxv2tiuAXGx6/xpTcQJ6btIiBjgmg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -1295,9 +1297,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@next/swc-win32-x64-msvc": {
|
||||
"version": "16.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-16.0.6.tgz",
|
||||
"integrity": "sha512-QGs18P4OKdK9y2F3Th42+KGnwsc2iaThOe6jxQgP62kslUU4W+g6AzI6bdIn/pslhSfxjAMU5SjakfT5Fyo/xA==",
|
||||
"version": "16.0.10",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-16.0.10.tgz",
|
||||
"integrity": "sha512-E+njfCoFLb01RAFEnGZn6ERoOqhK1Gl3Lfz1Kjnj0Ulfu7oJbuMyvBKNj/bw8XZnenHDASlygTjZICQW+rYW1Q==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -4239,6 +4241,12 @@
|
||||
"baseline-browser-mapping": "dist/cli.js"
|
||||
}
|
||||
},
|
||||
"node_modules/boolbase": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
|
||||
"integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/brace-expansion": {
|
||||
"version": "1.1.12",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
|
||||
@@ -4394,6 +4402,48 @@
|
||||
"url": "https://github.com/chalk/chalk?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/cheerio": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.2.0.tgz",
|
||||
"integrity": "sha512-WDrybc/gKFpTYQutKIK6UvfcuxijIZfMfXaYm8NMsPQxSYvf+13fXUJ4rztGGbJcBQ/GF55gvrZ0Bc0bj/mqvg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"cheerio-select": "^2.1.0",
|
||||
"dom-serializer": "^2.0.0",
|
||||
"domhandler": "^5.0.3",
|
||||
"domutils": "^3.2.2",
|
||||
"encoding-sniffer": "^0.2.1",
|
||||
"htmlparser2": "^10.1.0",
|
||||
"parse5": "^7.3.0",
|
||||
"parse5-htmlparser2-tree-adapter": "^7.1.0",
|
||||
"parse5-parser-stream": "^7.1.2",
|
||||
"undici": "^7.19.0",
|
||||
"whatwg-mimetype": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20.18.1"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/cheeriojs/cheerio?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/cheerio-select": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz",
|
||||
"integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==",
|
||||
"license": "BSD-2-Clause",
|
||||
"dependencies": {
|
||||
"boolbase": "^1.0.0",
|
||||
"css-select": "^5.1.0",
|
||||
"css-what": "^6.1.0",
|
||||
"domelementtype": "^2.3.0",
|
||||
"domhandler": "^5.0.3",
|
||||
"domutils": "^3.0.1"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/fb55"
|
||||
}
|
||||
},
|
||||
"node_modules/class-variance-authority": {
|
||||
"version": "0.7.1",
|
||||
"resolved": "https://registry.npmjs.org/class-variance-authority/-/class-variance-authority-0.7.1.tgz",
|
||||
@@ -4486,6 +4536,34 @@
|
||||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/css-select": {
|
||||
"version": "5.2.2",
|
||||
"resolved": "https://registry.npmjs.org/css-select/-/css-select-5.2.2.tgz",
|
||||
"integrity": "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==",
|
||||
"license": "BSD-2-Clause",
|
||||
"dependencies": {
|
||||
"boolbase": "^1.0.0",
|
||||
"css-what": "^6.1.0",
|
||||
"domhandler": "^5.0.2",
|
||||
"domutils": "^3.0.1",
|
||||
"nth-check": "^2.0.1"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/fb55"
|
||||
}
|
||||
},
|
||||
"node_modules/css-what": {
|
||||
"version": "6.2.2",
|
||||
"resolved": "https://registry.npmjs.org/css-what/-/css-what-6.2.2.tgz",
|
||||
"integrity": "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==",
|
||||
"license": "BSD-2-Clause",
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/fb55"
|
||||
}
|
||||
},
|
||||
"node_modules/csstype": {
|
||||
"version": "3.2.3",
|
||||
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz",
|
||||
@@ -4796,6 +4874,61 @@
|
||||
"csstype": "^3.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/dom-serializer": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
|
||||
"integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"domelementtype": "^2.3.0",
|
||||
"domhandler": "^5.0.2",
|
||||
"entities": "^4.2.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/domelementtype": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
|
||||
"integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/fb55"
|
||||
}
|
||||
],
|
||||
"license": "BSD-2-Clause"
|
||||
},
|
||||
"node_modules/domhandler": {
|
||||
"version": "5.0.3",
|
||||
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
|
||||
"integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
|
||||
"license": "BSD-2-Clause",
|
||||
"dependencies": {
|
||||
"domelementtype": "^2.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/fb55/domhandler?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/domutils": {
|
||||
"version": "3.2.2",
|
||||
"resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz",
|
||||
"integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==",
|
||||
"license": "BSD-2-Clause",
|
||||
"dependencies": {
|
||||
"dom-serializer": "^2.0.0",
|
||||
"domelementtype": "^2.3.0",
|
||||
"domhandler": "^5.0.3"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/fb55/domutils?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/dunder-proto": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
|
||||
@@ -4853,6 +4986,19 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/encoding-sniffer": {
|
||||
"version": "0.2.1",
|
||||
"resolved": "https://registry.npmjs.org/encoding-sniffer/-/encoding-sniffer-0.2.1.tgz",
|
||||
"integrity": "sha512-5gvq20T6vfpekVtqrYQsSCFZ1wEg5+wW0/QaZMWkFr6BqD3NfKs0rLCx4rrVlSWJeZb5NBJgVLswK/w2MWU+Gw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"iconv-lite": "^0.6.3",
|
||||
"whatwg-encoding": "^3.1.1"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/fb55/encoding-sniffer?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/enhanced-resolve": {
|
||||
"version": "5.18.3",
|
||||
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.3.tgz",
|
||||
@@ -4867,6 +5013,18 @@
|
||||
"node": ">=10.13.0"
|
||||
}
|
||||
},
|
||||
"node_modules/entities": {
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
|
||||
"integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
|
||||
"license": "BSD-2-Clause",
|
||||
"engines": {
|
||||
"node": ">=0.12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/fb55/entities?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/es-abstract": {
|
||||
"version": "1.24.0",
|
||||
"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.0.tgz",
|
||||
@@ -5995,6 +6153,49 @@
|
||||
"hermes-estree": "0.25.1"
|
||||
}
|
||||
},
|
||||
"node_modules/htmlparser2": {
|
||||
"version": "10.1.0",
|
||||
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-10.1.0.tgz",
|
||||
"integrity": "sha512-VTZkM9GWRAtEpveh7MSF6SjjrpNVNNVJfFup7xTY3UpFtm67foy9HDVXneLtFVt4pMz5kZtgNcvCniNFb1hlEQ==",
|
||||
"funding": [
|
||||
"https://github.com/fb55/htmlparser2?sponsor=1",
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/fb55"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"domelementtype": "^2.3.0",
|
||||
"domhandler": "^5.0.3",
|
||||
"domutils": "^3.2.2",
|
||||
"entities": "^7.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/htmlparser2/node_modules/entities": {
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/entities/-/entities-7.0.1.tgz",
|
||||
"integrity": "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==",
|
||||
"license": "BSD-2-Clause",
|
||||
"engines": {
|
||||
"node": ">=0.12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/fb55/entities?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/iconv-lite": {
|
||||
"version": "0.6.3",
|
||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
|
||||
"integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"safer-buffer": ">= 2.1.2 < 3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ignore": {
|
||||
"version": "5.3.2",
|
||||
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
|
||||
@@ -7127,12 +7328,12 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/next": {
|
||||
"version": "16.0.6",
|
||||
"resolved": "https://registry.npmjs.org/next/-/next-16.0.6.tgz",
|
||||
"integrity": "sha512-2zOZ/4FdaAp5hfCU/RnzARlZzBsjaTZ/XjNQmuyYLluAPM7kcrbIkdeO2SL0Ysd1vnrSgU+GwugfeWX1cUCgCg==",
|
||||
"version": "16.0.10",
|
||||
"resolved": "https://registry.npmjs.org/next/-/next-16.0.10.tgz",
|
||||
"integrity": "sha512-RtWh5PUgI+vxlV3HdR+IfWA1UUHu0+Ram/JBO4vWB54cVPentCD0e+lxyAYEsDTqGGMg7qpjhKh6dc6aW7W/sA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@next/env": "16.0.6",
|
||||
"@next/env": "16.0.10",
|
||||
"@swc/helpers": "0.5.15",
|
||||
"caniuse-lite": "^1.0.30001579",
|
||||
"postcss": "8.4.31",
|
||||
@@ -7145,14 +7346,14 @@
|
||||
"node": ">=20.9.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@next/swc-darwin-arm64": "16.0.6",
|
||||
"@next/swc-darwin-x64": "16.0.6",
|
||||
"@next/swc-linux-arm64-gnu": "16.0.6",
|
||||
"@next/swc-linux-arm64-musl": "16.0.6",
|
||||
"@next/swc-linux-x64-gnu": "16.0.6",
|
||||
"@next/swc-linux-x64-musl": "16.0.6",
|
||||
"@next/swc-win32-arm64-msvc": "16.0.6",
|
||||
"@next/swc-win32-x64-msvc": "16.0.6",
|
||||
"@next/swc-darwin-arm64": "16.0.10",
|
||||
"@next/swc-darwin-x64": "16.0.10",
|
||||
"@next/swc-linux-arm64-gnu": "16.0.10",
|
||||
"@next/swc-linux-arm64-musl": "16.0.10",
|
||||
"@next/swc-linux-x64-gnu": "16.0.10",
|
||||
"@next/swc-linux-x64-musl": "16.0.10",
|
||||
"@next/swc-win32-arm64-msvc": "16.0.10",
|
||||
"@next/swc-win32-x64-msvc": "16.0.10",
|
||||
"sharp": "^0.34.4"
|
||||
},
|
||||
"peerDependencies": {
|
||||
@@ -7223,6 +7424,18 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/nth-check": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
|
||||
"integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==",
|
||||
"license": "BSD-2-Clause",
|
||||
"dependencies": {
|
||||
"boolbase": "^1.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/fb55/nth-check?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/object-assign": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
||||
@@ -7426,6 +7639,55 @@
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/parse5": {
|
||||
"version": "7.3.0",
|
||||
"resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz",
|
||||
"integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"entities": "^6.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/inikulin/parse5?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/parse5-htmlparser2-tree-adapter": {
|
||||
"version": "7.1.0",
|
||||
"resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.1.0.tgz",
|
||||
"integrity": "sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"domhandler": "^5.0.3",
|
||||
"parse5": "^7.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/inikulin/parse5?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/parse5-parser-stream": {
|
||||
"version": "7.1.2",
|
||||
"resolved": "https://registry.npmjs.org/parse5-parser-stream/-/parse5-parser-stream-7.1.2.tgz",
|
||||
"integrity": "sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"parse5": "^7.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/inikulin/parse5?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/parse5/node_modules/entities": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz",
|
||||
"integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==",
|
||||
"license": "BSD-2-Clause",
|
||||
"engines": {
|
||||
"node": ">=0.12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/fb55/entities?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/path-exists": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
|
||||
@@ -7950,6 +8212,12 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/safer-buffer": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
|
||||
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/scheduler": {
|
||||
"version": "0.27.0",
|
||||
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz",
|
||||
@@ -8698,6 +8966,15 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/undici": {
|
||||
"version": "7.22.0",
|
||||
"resolved": "https://registry.npmjs.org/undici/-/undici-7.22.0.tgz",
|
||||
"integrity": "sha512-RqslV2Us5BrllB+JeiZnK4peryVTndy9Dnqq62S3yYRRTj0tFQCwEniUy2167skdGOy3vqRzEvl1Dm4sV2ReDg==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=20.18.1"
|
||||
}
|
||||
},
|
||||
"node_modules/undici-types": {
|
||||
"version": "6.21.0",
|
||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
|
||||
@@ -8868,6 +9145,28 @@
|
||||
"d3-timer": "^3.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/whatwg-encoding": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz",
|
||||
"integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==",
|
||||
"deprecated": "Use @exodus/bytes instead for a more spec-conformant and faster implementation",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"iconv-lite": "0.6.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/whatwg-mimetype": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz",
|
||||
"integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/which": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
|
||||
|
||||
Reference in New Issue
Block a user