This commit is contained in:
hamid zarghami
2025-04-16 10:53:27 +03:30
parent 6ce2dca701
commit 3fe334d3ad
15 changed files with 770 additions and 157 deletions
+112
View File
@@ -0,0 +1,112 @@
export default function Loading() {
return (
<div className="mt-24 max-w-maxWidth mx-auto px-4 sm:px-0">
{/* Blog Title Skeleton */}
<div className="h-8 w-3/4 bg-gray-200 rounded-md animate-pulse"></div>
<div className="mt-10 flex flex-col xl:flex-row gap-8">
{/* Main Content Column */}
<div className="flex-1 bg-white rounded-4xl p-5 sm:p-10">
{/* Meta Info Row */}
<div className="flex flex-wrap gap-2 sm:gap-4">
{/* Category */}
<div className="flex gap-1 items-center">
<div className="size-5 bg-gray-200 rounded-full animate-pulse"></div>
<div className="h-5 w-20 bg-gray-200 rounded-md animate-pulse"></div>
</div>
{/* Author */}
<div className="flex gap-1 items-center">
<div className="size-5 bg-gray-200 rounded-full animate-pulse"></div>
<div className="h-5 w-32 bg-gray-200 rounded-md animate-pulse"></div>
</div>
{/* Date */}
<div className="flex gap-1 items-center">
<div className="size-5 bg-gray-200 rounded-full animate-pulse"></div>
<div className="h-5 w-24 bg-gray-200 rounded-md animate-pulse"></div>
</div>
</div>
{/* Featured Image */}
<div className="mt-6">
<div className="w-full h-[200px] sm:h-[250px] md:h-[300px] lg:h-[400px] bg-gray-200 rounded-4xl animate-pulse"></div>
</div>
{/* Content Paragraphs */}
<div className="mt-8 space-y-4">
<div className="h-4 w-full bg-gray-200 rounded-md animate-pulse"></div>
<div className="h-4 w-full bg-gray-200 rounded-md animate-pulse"></div>
<div className="h-4 w-full bg-gray-200 rounded-md animate-pulse"></div>
<div className="h-4 w-5/6 bg-gray-200 rounded-md animate-pulse"></div>
<div className="h-4 w-full bg-gray-200 rounded-md animate-pulse"></div>
<div className="h-4 w-full bg-gray-200 rounded-md animate-pulse"></div>
<div className="h-4 w-4/5 bg-gray-200 rounded-md animate-pulse"></div>
<div className="h-4 w-full bg-gray-200 rounded-md animate-pulse"></div>
<div className="h-4 w-full bg-gray-200 rounded-md animate-pulse"></div>
<div className="h-4 w-3/4 bg-gray-200 rounded-md animate-pulse"></div>
</div>
{/* Share Section */}
<div className="mt-6 flex items-center gap-4 border-y border-gray-200 py-4">
<div className="h-5 w-24 bg-gray-200 rounded-md animate-pulse"></div>
<div className="size-5 bg-gray-200 rounded-md animate-pulse"></div>
<div className="size-5 bg-gray-200 rounded-md animate-pulse"></div>
<div className="size-5 bg-gray-200 rounded-md animate-pulse"></div>
</div>
</div>
{/* Sidebar Column */}
<div className="w-full xl:w-[261px] mt-6 xl:mt-0">
{/* Most Visited */}
<div className="w-full rounded-4xl bg-white p-4 animate-pulse">
<div className="h-6 w-32 bg-gray-200 rounded-md"></div>
<div className="flex flex-col gap-6 mt-7">
{[1, 2, 3, 4].map((i) => (
<div key={i} className="flex gap-3">
<div className="size-16 bg-gray-200 rounded-lg"></div>
<div className="flex-1">
<div className="h-4 w-full bg-gray-200 rounded-md"></div>
<div className="h-3 w-16 bg-gray-200 rounded-md mt-2"></div>
</div>
</div>
))}
</div>
</div>
{/* Contact Us */}
<div className="w-full rounded-4xl bg-white p-4 mt-6 animate-pulse">
<div className="h-6 w-24 bg-gray-200 rounded-md"></div>
<div className="flex flex-wrap sm:flex-nowrap gap-4 mt-6">
<div className="flex-1 min-w-[45%] bg-gray-200 rounded-xl p-4">
<div className="size-6 bg-gray-300 rounded-md"></div>
<div className="mt-1.5">
<div className="h-4 w-20 bg-gray-300 rounded-md"></div>
<div className="h-3 w-16 bg-gray-300 rounded-md mt-1"></div>
</div>
</div>
<div className="flex-1 min-w-[45%] bg-gray-200 rounded-xl p-4">
<div className="size-6 bg-gray-300 rounded-md"></div>
<div className="mt-1.5">
<div className="h-4 w-20 bg-gray-300 rounded-md"></div>
<div className="h-3 w-16 bg-gray-300 rounded-md mt-1"></div>
</div>
</div>
</div>
<div className="bg-gray-200 rounded-xl p-4 mt-4">
<div className="size-6 bg-gray-300 rounded-md"></div>
<div className="mt-1.5">
<div className="h-4 w-32 bg-gray-300 rounded-md"></div>
<div className="h-3 w-24 bg-gray-300 rounded-md mt-1"></div>
</div>
</div>
</div>
</div>
</div>
</div>
)
}
+11
View File
@@ -1,7 +1,9 @@
import { Suspense } from 'react'
import { dehydrate, HydrationBoundary, QueryClient } from '@tanstack/react-query'
import { blogSingleQueryOptions } from '../hooks/useBlogsData'
import { NextPage } from 'next'
import SingleBlogPage from '../components/SingleBlogPage'
import Loading from './loading'
interface PageProps {
params: Promise<{
@@ -12,8 +14,17 @@ interface PageProps {
const SingleBlog: NextPage<PageProps> = async ({ params }) => {
const { id } = await params
return (
<Suspense fallback={<Loading />}>
<BlogContent id={id} />
</Suspense>
)
}
async function BlogContent({ id }: { id: string }) {
const queryClient = new QueryClient()
await queryClient.prefetchQuery(blogSingleQueryOptions(id))
return (
<HydrationBoundary state={dehydrate(queryClient)}>
<SingleBlogPage id={id} />
+3 -2
View File
@@ -39,8 +39,9 @@ const BigBlogItem: FC<BigBlogItemProps> = ({ item }) => {
</div>
</div>
<p dangerouslySetInnerHTML={{ __html: item.previewContent }} className='mt-3 text-sm leading-5'>
</p>
<div className='mt-3 text-sm leading-5'>
{item.previewContent.replace(/<\/?[^>]+(>|$)/g, "")}
</div>
<Link href={`/blogs/${item.id}`}>
<div className='mt-3 flex gap-1 text-sm text-[#8C90A3]'>
+4 -3
View File
@@ -19,7 +19,7 @@ const HeroSection: FC = () => {
alt={item.title}
width={1920}
height={1080}
className='w-full rounded-4xl object-cover xl:mt-14 mt-8 xl:min-h-[210px] min-h-[350px]'
className='w-full rounded-4xl object-cover xl:mt-14 mt-8 xl:min-h-[210px] min-h-[350px] max-h-[450px]'
/>
<div className='absolute bottom-0 h-[140px] modalGlass3 w-full p-6 text-white'>
@@ -27,8 +27,9 @@ const HeroSection: FC = () => {
{item.title}
</h4>
<p dangerouslySetInnerHTML={{ __html: item.previewContent }} className="text-xs xl:text-sm mt-4 leading-7 truncate xl:text-clip xl:whitespace-normal">
</p>
<div className="text-xs xl:text-sm mt-4 leading-7 truncate xl:text-clip xl:whitespace-normal">
{item.previewContent.replace(/<\/?[^>]+(>|$)/g, "")}
</div>
</div>
</div>
)
+5 -4
View File
@@ -13,16 +13,17 @@ type Props = {
}
const SingleBlogPage: FC<Props> = ({ id }) => {
const { data } = useGetBlogSingle(id)
if (!data) return <div></div>
if (!data) return null
return (
<div className='mt-24 max-w-maxWidth mx-auto'>
<h1 className='text-2xl font-bold'>
{data?.data?.blog?.title}
</h1>
<div className='mt-10 flex gap-8'>
<div className='mt-10 flex xl:flex-row flex-col gap-8'>
<div className='flex-1 bg-white rounded-4xl p-10'>
<div className='flex gap-4'>
<div className='flex gap-1'>
@@ -85,7 +86,7 @@ const SingleBlogPage: FC<Props> = ({ id }) => {
</div>
</div>
<div className='w-[261px]'>
<div className='xl:w-[261px]'>
<MostVisited />
<div className='mt-6'>
<ContactUs />
+160
View File
@@ -0,0 +1,160 @@
export default function Loading() {
return (
<div>
{/* Hero Section Skeleton */}
<div className="relative rounded-4xl overflow-hidden">
<div className="w-full rounded-4xl object-cover xl:mt-14 mt-8 xl:min-h-[340px] min-h-[200px] bg-gray-200 animate-pulse"></div>
<div className="absolute bottom-0 h-[140px] w-full p-6">
<div className="h-6 w-3/4 bg-gray-300 rounded-md animate-pulse"></div>
<div className="h-4 w-5/6 bg-gray-300 rounded-md animate-pulse mt-4"></div>
</div>
</div>
{/* Secondary Hero Items */}
<div className="flex xl:flex-row flex-col gap-8 mt-10">
{[1, 2, 3].map((i) => (
<div key={`hero-item-${i}`} className="flex-1 bg-white rounded-4xl p-4 overflow-hidden animate-pulse">
<div className="h-40 w-full bg-gray-200 rounded-4xl"></div>
<div className="p-4">
<div className="h-5 w-4/5 bg-gray-200 rounded-md"></div>
<div className="mt-3 flex gap-2">
<div className="h-4 w-24 bg-gray-200 rounded-md"></div>
<div className="h-4 w-16 bg-gray-200 rounded-md"></div>
</div>
<div className="mt-3 flex justify-between items-center">
<div className="h-4 w-32 bg-gray-200 rounded-md"></div>
<div className="h-6 w-6 bg-gray-200 rounded-md"></div>
</div>
</div>
</div>
))}
</div>
{/* Blog Title */}
<h1 className="text-2xl font-bold mt-10">
<div className="h-8 w-48 bg-gray-200 rounded-md animate-pulse"></div>
</h1>
{/* Main Content Area */}
<div className="mt-10 flex xl:flex-row flex-col gap-8">
{/* Left Sidebar - Categories */}
<div className="xl:w-[261px] w-full">
<div className="w-full rounded-4xl bg-white p-4 animate-pulse">
<div className="h-6 w-36 bg-gray-200 rounded-md"></div>
<div className="flex flex-col gap-4 mt-7">
{[1, 2, 3, 4, 5, 6].map((i) => (
<div key={`cat-${i}`} className="h-10 bg-gray-200 rounded-xl p-2.5 flex items-center gap-2">
<div className="size-5 bg-gray-300 rounded-full"></div>
<div className="h-4 w-24 bg-gray-300 rounded-md"></div>
</div>
))}
</div>
</div>
</div>
{/* Center Content - Blog List */}
<div className="flex-1 flex flex-col gap-8">
{[1, 2, 3, 4].map((i) => (
<div key={`blog-${i}`} className="w-full rounded-4xl bg-white p-7 flex xl:flex-row flex-col gap-6 animate-pulse">
<div className="size-[150px] bg-gray-200 rounded-4xl mx-auto xl:mx-0"></div>
<div className="flex-1">
<div className="h-5 w-3/4 bg-gray-200 rounded-md"></div>
<div className="mt-3 flex gap-3">
<div className="flex items-center gap-1">
<div className="size-[18px] bg-gray-200 rounded-full"></div>
<div className="h-4 w-20 bg-gray-200 rounded-md"></div>
</div>
<div className="flex items-center gap-1">
<div className="size-[18px] bg-gray-200 rounded-full"></div>
<div className="h-4 w-24 bg-gray-200 rounded-md"></div>
</div>
</div>
<div className="mt-3 space-y-2">
<div className="h-4 w-full bg-gray-200 rounded-md"></div>
<div className="h-4 w-full bg-gray-200 rounded-md"></div>
<div className="h-4 w-3/4 bg-gray-200 rounded-md"></div>
</div>
<div className="mt-3 flex gap-1 items-center">
<div className="h-4 w-24 bg-gray-200 rounded-md"></div>
<div className="size-[18px] bg-gray-200 rounded-md"></div>
</div>
</div>
</div>
))}
</div>
{/* Right Sidebar */}
<div className="xl:w-[261px] w-full">
{/* Most Visited Widget */}
<div className="w-full rounded-4xl bg-white p-4 animate-pulse">
<div className="h-6 w-36 bg-gray-200 rounded-md"></div>
<div className="flex flex-col gap-6 mt-7">
{[1, 2, 3, 4].map((i) => (
<div key={`most-visited-${i}`} className="flex gap-3">
<div className="size-16 bg-gray-200 rounded-lg"></div>
<div className="flex-1">
<div className="h-4 w-full bg-gray-200 rounded-md"></div>
<div className="h-3 w-16 bg-gray-200 rounded-md mt-2"></div>
</div>
</div>
))}
</div>
</div>
{/* Contact Us Widget */}
<div className="w-full rounded-4xl bg-white p-4 mt-6 animate-pulse">
<div className="h-6 w-28 bg-gray-200 rounded-md"></div>
<div className="flex gap-4 mt-6">
<div className="flex-1 bg-gray-200 rounded-xl p-4">
<div className="size-6 bg-gray-300 rounded-md"></div>
<div className="mt-1.5">
<div className="h-4 w-20 bg-gray-300 rounded-md"></div>
<div className="h-3 w-16 bg-gray-300 rounded-md mt-1"></div>
</div>
</div>
<div className="flex-1 bg-gray-200 rounded-xl p-4">
<div className="size-6 bg-gray-300 rounded-md"></div>
<div className="mt-1.5">
<div className="h-4 w-20 bg-gray-300 rounded-md"></div>
<div className="h-3 w-16 bg-gray-300 rounded-md mt-1"></div>
</div>
</div>
</div>
<div className="bg-gray-200 rounded-xl p-4 mt-4">
<div className="size-6 bg-gray-300 rounded-md"></div>
<div className="mt-1.5">
<div className="h-4 w-32 bg-gray-300 rounded-md"></div>
<div className="h-3 w-24 bg-gray-300 rounded-md mt-1"></div>
</div>
</div>
</div>
{/* Second Most Visited Widget */}
<div className="w-full rounded-4xl bg-white p-4 mt-6 animate-pulse">
<div className="h-6 w-36 bg-gray-200 rounded-md"></div>
<div className="flex flex-col gap-6 mt-7">
{[1, 2, 3, 4].map((i) => (
<div key={`most-visited-2-${i}`} className="flex gap-3">
<div className="size-16 bg-gray-200 rounded-lg"></div>
<div className="flex-1">
<div className="h-4 w-full bg-gray-200 rounded-md"></div>
<div className="h-3 w-16 bg-gray-200 rounded-md mt-2"></div>
</div>
</div>
))}
</div>
</div>
</div>
</div>
</div>
)
}
+10 -1
View File
@@ -1,6 +1,8 @@
import { HydrationBoundary, dehydrate } from '@tanstack/react-query'
import { QueryClient } from '@tanstack/react-query'
import { Suspense } from 'react'
import BlogList from './components/BlogList'
import Loading from './loading'
import { blogCategoriesQueryOptions, blogsQueryOptions, blogCombinedQueryOptions, mostVisitedBlogsQueryOptions } from './hooks/useBlogsData'
export const metadata = {
@@ -8,8 +10,15 @@ export const metadata = {
description: 'مقالات جذاب، نکات آموزشی و اخبار دنیای نرم‌افزار در مجله داناک',
}
export default async function BlogsPage() {
export default function BlogsPage() {
return (
<Suspense fallback={<Loading />}>
<BlogsContent />
</Suspense>
)
}
async function BlogsContent() {
const queryClient = new QueryClient()
await queryClient.prefetchQuery(blogsQueryOptions)
await queryClient.prefetchQuery(blogCategoriesQueryOptions)
@@ -0,0 +1,150 @@
'use client'
import { Headphone, Profile2User, ShieldTick, TrendUp } from 'iconsax-react'
import { FC } from 'react'
import Image from 'next/image'
const DanakServicesContent: FC = () => {
return (
<div className='mt-24'>
<div className='flex gap-y-4 flex-col xl:flex-row xl:items-center justify-between max-w-maxWidth mx-auto'>
<h1 className='text-2xl font-bold'>
خدمات داناک
</h1>
<div className='max-w-[300px] text-sm leading-6'>
ما در داناک با ترکیب خلاقیت، تخصص و تکنولوژیهای روز، راهکارهای نرمافزاری منحصربهفردی ارائه میدهیم که کسبوکار شما را به سطحی بالاتر میبرد.
</div>
</div>
<div className='mt-20 flex flex-col-reverse xl:flex-row gap-x-32 gap-y-12 max-w-maxWidth mx-auto'>
<div className='flex-1'>
<div className='flex gap-4 items-center'>
<div className="size-12 flex items-center justify-center bg-gradient-to-b from-[#f9fafc] to-[#f1f3f8] rounded-2xl shadow-[inset_4px_4px_6px_#e2e5ec,inset_-4px_-4px_6px_#ffffff] ">
<Profile2User
size={24}
color='black'
/>
</div>
<h6 className='font-bold'>
مشاوره
</h6>
</div>
<p className='mt-4 leading-6 text-sm'>
در دنیای امروز، نیاز به راهکارهای نرمافزاری که هم از لحاظ عملکردی بهینه و سریع باشند و هم با پیچیدگیهای فنی و نیازهای خاص کسبوکارها همخوانی داشته باشند، بیشتر از همیشه احساس میشود. تیم مشاوره داناک با ارائه راهکارهای نرمافزاری مدرن، به شما کمک میکند تا از ابزارها و فناوریهای روز دنیا استفاده کرده و فرایندهای کسبوکار خود را به شکلی بهینهسازی کنید. هدف ما این است که راهحلهایی با بالاترین کارایی و کمترین زمان اجرا ارائه دهیم تا شما بتوانید با کمترین هزینه و زمان ممکن، بهترین نتیجه را در پروژههای خود به دست آورید. چه در زمینه توسعه نرمافزارهای خاص، چه در یکپارچهسازی سیستمها، مشاوران ما به شما در انتخاب و پیادهسازی بهترین گزینهها کمک میکنند.
</p>
</div>
<div className='flex-1 xl:p-4 p-2 bg-white/23 rounded-4xl border-[3px] border-white'>
<Image
src='https://picsum.photos/seed/picsum/200/300'
alt='service-1'
width={300}
height={300}
className='w-full max-h-[300px] h-auto rounded-4xl'
/>
</div>
</div>
<div className='w-full xl:py-32 py-20 bg-gradient-to-l from-[#eef0f6] via-[#e2e5ec] to-[#dee1e9] xl:mt-40 mt-12 rounded-4xl'>
<div className='max-w-maxWidth px-4 xl:px-0 mx-auto flex xl:flex-row flex-col items-center xl:gap-32 gap-14'>
<div className='flex-1 xl:p-4 p-2 bg-white/23 rounded-4xl border-[3px] border-white'>
<Image
src='https://picsum.photos/seed/picsum/200/300'
alt='service-1'
width={300}
height={300}
className='min-w-full max-h-[300px] h-auto rounded-4xl'
/>
</div>
<div className='flex-1'>
<div className='flex gap-4 items-center'>
<div className="size-12 flex items-center justify-center bg-gradient-to-b from-[#f9fafc] to-[#f1f3f8] rounded-2xl shadow-[inset_4px_4px_6px_#e2e5ec,inset_-4px_-4px_6px_#ffffff] ">
<ShieldTick
size={24}
color='black'
/>
</div>
<h6 className='font-bold'>
خدمات امنیت
</h6>
</div>
<p className='mt-4 leading-6 text-sm'>
امنیت اطلاعات یکی از مهمترین ارکان هر کسبوکاری است که به دنیای دیجیتال وارد میشود. در داناک، ما به شما خدمات امنیتی پیشرفتهای را ارائه میدهیم که تضمینکننده حفاظت از دادهها و اطلاعات حساس شماست. سرویسهای امنیتی ما با رعایت استانداردهای جهانی و پیروی از آخرین متدهای امنیتی طراحی شدهاند تا از تهدیدات احتمالی جلوگیری کنند. از رمزگذاری دادهها و پیشگیری از حملات سایبری گرفته تا پیادهسازی سیستمهای احراز هویت چندعاملی، ما با استفاده از ابزارهای پیشرفته و تیم متخصص خود، امنیت سیستمها و زیرساختهای شما را تأمین میکنیم. با خدمات امنیتی ما، دیگر نگرانی از بابت حفاظت از دادهها و حفظ حریم خصوصی نخواهید داشت.
</p>
</div>
</div>
</div>
<div className='mt-20 flex flex-col-reverse xl:flex-row gap-x-32 gap-y-12 max-w-maxWidth mx-auto'>
<div className='flex-1'>
<div className='flex gap-4 items-center'>
<div className="size-12 flex items-center justify-center bg-gradient-to-b from-[#f9fafc] to-[#f1f3f8] rounded-2xl shadow-[inset_4px_4px_6px_#e2e5ec,inset_-4px_-4px_6px_#ffffff] ">
<TrendUp
size={24}
color='black'
/>
</div>
<h6 className='font-bold'>
راهکارهای اختصاصی
</h6>
</div>
<p className='mt-4 leading-6 text-sm'>
هر کسبوکاری ویژگیها و نیازهای خاص خود را دارد و نرمافزارهایی که برای یک صنعت یا کسبوکار طراحی شدهاند ممکن است برای شما کارآمد نباشند. در داناک، ما به شما راهکارهای نرمافزاری اختصاصی ارائه میدهیم که به طور دقیق بر اساس نیازها و فرآیندهای خاص کسبوکار شما طراحی میشوند. تیم توسعه ما با درک عمیق از اهداف شما، نرمافزارهایی را طراحی میکند که نه تنها کارایی بالا و مقیاسپذیری دارند، بلکه قابلیت انعطافپذیری لازم برای رشد و تغییرات آینده کسبوکار شما را نیز دارا هستند. چه به یک سیستم مدیریت منابع انسانی نیاز داشته باشید، چه نرمافزار خاصی برای تحلیل دادهها یا بهینهسازی زنجیره تأمین، راهکارهای اختصاصی ما شما را در رسیدن به هدفهایتان همراهی میکند و کمک میکند تا به طور دقیقتر و سریعتر به نیازهای بازار پاسخ دهید.
</p>
</div>
<div className='flex-1 xl:p-4 p-2 bg-white/23 rounded-4xl border-[3px] border-white'>
<Image
src='https://picsum.photos/seed/picsum/200/300'
alt='service-1'
width={300}
height={300}
className='w-full max-h-[300px] h-auto rounded-4xl'
/>
</div>
</div>
<div className='w-full xl:py-32 py-20 bg-gradient-to-l from-[#eef0f6] via-[#e2e5ec] to-[#dee1e9] xl:mt-40 mt-12 rounded-4xl'>
<div className='max-w-maxWidth px-4 xl:px-0 mx-auto flex xl:flex-row flex-col items-center xl:gap-32 gap-14'>
<div className='flex-1 xl:p-4 p-2 bg-white/23 rounded-4xl border-[3px] border-white'>
<Image
src='https://picsum.photos/seed/picsum/200/300'
alt='service-1'
width={300}
height={300}
className='min-w-full max-h-[300px] h-auto rounded-4xl'
/>
</div>
<div className='flex-1'>
<div className='flex gap-4 items-center'>
<div className="size-12 flex items-center justify-center bg-gradient-to-b from-[#f9fafc] to-[#f1f3f8] rounded-2xl shadow-[inset_4px_4px_6px_#e2e5ec,inset_-4px_-4px_6px_#ffffff] ">
<Headphone
size={24}
color='black'
/>
</div>
<h6 className='font-bold'>
خدمات پشتیبانی
</h6>
</div>
<p className='mt-4 leading-6 text-sm'>
در دنیای پرسرعت فناوری امروز، داشتن پشتیبانی مطمئن و مستمر برای نرمافزارها و سیستمهای شما، نقشی حیاتی در موفقیت کسبوکار دارد. در داناک، ما نه تنها در زمان طراحی و پیادهسازی راهکارها در کنار شما هستیم، بلکه پس از راهاندازی نیز به عنوان یک شریک بلندمدت همراه شما خواهیم بود. خدمات پشتیبانی ما به گونهای طراحی شده است که همیشه در دسترس شما قرار داشته باشیم تا هرگونه چالش یا مشکلی که ممکن است پیش آید، به سرعت و بهطور مؤثر حل شود. تیم پشتیبانی ما با ارائه مشاوره تخصصی، بهروزرسانیهای منظم، رفع اشکالات فنی، و راهنماییهای مستمر، به شما کمک میکند تا از تمامی امکانات نرمافزاری به بهترین شکل ممکن استفاده کنید و هیچگاه دچار اختلال در عملکرد نشوید. هدف ما این است که شما همواره بهترین تجربه کاربری را داشته باشید و هیچوقت در مسیر کسبوکارتان تنها نباشید.
</p>
</div>
</div>
</div>
</div>
)
}
export default DanakServicesContent
+103
View File
@@ -0,0 +1,103 @@
export default function Loading() {
return (
<div className="mt-24">
{/* Header Section */}
<div className="flex gap-y-4 flex-col xl:flex-row xl:items-center justify-between max-w-maxWidth mx-auto">
<div className="h-8 w-48 bg-gray-200 rounded-md animate-pulse"></div>
<div className="max-w-[300px]">
<div className="h-4 w-full bg-gray-200 rounded-md animate-pulse"></div>
<div className="h-4 w-full bg-gray-200 rounded-md animate-pulse mt-2"></div>
<div className="h-4 w-3/4 bg-gray-200 rounded-md animate-pulse mt-2"></div>
</div>
</div>
{/* First Service Section - Consulting */}
<div className="mt-20 flex flex-col-reverse xl:flex-row gap-x-32 gap-y-12 max-w-maxWidth mx-auto">
<div className="flex-1">
<div className="flex gap-4 items-center">
<div className="size-12 bg-gray-200 rounded-2xl animate-pulse"></div>
<div className="h-6 w-28 bg-gray-200 rounded-md animate-pulse"></div>
</div>
<div className="mt-4 space-y-2">
<div className="h-4 w-full bg-gray-200 rounded-md animate-pulse"></div>
<div className="h-4 w-full bg-gray-200 rounded-md animate-pulse"></div>
<div className="h-4 w-full bg-gray-200 rounded-md animate-pulse"></div>
<div className="h-4 w-full bg-gray-200 rounded-md animate-pulse"></div>
<div className="h-4 w-full bg-gray-200 rounded-md animate-pulse"></div>
<div className="h-4 w-3/4 bg-gray-200 rounded-md animate-pulse"></div>
</div>
</div>
<div className="flex-1 xl:p-4 p-2 bg-gray-100 rounded-4xl">
<div className="w-full h-[300px] bg-gray-200 rounded-4xl animate-pulse"></div>
</div>
</div>
{/* Second Service Section - Security */}
<div className="w-full xl:py-32 py-20 bg-gray-100 xl:mt-40 mt-12 rounded-4xl">
<div className="max-w-maxWidth px-4 xl:px-0 mx-auto flex xl:flex-row flex-col items-center xl:gap-32 gap-14">
<div className="flex-1 xl:p-4 p-2 bg-gray-200 rounded-4xl">
<div className="min-w-full h-[300px] bg-gray-300 rounded-4xl animate-pulse"></div>
</div>
<div className="flex-1">
<div className="flex gap-4 items-center">
<div className="size-12 bg-gray-200 rounded-2xl animate-pulse"></div>
<div className="h-6 w-36 bg-gray-200 rounded-md animate-pulse"></div>
</div>
<div className="mt-4 space-y-2">
<div className="h-4 w-full bg-gray-200 rounded-md animate-pulse"></div>
<div className="h-4 w-full bg-gray-200 rounded-md animate-pulse"></div>
<div className="h-4 w-full bg-gray-200 rounded-md animate-pulse"></div>
<div className="h-4 w-full bg-gray-200 rounded-md animate-pulse"></div>
<div className="h-4 w-full bg-gray-200 rounded-md animate-pulse"></div>
<div className="h-4 w-3/4 bg-gray-200 rounded-md animate-pulse"></div>
</div>
</div>
</div>
</div>
{/* Third Service Section - Custom Solutions */}
<div className="mt-20 flex flex-col-reverse xl:flex-row gap-x-32 gap-y-12 max-w-maxWidth mx-auto">
<div className="flex-1">
<div className="flex gap-4 items-center">
<div className="size-12 bg-gray-200 rounded-2xl animate-pulse"></div>
<div className="h-6 w-44 bg-gray-200 rounded-md animate-pulse"></div>
</div>
<div className="mt-4 space-y-2">
<div className="h-4 w-full bg-gray-200 rounded-md animate-pulse"></div>
<div className="h-4 w-full bg-gray-200 rounded-md animate-pulse"></div>
<div className="h-4 w-full bg-gray-200 rounded-md animate-pulse"></div>
<div className="h-4 w-full bg-gray-200 rounded-md animate-pulse"></div>
<div className="h-4 w-full bg-gray-200 rounded-md animate-pulse"></div>
<div className="h-4 w-3/4 bg-gray-200 rounded-md animate-pulse"></div>
</div>
</div>
<div className="flex-1 xl:p-4 p-2 bg-gray-100 rounded-4xl">
<div className="w-full h-[300px] bg-gray-200 rounded-4xl animate-pulse"></div>
</div>
</div>
{/* Fourth Service Section - Support */}
<div className="w-full xl:py-32 py-20 bg-gray-100 xl:mt-40 mt-12 rounded-4xl">
<div className="max-w-maxWidth px-4 xl:px-0 mx-auto flex xl:flex-row flex-col items-center xl:gap-32 gap-14">
<div className="flex-1 xl:p-4 p-2 bg-gray-200 rounded-4xl">
<div className="min-w-full h-[300px] bg-gray-300 rounded-4xl animate-pulse"></div>
</div>
<div className="flex-1">
<div className="flex gap-4 items-center">
<div className="size-12 bg-gray-200 rounded-2xl animate-pulse"></div>
<div className="h-6 w-40 bg-gray-200 rounded-md animate-pulse"></div>
</div>
<div className="mt-4 space-y-2">
<div className="h-4 w-full bg-gray-200 rounded-md animate-pulse"></div>
<div className="h-4 w-full bg-gray-200 rounded-md animate-pulse"></div>
<div className="h-4 w-full bg-gray-200 rounded-md animate-pulse"></div>
<div className="h-4 w-full bg-gray-200 rounded-md animate-pulse"></div>
<div className="h-4 w-full bg-gray-200 rounded-md animate-pulse"></div>
<div className="h-4 w-3/4 bg-gray-200 rounded-md animate-pulse"></div>
</div>
</div>
</div>
</div>
</div>
)
}
+6 -144
View File
@@ -1,151 +1,13 @@
import { Headphone, Profile2User, ShieldTick, TrendUp } from 'iconsax-react'
import { NextPage } from 'next'
import Image from 'next/image'
import React from 'react'
import { Suspense } from 'react'
import Loading from './loading'
import DanakServicesContent from './DanakServicesContent'
const DanakServices: NextPage = () => {
return (
<div className='mt-24'>
<div className='flex gap-y-4 flex-col xl:flex-row xl:items-center justify-between max-w-maxWidth mx-auto'>
<h1 className='text-2xl font-bold'>
خدمات داناک
</h1>
<div className='max-w-[300px] text-sm leading-6'>
ما در داناک با ترکیب خلاقیت، تخصص و تکنولوژیهای روز، راهکارهای نرمافزاری منحصربهفردی ارائه میدهیم که کسبوکار شما را به سطحی بالاتر میبرد.
</div>
</div>
<div className='mt-20 flex flex-col-reverse xl:flex-row gap-x-32 gap-y-12 max-w-maxWidth mx-auto'>
<div className='flex-1'>
<div className='flex gap-4 items-center'>
<div className="size-12 flex items-center justify-center bg-gradient-to-b from-[#f9fafc] to-[#f1f3f8] rounded-2xl shadow-[inset_4px_4px_6px_#e2e5ec,inset_-4px_-4px_6px_#ffffff] ">
<Profile2User
size={24}
color='black'
/>
</div>
<h6 className='font-bold'>
مشاوره
</h6>
</div>
<p className='mt-4 leading-6 text-sm'>
در دنیای امروز، نیاز به راهکارهای نرمافزاری که هم از لحاظ عملکردی بهینه و سریع باشند و هم با پیچیدگیهای فنی و نیازهای خاص کسبوکارها همخوانی داشته باشند، بیشتر از همیشه احساس میشود. تیم مشاوره داناک با ارائه راهکارهای نرمافزاری مدرن، به شما کمک میکند تا از ابزارها و فناوریهای روز دنیا استفاده کرده و فرایندهای کسبوکار خود را به شکلی بهینهسازی کنید. هدف ما این است که راهحلهایی با بالاترین کارایی و کمترین زمان اجرا ارائه دهیم تا شما بتوانید با کمترین هزینه و زمان ممکن، بهترین نتیجه را در پروژههای خود به دست آورید. چه در زمینه توسعه نرمافزارهای خاص، چه در یکپارچهسازی سیستمها، مشاوران ما به شما در انتخاب و پیادهسازی بهترین گزینهها کمک میکنند.
</p>
</div>
<div className='flex-1 xl:p-4 p-2 bg-white/23 rounded-4xl border-[3px] border-white'>
<Image
src='https://picsum.photos/seed/picsum/200/300'
alt='service-1'
width={300}
height={300}
className='w-full max-h-[300px] h-auto rounded-4xl'
/>
</div>
</div>
<div className='w-full xl:py-32 py-20 bg-gradient-to-l from-[#eef0f6] via-[#e2e5ec] to-[#dee1e9] xl:mt-40 mt-12 rounded-4xl'>
<div className='max-w-maxWidth px-4 xl:px-0 mx-auto flex xl:flex-row flex-col items-center xl:gap-32 gap-14'>
<div className='flex-1 xl:p-4 p-2 bg-white/23 rounded-4xl border-[3px] border-white'>
<Image
src='https://picsum.photos/seed/picsum/200/300'
alt='service-1'
width={300}
height={300}
className='min-w-full max-h-[300px] h-auto rounded-4xl'
/>
</div>
<div className='flex-1'>
<div className='flex gap-4 items-center'>
<div className="size-12 flex items-center justify-center bg-gradient-to-b from-[#f9fafc] to-[#f1f3f8] rounded-2xl shadow-[inset_4px_4px_6px_#e2e5ec,inset_-4px_-4px_6px_#ffffff] ">
<ShieldTick
size={24}
color='black'
/>
</div>
<h6 className='font-bold'>
خدمات امنیت
</h6>
</div>
<p className='mt-4 leading-6 text-sm'>
امنیت اطلاعات یکی از مهمترین ارکان هر کسبوکاری است که به دنیای دیجیتال وارد میشود. در داناک، ما به شما خدمات امنیتی پیشرفتهای را ارائه میدهیم که تضمینکننده حفاظت از دادهها و اطلاعات حساس شماست. سرویسهای امنیتی ما با رعایت استانداردهای جهانی و پیروی از آخرین متدهای امنیتی طراحی شدهاند تا از تهدیدات احتمالی جلوگیری کنند. از رمزگذاری دادهها و پیشگیری از حملات سایبری گرفته تا پیادهسازی سیستمهای احراز هویت چندعاملی، ما با استفاده از ابزارهای پیشرفته و تیم متخصص خود، امنیت سیستمها و زیرساختهای شما را تأمین میکنیم. با خدمات امنیتی ما، دیگر نگرانی از بابت حفاظت از دادهها و حفظ حریم خصوصی نخواهید داشت.
</p>
</div>
</div>
</div>
<div className='mt-20 flex flex-col-reverse xl:flex-row gap-x-32 gap-y-12 max-w-maxWidth mx-auto'>
<div className='flex-1'>
<div className='flex gap-4 items-center'>
<div className="size-12 flex items-center justify-center bg-gradient-to-b from-[#f9fafc] to-[#f1f3f8] rounded-2xl shadow-[inset_4px_4px_6px_#e2e5ec,inset_-4px_-4px_6px_#ffffff] ">
<TrendUp
size={24}
color='black'
/>
</div>
<h6 className='font-bold'>
راهکارهای اختصاصی
</h6>
</div>
<p className='mt-4 leading-6 text-sm'>
هر کسبوکاری ویژگیها و نیازهای خاص خود را دارد و نرمافزارهایی که برای یک صنعت یا کسبوکار طراحی شدهاند ممکن است برای شما کارآمد نباشند. در داناک، ما به شما راهکارهای نرمافزاری اختصاصی ارائه میدهیم که به طور دقیق بر اساس نیازها و فرآیندهای خاص کسبوکار شما طراحی میشوند. تیم توسعه ما با درک عمیق از اهداف شما، نرمافزارهایی را طراحی میکند که نه تنها کارایی بالا و مقیاسپذیری دارند، بلکه قابلیت انعطافپذیری لازم برای رشد و تغییرات آینده کسبوکار شما را نیز دارا هستند. چه به یک سیستم مدیریت منابع انسانی نیاز داشته باشید، چه نرمافزار خاصی برای تحلیل دادهها یا بهینهسازی زنجیره تأمین، راهکارهای اختصاصی ما شما را در رسیدن به هدفهایتان همراهی میکند و کمک میکند تا به طور دقیقتر و سریعتر به نیازهای بازار پاسخ دهید.
</p>
</div>
<div className='flex-1 xl:p-4 p-2 bg-white/23 rounded-4xl border-[3px] border-white'>
<Image
src='https://picsum.photos/seed/picsum/200/300'
alt='service-1'
width={300}
height={300}
className='w-full max-h-[300px] h-auto rounded-4xl'
/>
</div>
</div>
<div className='w-full xl:py-32 py-20 bg-gradient-to-l from-[#eef0f6] via-[#e2e5ec] to-[#dee1e9] xl:mt-40 mt-12 rounded-4xl'>
<div className='max-w-maxWidth px-4 xl:px-0 mx-auto flex xl:flex-row flex-col items-center xl:gap-32 gap-14'>
<div className='flex-1 xl:p-4 p-2 bg-white/23 rounded-4xl border-[3px] border-white'>
<Image
src='https://picsum.photos/seed/picsum/200/300'
alt='service-1'
width={300}
height={300}
className='min-w-full max-h-[300px] h-auto rounded-4xl'
/>
</div>
<div className='flex-1'>
<div className='flex gap-4 items-center'>
<div className="size-12 flex items-center justify-center bg-gradient-to-b from-[#f9fafc] to-[#f1f3f8] rounded-2xl shadow-[inset_4px_4px_6px_#e2e5ec,inset_-4px_-4px_6px_#ffffff] ">
<Headphone
size={24}
color='black'
/>
</div>
<h6 className='font-bold'>
خدمات پشتیبانی
</h6>
</div>
<p className='mt-4 leading-6 text-sm'>
در دنیای پرسرعت فناوری امروز، داشتن پشتیبانی مطمئن و مستمر برای نرمافزارها و سیستمهای شما، نقشی حیاتی در موفقیت کسبوکار دارد. در داناک، ما نه تنها در زمان طراحی و پیادهسازی راهکارها در کنار شما هستیم، بلکه پس از راهاندازی نیز به عنوان یک شریک بلندمدت همراه شما خواهیم بود. خدمات پشتیبانی ما به گونهای طراحی شده است که همیشه در دسترس شما قرار داشته باشیم تا هرگونه چالش یا مشکلی که ممکن است پیش آید، به سرعت و بهطور مؤثر حل شود. تیم پشتیبانی ما با ارائه مشاوره تخصصی، بهروزرسانیهای منظم، رفع اشکالات فنی، و راهنماییهای مستمر، به شما کمک میکند تا از تمامی امکانات نرمافزاری به بهترین شکل ممکن استفاده کنید و هیچگاه دچار اختلال در عملکرد نشوید. هدف ما این است که شما همواره بهترین تجربه کاربری را داشته باشید و هیچوقت در مسیر کسبوکارتان تنها نباشید.
</p>
</div>
</div>
</div>
</div>
<Suspense fallback={<Loading />}>
<DanakServicesContent />
</Suspense>
)
}
+1 -1
View File
@@ -22,7 +22,7 @@ const HeroSection: FC = () => {
alt='banner'
width={1920}
height={1080}
className='w-full rounded-4xl object-cover xl:mt-14 mt-8 min-h-[210px]'
className='w-full rounded-4xl object-cover xl:mt-14 mt-8 min-h-[210px] max-h-[500px]'
/>
<div className='absolute flex items-center z-1 top-0 left-0 w-full h-full bg-black/10 rounded-4xl'>
+87
View File
@@ -0,0 +1,87 @@
export default function Loading() {
return (
<div>
{/* Hero Section Skeleton */}
<div className="mt-5 h-[400px] xl:h-[500px] bg-gray-200 rounded-4xl animate-pulse relative">
<div className="absolute bottom-10 right-10">
<div className="h-10 w-36 xl:w-60 bg-gray-300 rounded-md animate-pulse"></div>
<div className="h-6 w-52 xl:w-96 bg-gray-300 rounded-md animate-pulse mt-4"></div>
<div className="h-6 w-48 xl:w-80 bg-gray-300 rounded-md animate-pulse mt-2"></div>
<div className="h-12 w-32 xl:w-40 bg-gray-300 rounded-md animate-pulse mt-6"></div>
</div>
</div>
{/* Danak Suggested Service Skeleton */}
<div className="mt-20">
<div className="h-8 w-40 xl:w-60 bg-gray-200 rounded-md animate-pulse mx-auto"></div>
<div className="h-4 w-52 xl:w-96 bg-gray-200 rounded-md animate-pulse mx-auto mt-4"></div>
<div className="mt-10 grid grid-cols-1 md:grid-cols-2 xl:grid-cols-4 gap-6">
{[1, 2, 3, 4].map((i) => (
<div key={`service-${i}`} className="bg-white rounded-4xl h-80 p-6 animate-pulse">
<div className="h-10 w-10 bg-gray-200 rounded-full mb-4"></div>
<div className="h-6 w-40 bg-gray-200 rounded-md"></div>
<div className="h-4 w-full bg-gray-200 rounded-md mt-4"></div>
<div className="h-4 w-full bg-gray-200 rounded-md mt-2"></div>
<div className="h-4 w-3/4 bg-gray-200 rounded-md mt-2"></div>
<div className="h-10 w-28 bg-gray-200 rounded-md mt-8"></div>
</div>
))}
</div>
</div>
{/* Why Danak Skeleton */}
<div className="mt-20">
<div className="h-8 w-40 xl:w-60 bg-gray-200 rounded-md animate-pulse mx-auto"></div>
<div className="h-4 w-52 xl:w-96 bg-gray-200 rounded-md animate-pulse mx-auto mt-4"></div>
<div className="mt-10 grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-6">
{[1, 2, 3].map((i) => (
<div key={`why-${i}`} className="bg-white rounded-4xl h-60 p-6 animate-pulse">
<div className="h-10 w-10 bg-gray-200 rounded-full mb-4"></div>
<div className="h-6 w-40 bg-gray-200 rounded-md"></div>
<div className="h-4 w-full bg-gray-200 rounded-md mt-4"></div>
<div className="h-4 w-full bg-gray-200 rounded-md mt-2"></div>
<div className="h-4 w-3/4 bg-gray-200 rounded-md mt-2"></div>
</div>
))}
</div>
</div>
{/* Blog Skeleton */}
<div className="mt-20">
<div className="h-8 w-40 xl:w-60 bg-gray-200 rounded-md animate-pulse mx-auto"></div>
<div className="h-4 w-52 xl:w-96 bg-gray-200 rounded-md animate-pulse mx-auto mt-4"></div>
<div className="mt-10 grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-6">
{[1, 2, 3].map((i) => (
<div key={`blog-${i}`} className="bg-white rounded-4xl h-80 p-0 animate-pulse overflow-hidden">
<div className="h-40 w-full bg-gray-200"></div>
<div className="p-4">
<div className="h-6 w-3/4 bg-gray-200 rounded-md"></div>
<div className="h-4 w-28 bg-gray-200 rounded-md mt-2"></div>
<div className="h-4 w-full bg-gray-200 rounded-md mt-4"></div>
<div className="h-4 w-full bg-gray-200 rounded-md mt-2"></div>
<div className="h-4 w-3/4 bg-gray-200 rounded-md mt-2"></div>
</div>
</div>
))}
</div>
</div>
{/* Collaboration Skeleton */}
<div className="mt-20 mb-20">
<div className="h-8 w-40 xl:w-60 bg-gray-200 rounded-md animate-pulse mx-auto"></div>
<div className="h-4 w-52 xl:w-96 bg-gray-200 rounded-md animate-pulse mx-auto mt-4"></div>
<div className="mt-10 grid grid-cols-2 md:grid-cols-3 xl:grid-cols-6 gap-6">
{[1, 2, 3, 4, 5, 6].map((i) => (
<div key={`collab-${i}`} className="bg-white rounded-4xl h-24 p-4 flex items-center justify-center animate-pulse">
<div className="h-12 w-20 xl:w-24 bg-gray-200 rounded-md"></div>
</div>
))}
</div>
</div>
</div>
)
}
+12 -1
View File
@@ -1,10 +1,21 @@
import { NextPage } from 'next'
import { Suspense } from 'react'
import { HydrationBoundary } from '@tanstack/react-query'
import { dehydrate } from '@tanstack/react-query'
import { QueryClient } from '@tanstack/react-query'
import { landingQueryOptions } from './home/hooks/useHomeData'
import LangingPage from './home/LangingPage'
const Home: NextPage = async () => {
import Loading from './loading'
const Home: NextPage = () => {
return (
<Suspense fallback={<Loading />}>
<HomeContent />
</Suspense>
)
}
async function HomeContent() {
const queryClient = new QueryClient()
await queryClient.prefetchQuery(landingQueryOptions)
+93
View File
@@ -0,0 +1,93 @@
export default function Loading() {
return (
<div className="max-w-maxWidth mx-auto">
{/* Header Skeleton */}
<div className="flex justify-between mt-20 items-center">
<div className="h-8 w-32 xl:w-40 bg-gray-200 rounded-md animate-pulse"></div>
<div className="max-w-[320px] hidden xl:block">
<div className="h-6 w-52 xl:w-80 bg-gray-200 rounded-md animate-pulse"></div>
</div>
</div>
{/* Product Slider Skeleton */}
<div className="mt-20">
<div className="flex gap-4 overflow-hidden">
{[1, 2].map((i) => (
<div key={`product-${i}`} className="min-w-[80%] xl:min-w-[45%] rounded-4xl overflow-hidden relative">
<div className="w-full h-[300px] xl:h-[400px] bg-gray-200 animate-pulse"></div>
<div className="absolute bottom-0 left-0 w-full h-[120px] xl:h-[150px] rounded-b-3xl p-4">
<div className="flex justify-between items-center">
<div className="h-4 w-24 xl:w-32 bg-gray-300 rounded-md animate-pulse"></div>
<div className="h-8 w-20 xl:w-28 bg-gray-300 rounded-xl animate-pulse"></div>
</div>
<div className="mt-6 flex justify-between items-end">
<div className="flex gap-2 xl:gap-4">
<div className="size-10 xl:size-14 bg-gray-300 rounded-2xl animate-pulse"></div>
<div>
<div className="h-5 xl:h-6 w-20 xl:w-28 bg-gray-300 rounded-md animate-pulse"></div>
<div className="mt-1">
<div className="h-3 xl:h-4 w-12 xl:w-16 bg-gray-300 rounded-md animate-pulse"></div>
</div>
</div>
</div>
<div className="flex gap-1.5 items-center">
<div className="h-4 xl:h-5 w-12 xl:w-16 bg-gray-300 rounded-md animate-pulse"></div>
<div className="h-4 xl:h-5 w-4 xl:w-5 bg-gray-300 rounded-md animate-pulse"></div>
</div>
</div>
</div>
</div>
))}
</div>
</div>
{/* Danak Suggested Service Skeleton */}
<div className="mt-20">
<div className="flex justify-between items-center">
<div className="h-8 w-40 xl:w-60 bg-gray-200 rounded-md animate-pulse"></div>
<div className="h-4 w-24 xl:w-32 bg-gray-200 rounded-md animate-pulse"></div>
</div>
<div className="mt-10 grid grid-cols-1 md:grid-cols-2 xl:grid-cols-4 gap-6">
{[1, 2, 3, 4].map((i) => (
<div key={`service-${i}`} className="bg-white rounded-4xl h-[340px] p-6 animate-pulse">
<div className="h-10 w-10 bg-gray-200 rounded-full mb-4"></div>
<div className="h-6 w-40 bg-gray-200 rounded-md"></div>
<div className="h-4 w-full bg-gray-200 rounded-md mt-4"></div>
<div className="h-4 w-full bg-gray-200 rounded-md mt-2"></div>
<div className="h-4 w-3/4 bg-gray-200 rounded-md mt-2"></div>
<div className="h-10 w-28 bg-gray-200 rounded-md mt-8"></div>
</div>
))}
</div>
</div>
{/* Danak Services Skeleton */}
<div className="mt-20 mb-20">
<div className="flex justify-between items-center">
<div className="h-8 w-60 bg-gray-200 rounded-md animate-pulse"></div>
<div className="h-10 w-32 bg-gray-200 rounded-3xl animate-pulse"></div>
</div>
<div className="mt-10 grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-6">
{[1, 2, 3, 4, 5, 6].map((i) => (
<div key={`service-item-${i}`} className="bg-white rounded-4xl h-[300px] animate-pulse">
<div className="h-40 w-full bg-gray-200"></div>
<div className="p-4">
<div className="h-6 w-3/4 bg-gray-200 rounded-md"></div>
<div className="mt-4 flex justify-between">
<div className="h-5 w-20 bg-gray-200 rounded-md"></div>
<div className="h-5 w-20 bg-gray-200 rounded-md"></div>
</div>
<div className="mt-4 flex justify-between">
<div className="h-5 w-28 bg-gray-200 rounded-md"></div>
<div className="h-8 w-8 bg-gray-200 rounded-xl"></div>
</div>
</div>
</div>
))}
</div>
</div>
</div>
)
}
+13 -1
View File
@@ -1,14 +1,26 @@
import { NextPage } from 'next'
import { Suspense } from 'react'
import { HydrationBoundary } from '@tanstack/react-query'
import { dehydrate } from '@tanstack/react-query'
import { QueryClient } from '@tanstack/react-query'
import { categoriesQueryOptions, danakServiceSuggestedQueryOptions, servicesQueryOptions } from './hooks/useProductData'
import Products from './ProductsPage'
const ProductsPage: NextPage = async () => {
import Loading from './loading'
const ProductsPage: NextPage = () => {
return (
<Suspense fallback={<Loading />}>
<ProductsContent />
</Suspense>
)
}
async function ProductsContent() {
const queryClient = new QueryClient()
await queryClient.prefetchQuery(servicesQueryOptions)
await queryClient.prefetchQuery(categoriesQueryOptions)
await queryClient.prefetchQuery(danakServiceSuggestedQueryOptions)
return (
<HydrationBoundary state={dehydrate(queryClient)}>
<Products />