feat: enhance image handling and layout adjustments
- Added image quality settings and device sizes in next.config.ts for better image optimization. - Updated package dependencies, including cheerio and baseline-browser-mapping. - Improved global styles for blog content images to ensure responsiveness. - Refactored button components for consistent sizing and styling across the application. - Enhanced blog post card layout with new variants and improved author name formatting. - Adjusted hero section and content layout for better visual appeal and user experience.
This commit is contained in:
@@ -25,7 +25,7 @@ export function BlogBlockquote({ payload }: BlogBlockquoteProps) {
|
||||
{citation ? (
|
||||
<footer className="mt-4 border-t border-border/60 pt-4">
|
||||
<cite className="text-sm text-muted-foreground not-italic">
|
||||
— {citation}
|
||||
{citation}
|
||||
</cite>
|
||||
</footer>
|
||||
) : null}
|
||||
|
||||
@@ -4,12 +4,13 @@ import { ImageIcon, User } from "lucide-react";
|
||||
import { Card, CardHeader, CardTitle, CardContent } from "@/components/ui/card";
|
||||
import { getFeaturedImageUrl, type WpPost } from "@/lib/wp-api";
|
||||
import { formatDateShamsi } from "@/lib/format-date";
|
||||
import { formatAuthorName } from "@/lib/blog-utils";
|
||||
|
||||
function stripHtml(html: string): string {
|
||||
return html.replace(/<[^>]*>/g, "").trim();
|
||||
}
|
||||
|
||||
type BlogPostCardVariant = "default" | "tiny";
|
||||
type BlogPostCardVariant = "default" | "tiny" | "related";
|
||||
|
||||
export function BlogPostCard({
|
||||
post,
|
||||
@@ -20,9 +21,57 @@ export function BlogPostCard({
|
||||
}) {
|
||||
const excerpt = stripHtml(post.excerpt.rendered) || stripHtml(post.content.rendered).slice(0, 160);
|
||||
const modifiedDate = post.modified ? formatDateShamsi(post.modified) : null;
|
||||
const authorName = post._embedded?.author?.[0]?.name ?? null;
|
||||
const authorName = formatAuthorName(post._embedded?.author?.[0]?.name);
|
||||
const thumbnailUrl = getFeaturedImageUrl(post, "full");
|
||||
|
||||
if (variant === "related") {
|
||||
return (
|
||||
<Link href={`/blog/${encodeURIComponent(post.slug)}`} className="block h-full min-w-0">
|
||||
<Card className="h-full overflow-hidden transition-all rounded-md duration-300 hover:shadow-md flex flex-col p-0 gap-0">
|
||||
<CardContent className="p-3 sm:p-4 grid grid-cols-3 gap-3 sm:gap-4 min-w-0">
|
||||
{thumbnailUrl ? (
|
||||
<div className="relative rounded-md aspect-[4/3] w-full overflow-hidden bg-muted shrink-0 col-span-1 min-w-0">
|
||||
<Image
|
||||
src={thumbnailUrl}
|
||||
alt=""
|
||||
fill
|
||||
className="object-cover"
|
||||
quality={100}
|
||||
sizes="(max-width: 640px) 33vw, (max-width: 1024px) 20vw, 200px"
|
||||
/>
|
||||
</div>
|
||||
) : (
|
||||
<div
|
||||
className="relative rounded-md flex aspect-[4/3] w-full items-center justify-center overflow-hidden bg-muted shrink-0 col-span-1"
|
||||
aria-hidden
|
||||
>
|
||||
<ImageIcon className="size-10 text-muted-foreground/50" />
|
||||
</div>
|
||||
)}
|
||||
<div className="col-span-2 min-w-0 flex flex-col justify-center">
|
||||
<h4 className="text-base font-semibold leading-snug line-clamp-3">
|
||||
{post.title.rendered}
|
||||
</h4>
|
||||
<div className="flex flex-wrap w-full items-center gap-x-4 gap-y-1 text-sm text-muted-foreground bg-muted inline-flex p-1.5 mt-3 rounded-sm">
|
||||
{authorName && (
|
||||
<span className="inline-flex flex-1 items-center gap-1.5 min-w-0">
|
||||
<User className="size-4 shrink-0" aria-hidden />
|
||||
<span className="truncate">{authorName}</span>
|
||||
</span>
|
||||
)}
|
||||
{modifiedDate && (
|
||||
<time dateTime={post.modified} className="shrink-0">
|
||||
{modifiedDate}
|
||||
</time>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
|
||||
if (variant === "tiny") {
|
||||
return (
|
||||
<Link href={`/blog/${encodeURIComponent(post.slug)}`} className="block h-full">
|
||||
@@ -35,7 +84,8 @@ export function BlogPostCard({
|
||||
alt=""
|
||||
fill
|
||||
className="object-cover"
|
||||
sizes="(max-width: 640px) 100vw, (max-width: 1024px) 50vw, 33vw"
|
||||
quality={100}
|
||||
sizes="(max-width: 640px) 100vw, (max-width: 1024px) 50vw, 400px"
|
||||
/>
|
||||
</div>
|
||||
) : (
|
||||
@@ -82,7 +132,7 @@ export function BlogPostCard({
|
||||
className="object-cover"
|
||||
quality={100}
|
||||
priority
|
||||
sizes="(max-width: 640px) 100vw, (max-width: 1024px) 50vw, 350px"
|
||||
sizes="(max-width: 640px) 100vw, (max-width: 1024px) 50vw, 400px"
|
||||
/>
|
||||
</div>
|
||||
) : (
|
||||
|
||||
@@ -140,7 +140,6 @@ export function BlogPostMeta({
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon-sm"
|
||||
className="size-8 text-muted-foreground hover:text-foreground"
|
||||
onClick={copyLink}
|
||||
aria-label="کپی لینک"
|
||||
>
|
||||
@@ -160,7 +159,6 @@ export function BlogPostMeta({
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon-sm"
|
||||
className="size-8 text-muted-foreground hover:text-foreground"
|
||||
onClick={handleShare}
|
||||
aria-label="اشتراکگذاری"
|
||||
>
|
||||
|
||||
@@ -20,7 +20,7 @@ export function BlogPullquote({ payload }: BlogPullquoteProps) {
|
||||
{citation ? (
|
||||
<footer className="mt-4">
|
||||
<cite className="text-sm text-muted-foreground not-italic">
|
||||
— {citation}
|
||||
{citation}
|
||||
</cite>
|
||||
</footer>
|
||||
) : null}
|
||||
|
||||
@@ -11,24 +11,35 @@ export default function ContentSection() {
|
||||
<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="اکوسیستم یکپارچه فیپ"
|
||||
src="/assets/main-pic/intelligent-workflow-control-center.jpg"
|
||||
className="rounded-[15px] object-cover dark:hidden"
|
||||
alt="مرکز کنترل گردش کار هوشمند"
|
||||
width={1207}
|
||||
height={929}
|
||||
quality={100}
|
||||
sizes="(max-width: 640px) 100vw, 50vw"
|
||||
/>
|
||||
<Image
|
||||
src="/assets/main-pic/intelligent-workflow-control-center-dark.jpg"
|
||||
className="hidden rounded-[15px] object-cover dark:block"
|
||||
alt="مرکز کنترل گردش کار هوشمند"
|
||||
width={1207}
|
||||
height={929}
|
||||
quality={100}
|
||||
sizes="(max-width: 640px) 100vw, 50vw"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="relative space-y-4">
|
||||
<p className="text-muted-foreground leading-relaxed tracking-normal">
|
||||
<p className="text-muted-foreground leading-relaxed tracking-normal text-justify sm:text-start">
|
||||
فیپ یک گروه متخصص است که در حوزه اینتگریشن و روشهای نوین یکپارچهسازی فعالیت میکند.{" "}
|
||||
<span className="text-accent-foreground font-bold">
|
||||
<span className="text-primary font-bold">
|
||||
ما با استفاده از تکنولوژیهای پیشرفته و رویکردهای نوآورانه
|
||||
</span>{" "}
|
||||
به کسبوکارها کمک میکنیم تا سیستمهای خود را به شکلی کارآمد و قابلاعتماد بهم متصل کنند.
|
||||
</p>
|
||||
<p className="text-muted-foreground leading-relaxed tracking-normal">
|
||||
<p className="text-muted-foreground leading-relaxed tracking-normal text-justify sm:text-start">
|
||||
ما در زمینه یکپارچهسازی سیستمها، اتوماسیون فرآیندها، ارتباطات چندکاناله و مدیریت دادهها تخصص داریم. با استفاده از روشهای نوین و ابزارهای پیشرفته، راهکارهای سفارشی برای هر کسبوکار طراحی و پیادهسازی میکنیم که به آنها امکان میدهد تا از قدرت اتوماسیون و ارتباطات هوشمند بهرهمند شوند.
|
||||
</p>
|
||||
|
||||
|
||||
+56
-34
@@ -20,22 +20,29 @@ export default function Features() {
|
||||
type ImageKey = "item-1" | "item-2" | "item-3" | "item-4";
|
||||
const [activeItem, setActiveItem] = useState<ImageKey>("item-1");
|
||||
|
||||
const sectionImage = (filename: string) =>
|
||||
`/assets/main-pic/4section/${encodeURIComponent(filename)}`;
|
||||
|
||||
const images = {
|
||||
"item-1": {
|
||||
image: "/assets/main-pic/4section/Systems Integration.jpg",
|
||||
alt: "System integration",
|
||||
image: sectionImage("Systems Integration.jpg"),
|
||||
imageDark: sectionImage("Systems Integration-dark.jpg"),
|
||||
alt: "یکپارچهسازی سیستمها",
|
||||
},
|
||||
"item-2": {
|
||||
image: "/assets/main-pic/4section/Powerful Management panels.jpg",
|
||||
alt: "Management panels",
|
||||
image: sectionImage("Powerful Management panels.jpg"),
|
||||
imageDark: sectionImage("Powerful Management panels-dark.jpg"),
|
||||
alt: "پنلهای مدیریتی قدرتمند",
|
||||
},
|
||||
"item-3": {
|
||||
image: "/assets/main-pic/4section/Interaction with Social Networks.jpg",
|
||||
alt: "Social media integration",
|
||||
image: sectionImage("Interaction with Social Networks.jpg"),
|
||||
imageDark: sectionImage("Interaction with Social Networks_dark.jpg"),
|
||||
alt: "تعامل با شبکههای اجتماعی",
|
||||
},
|
||||
"item-4": {
|
||||
image: "/assets/main-pic/4section/Process Automation.jpg",
|
||||
alt: "Process automation",
|
||||
image: sectionImage("Process Automation.jpg"),
|
||||
imageDark: sectionImage("Process Automation-dark.jpg"),
|
||||
alt: "اتوماسیون فرآیندها",
|
||||
},
|
||||
};
|
||||
|
||||
@@ -113,33 +120,48 @@ export default function Features() {
|
||||
</AccordionItem>
|
||||
</Accordion>
|
||||
|
||||
<div className="bg-background relative flex overflow-hidden rounded-3xl border p-0 m-0">
|
||||
<div className="w-15 absolute inset-0 right-0 ml-auto border-l bg-[repeating-linear-gradient(-45deg,var(--color-border),var(--color-border)_1px,transparent_1px,transparent_8px)]"></div>
|
||||
<div className="aspect-76/59 bg-background relative w-full rounded-3xl m-0 p-0">
|
||||
<AnimatePresence mode="wait">
|
||||
<motion.div
|
||||
key={`${activeItem}-id`}
|
||||
initial={{ opacity: 0, y: 6, scale: 0.98 }}
|
||||
animate={{ opacity: 1, y: 0, scale: 1 }}
|
||||
exit={{ opacity: 0, y: 6, scale: 0.98 }}
|
||||
transition={{ duration: 0.2 }}
|
||||
className="size-full overflow-hidden rounded-3xl m-0 p-0"
|
||||
>
|
||||
<Image
|
||||
src={images[activeItem].image}
|
||||
className="size-full object-cover dark:mix-blend-lighten"
|
||||
alt={images[activeItem].alt}
|
||||
width={1207}
|
||||
height={929}
|
||||
/>
|
||||
</motion.div>
|
||||
</AnimatePresence>
|
||||
<div className="relative rounded-3xl bg-linear-to-br from-primary/50 via-accent/40 to-secondary/50 p-px shadow-lg shadow-primary/10">
|
||||
<div className="bg-background relative flex overflow-hidden rounded-[calc(1.5rem-1px)] m-0 p-0">
|
||||
<div className="w-15 absolute inset-0 right-0 ml-auto border-l border-primary/15 bg-[repeating-linear-gradient(-45deg,color-mix(in_oklab,var(--color-primary)_25%,var(--color-border)),color-mix(in_oklab,var(--color-primary)_25%,var(--color-border))_1px,transparent_1px,transparent_8px)]"></div>
|
||||
<div className="aspect-76/59 bg-background relative w-full rounded-[calc(1.5rem-1px)] m-0 p-0">
|
||||
<AnimatePresence mode="wait">
|
||||
<motion.div
|
||||
key={`${activeItem}-id`}
|
||||
initial={{ opacity: 0, y: 6, scale: 0.98 }}
|
||||
animate={{ opacity: 1, y: 0, scale: 1 }}
|
||||
exit={{ opacity: 0, y: 6, scale: 0.98 }}
|
||||
transition={{ duration: 0.2 }}
|
||||
className="size-full overflow-hidden rounded-[calc(1.5rem-1px)] m-0 p-0"
|
||||
>
|
||||
<Image
|
||||
src={images[activeItem].image}
|
||||
className="size-full object-cover dark:hidden"
|
||||
alt={images[activeItem].alt}
|
||||
width={1207}
|
||||
height={929}
|
||||
quality={100}
|
||||
sizes="(max-width: 768px) 100vw, 50vw"
|
||||
/>
|
||||
<Image
|
||||
src={images[activeItem].imageDark}
|
||||
className="hidden size-full object-cover dark:block"
|
||||
alt={images[activeItem].alt}
|
||||
width={1207}
|
||||
height={929}
|
||||
quality={100}
|
||||
sizes="(max-width: 768px) 100vw, 50vw"
|
||||
/>
|
||||
</motion.div>
|
||||
</AnimatePresence>
|
||||
</div>
|
||||
<BorderBeam
|
||||
duration={6}
|
||||
size={200}
|
||||
borderWidth={1}
|
||||
colorFrom="#FCC61D"
|
||||
colorTo="#01796F"
|
||||
/>
|
||||
</div>
|
||||
<BorderBeam
|
||||
duration={6}
|
||||
size={200}
|
||||
className="from-transparent via-yellow-700 to-transparent dark:via-white/50"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
+68
-61
@@ -72,9 +72,11 @@ export default function HeroSection() {
|
||||
<Image
|
||||
src="/assets/main-pic/main-pic.jpg"
|
||||
alt="background"
|
||||
className="hidden size-full dark:block"
|
||||
width="1150"
|
||||
height="613"
|
||||
className="hidden size-full object-cover dark:block"
|
||||
width={1150}
|
||||
height={613}
|
||||
quality={100}
|
||||
sizes="100vw"
|
||||
/>
|
||||
</AnimatedGroup>
|
||||
|
||||
@@ -120,7 +122,7 @@ export default function HeroSection() {
|
||||
as="p"
|
||||
className="mx-auto mt-8 max-w-2xl text-balance text-base md:text-lg leading-relaxed tracking-normal"
|
||||
>
|
||||
ما مجموعهای از ابزارهای یکپارچهسازی، اتوماسیون و ارتباطات ارائه میکنیم که به شما کمک میکند دادهها، کاربران و فرآیندهای کسبوکارتان را از هر سیستم یا پلتفرمی — از وبسایت و CRM گرفته تا تلگرام و سرویسهای سفارشی — به شکلی دقیق، سریع و قابلاعتماد بهم متصل کنید.
|
||||
با ابزارهای یکپارچهسازی، اتوماسیون و ارتباطات ما، دادهها، کاربران و فرآیندهای کسبوکارتان را از هر سیستم یا پلتفرمی، از وبسایت و CRM تا تلگرام و سرویسهای سفارشی، دقیق، سریع و قابل اعتماد به هم متصل کنید.
|
||||
</TextEffect>
|
||||
|
||||
<AnimatedGroup
|
||||
@@ -141,11 +143,7 @@ export default function HeroSection() {
|
||||
key={1}
|
||||
className="bg-foreground/10 rounded-[calc(var(--radius-xl)+0.125rem)] border p-0.5"
|
||||
>
|
||||
<Button
|
||||
asChild
|
||||
size="lg"
|
||||
className="rounded-xl px-5 text-base"
|
||||
>
|
||||
<Button asChild size="lg">
|
||||
<Link href="#link">
|
||||
<span className="text-nowrap">شروع کنید</span>
|
||||
</Link>
|
||||
@@ -168,78 +166,87 @@ export default function HeroSection() {
|
||||
...transitionVariants,
|
||||
}}
|
||||
>
|
||||
<div className="relative mt-8 overflow-hidden px-2 sm:mt-12 md:mt-20 p-2">
|
||||
<div className="ring-background bg-background relative max-w-5xl mx-auto overflow-hidden rounded-2xl border ring-1 aspect-[3/2]">
|
||||
<Image
|
||||
src="/assets/main-pic/Untitled-1 copy-min.jpg"
|
||||
alt="یکپارچهسازی سیستمها و شبکه دیجیتال"
|
||||
fill
|
||||
className="object-cover rounded-2xl inline-block my-0"
|
||||
quality={100}
|
||||
priority
|
||||
/>
|
||||
<div className="relative mt-8 overflow-visible px-2 sm:mt-12 md:mt-20 p-2">
|
||||
<div className="relative max-w-4xl mx-auto flex items-center justify-center">
|
||||
<div className="relative rounded-2xl overflow-hidden">
|
||||
{/* Glow effect */}
|
||||
<div className="absolute inset-0 rounded-2xl bg-gradient-to-r from-blue-500/20 via-purple-500/20 to-pink-500/20 blur-3xl -z-10 scale-110 animate-pulse" />
|
||||
<div className="absolute inset-0 rounded-2xl bg-gradient-to-r from-blue-400/30 via-purple-400/30 to-pink-400/30 blur-2xl -z-10 scale-105" />
|
||||
|
||||
<div className="relative bg-background rounded-2xl border ring-1 ring-border/50 shadow-2xl shadow-blue-500/10 dark:shadow-blue-500/20">
|
||||
<Image
|
||||
src="/assets/main-pic/1.jpg"
|
||||
alt="یکپارچهسازی سیستمها و شبکه دیجیتال"
|
||||
width={1920}
|
||||
height={1280}
|
||||
className="object-contain rounded-2xl w-full h-auto max-h-[600px] md:max-h-[700px] dark:hidden"
|
||||
quality={100}
|
||||
priority
|
||||
sizes="(max-width: 768px) 100vw, (max-width: 1200px) 90vw, 1200px"
|
||||
/>
|
||||
<Image
|
||||
src="/assets/main-pic/1dark.jpg"
|
||||
alt="یکپارچهسازی سیستمها و شبکه دیجیتال"
|
||||
width={1920}
|
||||
height={1280}
|
||||
className="hidden object-contain rounded-2xl w-full h-auto max-h-[600px] md:max-h-[700px] dark:block"
|
||||
quality={100}
|
||||
priority
|
||||
sizes="(max-width: 768px) 100vw, (max-width: 1200px) 90vw, 1200px"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</AnimatedGroup>
|
||||
</div>
|
||||
</section>
|
||||
<section className="bg-background pb-16 pt-16 md:pb-32">
|
||||
<div className="group relative m-auto max-w-5xl px-6">
|
||||
<div className="absolute inset-0 z-10 flex scale-95 items-center justify-center opacity-0 duration-500 group-hover:scale-100 group-hover:opacity-100">
|
||||
<Link
|
||||
href="/"
|
||||
className="block text-sm duration-150 hover:text-accent transition-colors"
|
||||
>
|
||||
<span> اتصال به سایر سیستم ها </span>
|
||||
|
||||
<ChevronRight className="ml-1 inline-block size-3" />
|
||||
</Link>
|
||||
<div className="m-auto max-w-5xl px-6">
|
||||
<div className="text-center">
|
||||
<p className="text-sm font-medium text-muted-foreground">
|
||||
یکپارچه با ابزارهای محبوب
|
||||
</p>
|
||||
<h2 className="mt-2 text-lg font-semibold md:text-xl">
|
||||
اتصال به سایر سیستمها
|
||||
</h2>
|
||||
</div>
|
||||
<div className="group-hover:blur-xs mx-auto mt-12 grid max-w-4xl grid-cols-4 gap-x-12 gap-y-8 transition-all duration-500 group-hover:opacity-50 sm:gap-x-16 sm:gap-y-14">
|
||||
<LogoItem
|
||||
icon="logos:telegram"
|
||||
alt="Telegram Logo"
|
||||
size="md"
|
||||
className="translate-x-1"
|
||||
/>
|
||||
|
||||
<div className="mx-auto mt-10 flex max-w-3xl flex-wrap items-center justify-center gap-4 sm:gap-5">
|
||||
<LogoItem icon="logos:telegram" alt="Telegram Logo" size="md" />
|
||||
<LogoItem
|
||||
icon="simple-icons:n8n"
|
||||
alt="n8n Logo"
|
||||
size="lg"
|
||||
className="translate-x-4 "
|
||||
iconClassName="text-black"
|
||||
/>
|
||||
<LogoItem
|
||||
icon="skill-icons:wordpress"
|
||||
alt="WordPress Logo"
|
||||
size="md"
|
||||
className="-translate-x-2"
|
||||
/>
|
||||
<LogoItem icon="logos:google-icon" alt="Google Logo" size="md" />
|
||||
<LogoItem
|
||||
icon="logos:whatsapp-icon"
|
||||
alt="WhatsApp Logo"
|
||||
size="md"
|
||||
/>
|
||||
<LogoItem
|
||||
icon="logos:google-icon"
|
||||
alt="Google Logo"
|
||||
icon="logos:microsoft-windows-icon"
|
||||
alt="Microsoft Windows Logo"
|
||||
size="md"
|
||||
className="translate-x-5"
|
||||
/>
|
||||
<div className="col-span-4 flex justify-center gap-x-12 sm:gap-x-40">
|
||||
<LogoItem
|
||||
icon="logos:whatsapp-icon"
|
||||
alt="WhatsApp Logo"
|
||||
size="md"
|
||||
className="translate-x-2"
|
||||
/>
|
||||
<LogoItem
|
||||
icon="logos:microsoft-windows-icon"
|
||||
alt="Microsoft Windows Logo"
|
||||
size="md"
|
||||
className="translate-x-2"
|
||||
/>
|
||||
<LogoItem
|
||||
icon="skill-icons:github-dark"
|
||||
alt="github Logo"
|
||||
size="md"
|
||||
className="translate-x-4"
|
||||
/>
|
||||
</div>
|
||||
<LogoItem icon="logos:github-icon" alt="GitHub Logo" size="md" />
|
||||
</div>
|
||||
|
||||
<div className="mt-8 text-center">
|
||||
<Link
|
||||
href="/"
|
||||
className="inline-flex items-center text-sm text-muted-foreground transition-colors hover:text-accent"
|
||||
>
|
||||
<span>مشاهده همه یکپارچهسازیها</span>
|
||||
<ChevronRight className="ml-1 inline-block size-3" />
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@@ -61,10 +61,7 @@ export function LoginForm({
|
||||
/>
|
||||
</Field>
|
||||
<Field>
|
||||
<Button
|
||||
type="submit"
|
||||
className="w-full h-10 sm:h-11 text-sm sm:text-base"
|
||||
>
|
||||
<Button type="submit" size="lg" className="w-full">
|
||||
ورود
|
||||
</Button>
|
||||
</Field>
|
||||
@@ -72,11 +69,7 @@ export function LoginForm({
|
||||
یا ادامه با
|
||||
</FieldSeparator>
|
||||
<Field className="">
|
||||
<Button
|
||||
variant="outline"
|
||||
type="button"
|
||||
className="w-full h-10 sm:h-11 text-sm sm:text-base"
|
||||
>
|
||||
<Button variant="outline" type="button" size="lg" className="w-full">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
|
||||
@@ -174,10 +174,10 @@ export default function Pricing() {
|
||||
ما آمادهایم تا بر اساس نیازهای شما بهترین پیشنهاد را ارائه دهیم.
|
||||
</p>
|
||||
<div className="flex flex-col sm:flex-row gap-4 justify-center">
|
||||
<Button asChild size="lg" className="text-base px-8 py-6">
|
||||
<Button asChild size="lg">
|
||||
<Link href="#chat">شروع گفتگو با تیم</Link>
|
||||
</Button>
|
||||
<Button asChild size="lg" variant="outline" className="text-base px-8 py-6">
|
||||
<Button asChild size="lg" variant="outline">
|
||||
<Link href="/about">درباره ما</Link>
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
@@ -41,11 +41,11 @@ export function ScrollToTop({ className }: { className?: string }) {
|
||||
)}
|
||||
>
|
||||
<Button
|
||||
size="icon"
|
||||
size="icon-lg"
|
||||
variant="outline"
|
||||
onClick={scrollToTop}
|
||||
aria-label="برگشت به بالا"
|
||||
className="size-10 rounded-md shadow-md"
|
||||
className="shadow-md"
|
||||
>
|
||||
<ChevronUp className="size-5" />
|
||||
</Button>
|
||||
|
||||
@@ -18,8 +18,7 @@ export function ThemeToggle() {
|
||||
return (
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
className="size-9 rounded-lg"
|
||||
size="icon"
|
||||
aria-label="Toggle theme"
|
||||
>
|
||||
<Sun className="size-4" />
|
||||
@@ -30,9 +29,8 @@ export function ThemeToggle() {
|
||||
return (
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
size="icon"
|
||||
onClick={() => setTheme(theme === 'dark' ? 'light' : 'dark')}
|
||||
className="size-9 rounded-lg transition-all duration-300 hover:bg-muted"
|
||||
aria-label="Toggle theme"
|
||||
>
|
||||
<Sun className="size-4 rotate-0 scale-100 transition-all duration-300 dark:-rotate-90 dark:scale-0" />
|
||||
|
||||
@@ -57,7 +57,7 @@ export const BorderBeam = ({
|
||||
delay = 0,
|
||||
duration = 6,
|
||||
colorFrom = "#FCC61D",
|
||||
colorTo = "#0046FF",
|
||||
colorTo = "#01796F",
|
||||
transition,
|
||||
style,
|
||||
reverse = false,
|
||||
|
||||
+12
-10
@@ -5,25 +5,27 @@ import { cva, type VariantProps } from "class-variance-authority"
|
||||
import { cn } from "@/lib/utils"
|
||||
|
||||
const buttonVariants = cva(
|
||||
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
|
||||
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-lg font-medium transition-colors disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
|
||||
{
|
||||
variants: {
|
||||
variant: {
|
||||
default: "bg-primary text-primary-foreground hover:bg-accent hover:text-foreground dark:hover:bg-[#FCC61D] dark:hover:text-foreground transition-colors",
|
||||
default:
|
||||
"bg-primary text-primary-foreground hover:bg-accent hover:text-foreground dark:hover:bg-[#FCC61D] dark:hover:text-foreground",
|
||||
destructive:
|
||||
"bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
|
||||
outline:
|
||||
"border bg-background shadow-xs hover:bg-accent hover:text-foreground dark:bg-input/30 dark:border-input dark:hover:bg-[#FCC61D] dark:hover:text-foreground transition-colors",
|
||||
"border border-primary text-primary bg-transparent hover:bg-accent hover:text-foreground hover:border-accent dark:bg-input/30 dark:border-input dark:text-foreground dark:hover:bg-[#FCC61D] dark:hover:text-foreground",
|
||||
secondary:
|
||||
"bg-secondary text-secondary-foreground hover:bg-accent hover:text-foreground dark:hover:bg-[#FCC61D] dark:hover:text-foreground transition-colors",
|
||||
"bg-secondary text-secondary-foreground hover:bg-accent hover:text-foreground dark:hover:bg-[#FCC61D] dark:hover:text-foreground",
|
||||
ghost:
|
||||
"hover:bg-accent hover:text-foreground dark:hover:bg-[#FCC61D] dark:hover:text-foreground transition-colors",
|
||||
link: "text-primary underline-offset-4 hover:text-accent hover:underline dark:hover:text-[#FCC61D] transition-colors",
|
||||
"hover:bg-accent hover:text-foreground dark:hover:bg-[#FCC61D] dark:hover:text-foreground",
|
||||
link:
|
||||
"text-primary underline-offset-4 hover:text-accent hover:underline dark:hover:text-[#FCC61D]",
|
||||
},
|
||||
size: {
|
||||
default: "h-9 px-4 py-2 has-[>svg]:px-3",
|
||||
sm: "h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5",
|
||||
lg: "h-10 rounded-md px-6 has-[>svg]:px-4",
|
||||
default: "h-9 px-4 text-sm has-[>svg]:px-3",
|
||||
sm: "h-8 gap-1.5 px-3 text-sm has-[>svg]:px-2.5",
|
||||
lg: "h-11 px-8 text-base has-[>svg]:px-6",
|
||||
icon: "size-9",
|
||||
"icon-sm": "size-8",
|
||||
"icon-lg": "size-10",
|
||||
@@ -51,7 +53,7 @@ function Button({
|
||||
return (
|
||||
<Comp
|
||||
data-slot="button"
|
||||
className={cn(buttonVariants({ variant, size, className }))}
|
||||
className={cn(buttonVariants({ variant, size }), className)}
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
|
||||
+31
-13
@@ -6,26 +6,44 @@ interface LogoItemProps {
|
||||
alt: string;
|
||||
size?: "sm" | "md" | "lg";
|
||||
className?: string;
|
||||
iconClassName?: string;
|
||||
}
|
||||
|
||||
const sizeMap = {
|
||||
sm: "h-8",
|
||||
md: "h-10",
|
||||
lg: "h-12",
|
||||
const iconSizeMap = {
|
||||
sm: "size-6",
|
||||
md: "size-7",
|
||||
lg: "size-8",
|
||||
};
|
||||
|
||||
export function LogoItem({ icon, alt, size = "md", className }: LogoItemProps) {
|
||||
const tileSizeMap = {
|
||||
sm: "size-12",
|
||||
md: "size-14",
|
||||
lg: "size-16",
|
||||
};
|
||||
|
||||
export function LogoItem({
|
||||
icon,
|
||||
alt,
|
||||
size = "md",
|
||||
className,
|
||||
iconClassName,
|
||||
}: LogoItemProps) {
|
||||
return (
|
||||
<div className={cn("flex", className)}>
|
||||
<Icon
|
||||
icon={icon}
|
||||
<div className={cn("flex items-center justify-center", className)}>
|
||||
<div
|
||||
className={cn(
|
||||
"mx-auto w-fit dark:invert",
|
||||
sizeMap[size]
|
||||
"flex items-center justify-center rounded-2xl border border-border/50 bg-white shadow-sm transition-all duration-300",
|
||||
"hover:-translate-y-1 hover:shadow-md",
|
||||
"dark:border-white/10 dark:bg-white/95 dark:shadow-lg dark:shadow-black/25",
|
||||
tileSizeMap[size]
|
||||
)}
|
||||
aria-label={alt}
|
||||
/>
|
||||
>
|
||||
<Icon
|
||||
icon={icon}
|
||||
className={cn("shrink-0", iconSizeMap[size], iconClassName)}
|
||||
aria-label={alt}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user