diff --git a/README.md b/README.md index 3b375ad..2f27fc5 100644 --- a/README.md +++ b/README.md @@ -159,7 +159,7 @@ src/ ## نکات -- لینک‌های ناوبری به مسیرهای واقعی سایت (`/portfolios`، `/news`، …) اشاره می‌کنند +- لینک‌های ناوبری به مسیرهای واقعی سایت (`/projects`، `/news`، …) اشاره می‌کنند ولی تاکنون فقط صفحه اصلی و درباره ما طراحی شده‌اند. - انیمیشن‌ها به `prefers-reduced-motion` احترام می‌گذارند. - کروسل پروژه‌ها برای RTL نوشته شده (`scrollLeft` منفی) و با کیبورد و لمس کار می‌کند. diff --git a/next.config.ts b/next.config.ts index 5245dcc..7036834 100644 --- a/next.config.ts +++ b/next.config.ts @@ -7,7 +7,7 @@ const nextConfig: NextConfig = { formats: ["image/avif", "image/webp"], // Every quality value used across the page. Required from Next.js 16 on. qualities: [70, 72, 75, 80, 82, 88, 90], - // Portfolio media served live from the meshkee API. The storage host has + // Project media served live from the meshkee API. The storage host has // already changed once mid-project (parminstorage.ir -> parspack.net) — // keep both around since either could be what a given item still points to. remotePatterns: [ @@ -16,6 +16,20 @@ const nextConfig: NextConfig = { { protocol: "https", hostname: "c804387.parspack.net" }, ], }, + async redirects() { + return [ + { + source: "/our-services", + destination: "/atelier", + permanent: true, + }, + { + source: "/portfolios/:path*", + destination: "/projects/:path*", + permanent: true, + }, + ]; + }, }; export default nextConfig; diff --git a/public/raoofi-media/atelier/hero-desktop.mp4 b/public/raoofi-media/atelier/hero-desktop.mp4 index d0cdea0..0ad8709 100644 Binary files a/public/raoofi-media/atelier/hero-desktop.mp4 and b/public/raoofi-media/atelier/hero-desktop.mp4 differ diff --git a/public/raoofi-media/atelier/hero-mobile.mp4 b/public/raoofi-media/atelier/hero-mobile.mp4 index 8417c8e..ad2aedb 100644 Binary files a/public/raoofi-media/atelier/hero-mobile.mp4 and b/public/raoofi-media/atelier/hero-mobile.mp4 differ diff --git a/public/raoofi-media/atelier/overview-1.webp b/public/raoofi-media/atelier/overview-1.webp new file mode 100644 index 0000000..3743a9b Binary files /dev/null and b/public/raoofi-media/atelier/overview-1.webp differ diff --git a/public/raoofi-media/atelier/overview-2.jpg b/public/raoofi-media/atelier/overview-2.jpg new file mode 100644 index 0000000..e89a7d6 Binary files /dev/null and b/public/raoofi-media/atelier/overview-2.jpg differ diff --git a/public/raoofi-media/atelier/portfolio-1.webp b/public/raoofi-media/atelier/portfolio-1.webp new file mode 100644 index 0000000..b10d9f0 Binary files /dev/null and b/public/raoofi-media/atelier/portfolio-1.webp differ diff --git a/public/raoofi-media/atelier/portfolio-2.webp b/public/raoofi-media/atelier/portfolio-2.webp new file mode 100644 index 0000000..f57a461 Binary files /dev/null and b/public/raoofi-media/atelier/portfolio-2.webp differ diff --git a/public/raoofi-media/atelier/portfolio-3.webp b/public/raoofi-media/atelier/portfolio-3.webp new file mode 100644 index 0000000..f52dd92 Binary files /dev/null and b/public/raoofi-media/atelier/portfolio-3.webp differ diff --git a/public/raoofi-media/atelier/portfolio-4.jpg b/public/raoofi-media/atelier/portfolio-4.jpg new file mode 100644 index 0000000..2086e30 Binary files /dev/null and b/public/raoofi-media/atelier/portfolio-4.jpg differ diff --git a/public/raoofi-media/atelier/portfolio-5.jpg b/public/raoofi-media/atelier/portfolio-5.jpg new file mode 100644 index 0000000..137afaa Binary files /dev/null and b/public/raoofi-media/atelier/portfolio-5.jpg differ diff --git a/public/raoofi-media/atelier/portfolio-6.webp b/public/raoofi-media/atelier/portfolio-6.webp new file mode 100644 index 0000000..af1d057 Binary files /dev/null and b/public/raoofi-media/atelier/portfolio-6.webp differ diff --git a/public/raoofi-media/atelier/portfolio-7.webp b/public/raoofi-media/atelier/portfolio-7.webp new file mode 100644 index 0000000..c9b72e9 Binary files /dev/null and b/public/raoofi-media/atelier/portfolio-7.webp differ diff --git a/public/raoofi-media/atelier/service-1.jpg b/public/raoofi-media/atelier/service-1.jpg new file mode 100644 index 0000000..23be4ab Binary files /dev/null and b/public/raoofi-media/atelier/service-1.jpg differ diff --git a/public/raoofi-media/atelier/service-2.jpg b/public/raoofi-media/atelier/service-2.jpg new file mode 100644 index 0000000..4a7ae25 Binary files /dev/null and b/public/raoofi-media/atelier/service-2.jpg differ diff --git a/public/raoofi-media/atelier/service-3.jpg b/public/raoofi-media/atelier/service-3.jpg new file mode 100644 index 0000000..1cee0e3 Binary files /dev/null and b/public/raoofi-media/atelier/service-3.jpg differ diff --git a/public/raoofi-media/atelier/service-4.jpg b/public/raoofi-media/atelier/service-4.jpg new file mode 100644 index 0000000..5d26665 Binary files /dev/null and b/public/raoofi-media/atelier/service-4.jpg differ diff --git a/public/raoofi-media/atelier/service-5.jpg b/public/raoofi-media/atelier/service-5.jpg new file mode 100644 index 0000000..f65042d Binary files /dev/null and b/public/raoofi-media/atelier/service-5.jpg differ diff --git a/public/raoofi-media/news/aghaghiya.jpg b/public/raoofi-media/news/aghaghiya.jpg new file mode 100644 index 0000000..b00f983 Binary files /dev/null and b/public/raoofi-media/news/aghaghiya.jpg differ diff --git a/public/raoofi-media/news/azadi.jpg b/public/raoofi-media/news/azadi.jpg new file mode 100644 index 0000000..7da8f86 Binary files /dev/null and b/public/raoofi-media/news/azadi.jpg differ diff --git a/public/raoofi-media/news/elysium-opening.jpg b/public/raoofi-media/news/elysium-opening.jpg new file mode 100644 index 0000000..155988c Binary files /dev/null and b/public/raoofi-media/news/elysium-opening.jpg differ diff --git a/public/raoofi-media/news/ghab.jpg b/public/raoofi-media/news/ghab.jpg new file mode 100644 index 0000000..369616d Binary files /dev/null and b/public/raoofi-media/news/ghab.jpg differ diff --git a/public/raoofi-media/news/ghasr-5.jpg b/public/raoofi-media/news/ghasr-5.jpg new file mode 100644 index 0000000..1880008 Binary files /dev/null and b/public/raoofi-media/news/ghasr-5.jpg differ diff --git a/public/raoofi-media/news/ghasr-8.jpg b/public/raoofi-media/news/ghasr-8.jpg new file mode 100644 index 0000000..91badf7 Binary files /dev/null and b/public/raoofi-media/news/ghasr-8.jpg differ diff --git a/public/raoofi-media/news/ghasr.jpg b/public/raoofi-media/news/ghasr.jpg new file mode 100644 index 0000000..c255c11 Binary files /dev/null and b/public/raoofi-media/news/ghasr.jpg differ diff --git a/public/raoofi-media/news/golden-ghasr.jpg b/public/raoofi-media/news/golden-ghasr.jpg new file mode 100644 index 0000000..957717c Binary files /dev/null and b/public/raoofi-media/news/golden-ghasr.jpg differ diff --git a/public/raoofi-media/news/hayat-foundation.jpg b/public/raoofi-media/news/hayat-foundation.jpg new file mode 100644 index 0000000..bd40d96 Binary files /dev/null and b/public/raoofi-media/news/hayat-foundation.jpg differ diff --git a/public/raoofi-media/news/pania.jpg b/public/raoofi-media/news/pania.jpg new file mode 100644 index 0000000..c6840e6 Binary files /dev/null and b/public/raoofi-media/news/pania.jpg differ diff --git a/public/raoofi-media/news/year-end-ceremony.jpg b/public/raoofi-media/news/year-end-ceremony.jpg new file mode 100644 index 0000000..682a25b Binary files /dev/null and b/public/raoofi-media/news/year-end-ceremony.jpg differ diff --git a/public/raoofi-media/raoofi-home/collection-1.webp b/public/raoofi-media/raoofi-home/collection-1.webp new file mode 100644 index 0000000..5caed24 Binary files /dev/null and b/public/raoofi-media/raoofi-home/collection-1.webp differ diff --git a/public/raoofi-media/raoofi-home/collection-2.webp b/public/raoofi-media/raoofi-home/collection-2.webp new file mode 100644 index 0000000..820541f Binary files /dev/null and b/public/raoofi-media/raoofi-home/collection-2.webp differ diff --git a/public/raoofi-media/raoofi-home/collection-3.webp b/public/raoofi-media/raoofi-home/collection-3.webp new file mode 100644 index 0000000..d34d7ac Binary files /dev/null and b/public/raoofi-media/raoofi-home/collection-3.webp differ diff --git a/public/raoofi-media/raoofi-home/hero-desktop.mp4 b/public/raoofi-media/raoofi-home/hero-desktop.mp4 new file mode 100644 index 0000000..d0cdea0 Binary files /dev/null and b/public/raoofi-media/raoofi-home/hero-desktop.mp4 differ diff --git a/public/raoofi-media/raoofi-home/hero-mobile.mp4 b/public/raoofi-media/raoofi-home/hero-mobile.mp4 new file mode 100644 index 0000000..8417c8e Binary files /dev/null and b/public/raoofi-media/raoofi-home/hero-mobile.mp4 differ diff --git a/public/raoofi-media/raoofi-home/hero-poster.jpg b/public/raoofi-media/raoofi-home/hero-poster.jpg new file mode 100644 index 0000000..0fa0551 Binary files /dev/null and b/public/raoofi-media/raoofi-home/hero-poster.jpg differ diff --git a/public/raoofi-media/raoofi-home/story-1.webp b/public/raoofi-media/raoofi-home/story-1.webp new file mode 100644 index 0000000..f57a461 Binary files /dev/null and b/public/raoofi-media/raoofi-home/story-1.webp differ diff --git a/public/raoofi-media/raoofi-home/story-2.webp b/public/raoofi-media/raoofi-home/story-2.webp new file mode 100644 index 0000000..b10d9f0 Binary files /dev/null and b/public/raoofi-media/raoofi-home/story-2.webp differ diff --git a/public/raoofi-media/raoofi-home/story-3.jpg b/public/raoofi-media/raoofi-home/story-3.jpg new file mode 100644 index 0000000..2086e30 Binary files /dev/null and b/public/raoofi-media/raoofi-home/story-3.jpg differ diff --git a/public/raoofi-media/raoofi-home/story-4.webp b/public/raoofi-media/raoofi-home/story-4.webp new file mode 100644 index 0000000..f52dd92 Binary files /dev/null and b/public/raoofi-media/raoofi-home/story-4.webp differ diff --git a/public/raoofi-media/raoofi-home/textured-background.webp b/public/raoofi-media/raoofi-home/textured-background.webp new file mode 100644 index 0000000..0fcac01 Binary files /dev/null and b/public/raoofi-media/raoofi-home/textured-background.webp differ diff --git a/public/raoofi-media/services/hero-desktop.mp4 b/public/raoofi-media/services/hero-desktop.mp4 deleted file mode 100644 index 0ad8709..0000000 Binary files a/public/raoofi-media/services/hero-desktop.mp4 and /dev/null differ diff --git a/public/raoofi-media/services/hero-mobile.mp4 b/public/raoofi-media/services/hero-mobile.mp4 deleted file mode 100644 index ad2aedb..0000000 Binary files a/public/raoofi-media/services/hero-mobile.mp4 and /dev/null differ diff --git a/src/app/aboutus/page.tsx b/src/app/aboutus/page.tsx index 56f2537..2ea8b90 100644 --- a/src/app/aboutus/page.tsx +++ b/src/app/aboutus/page.tsx @@ -3,7 +3,7 @@ import type { Metadata } from "next"; import { RaoofiAbout } from "@/components/about/RaoofiAbout"; import { SiteFooter } from "@/components/SiteFooter"; import { SiteHeader } from "@/components/SiteHeader"; -import { getRecentPortfolios, toDisplayProject } from "@/lib/api"; +import { getRecentProjects, toDisplayProject } from "@/lib/api"; export const revalidate = 300; @@ -13,8 +13,8 @@ export const metadata: Metadata = { }; export default async function AboutPage() { - const portfolios = await getRecentPortfolios(8); - const displayProjects = portfolios.map(toDisplayProject); + const projects = await getRecentProjects(8); + const displayProjects = projects.map(toDisplayProject); return ( <> diff --git a/src/app/api/revalidate/route.ts b/src/app/api/revalidate/route.ts index a8662df..aa1bf05 100644 --- a/src/app/api/revalidate/route.ts +++ b/src/app/api/revalidate/route.ts @@ -4,7 +4,7 @@ import { NextRequest, NextResponse } from "next/server"; type RevalidateBody = { /** Revalidate a fetch cache tag (portfolios, blogs, portfolio:slug, blog:slug, …). */ tag?: string; - /** Revalidate a path (/portfolios/foo, /, …). */ + /** Revalidate a path (/projects/foo, /, …). */ path?: string; /** Shorthand: portfolios | blogs | all */ scope?: "portfolios" | "blogs" | "all"; @@ -15,7 +15,7 @@ type RevalidateBody = { * * POST /api/revalidate * Header: x-revalidate-secret: - * Body (JSON, optional): { "scope": "all" } | { "tag": "portfolios" } | { "path": "/portfolios/item" } + * Body (JSON, optional): { "scope": "all" } | { "tag": "portfolios" } | { "path": "/projects/item" } * * nginx may still serve cached HTML for up to its TTL (5m) unless purged separately. */ @@ -50,9 +50,10 @@ export async function POST(req: NextRequest) { } else if (scope === "portfolios" || scope === "all") { revalidateTag("portfolios"); revalidatePath("/"); - revalidatePath("/portfolios"); + revalidatePath("/projects"); revalidatePath("/aboutus"); - revalidatePath("/our-services"); + revalidatePath("/atelier"); + revalidatePath("/raoofi-home"); revalidated.push("scope:portfolios"); } diff --git a/src/app/atelier/page.tsx b/src/app/atelier/page.tsx index 544067d..c82c16f 100644 --- a/src/app/atelier/page.tsx +++ b/src/app/atelier/page.tsx @@ -3,17 +3,22 @@ import type { Metadata } from "next"; import { RaoofiAtelier } from "@/components/atelier/RaoofiAtelier"; import { SiteFooter } from "@/components/SiteFooter"; import { SiteHeader } from "@/components/SiteHeader"; +import { getRecentProjects, toDisplayProject } from "@/lib/api"; + +export const revalidate = 300; export const metadata: Metadata = { title: "آتلیه رئوفی", - description: "آتلیه رئوفی؛ خلق فضاهای شخصی، کمیاب و ماندگار با طراحی و اجرای یکپارچه.", + description: "آتلیه رئوفی؛ خدمات یکپارچه از نخستین ایده و طراحی تا مدیریت، اجرا و تحویل نهایی.", }; -export default function AtelierPage() { +export default async function AtelierPage() { + const projects = await getRecentProjects(12); + return ( <> - + ); diff --git a/src/app/blog/[slug]/page.tsx b/src/app/blog/[slug]/page.tsx index 6227889..c5ec3f5 100644 --- a/src/app/blog/[slug]/page.tsx +++ b/src/app/blog/[slug]/page.tsx @@ -4,21 +4,26 @@ import { notFound } from "next/navigation"; import { NewsArticleDetail } from "@/components/news/NewsArticleDetail"; import { SiteFooter } from "@/components/SiteFooter"; import { SiteHeader } from "@/components/SiteHeader"; +import { getDemoNewsItem, getDemoNewsItems } from "@/data/news-demo"; import { getBlogBySlug, getBlogSlugs, toDisplayNewsItem } from "@/lib/api"; export const revalidate = 300; // keep in sync with api.ts PAGE_REVALIDATE_SECONDS async function getBlogArticleBySlug(slug: string) { + const demoItem = getDemoNewsItem(slug, "blog"); + if (demoItem) return demoItem; + const item = await getBlogBySlug(slug); if (!item || item.type === "news") { return null; } - return item; + return toDisplayNewsItem(item); } export async function generateStaticParams() { const slugs = await getBlogSlugs(); - return slugs.map((slug) => ({ slug })); + return [...new Set([...slugs, ...getDemoNewsItems("blog").map((item) => item.slug)])] + .map((slug) => ({ slug })); } export async function generateMetadata({ @@ -29,7 +34,7 @@ export async function generateMetadata({ const { slug } = await params; const item = await getBlogArticleBySlug(slug); if (!item) return {}; - return { title: item.titleFa || item.title, description: item.abstract || item.titleFa }; + return { title: item.title, description: item.title }; } export default async function BlogDetailPage({ @@ -46,7 +51,7 @@ export default async function BlogDetailPage({
; -}) { - const { page: pageParam } = await searchParams; - const page = Math.max(1, Number(pageParam) || 1); +export default async function BlogListPage() { const posts = await getBlogs(); - const blog = posts.filter((p) => p.type !== "news").map(toDisplayNewsItem); + const articles = posts.filter((post) => post.type !== "news"); + const blog = articles.length ? articles.map(toDisplayNewsItem) : getDemoNewsItems("blog"); return ( <> -
- - -
- -
- -
- -
- -
- ); diff --git a/src/app/contactus/page.tsx b/src/app/contactus/page.tsx index bbdc201..4b51c8a 100644 --- a/src/app/contactus/page.tsx +++ b/src/app/contactus/page.tsx @@ -1,14 +1,9 @@ import type { Metadata } from "next"; import Link from "next/link"; -import heroImage from "@/assets/images/hero/hero-3.jpg"; -import heroImageMobile from "@/assets/images/hero/hero-3-mobile.jpg"; import { InstagramIcon, MailIcon, PhoneIcon, PinIcon } from "@/components/ContactIcons"; import { ContactForm } from "@/components/contact/ContactForm"; import { Reveal } from "@/components/Reveal"; -import { Editorial } from "@/components/shared/Editorial"; -import { PageHero } from "@/components/shared/PageHero"; -import { SectionLabel } from "@/components/shared/SectionLabel"; import { SiteFooter } from "@/components/SiteFooter"; import { SiteHeader } from "@/components/SiteHeader"; import { contact, contactPage } from "@/data/site"; @@ -26,98 +21,85 @@ export default function ContactPage() { <> -
- - -
- -
+
-
- {/* Contact info + map */} - - +
+
+ +
+ +

دفتر مرکزی

+
+

{contact.address}

+ + مشاهده موقعیت روی نقشه + +
-
    -
  • - -

    {contact.address}

    -
  • - - {contact.phones.map((phone, i) => ( -
  • - - - {phone} + +
    + +

    تماس با ما

    +
    +
      + {contact.phones.map((phone, i) => ( +
    • + + {phone} + +
    • + ))} +
    • + + {contact.email}
    • - ))} +
    +
    -
  • - - - {contact.email} - -
  • + +
    + +

    شبکه‌های اجتماعی

    +
    +

    برای آشنایی با تازه‌ترین خبرها و پروژه‌های رئوفی، ما را دنبال کنید.

    + + {contact.instagram} + +
    +
-
  • - - - {contact.instagram} - -
  • - - -
    -